blob: a31a5a189ae080c5d6adb74898dc20a51561e656 [file] [log] [blame]
Dan Sinclair1770c022016-03-14 14:14:16 -04001// Copyright 2014 PDFium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7#include "xfa/fxfa/fm2js/xfa_fm2jscontext.h"
8
9#include <time.h>
10
Dan Sinclaira8a28e02016-03-23 15:41:39 -040011#include "core/fxcrt/include/fx_ext.h"
Dan Sinclair1770c022016-03-14 14:14:16 -040012#include "xfa/fgas/localization/fgas_locale.h"
dsinclairdf4bc592016-03-31 20:34:43 -070013#include "xfa/fxfa/app/xfa_ffnotify.h"
dsinclaire80e9f82016-06-01 06:10:04 -070014#include "xfa/fxfa/fm2js/xfa_program.h"
Dan Sinclair1770c022016-03-14 14:14:16 -040015#include "xfa/fxfa/parser/xfa_document.h"
16#include "xfa/fxfa/parser/xfa_localevalue.h"
17#include "xfa/fxfa/parser/xfa_parser.h"
dsinclairdf4bc592016-03-31 20:34:43 -070018#include "xfa/fxfa/parser/xfa_parser_imp.h"
19#include "xfa/fxfa/parser/xfa_script_imp.h"
Dan Sinclair3a8051c2016-03-15 15:42:31 -040020#include "xfa/fxjse/cfxjse_arguments.h"
dsinclair86fad992016-05-31 11:34:04 -070021#include "xfa/fxjse/value.h"
Dan Sinclair1770c022016-03-14 14:14:16 -040022
Dan Sinclair1770c022016-03-14 14:14:16 -040023namespace {
24
dsinclair48d91dd2016-05-31 11:54:01 -070025const double kFinancialPrecision = 0.00000001;
26
Dan Sinclair1770c022016-03-14 14:14:16 -040027struct XFA_FMHtmlReserveCode {
28 uint32_t m_uCode;
29 const FX_WCHAR* m_htmlReserve;
30};
dsinclair48d91dd2016-05-31 11:54:01 -070031
Dan Sinclair1770c022016-03-14 14:14:16 -040032struct XFA_FMHtmlHashedReserveCode {
33 uint32_t m_uHash;
Dan Sinclair1770c022016-03-14 14:14:16 -040034 uint32_t m_uCode;
35};
36
37const XFA_FMHtmlHashedReserveCode reservesForDecode[] = {
dsinclair89ba6de2016-05-31 12:11:22 -070038 {0x00018b62, /*L"Mu",*/ 924}, {0x00019083, /*L"Nu",*/ 925},
39 {0x00019ab9, /*L"Pi",*/ 928}, {0x0001c3c1, /*L"Xi",*/ 926},
40 {0x000210ac, /*L"ge",*/ 8805}, {0x000210bb, /*L"gt",*/ 62},
41 {0x00022a51, /*L"le",*/ 8804}, {0x00022a60, /*L"lt",*/ 60},
42 {0x00022f82, /*L"mu",*/ 956}, {0x00023493, /*L"ne",*/ 8800},
43 {0x00023497, /*L"ni",*/ 8715}, {0x000234a3, /*L"nu",*/ 957},
44 {0x000239c1, /*L"or",*/ 8744}, {0x00023ed9, /*L"pi",*/ 960},
45 {0x000267e1, /*L"xi",*/ 958}, {0x00c41789, /*L"lceil",*/ 8968},
46 {0x00eef34f, /*L"thetasym",*/ 977}, {0x012d7ead, /*L"lcirc",*/ 206},
47 {0x01637b56, /*L"agrave",*/ 224}, {0x020856da, /*L"crarr",*/ 8629},
48 {0x022188c3, /*L"gamma",*/ 947}, {0x033586d3, /*L"nbsp",*/ 160},
49 {0x04f4c358, /*L"nsub",*/ 8836}, {0x0581466a, /*L"dagger",*/ 8224},
50 {0x06b1f790, /*L"oelig",*/ 339}, {0x06e490d4, /*L"Chi",*/ 935},
51 {0x0718c6a1, /*L"ETH",*/ 208}, {0x07196ada, /*L"Eta",*/ 919},
52 {0x07f667ca, /*L"Ugrave",*/ 217}, {0x083a8a21, /*L"Phi",*/ 934},
53 {0x083ac28c, /*L"Psi",*/ 936}, {0x086f26a9, /*L"Rho",*/ 929},
54 {0x089b5b51, /*L"aring",*/ 229}, {0x08a39f4a, /*L"Tau",*/ 932},
55 {0x08b6188b, /*L"THORN",*/ 222}, {0x09ce792a, /*L"icirc",*/ 238},
56 {0x09f9d61e, /*L"amp",*/ 38}, {0x09f9db33, /*L"and",*/ 8743},
57 {0x09f9db36, /*L"ang",*/ 8736}, {0x0a2e3514, /*L"cap",*/ 8745},
58 {0x0a2e58f4, /*L"chi",*/ 967}, {0x0a2e9ba8, /*L"cup",*/ 8746},
59 {0x0a4897d0, /*L"deg",*/ 176}, {0x0a6332fa, /*L"eta",*/ 951},
60 {0x0a633301, /*L"eth",*/ 240}, {0x0acc4d4b, /*L"int",*/ 8747},
61 {0x0b1b3d35, /*L"loz",*/ 9674}, {0x0b1b4c8b, /*L"lrm",*/ 8206},
62 {0x0b4fd9b1, /*L"not",*/ 172}, {0x0b845241, /*L"phi",*/ 966},
63 {0x0b84576f, /*L"piv",*/ 982}, {0x0b848aac, /*L"psi",*/ 968},
64 {0x0bb8df5e, /*L"reg",*/ 174}, {0x0bb8eec9, /*L"rho",*/ 961},
65 {0x0bb9034b, /*L"rlm",*/ 8207}, {0x0bd33d14, /*L"shy",*/ 173},
66 {0x0bd34229, /*L"sim",*/ 8764}, {0x0bd37faa, /*L"sub",*/ 8834},
67 {0x0bd37fb5, /*L"sum",*/ 8721}, {0x0bd37fb8, /*L"sup",*/ 8835},
68 {0x0bed676a, /*L"tau",*/ 964}, {0x0c07f32e, /*L"uml",*/ 168},
69 {0x0c71032c, /*L"yen",*/ 165}, {0x0c7f2889, /*L"szlig",*/ 223},
70 {0x0c8badbb, /*L"zwj",*/ 8205}, {0x10ba4dba, /*L"Egrave",*/ 200},
71 {0x10f1ea24, /*L"para",*/ 182}, {0x10f1ea37, /*L"part",*/ 8706},
72 {0x115b2337, /*L"perp",*/ 8869}, {0x12b10d15, /*L"prod",*/ 8719},
73 {0x12b10d21, /*L"prop",*/ 8733}, {0x12dfa9f4, /*L"rfloor",*/ 8971},
74 {0x12eb4736, /*L"Agrave",*/ 192}, {0x12fff2b7, /*L"pund",*/ 163},
75 {0x13fda9f2, /*L"tilde",*/ 732}, {0x1417fd62, /*L"times",*/ 215},
76 {0x154fc726, /*L"ecirc",*/ 234}, {0x165aa451, /*L"sigma",*/ 963},
77 {0x1709124a, /*L"Dagger",*/ 8225}, {0x192f78d5, /*L"iexcl",*/ 161},
78 {0x1b7ed8d7, /*L"rArr",*/ 8658}, {0x1ec88c68, /*L"rang",*/ 9002},
79 {0x1ec8a0f7, /*L"rarr",*/ 8594}, {0x1eda07f3, /*L"atilde",*/ 227},
80 {0x1f3182c4, /*L"real",*/ 8476}, {0x1fc34f8b, /*L"yacute",*/ 253},
81 {0x20d11522, /*L"acirc",*/ 226}, {0x21933a9b, /*L"rsaquo",*/ 8250},
82 {0x21f44907, /*L"uacute",*/ 250}, {0x220cca72, /*L"acute",*/ 180},
83 {0x242cded1, /*L"alefsym",*/ 8501}, {0x2655c66a, /*L"delta",*/ 948},
84 {0x269e4b4d, /*L"exist",*/ 8707}, {0x273379fa, /*L"micro",*/ 181},
85 {0x27a37440, /*L"forall",*/ 8704}, {0x2854e62c, /*L"minus",*/ 8722},
86 {0x28636f81, /*L"cedil",*/ 184}, {0x2887357b, /*L"iacute",*/ 237},
87 {0x2994d5ff, /*L"frac12",*/ 189}, {0x2994d601, /*L"frac14",*/ 188},
88 {0x2994e043, /*L"frac34",*/ 190}, {0x2a1feb41, /*L"lambda",*/ 955},
89 {0x2ab215f3, /*L"apos",*/ 39}, {0x2ab82ef7, /*L"eacute",*/ 233},
90 {0x2b3592ef, /*L"auml",*/ 228}, {0x2ce92873, /*L"aacute",*/ 225},
91 {0x2daff48a, /*L"oslash",*/ 248}, {0x2ef68882, /*L"aelig",*/ 230},
92 {0x3061d3d3, /*L"Atilde",*/ 195}, {0x314b1b6b, /*L"Yacute",*/ 221},
93 {0x337c14e7, /*L"Uacute",*/ 218}, {0x37676aca, /*L"cent",*/ 162},
94 {0x37d0b841, /*L"circ",*/ 710}, {0x386e7947, /*L"cong",*/ 8773},
95 {0x386e839b, /*L"copy",*/ 169}, {0x3a0e225a, /*L"Epsilon",*/ 917},
96 {0x3ba7b721, /*L"Lambda",*/ 923}, {0x3bd9abe6, /*L"Alpha",*/ 913},
97 {0x3c3ffad7, /*L"Eacute",*/ 201}, {0x3cfaf69f, /*L"brvbar",*/ 166},
98 {0x3d54a489, /*L"omega",*/ 969}, {0x3e70f453, /*L"Aacute",*/ 193},
99 {0x3f37c06a, /*L"Oslash",*/ 216}, {0x40e1b34e, /*L"diams",*/ 9830},
100 {0x416596df, /*L"plusmn",*/ 177}, {0x4354ff16, /*L"Ucirc",*/ 219},
101 {0x454fce6a, /*L"Upsilon",*/ 933}, {0x4610ad35, /*L"emsp",*/ 8195},
102 {0x462afb76, /*L"ensp",*/ 8194}, {0x46e30073, /*L"euml",*/ 235},
103 {0x46e31a1b, /*L"euro",*/ 8364}, {0x46f2eada, /*L"lowast",*/ 8727},
104 {0x4dca26cf, /*L"Auml",*/ 196}, {0x4e2d6083, /*L"image",*/ 8465},
105 {0x4f964ee8, /*L"notin",*/ 8713}, {0x50917a7a, /*L"epsilon",*/ 949},
106 {0x52f9a4cd, /*L"Kappa",*/ 922}, {0x5496f410, /*L"Ocirc",*/ 212},
107 {0x568cbf34, /*L"zeta",*/ 950}, {0x57badd20, /*L"ntilde",*/ 241},
108 {0x58662109, /*L"zwnj",*/ 8204}, {0x5b39870f, /*L"empty",*/ 8709},
109 {0x5bd3268a, /*L"upsilon",*/ 965}, {0x5e2bf8a3, /*L"Gamma",*/ 915},
110 {0x5f73c13a, /*L"rsquo",*/ 8217}, {0x61f2bc4d, /*L"iota",*/ 953},
111 {0x625bbcf3, /*L"isin",*/ 8712}, {0x62906df7, /*L"iuml",*/ 239},
112 {0x64a5cb31, /*L"Aring",*/ 197}, {0x66f25c4a, /*L"sbquo",*/ 8218},
113 {0x6851ab60, /*L"spades",*/ 9824}, {0x6942a900, /*L"Ntilde",*/ 209},
114 {0x69779453, /*L"Euml",*/ 203}, {0x6cda6e23, /*L"current",*/ 164},
115 {0x70b5b634, /*L"lsquo",*/ 8216}, {0x715a3706, /*L"Ecirc",*/ 202},
116 {0x71e8bf8d, /*L"tdquo",*/ 8221}, {0x72651431, /*L"Sigma",*/ 931},
117 {0x7569813b, /*L"iquest",*/ 191}, {0x776a436a, /*L"equiv",*/ 8801},
118 {0x79215314, /*L"Zeta",*/ 918}, {0x79b81224, /*L"ograve",*/ 242},
119 {0x7c2f8b23, /*L"macr",*/ 175}, {0x7cdb8502, /*L"Acirc",*/ 194},
120 {0x8185c62e, /*L"ndash",*/ 8211}, {0x8260364a, /*L"Delta",*/ 916},
121 {0x846619ad, /*L"mdash",*/ 8212}, {0x8550fb50, /*L"OElig",*/ 338},
122 {0x88eb5b85, /*L"ldquo",*/ 8220}, {0x8b3fde04, /*L"Ograve",*/ 210},
123 {0x8bc5794b, /*L"ordf",*/ 170}, {0x8bc57952, /*L"ordm",*/ 186},
124 {0x8c14923d, /*L"ouml",*/ 246}, {0x8c5a7cd6, /*L"theta",*/ 952},
125 {0x8d61812b, /*L"thorn",*/ 254}, {0x912b95aa, /*L"asymp",*/ 8776},
126 {0x947faf81, /*L"middot",*/ 183}, {0x9629202e, /*L"lfloor",*/ 8970},
127 {0x972e9ec1, /*L"otilde",*/ 245}, {0x9748f231, /*L"otimes",*/ 8855},
128 {0x995f1469, /*L"Omega",*/ 937}, {0x99eb5349, /*L"quot",*/ 34},
129 {0x9aeb639e, /*L"hellip",*/ 8230}, {0xa0ae2f86, /*L"Scaron",*/ 352},
130 {0xa4dcb0d5, /*L"lsaquo",*/ 8249}, {0xa53dbf41, /*L"oacute",*/ 243},
131 {0xa5ae9e7b, /*L"bdquo",*/ 8222}, {0xa602d7ba, /*L"sdot",*/ 8901},
132 {0xa61ce86f, /*L"sect",*/ 167}, {0xa6e4c3d7, /*L"sigmaf",*/ 962},
133 {0xa7c1c74f, /*L"sube",*/ 8838}, {0xa7c20ee9, /*L"sup1",*/ 185},
134 {0xa7c20eea, /*L"sup2",*/ 178}, {0xa7c20eeb, /*L"sup3",*/ 179},
135 {0xa7c20f1d, /*L"supe",*/ 8839}, {0xa8b66aa1, /*L"Otilde",*/ 213},
136 {0xad958c42, /*L"AElig",*/ 198}, {0xaea9261d, /*L"Ouml",*/ 214},
137 {0xb040eafa, /*L"uArr",*/ 8657}, {0xb07c2e1c, /*L"beta",*/ 946},
138 {0xb220e92f, /*L"bull",*/ 8226}, {0xb22750c4, /*L"ccedil",*/ 231},
139 {0xb38ab31a, /*L"uarr",*/ 8593}, {0xb598b683, /*L"uuml",*/ 252},
140 {0xb6c58b21, /*L"Oacute",*/ 211}, {0xb6d2a617, /*L"oline",*/ 8254},
141 {0xba9fd989, /*L"dArr",*/ 8659}, {0xbb5ccd41, /*L"lgrave",*/ 204},
142 {0xbd39b44c, /*L"weierp",*/ 8472}, {0xbde9a1a9, /*L"darr",*/ 8595},
143 {0xc027e329, /*L"permil",*/ 8240}, {0xc2451389, /*L"upsih",*/ 978},
144 {0xc3af1ca4, /*L"Ccedil",*/ 199}, {0xcd164249, /*L"fnof",*/ 402},
145 {0xcf6c8467, /*L"hearts",*/ 9829}, {0xd1228390, /*L"trade",*/ 8482},
146 {0xd1462407, /*L"yuml",*/ 255}, {0xd2cf2253, /*L"oplus",*/ 8853},
147 {0xd310c1fc, /*L"Beta",*/ 914}, {0xd59c4d74, /*L"infin",*/ 8734},
148 {0xd64d470d, /*L"hArr",*/ 8660}, {0xd67d9c75, /*L"divide",*/ 247},
149 {0xd698dd37, /*L"Omicron",*/ 927}, {0xd82d4a63, /*L"Uuml",*/ 220},
150 {0xd9970f2d, /*L"harr",*/ 8596}, {0xda91fd99, /*L"clubs",*/ 9827},
151 {0xdbe5bdcc, /*L"there4",*/ 8756}, {0xdd7671bd, /*L"prime",*/ 8242},
152 {0xdfcf3c06, /*L"alpha",*/ 945}, {0xe0213063, /*L"saron",*/ 353},
153 {0xe1911d83, /*L"radic",*/ 8730}, {0xe2e75468, /*L"raquo",*/ 187},
154 {0xe6e27a5e, /*L"lacute",*/ 205}, {0xe74a8f36, /*L"ucirc",*/ 251},
155 {0xe864ecb6, /*L"Theta",*/ 920}, {0xecddde5e, /*L"nabla",*/ 8711},
156 {0xed1c3557, /*L"omicron",*/ 959}, {0xef82228f, /*L"rceil",*/ 8969},
157 {0xf1fab491, /*L"lArr",*/ 8656}, {0xf3dab7e7, /*L"Yuml",*/ 376},
158 {0xf4294962, /*L"laquo",*/ 171}, {0xf5446822, /*L"lang",*/ 9001},
159 {0xf5447cb1, /*L"larr",*/ 8592}, {0xf66e9bea, /*L"ugrave",*/ 249},
160 {0xf6b4ce70, /*L"lota",*/ 921}, {0xf6ef34ed, /*L"kappa",*/ 954},
161 {0xf72a3a56, /*L"thinsp",*/ 8201}, {0xf752801a, /*L"luml",*/ 207},
162 {0xf88c8430, /*L"ocirc",*/ 244}, {0xf9676178, /*L"frasl",*/ 8260},
163 {0xfd01885e, /*L"igrave",*/ 236}, {0xff3281da, /*L"egrave",*/ 232},
Dan Sinclair1770c022016-03-14 14:14:16 -0400164};
165
166const XFA_FMHtmlReserveCode reservesForEncode[] = {
167 {34, L"quot"}, {38, L"amp"}, {39, L"apos"},
168 {60, L"lt"}, {62, L"gt"}, {160, L"nbsp"},
169 {161, L"iexcl"}, {162, L"cent"}, {163, L"pund"},
170 {164, L"current"}, {165, L"yen"}, {166, L"brvbar"},
171 {167, L"sect"}, {168, L"uml"}, {169, L"copy"},
172 {170, L"ordf"}, {171, L"laquo"}, {172, L"not"},
173 {173, L"shy"}, {174, L"reg"}, {175, L"macr"},
174 {176, L"deg"}, {177, L"plusmn"}, {178, L"sup2"},
175 {179, L"sup3"}, {180, L"acute"}, {181, L"micro"},
176 {182, L"para"}, {183, L"middot"}, {184, L"cedil"},
177 {185, L"sup1"}, {186, L"ordm"}, {187, L"raquo"},
178 {188, L"frac14"}, {189, L"frac12"}, {190, L"frac34"},
179 {191, L"iquest"}, {192, L"Agrave"}, {193, L"Aacute"},
180 {194, L"Acirc"}, {195, L"Atilde"}, {196, L"Auml"},
181 {197, L"Aring"}, {198, L"AElig"}, {199, L"Ccedil"},
182 {200, L"Egrave"}, {201, L"Eacute"}, {202, L"Ecirc"},
183 {203, L"Euml"}, {204, L"lgrave"}, {205, L"lacute"},
184 {206, L"lcirc"}, {207, L"luml"}, {208, L"ETH"},
185 {209, L"Ntilde"}, {210, L"Ograve"}, {211, L"Oacute"},
186 {212, L"Ocirc"}, {213, L"Otilde"}, {214, L"Ouml"},
187 {215, L"times"}, {216, L"Oslash"}, {217, L"Ugrave"},
188 {218, L"Uacute"}, {219, L"Ucirc"}, {220, L"Uuml"},
189 {221, L"Yacute"}, {222, L"THORN"}, {223, L"szlig"},
190 {224, L"agrave"}, {225, L"aacute"}, {226, L"acirc"},
191 {227, L"atilde"}, {228, L"auml"}, {229, L"aring"},
192 {230, L"aelig"}, {231, L"ccedil"}, {232, L"egrave"},
193 {233, L"eacute"}, {234, L"ecirc"}, {235, L"euml"},
194 {236, L"igrave"}, {237, L"iacute"}, {238, L"icirc"},
195 {239, L"iuml"}, {240, L"eth"}, {241, L"ntilde"},
196 {242, L"ograve"}, {243, L"oacute"}, {244, L"ocirc"},
197 {245, L"otilde"}, {246, L"ouml"}, {247, L"divide"},
198 {248, L"oslash"}, {249, L"ugrave"}, {250, L"uacute"},
199 {251, L"ucirc"}, {252, L"uuml"}, {253, L"yacute"},
200 {254, L"thorn"}, {255, L"yuml"}, {338, L"OElig"},
201 {339, L"oelig"}, {352, L"Scaron"}, {353, L"saron"},
202 {376, L"Yuml"}, {402, L"fnof"}, {710, L"circ"},
203 {732, L"tilde"}, {913, L"Alpha"}, {914, L"Beta"},
204 {915, L"Gamma"}, {916, L"Delta"}, {917, L"Epsilon"},
205 {918, L"Zeta"}, {919, L"Eta"}, {920, L"Theta"},
206 {921, L"lota"}, {922, L"Kappa"}, {923, L"Lambda"},
207 {924, L"Mu"}, {925, L"Nu"}, {926, L"Xi"},
208 {927, L"Omicron"}, {928, L"Pi"}, {929, L"Rho"},
209 {931, L"Sigma"}, {932, L"Tau"}, {933, L"Upsilon"},
210 {934, L"Phi"}, {935, L"Chi"}, {936, L"Psi"},
211 {937, L"Omega"}, {945, L"alpha"}, {946, L"beta"},
212 {947, L"gamma"}, {948, L"delta"}, {949, L"epsilon"},
213 {950, L"zeta"}, {951, L"eta"}, {952, L"theta"},
214 {953, L"iota"}, {954, L"kappa"}, {955, L"lambda"},
215 {956, L"mu"}, {957, L"nu"}, {958, L"xi"},
216 {959, L"omicron"}, {960, L"pi"}, {961, L"rho"},
217 {962, L"sigmaf"}, {963, L"sigma"}, {964, L"tau"},
218 {965, L"upsilon"}, {966, L"phi"}, {967, L"chi"},
219 {968, L"psi"}, {969, L"omega"}, {977, L"thetasym"},
220 {978, L"upsih"}, {982, L"piv"}, {8194, L"ensp"},
221 {8195, L"emsp"}, {8201, L"thinsp"}, {8204, L"zwnj"},
222 {8205, L"zwj"}, {8206, L"lrm"}, {8207, L"rlm"},
223 {8211, L"ndash"}, {8212, L"mdash"}, {8216, L"lsquo"},
224 {8217, L"rsquo"}, {8218, L"sbquo"}, {8220, L"ldquo"},
225 {8221, L"tdquo"}, {8222, L"bdquo"}, {8224, L"dagger"},
226 {8225, L"Dagger"}, {8226, L"bull"}, {8230, L"hellip"},
227 {8240, L"permil"}, {8242, L"prime"}, {8249, L"lsaquo"},
228 {8250, L"rsaquo"}, {8254, L"oline"}, {8260, L"frasl"},
229 {8364, L"euro"}, {8465, L"image"}, {8472, L"weierp"},
230 {8476, L"real"}, {8482, L"trade"}, {8501, L"alefsym"},
231 {8592, L"larr"}, {8593, L"uarr"}, {8594, L"rarr"},
232 {8595, L"darr"}, {8596, L"harr"}, {8629, L"crarr"},
233 {8656, L"lArr"}, {8657, L"uArr"}, {8658, L"rArr"},
234 {8659, L"dArr"}, {8660, L"hArr"}, {8704, L"forall"},
235 {8706, L"part"}, {8707, L"exist"}, {8709, L"empty"},
236 {8711, L"nabla"}, {8712, L"isin"}, {8713, L"notin"},
237 {8715, L"ni"}, {8719, L"prod"}, {8721, L"sum"},
238 {8722, L"minus"}, {8727, L"lowast"}, {8730, L"radic"},
239 {8733, L"prop"}, {8734, L"infin"}, {8736, L"ang"},
240 {8743, L"and"}, {8744, L"or"}, {8745, L"cap"},
241 {8746, L"cup"}, {8747, L"int"}, {8756, L"there4"},
242 {8764, L"sim"}, {8773, L"cong"}, {8776, L"asymp"},
243 {8800, L"ne"}, {8801, L"equiv"}, {8804, L"le"},
244 {8805, L"ge"}, {8834, L"sub"}, {8835, L"sup"},
245 {8836, L"nsub"}, {8838, L"sube"}, {8839, L"supe"},
246 {8853, L"oplus"}, {8855, L"otimes"}, {8869, L"perp"},
247 {8901, L"sdot"}, {8968, L"lceil"}, {8969, L"rceil"},
248 {8970, L"lfloor"}, {8971, L"rfloor"}, {9001, L"lang"},
249 {9002, L"rang"}, {9674, L"loz"}, {9824, L"spades"},
250 {9827, L"clubs"}, {9829, L"hearts"}, {9830, L"diams"},
251};
252
tsepez1c9cfe12016-05-26 13:30:56 -0700253const FXJSE_FUNCTION_DESCRIPTOR formcalc_fm2js_functions[] = {
254 {"Abs", CXFA_FM2JSContext::Abs},
255 {"Avg", CXFA_FM2JSContext::Avg},
256 {"Ceil", CXFA_FM2JSContext::Ceil},
257 {"Count", CXFA_FM2JSContext::Count},
258 {"Floor", CXFA_FM2JSContext::Floor},
259 {"Max", CXFA_FM2JSContext::Max},
260 {"Min", CXFA_FM2JSContext::Min},
261 {"Mod", CXFA_FM2JSContext::Mod},
262 {"Round", CXFA_FM2JSContext::Round},
263 {"Sum", CXFA_FM2JSContext::Sum},
264 {"Date", CXFA_FM2JSContext::Date},
265 {"Date2Num", CXFA_FM2JSContext::Date2Num},
266 {"DateFmt", CXFA_FM2JSContext::DateFmt},
267 {"IsoDate2Num", CXFA_FM2JSContext::IsoDate2Num},
268 {"IsoTime2Num", CXFA_FM2JSContext::IsoTime2Num},
269 {"LocalDateFmt", CXFA_FM2JSContext::LocalDateFmt},
270 {"LocalTimeFmt", CXFA_FM2JSContext::LocalTimeFmt},
271 {"Num2Date", CXFA_FM2JSContext::Num2Date},
272 {"Num2GMTime", CXFA_FM2JSContext::Num2GMTime},
273 {"Num2Time", CXFA_FM2JSContext::Num2Time},
274 {"Time", CXFA_FM2JSContext::Time},
275 {"Time2Num", CXFA_FM2JSContext::Time2Num},
276 {"TimeFmt", CXFA_FM2JSContext::TimeFmt},
277 {"Apr", CXFA_FM2JSContext::Apr},
278 {"Cterm", CXFA_FM2JSContext::CTerm},
279 {"FV", CXFA_FM2JSContext::FV},
280 {"Ipmt", CXFA_FM2JSContext::IPmt},
281 {"NPV", CXFA_FM2JSContext::NPV},
282 {"Pmt", CXFA_FM2JSContext::Pmt},
283 {"PPmt", CXFA_FM2JSContext::PPmt},
284 {"PV", CXFA_FM2JSContext::PV},
285 {"Rate", CXFA_FM2JSContext::Rate},
286 {"Term", CXFA_FM2JSContext::Term},
287 {"Choose", CXFA_FM2JSContext::Choose},
288 {"Exists", CXFA_FM2JSContext::Exists},
289 {"HasValue", CXFA_FM2JSContext::HasValue},
290 {"Oneof", CXFA_FM2JSContext::Oneof},
291 {"Within", CXFA_FM2JSContext::Within},
292 {"If", CXFA_FM2JSContext::If},
293 {"Eval", CXFA_FM2JSContext::Eval},
294 {"Translate", CXFA_FM2JSContext::eval_translation},
295 {"Ref", CXFA_FM2JSContext::Ref},
296 {"UnitType", CXFA_FM2JSContext::UnitType},
297 {"UnitValue", CXFA_FM2JSContext::UnitValue},
298 {"At", CXFA_FM2JSContext::At},
299 {"Concat", CXFA_FM2JSContext::Concat},
300 {"Decode", CXFA_FM2JSContext::Decode},
301 {"Encode", CXFA_FM2JSContext::Encode},
302 {"Format", CXFA_FM2JSContext::Format},
303 {"Left", CXFA_FM2JSContext::Left},
304 {"Len", CXFA_FM2JSContext::Len},
305 {"Lower", CXFA_FM2JSContext::Lower},
306 {"Ltrim", CXFA_FM2JSContext::Ltrim},
307 {"Parse", CXFA_FM2JSContext::Parse},
308 {"Replace", CXFA_FM2JSContext::Replace},
309 {"Right", CXFA_FM2JSContext::Right},
310 {"Rtrim", CXFA_FM2JSContext::Rtrim},
311 {"Space", CXFA_FM2JSContext::Space},
312 {"Str", CXFA_FM2JSContext::Str},
313 {"Stuff", CXFA_FM2JSContext::Stuff},
314 {"Substr", CXFA_FM2JSContext::Substr},
315 {"Uuid", CXFA_FM2JSContext::Uuid},
316 {"Upper", CXFA_FM2JSContext::Upper},
317 {"WordNum", CXFA_FM2JSContext::WordNum},
318 {"Get", CXFA_FM2JSContext::Get},
319 {"Post", CXFA_FM2JSContext::Post},
320 {"Put", CXFA_FM2JSContext::Put},
321 {"positive_operator", CXFA_FM2JSContext::positive_operator},
322 {"negative_operator", CXFA_FM2JSContext::negative_operator},
323 {"logical_or_operator", CXFA_FM2JSContext::logical_or_operator},
324 {"logical_and_operator", CXFA_FM2JSContext::logical_and_operator},
325 {"logical_not_operator", CXFA_FM2JSContext::logical_not_operator},
326 {"equality_operator", CXFA_FM2JSContext::equality_operator},
327 {"notequality_operator", CXFA_FM2JSContext::notequality_operator},
328 {"less_operator", CXFA_FM2JSContext::less_operator},
329 {"lessequal_operator", CXFA_FM2JSContext::lessequal_operator},
330 {"greater_operator", CXFA_FM2JSContext::greater_operator},
331 {"greaterequal_operator", CXFA_FM2JSContext::greaterequal_operator},
332 {"plus_operator", CXFA_FM2JSContext::plus_operator},
333 {"minus_operator", CXFA_FM2JSContext::minus_operator},
334 {"multiple_operator", CXFA_FM2JSContext::multiple_operator},
335 {"divide_operator", CXFA_FM2JSContext::divide_operator},
336 {"assign_value_operator", CXFA_FM2JSContext::assign_value_operator},
337 {"dot_accessor", CXFA_FM2JSContext::dot_accessor},
338 {"dotdot_accessor", CXFA_FM2JSContext::dotdot_accessor},
339 {"concat_fm_object", CXFA_FM2JSContext::concat_fm_object},
340 {"is_fm_object", CXFA_FM2JSContext::is_fm_object},
341 {"is_fm_array", CXFA_FM2JSContext::is_fm_array},
342 {"get_fm_value", CXFA_FM2JSContext::get_fm_value},
343 {"get_fm_jsobj", CXFA_FM2JSContext::get_fm_jsobj},
344 {"fm_var_filter", CXFA_FM2JSContext::fm_var_filter},
345};
346
347const FXJSE_CLASS_DESCRIPTOR formcalc_fm2js_descriptor = {
348 "XFA_FM2JS_FormCalcClass", // name
349 nullptr, // constructor
350 nullptr, // properties
351 formcalc_fm2js_functions, // methods
352 0, // number of properties
353 FX_ArraySize(formcalc_fm2js_functions), // number of methods
354 nullptr, // dynamic prop type
355 nullptr, // dynamic prop getter
356 nullptr, // dynamic prop setter
357 nullptr, // dynamic prop deleter
358 nullptr, // dynamic prop method call
359};
360
dsinclair0c268e92016-05-17 14:04:14 -0700361const uint8_t g_sAltTable_Date[] = {
ochangf6be1452016-06-01 12:20:03 -0700362 255, 255, 255, 3, 9, 255, 255, 255, 255, 255, 255,
363 255, 2, 255, 255, 255, 255, 255, 255, 255, 255, 255,
364 255, 255, 1, 255, 255, 255, 255, 255, 255, 255, 255,
dsinclair0c268e92016-05-17 14:04:14 -0700365};
ochangf6be1452016-06-01 12:20:03 -0700366static_assert(FX_ArraySize(g_sAltTable_Date) == L'a' - L'A' + 1,
367 "Invalid g_sAltTable_Date size.");
dsinclair0c268e92016-05-17 14:04:14 -0700368
369const uint8_t g_sAltTable_Time[] = {
ochangf6be1452016-06-01 12:20:03 -0700370 14, 255, 255, 3, 9, 255, 255, 15, 255, 255, 255,
371 255, 6, 255, 255, 255, 255, 255, 7, 255, 255, 255,
372 255, 255, 1, 17, 255, 255, 255, 255, 255, 255, 255,
dsinclair0c268e92016-05-17 14:04:14 -0700373};
ochangf6be1452016-06-01 12:20:03 -0700374static_assert(FX_ArraySize(g_sAltTable_Time) == L'a' - L'A' + 1,
375 "Invalid g_sAltTable_Time size.");
dsinclair0c268e92016-05-17 14:04:14 -0700376
377void AlternateDateTimeSymbols(CFX_WideString& wsPattern,
378 const CFX_WideString& wsAltSymbols,
379 const uint8_t* pAltTable) {
380 int32_t nLength = wsPattern.GetLength();
381 FX_BOOL bInConstRange = FALSE;
382 FX_BOOL bEscape = FALSE;
ochangf6be1452016-06-01 12:20:03 -0700383 int32_t i = 0;
dsinclair0c268e92016-05-17 14:04:14 -0700384 while (i < nLength) {
385 FX_WCHAR wc = wsPattern[i];
386 if (wc == L'\'') {
387 bInConstRange = !bInConstRange;
388 if (bEscape) {
389 i++;
390 } else {
391 wsPattern.Delete(i);
392 nLength--;
393 }
394 bEscape = !bEscape;
395 continue;
396 }
ochangf6be1452016-06-01 12:20:03 -0700397 if (!bInConstRange && wc >= L'A' && wc <= L'a') {
398 uint8_t nAlt = pAltTable[wc - L'A'];
dsinclair48d91dd2016-05-31 11:54:01 -0700399 if (nAlt != 255)
dsinclair0c268e92016-05-17 14:04:14 -0700400 wsPattern.SetAt(i, wsAltSymbols[nAlt]);
dsinclair0c268e92016-05-17 14:04:14 -0700401 }
402 i++;
403 bEscape = FALSE;
404 }
405}
406
dsinclair48d91dd2016-05-31 11:54:01 -0700407bool PatternStringType(const CFX_ByteStringC& szPattern,
408 uint32_t& patternType) {
409 CFX_WideString wsPattern = CFX_WideString::FromUTF8(szPattern);
410 if (FX_WSTRC(L"datetime") == wsPattern.Left(8)) {
411 patternType = XFA_VT_DATETIME;
412 return true;
413 }
414 if (FX_WSTRC(L"date") == wsPattern.Left(4)) {
415 patternType = wsPattern.Find(L"time") > 0 ? XFA_VT_DATETIME : XFA_VT_DATE;
416 return true;
417 }
418 if (FX_WSTRC(L"time") == wsPattern.Left(4)) {
419 patternType = XFA_VT_TIME;
420 return true;
421 }
422 if (FX_WSTRC(L"text") == wsPattern.Left(4)) {
423 patternType = XFA_VT_TEXT;
424 return true;
425 }
426 if (FX_WSTRC(L"num") == wsPattern.Left(3)) {
427 if (FX_WSTRC(L"integer") == wsPattern.Mid(4, 7)) {
428 patternType = XFA_VT_INTEGER;
429 } else if (FX_WSTRC(L"decimal") == wsPattern.Mid(4, 7)) {
430 patternType = XFA_VT_DECIMAL;
431 } else if (FX_WSTRC(L"currency") == wsPattern.Mid(4, 8)) {
432 patternType = XFA_VT_FLOAT;
433 } else if (FX_WSTRC(L"percent") == wsPattern.Mid(4, 7)) {
434 patternType = XFA_VT_FLOAT;
435 } else {
436 patternType = XFA_VT_FLOAT;
437 }
438 return true;
439 }
440
441 patternType = XFA_VT_NULL;
442 wsPattern.MakeLower();
443 const FX_WCHAR* pData = wsPattern.c_str();
444 int32_t iLength = wsPattern.GetLength();
445 int32_t iIndex = 0;
446 FX_BOOL bSingleQuotation = FALSE;
447 FX_WCHAR patternChar;
448 while (iIndex < iLength) {
449 patternChar = *(pData + iIndex);
450 if (patternChar == 0x27) {
451 bSingleQuotation = !bSingleQuotation;
452 } else if (!bSingleQuotation &&
453 (patternChar == 'y' || patternChar == 'j')) {
454 patternType = XFA_VT_DATE;
455 iIndex++;
456 FX_WCHAR timePatternChar;
457 while (iIndex < iLength) {
458 timePatternChar = *(pData + iIndex);
459 if (timePatternChar == 0x27) {
460 bSingleQuotation = !bSingleQuotation;
461 } else if (!bSingleQuotation && timePatternChar == 't') {
462 patternType = XFA_VT_DATETIME;
463 break;
464 }
465 iIndex++;
466 }
467 break;
468 } else if (!bSingleQuotation &&
469 (patternChar == 'h' || patternChar == 'k')) {
470 patternType = XFA_VT_TIME;
471 break;
472 } else if (!bSingleQuotation &&
473 (patternChar == 'a' || patternChar == 'x' ||
474 patternChar == 'o' || patternChar == '0')) {
475 patternType = XFA_VT_TEXT;
476 if (patternChar == 'x' || patternChar == 'o' || patternChar == '0') {
477 break;
478 }
479 } else if (!bSingleQuotation &&
480 (patternChar == 'z' || patternChar == 's' ||
481 patternChar == 'e' || patternChar == 'v' ||
482 patternChar == '8' || patternChar == ',' ||
483 patternChar == '.' || patternChar == '$')) {
484 patternType = XFA_VT_FLOAT;
485 if (patternChar == 'v' || patternChar == '8' || patternChar == '$') {
486 break;
487 }
488 }
489 iIndex++;
490 }
491 if (patternType == XFA_VT_NULL) {
492 patternType = XFA_VT_TEXT | XFA_VT_FLOAT;
493 }
494 return false;
495}
496
Dan Sinclair1770c022016-03-14 14:14:16 -0400497} // namespace
498
dsinclair48d91dd2016-05-31 11:54:01 -0700499// static
dsinclair12a6b0c2016-05-26 11:14:08 -0700500void CXFA_FM2JSContext::Abs(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -0400501 const CFX_ByteStringC& szFuncName,
502 CFXJSE_Arguments& args) {
dsinclair89ba6de2016-05-31 12:11:22 -0700503 if (args.GetLength() != 1) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400504 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -0700505 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair2235b7b2016-06-02 07:42:25 -0700506 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Abs");
dsinclair89ba6de2016-05-31 12:11:22 -0700507 return;
Dan Sinclair1770c022016-03-14 14:14:16 -0400508 }
dsinclair89ba6de2016-05-31 12:11:22 -0700509
510 std::unique_ptr<CFXJSE_Value> argOne = args.GetValue(0);
511 if (ValueIsNull(pThis, argOne.get())) {
512 FXJSE_Value_SetNull(args.GetReturnValue());
513 return;
514 }
515
516 FX_DOUBLE dValue = ValueToDouble(pThis, argOne.get());
517 if (dValue < 0)
518 dValue = -dValue;
519
520 FXJSE_Value_SetDouble(args.GetReturnValue(), dValue);
Dan Sinclair1770c022016-03-14 14:14:16 -0400521}
dsinclair48d91dd2016-05-31 11:54:01 -0700522
523// static
dsinclair12a6b0c2016-05-26 11:14:08 -0700524void CXFA_FM2JSContext::Avg(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -0400525 const CFX_ByteStringC& szFuncName,
526 CFXJSE_Arguments& args) {
dsinclair89ba6de2016-05-31 12:11:22 -0700527 int32_t argc = args.GetLength();
528 if (argc < 1) {
529 FXJSE_Value_SetNull(args.GetReturnValue());
530 return;
531 }
532
dsinclairdd6a46c2016-05-26 08:41:45 -0700533 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -0700534 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclairec3da5b2016-05-25 16:42:05 -0700535 v8::Isolate* pIsolate = pContext->GetScriptRuntime();
Dan Sinclair1770c022016-03-14 14:14:16 -0400536 uint32_t uCount = 0;
537 FX_DOUBLE dSum = 0.0;
dsinclair89ba6de2016-05-31 12:11:22 -0700538 for (int32_t i = 0; i < argc; i++) {
539 std::unique_ptr<CFXJSE_Value> argValue = args.GetValue(i);
540 if (FXJSE_Value_IsNull(argValue.get()))
541 continue;
dsinclair86fad992016-05-31 11:34:04 -0700542
dsinclair89ba6de2016-05-31 12:11:22 -0700543 if (!FXJSE_Value_IsArray(argValue.get())) {
544 dSum += ValueToDouble(pThis, argValue.get());
545 uCount++;
546 continue;
547 }
548
549 std::unique_ptr<CFXJSE_Value> lengthValue(new CFXJSE_Value(pIsolate));
550 FXJSE_Value_GetObjectProp(argValue.get(), "length", lengthValue.get());
551 int32_t iLength = FXJSE_Value_ToInteger(lengthValue.get());
552
553 if (iLength > 2) {
554 std::unique_ptr<CFXJSE_Value> propertyValue(new CFXJSE_Value(pIsolate));
555 FXJSE_Value_GetObjectPropByIdx(argValue.get(), 1, propertyValue.get());
556
557 std::unique_ptr<CFXJSE_Value> jsObjectValue(new CFXJSE_Value(pIsolate));
558 if (FXJSE_Value_IsNull(propertyValue.get())) {
559 for (int32_t j = 2; j < iLength; j++) {
560 FXJSE_Value_GetObjectPropByIdx(argValue.get(), j,
561 jsObjectValue.get());
562 std::unique_ptr<CFXJSE_Value> defaultPropValue(
dsinclair86fad992016-05-31 11:34:04 -0700563 new CFXJSE_Value(pIsolate));
dsinclair89ba6de2016-05-31 12:11:22 -0700564 GetObjectDefaultValue(jsObjectValue.get(), defaultPropValue.get());
565 if (FXJSE_Value_IsNull(defaultPropValue.get()))
566 continue;
567
568 dSum += ValueToDouble(pThis, defaultPropValue.get());
569 uCount++;
Dan Sinclair1770c022016-03-14 14:14:16 -0400570 }
571 } else {
dsinclair89ba6de2016-05-31 12:11:22 -0700572 CFX_ByteString propertyStr;
573 FXJSE_Value_ToUTF8String(propertyValue.get(), propertyStr);
574 for (int32_t j = 2; j < iLength; j++) {
575 FXJSE_Value_GetObjectPropByIdx(argValue.get(), j,
576 jsObjectValue.get());
577 std::unique_ptr<CFXJSE_Value> newPropertyValue(
578 new CFXJSE_Value(pIsolate));
579 FXJSE_Value_GetObjectProp(jsObjectValue.get(),
580 propertyStr.AsStringC(),
581 newPropertyValue.get());
582 if (FXJSE_Value_IsNull(newPropertyValue.get()))
583 continue;
584
585 dSum += ValueToDouble(pThis, newPropertyValue.get());
586 uCount++;
587 }
Dan Sinclair1770c022016-03-14 14:14:16 -0400588 }
Dan Sinclair1770c022016-03-14 14:14:16 -0400589 }
Dan Sinclair1770c022016-03-14 14:14:16 -0400590 }
dsinclair89ba6de2016-05-31 12:11:22 -0700591 if (uCount == 0) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400592 FXJSE_Value_SetNull(args.GetReturnValue());
dsinclair89ba6de2016-05-31 12:11:22 -0700593 return;
Dan Sinclair1770c022016-03-14 14:14:16 -0400594 }
dsinclair89ba6de2016-05-31 12:11:22 -0700595
596 FXJSE_Value_SetDouble(args.GetReturnValue(), dSum / uCount);
Dan Sinclair1770c022016-03-14 14:14:16 -0400597}
dsinclair48d91dd2016-05-31 11:54:01 -0700598
599// static
dsinclair12a6b0c2016-05-26 11:14:08 -0700600void CXFA_FM2JSContext::Ceil(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -0400601 const CFX_ByteStringC& szFuncName,
602 CFXJSE_Arguments& args) {
dsinclair89ba6de2016-05-31 12:11:22 -0700603 if (args.GetLength() != 1) {
dsinclair48d91dd2016-05-31 11:54:01 -0700604 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -0700605 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair2235b7b2016-06-02 07:42:25 -0700606 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Ceil");
dsinclair89ba6de2016-05-31 12:11:22 -0700607 return;
Dan Sinclair1770c022016-03-14 14:14:16 -0400608 }
dsinclair89ba6de2016-05-31 12:11:22 -0700609
610 std::unique_ptr<CFXJSE_Value> argValue = GetSimpleValue(pThis, args, 0);
611 if (ValueIsNull(pThis, argValue.get())) {
612 FXJSE_Value_SetNull(args.GetReturnValue());
613 return;
614 }
615
616 FXJSE_Value_SetFloat(args.GetReturnValue(),
617 FXSYS_ceil(ValueToFloat(pThis, argValue.get())));
Dan Sinclair1770c022016-03-14 14:14:16 -0400618}
dsinclair48d91dd2016-05-31 11:54:01 -0700619
620// static
dsinclair12a6b0c2016-05-26 11:14:08 -0700621void CXFA_FM2JSContext::Count(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -0400622 const CFX_ByteStringC& szFuncName,
623 CFXJSE_Arguments& args) {
dsinclairdd6a46c2016-05-26 08:41:45 -0700624 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -0700625 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclairec3da5b2016-05-25 16:42:05 -0700626 v8::Isolate* pIsolate = pContext->GetScriptRuntime();
dsinclair89ba6de2016-05-31 12:11:22 -0700627 int32_t iCount = 0;
dsinclair48d91dd2016-05-31 11:54:01 -0700628 for (int32_t i = 0; i < args.GetLength(); i++) {
dsinclair86fad992016-05-31 11:34:04 -0700629 std::unique_ptr<CFXJSE_Value> argValue = args.GetValue(i);
dsinclair89ba6de2016-05-31 12:11:22 -0700630 if (FXJSE_Value_IsNull(argValue.get()))
Dan Sinclair1770c022016-03-14 14:14:16 -0400631 continue;
dsinclair89ba6de2016-05-31 12:11:22 -0700632
633 if (FXJSE_Value_IsArray(argValue.get())) {
dsinclair86fad992016-05-31 11:34:04 -0700634 std::unique_ptr<CFXJSE_Value> lengthValue(new CFXJSE_Value(pIsolate));
635 FXJSE_Value_GetObjectProp(argValue.get(), "length", lengthValue.get());
dsinclair86fad992016-05-31 11:34:04 -0700636
dsinclair89ba6de2016-05-31 12:11:22 -0700637 int32_t iLength = FXJSE_Value_ToInteger(lengthValue.get());
638 if (iLength <= 2) {
dsinclair2235b7b2016-06-02 07:42:25 -0700639 pContext->ThrowException(XFA_IDS_ARGUMENT_MISMATCH);
dsinclair89ba6de2016-05-31 12:11:22 -0700640 return;
641 }
642
643 std::unique_ptr<CFXJSE_Value> propertyValue(new CFXJSE_Value(pIsolate));
644 std::unique_ptr<CFXJSE_Value> jsObjectValue(new CFXJSE_Value(pIsolate));
645 std::unique_ptr<CFXJSE_Value> newPropertyValue(
646 new CFXJSE_Value(pIsolate));
647 FXJSE_Value_GetObjectPropByIdx(argValue.get(), 1, propertyValue.get());
648 FXJSE_Value_GetObjectPropByIdx(argValue.get(), 2, jsObjectValue.get());
649 if (FXJSE_Value_IsNull(propertyValue.get())) {
650 for (int32_t i = 2; i < iLength; i++) {
651 FXJSE_Value_GetObjectPropByIdx(argValue.get(), i,
652 jsObjectValue.get());
653 GetObjectDefaultValue(jsObjectValue.get(), newPropertyValue.get());
654 if (!FXJSE_Value_IsNull(newPropertyValue.get()))
655 iCount++;
Dan Sinclair1770c022016-03-14 14:14:16 -0400656 }
Dan Sinclair1770c022016-03-14 14:14:16 -0400657 } else {
dsinclair89ba6de2016-05-31 12:11:22 -0700658 CFX_ByteString propertyStr;
659 FXJSE_Value_ToUTF8String(propertyValue.get(), propertyStr);
660 for (int32_t i = 2; i < iLength; i++) {
661 FXJSE_Value_GetObjectPropByIdx(argValue.get(), i,
662 jsObjectValue.get());
663 FXJSE_Value_GetObjectProp(jsObjectValue.get(),
664 propertyStr.AsStringC(),
665 newPropertyValue.get());
666 iCount += (FXJSE_Value_IsNull(newPropertyValue.get()) ? 0 : 1);
667 }
Dan Sinclair1770c022016-03-14 14:14:16 -0400668 }
dsinclair86fad992016-05-31 11:34:04 -0700669 } else if (FXJSE_Value_IsObject(argValue.get())) {
670 std::unique_ptr<CFXJSE_Value> newPropertyValue(
671 new CFXJSE_Value(pIsolate));
672 GetObjectDefaultValue(argValue.get(), newPropertyValue.get());
dsinclair89ba6de2016-05-31 12:11:22 -0700673 if (!FXJSE_Value_IsNull(newPropertyValue.get()))
674 iCount++;
Dan Sinclair1770c022016-03-14 14:14:16 -0400675 } else {
dsinclair89ba6de2016-05-31 12:11:22 -0700676 iCount++;
Dan Sinclair1770c022016-03-14 14:14:16 -0400677 }
Dan Sinclair1770c022016-03-14 14:14:16 -0400678 }
dsinclair89ba6de2016-05-31 12:11:22 -0700679 FXJSE_Value_SetInteger(args.GetReturnValue(), iCount);
Dan Sinclair1770c022016-03-14 14:14:16 -0400680}
dsinclair48d91dd2016-05-31 11:54:01 -0700681
682// static
dsinclair12a6b0c2016-05-26 11:14:08 -0700683void CXFA_FM2JSContext::Floor(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -0400684 const CFX_ByteStringC& szFuncName,
685 CFXJSE_Arguments& args) {
dsinclair89ba6de2016-05-31 12:11:22 -0700686 if (args.GetLength() != 1) {
dsinclair48d91dd2016-05-31 11:54:01 -0700687 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -0700688 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair2235b7b2016-06-02 07:42:25 -0700689 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Floor");
dsinclair89ba6de2016-05-31 12:11:22 -0700690 return;
Dan Sinclair1770c022016-03-14 14:14:16 -0400691 }
dsinclair89ba6de2016-05-31 12:11:22 -0700692
693 std::unique_ptr<CFXJSE_Value> argValue = GetSimpleValue(pThis, args, 0);
694 if (ValueIsNull(pThis, argValue.get())) {
695 FXJSE_Value_SetNull(args.GetReturnValue());
696 return;
697 }
698
699 FXJSE_Value_SetFloat(args.GetReturnValue(),
700 FXSYS_floor(ValueToFloat(pThis, argValue.get())));
Dan Sinclair1770c022016-03-14 14:14:16 -0400701}
dsinclair48d91dd2016-05-31 11:54:01 -0700702
703// static
dsinclair12a6b0c2016-05-26 11:14:08 -0700704void CXFA_FM2JSContext::Max(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -0400705 const CFX_ByteStringC& szFuncName,
706 CFXJSE_Arguments& args) {
dsinclairdd6a46c2016-05-26 08:41:45 -0700707 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -0700708 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclairec3da5b2016-05-25 16:42:05 -0700709 v8::Isolate* pIsolate = pContext->GetScriptRuntime();
Dan Sinclair1770c022016-03-14 14:14:16 -0400710 uint32_t uCount = 0;
711 FX_DOUBLE dMaxValue = 0.0;
dsinclair48d91dd2016-05-31 11:54:01 -0700712 for (int32_t i = 0; i < args.GetLength(); i++) {
dsinclair86fad992016-05-31 11:34:04 -0700713 std::unique_ptr<CFXJSE_Value> argValue = args.GetValue(i);
dsinclair89ba6de2016-05-31 12:11:22 -0700714 if (FXJSE_Value_IsNull(argValue.get()))
Dan Sinclair1770c022016-03-14 14:14:16 -0400715 continue;
dsinclair89ba6de2016-05-31 12:11:22 -0700716
717 if (FXJSE_Value_IsArray(argValue.get())) {
dsinclair86fad992016-05-31 11:34:04 -0700718 std::unique_ptr<CFXJSE_Value> lengthValue(new CFXJSE_Value(pIsolate));
719 FXJSE_Value_GetObjectProp(argValue.get(), "length", lengthValue.get());
720 int32_t iLength = FXJSE_Value_ToInteger(lengthValue.get());
dsinclair89ba6de2016-05-31 12:11:22 -0700721 if (iLength <= 2) {
dsinclair2235b7b2016-06-02 07:42:25 -0700722 pContext->ThrowException(XFA_IDS_ARGUMENT_MISMATCH);
dsinclair89ba6de2016-05-31 12:11:22 -0700723 return;
724 }
dsinclair86fad992016-05-31 11:34:04 -0700725
dsinclair89ba6de2016-05-31 12:11:22 -0700726 std::unique_ptr<CFXJSE_Value> propertyValue(new CFXJSE_Value(pIsolate));
727 std::unique_ptr<CFXJSE_Value> jsObjectValue(new CFXJSE_Value(pIsolate));
728 std::unique_ptr<CFXJSE_Value> newPropertyValue(
729 new CFXJSE_Value(pIsolate));
730 FXJSE_Value_GetObjectPropByIdx(argValue.get(), 1, propertyValue.get());
731 FXJSE_Value_GetObjectPropByIdx(argValue.get(), 2, jsObjectValue.get());
732 if (FXJSE_Value_IsNull(propertyValue.get())) {
733 for (int32_t i = 2; i < iLength; i++) {
734 FXJSE_Value_GetObjectPropByIdx(argValue.get(), i,
735 jsObjectValue.get());
736 GetObjectDefaultValue(jsObjectValue.get(), newPropertyValue.get());
737 if (FXJSE_Value_IsNull(newPropertyValue.get()))
738 continue;
739
740 uCount++;
741 FX_DOUBLE dValue = ValueToDouble(pThis, newPropertyValue.get());
742 dMaxValue = (uCount == 1) ? dValue : std::max(dMaxValue, dValue);
Dan Sinclair1770c022016-03-14 14:14:16 -0400743 }
Dan Sinclair1770c022016-03-14 14:14:16 -0400744 } else {
dsinclair89ba6de2016-05-31 12:11:22 -0700745 CFX_ByteString propertyStr;
746 FXJSE_Value_ToUTF8String(propertyValue.get(), propertyStr);
747 for (int32_t i = 2; i < iLength; i++) {
748 FXJSE_Value_GetObjectPropByIdx(argValue.get(), i,
749 jsObjectValue.get());
750 FXJSE_Value_GetObjectProp(jsObjectValue.get(),
751 propertyStr.AsStringC(),
752 newPropertyValue.get());
753 if (FXJSE_Value_IsNull(newPropertyValue.get()))
754 continue;
755
756 uCount++;
757 FX_DOUBLE dValue = ValueToDouble(pThis, newPropertyValue.get());
758 dMaxValue = (uCount == 1) ? dValue : std::max(dMaxValue, dValue);
759 }
Dan Sinclair1770c022016-03-14 14:14:16 -0400760 }
dsinclair86fad992016-05-31 11:34:04 -0700761 } else if (FXJSE_Value_IsObject(argValue.get())) {
762 std::unique_ptr<CFXJSE_Value> newPropertyValue(
763 new CFXJSE_Value(pIsolate));
764 GetObjectDefaultValue(argValue.get(), newPropertyValue.get());
dsinclair89ba6de2016-05-31 12:11:22 -0700765 if (FXJSE_Value_IsNull(newPropertyValue.get()))
766 continue;
767
768 uCount++;
769 FX_DOUBLE dValue = ValueToDouble(pThis, newPropertyValue.get());
770 dMaxValue = (uCount == 1) ? dValue : std::max(dMaxValue, dValue);
Dan Sinclair1770c022016-03-14 14:14:16 -0400771 } else {
772 uCount++;
dsinclair89ba6de2016-05-31 12:11:22 -0700773 FX_DOUBLE dValue = ValueToDouble(pThis, argValue.get());
774 dMaxValue = (uCount == 1) ? dValue : std::max(dMaxValue, dValue);
Dan Sinclair1770c022016-03-14 14:14:16 -0400775 }
Dan Sinclair1770c022016-03-14 14:14:16 -0400776 }
dsinclair89ba6de2016-05-31 12:11:22 -0700777 if (uCount == 0) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400778 FXJSE_Value_SetNull(args.GetReturnValue());
dsinclair89ba6de2016-05-31 12:11:22 -0700779 return;
Dan Sinclair1770c022016-03-14 14:14:16 -0400780 }
dsinclair89ba6de2016-05-31 12:11:22 -0700781
782 FXJSE_Value_SetDouble(args.GetReturnValue(), dMaxValue);
Dan Sinclair1770c022016-03-14 14:14:16 -0400783}
dsinclair48d91dd2016-05-31 11:54:01 -0700784
785// static
dsinclair12a6b0c2016-05-26 11:14:08 -0700786void CXFA_FM2JSContext::Min(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -0400787 const CFX_ByteStringC& szFuncName,
788 CFXJSE_Arguments& args) {
dsinclairdd6a46c2016-05-26 08:41:45 -0700789 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -0700790 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclairec3da5b2016-05-25 16:42:05 -0700791 v8::Isolate* pIsolate = pContext->GetScriptRuntime();
Dan Sinclair1770c022016-03-14 14:14:16 -0400792 uint32_t uCount = 0;
793 FX_DOUBLE dMinValue = 0.0;
dsinclair48d91dd2016-05-31 11:54:01 -0700794 for (int32_t i = 0; i < args.GetLength(); i++) {
dsinclair86fad992016-05-31 11:34:04 -0700795 std::unique_ptr<CFXJSE_Value> argValue = args.GetValue(i);
dsinclairdbdcb812016-06-01 20:07:22 -0700796 if (FXJSE_Value_IsNull(argValue.get()))
Dan Sinclair1770c022016-03-14 14:14:16 -0400797 continue;
dsinclairdbdcb812016-06-01 20:07:22 -0700798
799 if (FXJSE_Value_IsArray(argValue.get())) {
dsinclair86fad992016-05-31 11:34:04 -0700800 std::unique_ptr<CFXJSE_Value> lengthValue(new CFXJSE_Value(pIsolate));
801 FXJSE_Value_GetObjectProp(argValue.get(), "length", lengthValue.get());
802 int32_t iLength = FXJSE_Value_ToInteger(lengthValue.get());
dsinclairdbdcb812016-06-01 20:07:22 -0700803 if (iLength <= 2) {
dsinclair2235b7b2016-06-02 07:42:25 -0700804 pContext->ThrowException(XFA_IDS_ARGUMENT_MISMATCH);
dsinclairdbdcb812016-06-01 20:07:22 -0700805 return;
806 }
807
808 std::unique_ptr<CFXJSE_Value> propertyValue(new CFXJSE_Value(pIsolate));
809 std::unique_ptr<CFXJSE_Value> jsObjectValue(new CFXJSE_Value(pIsolate));
810 std::unique_ptr<CFXJSE_Value> newPropertyValue(
811 new CFXJSE_Value(pIsolate));
812 FXJSE_Value_GetObjectPropByIdx(argValue.get(), 1, propertyValue.get());
813 FXJSE_Value_GetObjectPropByIdx(argValue.get(), 2, jsObjectValue.get());
814 if (FXJSE_Value_IsNull(propertyValue.get())) {
815 for (int32_t i = 2; i < iLength; i++) {
816 FXJSE_Value_GetObjectPropByIdx(argValue.get(), i,
817 jsObjectValue.get());
818 GetObjectDefaultValue(jsObjectValue.get(), newPropertyValue.get());
819 if (FXJSE_Value_IsNull(newPropertyValue.get()))
820 continue;
821
822 uCount++;
823 FX_DOUBLE dValue = ValueToDouble(pThis, newPropertyValue.get());
824 dMinValue = uCount == 1 ? dValue : std::min(dMinValue, dValue);
Dan Sinclair1770c022016-03-14 14:14:16 -0400825 }
Dan Sinclair1770c022016-03-14 14:14:16 -0400826 } else {
dsinclairdbdcb812016-06-01 20:07:22 -0700827 CFX_ByteString propertyStr;
828 FXJSE_Value_ToUTF8String(propertyValue.get(), propertyStr);
829 for (int32_t i = 2; i < iLength; i++) {
830 FXJSE_Value_GetObjectPropByIdx(argValue.get(), i,
831 jsObjectValue.get());
832 FXJSE_Value_GetObjectProp(jsObjectValue.get(),
833 propertyStr.AsStringC(),
834 newPropertyValue.get());
835 if (FXJSE_Value_IsNull(newPropertyValue.get()))
836 continue;
837
838 uCount++;
839 FX_DOUBLE dValue = ValueToDouble(pThis, newPropertyValue.get());
840 dMinValue = uCount == 1 ? dValue : std::min(dMinValue, dValue);
841 }
Dan Sinclair1770c022016-03-14 14:14:16 -0400842 }
dsinclair86fad992016-05-31 11:34:04 -0700843 } else if (FXJSE_Value_IsObject(argValue.get())) {
844 std::unique_ptr<CFXJSE_Value> newPropertyValue(
845 new CFXJSE_Value(pIsolate));
846 GetObjectDefaultValue(argValue.get(), newPropertyValue.get());
dsinclairdbdcb812016-06-01 20:07:22 -0700847 if (FXJSE_Value_IsNull(newPropertyValue.get()))
848 continue;
849
850 uCount++;
851 FX_DOUBLE dValue = ValueToDouble(pThis, newPropertyValue.get());
852 dMinValue = uCount == 1 ? dValue : std::min(dMinValue, dValue);
Dan Sinclair1770c022016-03-14 14:14:16 -0400853 } else {
854 uCount++;
dsinclairdbdcb812016-06-01 20:07:22 -0700855 FX_DOUBLE dValue = ValueToDouble(pThis, argValue.get());
856 dMinValue = uCount == 1 ? dValue : std::min(dMinValue, dValue);
Dan Sinclair1770c022016-03-14 14:14:16 -0400857 }
Dan Sinclair1770c022016-03-14 14:14:16 -0400858 }
dsinclairdbdcb812016-06-01 20:07:22 -0700859 if (uCount == 0) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400860 FXJSE_Value_SetNull(args.GetReturnValue());
dsinclairdbdcb812016-06-01 20:07:22 -0700861 return;
Dan Sinclair1770c022016-03-14 14:14:16 -0400862 }
dsinclairdbdcb812016-06-01 20:07:22 -0700863
864 FXJSE_Value_SetDouble(args.GetReturnValue(), dMinValue);
Dan Sinclair1770c022016-03-14 14:14:16 -0400865}
dsinclair48d91dd2016-05-31 11:54:01 -0700866
867// static
dsinclair12a6b0c2016-05-26 11:14:08 -0700868void CXFA_FM2JSContext::Mod(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -0400869 const CFX_ByteStringC& szFuncName,
870 CFXJSE_Arguments& args) {
dsinclairdd6a46c2016-05-26 08:41:45 -0700871 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -0700872 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclairdbdcb812016-06-01 20:07:22 -0700873 if (args.GetLength() != 2) {
dsinclair2235b7b2016-06-02 07:42:25 -0700874 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Mod");
dsinclairdbdcb812016-06-01 20:07:22 -0700875 return;
Dan Sinclair1770c022016-03-14 14:14:16 -0400876 }
dsinclairdbdcb812016-06-01 20:07:22 -0700877
878 std::unique_ptr<CFXJSE_Value> argOne = args.GetValue(0);
879 std::unique_ptr<CFXJSE_Value> argTwo = args.GetValue(1);
880 if (FXJSE_Value_IsNull(argOne.get()) || FXJSE_Value_IsNull(argTwo.get())) {
881 FXJSE_Value_SetNull(args.GetReturnValue());
882 return;
883 }
884
885 bool argOneResult;
886 FX_DOUBLE dDividend = ExtractDouble(pThis, argOne.get(), &argOneResult);
887 bool argTwoResult;
888 FX_DOUBLE dDivisor = ExtractDouble(pThis, argTwo.get(), &argTwoResult);
889 if (!argOneResult || !argTwoResult) {
dsinclair2235b7b2016-06-02 07:42:25 -0700890 pContext->ThrowException(XFA_IDS_ARGUMENT_MISMATCH);
dsinclairdbdcb812016-06-01 20:07:22 -0700891 return;
892 }
893
894 if (dDivisor == 0.0) {
dsinclair2235b7b2016-06-02 07:42:25 -0700895 pContext->ThrowException(XFA_IDS_DIVIDE_ZERO);
dsinclairdbdcb812016-06-01 20:07:22 -0700896 return;
897 }
898
899 FXJSE_Value_SetDouble(args.GetReturnValue(),
900 dDividend - dDivisor * (int32_t)(dDividend / dDivisor));
Dan Sinclair1770c022016-03-14 14:14:16 -0400901}
dsinclair48d91dd2016-05-31 11:54:01 -0700902
903// static
dsinclair12a6b0c2016-05-26 11:14:08 -0700904void CXFA_FM2JSContext::Round(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -0400905 const CFX_ByteStringC& szFuncName,
906 CFXJSE_Arguments& args) {
dsinclairdd6a46c2016-05-26 08:41:45 -0700907 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -0700908 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
Dan Sinclair1770c022016-03-14 14:14:16 -0400909 int32_t argc = args.GetLength();
dsinclairdbdcb812016-06-01 20:07:22 -0700910 if (argc != 1 && argc != 2) {
dsinclair2235b7b2016-06-02 07:42:25 -0700911 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Round");
dsinclairdbdcb812016-06-01 20:07:22 -0700912 return;
Dan Sinclair1770c022016-03-14 14:14:16 -0400913 }
dsinclairdbdcb812016-06-01 20:07:22 -0700914
915 std::unique_ptr<CFXJSE_Value> argOne = args.GetValue(0);
916 if (FXJSE_Value_IsNull(argOne.get())) {
917 FXJSE_Value_SetNull(args.GetReturnValue());
918 return;
919 }
920
921 bool dValueRet;
922 FX_DOUBLE dValue = ExtractDouble(pThis, argOne.get(), &dValueRet);
923 if (!dValueRet) {
dsinclair2235b7b2016-06-02 07:42:25 -0700924 pContext->ThrowException(XFA_IDS_ARGUMENT_MISMATCH);
dsinclairdbdcb812016-06-01 20:07:22 -0700925 return;
926 }
927
928 uint8_t uPrecision = 0;
929 if (argc == 2) {
930 std::unique_ptr<CFXJSE_Value> argTwo = args.GetValue(1);
931 if (FXJSE_Value_IsNull(argTwo.get())) {
932 FXJSE_Value_SetNull(args.GetReturnValue());
933 return;
934 }
935
936 bool dPrecisionRet;
937 FX_DOUBLE dPrecision = ExtractDouble(pThis, argTwo.get(), &dPrecisionRet);
938 if (!dPrecisionRet) {
dsinclair2235b7b2016-06-02 07:42:25 -0700939 pContext->ThrowException(XFA_IDS_ARGUMENT_MISMATCH);
dsinclairdbdcb812016-06-01 20:07:22 -0700940 return;
941 }
942
943 uPrecision =
944 static_cast<uint8_t>(std::min(std::max(dPrecision, 0.0), 12.0));
945 }
946
947 CFX_Decimal decimalValue((FX_FLOAT)dValue, uPrecision);
948 CFX_WideString wsValue = decimalValue;
949 FXJSE_Value_SetUTF8String(args.GetReturnValue(),
950 wsValue.UTF8Encode().AsStringC());
Dan Sinclair1770c022016-03-14 14:14:16 -0400951}
dsinclair48d91dd2016-05-31 11:54:01 -0700952
953// static
dsinclair12a6b0c2016-05-26 11:14:08 -0700954void CXFA_FM2JSContext::Sum(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -0400955 const CFX_ByteStringC& szFuncName,
956 CFXJSE_Arguments& args) {
dsinclairdbdcb812016-06-01 20:07:22 -0700957 int32_t argc = args.GetLength();
958 if (argc == 0) {
959 FXJSE_Value_SetNull(args.GetReturnValue());
960 return;
961 }
962
dsinclairdd6a46c2016-05-26 08:41:45 -0700963 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -0700964 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclairec3da5b2016-05-25 16:42:05 -0700965 v8::Isolate* pIsolate = pContext->GetScriptRuntime();
Dan Sinclair1770c022016-03-14 14:14:16 -0400966 uint32_t uCount = 0;
967 FX_DOUBLE dSum = 0.0;
dsinclairdbdcb812016-06-01 20:07:22 -0700968 for (int32_t i = 0; i < argc; i++) {
969 std::unique_ptr<CFXJSE_Value> argValue = args.GetValue(i);
970 if (FXJSE_Value_IsNull(argValue.get()))
971 continue;
972
973 if (FXJSE_Value_IsArray(argValue.get())) {
974 std::unique_ptr<CFXJSE_Value> lengthValue(new CFXJSE_Value(pIsolate));
975 FXJSE_Value_GetObjectProp(argValue.get(), "length", lengthValue.get());
976 int32_t iLength = FXJSE_Value_ToInteger(lengthValue.get());
977 if (iLength <= 2) {
dsinclair2235b7b2016-06-02 07:42:25 -0700978 pContext->ThrowException(XFA_IDS_ARGUMENT_MISMATCH);
dsinclairdbdcb812016-06-01 20:07:22 -0700979 return;
980 }
981
982 std::unique_ptr<CFXJSE_Value> propertyValue(new CFXJSE_Value(pIsolate));
983 FXJSE_Value_GetObjectPropByIdx(argValue.get(), 1, propertyValue.get());
984 std::unique_ptr<CFXJSE_Value> jsObjectValue(new CFXJSE_Value(pIsolate));
985 std::unique_ptr<CFXJSE_Value> newPropertyValue(
986 new CFXJSE_Value(pIsolate));
987 if (FXJSE_Value_IsNull(propertyValue.get())) {
988 for (int32_t j = 2; j < iLength; j++) {
989 FXJSE_Value_GetObjectPropByIdx(argValue.get(), j,
990 jsObjectValue.get());
991 GetObjectDefaultValue(jsObjectValue.get(), newPropertyValue.get());
992 if (FXJSE_Value_IsNull(newPropertyValue.get()))
993 continue;
994
995 dSum += ValueToDouble(pThis, jsObjectValue.get());
Dan Sinclair1770c022016-03-14 14:14:16 -0400996 uCount++;
997 }
Dan Sinclair1770c022016-03-14 14:14:16 -0400998 } else {
dsinclairdbdcb812016-06-01 20:07:22 -0700999 CFX_ByteString propertyStr;
1000 FXJSE_Value_ToUTF8String(propertyValue.get(), propertyStr);
1001 for (int32_t j = 2; j < iLength; j++) {
1002 FXJSE_Value_GetObjectPropByIdx(argValue.get(), j,
1003 jsObjectValue.get());
1004 FXJSE_Value_GetObjectProp(jsObjectValue.get(),
1005 propertyStr.AsStringC(),
1006 newPropertyValue.get());
1007 if (FXJSE_Value_IsNull(newPropertyValue.get()))
1008 continue;
1009
1010 dSum += ValueToDouble(pThis, newPropertyValue.get());
1011 uCount++;
1012 }
Dan Sinclair1770c022016-03-14 14:14:16 -04001013 }
dsinclairdbdcb812016-06-01 20:07:22 -07001014 } else if (FXJSE_Value_IsObject(argValue.get())) {
1015 std::unique_ptr<CFXJSE_Value> newPropertyValue(
1016 new CFXJSE_Value(pIsolate));
1017 GetObjectDefaultValue(argValue.get(), newPropertyValue.get());
1018 if (FXJSE_Value_IsNull(newPropertyValue.get()))
1019 continue;
1020
1021 dSum += ValueToDouble(pThis, argValue.get());
1022 uCount++;
1023 } else {
1024 dSum += ValueToDouble(pThis, argValue.get());
1025 uCount++;
Dan Sinclair1770c022016-03-14 14:14:16 -04001026 }
Dan Sinclair1770c022016-03-14 14:14:16 -04001027 }
dsinclairdbdcb812016-06-01 20:07:22 -07001028 if (uCount == 0) {
Dan Sinclair1770c022016-03-14 14:14:16 -04001029 FXJSE_Value_SetNull(args.GetReturnValue());
dsinclairdbdcb812016-06-01 20:07:22 -07001030 return;
Dan Sinclair1770c022016-03-14 14:14:16 -04001031 }
dsinclairdbdcb812016-06-01 20:07:22 -07001032
1033 FXJSE_Value_SetDouble(args.GetReturnValue(), dSum);
Dan Sinclair1770c022016-03-14 14:14:16 -04001034}
dsinclair48d91dd2016-05-31 11:54:01 -07001035
1036// static
dsinclair12a6b0c2016-05-26 11:14:08 -07001037void CXFA_FM2JSContext::Date(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04001038 const CFX_ByteStringC& szFuncName,
1039 CFXJSE_Arguments& args) {
dsinclairdbdcb812016-06-01 20:07:22 -07001040 if (args.GetLength() != 0) {
Dan Sinclair1770c022016-03-14 14:14:16 -04001041 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07001042 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair2235b7b2016-06-02 07:42:25 -07001043 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Date");
dsinclairdbdcb812016-06-01 20:07:22 -07001044 return;
Dan Sinclair1770c022016-03-14 14:14:16 -04001045 }
dsinclairdbdcb812016-06-01 20:07:22 -07001046
1047 time_t currentTime;
1048 time(&currentTime);
1049 struct tm* pTmStruct = gmtime(&currentTime);
1050
1051 CFX_ByteString bufferYear;
1052 CFX_ByteString bufferMon;
1053 CFX_ByteString bufferDay;
1054 bufferYear.Format("%d", pTmStruct->tm_year + 1900);
1055 bufferMon.Format("%02d", pTmStruct->tm_mon + 1);
1056 bufferDay.Format("%02d", pTmStruct->tm_mday);
1057
1058 CFX_ByteString bufferCurrent = bufferYear + bufferMon + bufferDay;
1059 FXJSE_Value_SetInteger(args.GetReturnValue(),
1060 DateString2Num(bufferCurrent.AsStringC()));
Dan Sinclair1770c022016-03-14 14:14:16 -04001061}
dsinclair48d91dd2016-05-31 11:54:01 -07001062
1063// static
dsinclair12a6b0c2016-05-26 11:14:08 -07001064void CXFA_FM2JSContext::Date2Num(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04001065 const CFX_ByteStringC& szFuncName,
1066 CFXJSE_Arguments& args) {
1067 int32_t argc = args.GetLength();
dsinclairdbdcb812016-06-01 20:07:22 -07001068 if (argc <= 0 || argc >= 4) {
Dan Sinclair1770c022016-03-14 14:14:16 -04001069 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07001070 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair2235b7b2016-06-02 07:42:25 -07001071 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Date2Num");
dsinclairdbdcb812016-06-01 20:07:22 -07001072 return;
Dan Sinclair1770c022016-03-14 14:14:16 -04001073 }
dsinclairdbdcb812016-06-01 20:07:22 -07001074
1075 std::unique_ptr<CFXJSE_Value> dateValue = GetSimpleValue(pThis, args, 0);
1076 if (ValueIsNull(pThis, dateValue.get())) {
1077 FXJSE_Value_SetNull(args.GetReturnValue());
1078 return;
1079 }
1080
1081 CFX_ByteString dateString;
1082 ValueToUTF8String(dateValue.get(), dateString);
1083
1084 CFX_ByteString formatString;
1085 if (argc > 1) {
1086 std::unique_ptr<CFXJSE_Value> formatValue = GetSimpleValue(pThis, args, 1);
1087 if (ValueIsNull(pThis, formatValue.get())) {
1088 FXJSE_Value_SetNull(args.GetReturnValue());
1089 return;
1090 }
1091 ValueToUTF8String(formatValue.get(), formatString);
1092 }
1093
1094 CFX_ByteString localString;
1095 if (argc == 3) {
1096 std::unique_ptr<CFXJSE_Value> localValue = GetSimpleValue(pThis, args, 2);
1097 if (ValueIsNull(pThis, localValue.get())) {
1098 FXJSE_Value_SetNull(args.GetReturnValue());
1099 return;
1100 }
1101 ValueToUTF8String(localValue.get(), localString);
1102 }
1103
1104 CFX_ByteString szIsoDateString;
1105 if (!Local2IsoDate(pThis, dateString.AsStringC(), formatString.AsStringC(),
1106 localString.AsStringC(), szIsoDateString)) {
1107 FXJSE_Value_SetInteger(args.GetReturnValue(), 0);
1108 return;
1109 }
1110
1111 FXJSE_Value_SetInteger(args.GetReturnValue(),
1112 DateString2Num(szIsoDateString.AsStringC()));
Dan Sinclair1770c022016-03-14 14:14:16 -04001113}
dsinclair48d91dd2016-05-31 11:54:01 -07001114
1115// static
dsinclair12a6b0c2016-05-26 11:14:08 -07001116void CXFA_FM2JSContext::DateFmt(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04001117 const CFX_ByteStringC& szFuncName,
1118 CFXJSE_Arguments& args) {
1119 int32_t argc = args.GetLength();
dsinclairdbdcb812016-06-01 20:07:22 -07001120 if (argc >= 3) {
Dan Sinclair1770c022016-03-14 14:14:16 -04001121 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07001122 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair2235b7b2016-06-02 07:42:25 -07001123 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Date2Num");
dsinclairdbdcb812016-06-01 20:07:22 -07001124 return;
Dan Sinclair1770c022016-03-14 14:14:16 -04001125 }
dsinclairdbdcb812016-06-01 20:07:22 -07001126
1127 int32_t iStyle = 0;
1128 if (argc > 0) {
1129 std::unique_ptr<CFXJSE_Value> argStyle = GetSimpleValue(pThis, args, 0);
1130 if (FXJSE_Value_IsNull(argStyle.get())) {
1131 FXJSE_Value_SetNull(args.GetReturnValue());
1132 return;
1133 }
1134
1135 iStyle = (int32_t)ValueToFloat(pThis, argStyle.get());
1136 if (iStyle < 0 || iStyle > 4)
1137 iStyle = 0;
1138 }
1139
1140 CFX_ByteString szLocal;
1141 if (argc == 2) {
1142 std::unique_ptr<CFXJSE_Value> argLocal = GetSimpleValue(pThis, args, 1);
1143 if (FXJSE_Value_IsNull(argLocal.get())) {
1144 FXJSE_Value_SetNull(args.GetReturnValue());
1145 return;
1146 }
1147 ValueToUTF8String(argLocal.get(), szLocal);
1148 }
1149
1150 CFX_ByteString formatStr;
1151 GetStandardDateFormat(pThis, iStyle, szLocal.AsStringC(), formatStr);
1152 FXJSE_Value_SetUTF8String(args.GetReturnValue(), formatStr.AsStringC());
Dan Sinclair1770c022016-03-14 14:14:16 -04001153}
dsinclair48d91dd2016-05-31 11:54:01 -07001154
1155// static
dsinclair12a6b0c2016-05-26 11:14:08 -07001156void CXFA_FM2JSContext::IsoDate2Num(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04001157 const CFX_ByteStringC& szFuncName,
1158 CFXJSE_Arguments& args) {
dsinclairdbdcb812016-06-01 20:07:22 -07001159 if (args.GetLength() != 1) {
Dan Sinclair1770c022016-03-14 14:14:16 -04001160 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07001161 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair2235b7b2016-06-02 07:42:25 -07001162 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
1163 L"IsoDate2Num");
dsinclairdbdcb812016-06-01 20:07:22 -07001164 return;
Dan Sinclair1770c022016-03-14 14:14:16 -04001165 }
dsinclairdbdcb812016-06-01 20:07:22 -07001166
1167 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
1168 if (FXJSE_Value_IsNull(argOne.get())) {
1169 FXJSE_Value_SetNull(args.GetReturnValue());
1170 return;
1171 }
1172
1173 CFX_ByteString szArgString;
1174 ValueToUTF8String(argOne.get(), szArgString);
1175 FXJSE_Value_SetInteger(args.GetReturnValue(),
1176 DateString2Num(szArgString.AsStringC()));
Dan Sinclair1770c022016-03-14 14:14:16 -04001177}
dsinclair48d91dd2016-05-31 11:54:01 -07001178
1179// static
dsinclair12a6b0c2016-05-26 11:14:08 -07001180void CXFA_FM2JSContext::IsoTime2Num(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04001181 const CFX_ByteStringC& szFuncName,
1182 CFXJSE_Arguments& args) {
dsinclairdd6a46c2016-05-26 08:41:45 -07001183 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07001184 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclairdbdcb812016-06-01 20:07:22 -07001185 if (args.GetLength() != 1) {
dsinclair2235b7b2016-06-02 07:42:25 -07001186 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
1187 L"IsoTime2Num");
dsinclairdbdcb812016-06-01 20:07:22 -07001188 return;
Dan Sinclair1770c022016-03-14 14:14:16 -04001189 }
dsinclairdbdcb812016-06-01 20:07:22 -07001190
1191 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
1192 if (ValueIsNull(pThis, argOne.get())) {
1193 FXJSE_Value_SetNull(args.GetReturnValue());
1194 return;
1195 }
1196
1197 CXFA_Document* pDoc = pContext->GetDocument();
1198 CXFA_LocaleMgr* pMgr = pDoc->GetLocalMgr();
1199
1200 CFX_ByteString szArgString;
1201 ValueToUTF8String(argOne.get(), szArgString);
1202 szArgString = szArgString.Mid(szArgString.Find('T', 0) + 1);
1203 if (szArgString.IsEmpty()) {
1204 FXJSE_Value_SetInteger(args.GetReturnValue(), 0);
1205 return;
1206 }
1207
1208 CXFA_LocaleValue timeValue(
1209 XFA_VT_TIME, CFX_WideString::FromUTF8(szArgString.AsStringC()), pMgr);
1210 if (!timeValue.IsValid()) {
1211 FXJSE_Value_SetInteger(args.GetReturnValue(), 0);
1212 return;
1213 }
1214
1215 CFX_Unitime uniTime = timeValue.GetTime();
1216 int32_t hour = uniTime.GetHour();
1217 int32_t min = uniTime.GetMinute();
1218 int32_t second = uniTime.GetSecond();
1219 int32_t milSecond = uniTime.GetMillisecond();
1220
1221 FX_TIMEZONE tzLocale;
1222 pMgr->GetDefLocale()->GetTimeZone(tzLocale);
1223
1224 // TODO(dsinclair): See if there is other time conversion code in pdfium and
1225 // consolidate.
1226 int32_t mins = hour * 60 + min;
1227 mins -= (tzLocale.tzHour * 60);
1228 while (mins > 1440)
1229 mins -= 1440;
1230 while (mins < 0)
1231 mins += 1440;
1232 hour = mins / 60;
1233 min = mins % 60;
1234 int32_t iResult =
1235 hour * 3600000 + min * 60000 + second * 1000 + milSecond + 1;
1236 FXJSE_Value_SetInteger(args.GetReturnValue(), iResult);
Dan Sinclair1770c022016-03-14 14:14:16 -04001237}
dsinclair48d91dd2016-05-31 11:54:01 -07001238
1239// static
dsinclair12a6b0c2016-05-26 11:14:08 -07001240void CXFA_FM2JSContext::LocalDateFmt(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04001241 const CFX_ByteStringC& szFuncName,
1242 CFXJSE_Arguments& args) {
1243 int32_t argc = args.GetLength();
1244 if (argc < 3) {
1245 FX_BOOL bFlags = FALSE;
1246 int32_t iStyle = 0;
1247 CFX_ByteString szLocal;
Dan Sinclair1770c022016-03-14 14:14:16 -04001248 if (argc > 0) {
dsinclair86fad992016-05-31 11:34:04 -07001249 std::unique_ptr<CFXJSE_Value> argStyle = GetSimpleValue(pThis, args, 0);
1250 if (FXJSE_Value_IsNull(argStyle.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04001251 bFlags = TRUE;
1252 }
dsinclair86fad992016-05-31 11:34:04 -07001253 iStyle = (int32_t)ValueToFloat(pThis, argStyle.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04001254 if (iStyle > 4 || iStyle < 0) {
1255 iStyle = 0;
1256 }
1257 }
1258 if (argc == 2) {
dsinclair86fad992016-05-31 11:34:04 -07001259 std::unique_ptr<CFXJSE_Value> argLocal = GetSimpleValue(pThis, args, 1);
1260 if (FXJSE_Value_IsNull(argLocal.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04001261 bFlags = TRUE;
1262 } else {
dsinclair86fad992016-05-31 11:34:04 -07001263 ValueToUTF8String(argLocal.get(), szLocal);
Dan Sinclair1770c022016-03-14 14:14:16 -04001264 }
1265 }
1266 if (!bFlags) {
1267 CFX_ByteString formatStr;
dsinclair12a6b0c2016-05-26 11:14:08 -07001268 GetLocalDateFormat(pThis, iStyle, szLocal.AsStringC(), formatStr, FALSE);
Dan Sinclair1770c022016-03-14 14:14:16 -04001269 if (formatStr.IsEmpty()) {
1270 formatStr = "";
1271 }
tsepez4c3debb2016-04-08 12:20:38 -07001272 FXJSE_Value_SetUTF8String(args.GetReturnValue(), formatStr.AsStringC());
Dan Sinclair1770c022016-03-14 14:14:16 -04001273 } else {
1274 FXJSE_Value_SetNull(args.GetReturnValue());
1275 }
Dan Sinclair1770c022016-03-14 14:14:16 -04001276 } else {
1277 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07001278 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair2235b7b2016-06-02 07:42:25 -07001279 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
1280 L"LocalDateFmt");
Dan Sinclair1770c022016-03-14 14:14:16 -04001281 }
1282}
dsinclair48d91dd2016-05-31 11:54:01 -07001283
1284// static
dsinclair12a6b0c2016-05-26 11:14:08 -07001285void CXFA_FM2JSContext::LocalTimeFmt(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04001286 const CFX_ByteStringC& szFuncName,
1287 CFXJSE_Arguments& args) {
1288 int32_t argc = args.GetLength();
1289 if (argc < 3) {
1290 FX_BOOL bFlags = FALSE;
1291 int32_t iStyle = 0;
1292 CFX_ByteString szLocal;
Dan Sinclair1770c022016-03-14 14:14:16 -04001293 if (argc > 0) {
dsinclair86fad992016-05-31 11:34:04 -07001294 std::unique_ptr<CFXJSE_Value> argStyle = GetSimpleValue(pThis, args, 0);
1295 if (FXJSE_Value_IsNull(argStyle.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04001296 bFlags = TRUE;
1297 }
dsinclair86fad992016-05-31 11:34:04 -07001298 iStyle = (int32_t)ValueToFloat(pThis, argStyle.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04001299 if (iStyle > 4 || iStyle < 0) {
1300 iStyle = 0;
1301 }
1302 }
1303 if (argc == 2) {
dsinclair86fad992016-05-31 11:34:04 -07001304 std::unique_ptr<CFXJSE_Value> argLocal = GetSimpleValue(pThis, args, 1);
1305 if (FXJSE_Value_IsNull(argLocal.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04001306 bFlags = TRUE;
1307 } else {
dsinclair86fad992016-05-31 11:34:04 -07001308 ValueToUTF8String(argLocal.get(), szLocal);
Dan Sinclair1770c022016-03-14 14:14:16 -04001309 }
1310 }
1311 if (!bFlags) {
1312 CFX_ByteString formatStr;
dsinclair12a6b0c2016-05-26 11:14:08 -07001313 GetLocalTimeFormat(pThis, iStyle, szLocal.AsStringC(), formatStr, FALSE);
Dan Sinclair1770c022016-03-14 14:14:16 -04001314 if (formatStr.IsEmpty()) {
1315 formatStr = "";
1316 }
tsepez4c3debb2016-04-08 12:20:38 -07001317 FXJSE_Value_SetUTF8String(args.GetReturnValue(), formatStr.AsStringC());
Dan Sinclair1770c022016-03-14 14:14:16 -04001318 } else {
1319 FXJSE_Value_SetNull(args.GetReturnValue());
1320 }
Dan Sinclair1770c022016-03-14 14:14:16 -04001321 } else {
1322 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07001323 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair2235b7b2016-06-02 07:42:25 -07001324 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
1325 L"LocalTimeFmt");
Dan Sinclair1770c022016-03-14 14:14:16 -04001326 }
1327}
dsinclair48d91dd2016-05-31 11:54:01 -07001328
1329// static
dsinclair12a6b0c2016-05-26 11:14:08 -07001330void CXFA_FM2JSContext::Num2Date(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04001331 const CFX_ByteStringC& szFuncName,
1332 CFXJSE_Arguments& args) {
1333 int32_t argc = args.GetLength();
1334 if ((argc > 0) && (argc < 4)) {
1335 FX_BOOL bFlags = FALSE;
weili038aa532016-05-20 15:38:29 -07001336 int32_t dDate = 0;
Dan Sinclair1770c022016-03-14 14:14:16 -04001337 CFX_ByteString formatString;
1338 CFX_ByteString localString;
dsinclair86fad992016-05-31 11:34:04 -07001339 std::unique_ptr<CFXJSE_Value> dateValue = GetSimpleValue(pThis, args, 0);
1340 if (ValueIsNull(pThis, dateValue.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04001341 bFlags = TRUE;
1342 } else {
dsinclair86fad992016-05-31 11:34:04 -07001343 dDate = (int32_t)ValueToFloat(pThis, dateValue.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04001344 bFlags = dDate < 1;
1345 }
1346 if (argc > 1) {
dsinclair86fad992016-05-31 11:34:04 -07001347 std::unique_ptr<CFXJSE_Value> formatValue =
1348 GetSimpleValue(pThis, args, 1);
1349 if (ValueIsNull(pThis, formatValue.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04001350 bFlags = TRUE;
1351 } else {
dsinclair86fad992016-05-31 11:34:04 -07001352 ValueToUTF8String(formatValue.get(), formatString);
Dan Sinclair1770c022016-03-14 14:14:16 -04001353 }
1354 }
1355 if (argc == 3) {
dsinclair86fad992016-05-31 11:34:04 -07001356 std::unique_ptr<CFXJSE_Value> localValue = GetSimpleValue(pThis, args, 2);
1357 if (ValueIsNull(pThis, localValue.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04001358 bFlags = TRUE;
1359 } else {
dsinclair86fad992016-05-31 11:34:04 -07001360 ValueToUTF8String(localValue.get(), localString);
Dan Sinclair1770c022016-03-14 14:14:16 -04001361 }
1362 }
1363 if (!bFlags) {
1364 int32_t iYear = 1900;
1365 int32_t iMonth = 1;
1366 int32_t iDay = 1;
1367 int32_t i = 0;
1368 while (dDate > 0) {
1369 if (iMonth == 2) {
1370 if ((!((iYear + i) % 4) && ((iYear + i) % 100)) ||
1371 !((iYear + i) % 400)) {
1372 if (dDate > 29) {
1373 ++iMonth;
1374 if (iMonth > 12) {
1375 iMonth = 1;
1376 ++i;
1377 }
1378 iDay = 1;
1379 dDate -= 29;
1380 } else {
1381 iDay += static_cast<int32_t>(dDate) - 1;
1382 dDate = 0;
1383 }
1384 } else {
1385 if (dDate > 28) {
1386 ++iMonth;
1387 if (iMonth > 12) {
1388 iMonth = 1;
1389 ++i;
1390 }
1391 iDay = 1;
1392 dDate -= 28;
1393 } else {
1394 iDay += static_cast<int32_t>(dDate) - 1;
1395 dDate = 0;
1396 }
1397 }
1398 } else if (iMonth < 8) {
1399 if ((iMonth % 2 == 0)) {
1400 if (dDate > 30) {
1401 ++iMonth;
1402 if (iMonth > 12) {
1403 iMonth = 1;
1404 ++i;
1405 }
1406 iDay = 1;
1407 dDate -= 30;
1408 } else {
1409 iDay += static_cast<int32_t>(dDate) - 1;
1410 dDate = 0;
1411 }
1412 } else {
1413 if (dDate > 31) {
1414 ++iMonth;
1415 if (iMonth > 12) {
1416 iMonth = 1;
1417 ++i;
1418 }
1419 iDay = 1;
1420 dDate -= 31;
1421 } else {
1422 iDay += static_cast<int32_t>(dDate) - 1;
1423 dDate = 0;
1424 }
1425 }
1426 } else {
1427 if (iMonth % 2 != 0) {
1428 if (dDate > 30) {
1429 ++iMonth;
1430 if (iMonth > 12) {
1431 iMonth = 1;
1432 ++i;
1433 }
1434 iDay = 1;
1435 dDate -= 30;
1436 } else {
1437 iDay += static_cast<int32_t>(dDate) - 1;
1438 dDate = 0;
1439 }
1440 } else {
1441 if (dDate > 31) {
1442 ++iMonth;
1443 if (iMonth > 12) {
1444 iMonth = 1;
1445 ++i;
1446 }
1447 iDay = 1;
1448 dDate -= 31;
1449 } else {
1450 iDay += static_cast<int32_t>(dDate) - 1;
1451 dDate = 0;
1452 }
1453 }
1454 }
1455 }
1456 CFX_ByteString szIsoDateString;
1457 szIsoDateString.Format("%d%02d%02d", iYear + i, iMonth, iDay);
1458 CFX_ByteString szLocalDateString;
dsinclair12a6b0c2016-05-26 11:14:08 -07001459 IsoDate2Local(pThis, szIsoDateString.AsStringC(),
tsepez4c3debb2016-04-08 12:20:38 -07001460 formatString.AsStringC(), localString.AsStringC(),
Dan Sinclair1770c022016-03-14 14:14:16 -04001461 szLocalDateString);
1462 if (szLocalDateString.IsEmpty()) {
1463 szLocalDateString = "";
1464 }
tsepez28f97ff2016-04-04 16:41:35 -07001465 FXJSE_Value_SetUTF8String(args.GetReturnValue(),
tsepez4c3debb2016-04-08 12:20:38 -07001466 szLocalDateString.AsStringC());
Dan Sinclair1770c022016-03-14 14:14:16 -04001467 } else {
1468 FXJSE_Value_SetNull(args.GetReturnValue());
1469 }
Dan Sinclair1770c022016-03-14 14:14:16 -04001470 } else {
1471 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07001472 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair2235b7b2016-06-02 07:42:25 -07001473 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Num2Date");
Dan Sinclair1770c022016-03-14 14:14:16 -04001474 }
1475}
dsinclair48d91dd2016-05-31 11:54:01 -07001476
1477// static
dsinclair12a6b0c2016-05-26 11:14:08 -07001478void CXFA_FM2JSContext::Num2GMTime(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04001479 const CFX_ByteStringC& szFuncName,
1480 CFXJSE_Arguments& args) {
1481 int32_t argc = args.GetLength();
1482 if ((argc > 0) && (argc < 4)) {
1483 FX_BOOL bFlags = FALSE;
weili038aa532016-05-20 15:38:29 -07001484 int32_t iTime = 0;
Dan Sinclair1770c022016-03-14 14:14:16 -04001485 CFX_ByteString formatString;
1486 CFX_ByteString localString;
dsinclair86fad992016-05-31 11:34:04 -07001487 std::unique_ptr<CFXJSE_Value> timeValue = GetSimpleValue(pThis, args, 0);
1488 if (FXJSE_Value_IsNull(timeValue.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04001489 bFlags = TRUE;
1490 } else {
dsinclair86fad992016-05-31 11:34:04 -07001491 iTime = (int32_t)ValueToFloat(pThis, timeValue.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04001492 if (FXSYS_abs(iTime) < 1.0) {
1493 bFlags = TRUE;
1494 }
1495 }
1496 if (argc > 1) {
dsinclair86fad992016-05-31 11:34:04 -07001497 std::unique_ptr<CFXJSE_Value> formatValue =
1498 GetSimpleValue(pThis, args, 1);
1499 if (FXJSE_Value_IsNull(formatValue.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04001500 bFlags = TRUE;
1501 } else {
dsinclair86fad992016-05-31 11:34:04 -07001502 ValueToUTF8String(formatValue.get(), formatString);
Dan Sinclair1770c022016-03-14 14:14:16 -04001503 }
1504 }
1505 if (argc == 3) {
dsinclair86fad992016-05-31 11:34:04 -07001506 std::unique_ptr<CFXJSE_Value> localValue = GetSimpleValue(pThis, args, 2);
1507 if (FXJSE_Value_IsNull(localValue.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04001508 bFlags = TRUE;
1509 } else {
dsinclair86fad992016-05-31 11:34:04 -07001510 ValueToUTF8String(localValue.get(), localString);
Dan Sinclair1770c022016-03-14 14:14:16 -04001511 }
1512 }
1513 if (!bFlags) {
1514 CFX_ByteString szGMTTimeString;
dsinclair12a6b0c2016-05-26 11:14:08 -07001515 Num2AllTime(pThis, iTime, formatString.AsStringC(),
tsepez4c3debb2016-04-08 12:20:38 -07001516 localString.AsStringC(), TRUE, szGMTTimeString);
Dan Sinclair1770c022016-03-14 14:14:16 -04001517 if (szGMTTimeString.IsEmpty()) {
1518 szGMTTimeString = "";
1519 }
tsepez28f97ff2016-04-04 16:41:35 -07001520 FXJSE_Value_SetUTF8String(args.GetReturnValue(),
tsepez4c3debb2016-04-08 12:20:38 -07001521 szGMTTimeString.AsStringC());
Dan Sinclair1770c022016-03-14 14:14:16 -04001522 } else {
1523 FXJSE_Value_SetNull(args.GetReturnValue());
1524 }
Dan Sinclair1770c022016-03-14 14:14:16 -04001525 } else {
1526 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07001527 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair2235b7b2016-06-02 07:42:25 -07001528 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Num2GMTime");
Dan Sinclair1770c022016-03-14 14:14:16 -04001529 }
1530}
dsinclair48d91dd2016-05-31 11:54:01 -07001531
1532// static
dsinclair12a6b0c2016-05-26 11:14:08 -07001533void CXFA_FM2JSContext::Num2Time(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04001534 const CFX_ByteStringC& szFuncName,
1535 CFXJSE_Arguments& args) {
1536 int32_t argc = args.GetLength();
1537 if ((argc > 0) && (argc < 4)) {
1538 FX_BOOL bFlags = FALSE;
weili038aa532016-05-20 15:38:29 -07001539 FX_FLOAT fTime = 0.0f;
Dan Sinclair1770c022016-03-14 14:14:16 -04001540 CFX_ByteString formatString;
1541 CFX_ByteString localString;
dsinclair86fad992016-05-31 11:34:04 -07001542 std::unique_ptr<CFXJSE_Value> timeValue = GetSimpleValue(pThis, args, 0);
1543 if (FXJSE_Value_IsNull(timeValue.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04001544 bFlags = TRUE;
1545 } else {
dsinclair86fad992016-05-31 11:34:04 -07001546 fTime = ValueToFloat(pThis, timeValue.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04001547 if (FXSYS_fabs(fTime) < 1.0) {
1548 bFlags = TRUE;
1549 }
1550 }
1551 if (argc > 1) {
dsinclair86fad992016-05-31 11:34:04 -07001552 std::unique_ptr<CFXJSE_Value> formatValue =
1553 GetSimpleValue(pThis, args, 1);
1554 if (FXJSE_Value_IsNull(formatValue.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04001555 bFlags = TRUE;
1556 } else {
dsinclair86fad992016-05-31 11:34:04 -07001557 ValueToUTF8String(formatValue.get(), formatString);
Dan Sinclair1770c022016-03-14 14:14:16 -04001558 }
1559 }
1560 if (argc == 3) {
dsinclair86fad992016-05-31 11:34:04 -07001561 std::unique_ptr<CFXJSE_Value> localValue = GetSimpleValue(pThis, args, 2);
1562 if (FXJSE_Value_IsNull(localValue.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04001563 bFlags = TRUE;
1564 } else {
dsinclair86fad992016-05-31 11:34:04 -07001565 ValueToUTF8String(localValue.get(), localString);
Dan Sinclair1770c022016-03-14 14:14:16 -04001566 }
1567 }
1568 if (!bFlags) {
1569 CFX_ByteString szLocalTimeString;
dsinclair12a6b0c2016-05-26 11:14:08 -07001570 Num2AllTime(pThis, (int32_t)fTime, formatString.AsStringC(),
tsepez4c3debb2016-04-08 12:20:38 -07001571 localString.AsStringC(), FALSE, szLocalTimeString);
Dan Sinclair1770c022016-03-14 14:14:16 -04001572 if (szLocalTimeString.IsEmpty()) {
1573 szLocalTimeString = "";
1574 }
tsepez28f97ff2016-04-04 16:41:35 -07001575 FXJSE_Value_SetUTF8String(args.GetReturnValue(),
tsepez4c3debb2016-04-08 12:20:38 -07001576 szLocalTimeString.AsStringC());
Dan Sinclair1770c022016-03-14 14:14:16 -04001577 } else {
1578 FXJSE_Value_SetNull(args.GetReturnValue());
1579 }
Dan Sinclair1770c022016-03-14 14:14:16 -04001580 } else {
1581 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07001582 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair2235b7b2016-06-02 07:42:25 -07001583 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Num2Time");
Dan Sinclair1770c022016-03-14 14:14:16 -04001584 }
1585}
dsinclair48d91dd2016-05-31 11:54:01 -07001586
1587// static
dsinclair12a6b0c2016-05-26 11:14:08 -07001588void CXFA_FM2JSContext::Time(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04001589 const CFX_ByteStringC& szFuncName,
1590 CFXJSE_Arguments& args) {
1591 if (args.GetLength() == 0) {
1592 time_t now;
1593 time(&now);
1594 struct tm* pGmt = gmtime(&now);
1595 int32_t iGMHour = pGmt->tm_hour;
1596 int32_t iGMMin = pGmt->tm_min;
1597 int32_t iGMSec = pGmt->tm_sec;
1598 FXJSE_Value_SetInteger(args.GetReturnValue(),
1599 ((iGMHour * 3600 + iGMMin * 60 + iGMSec) * 1000));
1600 } else {
1601 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07001602 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair2235b7b2016-06-02 07:42:25 -07001603 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Time");
Dan Sinclair1770c022016-03-14 14:14:16 -04001604 }
1605}
dsinclair48d91dd2016-05-31 11:54:01 -07001606
1607// static
dsinclair12a6b0c2016-05-26 11:14:08 -07001608void CXFA_FM2JSContext::Time2Num(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04001609 const CFX_ByteStringC& szFuncName,
1610 CFXJSE_Arguments& args) {
1611 int32_t argc = args.GetLength();
1612 if ((argc > 0) && (argc < 4)) {
1613 FX_BOOL bFlags = FALSE;
1614 CFX_ByteString timeString;
1615 CFX_ByteString formatString;
1616 CFX_ByteString localString;
dsinclair86fad992016-05-31 11:34:04 -07001617 std::unique_ptr<CFXJSE_Value> timeValue = GetSimpleValue(pThis, args, 0);
1618 if (ValueIsNull(pThis, timeValue.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04001619 bFlags = TRUE;
1620 } else {
dsinclair86fad992016-05-31 11:34:04 -07001621 ValueToUTF8String(timeValue.get(), timeString);
Dan Sinclair1770c022016-03-14 14:14:16 -04001622 }
1623 if (argc > 1) {
dsinclair86fad992016-05-31 11:34:04 -07001624 std::unique_ptr<CFXJSE_Value> formatValue =
1625 GetSimpleValue(pThis, args, 1);
1626 if (ValueIsNull(pThis, formatValue.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04001627 bFlags = TRUE;
1628 } else {
dsinclair86fad992016-05-31 11:34:04 -07001629 ValueToUTF8String(formatValue.get(), formatString);
Dan Sinclair1770c022016-03-14 14:14:16 -04001630 }
1631 }
1632 if (argc == 3) {
dsinclair86fad992016-05-31 11:34:04 -07001633 std::unique_ptr<CFXJSE_Value> localValue = GetSimpleValue(pThis, args, 2);
1634 if (ValueIsNull(pThis, localValue.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04001635 bFlags = TRUE;
1636 } else {
dsinclair86fad992016-05-31 11:34:04 -07001637 ValueToUTF8String(localValue.get(), localString);
Dan Sinclair1770c022016-03-14 14:14:16 -04001638 }
1639 }
1640 if (!bFlags) {
1641 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07001642 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
Dan Sinclair1770c022016-03-14 14:14:16 -04001643 CXFA_Document* pDoc = pContext->GetDocument();
1644 IFX_LocaleMgr* pMgr = (IFX_LocaleMgr*)pDoc->GetLocalMgr();
dsinclair48d91dd2016-05-31 11:54:01 -07001645 IFX_Locale* pLocale = nullptr;
Dan Sinclair1770c022016-03-14 14:14:16 -04001646 if (localString.IsEmpty()) {
1647 CXFA_Node* pThisNode =
1648 ToNode(pDoc->GetScriptContext()->GetThisObject());
dsinclair43854a52016-04-27 12:26:00 -07001649 ASSERT(pThisNode);
Dan Sinclair1770c022016-03-14 14:14:16 -04001650 CXFA_WidgetData widgetData(pThisNode);
1651 pLocale = widgetData.GetLocal();
1652 } else {
1653 pLocale = pMgr->GetLocaleByName(
tsepezafe94302016-05-13 17:21:31 -07001654 CFX_WideString::FromUTF8(localString.AsStringC()));
Dan Sinclair1770c022016-03-14 14:14:16 -04001655 }
1656 CFX_WideString wsFormat;
1657 if (formatString.IsEmpty()) {
1658 pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Default, wsFormat);
1659 } else {
tsepez4c3debb2016-04-08 12:20:38 -07001660 wsFormat = CFX_WideString::FromUTF8(formatString.AsStringC());
Dan Sinclair1770c022016-03-14 14:14:16 -04001661 }
1662 wsFormat = FX_WSTRC(L"time{") + wsFormat;
1663 wsFormat += FX_WSTRC(L"}");
dsinclair86fad992016-05-31 11:34:04 -07001664 CXFA_LocaleValue localeValue(
tsepez4c3debb2016-04-08 12:20:38 -07001665 XFA_VT_TIME, CFX_WideString::FromUTF8(timeString.AsStringC()),
Dan Sinclair1770c022016-03-14 14:14:16 -04001666 wsFormat, pLocale, (CXFA_LocaleMgr*)pMgr);
dsinclair86fad992016-05-31 11:34:04 -07001667 if (localeValue.IsValid()) {
1668 CFX_Unitime uniTime = localeValue.GetTime();
Dan Sinclair1770c022016-03-14 14:14:16 -04001669 int32_t hour = uniTime.GetHour();
1670 int32_t min = uniTime.GetMinute();
1671 int32_t second = uniTime.GetSecond();
1672 int32_t milSecond = uniTime.GetMillisecond();
1673 int32_t mins = hour * 60 + min;
dsinclairdf4bc592016-03-31 20:34:43 -07001674 CXFA_TimeZoneProvider* pProvider = CXFA_TimeZoneProvider::Get();
Dan Sinclair1770c022016-03-14 14:14:16 -04001675 if (pProvider) {
1676 FX_TIMEZONE tz;
1677 pProvider->GetTimeZone(tz);
1678 mins -= (tz.tzHour * 60);
1679 while (mins > 1440) {
1680 mins -= 1440;
1681 }
1682 while (mins < 0) {
1683 mins += 1440;
1684 }
1685 hour = mins / 60;
1686 min = mins % 60;
1687 }
1688 int32_t iResult =
1689 hour * 3600000 + min * 60000 + second * 1000 + milSecond + 1;
1690 FXJSE_Value_SetInteger(args.GetReturnValue(), iResult);
1691 } else {
1692 FXJSE_Value_SetInteger(args.GetReturnValue(), 0);
1693 }
1694 } else {
1695 FXJSE_Value_SetNull(args.GetReturnValue());
1696 }
Dan Sinclair1770c022016-03-14 14:14:16 -04001697 } else {
1698 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07001699 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair2235b7b2016-06-02 07:42:25 -07001700 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Time2Num");
Dan Sinclair1770c022016-03-14 14:14:16 -04001701 }
1702}
dsinclair48d91dd2016-05-31 11:54:01 -07001703
1704// static
dsinclair12a6b0c2016-05-26 11:14:08 -07001705void CXFA_FM2JSContext::TimeFmt(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04001706 const CFX_ByteStringC& szFuncName,
1707 CFXJSE_Arguments& args) {
1708 int32_t argc = args.GetLength();
1709 if (argc < 3) {
1710 FX_BOOL bFlags = FALSE;
1711 int32_t iStyle = 0;
1712 CFX_ByteString szLocal;
Dan Sinclair1770c022016-03-14 14:14:16 -04001713 if (argc > 0) {
dsinclair86fad992016-05-31 11:34:04 -07001714 std::unique_ptr<CFXJSE_Value> argStyle = GetSimpleValue(pThis, args, 0);
1715 if (FXJSE_Value_IsNull(argStyle.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04001716 bFlags = TRUE;
1717 }
dsinclair86fad992016-05-31 11:34:04 -07001718 iStyle = (int32_t)ValueToFloat(pThis, argStyle.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04001719 if (iStyle > 4 || iStyle < 0) {
1720 iStyle = 0;
1721 }
1722 }
1723 if (argc == 2) {
dsinclair86fad992016-05-31 11:34:04 -07001724 std::unique_ptr<CFXJSE_Value> argLocal = GetSimpleValue(pThis, args, 1);
1725 if (FXJSE_Value_IsNull(argLocal.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04001726 bFlags = TRUE;
1727 } else {
dsinclair86fad992016-05-31 11:34:04 -07001728 ValueToUTF8String(argLocal.get(), szLocal);
Dan Sinclair1770c022016-03-14 14:14:16 -04001729 }
1730 }
1731 if (!bFlags) {
1732 CFX_ByteString formatStr;
dsinclair12a6b0c2016-05-26 11:14:08 -07001733 GetStandardTimeFormat(pThis, iStyle, szLocal.AsStringC(), formatStr);
Dan Sinclair1770c022016-03-14 14:14:16 -04001734 if (formatStr.IsEmpty()) {
1735 formatStr = "";
1736 }
tsepez4c3debb2016-04-08 12:20:38 -07001737 FXJSE_Value_SetUTF8String(args.GetReturnValue(), formatStr.AsStringC());
Dan Sinclair1770c022016-03-14 14:14:16 -04001738 } else {
1739 FXJSE_Value_SetNull(args.GetReturnValue());
1740 }
Dan Sinclair1770c022016-03-14 14:14:16 -04001741 } else {
1742 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07001743 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair2235b7b2016-06-02 07:42:25 -07001744 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"TimeFmt");
Dan Sinclair1770c022016-03-14 14:14:16 -04001745 }
1746}
dsinclair48d91dd2016-05-31 11:54:01 -07001747
1748// static
Dan Sinclair1770c022016-03-14 14:14:16 -04001749FX_BOOL CXFA_FM2JSContext::IsIsoDateFormat(const FX_CHAR* pData,
1750 int32_t iLength,
1751 int32_t& iStyle,
1752 int32_t& iYear,
1753 int32_t& iMonth,
1754 int32_t& iDay) {
1755 iYear = 0;
1756 iMonth = 1;
1757 iDay = 1;
1758 FX_BOOL iRet = FALSE;
1759 if (iLength < 4) {
1760 return iRet;
1761 }
1762 FX_CHAR strYear[5];
1763 strYear[4] = '\0';
1764 for (int32_t i = 0; i < 4; ++i) {
1765 if (*(pData + i) <= '9' && *(pData + i) >= '0') {
1766 strYear[i] = *(pData + i);
1767 } else {
1768 return iRet;
1769 }
1770 }
1771 iYear = FXSYS_atoi(strYear);
1772 iStyle = 0;
1773 if (iLength > 4) {
1774 if (*(pData + 4) == '-') {
1775 iStyle = 1;
1776 } else {
1777 iStyle = 0;
1778 }
1779 } else {
1780 iRet = TRUE;
1781 return iRet;
1782 }
1783 FX_CHAR strTemp[3];
1784 strTemp[2] = '\0';
1785 int32_t iPosOff = 0;
1786 if (iStyle == 0) {
1787 iPosOff = 4;
1788 if (iLength == 4) {
1789 iRet = TRUE;
1790 return iRet;
1791 }
1792 } else {
1793 iPosOff = 5;
1794 if (iLength == 4) {
1795 iRet = TRUE;
1796 return iRet;
1797 }
1798 }
1799 if ((*(pData + iPosOff) > '9' || *(pData + iPosOff) < '0') ||
1800 (*(pData + iPosOff + 1) > '9' || *(pData + iPosOff + 1) < '0')) {
1801 return iRet;
1802 }
1803 strTemp[0] = *(pData + iPosOff);
1804 strTemp[1] = *(pData + iPosOff + 1);
1805 iMonth = FXSYS_atoi(strTemp);
1806 if (iMonth > 12 || iMonth < 1) {
1807 return iRet;
1808 }
1809 if (iStyle == 0) {
1810 iPosOff += 2;
1811 if (iLength == 6) {
1812 iRet = 1;
1813 return iRet;
1814 }
1815 } else {
1816 iPosOff += 3;
1817 if (iLength == 7) {
1818 iRet = 1;
1819 return iRet;
1820 }
1821 }
1822 if ((*(pData + iPosOff) > '9' || *(pData + iPosOff) < '0') ||
1823 (*(pData + iPosOff + 1) > '9' || *(pData + iPosOff + 1) < '0')) {
1824 return iRet;
1825 }
1826 strTemp[0] = *(pData + iPosOff);
1827 strTemp[1] = *(pData + iPosOff + 1);
1828 iDay = FXSYS_atoi(strTemp);
1829 if (iPosOff + 2 < iLength) {
1830 return iRet;
1831 }
1832 if ((!(iYear % 4) && (iYear % 100)) || !(iYear % 400)) {
1833 if (iMonth == 2) {
1834 if (iDay > 29) {
1835 return iRet;
1836 }
1837 } else {
1838 if (iMonth < 8) {
1839 if (iDay > (iMonth % 2 == 0 ? 30 : 31)) {
1840 return iRet;
1841 }
1842 } else {
1843 if (iDay > (iMonth % 2 == 0 ? 31 : 30)) {
1844 return iRet;
1845 }
1846 }
1847 }
1848 } else {
1849 if (iMonth == 2) {
1850 if (iDay > 28) {
1851 return iRet;
1852 }
1853 } else {
1854 if (iMonth < 8) {
1855 if (iDay > (iMonth % 2 == 0 ? 30 : 31)) {
1856 return iRet;
1857 }
1858 } else {
1859 if (iDay > (iMonth % 2 == 0 ? 31 : 30)) {
1860 return iRet;
1861 }
1862 }
1863 }
1864 }
1865 iRet = TRUE;
1866 return iRet;
1867}
dsinclair48d91dd2016-05-31 11:54:01 -07001868
1869// static
Dan Sinclair1770c022016-03-14 14:14:16 -04001870FX_BOOL CXFA_FM2JSContext::IsIsoTimeFormat(const FX_CHAR* pData,
1871 int32_t iLength,
1872 int32_t& iHour,
1873 int32_t& iMinute,
1874 int32_t& iSecond,
1875 int32_t& iMilliSecond,
1876 int32_t& iZoneHour,
1877 int32_t& iZoneMinute) {
1878 iHour = 0;
1879 iMinute = 0;
1880 iSecond = 0;
1881 iMilliSecond = 0;
1882 iZoneHour = 0;
1883 iZoneMinute = 0;
1884 if (!pData) {
1885 return FALSE;
1886 }
1887 int32_t iRet = FALSE;
1888 FX_CHAR strTemp[3];
1889 strTemp[2] = '\0';
1890 int32_t iIndex = 0;
1891 int32_t iZone = 0;
1892 int32_t i = iIndex;
1893 while (i < iLength) {
1894 if ((*(pData + i) > '9' || *(pData + i) < '0') && *(pData + i) != ':') {
1895 iZone = i;
1896 break;
1897 }
1898 ++i;
1899 }
1900 if (i == iLength) {
1901 iZone = iLength;
1902 }
1903 int32_t iPos = 0;
1904 while (iIndex < iZone) {
1905 if (iIndex >= iZone) {
1906 break;
1907 }
1908 if (*(pData + iIndex) > '9' || *(pData + iIndex) < '0') {
1909 return iRet;
1910 }
1911 strTemp[0] = *(pData + iIndex);
1912 if (*(pData + iIndex + 1) > '9' || *(pData + iIndex + 1) < '0') {
1913 return iRet;
1914 }
1915 strTemp[1] = *(pData + iIndex + 1);
1916 if (FXSYS_atoi(strTemp) > 60) {
1917 return iRet;
1918 }
1919 if (*(pData + 2) == ':') {
1920 if (iPos == 0) {
1921 iHour = FXSYS_atoi(strTemp);
1922 ++iPos;
1923 } else if (iPos == 1) {
1924 iMinute = FXSYS_atoi(strTemp);
1925 ++iPos;
1926 } else {
1927 iSecond = FXSYS_atoi(strTemp);
1928 }
1929 iIndex += 3;
1930 } else {
1931 if (iPos == 0) {
1932 iHour = FXSYS_atoi(strTemp);
1933 ++iPos;
1934 } else if (iPos == 1) {
1935 iMinute = FXSYS_atoi(strTemp);
1936 ++iPos;
1937 } else if (iPos == 2) {
1938 iSecond = FXSYS_atoi(strTemp);
1939 ++iPos;
1940 }
1941 iIndex += 2;
1942 }
1943 }
1944 if (*(pData + iIndex) == '.') {
1945 ++iIndex;
1946 FX_CHAR strTemp[4];
1947 strTemp[3] = '\0';
1948 if (*(pData + iIndex) > '9' || *(pData + iIndex) < '0') {
1949 return iRet;
1950 }
1951 strTemp[0] = *(pData + iIndex);
1952 if (*(pData + iIndex + 1) > '9' || *(pData + iIndex + 1) < '0') {
1953 return iRet;
1954 }
1955 strTemp[1] = *(pData + iIndex + 1);
1956 if (*(pData + iIndex + 2) > '9' || *(pData + iIndex + 2) < '0') {
1957 return iRet;
1958 }
1959 strTemp[2] = *(pData + iIndex + 2);
1960 iMilliSecond = FXSYS_atoi(strTemp);
1961 if (iMilliSecond > 100) {
1962 iMilliSecond = 0;
1963 return iRet;
1964 }
1965 iIndex += 3;
1966 }
1967 int32_t iSign = 1;
1968 if (*(pData + iIndex) == 'z' || *(pData + iIndex) == 'Z') {
1969 iRet = 1;
1970 return iRet;
1971 } else if (*(pData + iIndex) == '+') {
1972 ++iIndex;
1973 } else if (*(pData + iIndex) == '-') {
1974 iSign = -1;
1975 ++iIndex;
1976 }
1977 iPos = 0;
1978 while (iIndex < iLength) {
1979 if (iIndex >= iLength) {
1980 return iRet;
1981 }
1982 if (*(pData + iIndex) > '9' || *(pData + iIndex) < '0') {
1983 return iRet;
1984 }
1985 strTemp[0] = *(pData + iIndex);
1986 if (*(pData + iIndex + 1) > '9' || *(pData + iIndex + 1) < '0') {
1987 return iRet;
1988 }
1989 strTemp[1] = *(pData + iIndex + 1);
1990 if (FXSYS_atoi(strTemp) > 60) {
1991 return iRet;
1992 }
1993 if (*(pData + 2) == ':') {
1994 if (iPos == 0) {
1995 iZoneHour = FXSYS_atoi(strTemp);
1996 } else if (iPos == 1) {
1997 iZoneMinute = FXSYS_atoi(strTemp);
1998 }
1999 iIndex += 3;
2000 } else {
2001 if (!iPos) {
2002 iZoneHour = FXSYS_atoi(strTemp);
2003 ++iPos;
2004 } else if (iPos == 1) {
2005 iZoneMinute = FXSYS_atoi(strTemp);
2006 ++iPos;
2007 }
2008 iIndex += 2;
2009 }
2010 }
2011 if (iIndex < iLength) {
2012 return iRet;
2013 }
2014 iZoneHour *= iSign;
2015 iRet = TRUE;
2016 return iRet;
2017}
dsinclair48d91dd2016-05-31 11:54:01 -07002018
2019// static
Dan Sinclair1770c022016-03-14 14:14:16 -04002020FX_BOOL CXFA_FM2JSContext::IsIsoDateTimeFormat(const FX_CHAR* pData,
2021 int32_t iLength,
2022 int32_t& iYear,
2023 int32_t& iMonth,
2024 int32_t& iDay,
2025 int32_t& iHour,
2026 int32_t& iMinute,
2027 int32_t& iSecond,
2028 int32_t& iMillionSecond,
2029 int32_t& iZoneHour,
2030 int32_t& iZoneMinute) {
2031 iYear = 0;
2032 iMonth = 0;
2033 iDay = 0;
2034 iHour = 0;
2035 iMinute = 0;
2036 iSecond = 0;
2037 if (!pData) {
2038 return FALSE;
2039 }
2040 int32_t iRet = FALSE;
2041 int32_t iIndex = 0;
2042 while (*(pData + iIndex) != 'T' && *(pData + iIndex) != 't') {
2043 if (iIndex >= iLength) {
2044 return iRet;
2045 }
2046 ++iIndex;
2047 }
2048 if (iIndex != 8 && iIndex != 10) {
2049 return iRet;
2050 }
2051 int32_t iStyle = -1;
2052 iRet = IsIsoDateFormat(pData, iIndex, iStyle, iYear, iMonth, iDay);
2053 if (!iRet) {
2054 return iRet;
2055 }
2056 if (*(pData + iIndex) != 'T' && *(pData + iIndex) != 't') {
2057 return iRet;
2058 }
2059 ++iIndex;
2060 if (((iLength - iIndex > 13) && (iLength - iIndex < 6)) &&
2061 (iLength - iIndex != 15)) {
2062 return iRet;
2063 }
2064 iRet = IsIsoTimeFormat(pData + iIndex, iLength - iIndex, iHour, iMinute,
2065 iSecond, iMillionSecond, iZoneHour, iZoneMinute);
2066 if (!iRet) {
2067 return iRet;
2068 }
2069 iRet = TRUE;
2070 return iRet;
2071}
dsinclair48d91dd2016-05-31 11:54:01 -07002072
2073// static
dsinclair12a6b0c2016-05-26 11:14:08 -07002074FX_BOOL CXFA_FM2JSContext::Local2IsoDate(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04002075 const CFX_ByteStringC& szDate,
2076 const CFX_ByteStringC& szFormat,
2077 const CFX_ByteStringC& szLocale,
2078 CFX_ByteString& strIsoDate) {
dsinclairdd6a46c2016-05-26 08:41:45 -07002079 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07002080 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
Dan Sinclair1770c022016-03-14 14:14:16 -04002081 CXFA_Document* pDoc = pContext->GetDocument();
2082 if (!pDoc) {
2083 return FALSE;
2084 }
2085 IFX_LocaleMgr* pMgr = (IFX_LocaleMgr*)pDoc->GetLocalMgr();
dsinclair48d91dd2016-05-31 11:54:01 -07002086 IFX_Locale* pLocale = nullptr;
Dan Sinclair1770c022016-03-14 14:14:16 -04002087 if (szLocale.IsEmpty()) {
2088 CXFA_Node* pThisNode = ToNode(pDoc->GetScriptContext()->GetThisObject());
dsinclair43854a52016-04-27 12:26:00 -07002089 ASSERT(pThisNode);
Dan Sinclair1770c022016-03-14 14:14:16 -04002090 CXFA_WidgetData widgetData(pThisNode);
2091 pLocale = widgetData.GetLocal();
2092 } else {
tsepezafe94302016-05-13 17:21:31 -07002093 pLocale = pMgr->GetLocaleByName(CFX_WideString::FromUTF8(szLocale));
Dan Sinclair1770c022016-03-14 14:14:16 -04002094 }
2095 if (!pLocale) {
2096 return FALSE;
2097 }
2098 CFX_WideString wsFormat;
2099 if (szFormat.IsEmpty()) {
2100 pLocale->GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY_Default, wsFormat);
2101 } else {
tsepez6fe7d212016-04-06 10:51:14 -07002102 wsFormat = CFX_WideString::FromUTF8(szFormat);
Dan Sinclair1770c022016-03-14 14:14:16 -04002103 }
tsepez6fe7d212016-04-06 10:51:14 -07002104 CXFA_LocaleValue widgetValue(XFA_VT_DATE, CFX_WideString::FromUTF8(szDate),
2105 wsFormat, pLocale, (CXFA_LocaleMgr*)pMgr);
Dan Sinclair1770c022016-03-14 14:14:16 -04002106 CFX_Unitime dt = widgetValue.GetDate();
2107 strIsoDate.Format("%4d-%02d-%02d", dt.GetYear(), dt.GetMonth(), dt.GetDay());
2108 return TRUE;
2109}
dsinclair48d91dd2016-05-31 11:54:01 -07002110
2111// static
dsinclair12a6b0c2016-05-26 11:14:08 -07002112FX_BOOL CXFA_FM2JSContext::Local2IsoTime(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04002113 const CFX_ByteStringC& szTime,
2114 const CFX_ByteStringC& szFormat,
2115 const CFX_ByteStringC& szLocale,
2116 CFX_ByteString& strIsoTime) {
dsinclairdd6a46c2016-05-26 08:41:45 -07002117 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07002118 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
Dan Sinclair1770c022016-03-14 14:14:16 -04002119 CXFA_Document* pDoc = pContext->GetDocument();
2120 if (!pDoc) {
2121 return FALSE;
2122 }
2123 IFX_LocaleMgr* pMgr = (IFX_LocaleMgr*)pDoc->GetLocalMgr();
dsinclair48d91dd2016-05-31 11:54:01 -07002124 IFX_Locale* pLocale = nullptr;
Dan Sinclair1770c022016-03-14 14:14:16 -04002125 if (szLocale.IsEmpty()) {
2126 CXFA_Node* pThisNode = ToNode(pDoc->GetScriptContext()->GetThisObject());
dsinclair43854a52016-04-27 12:26:00 -07002127 ASSERT(pThisNode);
Dan Sinclair1770c022016-03-14 14:14:16 -04002128 CXFA_WidgetData widgetData(pThisNode);
2129 pLocale = widgetData.GetLocal();
2130 } else {
tsepezafe94302016-05-13 17:21:31 -07002131 pLocale = pMgr->GetLocaleByName(CFX_WideString::FromUTF8(szLocale));
Dan Sinclair1770c022016-03-14 14:14:16 -04002132 }
2133 if (!pLocale) {
2134 return FALSE;
2135 }
2136 CFX_WideString wsFormat;
2137 if (szFormat.IsEmpty()) {
2138 pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Default, wsFormat);
2139 } else {
tsepez6fe7d212016-04-06 10:51:14 -07002140 wsFormat = CFX_WideString::FromUTF8(szFormat);
Dan Sinclair1770c022016-03-14 14:14:16 -04002141 }
2142 wsFormat = FX_WSTRC(L"time{") + wsFormat;
2143 wsFormat += FX_WSTRC(L"}");
tsepez6fe7d212016-04-06 10:51:14 -07002144 CXFA_LocaleValue widgetValue(XFA_VT_TIME, CFX_WideString::FromUTF8(szTime),
2145 wsFormat, pLocale, (CXFA_LocaleMgr*)pMgr);
Dan Sinclair1770c022016-03-14 14:14:16 -04002146 CFX_Unitime utime = widgetValue.GetTime();
2147 strIsoTime.Format("%02d:%02d:%02d.%03d", utime.GetHour(), utime.GetMinute(),
2148 utime.GetSecond(), utime.GetMillisecond());
2149 return TRUE;
2150}
dsinclair48d91dd2016-05-31 11:54:01 -07002151
2152// static
dsinclair12a6b0c2016-05-26 11:14:08 -07002153FX_BOOL CXFA_FM2JSContext::IsoDate2Local(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04002154 const CFX_ByteStringC& szDate,
2155 const CFX_ByteStringC& szFormat,
2156 const CFX_ByteStringC& szLocale,
2157 CFX_ByteString& strLocalDate) {
dsinclairdd6a46c2016-05-26 08:41:45 -07002158 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07002159 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
Dan Sinclair1770c022016-03-14 14:14:16 -04002160 CXFA_Document* pDoc = pContext->GetDocument();
2161 if (!pDoc) {
2162 return FALSE;
2163 }
2164 IFX_LocaleMgr* pMgr = (IFX_LocaleMgr*)pDoc->GetLocalMgr();
dsinclair48d91dd2016-05-31 11:54:01 -07002165 IFX_Locale* pLocale = nullptr;
Dan Sinclair1770c022016-03-14 14:14:16 -04002166 if (szLocale.IsEmpty()) {
2167 CXFA_Node* pThisNode = ToNode(pDoc->GetScriptContext()->GetThisObject());
dsinclair43854a52016-04-27 12:26:00 -07002168 ASSERT(pThisNode);
Dan Sinclair1770c022016-03-14 14:14:16 -04002169 CXFA_WidgetData widgetData(pThisNode);
2170 pLocale = widgetData.GetLocal();
2171 } else {
tsepezafe94302016-05-13 17:21:31 -07002172 pLocale = pMgr->GetLocaleByName(CFX_WideString::FromUTF8(szLocale));
Dan Sinclair1770c022016-03-14 14:14:16 -04002173 }
2174 if (!pLocale) {
2175 return FALSE;
2176 }
2177 CFX_WideString wsFormat;
2178 if (szFormat.IsEmpty()) {
2179 pLocale->GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY_Default, wsFormat);
2180 } else {
tsepez6fe7d212016-04-06 10:51:14 -07002181 wsFormat = CFX_WideString::FromUTF8(szFormat);
Dan Sinclair1770c022016-03-14 14:14:16 -04002182 }
tsepez6fe7d212016-04-06 10:51:14 -07002183 CXFA_LocaleValue widgetValue(XFA_VT_DATE, CFX_WideString::FromUTF8(szDate),
2184 (CXFA_LocaleMgr*)pMgr);
Dan Sinclair1770c022016-03-14 14:14:16 -04002185 CFX_WideString wsRet;
2186 widgetValue.FormatPatterns(wsRet, wsFormat, pLocale,
2187 XFA_VALUEPICTURE_Display);
tsepezbd9748d2016-04-13 21:40:19 -07002188 strLocalDate = FX_UTF8Encode(wsRet.c_str(), wsRet.GetLength());
Dan Sinclair1770c022016-03-14 14:14:16 -04002189 return TRUE;
2190}
dsinclair48d91dd2016-05-31 11:54:01 -07002191
2192// static
dsinclair12a6b0c2016-05-26 11:14:08 -07002193FX_BOOL CXFA_FM2JSContext::IsoTime2Local(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04002194 const CFX_ByteStringC& szTime,
2195 const CFX_ByteStringC& szFormat,
2196 const CFX_ByteStringC& szLocale,
2197 CFX_ByteString& strLocalTime) {
dsinclairdd6a46c2016-05-26 08:41:45 -07002198 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07002199 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
Dan Sinclair1770c022016-03-14 14:14:16 -04002200 CXFA_Document* pDoc = pContext->GetDocument();
2201 if (!pDoc) {
2202 return FALSE;
2203 }
2204 IFX_LocaleMgr* pMgr = (IFX_LocaleMgr*)pDoc->GetLocalMgr();
dsinclair48d91dd2016-05-31 11:54:01 -07002205 IFX_Locale* pLocale = nullptr;
Dan Sinclair1770c022016-03-14 14:14:16 -04002206 if (szLocale.IsEmpty()) {
2207 CXFA_Node* pThisNode = ToNode(pDoc->GetScriptContext()->GetThisObject());
dsinclair43854a52016-04-27 12:26:00 -07002208 ASSERT(pThisNode);
Dan Sinclair1770c022016-03-14 14:14:16 -04002209 CXFA_WidgetData widgetData(pThisNode);
2210 pLocale = widgetData.GetLocal();
2211 } else {
tsepezafe94302016-05-13 17:21:31 -07002212 pLocale = pMgr->GetLocaleByName(CFX_WideString::FromUTF8(szLocale));
Dan Sinclair1770c022016-03-14 14:14:16 -04002213 }
2214 if (!pLocale) {
2215 return FALSE;
2216 }
2217 CFX_WideString wsFormat;
2218 if (szFormat.IsEmpty()) {
2219 pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Default, wsFormat);
2220 } else {
tsepez6fe7d212016-04-06 10:51:14 -07002221 wsFormat = CFX_WideString::FromUTF8(szFormat);
Dan Sinclair1770c022016-03-14 14:14:16 -04002222 }
2223 wsFormat = FX_WSTRC(L"time{") + wsFormat;
2224 wsFormat += FX_WSTRC(L"}");
tsepez6fe7d212016-04-06 10:51:14 -07002225 CXFA_LocaleValue widgetValue(XFA_VT_TIME, CFX_WideString::FromUTF8(szTime),
2226 (CXFA_LocaleMgr*)pMgr);
Dan Sinclair1770c022016-03-14 14:14:16 -04002227 CFX_WideString wsRet;
2228 widgetValue.FormatPatterns(wsRet, wsFormat, pLocale,
2229 XFA_VALUEPICTURE_Display);
tsepezbd9748d2016-04-13 21:40:19 -07002230 strLocalTime = FX_UTF8Encode(wsRet.c_str(), wsRet.GetLength());
Dan Sinclair1770c022016-03-14 14:14:16 -04002231 return TRUE;
2232}
dsinclair48d91dd2016-05-31 11:54:01 -07002233
2234// static
dsinclair12a6b0c2016-05-26 11:14:08 -07002235FX_BOOL CXFA_FM2JSContext::GetGMTTime(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04002236 const CFX_ByteStringC& szTime,
2237 const CFX_ByteStringC& szFormat,
2238 const CFX_ByteStringC& szLocale,
2239 CFX_ByteString& strGMTTime) {
dsinclairdd6a46c2016-05-26 08:41:45 -07002240 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07002241 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
Dan Sinclair1770c022016-03-14 14:14:16 -04002242 CXFA_Document* pDoc = pContext->GetDocument();
2243 if (!pDoc) {
2244 return FALSE;
2245 }
2246 IFX_LocaleMgr* pMgr = (IFX_LocaleMgr*)pDoc->GetLocalMgr();
dsinclair48d91dd2016-05-31 11:54:01 -07002247 IFX_Locale* pLocale = nullptr;
Dan Sinclair1770c022016-03-14 14:14:16 -04002248 if (szLocale.IsEmpty()) {
2249 CXFA_Node* pThisNode = ToNode(pDoc->GetScriptContext()->GetThisObject());
dsinclair43854a52016-04-27 12:26:00 -07002250 ASSERT(pThisNode);
Dan Sinclair1770c022016-03-14 14:14:16 -04002251 CXFA_WidgetData widgetData(pThisNode);
2252 pLocale = widgetData.GetLocal();
2253 } else {
tsepezafe94302016-05-13 17:21:31 -07002254 pLocale = pMgr->GetLocaleByName(CFX_WideString::FromUTF8(szLocale));
Dan Sinclair1770c022016-03-14 14:14:16 -04002255 }
2256 if (!pLocale) {
2257 return FALSE;
2258 }
2259 CFX_WideString wsFormat;
2260 if (szFormat.IsEmpty()) {
2261 pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Default, wsFormat);
2262 } else {
tsepez6fe7d212016-04-06 10:51:14 -07002263 wsFormat = CFX_WideString::FromUTF8(szFormat);
Dan Sinclair1770c022016-03-14 14:14:16 -04002264 }
2265 wsFormat = FX_WSTRC(L"time{") + wsFormat;
2266 wsFormat += FX_WSTRC(L"}");
tsepez6fe7d212016-04-06 10:51:14 -07002267 CXFA_LocaleValue widgetValue(XFA_VT_TIME, CFX_WideString::FromUTF8(szTime),
2268 (CXFA_LocaleMgr*)pMgr);
Dan Sinclair1770c022016-03-14 14:14:16 -04002269 CFX_WideString wsRet;
2270 widgetValue.FormatPatterns(wsRet, wsFormat, pLocale,
2271 XFA_VALUEPICTURE_Display);
tsepezbd9748d2016-04-13 21:40:19 -07002272 strGMTTime = FX_UTF8Encode(wsRet.c_str(), wsRet.GetLength());
Dan Sinclair1770c022016-03-14 14:14:16 -04002273 return TRUE;
2274}
dsinclair48d91dd2016-05-31 11:54:01 -07002275
2276// static
Dan Sinclair1770c022016-03-14 14:14:16 -04002277int32_t CXFA_FM2JSContext::DateString2Num(const CFX_ByteStringC& szDateString) {
2278 FX_BOOL bFlags = FALSE;
2279 int32_t iLength = szDateString.GetLength();
2280 FX_BOOL iRet = FALSE;
2281 int32_t iStyle = -1;
2282 int32_t iYear = 0;
2283 int32_t iMonth = 0;
2284 int32_t iDay = 0;
2285 int32_t iHour = 0;
2286 int32_t iMinute = 0;
2287 int32_t iSecond = 0;
2288 int32_t iMillionSecond = 0;
2289 int32_t iZoneHour = 0;
2290 int32_t iZoneMinute = 0;
2291 if (iLength <= 10) {
dsinclair179bebb2016-04-05 11:02:18 -07002292 iRet = IsIsoDateFormat(szDateString.c_str(), iLength, iStyle, iYear, iMonth,
2293 iDay);
Dan Sinclair1770c022016-03-14 14:14:16 -04002294 } else {
dsinclair179bebb2016-04-05 11:02:18 -07002295 iRet = IsIsoDateTimeFormat(szDateString.c_str(), iLength, iYear, iMonth,
Dan Sinclair1770c022016-03-14 14:14:16 -04002296 iDay, iHour, iMinute, iSecond, iMillionSecond,
2297 iZoneHour, iZoneMinute);
2298 }
2299 if (!iRet) {
2300 bFlags = TRUE;
2301 }
2302 FX_FLOAT dDays = 0;
2303 int32_t i = 1;
2304 if (iYear < 1900) {
2305 bFlags = TRUE;
2306 }
2307 if (!bFlags) {
2308 while (iYear - i >= 1900) {
2309 if ((!((iYear - i) % 4) && ((iYear - i) % 100)) || !((iYear - i) % 400)) {
2310 dDays += 366;
2311 } else {
2312 dDays += 365;
2313 }
2314 ++i;
2315 }
2316 i = 1;
2317 while (i < iMonth) {
2318 if (i == 2) {
2319 if ((!(iYear % 4) && (iYear % 100)) || !(iYear % 400)) {
2320 dDays += 29;
2321 } else {
2322 dDays += 28;
2323 }
2324 } else if (i <= 7) {
2325 if (i % 2 == 0) {
2326 dDays += 30;
2327 } else {
2328 dDays += 31;
2329 }
2330 } else {
2331 if (i % 2 == 0) {
2332 dDays += 31;
2333 } else {
2334 dDays += 30;
2335 }
2336 }
2337 ++i;
2338 }
2339 i = 0;
2340 while (iDay - i > 0) {
2341 dDays += 1;
2342 ++i;
2343 }
2344 } else {
2345 dDays = 0;
2346 }
2347 return (int32_t)dDays;
2348}
dsinclair0c268e92016-05-17 14:04:14 -07002349
dsinclair48d91dd2016-05-31 11:54:01 -07002350// static
dsinclair12a6b0c2016-05-26 11:14:08 -07002351void CXFA_FM2JSContext::GetLocalDateFormat(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04002352 int32_t iStyle,
2353 const CFX_ByteStringC& szLocalStr,
2354 CFX_ByteString& strFormat,
2355 FX_BOOL bStandard) {
2356 FX_LOCALEDATETIMESUBCATEGORY strStyle;
2357 switch (iStyle) {
2358 case 0:
2359 strStyle = FX_LOCALEDATETIMESUBCATEGORY_Medium;
2360 break;
2361 case 1:
2362 strStyle = FX_LOCALEDATETIMESUBCATEGORY_Short;
2363 break;
2364 case 2:
2365 strStyle = FX_LOCALEDATETIMESUBCATEGORY_Medium;
2366 break;
2367 case 3:
2368 strStyle = FX_LOCALEDATETIMESUBCATEGORY_Long;
2369 break;
2370 case 4:
2371 strStyle = FX_LOCALEDATETIMESUBCATEGORY_Full;
2372 break;
2373 default:
2374 strStyle = FX_LOCALEDATETIMESUBCATEGORY_Medium;
2375 break;
2376 }
dsinclairdd6a46c2016-05-26 08:41:45 -07002377 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07002378 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
Dan Sinclair1770c022016-03-14 14:14:16 -04002379 CXFA_Document* pDoc = pContext->GetDocument();
2380 if (!pDoc) {
2381 return;
2382 }
2383 IFX_LocaleMgr* pMgr = (IFX_LocaleMgr*)pDoc->GetLocalMgr();
dsinclair48d91dd2016-05-31 11:54:01 -07002384 IFX_Locale* pLocale = nullptr;
Dan Sinclair1770c022016-03-14 14:14:16 -04002385 if (szLocalStr.IsEmpty()) {
2386 CXFA_Node* pThisNode = ToNode(pDoc->GetScriptContext()->GetThisObject());
dsinclair43854a52016-04-27 12:26:00 -07002387 ASSERT(pThisNode);
Dan Sinclair1770c022016-03-14 14:14:16 -04002388 CXFA_WidgetData widgetData(pThisNode);
2389 pLocale = widgetData.GetLocal();
2390 } else {
tsepezafe94302016-05-13 17:21:31 -07002391 pLocale = pMgr->GetLocaleByName(CFX_WideString::FromUTF8(szLocalStr));
Dan Sinclair1770c022016-03-14 14:14:16 -04002392 }
2393 if (!pLocale) {
2394 return;
2395 }
2396 CFX_WideString strRet;
2397 pLocale->GetDatePattern(strStyle, strRet);
2398 if (!bStandard) {
2399 CFX_WideString wsSymbols;
2400 pLocale->GetDateTimeSymbols(wsSymbols);
dsinclair0c268e92016-05-17 14:04:14 -07002401 AlternateDateTimeSymbols(strRet, wsSymbols, g_sAltTable_Date);
Dan Sinclair1770c022016-03-14 14:14:16 -04002402 }
tsepezbd9748d2016-04-13 21:40:19 -07002403 strFormat = FX_UTF8Encode(strRet.c_str(), strRet.GetLength());
Dan Sinclair1770c022016-03-14 14:14:16 -04002404}
dsinclair48d91dd2016-05-31 11:54:01 -07002405
2406// static
dsinclair12a6b0c2016-05-26 11:14:08 -07002407void CXFA_FM2JSContext::GetLocalTimeFormat(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04002408 int32_t iStyle,
2409 const CFX_ByteStringC& szLocalStr,
2410 CFX_ByteString& strFormat,
2411 FX_BOOL bStandard) {
2412 FX_LOCALEDATETIMESUBCATEGORY strStyle;
2413 switch (iStyle) {
2414 case 0:
2415 strStyle = FX_LOCALEDATETIMESUBCATEGORY_Medium;
2416 break;
2417 case 1:
2418 strStyle = FX_LOCALEDATETIMESUBCATEGORY_Short;
2419 break;
2420 case 2:
2421 strStyle = FX_LOCALEDATETIMESUBCATEGORY_Medium;
2422 break;
2423 case 3:
2424 strStyle = FX_LOCALEDATETIMESUBCATEGORY_Long;
2425 break;
2426 case 4:
2427 strStyle = FX_LOCALEDATETIMESUBCATEGORY_Full;
2428 break;
2429 default:
2430 strStyle = FX_LOCALEDATETIMESUBCATEGORY_Medium;
2431 break;
2432 }
dsinclairdd6a46c2016-05-26 08:41:45 -07002433 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07002434 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
Dan Sinclair1770c022016-03-14 14:14:16 -04002435 CXFA_Document* pDoc = pContext->GetDocument();
2436 if (!pDoc) {
2437 return;
2438 }
2439 IFX_LocaleMgr* pMgr = (IFX_LocaleMgr*)pDoc->GetLocalMgr();
dsinclair48d91dd2016-05-31 11:54:01 -07002440 IFX_Locale* pLocale = nullptr;
Dan Sinclair1770c022016-03-14 14:14:16 -04002441 if (szLocalStr.IsEmpty()) {
2442 CXFA_Node* pThisNode = ToNode(pDoc->GetScriptContext()->GetThisObject());
dsinclair43854a52016-04-27 12:26:00 -07002443 ASSERT(pThisNode);
Dan Sinclair1770c022016-03-14 14:14:16 -04002444 CXFA_WidgetData widgetData(pThisNode);
2445 pLocale = widgetData.GetLocal();
2446 } else {
tsepezafe94302016-05-13 17:21:31 -07002447 pLocale = pMgr->GetLocaleByName(CFX_WideString::FromUTF8(szLocalStr));
Dan Sinclair1770c022016-03-14 14:14:16 -04002448 }
2449 if (!pLocale) {
2450 return;
2451 }
2452 CFX_WideString strRet;
2453 pLocale->GetTimePattern(strStyle, strRet);
2454 if (!bStandard) {
2455 CFX_WideString wsSymbols;
2456 pLocale->GetDateTimeSymbols(wsSymbols);
dsinclair0c268e92016-05-17 14:04:14 -07002457 AlternateDateTimeSymbols(strRet, wsSymbols, g_sAltTable_Time);
Dan Sinclair1770c022016-03-14 14:14:16 -04002458 }
tsepezbd9748d2016-04-13 21:40:19 -07002459 strFormat = FX_UTF8Encode(strRet.c_str(), strRet.GetLength());
Dan Sinclair1770c022016-03-14 14:14:16 -04002460}
dsinclair48d91dd2016-05-31 11:54:01 -07002461
2462// static
dsinclair12a6b0c2016-05-26 11:14:08 -07002463void CXFA_FM2JSContext::GetStandardDateFormat(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04002464 int32_t iStyle,
2465 const CFX_ByteStringC& szLocalStr,
2466 CFX_ByteString& strFormat) {
dsinclair12a6b0c2016-05-26 11:14:08 -07002467 GetLocalDateFormat(pThis, iStyle, szLocalStr, strFormat, TRUE);
Dan Sinclair1770c022016-03-14 14:14:16 -04002468}
dsinclair48d91dd2016-05-31 11:54:01 -07002469
2470// static
dsinclair12a6b0c2016-05-26 11:14:08 -07002471void CXFA_FM2JSContext::GetStandardTimeFormat(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04002472 int32_t iStyle,
2473 const CFX_ByteStringC& szLocalStr,
2474 CFX_ByteString& strFormat) {
dsinclair12a6b0c2016-05-26 11:14:08 -07002475 GetLocalTimeFormat(pThis, iStyle, szLocalStr, strFormat, TRUE);
Dan Sinclair1770c022016-03-14 14:14:16 -04002476}
dsinclair48d91dd2016-05-31 11:54:01 -07002477
2478// static
dsinclair12a6b0c2016-05-26 11:14:08 -07002479void CXFA_FM2JSContext::Num2AllTime(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04002480 int32_t iTime,
2481 const CFX_ByteStringC& szFormat,
2482 const CFX_ByteStringC& szLocale,
2483 FX_BOOL bGM,
2484 CFX_ByteString& strTime) {
2485 int32_t iHour = 0;
2486 int32_t iMin = 0;
2487 int32_t iSec = 0;
2488 int32_t iZoneHour = 0;
2489 int32_t iZoneMin = 0;
2490 int32_t iZoneSec = 0;
2491 iHour = static_cast<int>(iTime) / 3600000;
2492 iMin = (static_cast<int>(iTime) - iHour * 3600000) / 60000;
2493 iSec = (static_cast<int>(iTime) - iHour * 3600000 - iMin * 60000) / 1000;
2494 if (!bGM) {
2495 GetLocalTimeZone(iZoneHour, iZoneMin, iZoneSec);
2496 iHour += iZoneHour;
2497 iMin += iZoneMin;
2498 iSec += iZoneSec;
2499 }
2500 int32_t iRet = 0;
2501 CFX_ByteString strIsoTime;
2502 strIsoTime.Format("%02d:%02d:%02d", iHour, iMin, iSec);
2503 if (bGM) {
tsepez4c3debb2016-04-08 12:20:38 -07002504 iRet =
dsinclair12a6b0c2016-05-26 11:14:08 -07002505 GetGMTTime(pThis, strIsoTime.AsStringC(), szFormat, szLocale, strTime);
Dan Sinclair1770c022016-03-14 14:14:16 -04002506 } else {
dsinclair12a6b0c2016-05-26 11:14:08 -07002507 iRet = IsoTime2Local(pThis, strIsoTime.AsStringC(), szFormat, szLocale,
tsepez28f97ff2016-04-04 16:41:35 -07002508 strTime);
Dan Sinclair1770c022016-03-14 14:14:16 -04002509 }
2510 if (!iRet) {
2511 strTime = "";
2512 }
2513}
2514
dsinclair48d91dd2016-05-31 11:54:01 -07002515// static
Dan Sinclair1770c022016-03-14 14:14:16 -04002516void CXFA_FM2JSContext::GetLocalTimeZone(int32_t& iHour,
2517 int32_t& iMin,
2518 int32_t& iSec) {
2519 time_t now;
2520 time(&now);
2521 struct tm* pGmt = gmtime(&now);
2522 int32_t iGMHour = pGmt->tm_hour;
2523 int32_t iGMMin = pGmt->tm_min;
2524 int32_t iGMSec = pGmt->tm_sec;
2525 struct tm* pLocal = localtime(&now);
2526 int32_t iLocalHour = pLocal->tm_hour;
2527 int32_t iLocalMin = pLocal->tm_min;
2528 int32_t iLocalSec = pLocal->tm_sec;
2529 iHour = iLocalHour - iGMHour;
2530 iMin = iLocalMin - iGMMin;
2531 iSec = iLocalSec - iGMSec;
2532}
dsinclair48d91dd2016-05-31 11:54:01 -07002533
2534// static
dsinclair12a6b0c2016-05-26 11:14:08 -07002535void CXFA_FM2JSContext::Apr(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04002536 const CFX_ByteStringC& szFuncName,
2537 CFXJSE_Arguments& args) {
dsinclairdd6a46c2016-05-26 08:41:45 -07002538 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07002539 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
Dan Sinclair1770c022016-03-14 14:14:16 -04002540 if (args.GetLength() == 3) {
2541 FX_BOOL bFlags = FALSE;
2542 FX_DOUBLE nPrincipal = 0;
2543 FX_DOUBLE nPayment = 0;
2544 FX_DOUBLE nPeriods = 0;
dsinclair86fad992016-05-31 11:34:04 -07002545 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
2546 std::unique_ptr<CFXJSE_Value> argTwo = GetSimpleValue(pThis, args, 1);
2547 std::unique_ptr<CFXJSE_Value> argThree = GetSimpleValue(pThis, args, 2);
2548 bFlags =
2549 (ValueIsNull(pThis, argOne.get()) || ValueIsNull(pThis, argTwo.get()) ||
2550 ValueIsNull(pThis, argThree.get()));
Dan Sinclair1770c022016-03-14 14:14:16 -04002551 if (bFlags) {
2552 FXJSE_Value_SetNull(args.GetReturnValue());
2553 } else {
dsinclair86fad992016-05-31 11:34:04 -07002554 nPrincipal = ValueToDouble(pThis, argOne.get());
2555 nPayment = ValueToDouble(pThis, argTwo.get());
2556 nPeriods = ValueToDouble(pThis, argThree.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04002557 bFlags = ((nPrincipal <= 0) || (nPayment <= 0) || (nPeriods <= 0));
2558 if (bFlags) {
dsinclair2235b7b2016-06-02 07:42:25 -07002559 pContext->ThrowException(XFA_IDS_ARGUMENT_MISMATCH);
Dan Sinclair1770c022016-03-14 14:14:16 -04002560 } else {
2561 FX_DOUBLE r =
2562 2 * (nPeriods * nPayment - nPrincipal) / (nPeriods * nPrincipal);
2563 FX_DOUBLE nTemp = 1;
2564 for (int32_t i = 0; i < nPeriods; ++i) {
2565 nTemp *= (1 + r);
2566 }
2567 FX_DOUBLE nRet = r * nTemp / (nTemp - 1) - nPayment / nPrincipal;
dsinclair48d91dd2016-05-31 11:54:01 -07002568 while (fabs(nRet) > kFinancialPrecision && !bFlags) {
Dan Sinclair1770c022016-03-14 14:14:16 -04002569 FX_DOUBLE nDerivative = 0;
2570 nDerivative =
2571 ((nTemp + r * nPeriods * (nTemp / (1 + r))) * (nTemp - 1) -
2572 (r * nTemp * nPeriods * (nTemp / (1 + r)))) /
2573 ((nTemp - 1) * (nTemp - 1));
2574 if (nDerivative == 0) {
2575 bFlags = TRUE;
2576 continue;
2577 }
2578 r = r - nRet / nDerivative;
2579 nTemp = 1;
2580 for (int32_t i = 0; i < nPeriods; ++i) {
2581 nTemp *= (1 + r);
2582 }
2583 nRet = r * nTemp / (nTemp - 1) - nPayment / nPrincipal;
2584 }
2585 if (bFlags) {
2586 FXJSE_Value_SetNull(args.GetReturnValue());
2587 } else {
2588 r = r * 12;
2589 FXJSE_Value_SetDouble(args.GetReturnValue(), r);
2590 }
2591 }
2592 }
Dan Sinclair1770c022016-03-14 14:14:16 -04002593 } else {
dsinclair2235b7b2016-06-02 07:42:25 -07002594 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Apr");
Dan Sinclair1770c022016-03-14 14:14:16 -04002595 }
2596}
dsinclair48d91dd2016-05-31 11:54:01 -07002597
2598// static
dsinclair12a6b0c2016-05-26 11:14:08 -07002599void CXFA_FM2JSContext::CTerm(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04002600 const CFX_ByteStringC& szFuncName,
2601 CFXJSE_Arguments& args) {
dsinclairdd6a46c2016-05-26 08:41:45 -07002602 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07002603 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
Dan Sinclair1770c022016-03-14 14:14:16 -04002604 if (args.GetLength() == 3) {
2605 FX_BOOL bFlags = FALSE;
2606 FX_FLOAT nRate = 0;
2607 FX_FLOAT nFutureValue = 0;
2608 FX_FLOAT nInitAmount = 0;
dsinclair86fad992016-05-31 11:34:04 -07002609 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
2610 std::unique_ptr<CFXJSE_Value> argTwo = GetSimpleValue(pThis, args, 1);
2611 std::unique_ptr<CFXJSE_Value> argThree = GetSimpleValue(pThis, args, 2);
2612 bFlags =
2613 (ValueIsNull(pThis, argOne.get()) || ValueIsNull(pThis, argTwo.get()) ||
2614 ValueIsNull(pThis, argThree.get()));
Dan Sinclair1770c022016-03-14 14:14:16 -04002615 if (bFlags) {
2616 FXJSE_Value_SetNull(args.GetReturnValue());
2617 } else {
dsinclair86fad992016-05-31 11:34:04 -07002618 nRate = ValueToFloat(pThis, argOne.get());
2619 nFutureValue = ValueToFloat(pThis, argTwo.get());
2620 nInitAmount = ValueToFloat(pThis, argThree.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04002621 bFlags = ((nRate <= 0) || (nFutureValue <= 0) || (nInitAmount <= 0));
2622 if (bFlags) {
dsinclair2235b7b2016-06-02 07:42:25 -07002623 pContext->ThrowException(XFA_IDS_ARGUMENT_MISMATCH);
Dan Sinclair1770c022016-03-14 14:14:16 -04002624 } else {
2625 FXJSE_Value_SetFloat(args.GetReturnValue(),
2626 FXSYS_log((FX_FLOAT)(nFutureValue / nInitAmount)) /
2627 FXSYS_log((FX_FLOAT)(1 + nRate)));
2628 }
2629 }
Dan Sinclair1770c022016-03-14 14:14:16 -04002630 } else {
dsinclair2235b7b2016-06-02 07:42:25 -07002631 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"CTerm");
Dan Sinclair1770c022016-03-14 14:14:16 -04002632 }
2633}
dsinclair48d91dd2016-05-31 11:54:01 -07002634
2635// static
dsinclair12a6b0c2016-05-26 11:14:08 -07002636void CXFA_FM2JSContext::FV(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04002637 const CFX_ByteStringC& szFuncName,
2638 CFXJSE_Arguments& args) {
dsinclairdd6a46c2016-05-26 08:41:45 -07002639 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07002640 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
Dan Sinclair1770c022016-03-14 14:14:16 -04002641 if (args.GetLength() == 3) {
2642 FX_BOOL bFlags = FALSE;
2643 FX_DOUBLE nAmount = 0;
2644 FX_DOUBLE nRate = 0;
2645 FX_DOUBLE nPeriod = 0;
dsinclair86fad992016-05-31 11:34:04 -07002646 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
2647 std::unique_ptr<CFXJSE_Value> argTwo = GetSimpleValue(pThis, args, 1);
2648 std::unique_ptr<CFXJSE_Value> argThree = GetSimpleValue(pThis, args, 2);
2649 bFlags =
2650 (ValueIsNull(pThis, argOne.get()) || ValueIsNull(pThis, argTwo.get()) ||
2651 ValueIsNull(pThis, argThree.get()));
Dan Sinclair1770c022016-03-14 14:14:16 -04002652 if (bFlags) {
2653 FXJSE_Value_SetNull(args.GetReturnValue());
2654 } else {
dsinclair86fad992016-05-31 11:34:04 -07002655 nAmount = ValueToDouble(pThis, argOne.get());
2656 nRate = ValueToDouble(pThis, argTwo.get());
2657 nPeriod = ValueToDouble(pThis, argThree.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04002658 bFlags = ((nRate < 0) || (nPeriod <= 0) || (nAmount <= 0));
2659 if (bFlags) {
dsinclair2235b7b2016-06-02 07:42:25 -07002660 pContext->ThrowException(XFA_IDS_ARGUMENT_MISMATCH);
Dan Sinclair1770c022016-03-14 14:14:16 -04002661 } else {
2662 FX_DOUBLE dResult = 0;
2663 if (!nRate) {
2664 dResult = nAmount * nPeriod;
2665 } else {
2666 FX_DOUBLE nTemp = 1;
2667 for (int i = 0; i < nPeriod; ++i) {
2668 nTemp *= 1 + nRate;
2669 }
2670 dResult = nAmount * (nTemp - 1) / nRate;
2671 }
2672 FXJSE_Value_SetDouble(args.GetReturnValue(), dResult);
2673 }
2674 }
Dan Sinclair1770c022016-03-14 14:14:16 -04002675 } else {
dsinclair2235b7b2016-06-02 07:42:25 -07002676 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"FV");
Dan Sinclair1770c022016-03-14 14:14:16 -04002677 }
2678}
dsinclair48d91dd2016-05-31 11:54:01 -07002679
2680// static
dsinclair12a6b0c2016-05-26 11:14:08 -07002681void CXFA_FM2JSContext::IPmt(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04002682 const CFX_ByteStringC& szFuncName,
2683 CFXJSE_Arguments& args) {
dsinclairdd6a46c2016-05-26 08:41:45 -07002684 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07002685 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
Dan Sinclair1770c022016-03-14 14:14:16 -04002686 if (args.GetLength() == 5) {
2687 FX_BOOL bFlags = FALSE;
2688 FX_FLOAT nPrincpalAmount = 0;
2689 FX_FLOAT nRate = 0;
2690 FX_FLOAT nPayment = 0;
2691 FX_FLOAT nFirstMonth = 0;
2692 FX_FLOAT nNumberOfMonths = 0;
dsinclair86fad992016-05-31 11:34:04 -07002693 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
2694 std::unique_ptr<CFXJSE_Value> argTwo = GetSimpleValue(pThis, args, 1);
2695 std::unique_ptr<CFXJSE_Value> argThree = GetSimpleValue(pThis, args, 2);
2696 std::unique_ptr<CFXJSE_Value> argFour = GetSimpleValue(pThis, args, 3);
2697 std::unique_ptr<CFXJSE_Value> argFive = GetSimpleValue(pThis, args, 4);
2698 bFlags =
2699 (ValueIsNull(pThis, argOne.get()) || ValueIsNull(pThis, argTwo.get()) ||
2700 ValueIsNull(pThis, argThree.get()) ||
2701 ValueIsNull(pThis, argFour.get()) ||
2702 ValueIsNull(pThis, argFive.get()));
Dan Sinclair1770c022016-03-14 14:14:16 -04002703 if (bFlags) {
2704 FXJSE_Value_SetNull(args.GetReturnValue());
2705 } else {
dsinclair86fad992016-05-31 11:34:04 -07002706 nPrincpalAmount = ValueToFloat(pThis, argOne.get());
2707 nRate = ValueToFloat(pThis, argTwo.get());
2708 nPayment = ValueToFloat(pThis, argThree.get());
2709 nFirstMonth = ValueToFloat(pThis, argFour.get());
2710 nNumberOfMonths = ValueToFloat(pThis, argFive.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04002711 bFlags = ((nPrincpalAmount <= 0) || (nRate <= 0) || (nPayment <= 0) ||
2712 (nFirstMonth < 0) || (nNumberOfMonths < 0));
2713 if (bFlags) {
dsinclair2235b7b2016-06-02 07:42:25 -07002714 pContext->ThrowException(XFA_IDS_ARGUMENT_MISMATCH);
Dan Sinclair1770c022016-03-14 14:14:16 -04002715 } else {
2716 FX_FLOAT fResult = 0;
2717 FX_FLOAT nRateOfMonth = nRate / 12;
2718 int32_t iNums =
2719 (int32_t)((FXSYS_log10((FX_FLOAT)(nPayment / nPrincpalAmount)) -
2720 FXSYS_log10((FX_FLOAT)(nPayment / nPrincpalAmount -
2721 nRateOfMonth))) /
2722 FXSYS_log10((FX_FLOAT)(1 + nRateOfMonth)));
2723 int32_t iEnd = (int32_t)(nFirstMonth + nNumberOfMonths - 1);
2724 if (iEnd > iNums) {
2725 iEnd = iNums;
2726 }
2727 FX_FLOAT nSum = 0;
2728 if (nPayment < nPrincpalAmount * nRateOfMonth) {
2729 bFlags = TRUE;
2730 fResult = 0;
2731 }
2732 if (!bFlags) {
2733 int32_t i = 0;
2734 for (i = 0; i < nFirstMonth - 1; ++i) {
2735 nPrincpalAmount -= nPayment - nPrincpalAmount * nRateOfMonth;
2736 }
2737 for (; i < iEnd; ++i) {
2738 nSum += nPrincpalAmount * nRateOfMonth;
2739 nPrincpalAmount -= nPayment - nPrincpalAmount * nRateOfMonth;
2740 }
2741 fResult = nSum;
2742 }
2743 FXJSE_Value_SetFloat(args.GetReturnValue(), fResult);
2744 }
2745 }
Dan Sinclair1770c022016-03-14 14:14:16 -04002746 } else {
dsinclair2235b7b2016-06-02 07:42:25 -07002747 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"IPmt");
Dan Sinclair1770c022016-03-14 14:14:16 -04002748 }
2749}
dsinclair48d91dd2016-05-31 11:54:01 -07002750
2751// static
dsinclair12a6b0c2016-05-26 11:14:08 -07002752void CXFA_FM2JSContext::NPV(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04002753 const CFX_ByteStringC& szFuncName,
2754 CFXJSE_Arguments& args) {
dsinclairdd6a46c2016-05-26 08:41:45 -07002755 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07002756 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
Dan Sinclair1770c022016-03-14 14:14:16 -04002757 int32_t argc = args.GetLength();
2758 if (argc > 2) {
2759 FX_BOOL bFlags = FALSE;
dsinclair86fad992016-05-31 11:34:04 -07002760 std::vector<std::unique_ptr<CFXJSE_Value>> argValues;
Dan Sinclair1770c022016-03-14 14:14:16 -04002761 for (int32_t i = 0; i < argc; i++) {
dsinclair86fad992016-05-31 11:34:04 -07002762 argValues.push_back(GetSimpleValue(pThis, args, i));
2763 if (ValueIsNull(pThis, argValues[i].get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04002764 bFlags = TRUE;
2765 }
2766 }
dsinclair86fad992016-05-31 11:34:04 -07002767 if (!bFlags && argc > 0) {
Dan Sinclair1770c022016-03-14 14:14:16 -04002768 FX_DOUBLE nRate = 0;
dsinclair86fad992016-05-31 11:34:04 -07002769 nRate = ValueToDouble(pThis, argValues[0].get());
Dan Sinclair1770c022016-03-14 14:14:16 -04002770 if (nRate <= 0) {
dsinclair2235b7b2016-06-02 07:42:25 -07002771 pContext->ThrowException(XFA_IDS_ARGUMENT_MISMATCH);
Dan Sinclair1770c022016-03-14 14:14:16 -04002772 } else {
2773 FX_DOUBLE* pData = FX_Alloc(FX_DOUBLE, argc - 1);
2774 for (int32_t i = 1; i < argc; i++) {
dsinclair86fad992016-05-31 11:34:04 -07002775 pData[i - 1] = ValueToDouble(pThis, argValues[i].get());
Dan Sinclair1770c022016-03-14 14:14:16 -04002776 }
2777 FX_DOUBLE nSum = 0;
2778 int32_t iIndex = 0;
2779 for (int32_t i = 0; i < argc - 1; i++) {
2780 FX_DOUBLE nTemp = 1;
2781 for (int32_t j = 0; j <= i; j++) {
2782 nTemp *= 1 + nRate;
2783 }
2784 FX_DOUBLE nNum = *(pData + iIndex++);
2785 nSum += nNum / nTemp;
2786 }
2787 FXJSE_Value_SetDouble(args.GetReturnValue(), nSum);
2788 FX_Free(pData);
2789 pData = 0;
2790 }
2791 } else {
2792 FXJSE_Value_SetNull(args.GetReturnValue());
2793 }
Dan Sinclair1770c022016-03-14 14:14:16 -04002794 } else {
dsinclair2235b7b2016-06-02 07:42:25 -07002795 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"NPV");
Dan Sinclair1770c022016-03-14 14:14:16 -04002796 }
2797}
dsinclair48d91dd2016-05-31 11:54:01 -07002798
2799// static
dsinclair12a6b0c2016-05-26 11:14:08 -07002800void CXFA_FM2JSContext::Pmt(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04002801 const CFX_ByteStringC& szFuncName,
2802 CFXJSE_Arguments& args) {
dsinclairdd6a46c2016-05-26 08:41:45 -07002803 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07002804 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
Dan Sinclair1770c022016-03-14 14:14:16 -04002805 if (args.GetLength() == 3) {
2806 FX_BOOL bFlags = FALSE;
2807 FX_FLOAT nPrincipal = 0;
2808 FX_FLOAT nRate = 0;
2809 FX_FLOAT nPeriods = 0;
dsinclair86fad992016-05-31 11:34:04 -07002810 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
2811 std::unique_ptr<CFXJSE_Value> argTwo = GetSimpleValue(pThis, args, 1);
2812 std::unique_ptr<CFXJSE_Value> argThree = GetSimpleValue(pThis, args, 2);
2813 bFlags =
2814 (ValueIsNull(pThis, argOne.get()) || ValueIsNull(pThis, argTwo.get()) ||
2815 ValueIsNull(pThis, argThree.get()));
Dan Sinclair1770c022016-03-14 14:14:16 -04002816 if (bFlags) {
2817 FXJSE_Value_SetNull(args.GetReturnValue());
2818 } else {
dsinclair86fad992016-05-31 11:34:04 -07002819 nPrincipal = ValueToFloat(pThis, argOne.get());
2820 nRate = ValueToFloat(pThis, argTwo.get());
2821 nPeriods = ValueToFloat(pThis, argThree.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04002822 bFlags = ((nPrincipal <= 0) || (nRate <= 0) || (nPeriods <= 0));
2823 if (bFlags) {
dsinclair2235b7b2016-06-02 07:42:25 -07002824 pContext->ThrowException(XFA_IDS_ARGUMENT_MISMATCH);
Dan Sinclair1770c022016-03-14 14:14:16 -04002825 } else {
2826 FX_FLOAT nSum = 0;
2827 FX_FLOAT nTmp = 1 + nRate;
2828 nSum = nTmp;
2829 for (int32_t i = 0; i < nPeriods - 1; ++i) {
2830 nSum *= nTmp;
2831 }
2832 FXJSE_Value_SetFloat(args.GetReturnValue(),
2833 (nPrincipal * nRate * nSum) / (nSum - 1));
2834 }
2835 }
Dan Sinclair1770c022016-03-14 14:14:16 -04002836 } else {
dsinclair2235b7b2016-06-02 07:42:25 -07002837 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Pmt");
Dan Sinclair1770c022016-03-14 14:14:16 -04002838 }
2839}
dsinclair48d91dd2016-05-31 11:54:01 -07002840
2841// static
dsinclair12a6b0c2016-05-26 11:14:08 -07002842void CXFA_FM2JSContext::PPmt(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04002843 const CFX_ByteStringC& szFuncName,
2844 CFXJSE_Arguments& args) {
dsinclairdd6a46c2016-05-26 08:41:45 -07002845 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07002846 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
Dan Sinclair1770c022016-03-14 14:14:16 -04002847 if (args.GetLength() == 5) {
2848 FX_BOOL bFlags = FALSE;
2849 FX_FLOAT nPrincpalAmount = 0;
2850 FX_FLOAT nRate = 0;
2851 FX_FLOAT nPayment = 0;
2852 FX_FLOAT nFirstMonth = 0;
2853 FX_FLOAT nNumberOfMonths = 0;
dsinclair86fad992016-05-31 11:34:04 -07002854 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
2855 std::unique_ptr<CFXJSE_Value> argTwo = GetSimpleValue(pThis, args, 1);
2856 std::unique_ptr<CFXJSE_Value> argThree = GetSimpleValue(pThis, args, 2);
2857 std::unique_ptr<CFXJSE_Value> argFour = GetSimpleValue(pThis, args, 3);
2858 std::unique_ptr<CFXJSE_Value> argFive = GetSimpleValue(pThis, args, 4);
2859 bFlags =
2860 (ValueIsNull(pThis, argOne.get()) || ValueIsNull(pThis, argTwo.get()) ||
2861 ValueIsNull(pThis, argThree.get()) ||
2862 ValueIsNull(pThis, argFour.get()) ||
2863 ValueIsNull(pThis, argFive.get()));
Dan Sinclair1770c022016-03-14 14:14:16 -04002864 if (bFlags) {
2865 FXJSE_Value_SetNull(args.GetReturnValue());
2866 } else {
dsinclair86fad992016-05-31 11:34:04 -07002867 nPrincpalAmount = ValueToFloat(pThis, argOne.get());
2868 nRate = ValueToFloat(pThis, argTwo.get());
2869 nPayment = ValueToFloat(pThis, argThree.get());
2870 nFirstMonth = ValueToFloat(pThis, argFour.get());
2871 nNumberOfMonths = ValueToFloat(pThis, argFive.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04002872 bFlags = ((nPrincpalAmount <= 0) || (nRate <= 0) || (nPayment <= 0) ||
2873 (nFirstMonth < 0) || (nNumberOfMonths < 0));
2874 if (bFlags) {
dsinclair2235b7b2016-06-02 07:42:25 -07002875 pContext->ThrowException(XFA_IDS_ARGUMENT_MISMATCH);
Dan Sinclair1770c022016-03-14 14:14:16 -04002876 } else {
2877 int32_t iEnd = (int32_t)(nFirstMonth + nNumberOfMonths - 1);
2878 FX_FLOAT nSum = 0;
2879 FX_FLOAT nRateOfMonth = nRate / 12;
2880 int32_t iNums =
2881 (int32_t)((FXSYS_log10((FX_FLOAT)(nPayment / nPrincpalAmount)) -
2882 FXSYS_log10((FX_FLOAT)(nPayment / nPrincpalAmount -
2883 nRateOfMonth))) /
2884 FXSYS_log10((FX_FLOAT)(1 + nRateOfMonth)));
2885 if (iEnd > iNums) {
2886 iEnd = iNums;
2887 }
2888 if (nPayment < nPrincpalAmount * nRateOfMonth) {
2889 bFlags = TRUE;
2890 }
2891 if (!bFlags) {
2892 int32_t i = 0;
2893 for (i = 0; i < nFirstMonth - 1; ++i) {
2894 nPrincpalAmount -= nPayment - nPrincpalAmount * nRateOfMonth;
2895 }
2896 FX_FLOAT nTemp = 0;
2897 for (; i < iEnd; ++i) {
2898 nTemp = nPayment - nPrincpalAmount * nRateOfMonth;
2899 nSum += nTemp;
2900 nPrincpalAmount -= nTemp;
2901 }
2902 FXJSE_Value_SetFloat(args.GetReturnValue(), nSum);
2903 } else {
dsinclair2235b7b2016-06-02 07:42:25 -07002904 pContext->ThrowException(XFA_IDS_ARGUMENT_MISMATCH);
Dan Sinclair1770c022016-03-14 14:14:16 -04002905 }
2906 }
2907 }
Dan Sinclair1770c022016-03-14 14:14:16 -04002908 } else {
dsinclair2235b7b2016-06-02 07:42:25 -07002909 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"PPmt");
Dan Sinclair1770c022016-03-14 14:14:16 -04002910 }
2911}
dsinclair48d91dd2016-05-31 11:54:01 -07002912
2913// static
dsinclair12a6b0c2016-05-26 11:14:08 -07002914void CXFA_FM2JSContext::PV(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04002915 const CFX_ByteStringC& szFuncName,
2916 CFXJSE_Arguments& args) {
dsinclairdd6a46c2016-05-26 08:41:45 -07002917 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07002918 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
Dan Sinclair1770c022016-03-14 14:14:16 -04002919 if (args.GetLength() == 3) {
2920 FX_BOOL bFlags = FALSE;
2921 FX_DOUBLE nAmount = 0;
2922 FX_DOUBLE nRate = 0;
2923 FX_DOUBLE nPeriod = 0;
dsinclair86fad992016-05-31 11:34:04 -07002924 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
2925 std::unique_ptr<CFXJSE_Value> argTwo = GetSimpleValue(pThis, args, 1);
2926 std::unique_ptr<CFXJSE_Value> argThree = GetSimpleValue(pThis, args, 2);
2927 bFlags =
2928 (ValueIsNull(pThis, argOne.get()) || ValueIsNull(pThis, argTwo.get()) ||
2929 ValueIsNull(pThis, argThree.get()));
Dan Sinclair1770c022016-03-14 14:14:16 -04002930 if (bFlags) {
2931 FXJSE_Value_SetNull(args.GetReturnValue());
2932 } else {
dsinclair86fad992016-05-31 11:34:04 -07002933 nAmount = ValueToDouble(pThis, argOne.get());
2934 nRate = ValueToDouble(pThis, argTwo.get());
2935 nPeriod = ValueToDouble(pThis, argThree.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04002936 bFlags = ((nAmount <= 0) || (nRate < 0) || (nPeriod <= 0));
2937 if (bFlags) {
dsinclair2235b7b2016-06-02 07:42:25 -07002938 pContext->ThrowException(XFA_IDS_ARGUMENT_MISMATCH);
Dan Sinclair1770c022016-03-14 14:14:16 -04002939 } else {
2940 FX_DOUBLE nTemp = 1;
2941 for (int32_t i = 0; i < nPeriod; ++i) {
2942 nTemp *= 1 + nRate;
2943 }
2944 nTemp = 1 / nTemp;
2945 FXJSE_Value_SetDouble(args.GetReturnValue(),
2946 nAmount * ((1 - nTemp) / nRate));
2947 }
2948 }
Dan Sinclair1770c022016-03-14 14:14:16 -04002949 } else {
dsinclair2235b7b2016-06-02 07:42:25 -07002950 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"PV");
Dan Sinclair1770c022016-03-14 14:14:16 -04002951 }
2952}
dsinclair48d91dd2016-05-31 11:54:01 -07002953
2954// static
dsinclair12a6b0c2016-05-26 11:14:08 -07002955void CXFA_FM2JSContext::Rate(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04002956 const CFX_ByteStringC& szFuncName,
2957 CFXJSE_Arguments& args) {
dsinclairdd6a46c2016-05-26 08:41:45 -07002958 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07002959 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
Dan Sinclair1770c022016-03-14 14:14:16 -04002960 if (args.GetLength() == 3) {
2961 FX_BOOL bFlags = FALSE;
2962 FX_FLOAT nFuture = 0;
2963 FX_FLOAT nPresent = 0;
2964 FX_FLOAT nTotalNumber = 0;
dsinclair86fad992016-05-31 11:34:04 -07002965 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
2966 std::unique_ptr<CFXJSE_Value> argTwo = GetSimpleValue(pThis, args, 1);
2967 std::unique_ptr<CFXJSE_Value> argThree = GetSimpleValue(pThis, args, 2);
2968 bFlags =
2969 (ValueIsNull(pThis, argOne.get()) || ValueIsNull(pThis, argTwo.get()) ||
2970 ValueIsNull(pThis, argThree.get()));
Dan Sinclair1770c022016-03-14 14:14:16 -04002971 if (bFlags) {
2972 FXJSE_Value_SetNull(args.GetReturnValue());
2973 } else {
dsinclair86fad992016-05-31 11:34:04 -07002974 nFuture = ValueToFloat(pThis, argOne.get());
2975 nPresent = ValueToFloat(pThis, argTwo.get());
2976 nTotalNumber = ValueToFloat(pThis, argThree.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04002977 bFlags = ((nFuture <= 0) || (nPresent < 0) || (nTotalNumber <= 0));
2978 if (bFlags) {
dsinclair2235b7b2016-06-02 07:42:25 -07002979 pContext->ThrowException(XFA_IDS_ARGUMENT_MISMATCH);
Dan Sinclair1770c022016-03-14 14:14:16 -04002980 } else {
2981 FXJSE_Value_SetFloat(args.GetReturnValue(),
2982 (FXSYS_pow((FX_FLOAT)(nFuture / nPresent),
2983 (FX_FLOAT)(1 / nTotalNumber)) -
2984 1));
2985 }
2986 }
Dan Sinclair1770c022016-03-14 14:14:16 -04002987 } else {
dsinclair2235b7b2016-06-02 07:42:25 -07002988 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Rate");
Dan Sinclair1770c022016-03-14 14:14:16 -04002989 }
2990}
dsinclair48d91dd2016-05-31 11:54:01 -07002991
2992// static
dsinclair12a6b0c2016-05-26 11:14:08 -07002993void CXFA_FM2JSContext::Term(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04002994 const CFX_ByteStringC& szFuncName,
2995 CFXJSE_Arguments& args) {
dsinclairdd6a46c2016-05-26 08:41:45 -07002996 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07002997 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
Dan Sinclair1770c022016-03-14 14:14:16 -04002998 if (args.GetLength() == 3) {
2999 FX_BOOL bFlags = FALSE;
3000 FX_FLOAT nMount = 0;
3001 FX_FLOAT nRate = 0;
3002 FX_FLOAT nFuture = 0;
dsinclair86fad992016-05-31 11:34:04 -07003003 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
3004 std::unique_ptr<CFXJSE_Value> argTwo = GetSimpleValue(pThis, args, 1);
3005 std::unique_ptr<CFXJSE_Value> argThree = GetSimpleValue(pThis, args, 2);
3006 bFlags =
3007 (ValueIsNull(pThis, argOne.get()) || ValueIsNull(pThis, argTwo.get()) ||
3008 ValueIsNull(pThis, argThree.get()));
Dan Sinclair1770c022016-03-14 14:14:16 -04003009 if (bFlags) {
3010 FXJSE_Value_SetNull(args.GetReturnValue());
3011 } else {
dsinclair86fad992016-05-31 11:34:04 -07003012 nMount = ValueToFloat(pThis, argOne.get());
3013 nRate = ValueToFloat(pThis, argTwo.get());
3014 nFuture = ValueToFloat(pThis, argThree.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04003015 bFlags = ((nMount <= 0) || (nRate <= 0) || (nFuture <= 0));
3016 if (bFlags) {
dsinclair2235b7b2016-06-02 07:42:25 -07003017 pContext->ThrowException(XFA_IDS_ARGUMENT_MISMATCH);
Dan Sinclair1770c022016-03-14 14:14:16 -04003018 } else {
3019 FXJSE_Value_SetFloat(
3020 args.GetReturnValue(),
3021 (FXSYS_log((FX_FLOAT)(nFuture / nMount * nRate) + 1) /
3022 FXSYS_log((FX_FLOAT)(1 + nRate))));
3023 }
3024 }
Dan Sinclair1770c022016-03-14 14:14:16 -04003025 } else {
dsinclair2235b7b2016-06-02 07:42:25 -07003026 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Term");
Dan Sinclair1770c022016-03-14 14:14:16 -04003027 }
3028}
dsinclair48d91dd2016-05-31 11:54:01 -07003029
3030// static
dsinclair12a6b0c2016-05-26 11:14:08 -07003031void CXFA_FM2JSContext::Choose(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04003032 const CFX_ByteStringC& szFuncName,
3033 CFXJSE_Arguments& args) {
dsinclairdd6a46c2016-05-26 08:41:45 -07003034 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07003035 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclairec3da5b2016-05-25 16:42:05 -07003036 v8::Isolate* pIsolate = pContext->GetScriptRuntime();
Dan Sinclair1770c022016-03-14 14:14:16 -04003037 int32_t argc = args.GetLength();
3038 if (argc > 1) {
dsinclair86fad992016-05-31 11:34:04 -07003039 std::unique_ptr<CFXJSE_Value> argOne = args.GetValue(0);
Dan Sinclair1770c022016-03-14 14:14:16 -04003040 FX_BOOL argOneIsNull = FALSE;
3041 int32_t iIndex = 0;
dsinclair86fad992016-05-31 11:34:04 -07003042 argOneIsNull = ValueIsNull(pThis, argOne.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04003043 if (!argOneIsNull) {
dsinclair86fad992016-05-31 11:34:04 -07003044 iIndex = (int32_t)ValueToFloat(pThis, argOne.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04003045 }
Dan Sinclair1770c022016-03-14 14:14:16 -04003046 if (argOneIsNull) {
3047 FXJSE_Value_SetNull(args.GetReturnValue());
3048 } else if (iIndex < 1) {
3049 FXJSE_Value_SetUTF8String(args.GetReturnValue(), "");
3050 } else {
3051 FX_BOOL bFound = FALSE;
3052 FX_BOOL bStopCounterFlags = FALSE;
3053 int32_t iArgIndex = 1;
3054 int32_t iValueIndex = 0;
3055 while (!bFound && !bStopCounterFlags && (iArgIndex < argc)) {
dsinclair86fad992016-05-31 11:34:04 -07003056 std::unique_ptr<CFXJSE_Value> argIndexValue = args.GetValue(iArgIndex);
3057 if (FXJSE_Value_IsArray(argIndexValue.get())) {
3058 std::unique_ptr<CFXJSE_Value> lengthValue(new CFXJSE_Value(pIsolate));
3059 FXJSE_Value_GetObjectProp(argIndexValue.get(), "length",
3060 lengthValue.get());
3061 int32_t iLength = FXJSE_Value_ToInteger(lengthValue.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04003062 if (iLength > 3) {
3063 bStopCounterFlags = TRUE;
3064 }
3065 iValueIndex += (iLength - 2);
3066 if (iValueIndex >= iIndex) {
dsinclair86fad992016-05-31 11:34:04 -07003067 std::unique_ptr<CFXJSE_Value> propertyValue(
3068 new CFXJSE_Value(pIsolate));
3069 std::unique_ptr<CFXJSE_Value> jsObjectValue(
3070 new CFXJSE_Value(pIsolate));
3071 std::unique_ptr<CFXJSE_Value> newPropertyValue(
3072 new CFXJSE_Value(pIsolate));
3073 FXJSE_Value_GetObjectPropByIdx(argIndexValue.get(), 1,
3074 propertyValue.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04003075 FXJSE_Value_GetObjectPropByIdx(
dsinclair86fad992016-05-31 11:34:04 -07003076 argIndexValue.get(), ((iLength - 1) - (iValueIndex - iIndex)),
3077 jsObjectValue.get());
3078 if (FXJSE_Value_IsNull(propertyValue.get())) {
3079 GetObjectDefaultValue(jsObjectValue.get(),
3080 newPropertyValue.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04003081 } else {
3082 CFX_ByteString propStr;
dsinclair86fad992016-05-31 11:34:04 -07003083 FXJSE_Value_ToUTF8String(propertyValue.get(), propStr);
3084 FXJSE_Value_GetObjectProp(jsObjectValue.get(),
3085 propStr.AsStringC(),
3086 newPropertyValue.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04003087 }
3088 CFX_ByteString bsChoosed;
dsinclair86fad992016-05-31 11:34:04 -07003089 ValueToUTF8String(newPropertyValue.get(), bsChoosed);
tsepez28f97ff2016-04-04 16:41:35 -07003090 FXJSE_Value_SetUTF8String(args.GetReturnValue(),
tsepez4c3debb2016-04-08 12:20:38 -07003091 bsChoosed.AsStringC());
Dan Sinclair1770c022016-03-14 14:14:16 -04003092 bFound = TRUE;
3093 }
3094 } else {
3095 iValueIndex++;
3096 if (iValueIndex == iIndex) {
3097 CFX_ByteString bsChoosed;
dsinclair86fad992016-05-31 11:34:04 -07003098 ValueToUTF8String(argIndexValue.get(), bsChoosed);
tsepez28f97ff2016-04-04 16:41:35 -07003099 FXJSE_Value_SetUTF8String(args.GetReturnValue(),
tsepez4c3debb2016-04-08 12:20:38 -07003100 bsChoosed.AsStringC());
Dan Sinclair1770c022016-03-14 14:14:16 -04003101 bFound = TRUE;
3102 }
3103 }
Dan Sinclair1770c022016-03-14 14:14:16 -04003104 iArgIndex++;
3105 }
3106 if (!bFound) {
3107 FXJSE_Value_SetUTF8String(args.GetReturnValue(), "");
3108 }
3109 }
3110 } else {
3111 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07003112 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair2235b7b2016-06-02 07:42:25 -07003113 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Choose");
Dan Sinclair1770c022016-03-14 14:14:16 -04003114 }
3115}
dsinclair48d91dd2016-05-31 11:54:01 -07003116
3117// static
dsinclair12a6b0c2016-05-26 11:14:08 -07003118void CXFA_FM2JSContext::Exists(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04003119 const CFX_ByteStringC& szFuncName,
3120 CFXJSE_Arguments& args) {
3121 if (args.GetLength() == 1) {
dsinclair86fad992016-05-31 11:34:04 -07003122 std::unique_ptr<CFXJSE_Value> argOne = args.GetValue(0);
3123 FXJSE_Value_SetInteger(args.GetReturnValue(),
3124 FXJSE_Value_IsObject(argOne.get()));
Dan Sinclair1770c022016-03-14 14:14:16 -04003125 } else {
3126 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07003127 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair2235b7b2016-06-02 07:42:25 -07003128 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Exists");
Dan Sinclair1770c022016-03-14 14:14:16 -04003129 }
3130}
dsinclair48d91dd2016-05-31 11:54:01 -07003131
3132// static
dsinclair12a6b0c2016-05-26 11:14:08 -07003133void CXFA_FM2JSContext::HasValue(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04003134 const CFX_ByteStringC& szFuncName,
3135 CFXJSE_Arguments& args) {
3136 if (args.GetLength() == 1) {
dsinclair86fad992016-05-31 11:34:04 -07003137 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
3138 if (FXJSE_Value_IsUTF8String(argOne.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04003139 CFX_ByteString valueStr;
dsinclair86fad992016-05-31 11:34:04 -07003140 FXJSE_Value_ToUTF8String(argOne.get(), valueStr);
Dan Sinclair1770c022016-03-14 14:14:16 -04003141 valueStr.TrimLeft();
3142 FXJSE_Value_SetInteger(args.GetReturnValue(), (!valueStr.IsEmpty()));
dsinclair86fad992016-05-31 11:34:04 -07003143 } else if (FXJSE_Value_IsNumber(argOne.get()) ||
3144 FXJSE_Value_IsBoolean(argOne.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04003145 FXJSE_Value_SetInteger(args.GetReturnValue(), TRUE);
3146 } else {
3147 FXJSE_Value_SetInteger(args.GetReturnValue(), FALSE);
3148 }
Dan Sinclair1770c022016-03-14 14:14:16 -04003149 } else {
3150 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07003151 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair2235b7b2016-06-02 07:42:25 -07003152 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"HasValue");
Dan Sinclair1770c022016-03-14 14:14:16 -04003153 }
3154}
dsinclair48d91dd2016-05-31 11:54:01 -07003155
3156// static
dsinclair12a6b0c2016-05-26 11:14:08 -07003157void CXFA_FM2JSContext::Oneof(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04003158 const CFX_ByteStringC& szFuncName,
3159 CFXJSE_Arguments& args) {
dsinclair48d91dd2016-05-31 11:54:01 -07003160 if (args.GetLength() > 1) {
Dan Sinclair1770c022016-03-14 14:14:16 -04003161 FX_BOOL bFlags = FALSE;
dsinclair86fad992016-05-31 11:34:04 -07003162 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
dsinclair12a6b0c2016-05-26 11:14:08 -07003163 CFXJSE_Value** parametersValue = nullptr;
Dan Sinclair1770c022016-03-14 14:14:16 -04003164 int32_t iCount = 0;
dsinclair12a6b0c2016-05-26 11:14:08 -07003165 unfoldArgs(pThis, args, parametersValue, iCount, 1);
Dan Sinclair1770c022016-03-14 14:14:16 -04003166 for (int32_t i = 0; i < iCount; i++) {
dsinclair86fad992016-05-31 11:34:04 -07003167 if (simpleValueCompare(pThis, argOne.get(), parametersValue[i])) {
Dan Sinclair1770c022016-03-14 14:14:16 -04003168 bFlags = TRUE;
3169 break;
3170 }
3171 }
3172 FXJSE_Value_SetInteger(args.GetReturnValue(), bFlags);
Dan Sinclair1770c022016-03-14 14:14:16 -04003173 for (int32_t i = 0; i < iCount; i++) {
dsinclair86fad992016-05-31 11:34:04 -07003174 delete parametersValue[i];
Dan Sinclair1770c022016-03-14 14:14:16 -04003175 }
3176 FX_Free(parametersValue);
Dan Sinclair1770c022016-03-14 14:14:16 -04003177 } else {
3178 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07003179 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair2235b7b2016-06-02 07:42:25 -07003180 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Oneof");
Dan Sinclair1770c022016-03-14 14:14:16 -04003181 }
3182}
dsinclair48d91dd2016-05-31 11:54:01 -07003183
3184// static
dsinclair12a6b0c2016-05-26 11:14:08 -07003185void CXFA_FM2JSContext::Within(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04003186 const CFX_ByteStringC& szFuncName,
3187 CFXJSE_Arguments& args) {
dsinclair48d91dd2016-05-31 11:54:01 -07003188 if (args.GetLength() == 3) {
dsinclair86fad992016-05-31 11:34:04 -07003189 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
3190 if (FXJSE_Value_IsNull(argOne.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04003191 FXJSE_Value_SetUndefined(args.GetReturnValue());
3192 } else {
dsinclair86fad992016-05-31 11:34:04 -07003193 std::unique_ptr<CFXJSE_Value> argLow = GetSimpleValue(pThis, args, 1);
3194 std::unique_ptr<CFXJSE_Value> argHeight = GetSimpleValue(pThis, args, 2);
3195 if (FXJSE_Value_IsNumber(argOne.get())) {
3196 FX_FLOAT oneNumber = ValueToFloat(pThis, argOne.get());
3197 FX_FLOAT lowNumber = ValueToFloat(pThis, argLow.get());
3198 FX_FLOAT heightNumber = ValueToFloat(pThis, argHeight.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04003199 FXJSE_Value_SetInteger(
3200 args.GetReturnValue(),
3201 ((oneNumber >= lowNumber) && (oneNumber <= heightNumber)));
3202 } else {
3203 CFX_ByteString oneString;
3204 CFX_ByteString lowString;
3205 CFX_ByteString heightString;
dsinclair86fad992016-05-31 11:34:04 -07003206 ValueToUTF8String(argOne.get(), oneString);
3207 ValueToUTF8String(argLow.get(), lowString);
3208 ValueToUTF8String(argHeight.get(), heightString);
tsepez28f97ff2016-04-04 16:41:35 -07003209 FXJSE_Value_SetInteger(
3210 args.GetReturnValue(),
tsepez4c3debb2016-04-08 12:20:38 -07003211 ((oneString.Compare(lowString.AsStringC()) >= 0) &&
3212 (oneString.Compare(heightString.AsStringC()) <= 0)));
Dan Sinclair1770c022016-03-14 14:14:16 -04003213 }
Dan Sinclair1770c022016-03-14 14:14:16 -04003214 }
Dan Sinclair1770c022016-03-14 14:14:16 -04003215 } else {
3216 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07003217 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair2235b7b2016-06-02 07:42:25 -07003218 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Within");
Dan Sinclair1770c022016-03-14 14:14:16 -04003219 }
3220}
dsinclair48d91dd2016-05-31 11:54:01 -07003221
3222// static
dsinclair12a6b0c2016-05-26 11:14:08 -07003223void CXFA_FM2JSContext::If(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04003224 const CFX_ByteStringC& szFuncName,
3225 CFXJSE_Arguments& args) {
3226 if (args.GetLength() == 3) {
dsinclair86fad992016-05-31 11:34:04 -07003227 std::unique_ptr<CFXJSE_Value> argCondition = GetSimpleValue(pThis, args, 0);
3228 std::unique_ptr<CFXJSE_Value> argFirstValue =
3229 GetSimpleValue(pThis, args, 1);
3230 std::unique_ptr<CFXJSE_Value> argSecondValue =
3231 GetSimpleValue(pThis, args, 2);
3232 FX_BOOL bCondition = FXJSE_Value_ToBoolean(argCondition.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04003233 FXJSE_Value_Set(args.GetReturnValue(),
dsinclair86fad992016-05-31 11:34:04 -07003234 bCondition ? argFirstValue.get() : argSecondValue.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04003235 } else {
3236 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07003237 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair2235b7b2016-06-02 07:42:25 -07003238 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"If");
Dan Sinclair1770c022016-03-14 14:14:16 -04003239 }
3240}
dsinclair48d91dd2016-05-31 11:54:01 -07003241
3242// static
dsinclair12a6b0c2016-05-26 11:14:08 -07003243void CXFA_FM2JSContext::Eval(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04003244 const CFX_ByteStringC& szFuncName,
3245 CFXJSE_Arguments& args) {
dsinclairdd6a46c2016-05-26 08:41:45 -07003246 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07003247 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclairec3da5b2016-05-25 16:42:05 -07003248 v8::Isolate* pIsolate = pContext->GetScriptRuntime();
Dan Sinclair1770c022016-03-14 14:14:16 -04003249 if (args.GetLength() == 1) {
dsinclair86fad992016-05-31 11:34:04 -07003250 std::unique_ptr<CFXJSE_Value> scriptValue = GetSimpleValue(pThis, args, 0);
Dan Sinclair1770c022016-03-14 14:14:16 -04003251 CFX_ByteString utf8ScriptString;
dsinclair86fad992016-05-31 11:34:04 -07003252 ValueToUTF8String(scriptValue.get(), utf8ScriptString);
Dan Sinclair1770c022016-03-14 14:14:16 -04003253 if (utf8ScriptString.IsEmpty()) {
3254 FXJSE_Value_SetNull(args.GetReturnValue());
3255 } else {
3256 CFX_WideTextBuf wsJavaScriptBuf;
3257 CFX_WideString javaScript;
3258 CFX_WideString wsError;
dsinclaire80e9f82016-06-01 06:10:04 -07003259 CXFA_FM2JSContext::Translate(
tsepez4c3debb2016-04-08 12:20:38 -07003260 CFX_WideString::FromUTF8(utf8ScriptString.AsStringC()).AsStringC(),
tsepez6fe7d212016-04-06 10:51:14 -07003261 wsJavaScriptBuf, wsError);
tsepez3a005f22016-05-27 17:45:00 -07003262 CFXJSE_Context* pContext =
3263 FXJSE_Context_Create(pIsolate, nullptr, nullptr);
dsinclair86fad992016-05-31 11:34:04 -07003264 std::unique_ptr<CFXJSE_Value> returnValue(new CFXJSE_Value(pIsolate));
tsepez8e4c5052016-04-14 13:42:44 -07003265 javaScript = wsJavaScriptBuf.AsStringC();
tsepezb4c9f3f2016-04-13 15:41:21 -07003266 FXJSE_ExecuteScript(
dsinclair7f2abcc2016-05-26 09:40:27 -07003267 pContext,
tsepezbd9748d2016-04-13 21:40:19 -07003268 FX_UTF8Encode(javaScript.c_str(), javaScript.GetLength()).c_str(),
dsinclair86fad992016-05-31 11:34:04 -07003269 returnValue.get());
3270 FXJSE_Value_Set(args.GetReturnValue(), returnValue.get());
dsinclair7f2abcc2016-05-26 09:40:27 -07003271 FXJSE_Context_Release(pContext);
Dan Sinclair1770c022016-03-14 14:14:16 -04003272 }
Dan Sinclair1770c022016-03-14 14:14:16 -04003273 } else {
dsinclair2235b7b2016-06-02 07:42:25 -07003274 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Eval");
Dan Sinclair1770c022016-03-14 14:14:16 -04003275 }
3276}
dsinclair48d91dd2016-05-31 11:54:01 -07003277
3278// static
dsinclair12a6b0c2016-05-26 11:14:08 -07003279void CXFA_FM2JSContext::Ref(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04003280 const CFX_ByteStringC& szFuncName,
3281 CFXJSE_Arguments& args) {
dsinclairdd6a46c2016-05-26 08:41:45 -07003282 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07003283 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclairec3da5b2016-05-25 16:42:05 -07003284 v8::Isolate* pIsolate = pContext->GetScriptRuntime();
Dan Sinclair1770c022016-03-14 14:14:16 -04003285 if (args.GetLength() == 1) {
dsinclair86fad992016-05-31 11:34:04 -07003286 std::unique_ptr<CFXJSE_Value> argOne = args.GetValue(0);
3287 if (FXJSE_Value_IsNull(argOne.get())) {
dsinclair12a6b0c2016-05-26 11:14:08 -07003288 CFXJSE_Value* rgValues[3];
dsinclair86fad992016-05-31 11:34:04 -07003289 for (int32_t i = 0; i < 3; i++)
3290 rgValues[i] = new CFXJSE_Value(pIsolate);
3291
Dan Sinclair1770c022016-03-14 14:14:16 -04003292 FXJSE_Value_SetInteger(rgValues[0], 4);
3293 FXJSE_Value_SetNull(rgValues[1]);
3294 FXJSE_Value_SetNull(rgValues[2]);
3295 FXJSE_Value_SetArray(args.GetReturnValue(), 3, rgValues);
dsinclair86fad992016-05-31 11:34:04 -07003296 for (int32_t i = 0; i < 3; i++)
3297 delete rgValues[i];
3298
3299 } else if (FXJSE_Value_IsArray(argOne.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04003300#ifndef NDEBUG
dsinclair86fad992016-05-31 11:34:04 -07003301 std::unique_ptr<CFXJSE_Value> lengthValue(new CFXJSE_Value(pIsolate));
3302 FXJSE_Value_GetObjectProp(argOne.get(), "length", lengthValue.get());
3303 ASSERT(FXJSE_Value_ToInteger(lengthValue.get()) >= 3);
Dan Sinclair1770c022016-03-14 14:14:16 -04003304#endif
dsinclair86fad992016-05-31 11:34:04 -07003305 std::unique_ptr<CFXJSE_Value> propertyValue(new CFXJSE_Value(pIsolate));
3306 std::unique_ptr<CFXJSE_Value> jsObjectValue(new CFXJSE_Value(pIsolate));
3307 FXJSE_Value_GetObjectPropByIdx(argOne.get(), 1, propertyValue.get());
3308 FXJSE_Value_GetObjectPropByIdx(argOne.get(), 2, jsObjectValue.get());
3309 if (FXJSE_Value_IsNull(jsObjectValue.get())) {
dsinclair2235b7b2016-06-02 07:42:25 -07003310 pContext->ThrowException(XFA_IDS_ARGUMENT_MISMATCH);
dsinclair86fad992016-05-31 11:34:04 -07003311 } else if (FXJSE_Value_IsNull(propertyValue.get()) &&
3312 (!FXJSE_Value_IsNull(jsObjectValue.get()))) {
dsinclair12a6b0c2016-05-26 11:14:08 -07003313 CFXJSE_Value* rgValues[3];
dsinclair86fad992016-05-31 11:34:04 -07003314 for (int32_t i = 0; i < 3; i++)
3315 rgValues[i] = new CFXJSE_Value(pIsolate);
3316
Dan Sinclair1770c022016-03-14 14:14:16 -04003317 FXJSE_Value_SetInteger(rgValues[0], 3);
3318 FXJSE_Value_SetNull(rgValues[1]);
dsinclair86fad992016-05-31 11:34:04 -07003319 FXJSE_Value_Set(rgValues[2], jsObjectValue.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04003320 FXJSE_Value_SetArray(args.GetReturnValue(), 3, rgValues);
dsinclair86fad992016-05-31 11:34:04 -07003321 for (int32_t i = 0; i < 3; i++)
3322 delete rgValues[i];
3323
Dan Sinclair1770c022016-03-14 14:14:16 -04003324 } else {
dsinclair2235b7b2016-06-02 07:42:25 -07003325 pContext->ThrowException(XFA_IDS_ARGUMENT_MISMATCH);
Dan Sinclair1770c022016-03-14 14:14:16 -04003326 }
dsinclair86fad992016-05-31 11:34:04 -07003327 } else if (FXJSE_Value_IsObject(argOne.get())) {
dsinclair12a6b0c2016-05-26 11:14:08 -07003328 CFXJSE_Value* rgValues[3];
dsinclair86fad992016-05-31 11:34:04 -07003329 for (int32_t i = 0; i < 3; i++)
3330 rgValues[i] = new CFXJSE_Value(pIsolate);
3331
Dan Sinclair1770c022016-03-14 14:14:16 -04003332 FXJSE_Value_SetInteger(rgValues[0], 3);
3333 FXJSE_Value_SetNull(rgValues[1]);
dsinclair86fad992016-05-31 11:34:04 -07003334 FXJSE_Value_Set(rgValues[2], argOne.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04003335 FXJSE_Value_SetArray(args.GetReturnValue(), 3, rgValues);
dsinclair86fad992016-05-31 11:34:04 -07003336
3337 for (int32_t i = 0; i < 3; i++)
3338 delete rgValues[i];
3339 } else if (FXJSE_Value_IsBoolean(argOne.get()) ||
3340 FXJSE_Value_IsUTF8String(argOne.get()) ||
3341 FXJSE_Value_IsNumber(argOne.get())) {
3342 FXJSE_Value_Set(args.GetReturnValue(), argOne.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04003343 } else {
dsinclair2235b7b2016-06-02 07:42:25 -07003344 pContext->ThrowException(XFA_IDS_ARGUMENT_MISMATCH);
Dan Sinclair1770c022016-03-14 14:14:16 -04003345 }
Dan Sinclair1770c022016-03-14 14:14:16 -04003346 } else {
dsinclair2235b7b2016-06-02 07:42:25 -07003347 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Ref");
Dan Sinclair1770c022016-03-14 14:14:16 -04003348 }
3349}
dsinclair48d91dd2016-05-31 11:54:01 -07003350
3351// static
dsinclair12a6b0c2016-05-26 11:14:08 -07003352void CXFA_FM2JSContext::UnitType(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04003353 const CFX_ByteStringC& szFuncName,
3354 CFXJSE_Arguments& args) {
3355 if (args.GetLength() == 1) {
dsinclair86fad992016-05-31 11:34:04 -07003356 std::unique_ptr<CFXJSE_Value> unitspanValue =
3357 GetSimpleValue(pThis, args, 0);
3358 if (FXJSE_Value_IsNull(unitspanValue.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04003359 FXJSE_Value_SetNull(args.GetReturnValue());
Dan Sinclair1770c022016-03-14 14:14:16 -04003360 return;
3361 }
3362 CFX_ByteString unitspanString;
dsinclair86fad992016-05-31 11:34:04 -07003363 ValueToUTF8String(unitspanValue.get(), unitspanString);
Dan Sinclair1770c022016-03-14 14:14:16 -04003364 if (unitspanString.IsEmpty()) {
3365 FXJSE_Value_SetUTF8String(args.GetReturnValue(), "in");
3366 } else {
3367 enum XFA_FM2JS_VALUETYPE_ParserStatus {
3368 VALUETYPE_START,
3369 VALUETYPE_HAVEINVALIDCHAR,
3370 VALUETYPE_HAVEDIGIT,
3371 VALUETYPE_HAVEDIGITWHITE,
3372 VALUETYPE_ISCM,
3373 VALUETYPE_ISMM,
3374 VALUETYPE_ISPT,
3375 VALUETYPE_ISMP,
3376 VALUETYPE_ISIN,
3377 };
3378 unitspanString.MakeLower();
3379 CFX_WideString wsTypeString =
tsepez4c3debb2016-04-08 12:20:38 -07003380 CFX_WideString::FromUTF8(unitspanString.AsStringC());
tsepezbd9748d2016-04-13 21:40:19 -07003381 const FX_WCHAR* pData = wsTypeString.c_str();
Dan Sinclair1770c022016-03-14 14:14:16 -04003382 int32_t u = 0;
3383 int32_t uLen = wsTypeString.GetLength();
3384 while (*(pData + u) == 0x20 || *(pData + u) == 0x09 ||
3385 *(pData + u) == 0x0B || *(pData + u) == 0x0C ||
3386 *(pData + u) == 0x0A || *(pData + u) == 0x0D) {
3387 u++;
3388 }
3389 XFA_FM2JS_VALUETYPE_ParserStatus eParserStatus = VALUETYPE_START;
3390 FX_WCHAR typeChar;
3391 while (u < uLen) {
3392 typeChar = *(pData + u);
3393 if (typeChar == 0x20 || typeChar == 0x09 || typeChar == 0x0B ||
3394 typeChar == 0x0C || typeChar == 0x0A || typeChar == 0x0D) {
3395 if (eParserStatus == VALUETYPE_HAVEDIGIT ||
3396 eParserStatus == VALUETYPE_HAVEDIGITWHITE) {
3397 eParserStatus = VALUETYPE_HAVEDIGITWHITE;
3398 } else {
3399 eParserStatus = VALUETYPE_ISIN;
3400 break;
3401 }
3402 } else if ((typeChar >= '0' && typeChar <= '9') || typeChar == '-' ||
3403 typeChar == '.') {
3404 if (eParserStatus == VALUETYPE_HAVEDIGITWHITE) {
3405 eParserStatus = VALUETYPE_ISIN;
3406 break;
3407 } else {
3408 eParserStatus = VALUETYPE_HAVEDIGIT;
3409 }
3410 } else if ((typeChar == 'c' || typeChar == 'p') && (u + 1 < uLen)) {
3411 FX_WCHAR nextChar = *(pData + u + 1);
3412 if ((eParserStatus == VALUETYPE_START ||
3413 eParserStatus == VALUETYPE_HAVEDIGIT ||
3414 eParserStatus == VALUETYPE_HAVEDIGITWHITE) &&
3415 (nextChar > '9' || nextChar < '0') && nextChar != '.' &&
3416 nextChar != '-') {
3417 eParserStatus = (typeChar == 'c') ? VALUETYPE_ISCM : VALUETYPE_ISPT;
3418 break;
3419 } else {
3420 eParserStatus = VALUETYPE_HAVEINVALIDCHAR;
3421 }
3422 } else if (typeChar == 'm' && (u + 1 < uLen)) {
3423 FX_WCHAR nextChar = *(pData + u + 1);
3424 if ((eParserStatus == VALUETYPE_START ||
3425 eParserStatus == VALUETYPE_HAVEDIGIT ||
3426 eParserStatus == VALUETYPE_HAVEDIGITWHITE) &&
3427 (nextChar > '9' || nextChar < '0') && nextChar != '.' &&
3428 nextChar != '-') {
3429 eParserStatus = VALUETYPE_ISMM;
3430 if (nextChar == 'p' ||
3431 ((u + 5 < uLen) && *(pData + u + 1) == 'i' &&
3432 *(pData + u + 2) == 'l' && *(pData + u + 3) == 'l' &&
3433 *(pData + u + 4) == 'i' && *(pData + u + 5) == 'p')) {
3434 eParserStatus = VALUETYPE_ISMP;
3435 }
3436 break;
3437 }
3438 } else {
3439 eParserStatus = VALUETYPE_HAVEINVALIDCHAR;
3440 }
3441 u++;
3442 }
3443 switch (eParserStatus) {
3444 case VALUETYPE_ISCM:
3445 FXJSE_Value_SetUTF8String(args.GetReturnValue(), "cm");
3446 break;
3447 case VALUETYPE_ISMM:
3448 FXJSE_Value_SetUTF8String(args.GetReturnValue(), "mm");
3449 break;
3450 case VALUETYPE_ISPT:
3451 FXJSE_Value_SetUTF8String(args.GetReturnValue(), "pt");
3452 break;
3453 case VALUETYPE_ISMP:
3454 FXJSE_Value_SetUTF8String(args.GetReturnValue(), "mp");
3455 break;
3456 default:
3457 FXJSE_Value_SetUTF8String(args.GetReturnValue(), "in");
3458 break;
3459 }
3460 }
Dan Sinclair1770c022016-03-14 14:14:16 -04003461 } else {
3462 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07003463 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair2235b7b2016-06-02 07:42:25 -07003464 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"UnitType");
Dan Sinclair1770c022016-03-14 14:14:16 -04003465 }
3466}
dsinclair48d91dd2016-05-31 11:54:01 -07003467
3468// static
dsinclair12a6b0c2016-05-26 11:14:08 -07003469void CXFA_FM2JSContext::UnitValue(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04003470 const CFX_ByteStringC& szFuncName,
3471 CFXJSE_Arguments& args) {
3472 int32_t argc = args.GetLength();
3473 if ((argc == 1) || (argc == 2)) {
dsinclair86fad992016-05-31 11:34:04 -07003474 std::unique_ptr<CFXJSE_Value> unitspanValue =
3475 GetSimpleValue(pThis, args, 0);
Dan Sinclair1770c022016-03-14 14:14:16 -04003476 CFX_ByteString unitspanString;
3477 FX_DOUBLE dFirstNumber = 0;
3478 CFX_ByteString strFirstUnit;
3479 CFX_ByteString strUnit;
dsinclair86fad992016-05-31 11:34:04 -07003480 if (FXJSE_Value_IsNull(unitspanValue.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04003481 FXJSE_Value_SetNull(args.GetReturnValue());
3482 } else {
dsinclair86fad992016-05-31 11:34:04 -07003483 ValueToUTF8String(unitspanValue.get(), unitspanString);
tsepezb4c9f3f2016-04-13 15:41:21 -07003484 const FX_CHAR* pData = unitspanString.c_str();
Dan Sinclair1770c022016-03-14 14:14:16 -04003485 if (pData) {
3486 int32_t u = 0;
3487 while (*(pData + u) == 0x20 || *(pData + u) == 0x09 ||
3488 *(pData + u) == 0x0B || *(pData + u) == 0x0C ||
3489 *(pData + u) == 0x0A || *(pData + u) == 0x0D) {
3490 ++u;
3491 }
3492 while (u < unitspanString.GetLength()) {
3493 if ((*(pData + u) > '9' || *(pData + u) < '0') &&
3494 *(pData + u) != '.' && *(pData + u) != '-') {
3495 break;
3496 }
3497 ++u;
3498 }
dsinclair48d91dd2016-05-31 11:54:01 -07003499 FX_CHAR* pTemp = nullptr;
Dan Sinclair1770c022016-03-14 14:14:16 -04003500 dFirstNumber = strtod(pData, &pTemp);
3501 while (*(pData + u) == ' ' || *(pData + u) == 0x09 ||
3502 *(pData + u) == 0x0B || *(pData + u) == 0x0C ||
3503 *(pData + u) == 0x0A || *(pData + u) == 0x0D) {
3504 ++u;
3505 }
3506 int32_t uLen = unitspanString.GetLength();
3507 while (u < uLen) {
3508 if (*(pData + u) == ' ') {
3509 break;
3510 }
3511 strFirstUnit += (*(pData + u));
3512 ++u;
3513 }
3514 strFirstUnit.MakeLower();
3515 if (argc == 2) {
dsinclair86fad992016-05-31 11:34:04 -07003516 std::unique_ptr<CFXJSE_Value> unitValue =
3517 GetSimpleValue(pThis, args, 1);
Dan Sinclair1770c022016-03-14 14:14:16 -04003518 CFX_ByteString unitTempString;
dsinclair86fad992016-05-31 11:34:04 -07003519 ValueToUTF8String(unitValue.get(), unitTempString);
tsepezb4c9f3f2016-04-13 15:41:21 -07003520 const FX_CHAR* pData = unitTempString.c_str();
Dan Sinclair1770c022016-03-14 14:14:16 -04003521 int32_t u = 0;
3522 while (*(pData + u) == ' ' || *(pData + u) == 0x09 ||
3523 *(pData + u) == 0x0B || *(pData + u) == 0x0C ||
3524 *(pData + u) == 0x0A || *(pData + u) == 0x0D) {
3525 ++u;
3526 }
3527 while (u < unitTempString.GetLength()) {
3528 if ((*(pData + u) > '9' || *(pData + u) < '0') &&
3529 *(pData + u) != '.') {
3530 break;
3531 }
3532 ++u;
3533 }
3534 while (*(pData + u) == ' ' || *(pData + u) == 0x09 ||
3535 *(pData + u) == 0x0B || *(pData + u) == 0x0C ||
3536 *(pData + u) == 0x0A || *(pData + u) == 0x0D) {
3537 ++u;
3538 }
3539 int32_t uLen = unitTempString.GetLength();
3540 while (u < uLen) {
3541 if (*(pData + u) == ' ') {
3542 break;
3543 }
3544 strUnit += (*(pData + u));
3545 ++u;
3546 }
3547 strUnit.MakeLower();
3548 } else {
3549 strUnit = strFirstUnit;
3550 }
3551 FX_DOUBLE dResult = 0;
tsepez9f2970c2016-04-01 10:23:04 -07003552 if (strFirstUnit == "in" || strFirstUnit == "inches") {
3553 if (strUnit == "mm" || strUnit == "millimeters") {
Dan Sinclair1770c022016-03-14 14:14:16 -04003554 dResult = dFirstNumber * 25.4;
tsepez9f2970c2016-04-01 10:23:04 -07003555 } else if (strUnit == "cm" || strUnit == "centimeters") {
Dan Sinclair1770c022016-03-14 14:14:16 -04003556 dResult = dFirstNumber * 2.54;
tsepez9f2970c2016-04-01 10:23:04 -07003557 } else if (strUnit == "pt" || strUnit == "points") {
Dan Sinclair1770c022016-03-14 14:14:16 -04003558 dResult = dFirstNumber / 72;
tsepez9f2970c2016-04-01 10:23:04 -07003559 } else if (strUnit == "mp" || strUnit == "millipoints") {
Dan Sinclair1770c022016-03-14 14:14:16 -04003560 dResult = dFirstNumber / 72000;
3561 } else {
3562 dResult = dFirstNumber;
3563 }
tsepez9f2970c2016-04-01 10:23:04 -07003564 } else if (strFirstUnit == "mm" || strFirstUnit == "millimeters") {
3565 if (strUnit == "mm" || strUnit == "millimeters") {
Dan Sinclair1770c022016-03-14 14:14:16 -04003566 dResult = dFirstNumber;
tsepez9f2970c2016-04-01 10:23:04 -07003567 } else if (strUnit == "cm" || strUnit == "centimeters") {
Dan Sinclair1770c022016-03-14 14:14:16 -04003568 dResult = dFirstNumber / 10;
tsepez9f2970c2016-04-01 10:23:04 -07003569 } else if (strUnit == "pt" || strUnit == "points") {
Dan Sinclair1770c022016-03-14 14:14:16 -04003570 dResult = dFirstNumber / 25.4 / 72;
tsepez9f2970c2016-04-01 10:23:04 -07003571 } else if (strUnit == "mp" || strUnit == "millipoints") {
Dan Sinclair1770c022016-03-14 14:14:16 -04003572 dResult = dFirstNumber / 25.4 / 72000;
3573 } else {
3574 dResult = dFirstNumber / 25.4;
3575 }
tsepez9f2970c2016-04-01 10:23:04 -07003576 } else if (strFirstUnit == "cm" || strFirstUnit == "centimeters") {
3577 if (strUnit == "mm" || strUnit == "millimeters") {
Dan Sinclair1770c022016-03-14 14:14:16 -04003578 dResult = dFirstNumber * 10;
tsepez9f2970c2016-04-01 10:23:04 -07003579 } else if (strUnit == "cm" || strUnit == "centimeters") {
Dan Sinclair1770c022016-03-14 14:14:16 -04003580 dResult = dFirstNumber;
tsepez9f2970c2016-04-01 10:23:04 -07003581 } else if (strUnit == "pt" || strUnit == "points") {
Dan Sinclair1770c022016-03-14 14:14:16 -04003582 dResult = dFirstNumber / 2.54 / 72;
tsepez9f2970c2016-04-01 10:23:04 -07003583 } else if (strUnit == "mp" || strUnit == "millipoints") {
Dan Sinclair1770c022016-03-14 14:14:16 -04003584 dResult = dFirstNumber / 2.54 / 72000;
3585 } else {
3586 dResult = dFirstNumber / 2.54;
3587 }
tsepez9f2970c2016-04-01 10:23:04 -07003588 } else if (strFirstUnit == "pt" || strFirstUnit == "points") {
3589 if (strUnit == "mm" || strUnit == "millimeters") {
Dan Sinclair1770c022016-03-14 14:14:16 -04003590 dResult = dFirstNumber / 72 * 25.4;
tsepez9f2970c2016-04-01 10:23:04 -07003591 } else if (strUnit == "cm" || strUnit == "centimeters") {
Dan Sinclair1770c022016-03-14 14:14:16 -04003592 dResult = dFirstNumber / 72 * 2.54;
tsepez9f2970c2016-04-01 10:23:04 -07003593 } else if (strUnit == "pt" || strUnit == "points") {
Dan Sinclair1770c022016-03-14 14:14:16 -04003594 dResult = dFirstNumber;
tsepez9f2970c2016-04-01 10:23:04 -07003595 } else if (strUnit == "mp" || strUnit == "millipoints") {
Dan Sinclair1770c022016-03-14 14:14:16 -04003596 dResult = dFirstNumber * 1000;
3597 } else {
3598 dResult = dFirstNumber / 72;
3599 }
tsepez9f2970c2016-04-01 10:23:04 -07003600 } else if (strFirstUnit == "mp" || strFirstUnit == "millipoints") {
3601 if (strUnit == "mm" || strUnit == "millimeters") {
Dan Sinclair1770c022016-03-14 14:14:16 -04003602 dResult = dFirstNumber / 72000 * 25.4;
tsepez9f2970c2016-04-01 10:23:04 -07003603 } else if (strUnit == "cm" || strUnit == "centimeters") {
Dan Sinclair1770c022016-03-14 14:14:16 -04003604 dResult = dFirstNumber / 72000 * 2.54;
tsepez9f2970c2016-04-01 10:23:04 -07003605 } else if (strUnit == "pt" || strUnit == "points") {
Dan Sinclair1770c022016-03-14 14:14:16 -04003606 dResult = dFirstNumber / 1000;
tsepez9f2970c2016-04-01 10:23:04 -07003607 } else if (strUnit == "mp" || strUnit == "millipoints") {
Dan Sinclair1770c022016-03-14 14:14:16 -04003608 dResult = dFirstNumber;
3609 } else {
3610 dResult = dFirstNumber / 72000;
3611 }
3612 }
3613 FXJSE_Value_SetDouble(args.GetReturnValue(), dResult);
3614 } else {
3615 FXJSE_Value_SetInteger(args.GetReturnValue(), 0);
3616 }
3617 }
Dan Sinclair1770c022016-03-14 14:14:16 -04003618 } else {
3619 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07003620 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair2235b7b2016-06-02 07:42:25 -07003621 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"UnitValue");
Dan Sinclair1770c022016-03-14 14:14:16 -04003622 }
3623}
dsinclair48d91dd2016-05-31 11:54:01 -07003624
3625// static
dsinclair12a6b0c2016-05-26 11:14:08 -07003626void CXFA_FM2JSContext::At(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04003627 const CFX_ByteStringC& szFuncName,
3628 CFXJSE_Arguments& args) {
Dan Sinclair1770c022016-03-14 14:14:16 -04003629 if (args.GetLength() == 2) {
dsinclair86fad992016-05-31 11:34:04 -07003630 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
3631 std::unique_ptr<CFXJSE_Value> argTwo = GetSimpleValue(pThis, args, 1);
3632 if (ValueIsNull(pThis, argOne.get()) || ValueIsNull(pThis, argTwo.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04003633 FXJSE_Value_SetNull(args.GetReturnValue());
3634 } else {
3635 CFX_ByteString stringTwo;
dsinclair86fad992016-05-31 11:34:04 -07003636 ValueToUTF8String(argTwo.get(), stringTwo);
Dan Sinclair1770c022016-03-14 14:14:16 -04003637 if (stringTwo.IsEmpty()) {
3638 FXJSE_Value_SetInteger(args.GetReturnValue(), 1);
3639 } else {
3640 CFX_ByteString stringOne;
dsinclair86fad992016-05-31 11:34:04 -07003641 ValueToUTF8String(argOne.get(), stringOne);
tsepez4c3debb2016-04-08 12:20:38 -07003642 FX_STRSIZE iPosition = stringOne.Find(stringTwo.AsStringC());
Dan Sinclair1770c022016-03-14 14:14:16 -04003643 FXJSE_Value_SetInteger(args.GetReturnValue(), iPosition + 1);
3644 }
3645 }
Dan Sinclair1770c022016-03-14 14:14:16 -04003646 } else {
dsinclair48d91dd2016-05-31 11:54:01 -07003647 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07003648 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair2235b7b2016-06-02 07:42:25 -07003649 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"At");
Dan Sinclair1770c022016-03-14 14:14:16 -04003650 }
3651}
dsinclair48d91dd2016-05-31 11:54:01 -07003652
3653// static
dsinclair12a6b0c2016-05-26 11:14:08 -07003654void CXFA_FM2JSContext::Concat(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04003655 const CFX_ByteStringC& szFuncName,
3656 CFXJSE_Arguments& args) {
Dan Sinclair1770c022016-03-14 14:14:16 -04003657 int32_t argc = args.GetLength();
3658 if (argc >= 1) {
3659 CFX_ByteString resultString;
3660 FX_BOOL bAllNull = TRUE;
dsinclair86fad992016-05-31 11:34:04 -07003661
Dan Sinclair1770c022016-03-14 14:14:16 -04003662 for (int32_t i = 0; i < argc; i++) {
dsinclair86fad992016-05-31 11:34:04 -07003663 std::unique_ptr<CFXJSE_Value> value = GetSimpleValue(pThis, args, i);
3664 if (!ValueIsNull(pThis, value.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04003665 CFX_ByteString valueStr;
dsinclair86fad992016-05-31 11:34:04 -07003666 ValueToUTF8String(value.get(), valueStr);
Dan Sinclair1770c022016-03-14 14:14:16 -04003667 resultString += valueStr;
3668 bAllNull = FALSE;
3669 }
3670 }
dsinclair86fad992016-05-31 11:34:04 -07003671
Dan Sinclair1770c022016-03-14 14:14:16 -04003672 if (bAllNull) {
3673 FXJSE_Value_SetNull(args.GetReturnValue());
3674 } else {
tsepez28f97ff2016-04-04 16:41:35 -07003675 FXJSE_Value_SetUTF8String(args.GetReturnValue(),
tsepez4c3debb2016-04-08 12:20:38 -07003676 resultString.AsStringC());
Dan Sinclair1770c022016-03-14 14:14:16 -04003677 }
3678 } else {
dsinclair48d91dd2016-05-31 11:54:01 -07003679 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07003680 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair2235b7b2016-06-02 07:42:25 -07003681 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Concat");
Dan Sinclair1770c022016-03-14 14:14:16 -04003682 }
3683}
dsinclair48d91dd2016-05-31 11:54:01 -07003684
3685// static
dsinclair12a6b0c2016-05-26 11:14:08 -07003686void CXFA_FM2JSContext::Decode(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04003687 const CFX_ByteStringC& szFuncName,
3688 CFXJSE_Arguments& args) {
Dan Sinclair1770c022016-03-14 14:14:16 -04003689 int32_t argc = args.GetLength();
3690 if (argc == 1) {
dsinclair86fad992016-05-31 11:34:04 -07003691 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
3692 if (ValueIsNull(pThis, argOne.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04003693 FXJSE_Value_SetNull(args.GetReturnValue());
3694 } else {
3695 CFX_ByteString toDecodeString;
dsinclair86fad992016-05-31 11:34:04 -07003696 ValueToUTF8String(argOne.get(), toDecodeString);
Dan Sinclair1770c022016-03-14 14:14:16 -04003697 CFX_ByteTextBuf resultBuf;
tsepez4c3debb2016-04-08 12:20:38 -07003698 DecodeURL(toDecodeString.AsStringC(), resultBuf);
tsepez8e4c5052016-04-14 13:42:44 -07003699 FXJSE_Value_SetUTF8String(args.GetReturnValue(), resultBuf.AsStringC());
Dan Sinclair1770c022016-03-14 14:14:16 -04003700 }
Dan Sinclair1770c022016-03-14 14:14:16 -04003701 } else if (argc == 2) {
dsinclair86fad992016-05-31 11:34:04 -07003702 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
3703 std::unique_ptr<CFXJSE_Value> argTwo = GetSimpleValue(pThis, args, 1);
3704 if (ValueIsNull(pThis, argOne.get()) || ValueIsNull(pThis, argTwo.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04003705 FXJSE_Value_SetNull(args.GetReturnValue());
3706 } else {
3707 CFX_ByteString toDecodeString;
dsinclair86fad992016-05-31 11:34:04 -07003708 ValueToUTF8String(argOne.get(), toDecodeString);
Dan Sinclair1770c022016-03-14 14:14:16 -04003709 CFX_ByteString identifyString;
dsinclair86fad992016-05-31 11:34:04 -07003710 ValueToUTF8String(argTwo.get(), identifyString);
Dan Sinclair1770c022016-03-14 14:14:16 -04003711 CFX_ByteTextBuf resultBuf;
3712 if (identifyString.EqualNoCase("html")) {
tsepez4c3debb2016-04-08 12:20:38 -07003713 DecodeHTML(toDecodeString.AsStringC(), resultBuf);
Dan Sinclair1770c022016-03-14 14:14:16 -04003714 } else if (identifyString.EqualNoCase("xml")) {
tsepez4c3debb2016-04-08 12:20:38 -07003715 DecodeXML(toDecodeString.AsStringC(), resultBuf);
Dan Sinclair1770c022016-03-14 14:14:16 -04003716 } else {
tsepez4c3debb2016-04-08 12:20:38 -07003717 DecodeURL(toDecodeString.AsStringC(), resultBuf);
Dan Sinclair1770c022016-03-14 14:14:16 -04003718 }
tsepez8e4c5052016-04-14 13:42:44 -07003719 FXJSE_Value_SetUTF8String(args.GetReturnValue(), resultBuf.AsStringC());
Dan Sinclair1770c022016-03-14 14:14:16 -04003720 }
Dan Sinclair1770c022016-03-14 14:14:16 -04003721 } else {
dsinclair48d91dd2016-05-31 11:54:01 -07003722 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07003723 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair2235b7b2016-06-02 07:42:25 -07003724 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Decode");
Dan Sinclair1770c022016-03-14 14:14:16 -04003725 }
3726}
dsinclair48d91dd2016-05-31 11:54:01 -07003727
3728// static
Dan Sinclair1770c022016-03-14 14:14:16 -04003729void CXFA_FM2JSContext::DecodeURL(const CFX_ByteStringC& szURLString,
3730 CFX_ByteTextBuf& szResultString) {
tsepez6fe7d212016-04-06 10:51:14 -07003731 CFX_WideString wsURLString = CFX_WideString::FromUTF8(szURLString);
tsepezbd9748d2016-04-13 21:40:19 -07003732 const FX_WCHAR* pData = wsURLString.c_str();
Dan Sinclair1770c022016-03-14 14:14:16 -04003733 int32_t iLen = wsURLString.GetLength();
3734 int32_t i = 0;
3735 FX_WCHAR ch = 0;
3736 FX_WCHAR chTemp = 0;
3737 CFX_WideTextBuf wsResultBuf;
3738 while (i < iLen) {
3739 ch = *(pData + i);
3740 if ('%' == ch) {
3741 chTemp = 0;
3742 int32_t iCount = 0;
3743 while (iCount < 2) {
3744 ++i;
3745 ch = *(pData + i);
3746 if (ch <= '9' && ch >= '0') {
3747 if (!iCount) {
3748 chTemp += (ch - '0') * 16;
3749 } else {
3750 chTemp += (ch - '0');
3751 }
3752 } else {
3753 if (ch <= 'F' && ch >= 'A') {
3754 if (!iCount) {
3755 chTemp += (ch - 'A' + 10) * 16;
3756 } else {
3757 chTemp += (ch - 'A' + 10);
3758 }
3759 } else if (ch <= 'f' && ch >= 'a') {
3760 if (!iCount) {
3761 chTemp += (ch - 'a' + 10) * 16;
3762 } else {
3763 chTemp += (ch - 'a' + 10);
3764 }
3765 } else {
3766 wsResultBuf.Clear();
3767 return;
3768 }
3769 }
3770 ++iCount;
3771 }
3772 wsResultBuf.AppendChar(chTemp);
3773 } else {
3774 wsResultBuf.AppendChar(ch);
3775 }
3776 ++i;
3777 }
3778 wsResultBuf.AppendChar(0);
3779 szResultString.Clear();
3780 szResultString << FX_UTF8Encode(wsResultBuf.GetBuffer(),
tsepez28f97ff2016-04-04 16:41:35 -07003781 wsResultBuf.GetLength())
tsepez4c3debb2016-04-08 12:20:38 -07003782 .AsStringC();
Dan Sinclair1770c022016-03-14 14:14:16 -04003783}
dsinclair48d91dd2016-05-31 11:54:01 -07003784
3785// static
Dan Sinclair1770c022016-03-14 14:14:16 -04003786void CXFA_FM2JSContext::DecodeHTML(const CFX_ByteStringC& szHTMLString,
3787 CFX_ByteTextBuf& szResultString) {
tsepez6fe7d212016-04-06 10:51:14 -07003788 CFX_WideString wsHTMLString = CFX_WideString::FromUTF8(szHTMLString);
Dan Sinclair1770c022016-03-14 14:14:16 -04003789 FX_WCHAR strString[9];
3790 int32_t iStrIndex = 0;
3791 int32_t iLen = wsHTMLString.GetLength();
3792 int32_t i = 0;
3793 int32_t iCode = 0;
3794 FX_WCHAR ch = 0;
tsepezbd9748d2016-04-13 21:40:19 -07003795 const FX_WCHAR* pData = wsHTMLString.c_str();
Dan Sinclair1770c022016-03-14 14:14:16 -04003796 CFX_WideTextBuf wsResultBuf;
3797 while (i < iLen) {
3798 ch = *(pData + i);
3799 if (ch == '&') {
3800 ++i;
3801 ch = *(pData + i);
3802 if (ch == '#') {
3803 ++i;
3804 ch = *(pData + i);
3805 if (ch == 'x' || ch == 'X') {
3806 ++i;
3807 ch = *(pData + i);
3808 if ((ch >= '0' && ch <= '9') || (ch <= 'f' && ch >= 'a') ||
3809 (ch <= 'F' && ch >= 'A')) {
3810 while (ch != ';' && i < iLen) {
3811 if (ch >= '0' && ch <= '9') {
3812 iCode += ch - '0';
3813 } else if (ch <= 'f' && ch >= 'a') {
3814 iCode += ch - 'a' + 10;
3815 } else if (ch <= 'F' && ch >= 'A') {
3816 iCode += ch - 'A' + 10;
3817 } else {
3818 wsResultBuf.Clear();
3819 return;
3820 }
3821 ++i;
3822 iCode *= 16;
3823 ch = *(pData + i);
3824 }
3825 iCode /= 16;
3826 }
3827 } else {
3828 wsResultBuf.Clear();
3829 return;
3830 }
3831 } else {
3832 while (ch != ';' && i < iLen) {
3833 strString[iStrIndex++] = ch;
3834 ++i;
3835 ch = *(pData + i);
3836 }
3837 strString[iStrIndex] = 0;
3838 }
3839 } else {
3840 wsResultBuf.AppendChar(ch);
3841 ++i;
3842 continue;
3843 }
3844 uint32_t iData = 0;
3845 if (HTMLSTR2Code(strString, iData)) {
3846 wsResultBuf.AppendChar((FX_WCHAR)iData);
3847 } else {
3848 wsResultBuf.AppendChar(iCode);
3849 }
3850 iStrIndex = 0;
3851 strString[iStrIndex] = 0;
3852 ++i;
3853 }
3854 wsResultBuf.AppendChar(0);
3855 szResultString.Clear();
3856 szResultString << FX_UTF8Encode(wsResultBuf.GetBuffer(),
tsepez28f97ff2016-04-04 16:41:35 -07003857 wsResultBuf.GetLength())
tsepez4c3debb2016-04-08 12:20:38 -07003858 .AsStringC();
Dan Sinclair1770c022016-03-14 14:14:16 -04003859}
dsinclair48d91dd2016-05-31 11:54:01 -07003860
3861// static
Dan Sinclair1770c022016-03-14 14:14:16 -04003862void CXFA_FM2JSContext::DecodeXML(const CFX_ByteStringC& szXMLString,
3863 CFX_ByteTextBuf& szResultString) {
tsepez6fe7d212016-04-06 10:51:14 -07003864 CFX_WideString wsXMLString = CFX_WideString::FromUTF8(szXMLString);
Dan Sinclair1770c022016-03-14 14:14:16 -04003865 FX_WCHAR strString[9];
3866 int32_t iStrIndex = 0;
3867 int32_t iLen = wsXMLString.GetLength();
3868 int32_t i = 0;
3869 int32_t iCode = 0;
3870 FX_WCHAR ch = 0;
tsepezbd9748d2016-04-13 21:40:19 -07003871 const FX_WCHAR* pData = wsXMLString.c_str();
Dan Sinclair1770c022016-03-14 14:14:16 -04003872 CFX_WideTextBuf wsXMLBuf;
3873 while (i < iLen) {
3874 ch = *(pData + i);
3875 if (ch == '&') {
3876 ++i;
3877 ch = *(pData + i);
3878 if (ch == '#') {
3879 ++i;
3880 ch = *(pData + i);
3881 if (ch == 'x' || ch == 'X') {
3882 ++i;
3883 ch = *(pData + i);
3884 if ((ch >= '0' && ch <= '9') || (ch <= 'f' && ch >= 'a') ||
3885 (ch <= 'F' && ch >= 'A')) {
3886 while (ch != ';') {
3887 if (ch >= '0' && ch <= '9') {
3888 iCode += ch - '0';
3889 } else if (ch <= 'f' && ch >= 'a') {
3890 iCode += ch - 'a' + 10;
3891 } else if (ch <= 'F' && ch >= 'A') {
3892 iCode += ch - 'A' + 10;
3893 } else {
3894 wsXMLBuf.Clear();
3895 return;
3896 }
3897 ++i;
3898 iCode *= 16;
3899 ch = *(pData + i);
3900 }
3901 iCode /= 16;
3902 }
3903 } else {
3904 wsXMLBuf.Clear();
3905 return;
3906 }
3907 } else {
3908 while (ch != ';' && i < iLen) {
3909 strString[iStrIndex++] = ch;
3910 ++i;
3911 ch = *(pData + i);
3912 }
3913 strString[iStrIndex] = 0;
3914 }
3915 } else {
3916 wsXMLBuf.AppendChar(ch);
3917 ++i;
3918 continue;
3919 }
3920 const FX_WCHAR* const strName[] = {L"quot", L"amp", L"apos", L"lt", L"gt"};
3921 int32_t iIndex = 0;
3922 while (iIndex < 5) {
3923 if (FXSYS_memcmp(strString, strName[iIndex],
3924 FXSYS_wcslen(strName[iIndex])) == 0) {
3925 break;
3926 }
3927 ++iIndex;
3928 }
3929 switch (iIndex) {
3930 case 0:
3931 wsXMLBuf.AppendChar('"');
3932 break;
3933 case 1:
3934 wsXMLBuf.AppendChar('&');
3935 break;
3936 case 2:
3937 wsXMLBuf.AppendChar('\'');
3938 break;
3939 case 3:
3940 wsXMLBuf.AppendChar('<');
3941 break;
3942 case 4:
3943 wsXMLBuf.AppendChar('>');
3944 break;
3945 default:
3946 wsXMLBuf.AppendChar(iCode);
3947 break;
3948 }
3949 iStrIndex = 0;
3950 strString[iStrIndex] = 0;
3951 ++i;
3952 iCode = 0;
3953 }
3954 wsXMLBuf.AppendChar(0);
3955 szResultString.Clear();
tsepez28f97ff2016-04-04 16:41:35 -07003956 szResultString << FX_UTF8Encode(wsXMLBuf.GetBuffer(), wsXMLBuf.GetLength())
tsepez4c3debb2016-04-08 12:20:38 -07003957 .AsStringC();
Dan Sinclair1770c022016-03-14 14:14:16 -04003958}
dsinclair48d91dd2016-05-31 11:54:01 -07003959
3960// static
dsinclair12a6b0c2016-05-26 11:14:08 -07003961void CXFA_FM2JSContext::Encode(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04003962 const CFX_ByteStringC& szFuncName,
3963 CFXJSE_Arguments& args) {
Dan Sinclair1770c022016-03-14 14:14:16 -04003964 int32_t argc = args.GetLength();
3965 if (argc == 1) {
dsinclair86fad992016-05-31 11:34:04 -07003966 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
3967 if (ValueIsNull(pThis, argOne.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04003968 FXJSE_Value_SetNull(args.GetReturnValue());
3969 } else {
3970 CFX_ByteString toEncodeString;
dsinclair86fad992016-05-31 11:34:04 -07003971 ValueToUTF8String(argOne.get(), toEncodeString);
Dan Sinclair1770c022016-03-14 14:14:16 -04003972 CFX_ByteTextBuf resultBuf;
tsepez4c3debb2016-04-08 12:20:38 -07003973 EncodeURL(toEncodeString.AsStringC(), resultBuf);
tsepez8e4c5052016-04-14 13:42:44 -07003974 FXJSE_Value_SetUTF8String(args.GetReturnValue(), resultBuf.AsStringC());
Dan Sinclair1770c022016-03-14 14:14:16 -04003975 }
Dan Sinclair1770c022016-03-14 14:14:16 -04003976 } else if (argc == 2) {
dsinclair86fad992016-05-31 11:34:04 -07003977 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
3978 std::unique_ptr<CFXJSE_Value> argTwo = GetSimpleValue(pThis, args, 1);
3979 if (ValueIsNull(pThis, argOne.get()) || ValueIsNull(pThis, argTwo.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04003980 FXJSE_Value_SetNull(args.GetReturnValue());
3981 } else {
3982 CFX_ByteString toEncodeString;
dsinclair86fad992016-05-31 11:34:04 -07003983 ValueToUTF8String(argOne.get(), toEncodeString);
Dan Sinclair1770c022016-03-14 14:14:16 -04003984 CFX_ByteString identifyString;
dsinclair86fad992016-05-31 11:34:04 -07003985 ValueToUTF8String(argTwo.get(), identifyString);
Dan Sinclair1770c022016-03-14 14:14:16 -04003986 CFX_ByteTextBuf resultBuf;
3987 if (identifyString.EqualNoCase("html")) {
tsepez4c3debb2016-04-08 12:20:38 -07003988 EncodeHTML(toEncodeString.AsStringC(), resultBuf);
Dan Sinclair1770c022016-03-14 14:14:16 -04003989 } else if (identifyString.EqualNoCase("xml")) {
tsepez4c3debb2016-04-08 12:20:38 -07003990 EncodeXML(toEncodeString.AsStringC(), resultBuf);
Dan Sinclair1770c022016-03-14 14:14:16 -04003991 } else {
tsepez4c3debb2016-04-08 12:20:38 -07003992 EncodeURL(toEncodeString.AsStringC(), resultBuf);
Dan Sinclair1770c022016-03-14 14:14:16 -04003993 }
tsepez8e4c5052016-04-14 13:42:44 -07003994 FXJSE_Value_SetUTF8String(args.GetReturnValue(), resultBuf.AsStringC());
Dan Sinclair1770c022016-03-14 14:14:16 -04003995 }
Dan Sinclair1770c022016-03-14 14:14:16 -04003996 } else {
dsinclair48d91dd2016-05-31 11:54:01 -07003997 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07003998 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair2235b7b2016-06-02 07:42:25 -07003999 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Encode");
Dan Sinclair1770c022016-03-14 14:14:16 -04004000 }
4001}
dsinclair48d91dd2016-05-31 11:54:01 -07004002
4003// static
Dan Sinclair1770c022016-03-14 14:14:16 -04004004void CXFA_FM2JSContext::EncodeURL(const CFX_ByteStringC& szURLString,
4005 CFX_ByteTextBuf& szResultBuf) {
tsepez6fe7d212016-04-06 10:51:14 -07004006 CFX_WideString wsURLString = CFX_WideString::FromUTF8(szURLString);
Dan Sinclair1770c022016-03-14 14:14:16 -04004007 CFX_WideTextBuf wsResultBuf;
4008 FX_WCHAR ch = 0;
4009 int32_t iLength = wsURLString.GetLength();
4010 FX_WCHAR strEncode[4];
4011 strEncode[0] = '%';
4012 strEncode[3] = 0;
4013 FX_WCHAR strUnsafe[] = {' ', '<', '>', '"', '#', '%', '{', '}',
4014 '|', '\\', '^', '~', '[', ']', '`'};
4015 FX_WCHAR strReserved[] = {';', '/', '?', ':', '@', '=', '&'};
4016 FX_WCHAR strSpecial[] = {'$', '-', '+', '!', '*', '\'', '(', ')', ','};
4017 const FX_WCHAR* strCode = L"0123456789abcdef";
4018 for (int32_t u = 0; u < iLength; ++u) {
4019 ch = wsURLString.GetAt(u);
4020 int32_t i = 0;
4021 int32_t iCount = sizeof(strUnsafe) / sizeof(strUnsafe[0]);
4022 while (i < iCount) {
4023 if (ch == strUnsafe[i]) {
4024 int32_t iIndex = ch / 16;
4025 strEncode[1] = strCode[iIndex];
4026 strEncode[2] = strCode[ch - iIndex * 16];
4027 wsResultBuf << FX_WSTRC(strEncode);
4028 break;
4029 }
4030 ++i;
4031 }
4032 if (i < iCount) {
4033 continue;
4034 }
4035 i = 0;
4036 iCount = sizeof(strReserved) / sizeof(strReserved[0]);
4037 while (i < iCount) {
4038 if (ch == strReserved[i]) {
4039 int32_t iIndex = ch / 16;
4040 strEncode[1] = strCode[iIndex];
4041 strEncode[2] = strCode[ch - iIndex * 16];
4042 wsResultBuf << FX_WSTRC(strEncode);
4043 break;
4044 }
4045 ++i;
4046 }
4047 if (i < iCount) {
4048 continue;
4049 }
4050 i = 0;
4051 iCount = sizeof(strSpecial) / sizeof(strSpecial[0]);
4052 while (i < iCount) {
4053 if (ch == strSpecial[i]) {
4054 wsResultBuf.AppendChar(ch);
4055 break;
4056 }
4057 ++i;
4058 }
4059 if (i < iCount) {
4060 continue;
4061 }
4062 if (ch >= 0x80 && ch <= 0xff) {
4063 int32_t iIndex = ch / 16;
4064 strEncode[1] = strCode[iIndex];
4065 strEncode[2] = strCode[ch - iIndex * 16];
4066 wsResultBuf << FX_WSTRC(strEncode);
4067 } else if (ch <= 0x1f || ch == 0x7f) {
4068 int32_t iIndex = ch / 16;
4069 strEncode[1] = strCode[iIndex];
4070 strEncode[2] = strCode[ch - iIndex * 16];
4071 wsResultBuf << FX_WSTRC(strEncode);
4072 } else if (ch >= 0x20 && ch <= 0x7e) {
4073 wsResultBuf.AppendChar(ch);
4074 } else {
ochangf6be1452016-06-01 12:20:03 -07004075 const FX_WCHAR iRadix = 16;
Dan Sinclair1770c022016-03-14 14:14:16 -04004076 CFX_WideString strTmp;
4077 while (ch >= iRadix) {
4078 FX_WCHAR tmp = strCode[ch % iRadix];
4079 ch /= iRadix;
4080 strTmp += tmp;
4081 }
4082 strTmp += strCode[ch];
4083 int32_t iLen = strTmp.GetLength();
4084 if (iLen < 2) {
4085 break;
4086 }
4087 int32_t iIndex = 0;
4088 if (iLen % 2 != 0) {
4089 strEncode[1] = '0';
4090 strEncode[2] = strTmp.GetAt(iLen - 1);
4091 iIndex = iLen - 2;
4092 } else {
4093 strEncode[1] = strTmp.GetAt(iLen - 1);
4094 strEncode[2] = strTmp.GetAt(iLen - 2);
4095 iIndex = iLen - 3;
4096 }
4097 wsResultBuf << FX_WSTRC(strEncode);
4098 while (iIndex > 0) {
4099 strEncode[1] = strTmp.GetAt(iIndex);
4100 strEncode[2] = strTmp.GetAt(iIndex - 1);
4101 iIndex -= 2;
4102 wsResultBuf << FX_WSTRC(strEncode);
4103 }
4104 }
4105 }
4106 wsResultBuf.AppendChar(0);
4107 szResultBuf.Clear();
tsepez28f97ff2016-04-04 16:41:35 -07004108 szResultBuf << FX_UTF8Encode(wsResultBuf.GetBuffer(), wsResultBuf.GetLength())
tsepez4c3debb2016-04-08 12:20:38 -07004109 .AsStringC();
Dan Sinclair1770c022016-03-14 14:14:16 -04004110}
dsinclair48d91dd2016-05-31 11:54:01 -07004111
4112// static
Dan Sinclair1770c022016-03-14 14:14:16 -04004113void CXFA_FM2JSContext::EncodeHTML(const CFX_ByteStringC& szHTMLString,
4114 CFX_ByteTextBuf& szResultBuf) {
dsinclair179bebb2016-04-05 11:02:18 -07004115 CFX_ByteString str = szHTMLString.c_str();
tsepez4c3debb2016-04-08 12:20:38 -07004116 CFX_WideString wsHTMLString = CFX_WideString::FromUTF8(str.AsStringC());
Dan Sinclair1770c022016-03-14 14:14:16 -04004117 const FX_WCHAR* strCode = L"0123456789abcdef";
4118 FX_WCHAR strEncode[9];
4119 strEncode[0] = '&';
4120 strEncode[1] = '#';
4121 strEncode[2] = 'x';
4122 strEncode[5] = ';';
4123 strEncode[6] = 0;
4124 strEncode[7] = ';';
4125 strEncode[8] = 0;
4126 CFX_WideTextBuf wsResultBuf;
4127 uint32_t ch = 0;
4128 int32_t iLen = wsHTMLString.GetLength();
4129 int32_t i = 0;
tsepezbd9748d2016-04-13 21:40:19 -07004130 const FX_WCHAR* pData = wsHTMLString.c_str();
Dan Sinclair1770c022016-03-14 14:14:16 -04004131 int32_t iIndex = 0;
4132 CFX_WideString htmlReserve;
4133 while (i < iLen) {
4134 ch = *(pData + i);
tsepez774bdde2016-04-14 09:49:44 -07004135 htmlReserve.clear();
Dan Sinclair1770c022016-03-14 14:14:16 -04004136 if (HTMLCode2STR(ch, htmlReserve)) {
4137 wsResultBuf.AppendChar(L'&');
4138 wsResultBuf << htmlReserve;
4139 wsResultBuf.AppendChar(L';');
4140 } else {
4141 if (ch >= 32 && ch <= 126) {
4142 wsResultBuf.AppendChar((FX_WCHAR)ch);
4143 } else if (ch < 256) {
4144 iIndex = ch / 16;
4145 strEncode[3] = strCode[iIndex];
4146 strEncode[4] = strCode[ch - iIndex * 16];
4147 strEncode[5] = ';';
4148 strEncode[6] = 0;
4149 wsResultBuf << FX_WSTRC(strEncode);
4150 } else {
4151 int32_t iBigByte = ch / 256;
4152 int32_t iLittleByte = ch % 256;
4153 strEncode[3] = strCode[iBigByte / 16];
4154 strEncode[4] = strCode[iBigByte % 16];
4155 strEncode[5] = strCode[iLittleByte / 16];
4156 strEncode[6] = strCode[iLittleByte % 16];
4157 wsResultBuf << FX_WSTRC(strEncode);
4158 }
4159 }
4160 ++i;
4161 }
4162 wsResultBuf.AppendChar(0);
4163 szResultBuf.Clear();
tsepez28f97ff2016-04-04 16:41:35 -07004164 szResultBuf << FX_UTF8Encode(wsResultBuf.GetBuffer(), wsResultBuf.GetLength())
tsepez4c3debb2016-04-08 12:20:38 -07004165 .AsStringC();
Dan Sinclair1770c022016-03-14 14:14:16 -04004166}
dsinclair48d91dd2016-05-31 11:54:01 -07004167
4168// static
Dan Sinclair1770c022016-03-14 14:14:16 -04004169void CXFA_FM2JSContext::EncodeXML(const CFX_ByteStringC& szXMLString,
4170 CFX_ByteTextBuf& szResultBuf) {
tsepez6fe7d212016-04-06 10:51:14 -07004171 CFX_WideString wsXMLString = CFX_WideString::FromUTF8(szXMLString);
Dan Sinclair1770c022016-03-14 14:14:16 -04004172 CFX_WideTextBuf wsResultBuf;
4173 enum {
4174 QUOT,
4175 AMP,
4176 APOS,
4177 LT,
4178 GT,
4179 };
4180 FX_WCHAR strEncode[9];
4181 strEncode[0] = '&';
4182 strEncode[1] = '#';
4183 strEncode[2] = 'x';
4184 strEncode[5] = ';';
4185 strEncode[6] = 0;
4186 strEncode[7] = ';';
4187 strEncode[8] = 0;
4188 const FX_WCHAR* const strName[] = {L"quot", L"amp", L"apos", L"lt", L"gt"};
4189 const FX_WCHAR* strCode = L"0123456789abcdef";
4190 FX_WCHAR ch = 0;
4191 int32_t iLength = wsXMLString.GetLength();
4192 int32_t iIndex = 0;
4193 int32_t u = 0;
tsepezbd9748d2016-04-13 21:40:19 -07004194 const FX_WCHAR* pData = wsXMLString.c_str();
Dan Sinclair1770c022016-03-14 14:14:16 -04004195 for (u = 0; u < iLength; ++u) {
4196 ch = *(pData + u);
4197 switch (ch) {
4198 case '"':
4199 wsResultBuf.AppendChar('&');
4200 wsResultBuf << CFX_WideStringC(strName[QUOT]);
4201 wsResultBuf.AppendChar(';');
4202 break;
4203 case '&':
4204 wsResultBuf.AppendChar('&');
4205 wsResultBuf << CFX_WideStringC(strName[AMP]);
4206 wsResultBuf.AppendChar(';');
4207 break;
4208 case '\'':
4209 wsResultBuf.AppendChar('&');
4210 wsResultBuf << CFX_WideStringC(strName[APOS]);
4211 wsResultBuf.AppendChar(';');
4212 break;
4213 case '<':
4214 wsResultBuf.AppendChar('&');
4215 wsResultBuf << CFX_WideStringC(strName[LT]);
4216 wsResultBuf.AppendChar(';');
4217 break;
4218 case '>':
4219 wsResultBuf.AppendChar('&');
4220 wsResultBuf << CFX_WideStringC(strName[GT]);
4221 wsResultBuf.AppendChar(';');
4222 break;
4223 default: {
4224 if (ch >= 32 && ch <= 126) {
4225 wsResultBuf.AppendChar(ch);
4226 } else if (ch < 256) {
4227 iIndex = ch / 16;
4228 strEncode[3] = strCode[iIndex];
4229 strEncode[4] = strCode[ch - iIndex * 16];
4230 strEncode[5] = ';';
4231 strEncode[6] = 0;
4232 wsResultBuf << FX_WSTRC(strEncode);
4233 } else {
4234 int32_t iBigByte = ch / 256;
4235 int32_t iLittleByte = ch % 256;
4236 strEncode[3] = strCode[iBigByte / 16];
4237 strEncode[4] = strCode[iBigByte % 16];
4238 strEncode[5] = strCode[iLittleByte / 16];
4239 strEncode[6] = strCode[iLittleByte % 16];
4240 wsResultBuf << FX_WSTRC(strEncode);
4241 }
4242 } break;
4243 }
4244 }
4245 wsResultBuf.AppendChar(0);
4246 szResultBuf.Clear();
tsepez28f97ff2016-04-04 16:41:35 -07004247 szResultBuf << FX_UTF8Encode(wsResultBuf.GetBuffer(), wsResultBuf.GetLength())
tsepez4c3debb2016-04-08 12:20:38 -07004248 .AsStringC();
Dan Sinclair1770c022016-03-14 14:14:16 -04004249}
dsinclair48d91dd2016-05-31 11:54:01 -07004250
4251// static
Dan Sinclair1770c022016-03-14 14:14:16 -04004252FX_BOOL CXFA_FM2JSContext::HTMLSTR2Code(const CFX_WideStringC& pData,
4253 uint32_t& iCode) {
tsepezb6853cf2016-04-25 11:23:43 -07004254 uint32_t uHash = FX_HashCode_GetW(pData, false);
4255 int32_t iStart = 0;
4256 int32_t iEnd = FX_ArraySize(reservesForDecode) - 1;
Dan Sinclair1770c022016-03-14 14:14:16 -04004257 do {
tsepezb6853cf2016-04-25 11:23:43 -07004258 int32_t iMid = (iStart + iEnd) / 2;
4259 XFA_FMHtmlHashedReserveCode htmlhashedreservecode = reservesForDecode[iMid];
Dan Sinclair1770c022016-03-14 14:14:16 -04004260 if (uHash == htmlhashedreservecode.m_uHash) {
4261 iCode = htmlhashedreservecode.m_uCode;
4262 return TRUE;
tsepezb6853cf2016-04-25 11:23:43 -07004263 }
4264 if (uHash < htmlhashedreservecode.m_uHash) {
Dan Sinclair1770c022016-03-14 14:14:16 -04004265 iEnd = iMid - 1;
4266 } else {
4267 iStart = iMid + 1;
4268 }
4269 } while (iStart <= iEnd);
4270 return FALSE;
4271}
dsinclair48d91dd2016-05-31 11:54:01 -07004272
4273// static
Dan Sinclair1770c022016-03-14 14:14:16 -04004274FX_BOOL CXFA_FM2JSContext::HTMLCode2STR(uint32_t iCode,
4275 CFX_WideString& wsHTMLReserve) {
4276 XFA_FMHtmlReserveCode htmlreservecode;
4277 int32_t iStart = 0,
4278 iEnd = (sizeof(reservesForEncode) / sizeof(reservesForEncode[0])) - 1;
4279 int32_t iMid = (iStart + iEnd) / 2;
4280 do {
4281 iMid = (iStart + iEnd) / 2;
4282 htmlreservecode = reservesForEncode[iMid];
4283 if (iCode == htmlreservecode.m_uCode) {
4284 wsHTMLReserve = htmlreservecode.m_htmlReserve;
4285 return TRUE;
4286 } else if (iCode < htmlreservecode.m_uCode) {
4287 iEnd = iMid - 1;
4288 } else {
4289 iStart = iMid + 1;
4290 }
4291 } while (iStart <= iEnd);
4292 return FALSE;
4293}
dsinclair48d91dd2016-05-31 11:54:01 -07004294
4295// static
dsinclair12a6b0c2016-05-26 11:14:08 -07004296void CXFA_FM2JSContext::Format(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04004297 const CFX_ByteStringC& szFuncName,
4298 CFXJSE_Arguments& args) {
dsinclairdd6a46c2016-05-26 08:41:45 -07004299 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07004300 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair48d91dd2016-05-31 11:54:01 -07004301 if (args.GetLength() >= 2) {
dsinclair86fad992016-05-31 11:34:04 -07004302 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
4303 std::unique_ptr<CFXJSE_Value> argTwo = GetSimpleValue(pThis, args, 1);
Dan Sinclair1770c022016-03-14 14:14:16 -04004304 CFX_ByteString szPattern;
dsinclair86fad992016-05-31 11:34:04 -07004305 ValueToUTF8String(argOne.get(), szPattern);
Dan Sinclair1770c022016-03-14 14:14:16 -04004306 CFX_ByteString szValue;
dsinclair86fad992016-05-31 11:34:04 -07004307 ValueToUTF8String(argTwo.get(), szValue);
Dan Sinclair1770c022016-03-14 14:14:16 -04004308 CXFA_Document* pDoc = pContext->GetDocument();
4309 IFX_LocaleMgr* pMgr = (IFX_LocaleMgr*)pDoc->GetLocalMgr();
4310 CXFA_Node* pThisNode = ToNode(pDoc->GetScriptContext()->GetThisObject());
dsinclair43854a52016-04-27 12:26:00 -07004311 ASSERT(pThisNode);
Dan Sinclair1770c022016-03-14 14:14:16 -04004312 CXFA_WidgetData widgetData(pThisNode);
4313 IFX_Locale* pLocale = widgetData.GetLocal();
tsepez736f28a2016-03-25 14:19:51 -07004314 uint32_t patternType;
tsepez4c3debb2016-04-08 12:20:38 -07004315 CFX_WideString wsPattern = CFX_WideString::FromUTF8(szPattern.AsStringC());
4316 CFX_WideString wsValue = CFX_WideString::FromUTF8(szValue.AsStringC());
dsinclair48d91dd2016-05-31 11:54:01 -07004317 if (!PatternStringType(szPattern.AsStringC(), patternType)) {
Dan Sinclair1770c022016-03-14 14:14:16 -04004318 switch (patternType) {
4319 case XFA_VT_DATETIME: {
4320 FX_STRSIZE iTChar = wsPattern.Find(L'T');
tsepezafe94302016-05-13 17:21:31 -07004321 CFX_WideString wsDatePattern(L"date{");
Dan Sinclair1770c022016-03-14 14:14:16 -04004322 wsDatePattern += wsPattern.Left(iTChar);
4323 wsDatePattern += FX_WSTRC(L"} ");
tsepezafe94302016-05-13 17:21:31 -07004324 CFX_WideString wsTimePattern(L"time{");
Dan Sinclair1770c022016-03-14 14:14:16 -04004325 wsTimePattern += wsPattern.Mid(iTChar + 1);
4326 wsTimePattern += FX_WSTRC(L"}");
4327 wsPattern = wsDatePattern + wsTimePattern;
4328 } break;
4329 case XFA_VT_DATE: {
4330 wsPattern = FX_WSTRC(L"date{") + wsPattern;
4331 wsPattern += FX_WSTRC(L"}");
4332 } break;
4333 case XFA_VT_TIME: {
4334 wsPattern = FX_WSTRC(L"time{") + wsPattern;
4335 wsPattern += FX_WSTRC(L"}");
4336 } break;
4337 case XFA_VT_TEXT: {
4338 wsPattern = FX_WSTRC(L"text{") + wsPattern;
4339 wsPattern += FX_WSTRC(L"}");
4340 } break;
4341 case XFA_VT_FLOAT: {
4342 wsPattern = FX_WSTRC(L"num{") + wsPattern;
4343 wsPattern += FX_WSTRC(L"}");
4344 } break;
4345 default: {
4346 CFX_WideString wsTestPattern;
4347 wsTestPattern = FX_WSTRC(L"num{") + wsPattern;
4348 wsTestPattern += FX_WSTRC(L"}");
4349 CXFA_LocaleValue tempLocaleValue(XFA_VT_FLOAT, wsValue, wsTestPattern,
4350 pLocale, (CXFA_LocaleMgr*)pMgr);
4351 if (tempLocaleValue.IsValid()) {
4352 wsPattern = wsTestPattern;
4353 patternType = XFA_VT_FLOAT;
4354 } else {
4355 wsTestPattern = FX_WSTRC(L"text{") + wsPattern;
4356 wsTestPattern += FX_WSTRC(L"}");
4357 wsPattern = wsTestPattern;
4358 patternType = XFA_VT_TEXT;
4359 }
4360 } break;
4361 }
4362 }
4363 CXFA_LocaleValue localeValue(patternType, wsValue, wsPattern, pLocale,
4364 (CXFA_LocaleMgr*)pMgr);
4365 CFX_WideString wsRet;
4366 if (localeValue.FormatPatterns(wsRet, wsPattern, pLocale,
4367 XFA_VALUEPICTURE_Display)) {
tsepez28f97ff2016-04-04 16:41:35 -07004368 FXJSE_Value_SetUTF8String(
4369 args.GetReturnValue(),
tsepezbd9748d2016-04-13 21:40:19 -07004370 FX_UTF8Encode(wsRet.c_str(), wsRet.GetLength()).AsStringC());
Dan Sinclair1770c022016-03-14 14:14:16 -04004371 } else {
4372 FXJSE_Value_SetUTF8String(args.GetReturnValue(), "");
4373 }
Dan Sinclair1770c022016-03-14 14:14:16 -04004374 } else {
dsinclair2235b7b2016-06-02 07:42:25 -07004375 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Format");
Dan Sinclair1770c022016-03-14 14:14:16 -04004376 }
4377}
dsinclair48d91dd2016-05-31 11:54:01 -07004378
4379// static
dsinclair12a6b0c2016-05-26 11:14:08 -07004380void CXFA_FM2JSContext::Left(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04004381 const CFX_ByteStringC& szFuncName,
4382 CFXJSE_Arguments& args) {
Dan Sinclair1770c022016-03-14 14:14:16 -04004383 if (args.GetLength() == 2) {
dsinclair86fad992016-05-31 11:34:04 -07004384 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
4385 std::unique_ptr<CFXJSE_Value> argTwo = GetSimpleValue(pThis, args, 1);
Dan Sinclair1770c022016-03-14 14:14:16 -04004386 FX_BOOL argIsNull = FALSE;
dsinclair86fad992016-05-31 11:34:04 -07004387 if ((ValueIsNull(pThis, argOne.get())) ||
4388 (ValueIsNull(pThis, argTwo.get()))) {
Dan Sinclair1770c022016-03-14 14:14:16 -04004389 argIsNull = TRUE;
4390 }
4391 if (argIsNull) {
4392 FXJSE_Value_SetNull(args.GetReturnValue());
4393 } else {
4394 CFX_ByteString sourceString;
dsinclair86fad992016-05-31 11:34:04 -07004395 ValueToUTF8String(argOne.get(), sourceString);
4396 int32_t count = ValueToInteger(pThis, argTwo.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04004397 if (count < 0) {
4398 count = 0;
4399 }
4400 FXJSE_Value_SetUTF8String(args.GetReturnValue(),
tsepez4c3debb2016-04-08 12:20:38 -07004401 sourceString.Left(count).AsStringC());
Dan Sinclair1770c022016-03-14 14:14:16 -04004402 }
Dan Sinclair1770c022016-03-14 14:14:16 -04004403 } else {
dsinclair48d91dd2016-05-31 11:54:01 -07004404 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07004405 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair2235b7b2016-06-02 07:42:25 -07004406 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Left");
Dan Sinclair1770c022016-03-14 14:14:16 -04004407 }
4408}
dsinclair48d91dd2016-05-31 11:54:01 -07004409
4410// static
dsinclair12a6b0c2016-05-26 11:14:08 -07004411void CXFA_FM2JSContext::Len(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04004412 const CFX_ByteStringC& szFuncName,
4413 CFXJSE_Arguments& args) {
Dan Sinclair1770c022016-03-14 14:14:16 -04004414 if (args.GetLength() == 1) {
dsinclair86fad992016-05-31 11:34:04 -07004415 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
4416 if (ValueIsNull(pThis, argOne.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04004417 FXJSE_Value_SetNull(args.GetReturnValue());
4418 } else {
4419 CFX_ByteString sourceString;
dsinclair86fad992016-05-31 11:34:04 -07004420 ValueToUTF8String(argOne.get(), sourceString);
Dan Sinclair1770c022016-03-14 14:14:16 -04004421 FXJSE_Value_SetInteger(args.GetReturnValue(), sourceString.GetLength());
4422 }
Dan Sinclair1770c022016-03-14 14:14:16 -04004423 } else {
dsinclair48d91dd2016-05-31 11:54:01 -07004424 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07004425 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair2235b7b2016-06-02 07:42:25 -07004426 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Len");
Dan Sinclair1770c022016-03-14 14:14:16 -04004427 }
4428}
dsinclair48d91dd2016-05-31 11:54:01 -07004429
4430// static
dsinclair12a6b0c2016-05-26 11:14:08 -07004431void CXFA_FM2JSContext::Lower(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04004432 const CFX_ByteStringC& szFuncName,
4433 CFXJSE_Arguments& args) {
4434 int32_t argc = args.GetLength();
4435 if ((argc > 0) && (argc < 3)) {
4436 CFX_ByteString argString;
dsinclair86fad992016-05-31 11:34:04 -07004437 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
4438 if (ValueIsNull(pThis, argOne.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04004439 FXJSE_Value_SetNull(args.GetReturnValue());
4440 } else {
dsinclair86fad992016-05-31 11:34:04 -07004441 ValueToUTF8String(argOne.get(), argString);
Dan Sinclair1770c022016-03-14 14:14:16 -04004442 CFX_WideTextBuf lowStringBuf;
4443 CFX_WideString wsArgString =
tsepez4c3debb2016-04-08 12:20:38 -07004444 CFX_WideString::FromUTF8(argString.AsStringC());
tsepezbd9748d2016-04-13 21:40:19 -07004445 const FX_WCHAR* pData = wsArgString.c_str();
Dan Sinclair1770c022016-03-14 14:14:16 -04004446 int32_t iLen = argString.GetLength();
4447 int32_t i = 0;
4448 int32_t ch = 0;
4449 while (i < iLen) {
4450 ch = *(pData + i);
4451 if (ch >= 0x41 && ch <= 0x5A) {
4452 ch += 32;
4453 } else if (ch >= 0xC0 && ch <= 0xDE) {
4454 ch += 32;
4455 } else if (ch == 0x100 || ch == 0x102 || ch == 0x104) {
4456 ch += 1;
4457 }
4458 lowStringBuf.AppendChar(ch);
4459 ++i;
4460 }
4461 lowStringBuf.AppendChar(0);
4462 FXJSE_Value_SetUTF8String(
4463 args.GetReturnValue(),
tsepez28f97ff2016-04-04 16:41:35 -07004464 FX_UTF8Encode(lowStringBuf.GetBuffer(), lowStringBuf.GetLength())
tsepez4c3debb2016-04-08 12:20:38 -07004465 .AsStringC());
Dan Sinclair1770c022016-03-14 14:14:16 -04004466 }
Dan Sinclair1770c022016-03-14 14:14:16 -04004467 } else {
4468 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07004469 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair2235b7b2016-06-02 07:42:25 -07004470 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Lower");
Dan Sinclair1770c022016-03-14 14:14:16 -04004471 }
4472}
dsinclair48d91dd2016-05-31 11:54:01 -07004473
4474// static
dsinclair12a6b0c2016-05-26 11:14:08 -07004475void CXFA_FM2JSContext::Ltrim(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04004476 const CFX_ByteStringC& szFuncName,
4477 CFXJSE_Arguments& args) {
Dan Sinclair1770c022016-03-14 14:14:16 -04004478 if (args.GetLength() == 1) {
dsinclair86fad992016-05-31 11:34:04 -07004479 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
4480 if (ValueIsNull(pThis, argOne.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04004481 FXJSE_Value_SetNull(args.GetReturnValue());
4482 } else {
4483 CFX_ByteString sourceString;
dsinclair86fad992016-05-31 11:34:04 -07004484 ValueToUTF8String(argOne.get(), sourceString);
Dan Sinclair1770c022016-03-14 14:14:16 -04004485 sourceString.TrimLeft();
tsepez28f97ff2016-04-04 16:41:35 -07004486 FXJSE_Value_SetUTF8String(args.GetReturnValue(),
tsepez4c3debb2016-04-08 12:20:38 -07004487 sourceString.AsStringC());
Dan Sinclair1770c022016-03-14 14:14:16 -04004488 }
Dan Sinclair1770c022016-03-14 14:14:16 -04004489 } else {
dsinclair48d91dd2016-05-31 11:54:01 -07004490 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07004491 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair2235b7b2016-06-02 07:42:25 -07004492 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Ltrim");
Dan Sinclair1770c022016-03-14 14:14:16 -04004493 }
4494}
dsinclair48d91dd2016-05-31 11:54:01 -07004495
4496// static
dsinclair12a6b0c2016-05-26 11:14:08 -07004497void CXFA_FM2JSContext::Parse(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04004498 const CFX_ByteStringC& szFuncName,
4499 CFXJSE_Arguments& args) {
dsinclairdd6a46c2016-05-26 08:41:45 -07004500 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07004501 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
Dan Sinclair1770c022016-03-14 14:14:16 -04004502 if (args.GetLength() == 2) {
dsinclair86fad992016-05-31 11:34:04 -07004503 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
4504 std::unique_ptr<CFXJSE_Value> argTwo = GetSimpleValue(pThis, args, 1);
4505 if (ValueIsNull(pThis, argTwo.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04004506 FXJSE_Value_SetNull(args.GetReturnValue());
4507 } else {
4508 CFX_ByteString szPattern;
dsinclair86fad992016-05-31 11:34:04 -07004509 ValueToUTF8String(argOne.get(), szPattern);
Dan Sinclair1770c022016-03-14 14:14:16 -04004510 CFX_ByteString szValue;
dsinclair86fad992016-05-31 11:34:04 -07004511 ValueToUTF8String(argTwo.get(), szValue);
Dan Sinclair1770c022016-03-14 14:14:16 -04004512 CXFA_Document* pDoc = pContext->GetDocument();
4513 IFX_LocaleMgr* pMgr = (IFX_LocaleMgr*)pDoc->GetLocalMgr();
4514 CXFA_Node* pThisNode = ToNode(pDoc->GetScriptContext()->GetThisObject());
dsinclair43854a52016-04-27 12:26:00 -07004515 ASSERT(pThisNode);
Dan Sinclair1770c022016-03-14 14:14:16 -04004516 CXFA_WidgetData widgetData(pThisNode);
4517 IFX_Locale* pLocale = widgetData.GetLocal();
tsepez736f28a2016-03-25 14:19:51 -07004518 uint32_t patternType;
Dan Sinclair1770c022016-03-14 14:14:16 -04004519 CFX_WideString wsPattern =
tsepez4c3debb2016-04-08 12:20:38 -07004520 CFX_WideString::FromUTF8(szPattern.AsStringC());
4521 CFX_WideString wsValue = CFX_WideString::FromUTF8(szValue.AsStringC());
Dan Sinclair1770c022016-03-14 14:14:16 -04004522 CFX_ByteString szParsedValue;
dsinclair48d91dd2016-05-31 11:54:01 -07004523 if (PatternStringType(szPattern.AsStringC(), patternType)) {
Dan Sinclair1770c022016-03-14 14:14:16 -04004524 CXFA_LocaleValue localeValue(patternType, wsValue, wsPattern, pLocale,
4525 (CXFA_LocaleMgr*)pMgr);
4526 if (localeValue.IsValid()) {
4527 szParsedValue = FX_UTF8Encode(localeValue.GetValue());
tsepez28f97ff2016-04-04 16:41:35 -07004528 FXJSE_Value_SetUTF8String(args.GetReturnValue(),
tsepez4c3debb2016-04-08 12:20:38 -07004529 szParsedValue.AsStringC());
Dan Sinclair1770c022016-03-14 14:14:16 -04004530 } else {
4531 FXJSE_Value_SetUTF8String(args.GetReturnValue(), "");
4532 }
4533 } else {
4534 switch (patternType) {
4535 case XFA_VT_DATETIME: {
4536 FX_STRSIZE iTChar = wsPattern.Find(L'T');
tsepezafe94302016-05-13 17:21:31 -07004537 CFX_WideString wsDatePattern(L"date{");
Dan Sinclair1770c022016-03-14 14:14:16 -04004538 wsDatePattern += wsPattern.Left(iTChar);
4539 wsDatePattern += FX_WSTRC(L"} ");
tsepezafe94302016-05-13 17:21:31 -07004540 CFX_WideString wsTimePattern(L"time{");
Dan Sinclair1770c022016-03-14 14:14:16 -04004541 wsTimePattern += wsPattern.Mid(iTChar + 1);
4542 wsTimePattern += FX_WSTRC(L"}");
4543 wsPattern = wsDatePattern + wsTimePattern;
4544 CXFA_LocaleValue localeValue(patternType, wsValue, wsPattern,
4545 pLocale, (CXFA_LocaleMgr*)pMgr);
4546 if (localeValue.IsValid()) {
4547 szParsedValue = FX_UTF8Encode(localeValue.GetValue());
tsepez28f97ff2016-04-04 16:41:35 -07004548 FXJSE_Value_SetUTF8String(args.GetReturnValue(),
tsepez4c3debb2016-04-08 12:20:38 -07004549 szParsedValue.AsStringC());
Dan Sinclair1770c022016-03-14 14:14:16 -04004550 } else {
4551 FXJSE_Value_SetUTF8String(args.GetReturnValue(), "");
4552 }
4553 } break;
4554 case XFA_VT_DATE: {
4555 wsPattern = FX_WSTRC(L"date{") + wsPattern;
4556 wsPattern += FX_WSTRC(L"}");
4557 CXFA_LocaleValue localeValue(patternType, wsValue, wsPattern,
4558 pLocale, (CXFA_LocaleMgr*)pMgr);
4559 if (localeValue.IsValid()) {
4560 szParsedValue = FX_UTF8Encode(localeValue.GetValue());
tsepez28f97ff2016-04-04 16:41:35 -07004561 FXJSE_Value_SetUTF8String(args.GetReturnValue(),
tsepez4c3debb2016-04-08 12:20:38 -07004562 szParsedValue.AsStringC());
Dan Sinclair1770c022016-03-14 14:14:16 -04004563 } else {
4564 FXJSE_Value_SetUTF8String(args.GetReturnValue(), "");
4565 }
4566 } break;
4567 case XFA_VT_TIME: {
4568 wsPattern = FX_WSTRC(L"time{") + wsPattern;
4569 wsPattern += FX_WSTRC(L"}");
4570 CXFA_LocaleValue localeValue(patternType, wsValue, wsPattern,
4571 pLocale, (CXFA_LocaleMgr*)pMgr);
4572 if (localeValue.IsValid()) {
4573 szParsedValue = FX_UTF8Encode(localeValue.GetValue());
tsepez28f97ff2016-04-04 16:41:35 -07004574 FXJSE_Value_SetUTF8String(args.GetReturnValue(),
tsepez4c3debb2016-04-08 12:20:38 -07004575 szParsedValue.AsStringC());
Dan Sinclair1770c022016-03-14 14:14:16 -04004576 } else {
4577 FXJSE_Value_SetUTF8String(args.GetReturnValue(), "");
4578 }
4579 } break;
4580 case XFA_VT_TEXT: {
4581 wsPattern = FX_WSTRC(L"text{") + wsPattern;
4582 wsPattern += FX_WSTRC(L"}");
4583 CXFA_LocaleValue localeValue(XFA_VT_TEXT, wsValue, wsPattern,
4584 pLocale, (CXFA_LocaleMgr*)pMgr);
4585 if (localeValue.IsValid()) {
4586 szParsedValue = FX_UTF8Encode(localeValue.GetValue());
tsepez28f97ff2016-04-04 16:41:35 -07004587 FXJSE_Value_SetUTF8String(args.GetReturnValue(),
tsepez4c3debb2016-04-08 12:20:38 -07004588 szParsedValue.AsStringC());
Dan Sinclair1770c022016-03-14 14:14:16 -04004589 } else {
4590 FXJSE_Value_SetUTF8String(args.GetReturnValue(), "");
4591 }
4592 } break;
4593 case XFA_VT_FLOAT: {
4594 wsPattern = FX_WSTRC(L"num{") + wsPattern;
4595 wsPattern += FX_WSTRC(L"}");
4596 CXFA_LocaleValue localeValue(XFA_VT_FLOAT, wsValue, wsPattern,
4597 pLocale, (CXFA_LocaleMgr*)pMgr);
4598 if (localeValue.IsValid()) {
4599 FXJSE_Value_SetDouble(args.GetReturnValue(),
4600 localeValue.GetDoubleNum());
4601 } else {
4602 FXJSE_Value_SetUTF8String(args.GetReturnValue(), "");
4603 }
4604 } break;
4605 default: {
4606 CFX_WideString wsTestPattern;
4607 wsTestPattern = FX_WSTRC(L"num{") + wsPattern;
4608 wsTestPattern += FX_WSTRC(L"}");
4609 CXFA_LocaleValue localeValue(XFA_VT_FLOAT, wsValue, wsTestPattern,
4610 pLocale, (CXFA_LocaleMgr*)pMgr);
4611 if (localeValue.IsValid()) {
4612 FXJSE_Value_SetDouble(args.GetReturnValue(),
4613 localeValue.GetDoubleNum());
4614 } else {
4615 wsTestPattern = FX_WSTRC(L"text{") + wsPattern;
4616 wsTestPattern += FX_WSTRC(L"}");
4617 CXFA_LocaleValue localeValue(XFA_VT_TEXT, wsValue, wsTestPattern,
4618 pLocale, (CXFA_LocaleMgr*)pMgr);
4619 if (localeValue.IsValid()) {
4620 szParsedValue = FX_UTF8Encode(localeValue.GetValue());
tsepez28f97ff2016-04-04 16:41:35 -07004621 FXJSE_Value_SetUTF8String(args.GetReturnValue(),
tsepez4c3debb2016-04-08 12:20:38 -07004622 szParsedValue.AsStringC());
Dan Sinclair1770c022016-03-14 14:14:16 -04004623 } else {
4624 FXJSE_Value_SetUTF8String(args.GetReturnValue(), "");
4625 }
4626 }
4627 } break;
4628 }
4629 }
4630 }
Dan Sinclair1770c022016-03-14 14:14:16 -04004631 } else {
dsinclair2235b7b2016-06-02 07:42:25 -07004632 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Parse");
Dan Sinclair1770c022016-03-14 14:14:16 -04004633 }
4634}
dsinclair48d91dd2016-05-31 11:54:01 -07004635
4636// static
dsinclair12a6b0c2016-05-26 11:14:08 -07004637void CXFA_FM2JSContext::Replace(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04004638 const CFX_ByteStringC& szFuncName,
4639 CFXJSE_Arguments& args) {
4640 int32_t argc = args.GetLength();
4641 if ((argc == 2) || (argc == 3)) {
dsinclair86fad992016-05-31 11:34:04 -07004642 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
4643 std::unique_ptr<CFXJSE_Value> argTwo = GetSimpleValue(pThis, args, 1);
Dan Sinclair1770c022016-03-14 14:14:16 -04004644 CFX_ByteString oneString;
4645 CFX_ByteString twoString;
4646 CFX_ByteString threeString;
dsinclair86fad992016-05-31 11:34:04 -07004647 if (!ValueIsNull(pThis, argOne.get()) &&
4648 !ValueIsNull(pThis, argTwo.get())) {
4649 ValueToUTF8String(argOne.get(), oneString);
4650 ValueToUTF8String(argTwo.get(), twoString);
Dan Sinclair1770c022016-03-14 14:14:16 -04004651 }
4652 if (argc == 3) {
dsinclair86fad992016-05-31 11:34:04 -07004653 std::unique_ptr<CFXJSE_Value> argThree = GetSimpleValue(pThis, args, 2);
4654 ValueToUTF8String(argThree.get(), threeString);
Dan Sinclair1770c022016-03-14 14:14:16 -04004655 }
4656 int32_t iSrcLen = oneString.GetLength();
4657 int32_t iFindLen = twoString.GetLength();
4658 CFX_ByteTextBuf resultString;
4659 int32_t iFindIndex = 0;
4660 uint8_t ch = 0;
4661 for (int32_t u = 0; u < iSrcLen; ++u) {
4662 ch = oneString.GetAt(u);
4663 if (ch == twoString.GetAt(iFindIndex)) {
4664 int32_t iTemp = u + 1;
4665 ++iFindIndex;
4666 uint8_t chTemp = 0;
4667 while (iFindIndex < iFindLen) {
4668 chTemp = oneString.GetAt(iTemp);
4669 if (chTemp == twoString.GetAt(iFindIndex)) {
4670 ++iTemp;
4671 ++iFindIndex;
4672 } else {
4673 iFindIndex = 0;
4674 break;
4675 }
4676 }
4677 if (iFindIndex == iFindLen) {
tsepez4c3debb2016-04-08 12:20:38 -07004678 resultString << threeString.AsStringC();
Dan Sinclair1770c022016-03-14 14:14:16 -04004679 u += iFindLen - 1;
4680 iFindIndex = 0;
4681 } else {
4682 resultString.AppendChar(ch);
4683 }
4684 } else {
4685 resultString.AppendChar(ch);
4686 }
4687 }
4688 resultString.AppendChar(0);
tsepez8e4c5052016-04-14 13:42:44 -07004689 FXJSE_Value_SetUTF8String(args.GetReturnValue(), resultString.AsStringC());
Dan Sinclair1770c022016-03-14 14:14:16 -04004690 } else {
4691 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07004692 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair2235b7b2016-06-02 07:42:25 -07004693 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Replace");
Dan Sinclair1770c022016-03-14 14:14:16 -04004694 }
4695}
dsinclair48d91dd2016-05-31 11:54:01 -07004696
4697// static
dsinclair12a6b0c2016-05-26 11:14:08 -07004698void CXFA_FM2JSContext::Right(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04004699 const CFX_ByteStringC& szFuncName,
4700 CFXJSE_Arguments& args) {
Dan Sinclair1770c022016-03-14 14:14:16 -04004701 if (args.GetLength() == 2) {
dsinclair86fad992016-05-31 11:34:04 -07004702 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
4703 std::unique_ptr<CFXJSE_Value> argTwo = GetSimpleValue(pThis, args, 1);
Dan Sinclair1770c022016-03-14 14:14:16 -04004704 FX_BOOL argIsNull = FALSE;
dsinclair86fad992016-05-31 11:34:04 -07004705 if ((ValueIsNull(pThis, argOne.get())) ||
4706 (ValueIsNull(pThis, argTwo.get()))) {
Dan Sinclair1770c022016-03-14 14:14:16 -04004707 argIsNull = TRUE;
4708 }
4709 if (argIsNull) {
4710 FXJSE_Value_SetNull(args.GetReturnValue());
4711 } else {
4712 CFX_ByteString sourceString;
dsinclair86fad992016-05-31 11:34:04 -07004713 ValueToUTF8String(argOne.get(), sourceString);
4714 int32_t count = ValueToInteger(pThis, argTwo.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04004715 if (count < 0) {
4716 count = 0;
4717 }
4718 FXJSE_Value_SetUTF8String(args.GetReturnValue(),
tsepez4c3debb2016-04-08 12:20:38 -07004719 sourceString.Right(count).AsStringC());
Dan Sinclair1770c022016-03-14 14:14:16 -04004720 }
Dan Sinclair1770c022016-03-14 14:14:16 -04004721 } else {
dsinclair48d91dd2016-05-31 11:54:01 -07004722 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07004723 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair2235b7b2016-06-02 07:42:25 -07004724 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Right");
Dan Sinclair1770c022016-03-14 14:14:16 -04004725 }
4726}
dsinclair48d91dd2016-05-31 11:54:01 -07004727
4728// static
dsinclair12a6b0c2016-05-26 11:14:08 -07004729void CXFA_FM2JSContext::Rtrim(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04004730 const CFX_ByteStringC& szFuncName,
4731 CFXJSE_Arguments& args) {
Dan Sinclair1770c022016-03-14 14:14:16 -04004732 if (args.GetLength() == 1) {
dsinclair86fad992016-05-31 11:34:04 -07004733 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
4734 if (ValueIsNull(pThis, argOne.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04004735 FXJSE_Value_SetNull(args.GetReturnValue());
4736 } else {
4737 CFX_ByteString sourceString;
dsinclair86fad992016-05-31 11:34:04 -07004738 ValueToUTF8String(argOne.get(), sourceString);
Dan Sinclair1770c022016-03-14 14:14:16 -04004739 sourceString.TrimRight();
tsepez28f97ff2016-04-04 16:41:35 -07004740 FXJSE_Value_SetUTF8String(args.GetReturnValue(),
tsepez4c3debb2016-04-08 12:20:38 -07004741 sourceString.AsStringC());
Dan Sinclair1770c022016-03-14 14:14:16 -04004742 }
Dan Sinclair1770c022016-03-14 14:14:16 -04004743 } else {
dsinclair48d91dd2016-05-31 11:54:01 -07004744 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07004745 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair2235b7b2016-06-02 07:42:25 -07004746 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Rtrim");
Dan Sinclair1770c022016-03-14 14:14:16 -04004747 }
4748}
dsinclair48d91dd2016-05-31 11:54:01 -07004749
4750// static
dsinclair12a6b0c2016-05-26 11:14:08 -07004751void CXFA_FM2JSContext::Space(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04004752 const CFX_ByteStringC& szFuncName,
4753 CFXJSE_Arguments& args) {
Dan Sinclair1770c022016-03-14 14:14:16 -04004754 if (args.GetLength() == 1) {
dsinclair86fad992016-05-31 11:34:04 -07004755 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
4756 if (FXJSE_Value_IsNull(argOne.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04004757 FXJSE_Value_SetNull(args.GetReturnValue());
4758 } else {
4759 int32_t count = 0;
dsinclair86fad992016-05-31 11:34:04 -07004760 count = ValueToInteger(pThis, argOne.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04004761 count = (count < 0) ? 0 : count;
4762 CFX_ByteTextBuf spaceString;
4763 int32_t index = 0;
4764 while (index < count) {
4765 spaceString.AppendByte(' ');
4766 index++;
4767 }
4768 spaceString.AppendByte(0);
tsepez8e4c5052016-04-14 13:42:44 -07004769 FXJSE_Value_SetUTF8String(args.GetReturnValue(), spaceString.AsStringC());
Dan Sinclair1770c022016-03-14 14:14:16 -04004770 }
Dan Sinclair1770c022016-03-14 14:14:16 -04004771 } else {
dsinclair48d91dd2016-05-31 11:54:01 -07004772 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07004773 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair2235b7b2016-06-02 07:42:25 -07004774 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Space");
Dan Sinclair1770c022016-03-14 14:14:16 -04004775 }
4776}
dsinclair48d91dd2016-05-31 11:54:01 -07004777
4778// static
dsinclair12a6b0c2016-05-26 11:14:08 -07004779void CXFA_FM2JSContext::Str(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04004780 const CFX_ByteStringC& szFuncName,
4781 CFXJSE_Arguments& args) {
4782 int32_t argc = args.GetLength();
4783 if ((argc > 0) && (argc < 4)) {
4784 FX_BOOL bFlags = FALSE;
weili038aa532016-05-20 15:38:29 -07004785 FX_FLOAT fNumber = 0.0f;
Dan Sinclair1770c022016-03-14 14:14:16 -04004786 int32_t iWidth = 10;
4787 int32_t iPrecision = 0;
dsinclair86fad992016-05-31 11:34:04 -07004788 std::unique_ptr<CFXJSE_Value> numberValue = GetSimpleValue(pThis, args, 0);
4789 if (FXJSE_Value_IsNull(numberValue.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04004790 bFlags = TRUE;
4791 } else {
dsinclair86fad992016-05-31 11:34:04 -07004792 fNumber = ValueToFloat(pThis, numberValue.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04004793 }
4794 if (argc > 1) {
dsinclair86fad992016-05-31 11:34:04 -07004795 std::unique_ptr<CFXJSE_Value> widthValue = GetSimpleValue(pThis, args, 1);
4796 iWidth = (int32_t)ValueToFloat(pThis, widthValue.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04004797 }
4798 if (argc == 3) {
dsinclair86fad992016-05-31 11:34:04 -07004799 std::unique_ptr<CFXJSE_Value> precisionValue =
4800 GetSimpleValue(pThis, args, 2);
4801 iPrecision = (int32_t)ValueToFloat(pThis, precisionValue.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04004802 if (iPrecision < 0) {
4803 iPrecision = 0;
4804 }
4805 }
4806 if (!bFlags) {
4807 CFX_ByteString numberString;
4808 CFX_ByteString formatStr = "%";
4809 if (iPrecision) {
4810 formatStr += ".";
4811 formatStr += CFX_ByteString::FormatInteger(iPrecision);
4812 }
4813 formatStr += "f";
tsepezb4c9f3f2016-04-13 15:41:21 -07004814 numberString.Format(formatStr.c_str(), fNumber);
4815 const FX_CHAR* pData = numberString.c_str();
Dan Sinclair1770c022016-03-14 14:14:16 -04004816 int32_t iLength = numberString.GetLength();
4817 int32_t u = 0;
4818 while (u < iLength) {
4819 if (*(pData + u) == '.') {
4820 break;
4821 }
4822 ++u;
4823 }
4824 CFX_ByteTextBuf resultBuf;
4825 if (u > iWidth || (iPrecision + u) >= iWidth) {
4826 int32_t i = 0;
4827 while (i < iWidth) {
4828 resultBuf.AppendChar('*');
4829 ++i;
4830 }
4831 resultBuf.AppendChar(0);
4832 } else {
4833 if (u == iLength) {
4834 if (iLength > iWidth) {
4835 int32_t i = 0;
4836 while (i < iWidth) {
4837 resultBuf.AppendChar('*');
4838 ++i;
4839 }
4840 } else {
4841 int32_t i = 0;
4842 int32_t iSpace = iWidth - iLength;
4843 while (i < iSpace) {
4844 resultBuf.AppendChar(' ');
4845 ++i;
4846 }
4847 resultBuf << pData;
4848 }
4849 } else {
4850 int32_t iLeavingSpace = 0;
4851 if (iPrecision == 0) {
4852 iLeavingSpace = iWidth - (u + iPrecision);
4853 } else {
4854 iLeavingSpace = iWidth - (u + iPrecision + 1);
4855 }
4856 int32_t i = 0;
4857 while (i < iLeavingSpace) {
4858 resultBuf.AppendChar(' ');
4859 ++i;
4860 }
4861 i = 0;
4862 while (i < u) {
4863 resultBuf.AppendChar(*(pData + i));
4864 ++i;
4865 }
4866 if (iPrecision != 0) {
4867 resultBuf.AppendChar('.');
4868 }
4869 u++;
4870 i = 0;
4871 while (u < iLength) {
4872 if (i >= iPrecision) {
4873 break;
4874 }
4875 resultBuf.AppendChar(*(pData + u));
4876 ++i;
4877 ++u;
4878 }
4879 while (i < iPrecision) {
4880 resultBuf.AppendChar('0');
4881 ++i;
4882 }
4883 resultBuf.AppendChar(0);
4884 }
4885 }
tsepez8e4c5052016-04-14 13:42:44 -07004886 FXJSE_Value_SetUTF8String(args.GetReturnValue(), resultBuf.AsStringC());
Dan Sinclair1770c022016-03-14 14:14:16 -04004887 } else {
4888 FXJSE_Value_SetNull(args.GetReturnValue());
4889 }
Dan Sinclair1770c022016-03-14 14:14:16 -04004890 } else {
4891 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07004892 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair2235b7b2016-06-02 07:42:25 -07004893 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Str");
Dan Sinclair1770c022016-03-14 14:14:16 -04004894 }
4895}
dsinclair48d91dd2016-05-31 11:54:01 -07004896
4897// static
dsinclair12a6b0c2016-05-26 11:14:08 -07004898void CXFA_FM2JSContext::Stuff(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04004899 const CFX_ByteStringC& szFuncName,
4900 CFXJSE_Arguments& args) {
4901 int32_t argc = args.GetLength();
4902 if ((argc == 3) || (argc == 4)) {
4903 CFX_ByteString sourceString;
4904 CFX_ByteString insertString;
4905 int32_t iLength = 0;
4906 int32_t iStart = 0;
4907 int32_t iDelete = 0;
dsinclair86fad992016-05-31 11:34:04 -07004908 std::unique_ptr<CFXJSE_Value> sourceValue = GetSimpleValue(pThis, args, 0);
4909 std::unique_ptr<CFXJSE_Value> startValue = GetSimpleValue(pThis, args, 1);
4910 std::unique_ptr<CFXJSE_Value> deleteValue = GetSimpleValue(pThis, args, 2);
4911 if (!FXJSE_Value_IsNull(sourceValue.get()) &&
4912 !FXJSE_Value_IsNull(startValue.get()) &&
4913 !FXJSE_Value_IsNull(deleteValue.get())) {
4914 ValueToUTF8String(sourceValue.get(), sourceString);
Dan Sinclair1770c022016-03-14 14:14:16 -04004915 iLength = sourceString.GetLength();
dsinclair86fad992016-05-31 11:34:04 -07004916 iStart = (int32_t)ValueToFloat(pThis, startValue.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04004917 if (iStart < 1) {
4918 iStart = 1;
4919 }
4920 if (iStart > iLength) {
4921 iStart = iLength;
4922 }
dsinclair86fad992016-05-31 11:34:04 -07004923 iDelete = (int32_t)ValueToFloat(pThis, deleteValue.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04004924 if (iDelete <= 0) {
4925 iDelete = 0;
4926 }
4927 }
4928 if (argc == 4) {
dsinclair86fad992016-05-31 11:34:04 -07004929 std::unique_ptr<CFXJSE_Value> insertValue =
4930 GetSimpleValue(pThis, args, 3);
4931 ValueToUTF8String(insertValue.get(), insertString);
Dan Sinclair1770c022016-03-14 14:14:16 -04004932 }
4933 iStart -= 1;
4934 CFX_ByteTextBuf resultString;
4935 int32_t i = 0;
4936 while (i < iStart) {
4937 resultString.AppendChar(sourceString.GetAt(i));
4938 ++i;
4939 }
tsepez4c3debb2016-04-08 12:20:38 -07004940 resultString << insertString.AsStringC();
Dan Sinclair1770c022016-03-14 14:14:16 -04004941 i = iStart + iDelete;
4942 while (i < iLength) {
4943 resultString.AppendChar(sourceString.GetAt(i));
4944 ++i;
4945 }
4946 resultString.AppendChar(0);
tsepez8e4c5052016-04-14 13:42:44 -07004947 FXJSE_Value_SetUTF8String(args.GetReturnValue(), resultString.AsStringC());
Dan Sinclair1770c022016-03-14 14:14:16 -04004948 } else {
4949 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07004950 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair2235b7b2016-06-02 07:42:25 -07004951 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Stuff");
Dan Sinclair1770c022016-03-14 14:14:16 -04004952 }
4953}
dsinclair48d91dd2016-05-31 11:54:01 -07004954
4955// static
dsinclair12a6b0c2016-05-26 11:14:08 -07004956void CXFA_FM2JSContext::Substr(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04004957 const CFX_ByteStringC& szFuncName,
4958 CFXJSE_Arguments& args) {
dsinclair48d91dd2016-05-31 11:54:01 -07004959 if (args.GetLength() == 3) {
dsinclair86fad992016-05-31 11:34:04 -07004960 std::unique_ptr<CFXJSE_Value> stringValue = GetSimpleValue(pThis, args, 0);
4961 std::unique_ptr<CFXJSE_Value> startValue = GetSimpleValue(pThis, args, 1);
4962 std::unique_ptr<CFXJSE_Value> endValue = GetSimpleValue(pThis, args, 2);
4963 if (ValueIsNull(pThis, stringValue.get()) ||
4964 (ValueIsNull(pThis, startValue.get())) ||
4965 (ValueIsNull(pThis, endValue.get()))) {
Dan Sinclair1770c022016-03-14 14:14:16 -04004966 FXJSE_Value_SetNull(args.GetReturnValue());
4967 } else {
4968 CFX_ByteString szSourceStr;
4969 int32_t iStart = 0;
4970 int32_t iCount = 0;
dsinclair86fad992016-05-31 11:34:04 -07004971 ValueToUTF8String(stringValue.get(), szSourceStr);
Dan Sinclair1770c022016-03-14 14:14:16 -04004972 int32_t iLength = szSourceStr.GetLength();
4973 if (iLength == 0) {
4974 FXJSE_Value_SetUTF8String(args.GetReturnValue(), "");
4975 } else {
dsinclair86fad992016-05-31 11:34:04 -07004976 iStart = (int32_t)ValueToFloat(pThis, startValue.get());
4977 iCount = (int32_t)ValueToFloat(pThis, endValue.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04004978 if (iStart < 1) {
4979 iStart = 1;
4980 }
4981 if (iStart > iLength) {
4982 iStart = iLength;
4983 }
4984 if (iCount <= 0) {
4985 iCount = 0;
4986 }
4987 iStart -= 1;
tsepez4c3debb2016-04-08 12:20:38 -07004988 FXJSE_Value_SetUTF8String(args.GetReturnValue(),
4989 szSourceStr.Mid(iStart, iCount).AsStringC());
Dan Sinclair1770c022016-03-14 14:14:16 -04004990 }
4991 }
Dan Sinclair1770c022016-03-14 14:14:16 -04004992 } else {
4993 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07004994 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair2235b7b2016-06-02 07:42:25 -07004995 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Substr");
Dan Sinclair1770c022016-03-14 14:14:16 -04004996 }
4997}
dsinclair48d91dd2016-05-31 11:54:01 -07004998
4999// static
dsinclair12a6b0c2016-05-26 11:14:08 -07005000void CXFA_FM2JSContext::Uuid(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04005001 const CFX_ByteStringC& szFuncName,
5002 CFXJSE_Arguments& args) {
5003 int32_t argc = args.GetLength();
5004 if ((argc == 0) || (argc == 1)) {
5005 int32_t iNum = 0;
Dan Sinclair1770c022016-03-14 14:14:16 -04005006 if (argc == 1) {
dsinclair86fad992016-05-31 11:34:04 -07005007 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
5008 iNum = (int32_t)ValueToFloat(pThis, argOne.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04005009 }
5010 FX_GUID guid;
5011 FX_GUID_CreateV4(&guid);
5012 CFX_ByteString bsUId;
5013 FX_GUID_ToString(&guid, bsUId, iNum);
tsepez4c3debb2016-04-08 12:20:38 -07005014 FXJSE_Value_SetUTF8String(args.GetReturnValue(), bsUId.AsStringC());
Dan Sinclair1770c022016-03-14 14:14:16 -04005015 } else {
5016 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07005017 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair2235b7b2016-06-02 07:42:25 -07005018 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Uuid");
Dan Sinclair1770c022016-03-14 14:14:16 -04005019 }
5020}
dsinclair48d91dd2016-05-31 11:54:01 -07005021
5022// static
dsinclair12a6b0c2016-05-26 11:14:08 -07005023void CXFA_FM2JSContext::Upper(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04005024 const CFX_ByteStringC& szFuncName,
5025 CFXJSE_Arguments& args) {
5026 int32_t argc = args.GetLength();
5027 if ((argc > 0) && (argc < 3)) {
5028 CFX_ByteString argString;
dsinclair86fad992016-05-31 11:34:04 -07005029 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
5030 if (ValueIsNull(pThis, argOne.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04005031 FXJSE_Value_SetNull(args.GetReturnValue());
5032 } else {
dsinclair86fad992016-05-31 11:34:04 -07005033 ValueToUTF8String(argOne.get(), argString);
Dan Sinclair1770c022016-03-14 14:14:16 -04005034 CFX_WideTextBuf upperStringBuf;
5035 CFX_WideString wsArgString =
tsepez4c3debb2016-04-08 12:20:38 -07005036 CFX_WideString::FromUTF8(argString.AsStringC());
tsepezbd9748d2016-04-13 21:40:19 -07005037 const FX_WCHAR* pData = wsArgString.c_str();
Dan Sinclair1770c022016-03-14 14:14:16 -04005038 int32_t iLen = wsArgString.GetLength();
5039 int32_t i = 0;
5040 int32_t ch = 0;
5041 while (i < iLen) {
5042 ch = *(pData + i);
5043 if (ch >= 0x61 && ch <= 0x7A) {
5044 ch -= 32;
5045 } else if (ch >= 0xE0 && ch <= 0xFE) {
5046 ch -= 32;
5047 } else if (ch == 0x101 || ch == 0x103 || ch == 0x105) {
5048 ch -= 1;
5049 }
5050 upperStringBuf.AppendChar(ch);
5051 ++i;
5052 }
5053 upperStringBuf.AppendChar(0);
tsepez28f97ff2016-04-04 16:41:35 -07005054 FXJSE_Value_SetUTF8String(
5055 args.GetReturnValue(),
5056 FX_UTF8Encode(upperStringBuf.GetBuffer(), upperStringBuf.GetLength())
tsepez4c3debb2016-04-08 12:20:38 -07005057 .AsStringC());
Dan Sinclair1770c022016-03-14 14:14:16 -04005058 }
Dan Sinclair1770c022016-03-14 14:14:16 -04005059 } else {
5060 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07005061 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair2235b7b2016-06-02 07:42:25 -07005062 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Upper");
Dan Sinclair1770c022016-03-14 14:14:16 -04005063 }
5064}
dsinclair48d91dd2016-05-31 11:54:01 -07005065
5066// static
dsinclair12a6b0c2016-05-26 11:14:08 -07005067void CXFA_FM2JSContext::WordNum(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04005068 const CFX_ByteStringC& szFuncName,
5069 CFXJSE_Arguments& args) {
5070 int32_t argc = args.GetLength();
5071 if ((argc > 0) && (argc < 4)) {
5072 FX_BOOL bFlags = FALSE;
weili038aa532016-05-20 15:38:29 -07005073 FX_FLOAT fNumber = 0.0f;
Dan Sinclair1770c022016-03-14 14:14:16 -04005074 int32_t iIdentifier = 0;
5075 CFX_ByteString localeString;
dsinclair86fad992016-05-31 11:34:04 -07005076 std::unique_ptr<CFXJSE_Value> numberValue = GetSimpleValue(pThis, args, 0);
5077 if (FXJSE_Value_IsNull(numberValue.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04005078 bFlags = TRUE;
5079 } else {
dsinclair86fad992016-05-31 11:34:04 -07005080 fNumber = ValueToFloat(pThis, numberValue.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04005081 }
5082 if (argc > 1) {
dsinclair86fad992016-05-31 11:34:04 -07005083 std::unique_ptr<CFXJSE_Value> identifierValue =
5084 GetSimpleValue(pThis, args, 1);
5085 if (FXJSE_Value_IsNull(identifierValue.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04005086 bFlags = TRUE;
5087 } else {
dsinclair86fad992016-05-31 11:34:04 -07005088 iIdentifier = (int32_t)ValueToFloat(pThis, identifierValue.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04005089 }
5090 }
5091 if (argc == 3) {
dsinclair86fad992016-05-31 11:34:04 -07005092 std::unique_ptr<CFXJSE_Value> localeValue =
5093 GetSimpleValue(pThis, args, 2);
5094 if (FXJSE_Value_IsNull(localeValue.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04005095 bFlags = TRUE;
5096 } else {
dsinclair86fad992016-05-31 11:34:04 -07005097 ValueToUTF8String(localeValue.get(), localeString);
Dan Sinclair1770c022016-03-14 14:14:16 -04005098 }
5099 }
5100 if (!bFlags) {
5101 if ((fNumber < 0) || (fNumber > 922337203685477550)) {
5102 FXJSE_Value_SetUTF8String(args.GetReturnValue(), "*");
5103 } else {
5104 CFX_ByteTextBuf resultBuf;
5105 CFX_ByteString numberString;
5106 numberString.Format("%.2f", fNumber);
tsepez4c3debb2016-04-08 12:20:38 -07005107 WordUS(numberString.AsStringC(), iIdentifier, resultBuf);
tsepez8e4c5052016-04-14 13:42:44 -07005108 FXJSE_Value_SetUTF8String(args.GetReturnValue(), resultBuf.AsStringC());
Dan Sinclair1770c022016-03-14 14:14:16 -04005109 }
5110 } else {
5111 FXJSE_Value_SetNull(args.GetReturnValue());
5112 }
Dan Sinclair1770c022016-03-14 14:14:16 -04005113 } else {
5114 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07005115 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair2235b7b2016-06-02 07:42:25 -07005116 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"WordNum");
Dan Sinclair1770c022016-03-14 14:14:16 -04005117 }
5118}
dsinclair48d91dd2016-05-31 11:54:01 -07005119
5120// static
Dan Sinclair1770c022016-03-14 14:14:16 -04005121void CXFA_FM2JSContext::TrillionUS(const CFX_ByteStringC& szData,
5122 CFX_ByteTextBuf& strBuf) {
5123 CFX_ByteStringC pUnits[] = {"zero", "one", "two", "three", "four",
5124 "five", "six", "seven", "eight", "nine"};
5125 CFX_ByteStringC pCapUnits[] = {"Zero", "One", "Two", "Three", "Four",
5126 "Five", "Six", "Seven", "Eight", "Nine"};
5127 CFX_ByteStringC pTens[] = {"Ten", "Eleven", "Twelve", "Thirteen",
5128 "Fourteen", "Fifteen", "Sixteen", "Seventeen",
5129 "Eighteen", "Nineteen"};
5130 CFX_ByteStringC pLastTens[] = {"Twenty", "Thirty", "Forty", "Fifty",
5131 "Sixty", "Seventy", "Eighty", "Ninety"};
5132 CFX_ByteStringC pComm[] = {" Hundred ", " Thousand ", " Million ",
5133 " Billion ", "Trillion"};
5134 int32_t iComm = 0;
dsinclair179bebb2016-04-05 11:02:18 -07005135 const FX_CHAR* pData = szData.c_str();
Dan Sinclair1770c022016-03-14 14:14:16 -04005136 int32_t iLength = szData.GetLength();
5137 if (iLength > 12) {
5138 iComm = 4;
5139 } else if (iLength > 9) {
5140 iComm = 3;
5141 } else if (iLength > 6) {
5142 iComm = 2;
5143 } else if (iLength > 3) {
5144 iComm = 1;
5145 }
5146 int32_t iIndex = 0;
5147 int32_t iFirstCount = iLength % 3;
5148 if (iFirstCount == 0) {
5149 iFirstCount = 3;
5150 }
5151 if (iFirstCount == 3) {
5152 if (*(pData + iIndex) != '0') {
5153 strBuf << pCapUnits[*(pData + iIndex) - '0'];
5154 strBuf << pComm[0];
5155 }
5156 if (*(pData + iIndex + 1) == '0') {
5157 strBuf << pCapUnits[*(pData + iIndex + 2) - '0'];
5158 } else {
5159 if (*(pData + iIndex + 1) > '1') {
5160 strBuf << pLastTens[*(pData + iIndex + 1) - '2'];
5161 strBuf << "-";
5162 strBuf << pUnits[*(pData + iIndex + 2) - '0'];
5163 } else if (*(pData + iIndex + 1) == '1') {
5164 strBuf << pTens[*(pData + iIndex + 2) - '0'];
5165 } else if (*(pData + iIndex + 1) == '0') {
5166 strBuf << pCapUnits[*(pData + iIndex + 2) - '0'];
5167 }
5168 }
5169 iIndex += 3;
5170 } else if (iFirstCount == 2) {
5171 if (*(pData + iIndex) == '0') {
5172 strBuf << pCapUnits[*(pData + iIndex + 1) - '0'];
5173 } else {
5174 if (*(pData + iIndex) > '1') {
5175 strBuf << pLastTens[*(pData + iIndex) - '2'];
5176 strBuf << "-";
5177 strBuf << pUnits[*(pData + iIndex + 1) - '0'];
5178 } else if (*(pData + iIndex) == '1') {
5179 strBuf << pTens[*(pData + iIndex + 1) - '0'];
5180 } else if (*(pData + iIndex) == '0') {
5181 strBuf << pCapUnits[*(pData + iIndex + 1) - '0'];
5182 }
5183 }
5184 iIndex += 2;
5185 } else if (iFirstCount == 1) {
5186 strBuf << pCapUnits[*(pData + iIndex) - '0'];
5187 iIndex += 1;
5188 }
5189 if (iLength > 3 && iFirstCount > 0) {
5190 strBuf << pComm[iComm];
5191 --iComm;
5192 }
5193 while (iIndex < iLength) {
5194 if (*(pData + iIndex) != '0') {
5195 strBuf << pCapUnits[*(pData + iIndex) - '0'];
5196 strBuf << pComm[0];
5197 }
5198 if (*(pData + iIndex + 1) == '0') {
5199 strBuf << pCapUnits[*(pData + iIndex + 2) - '0'];
5200 } else {
5201 if (*(pData + iIndex + 1) > '1') {
5202 strBuf << pLastTens[*(pData + iIndex + 1) - '2'];
5203 strBuf << "-";
5204 strBuf << pUnits[*(pData + iIndex + 2) - '0'];
5205 } else if (*(pData + iIndex + 1) == '1') {
5206 strBuf << pTens[*(pData + iIndex + 2) - '0'];
5207 } else if (*(pData + iIndex + 1) == '0') {
5208 strBuf << pCapUnits[*(pData + iIndex + 2) - '0'];
5209 }
5210 }
5211 if (iIndex < iLength - 3) {
5212 strBuf << pComm[iComm];
5213 --iComm;
5214 }
5215 iIndex += 3;
5216 }
5217}
dsinclair48d91dd2016-05-31 11:54:01 -07005218
5219// static
Dan Sinclair1770c022016-03-14 14:14:16 -04005220void CXFA_FM2JSContext::WordUS(const CFX_ByteStringC& szData,
5221 int32_t iStyle,
5222 CFX_ByteTextBuf& strBuf) {
dsinclair179bebb2016-04-05 11:02:18 -07005223 const FX_CHAR* pData = szData.c_str();
Dan Sinclair1770c022016-03-14 14:14:16 -04005224 int32_t iLength = szData.GetLength();
5225 switch (iStyle) {
5226 case 0: {
5227 int32_t iIndex = 0;
5228 while (iIndex < iLength) {
5229 if (*(pData + iIndex) == '.') {
5230 break;
5231 }
5232 ++iIndex;
5233 }
5234 iLength = iIndex;
5235 iIndex = 0;
5236 int32_t iCount = 0;
5237 while (iIndex < iLength) {
5238 iCount = (iLength - iIndex) % 12;
5239 if (!iCount && iLength - iIndex > 0) {
5240 iCount = 12;
5241 }
5242 TrillionUS(CFX_ByteStringC(pData + iIndex, iCount), strBuf);
5243 iIndex += iCount;
5244 if (iIndex < iLength) {
5245 strBuf << " Trillion ";
5246 }
5247 }
5248 } break;
5249 case 1: {
5250 int32_t iIndex = 0;
5251 while (iIndex < iLength) {
5252 if (*(pData + iIndex) == '.') {
5253 break;
5254 }
5255 ++iIndex;
5256 }
5257 iLength = iIndex;
5258 iIndex = 0;
5259 int32_t iCount = 0;
5260 while (iIndex < iLength) {
5261 iCount = (iLength - iIndex) % 12;
5262 if (!iCount && iLength - iIndex > 0) {
5263 iCount = 12;
5264 }
5265 TrillionUS(CFX_ByteStringC(pData + iIndex, iCount), strBuf);
5266 iIndex += iCount;
5267 if (iIndex < iLength) {
5268 strBuf << " Trillion ";
5269 }
5270 }
5271 strBuf << " Dollars";
5272 } break;
5273 case 2: {
5274 int32_t iIndex = 0;
5275 while (iIndex < iLength) {
5276 if (*(pData + iIndex) == '.') {
5277 break;
5278 }
5279 ++iIndex;
5280 }
5281 int32_t iInteger = iIndex;
5282 iIndex = 0;
5283 int32_t iCount = 0;
5284 while (iIndex < iInteger) {
5285 iCount = (iInteger - iIndex) % 12;
5286 if (!iCount && iLength - iIndex > 0) {
5287 iCount = 12;
5288 }
5289 TrillionUS(CFX_ByteStringC(pData + iIndex, iCount), strBuf);
5290 iIndex += iCount;
5291 if (iIndex < iInteger) {
5292 strBuf << " Trillion ";
5293 }
5294 }
5295 strBuf << " Dollars";
5296 if (iInteger < iLength) {
5297 strBuf << " And ";
5298 iIndex = iInteger + 1;
5299 int32_t iCount = 0;
5300 while (iIndex < iLength) {
5301 iCount = (iLength - iIndex) % 12;
5302 if (!iCount && iLength - iIndex > 0) {
5303 iCount = 12;
5304 }
5305 TrillionUS(CFX_ByteStringC(pData + iIndex, iCount), strBuf);
5306 iIndex += iCount;
5307 if (iIndex < iLength) {
5308 strBuf << " Trillion ";
5309 }
5310 }
5311 strBuf << " Cents";
5312 }
5313 } break;
5314 default:
5315 break;
5316 }
5317}
dsinclair48d91dd2016-05-31 11:54:01 -07005318
5319// static
dsinclair12a6b0c2016-05-26 11:14:08 -07005320void CXFA_FM2JSContext::Get(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04005321 const CFX_ByteStringC& szFuncName,
5322 CFXJSE_Arguments& args) {
dsinclairdd6a46c2016-05-26 08:41:45 -07005323 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07005324 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair48d91dd2016-05-31 11:54:01 -07005325 if (args.GetLength() == 1) {
Dan Sinclair1770c022016-03-14 14:14:16 -04005326 CXFA_Document* pDoc = pContext->GetDocument();
5327 if (!pDoc) {
5328 return;
5329 }
5330 IXFA_AppProvider* pAppProvider =
5331 pDoc->GetParser()->GetNotify()->GetAppProvider();
5332 if (!pAppProvider) {
5333 return;
5334 }
dsinclair86fad992016-05-31 11:34:04 -07005335 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
Dan Sinclair1770c022016-03-14 14:14:16 -04005336 CFX_ByteString urlString;
dsinclair86fad992016-05-31 11:34:04 -07005337 ValueToUTF8String(argOne.get(), urlString);
Dan Sinclair1770c022016-03-14 14:14:16 -04005338 IFX_FileRead* pFile = pAppProvider->DownloadURL(
tsepez3f80c862016-05-16 12:03:24 -07005339 CFX_WideString::FromUTF8(urlString.AsStringC()));
Dan Sinclair1770c022016-03-14 14:14:16 -04005340 if (pFile) {
5341 int32_t size = pFile->GetSize();
5342 uint8_t* pData = FX_Alloc(uint8_t, size);
5343 pFile->ReadBlock(pData, size);
5344 FXJSE_Value_SetUTF8String(args.GetReturnValue(),
5345 CFX_ByteStringC(pData, size));
5346 FX_Free(pData);
5347 pFile->Release();
5348 }
Dan Sinclair1770c022016-03-14 14:14:16 -04005349 } else {
dsinclair2235b7b2016-06-02 07:42:25 -07005350 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Get");
Dan Sinclair1770c022016-03-14 14:14:16 -04005351 }
5352}
dsinclair48d91dd2016-05-31 11:54:01 -07005353
5354// static
dsinclair12a6b0c2016-05-26 11:14:08 -07005355void CXFA_FM2JSContext::Post(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04005356 const CFX_ByteStringC& szFuncName,
5357 CFXJSE_Arguments& args) {
dsinclairdd6a46c2016-05-26 08:41:45 -07005358 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07005359 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
Dan Sinclair1770c022016-03-14 14:14:16 -04005360 int32_t argc = args.GetLength();
5361 if ((argc >= 2) && (argc <= 5)) {
5362 CXFA_Document* pDoc = pContext->GetDocument();
5363 if (!pDoc) {
5364 return;
5365 }
5366 IXFA_AppProvider* pAppProvider =
5367 pDoc->GetParser()->GetNotify()->GetAppProvider();
5368 if (!pAppProvider) {
5369 return;
5370 }
5371 CFX_ByteString bsURL;
5372 CFX_ByteString bsData;
5373 CFX_ByteString bsContentType;
5374 CFX_ByteString bsEncode;
5375 CFX_ByteString bsHeader;
dsinclair86fad992016-05-31 11:34:04 -07005376 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
5377 ValueToUTF8String(argOne.get(), bsURL);
5378 std::unique_ptr<CFXJSE_Value> argTwo = GetSimpleValue(pThis, args, 1);
5379 ValueToUTF8String(argTwo.get(), bsData);
Dan Sinclair1770c022016-03-14 14:14:16 -04005380 if (argc > 2) {
dsinclair86fad992016-05-31 11:34:04 -07005381 std::unique_ptr<CFXJSE_Value> argThree = GetSimpleValue(pThis, args, 2);
5382 ValueToUTF8String(argThree.get(), bsContentType);
Dan Sinclair1770c022016-03-14 14:14:16 -04005383 }
5384 if (argc > 3) {
dsinclair86fad992016-05-31 11:34:04 -07005385 std::unique_ptr<CFXJSE_Value> argFour = GetSimpleValue(pThis, args, 3);
5386 ValueToUTF8String(argFour.get(), bsEncode);
Dan Sinclair1770c022016-03-14 14:14:16 -04005387 }
5388 if (argc > 4) {
dsinclair86fad992016-05-31 11:34:04 -07005389 std::unique_ptr<CFXJSE_Value> argFive = GetSimpleValue(pThis, args, 4);
5390 ValueToUTF8String(argFive.get(), bsHeader);
Dan Sinclair1770c022016-03-14 14:14:16 -04005391 }
5392 CFX_WideString decodedResponse;
5393 FX_BOOL bFlags = pAppProvider->PostRequestURL(
tsepez3f80c862016-05-16 12:03:24 -07005394 CFX_WideString::FromUTF8(bsURL.AsStringC()),
5395 CFX_WideString::FromUTF8(bsData.AsStringC()),
5396 CFX_WideString::FromUTF8(bsContentType.AsStringC()),
5397 CFX_WideString::FromUTF8(bsEncode.AsStringC()),
5398 CFX_WideString::FromUTF8(bsHeader.AsStringC()), decodedResponse);
Dan Sinclair1770c022016-03-14 14:14:16 -04005399 if (bFlags) {
5400 FXJSE_Value_SetUTF8String(
5401 args.GetReturnValue(),
tsepezbd9748d2016-04-13 21:40:19 -07005402 FX_UTF8Encode(decodedResponse.c_str(), decodedResponse.GetLength())
tsepez4c3debb2016-04-08 12:20:38 -07005403 .AsStringC());
Dan Sinclair1770c022016-03-14 14:14:16 -04005404 } else {
dsinclair2235b7b2016-06-02 07:42:25 -07005405 pContext->ThrowException(XFA_IDS_SERVER_DENY);
Dan Sinclair1770c022016-03-14 14:14:16 -04005406 }
5407 } else {
dsinclair2235b7b2016-06-02 07:42:25 -07005408 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Post");
Dan Sinclair1770c022016-03-14 14:14:16 -04005409 }
5410}
dsinclair48d91dd2016-05-31 11:54:01 -07005411
5412// static
dsinclair12a6b0c2016-05-26 11:14:08 -07005413void CXFA_FM2JSContext::Put(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04005414 const CFX_ByteStringC& szFuncName,
5415 CFXJSE_Arguments& args) {
dsinclairdd6a46c2016-05-26 08:41:45 -07005416 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07005417 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
Dan Sinclair1770c022016-03-14 14:14:16 -04005418 int32_t argc = args.GetLength();
5419 if ((argc == 2) || (argc == 3)) {
5420 CXFA_Document* pDoc = pContext->GetDocument();
5421 if (!pDoc) {
5422 return;
5423 }
5424 IXFA_AppProvider* pAppProvider =
5425 pDoc->GetParser()->GetNotify()->GetAppProvider();
5426 if (!pAppProvider) {
5427 return;
5428 }
5429 CFX_ByteString bsURL;
5430 CFX_ByteString bsData;
5431 CFX_ByteString bsEncode;
dsinclair86fad992016-05-31 11:34:04 -07005432 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
5433 ValueToUTF8String(argOne.get(), bsURL);
5434 std::unique_ptr<CFXJSE_Value> argTwo = GetSimpleValue(pThis, args, 1);
5435 ValueToUTF8String(argTwo.get(), bsData);
Dan Sinclair1770c022016-03-14 14:14:16 -04005436 if (argc > 2) {
dsinclair86fad992016-05-31 11:34:04 -07005437 std::unique_ptr<CFXJSE_Value> argThree = GetSimpleValue(pThis, args, 2);
5438 ValueToUTF8String(argThree.get(), bsEncode);
Dan Sinclair1770c022016-03-14 14:14:16 -04005439 }
5440 FX_BOOL bFlags = pAppProvider->PutRequestURL(
tsepez3f80c862016-05-16 12:03:24 -07005441 CFX_WideString::FromUTF8(bsURL.AsStringC()),
5442 CFX_WideString::FromUTF8(bsData.AsStringC()),
5443 CFX_WideString::FromUTF8(bsEncode.AsStringC()));
Dan Sinclair1770c022016-03-14 14:14:16 -04005444 if (bFlags) {
5445 FXJSE_Value_SetUTF8String(args.GetReturnValue(), "");
5446 } else {
dsinclair2235b7b2016-06-02 07:42:25 -07005447 pContext->ThrowException(XFA_IDS_SERVER_DENY);
Dan Sinclair1770c022016-03-14 14:14:16 -04005448 }
5449 } else {
dsinclair2235b7b2016-06-02 07:42:25 -07005450 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Put");
Dan Sinclair1770c022016-03-14 14:14:16 -04005451 }
5452}
dsinclair48d91dd2016-05-31 11:54:01 -07005453
5454// static
dsinclair12a6b0c2016-05-26 11:14:08 -07005455void CXFA_FM2JSContext::assign_value_operator(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04005456 const CFX_ByteStringC& szFuncName,
5457 CFXJSE_Arguments& args) {
dsinclairdd6a46c2016-05-26 08:41:45 -07005458 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07005459 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclairec3da5b2016-05-25 16:42:05 -07005460 v8::Isolate* pIsolate = pContext->GetScriptRuntime();
Dan Sinclair1770c022016-03-14 14:14:16 -04005461 if (args.GetLength() == 2) {
dsinclair86fad992016-05-31 11:34:04 -07005462 std::unique_ptr<CFXJSE_Value> lValue = args.GetValue(0);
5463 std::unique_ptr<CFXJSE_Value> rValue = GetSimpleValue(pThis, args, 1);
Dan Sinclair1770c022016-03-14 14:14:16 -04005464 FX_BOOL bSetStatus = TRUE;
dsinclair86fad992016-05-31 11:34:04 -07005465 if (FXJSE_Value_IsArray(lValue.get())) {
5466 std::unique_ptr<CFXJSE_Value> leftLengthValue(new CFXJSE_Value(pIsolate));
5467 FXJSE_Value_GetObjectProp(lValue.get(), "length", leftLengthValue.get());
5468 int32_t iLeftLength = FXJSE_Value_ToInteger(leftLengthValue.get());
5469 std::unique_ptr<CFXJSE_Value> jsObjectValue(new CFXJSE_Value(pIsolate));
5470 std::unique_ptr<CFXJSE_Value> propertyValue(new CFXJSE_Value(pIsolate));
5471 FXJSE_Value_GetObjectPropByIdx(lValue.get(), 1, propertyValue.get());
5472 if (FXJSE_Value_IsNull(propertyValue.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04005473 for (int32_t i = 2; i < iLeftLength; i++) {
dsinclair86fad992016-05-31 11:34:04 -07005474 FXJSE_Value_GetObjectPropByIdx(lValue.get(), i, jsObjectValue.get());
5475 bSetStatus = SetObjectDefaultValue(jsObjectValue.get(), rValue.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04005476 if (!bSetStatus) {
dsinclair2235b7b2016-06-02 07:42:25 -07005477 pContext->ThrowException(XFA_IDS_NOT_DEFAUL_VALUE);
Dan Sinclair1770c022016-03-14 14:14:16 -04005478 break;
5479 }
5480 }
5481 } else {
5482 CFX_ByteString propertyStr;
dsinclair86fad992016-05-31 11:34:04 -07005483 FXJSE_Value_ToUTF8String(propertyValue.get(), propertyStr);
Dan Sinclair1770c022016-03-14 14:14:16 -04005484 for (int32_t i = 2; i < iLeftLength; i++) {
dsinclair86fad992016-05-31 11:34:04 -07005485 FXJSE_Value_GetObjectPropByIdx(lValue.get(), i, jsObjectValue.get());
5486 FXJSE_Value_SetObjectProp(jsObjectValue.get(),
5487 propertyStr.AsStringC(), rValue.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04005488 }
5489 }
dsinclair86fad992016-05-31 11:34:04 -07005490 } else if (FXJSE_Value_IsObject(lValue.get())) {
5491 bSetStatus = SetObjectDefaultValue(lValue.get(), rValue.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04005492 if (!bSetStatus) {
dsinclair2235b7b2016-06-02 07:42:25 -07005493 pContext->ThrowException(XFA_IDS_NOT_DEFAUL_VALUE);
Dan Sinclair1770c022016-03-14 14:14:16 -04005494 }
5495 }
dsinclair86fad992016-05-31 11:34:04 -07005496 FXJSE_Value_Set(args.GetReturnValue(), rValue.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04005497 } else {
dsinclair2235b7b2016-06-02 07:42:25 -07005498 pContext->ThrowException(XFA_IDS_COMPILER_ERROR);
Dan Sinclair1770c022016-03-14 14:14:16 -04005499 }
5500}
dsinclair48d91dd2016-05-31 11:54:01 -07005501
5502// static
dsinclair12a6b0c2016-05-26 11:14:08 -07005503void CXFA_FM2JSContext::logical_or_operator(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04005504 const CFX_ByteStringC& szFuncName,
5505 CFXJSE_Arguments& args) {
5506 if (args.GetLength() == 2) {
dsinclair86fad992016-05-31 11:34:04 -07005507 std::unique_ptr<CFXJSE_Value> argFirst = GetSimpleValue(pThis, args, 0);
5508 std::unique_ptr<CFXJSE_Value> argSecond = GetSimpleValue(pThis, args, 1);
5509 if (FXJSE_Value_IsNull(argFirst.get()) &&
5510 FXJSE_Value_IsNull(argSecond.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04005511 FXJSE_Value_SetNull(args.GetReturnValue());
5512 } else {
dsinclair86fad992016-05-31 11:34:04 -07005513 FX_FLOAT first = ValueToFloat(pThis, argFirst.get());
5514 FX_FLOAT second = ValueToFloat(pThis, argSecond.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04005515 FXJSE_Value_SetInteger(args.GetReturnValue(), (first || second) ? 1 : 0);
5516 }
Dan Sinclair1770c022016-03-14 14:14:16 -04005517 } else {
5518 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07005519 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair2235b7b2016-06-02 07:42:25 -07005520 pContext->ThrowException(XFA_IDS_COMPILER_ERROR);
Dan Sinclair1770c022016-03-14 14:14:16 -04005521 }
5522}
dsinclair48d91dd2016-05-31 11:54:01 -07005523
5524// static
dsinclair12a6b0c2016-05-26 11:14:08 -07005525void CXFA_FM2JSContext::logical_and_operator(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04005526 const CFX_ByteStringC& szFuncName,
5527 CFXJSE_Arguments& args) {
5528 if (args.GetLength() == 2) {
dsinclair86fad992016-05-31 11:34:04 -07005529 std::unique_ptr<CFXJSE_Value> argFirst = GetSimpleValue(pThis, args, 0);
5530 std::unique_ptr<CFXJSE_Value> argSecond = GetSimpleValue(pThis, args, 1);
5531 if (FXJSE_Value_IsNull(argFirst.get()) &&
5532 FXJSE_Value_IsNull(argSecond.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04005533 FXJSE_Value_SetNull(args.GetReturnValue());
5534 } else {
dsinclair86fad992016-05-31 11:34:04 -07005535 FX_FLOAT first = ValueToFloat(pThis, argFirst.get());
5536 FX_FLOAT second = ValueToFloat(pThis, argSecond.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04005537 FXJSE_Value_SetInteger(args.GetReturnValue(), (first && second) ? 1 : 0);
5538 }
Dan Sinclair1770c022016-03-14 14:14:16 -04005539 } else {
5540 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07005541 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair2235b7b2016-06-02 07:42:25 -07005542 pContext->ThrowException(XFA_IDS_COMPILER_ERROR);
Dan Sinclair1770c022016-03-14 14:14:16 -04005543 }
5544}
dsinclair48d91dd2016-05-31 11:54:01 -07005545
5546// static
dsinclair12a6b0c2016-05-26 11:14:08 -07005547void CXFA_FM2JSContext::equality_operator(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04005548 const CFX_ByteStringC& szFuncName,
5549 CFXJSE_Arguments& args) {
5550 if (args.GetLength() == 2) {
dsinclair12a6b0c2016-05-26 11:14:08 -07005551 if (fm_ref_equal(pThis, args)) {
Dan Sinclair1770c022016-03-14 14:14:16 -04005552 FXJSE_Value_SetInteger(args.GetReturnValue(), 1);
5553 } else {
dsinclair86fad992016-05-31 11:34:04 -07005554 std::unique_ptr<CFXJSE_Value> argFirst = GetSimpleValue(pThis, args, 0);
5555 std::unique_ptr<CFXJSE_Value> argSecond = GetSimpleValue(pThis, args, 1);
5556 if (FXJSE_Value_IsNull(argFirst.get()) ||
5557 FXJSE_Value_IsNull(argSecond.get())) {
5558 FXJSE_Value_SetInteger(args.GetReturnValue(),
5559 (FXJSE_Value_IsNull(argFirst.get()) &&
5560 FXJSE_Value_IsNull(argSecond.get()))
5561 ? 1
5562 : 0);
5563 } else if (FXJSE_Value_IsUTF8String(argFirst.get()) &&
5564 FXJSE_Value_IsUTF8String(argSecond.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04005565 CFX_ByteString firstOutput;
5566 CFX_ByteString secondOutput;
dsinclair86fad992016-05-31 11:34:04 -07005567 FXJSE_Value_ToUTF8String(argFirst.get(), firstOutput);
5568 FXJSE_Value_ToUTF8String(argSecond.get(), secondOutput);
Dan Sinclair1770c022016-03-14 14:14:16 -04005569 FXJSE_Value_SetInteger(args.GetReturnValue(),
tsepez9f2970c2016-04-01 10:23:04 -07005570 firstOutput == secondOutput);
Dan Sinclair1770c022016-03-14 14:14:16 -04005571 } else {
dsinclair86fad992016-05-31 11:34:04 -07005572 FX_DOUBLE first = ValueToDouble(pThis, argFirst.get());
5573 FX_DOUBLE second = ValueToDouble(pThis, argSecond.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04005574 FXJSE_Value_SetInteger(args.GetReturnValue(),
5575 (first == second) ? 1 : 0);
5576 }
Dan Sinclair1770c022016-03-14 14:14:16 -04005577 }
5578 } else {
5579 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07005580 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair2235b7b2016-06-02 07:42:25 -07005581 pContext->ThrowException(XFA_IDS_COMPILER_ERROR);
Dan Sinclair1770c022016-03-14 14:14:16 -04005582 }
5583}
dsinclair48d91dd2016-05-31 11:54:01 -07005584
5585// static
dsinclair12a6b0c2016-05-26 11:14:08 -07005586void CXFA_FM2JSContext::notequality_operator(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04005587 const CFX_ByteStringC& szFuncName,
5588 CFXJSE_Arguments& args) {
5589 if (args.GetLength() == 2) {
dsinclair12a6b0c2016-05-26 11:14:08 -07005590 if (fm_ref_equal(pThis, args)) {
Dan Sinclair1770c022016-03-14 14:14:16 -04005591 FXJSE_Value_SetInteger(args.GetReturnValue(), 0);
5592 } else {
dsinclair86fad992016-05-31 11:34:04 -07005593 std::unique_ptr<CFXJSE_Value> argFirst = GetSimpleValue(pThis, args, 0);
5594 std::unique_ptr<CFXJSE_Value> argSecond = GetSimpleValue(pThis, args, 1);
5595 if (FXJSE_Value_IsNull(argFirst.get()) ||
5596 FXJSE_Value_IsNull(argSecond.get())) {
5597 FXJSE_Value_SetInteger(args.GetReturnValue(),
5598 (FXJSE_Value_IsNull(argFirst.get()) &&
5599 FXJSE_Value_IsNull(argSecond.get()))
5600 ? 0
5601 : 1);
5602 } else if (FXJSE_Value_IsUTF8String(argFirst.get()) &&
5603 FXJSE_Value_IsUTF8String(argSecond.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04005604 CFX_ByteString firstOutput;
5605 CFX_ByteString secondOutput;
dsinclair86fad992016-05-31 11:34:04 -07005606 FXJSE_Value_ToUTF8String(argFirst.get(), firstOutput);
5607 FXJSE_Value_ToUTF8String(argSecond.get(), secondOutput);
Dan Sinclair1770c022016-03-14 14:14:16 -04005608 FXJSE_Value_SetInteger(args.GetReturnValue(),
tsepez9f2970c2016-04-01 10:23:04 -07005609 firstOutput != secondOutput);
Dan Sinclair1770c022016-03-14 14:14:16 -04005610 } else {
dsinclair86fad992016-05-31 11:34:04 -07005611 FX_DOUBLE first = ValueToDouble(pThis, argFirst.get());
5612 FX_DOUBLE second = ValueToDouble(pThis, argSecond.get());
tsepez9f2970c2016-04-01 10:23:04 -07005613 FXJSE_Value_SetInteger(args.GetReturnValue(), first != second);
Dan Sinclair1770c022016-03-14 14:14:16 -04005614 }
Dan Sinclair1770c022016-03-14 14:14:16 -04005615 }
5616 } else {
5617 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07005618 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair2235b7b2016-06-02 07:42:25 -07005619 pContext->ThrowException(XFA_IDS_COMPILER_ERROR);
Dan Sinclair1770c022016-03-14 14:14:16 -04005620 }
5621}
dsinclair48d91dd2016-05-31 11:54:01 -07005622
5623// static
dsinclair12a6b0c2016-05-26 11:14:08 -07005624FX_BOOL CXFA_FM2JSContext::fm_ref_equal(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04005625 CFXJSE_Arguments& args) {
5626 FX_BOOL bRet = FALSE;
dsinclairdd6a46c2016-05-26 08:41:45 -07005627 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07005628 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclairec3da5b2016-05-25 16:42:05 -07005629 v8::Isolate* pIsolate = pContext->GetScriptRuntime();
dsinclair86fad992016-05-31 11:34:04 -07005630 std::unique_ptr<CFXJSE_Value> argFirst = args.GetValue(0);
5631 std::unique_ptr<CFXJSE_Value> argSecond = args.GetValue(1);
5632 if (FXJSE_Value_IsArray(argFirst.get()) &&
5633 FXJSE_Value_IsArray(argSecond.get())) {
5634 std::unique_ptr<CFXJSE_Value> firstFlagValue(new CFXJSE_Value(pIsolate));
5635 std::unique_ptr<CFXJSE_Value> secondFlagValue(new CFXJSE_Value(pIsolate));
5636 FXJSE_Value_GetObjectPropByIdx(argFirst.get(), 0, firstFlagValue.get());
5637 FXJSE_Value_GetObjectPropByIdx(argSecond.get(), 0, secondFlagValue.get());
5638 if ((FXJSE_Value_ToInteger(firstFlagValue.get()) == 3) &&
5639 (FXJSE_Value_ToInteger(secondFlagValue.get()) == 3)) {
5640 std::unique_ptr<CFXJSE_Value> firstJSObject(new CFXJSE_Value(pIsolate));
5641 std::unique_ptr<CFXJSE_Value> secondJSObject(new CFXJSE_Value(pIsolate));
5642 FXJSE_Value_GetObjectPropByIdx(argFirst.get(), 2, firstJSObject.get());
5643 FXJSE_Value_GetObjectPropByIdx(argSecond.get(), 2, secondJSObject.get());
5644 if (!FXJSE_Value_IsNull(firstJSObject.get()) &&
5645 !FXJSE_Value_IsNull(secondJSObject.get())) {
dsinclair48d91dd2016-05-31 11:54:01 -07005646 bRet = (FXJSE_Value_ToObject(firstJSObject.get(), nullptr) ==
5647 FXJSE_Value_ToObject(secondJSObject.get(), nullptr));
Dan Sinclair1770c022016-03-14 14:14:16 -04005648 }
Dan Sinclair1770c022016-03-14 14:14:16 -04005649 }
Dan Sinclair1770c022016-03-14 14:14:16 -04005650 }
Dan Sinclair1770c022016-03-14 14:14:16 -04005651 return bRet;
5652}
dsinclair48d91dd2016-05-31 11:54:01 -07005653
5654// static
dsinclair12a6b0c2016-05-26 11:14:08 -07005655void CXFA_FM2JSContext::less_operator(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04005656 const CFX_ByteStringC& szFuncName,
5657 CFXJSE_Arguments& args) {
5658 if (args.GetLength() == 2) {
dsinclair86fad992016-05-31 11:34:04 -07005659 std::unique_ptr<CFXJSE_Value> argFirst = GetSimpleValue(pThis, args, 0);
5660 std::unique_ptr<CFXJSE_Value> argSecond = GetSimpleValue(pThis, args, 1);
5661 if (FXJSE_Value_IsNull(argFirst.get()) ||
5662 FXJSE_Value_IsNull(argSecond.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04005663 FXJSE_Value_SetInteger(args.GetReturnValue(), 0);
dsinclair86fad992016-05-31 11:34:04 -07005664 } else if (FXJSE_Value_IsUTF8String(argFirst.get()) &&
5665 FXJSE_Value_IsUTF8String(argSecond.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04005666 CFX_ByteString firstOutput;
5667 CFX_ByteString secondOutput;
dsinclair86fad992016-05-31 11:34:04 -07005668 FXJSE_Value_ToUTF8String(argFirst.get(), firstOutput);
5669 FXJSE_Value_ToUTF8String(argSecond.get(), secondOutput);
tsepez28f97ff2016-04-04 16:41:35 -07005670 FXJSE_Value_SetInteger(
5671 args.GetReturnValue(),
tsepez4c3debb2016-04-08 12:20:38 -07005672 firstOutput.Compare(secondOutput.AsStringC()) == -1);
Dan Sinclair1770c022016-03-14 14:14:16 -04005673 } else {
dsinclair86fad992016-05-31 11:34:04 -07005674 FX_DOUBLE first = ValueToDouble(pThis, argFirst.get());
5675 FX_DOUBLE second = ValueToDouble(pThis, argSecond.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04005676 FXJSE_Value_SetInteger(args.GetReturnValue(), (first < second) ? 1 : 0);
5677 }
Dan Sinclair1770c022016-03-14 14:14:16 -04005678 } else {
5679 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07005680 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair2235b7b2016-06-02 07:42:25 -07005681 pContext->ThrowException(XFA_IDS_COMPILER_ERROR);
Dan Sinclair1770c022016-03-14 14:14:16 -04005682 }
5683}
dsinclair48d91dd2016-05-31 11:54:01 -07005684
5685// static
dsinclair12a6b0c2016-05-26 11:14:08 -07005686void CXFA_FM2JSContext::lessequal_operator(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04005687 const CFX_ByteStringC& szFuncName,
5688 CFXJSE_Arguments& args) {
5689 if (args.GetLength() == 2) {
dsinclair86fad992016-05-31 11:34:04 -07005690 std::unique_ptr<CFXJSE_Value> argFirst = GetSimpleValue(pThis, args, 0);
5691 std::unique_ptr<CFXJSE_Value> argSecond = GetSimpleValue(pThis, args, 1);
5692 if (FXJSE_Value_IsNull(argFirst.get()) ||
5693 FXJSE_Value_IsNull(argSecond.get())) {
5694 FXJSE_Value_SetInteger(args.GetReturnValue(),
5695 (FXJSE_Value_IsNull(argFirst.get()) &&
5696 FXJSE_Value_IsNull(argSecond.get()))
5697 ? 1
5698 : 0);
5699 } else if (FXJSE_Value_IsUTF8String(argFirst.get()) &&
5700 FXJSE_Value_IsUTF8String(argSecond.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04005701 CFX_ByteString firstOutput;
5702 CFX_ByteString secondOutput;
dsinclair86fad992016-05-31 11:34:04 -07005703 FXJSE_Value_ToUTF8String(argFirst.get(), firstOutput);
5704 FXJSE_Value_ToUTF8String(argSecond.get(), secondOutput);
tsepez28f97ff2016-04-04 16:41:35 -07005705 FXJSE_Value_SetInteger(
5706 args.GetReturnValue(),
tsepez4c3debb2016-04-08 12:20:38 -07005707 firstOutput.Compare(secondOutput.AsStringC()) != 1);
Dan Sinclair1770c022016-03-14 14:14:16 -04005708 } else {
dsinclair86fad992016-05-31 11:34:04 -07005709 FX_DOUBLE first = ValueToDouble(pThis, argFirst.get());
5710 FX_DOUBLE second = ValueToDouble(pThis, argSecond.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04005711 FXJSE_Value_SetInteger(args.GetReturnValue(), (first <= second) ? 1 : 0);
5712 }
Dan Sinclair1770c022016-03-14 14:14:16 -04005713 } else {
5714 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07005715 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair2235b7b2016-06-02 07:42:25 -07005716 pContext->ThrowException(XFA_IDS_COMPILER_ERROR);
Dan Sinclair1770c022016-03-14 14:14:16 -04005717 }
5718}
dsinclair48d91dd2016-05-31 11:54:01 -07005719
5720// static
dsinclair12a6b0c2016-05-26 11:14:08 -07005721void CXFA_FM2JSContext::greater_operator(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04005722 const CFX_ByteStringC& szFuncName,
5723 CFXJSE_Arguments& args) {
5724 if (args.GetLength() == 2) {
dsinclair86fad992016-05-31 11:34:04 -07005725 std::unique_ptr<CFXJSE_Value> argFirst = GetSimpleValue(pThis, args, 0);
5726 std::unique_ptr<CFXJSE_Value> argSecond = GetSimpleValue(pThis, args, 1);
5727 if (FXJSE_Value_IsNull(argFirst.get()) ||
5728 FXJSE_Value_IsNull(argSecond.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04005729 FXJSE_Value_SetInteger(args.GetReturnValue(), 0);
dsinclair86fad992016-05-31 11:34:04 -07005730 } else if (FXJSE_Value_IsUTF8String(argFirst.get()) &&
5731 FXJSE_Value_IsUTF8String(argSecond.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04005732 CFX_ByteString firstOutput;
5733 CFX_ByteString secondOutput;
dsinclair86fad992016-05-31 11:34:04 -07005734 FXJSE_Value_ToUTF8String(argFirst.get(), firstOutput);
5735 FXJSE_Value_ToUTF8String(argSecond.get(), secondOutput);
tsepez28f97ff2016-04-04 16:41:35 -07005736 FXJSE_Value_SetInteger(
5737 args.GetReturnValue(),
tsepez4c3debb2016-04-08 12:20:38 -07005738 firstOutput.Compare(secondOutput.AsStringC()) == 1);
Dan Sinclair1770c022016-03-14 14:14:16 -04005739 } else {
dsinclair86fad992016-05-31 11:34:04 -07005740 FX_DOUBLE first = ValueToDouble(pThis, argFirst.get());
5741 FX_DOUBLE second = ValueToDouble(pThis, argSecond.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04005742 FXJSE_Value_SetInteger(args.GetReturnValue(), (first > second) ? 1 : 0);
5743 }
Dan Sinclair1770c022016-03-14 14:14:16 -04005744 } else {
5745 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07005746 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair2235b7b2016-06-02 07:42:25 -07005747 pContext->ThrowException(XFA_IDS_COMPILER_ERROR);
Dan Sinclair1770c022016-03-14 14:14:16 -04005748 }
5749}
dsinclair48d91dd2016-05-31 11:54:01 -07005750
5751// static
dsinclair12a6b0c2016-05-26 11:14:08 -07005752void CXFA_FM2JSContext::greaterequal_operator(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04005753 const CFX_ByteStringC& szFuncName,
5754 CFXJSE_Arguments& args) {
5755 if (args.GetLength() == 2) {
dsinclair86fad992016-05-31 11:34:04 -07005756 std::unique_ptr<CFXJSE_Value> argFirst = GetSimpleValue(pThis, args, 0);
5757 std::unique_ptr<CFXJSE_Value> argSecond = GetSimpleValue(pThis, args, 1);
5758 if (FXJSE_Value_IsNull(argFirst.get()) ||
5759 FXJSE_Value_IsNull(argSecond.get())) {
5760 FXJSE_Value_SetInteger(args.GetReturnValue(),
5761 (FXJSE_Value_IsNull(argFirst.get()) &&
5762 FXJSE_Value_IsNull(argSecond.get()))
5763 ? 1
5764 : 0);
5765 } else if (FXJSE_Value_IsUTF8String(argFirst.get()) &&
5766 FXJSE_Value_IsUTF8String(argSecond.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04005767 CFX_ByteString firstOutput;
5768 CFX_ByteString secondOutput;
dsinclair86fad992016-05-31 11:34:04 -07005769 FXJSE_Value_ToUTF8String(argFirst.get(), firstOutput);
5770 FXJSE_Value_ToUTF8String(argSecond.get(), secondOutput);
tsepez28f97ff2016-04-04 16:41:35 -07005771 FXJSE_Value_SetInteger(
5772 args.GetReturnValue(),
tsepez4c3debb2016-04-08 12:20:38 -07005773 firstOutput.Compare(secondOutput.AsStringC()) != -1);
Dan Sinclair1770c022016-03-14 14:14:16 -04005774 } else {
dsinclair86fad992016-05-31 11:34:04 -07005775 FX_DOUBLE first = ValueToDouble(pThis, argFirst.get());
5776 FX_DOUBLE second = ValueToDouble(pThis, argSecond.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04005777 FXJSE_Value_SetInteger(args.GetReturnValue(), (first >= second) ? 1 : 0);
5778 }
Dan Sinclair1770c022016-03-14 14:14:16 -04005779 } else {
5780 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07005781 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair2235b7b2016-06-02 07:42:25 -07005782 pContext->ThrowException(XFA_IDS_COMPILER_ERROR);
Dan Sinclair1770c022016-03-14 14:14:16 -04005783 }
5784}
dsinclair48d91dd2016-05-31 11:54:01 -07005785
5786// static
dsinclair12a6b0c2016-05-26 11:14:08 -07005787void CXFA_FM2JSContext::plus_operator(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04005788 const CFX_ByteStringC& szFuncName,
5789 CFXJSE_Arguments& args) {
5790 if (args.GetLength() == 2) {
dsinclair86fad992016-05-31 11:34:04 -07005791 std::unique_ptr<CFXJSE_Value> argFirst = args.GetValue(0);
5792 std::unique_ptr<CFXJSE_Value> argSecond = args.GetValue(1);
5793 if (ValueIsNull(pThis, argFirst.get()) &&
5794 ValueIsNull(pThis, argSecond.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04005795 FXJSE_Value_SetNull(args.GetReturnValue());
5796 } else {
dsinclair86fad992016-05-31 11:34:04 -07005797 FX_DOUBLE first = ValueToDouble(pThis, argFirst.get());
5798 FX_DOUBLE second = ValueToDouble(pThis, argSecond.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04005799 FXJSE_Value_SetDouble(args.GetReturnValue(), first + second);
5800 }
Dan Sinclair1770c022016-03-14 14:14:16 -04005801 } else {
5802 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07005803 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair2235b7b2016-06-02 07:42:25 -07005804 pContext->ThrowException(XFA_IDS_COMPILER_ERROR);
Dan Sinclair1770c022016-03-14 14:14:16 -04005805 }
5806}
dsinclair48d91dd2016-05-31 11:54:01 -07005807
5808// static
dsinclair12a6b0c2016-05-26 11:14:08 -07005809void CXFA_FM2JSContext::minus_operator(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04005810 const CFX_ByteStringC& szFuncName,
5811 CFXJSE_Arguments& args) {
5812 if (args.GetLength() == 2) {
dsinclair86fad992016-05-31 11:34:04 -07005813 std::unique_ptr<CFXJSE_Value> argFirst = GetSimpleValue(pThis, args, 0);
5814 std::unique_ptr<CFXJSE_Value> argSecond = GetSimpleValue(pThis, args, 1);
5815 if (FXJSE_Value_IsNull(argFirst.get()) &&
5816 FXJSE_Value_IsNull(argSecond.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04005817 FXJSE_Value_SetNull(args.GetReturnValue());
5818 } else {
dsinclair86fad992016-05-31 11:34:04 -07005819 FX_DOUBLE first = ValueToDouble(pThis, argFirst.get());
5820 FX_DOUBLE second = ValueToDouble(pThis, argSecond.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04005821 FXJSE_Value_SetDouble(args.GetReturnValue(), first - second);
5822 }
Dan Sinclair1770c022016-03-14 14:14:16 -04005823 } else {
5824 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07005825 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair2235b7b2016-06-02 07:42:25 -07005826 pContext->ThrowException(XFA_IDS_COMPILER_ERROR);
Dan Sinclair1770c022016-03-14 14:14:16 -04005827 }
5828}
dsinclair48d91dd2016-05-31 11:54:01 -07005829
5830// static
dsinclair12a6b0c2016-05-26 11:14:08 -07005831void CXFA_FM2JSContext::multiple_operator(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04005832 const CFX_ByteStringC& szFuncName,
5833 CFXJSE_Arguments& args) {
5834 if (args.GetLength() == 2) {
dsinclair86fad992016-05-31 11:34:04 -07005835 std::unique_ptr<CFXJSE_Value> argFirst = GetSimpleValue(pThis, args, 0);
5836 std::unique_ptr<CFXJSE_Value> argSecond = GetSimpleValue(pThis, args, 1);
5837 if (FXJSE_Value_IsNull(argFirst.get()) &&
5838 FXJSE_Value_IsNull(argSecond.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04005839 FXJSE_Value_SetNull(args.GetReturnValue());
5840 } else {
dsinclair86fad992016-05-31 11:34:04 -07005841 FX_DOUBLE first = ValueToDouble(pThis, argFirst.get());
5842 FX_DOUBLE second = ValueToDouble(pThis, argSecond.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04005843 FXJSE_Value_SetDouble(args.GetReturnValue(), first * second);
5844 }
Dan Sinclair1770c022016-03-14 14:14:16 -04005845 } else {
5846 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07005847 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair2235b7b2016-06-02 07:42:25 -07005848 pContext->ThrowException(XFA_IDS_COMPILER_ERROR);
Dan Sinclair1770c022016-03-14 14:14:16 -04005849 }
5850}
dsinclair48d91dd2016-05-31 11:54:01 -07005851
5852// static
dsinclair12a6b0c2016-05-26 11:14:08 -07005853void CXFA_FM2JSContext::divide_operator(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04005854 const CFX_ByteStringC& szFuncName,
5855 CFXJSE_Arguments& args) {
dsinclairdd6a46c2016-05-26 08:41:45 -07005856 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07005857 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
Dan Sinclair1770c022016-03-14 14:14:16 -04005858 if (args.GetLength() == 2) {
dsinclair86fad992016-05-31 11:34:04 -07005859 std::unique_ptr<CFXJSE_Value> argFirst = GetSimpleValue(pThis, args, 0);
5860 std::unique_ptr<CFXJSE_Value> argSecond = GetSimpleValue(pThis, args, 1);
5861 if (FXJSE_Value_IsNull(argFirst.get()) &&
5862 FXJSE_Value_IsNull(argSecond.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04005863 FXJSE_Value_SetNull(args.GetReturnValue());
5864 } else {
dsinclair86fad992016-05-31 11:34:04 -07005865 FX_DOUBLE first = ValueToDouble(pThis, argFirst.get());
5866 FX_DOUBLE second = ValueToDouble(pThis, argSecond.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04005867 if (second == 0.0) {
dsinclair2235b7b2016-06-02 07:42:25 -07005868 pContext->ThrowException(XFA_IDS_DIVIDE_ZERO);
Dan Sinclair1770c022016-03-14 14:14:16 -04005869 } else {
5870 FXJSE_Value_SetDouble(args.GetReturnValue(), first / second);
5871 }
5872 }
Dan Sinclair1770c022016-03-14 14:14:16 -04005873 } else {
dsinclair2235b7b2016-06-02 07:42:25 -07005874 pContext->ThrowException(XFA_IDS_COMPILER_ERROR);
Dan Sinclair1770c022016-03-14 14:14:16 -04005875 }
5876}
dsinclair48d91dd2016-05-31 11:54:01 -07005877
5878// static
dsinclair12a6b0c2016-05-26 11:14:08 -07005879void CXFA_FM2JSContext::positive_operator(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04005880 const CFX_ByteStringC& szFuncName,
5881 CFXJSE_Arguments& args) {
dsinclair48d91dd2016-05-31 11:54:01 -07005882 if (args.GetLength() == 1) {
dsinclair86fad992016-05-31 11:34:04 -07005883 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
5884 if (FXJSE_Value_IsNull(argOne.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04005885 FXJSE_Value_SetNull(args.GetReturnValue());
5886 } else {
5887 FXJSE_Value_SetDouble(args.GetReturnValue(),
dsinclair86fad992016-05-31 11:34:04 -07005888 0.0 + ValueToDouble(pThis, argOne.get()));
Dan Sinclair1770c022016-03-14 14:14:16 -04005889 }
Dan Sinclair1770c022016-03-14 14:14:16 -04005890 } else {
5891 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07005892 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair2235b7b2016-06-02 07:42:25 -07005893 pContext->ThrowException(XFA_IDS_COMPILER_ERROR);
Dan Sinclair1770c022016-03-14 14:14:16 -04005894 }
5895}
dsinclair48d91dd2016-05-31 11:54:01 -07005896
5897// static
dsinclair12a6b0c2016-05-26 11:14:08 -07005898void CXFA_FM2JSContext::negative_operator(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04005899 const CFX_ByteStringC& szFuncName,
5900 CFXJSE_Arguments& args) {
dsinclair48d91dd2016-05-31 11:54:01 -07005901 if (args.GetLength() == 1) {
dsinclair86fad992016-05-31 11:34:04 -07005902 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
5903 if (FXJSE_Value_IsNull(argOne.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04005904 FXJSE_Value_SetNull(args.GetReturnValue());
5905 } else {
5906 FXJSE_Value_SetDouble(args.GetReturnValue(),
dsinclair86fad992016-05-31 11:34:04 -07005907 0.0 - ValueToDouble(pThis, argOne.get()));
Dan Sinclair1770c022016-03-14 14:14:16 -04005908 }
Dan Sinclair1770c022016-03-14 14:14:16 -04005909 } else {
5910 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07005911 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair2235b7b2016-06-02 07:42:25 -07005912 pContext->ThrowException(XFA_IDS_COMPILER_ERROR);
Dan Sinclair1770c022016-03-14 14:14:16 -04005913 }
5914}
dsinclair48d91dd2016-05-31 11:54:01 -07005915
5916// static
dsinclair12a6b0c2016-05-26 11:14:08 -07005917void CXFA_FM2JSContext::logical_not_operator(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04005918 const CFX_ByteStringC& szFuncName,
5919 CFXJSE_Arguments& args) {
dsinclair48d91dd2016-05-31 11:54:01 -07005920 if (args.GetLength() == 1) {
dsinclair86fad992016-05-31 11:34:04 -07005921 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
5922 if (FXJSE_Value_IsNull(argOne.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04005923 FXJSE_Value_SetNull(args.GetReturnValue());
5924 } else {
dsinclair86fad992016-05-31 11:34:04 -07005925 FX_DOUBLE first = ValueToDouble(pThis, argOne.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04005926 FXJSE_Value_SetInteger(args.GetReturnValue(), (first == 0.0) ? 1 : 0);
5927 }
Dan Sinclair1770c022016-03-14 14:14:16 -04005928 } else {
5929 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07005930 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair2235b7b2016-06-02 07:42:25 -07005931 pContext->ThrowException(XFA_IDS_COMPILER_ERROR);
Dan Sinclair1770c022016-03-14 14:14:16 -04005932 }
5933}
dsinclair48d91dd2016-05-31 11:54:01 -07005934
5935// static
dsinclair12a6b0c2016-05-26 11:14:08 -07005936void CXFA_FM2JSContext::dot_accessor(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04005937 const CFX_ByteStringC& szFuncName,
5938 CFXJSE_Arguments& args) {
dsinclairdd6a46c2016-05-26 08:41:45 -07005939 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07005940 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclairec3da5b2016-05-25 16:42:05 -07005941 v8::Isolate* pIsolate = pContext->GetScriptRuntime();
Dan Sinclair1770c022016-03-14 14:14:16 -04005942 int32_t argc = args.GetLength();
5943 if ((argc == 4) || (argc == 5)) {
5944 FX_BOOL bIsStar = TRUE;
dsinclair86fad992016-05-31 11:34:04 -07005945 std::unique_ptr<CFXJSE_Value> argAccessor = args.GetValue(0);
Dan Sinclair1770c022016-03-14 14:14:16 -04005946 CFX_ByteString bsAccessorName = args.GetUTF8String(1);
5947 CFX_ByteString szName = args.GetUTF8String(2);
5948 int32_t iIndexFlags = args.GetInt32(3);
5949 int32_t iIndexValue = 0;
Dan Sinclair1770c022016-03-14 14:14:16 -04005950 if (argc == 5) {
5951 bIsStar = FALSE;
dsinclair86fad992016-05-31 11:34:04 -07005952 std::unique_ptr<CFXJSE_Value> argIndex = args.GetValue(4);
5953 iIndexValue = ValueToInteger(pThis, argIndex.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04005954 }
5955 CFX_ByteString szSomExp;
tsepez4c3debb2016-04-08 12:20:38 -07005956 GenerateSomExpression(szName.AsStringC(), iIndexFlags, iIndexValue, bIsStar,
5957 szSomExp);
dsinclair86fad992016-05-31 11:34:04 -07005958 if (FXJSE_Value_IsArray(argAccessor.get())) {
5959 std::unique_ptr<CFXJSE_Value> pLengthValue(new CFXJSE_Value(pIsolate));
5960 FXJSE_Value_GetObjectProp(argAccessor.get(), "length",
5961 pLengthValue.get());
5962 int32_t iLength = FXJSE_Value_ToInteger(pLengthValue.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04005963 int32_t iCounter = 0;
dsinclair12a6b0c2016-05-26 11:14:08 -07005964 CFXJSE_Value*** hResolveValues = FX_Alloc(CFXJSE_Value**, iLength - 2);
Dan Sinclair1770c022016-03-14 14:14:16 -04005965 int32_t* iSizes = FX_Alloc(int32_t, iLength - 2);
5966 for (int32_t i = 0; i < (iLength - 2); i++) {
5967 iSizes[i] = 0;
5968 }
dsinclair86fad992016-05-31 11:34:04 -07005969 std::unique_ptr<CFXJSE_Value> hJSObjValue(new CFXJSE_Value(pIsolate));
Dan Sinclair1770c022016-03-14 14:14:16 -04005970 FX_BOOL bAttribute = FALSE;
5971 for (int32_t i = 2; i < iLength; i++) {
dsinclair86fad992016-05-31 11:34:04 -07005972 FXJSE_Value_GetObjectPropByIdx(argAccessor.get(), i, hJSObjValue.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04005973 XFA_RESOLVENODE_RS resoveNodeRS;
dsinclair86fad992016-05-31 11:34:04 -07005974 int32_t iRet =
5975 ResolveObjects(pThis, hJSObjValue.get(), szSomExp.AsStringC(),
5976 resoveNodeRS, TRUE, szName.IsEmpty());
Dan Sinclair1770c022016-03-14 14:14:16 -04005977 if (iRet > 0) {
dsinclair86fad992016-05-31 11:34:04 -07005978 ParseResolveResult(pThis, resoveNodeRS, hJSObjValue.get(),
Dan Sinclair1770c022016-03-14 14:14:16 -04005979 hResolveValues[i - 2], iSizes[i - 2], bAttribute);
5980 iCounter += iSizes[i - 2];
5981 }
5982 }
Dan Sinclair1770c022016-03-14 14:14:16 -04005983 if (iCounter > 0) {
dsinclair12a6b0c2016-05-26 11:14:08 -07005984 CFXJSE_Value** rgValues = FX_Alloc(CFXJSE_Value*, iCounter + 2);
dsinclair86fad992016-05-31 11:34:04 -07005985 for (int32_t i = 0; i < (iCounter + 2); i++)
5986 rgValues[i] = new CFXJSE_Value(pIsolate);
5987
Dan Sinclair1770c022016-03-14 14:14:16 -04005988 FXJSE_Value_SetInteger(rgValues[0], 1);
5989 if (bAttribute) {
tsepez4c3debb2016-04-08 12:20:38 -07005990 FXJSE_Value_SetUTF8String(rgValues[1], szName.AsStringC());
Dan Sinclair1770c022016-03-14 14:14:16 -04005991 } else {
5992 FXJSE_Value_SetNull(rgValues[1]);
5993 }
5994 int32_t iIndex = 2;
5995 for (int32_t i = 0; i < iLength - 2; i++) {
5996 for (int32_t j = 0; j < iSizes[i]; j++) {
5997 FXJSE_Value_Set(rgValues[iIndex], hResolveValues[i][j]);
5998 iIndex++;
5999 }
6000 }
6001 FXJSE_Value_SetArray(args.GetReturnValue(), (iCounter + 2), rgValues);
dsinclair86fad992016-05-31 11:34:04 -07006002 for (int32_t i = 0; i < (iCounter + 2); i++)
6003 delete rgValues[i];
6004
Dan Sinclair1770c022016-03-14 14:14:16 -04006005 FX_Free(rgValues);
6006 } else {
6007 CFX_WideString wsPropertyName =
tsepez4c3debb2016-04-08 12:20:38 -07006008 CFX_WideString::FromUTF8(szName.AsStringC());
Dan Sinclair1770c022016-03-14 14:14:16 -04006009 CFX_WideString wsSomExpression =
tsepez4c3debb2016-04-08 12:20:38 -07006010 CFX_WideString::FromUTF8(szSomExp.AsStringC());
dsinclair2235b7b2016-06-02 07:42:25 -07006011 pContext->ThrowException(XFA_IDS_ACCESS_PROPERTY_IN_NOT_OBJECT,
6012 wsPropertyName.c_str(),
6013 wsSomExpression.c_str());
Dan Sinclair1770c022016-03-14 14:14:16 -04006014 }
6015 for (int32_t i = 0; i < iLength - 2; i++) {
dsinclair86fad992016-05-31 11:34:04 -07006016 for (int32_t j = 0; j < iSizes[i]; j++)
6017 delete hResolveValues[i][j];
6018
Dan Sinclair1770c022016-03-14 14:14:16 -04006019 if (iSizes[i] > 0) {
6020 FX_Free(hResolveValues[i]);
6021 }
6022 }
6023 FX_Free(hResolveValues);
6024 FX_Free(iSizes);
6025 } else {
6026 XFA_RESOLVENODE_RS resoveNodeRS;
6027 int32_t iRet = 0;
dsinclair86fad992016-05-31 11:34:04 -07006028 if (FXJSE_Value_IsObject(argAccessor.get()) ||
6029 (FXJSE_Value_IsNull(argAccessor.get()) && bsAccessorName.IsEmpty())) {
6030 iRet = ResolveObjects(pThis, argAccessor.get(), szSomExp.AsStringC(),
tsepez28f97ff2016-04-04 16:41:35 -07006031 resoveNodeRS, TRUE, szName.IsEmpty());
dsinclair86fad992016-05-31 11:34:04 -07006032 } else if (!FXJSE_Value_IsObject(argAccessor.get()) &&
Dan Sinclair1770c022016-03-14 14:14:16 -04006033 !bsAccessorName.IsEmpty()) {
dsinclair86fad992016-05-31 11:34:04 -07006034 FX_BOOL bGetObject = GetObjectByName(pThis, argAccessor.get(),
6035 bsAccessorName.AsStringC());
Dan Sinclair1770c022016-03-14 14:14:16 -04006036 if (bGetObject) {
dsinclair86fad992016-05-31 11:34:04 -07006037 iRet = ResolveObjects(pThis, argAccessor.get(), szSomExp.AsStringC(),
tsepez28f97ff2016-04-04 16:41:35 -07006038 resoveNodeRS, TRUE, szName.IsEmpty());
Dan Sinclair1770c022016-03-14 14:14:16 -04006039 }
6040 }
6041 if (iRet > 0) {
dsinclair12a6b0c2016-05-26 11:14:08 -07006042 CFXJSE_Value** hResolveValues;
Dan Sinclair1770c022016-03-14 14:14:16 -04006043 int32_t iSize = 0;
6044 FX_BOOL bAttribute = FALSE;
dsinclair86fad992016-05-31 11:34:04 -07006045 ParseResolveResult(pThis, resoveNodeRS, argAccessor.get(),
6046 hResolveValues, iSize, bAttribute);
dsinclair12a6b0c2016-05-26 11:14:08 -07006047 CFXJSE_Value** rgValues = FX_Alloc(CFXJSE_Value*, iSize + 2);
dsinclair86fad992016-05-31 11:34:04 -07006048 for (int32_t i = 0; i < (iSize + 2); i++)
6049 rgValues[i] = new CFXJSE_Value(pIsolate);
6050
Dan Sinclair1770c022016-03-14 14:14:16 -04006051 FXJSE_Value_SetInteger(rgValues[0], 1);
6052 if (bAttribute) {
tsepez4c3debb2016-04-08 12:20:38 -07006053 FXJSE_Value_SetUTF8String(rgValues[1], szName.AsStringC());
Dan Sinclair1770c022016-03-14 14:14:16 -04006054 } else {
6055 FXJSE_Value_SetNull(rgValues[1]);
6056 }
6057 for (int32_t i = 0; i < iSize; i++) {
6058 FXJSE_Value_Set(rgValues[i + 2], hResolveValues[i]);
6059 }
6060 FXJSE_Value_SetArray(args.GetReturnValue(), (iSize + 2), rgValues);
dsinclair86fad992016-05-31 11:34:04 -07006061 for (int32_t i = 0; i < (iSize + 2); i++)
6062 delete rgValues[i];
6063
Dan Sinclair1770c022016-03-14 14:14:16 -04006064 FX_Free(rgValues);
dsinclair86fad992016-05-31 11:34:04 -07006065 for (int32_t i = 0; i < iSize; i++)
6066 delete hResolveValues[i];
6067
Dan Sinclair1770c022016-03-14 14:14:16 -04006068 FX_Free(hResolveValues);
6069 } else {
6070 CFX_WideString wsPropertyName =
tsepez4c3debb2016-04-08 12:20:38 -07006071 CFX_WideString::FromUTF8(szName.AsStringC());
Dan Sinclair1770c022016-03-14 14:14:16 -04006072 CFX_WideString wsSomExpression =
tsepez4c3debb2016-04-08 12:20:38 -07006073 CFX_WideString::FromUTF8(szSomExp.AsStringC());
dsinclair2235b7b2016-06-02 07:42:25 -07006074 pContext->ThrowException(XFA_IDS_ACCESS_PROPERTY_IN_NOT_OBJECT,
6075 wsPropertyName.c_str(),
6076 wsSomExpression.c_str());
Dan Sinclair1770c022016-03-14 14:14:16 -04006077 }
6078 }
Dan Sinclair1770c022016-03-14 14:14:16 -04006079 } else {
dsinclair2235b7b2016-06-02 07:42:25 -07006080 pContext->ThrowException(XFA_IDS_COMPILER_ERROR);
Dan Sinclair1770c022016-03-14 14:14:16 -04006081 }
6082}
dsinclair48d91dd2016-05-31 11:54:01 -07006083
6084// static
dsinclair12a6b0c2016-05-26 11:14:08 -07006085void CXFA_FM2JSContext::dotdot_accessor(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04006086 const CFX_ByteStringC& szFuncName,
6087 CFXJSE_Arguments& args) {
dsinclairdd6a46c2016-05-26 08:41:45 -07006088 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07006089 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclairec3da5b2016-05-25 16:42:05 -07006090 v8::Isolate* pIsolate = pContext->GetScriptRuntime();
Dan Sinclair1770c022016-03-14 14:14:16 -04006091 int32_t argc = args.GetLength();
6092 if ((argc == 4) || (argc == 5)) {
6093 FX_BOOL bIsStar = TRUE;
dsinclair86fad992016-05-31 11:34:04 -07006094 std::unique_ptr<CFXJSE_Value> argAccessor = args.GetValue(0);
Dan Sinclair1770c022016-03-14 14:14:16 -04006095 CFX_ByteString bsAccessorName = args.GetUTF8String(1);
6096 CFX_ByteString szName = args.GetUTF8String(2);
6097 int32_t iIndexFlags = args.GetInt32(3);
6098 int32_t iIndexValue = 0;
Dan Sinclair1770c022016-03-14 14:14:16 -04006099 if (argc == 5) {
6100 bIsStar = FALSE;
dsinclair86fad992016-05-31 11:34:04 -07006101 std::unique_ptr<CFXJSE_Value> argIndex = args.GetValue(4);
6102 iIndexValue = ValueToInteger(pThis, argIndex.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04006103 }
6104 CFX_ByteString szSomExp;
tsepez4c3debb2016-04-08 12:20:38 -07006105 GenerateSomExpression(szName.AsStringC(), iIndexFlags, iIndexValue, bIsStar,
6106 szSomExp);
dsinclair86fad992016-05-31 11:34:04 -07006107 if (FXJSE_Value_IsArray(argAccessor.get())) {
6108 std::unique_ptr<CFXJSE_Value> pLengthValue(new CFXJSE_Value(pIsolate));
6109 FXJSE_Value_GetObjectProp(argAccessor.get(), "length",
6110 pLengthValue.get());
6111 int32_t iLength = FXJSE_Value_ToInteger(pLengthValue.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04006112 int32_t iCounter = 0;
dsinclair12a6b0c2016-05-26 11:14:08 -07006113 CFXJSE_Value*** hResolveValues = FX_Alloc(CFXJSE_Value**, iLength - 2);
Dan Sinclair1770c022016-03-14 14:14:16 -04006114 int32_t* iSizes = FX_Alloc(int32_t, iLength - 2);
dsinclair86fad992016-05-31 11:34:04 -07006115 std::unique_ptr<CFXJSE_Value> hJSObjValue(new CFXJSE_Value(pIsolate));
Dan Sinclair1770c022016-03-14 14:14:16 -04006116 FX_BOOL bAttribute = FALSE;
6117 for (int32_t i = 2; i < iLength; i++) {
dsinclair86fad992016-05-31 11:34:04 -07006118 FXJSE_Value_GetObjectPropByIdx(argAccessor.get(), i, hJSObjValue.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04006119 XFA_RESOLVENODE_RS resoveNodeRS;
dsinclair86fad992016-05-31 11:34:04 -07006120 int32_t iRet =
6121 ResolveObjects(pThis, hJSObjValue.get(), szSomExp.AsStringC(),
6122 resoveNodeRS, FALSE);
Dan Sinclair1770c022016-03-14 14:14:16 -04006123 if (iRet > 0) {
dsinclair86fad992016-05-31 11:34:04 -07006124 ParseResolveResult(pThis, resoveNodeRS, hJSObjValue.get(),
Dan Sinclair1770c022016-03-14 14:14:16 -04006125 hResolveValues[i - 2], iSizes[i - 2], bAttribute);
6126 iCounter += iSizes[i - 2];
6127 }
6128 }
Dan Sinclair1770c022016-03-14 14:14:16 -04006129 if (iCounter > 0) {
dsinclair12a6b0c2016-05-26 11:14:08 -07006130 CFXJSE_Value** rgValues = FX_Alloc(CFXJSE_Value*, iCounter + 2);
dsinclair86fad992016-05-31 11:34:04 -07006131 for (int32_t i = 0; i < (iCounter + 2); i++)
6132 rgValues[i] = new CFXJSE_Value(pIsolate);
6133
Dan Sinclair1770c022016-03-14 14:14:16 -04006134 FXJSE_Value_SetInteger(rgValues[0], 1);
6135 if (bAttribute) {
tsepez4c3debb2016-04-08 12:20:38 -07006136 FXJSE_Value_SetUTF8String(rgValues[1], szName.AsStringC());
Dan Sinclair1770c022016-03-14 14:14:16 -04006137 } else {
6138 FXJSE_Value_SetNull(rgValues[1]);
6139 }
6140 int32_t iIndex = 2;
6141 for (int32_t i = 0; i < iLength - 2; i++) {
6142 for (int32_t j = 0; j < iSizes[i]; j++) {
6143 FXJSE_Value_Set(rgValues[iIndex], hResolveValues[i][j]);
6144 iIndex++;
6145 }
6146 }
6147 FXJSE_Value_SetArray(args.GetReturnValue(), (iCounter + 2), rgValues);
dsinclair86fad992016-05-31 11:34:04 -07006148 for (int32_t i = 0; i < (iCounter + 2); i++)
6149 delete rgValues[i];
6150
Dan Sinclair1770c022016-03-14 14:14:16 -04006151 FX_Free(rgValues);
6152 } else {
6153 CFX_WideString wsPropertyName =
tsepez4c3debb2016-04-08 12:20:38 -07006154 CFX_WideString::FromUTF8(szName.AsStringC());
Dan Sinclair1770c022016-03-14 14:14:16 -04006155 CFX_WideString wsSomExpression =
tsepez4c3debb2016-04-08 12:20:38 -07006156 CFX_WideString::FromUTF8(szSomExp.AsStringC());
dsinclair2235b7b2016-06-02 07:42:25 -07006157 pContext->ThrowException(XFA_IDS_ACCESS_PROPERTY_IN_NOT_OBJECT,
6158 wsPropertyName.c_str(),
6159 wsSomExpression.c_str());
Dan Sinclair1770c022016-03-14 14:14:16 -04006160 }
6161 for (int32_t i = 0; i < iLength - 2; i++) {
dsinclair86fad992016-05-31 11:34:04 -07006162 for (int32_t j = 0; j < iSizes[i]; j++)
6163 delete hResolveValues[i][j];
6164
Dan Sinclair1770c022016-03-14 14:14:16 -04006165 FX_Free(hResolveValues[i]);
6166 }
6167 FX_Free(hResolveValues);
6168 FX_Free(iSizes);
Dan Sinclair1770c022016-03-14 14:14:16 -04006169 } else {
6170 XFA_RESOLVENODE_RS resoveNodeRS;
6171 int32_t iRet = 0;
dsinclair86fad992016-05-31 11:34:04 -07006172 if (FXJSE_Value_IsObject(argAccessor.get()) ||
6173 (FXJSE_Value_IsNull(argAccessor.get()) && bsAccessorName.IsEmpty())) {
6174 iRet = ResolveObjects(pThis, argAccessor.get(), szSomExp.AsStringC(),
tsepez28f97ff2016-04-04 16:41:35 -07006175 resoveNodeRS, FALSE);
dsinclair86fad992016-05-31 11:34:04 -07006176 } else if (!FXJSE_Value_IsObject(argAccessor.get()) &&
Dan Sinclair1770c022016-03-14 14:14:16 -04006177 !bsAccessorName.IsEmpty()) {
dsinclair86fad992016-05-31 11:34:04 -07006178 FX_BOOL bGetObject = GetObjectByName(pThis, argAccessor.get(),
6179 bsAccessorName.AsStringC());
Dan Sinclair1770c022016-03-14 14:14:16 -04006180 if (bGetObject) {
dsinclair86fad992016-05-31 11:34:04 -07006181 iRet = ResolveObjects(pThis, argAccessor.get(), szSomExp.AsStringC(),
tsepez28f97ff2016-04-04 16:41:35 -07006182 resoveNodeRS, FALSE);
Dan Sinclair1770c022016-03-14 14:14:16 -04006183 }
6184 }
6185 if (iRet > 0) {
dsinclair12a6b0c2016-05-26 11:14:08 -07006186 CFXJSE_Value** hResolveValues;
Dan Sinclair1770c022016-03-14 14:14:16 -04006187 int32_t iSize = 0;
6188 FX_BOOL bAttribute = FALSE;
dsinclair86fad992016-05-31 11:34:04 -07006189 ParseResolveResult(pThis, resoveNodeRS, argAccessor.get(),
6190 hResolveValues, iSize, bAttribute);
dsinclair12a6b0c2016-05-26 11:14:08 -07006191 CFXJSE_Value** rgValues = FX_Alloc(CFXJSE_Value*, iSize + 2);
dsinclair86fad992016-05-31 11:34:04 -07006192 for (int32_t i = 0; i < (iSize + 2); i++)
6193 rgValues[i] = new CFXJSE_Value(pIsolate);
6194
Dan Sinclair1770c022016-03-14 14:14:16 -04006195 FXJSE_Value_SetInteger(rgValues[0], 1);
6196 if (bAttribute) {
tsepez4c3debb2016-04-08 12:20:38 -07006197 FXJSE_Value_SetUTF8String(rgValues[1], szName.AsStringC());
Dan Sinclair1770c022016-03-14 14:14:16 -04006198 } else {
6199 FXJSE_Value_SetNull(rgValues[1]);
6200 }
6201 for (int32_t i = 0; i < iSize; i++) {
6202 FXJSE_Value_Set(rgValues[i + 2], hResolveValues[i]);
6203 }
6204 FXJSE_Value_SetArray(args.GetReturnValue(), (iSize + 2), rgValues);
dsinclair86fad992016-05-31 11:34:04 -07006205 for (int32_t i = 0; i < (iSize + 2); i++)
6206 delete rgValues[i];
6207
Dan Sinclair1770c022016-03-14 14:14:16 -04006208 FX_Free(rgValues);
dsinclair86fad992016-05-31 11:34:04 -07006209 for (int32_t i = 0; i < iSize; i++)
6210 delete hResolveValues[i];
6211
Dan Sinclair1770c022016-03-14 14:14:16 -04006212 FX_Free(hResolveValues);
6213 } else {
6214 CFX_WideString wsPropertyName =
tsepez4c3debb2016-04-08 12:20:38 -07006215 CFX_WideString::FromUTF8(szName.AsStringC());
Dan Sinclair1770c022016-03-14 14:14:16 -04006216 CFX_WideString wsSomExpression =
tsepez4c3debb2016-04-08 12:20:38 -07006217 CFX_WideString::FromUTF8(szSomExp.AsStringC());
dsinclair2235b7b2016-06-02 07:42:25 -07006218 pContext->ThrowException(XFA_IDS_ACCESS_PROPERTY_IN_NOT_OBJECT,
6219 wsPropertyName.c_str(),
6220 wsSomExpression.c_str());
Dan Sinclair1770c022016-03-14 14:14:16 -04006221 }
6222 }
Dan Sinclair1770c022016-03-14 14:14:16 -04006223 } else {
dsinclair2235b7b2016-06-02 07:42:25 -07006224 pContext->ThrowException(XFA_IDS_COMPILER_ERROR);
Dan Sinclair1770c022016-03-14 14:14:16 -04006225 }
6226}
dsinclair48d91dd2016-05-31 11:54:01 -07006227
6228// static
dsinclair12a6b0c2016-05-26 11:14:08 -07006229void CXFA_FM2JSContext::eval_translation(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04006230 const CFX_ByteStringC& szFuncName,
6231 CFXJSE_Arguments& args) {
dsinclairdd6a46c2016-05-26 08:41:45 -07006232 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07006233 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair48d91dd2016-05-31 11:54:01 -07006234 if (args.GetLength() == 1) {
dsinclair86fad992016-05-31 11:34:04 -07006235 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
Dan Sinclair1770c022016-03-14 14:14:16 -04006236 CFX_ByteString argString;
dsinclair86fad992016-05-31 11:34:04 -07006237 ValueToUTF8String(argOne.get(), argString);
Dan Sinclair1770c022016-03-14 14:14:16 -04006238 if (argString.IsEmpty()) {
dsinclair2235b7b2016-06-02 07:42:25 -07006239 pContext->ThrowException(XFA_IDS_ARGUMENT_MISMATCH);
Dan Sinclair1770c022016-03-14 14:14:16 -04006240 } else {
6241 CFX_WideString scriptString =
tsepez4c3debb2016-04-08 12:20:38 -07006242 CFX_WideString::FromUTF8(argString.AsStringC());
Dan Sinclair1770c022016-03-14 14:14:16 -04006243 CFX_WideTextBuf wsJavaScriptBuf;
6244 CFX_WideString wsError;
dsinclaire80e9f82016-06-01 06:10:04 -07006245 CXFA_FM2JSContext::Translate(scriptString.AsStringC(), wsJavaScriptBuf,
6246 wsError);
Dan Sinclair1770c022016-03-14 14:14:16 -04006247 if (wsError.IsEmpty()) {
tsepezafe94302016-05-13 17:21:31 -07006248 CFX_WideString javaScript = wsJavaScriptBuf.MakeString();
Dan Sinclair1770c022016-03-14 14:14:16 -04006249 FXJSE_Value_SetUTF8String(
6250 args.GetReturnValue(),
tsepezbd9748d2016-04-13 21:40:19 -07006251 FX_UTF8Encode(javaScript.c_str(), javaScript.GetLength())
6252 .AsStringC());
Dan Sinclair1770c022016-03-14 14:14:16 -04006253 } else {
dsinclair2235b7b2016-06-02 07:42:25 -07006254 pContext->ThrowException(XFA_IDS_COMPILER_ERROR);
Dan Sinclair1770c022016-03-14 14:14:16 -04006255 }
6256 }
Dan Sinclair1770c022016-03-14 14:14:16 -04006257 } else {
dsinclair2235b7b2016-06-02 07:42:25 -07006258 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Eval");
Dan Sinclair1770c022016-03-14 14:14:16 -04006259 }
6260}
dsinclair48d91dd2016-05-31 11:54:01 -07006261
6262// static
dsinclair12a6b0c2016-05-26 11:14:08 -07006263void CXFA_FM2JSContext::is_fm_object(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04006264 const CFX_ByteStringC& szFuncName,
6265 CFXJSE_Arguments& args) {
dsinclair48d91dd2016-05-31 11:54:01 -07006266 if (args.GetLength() == 1) {
dsinclair86fad992016-05-31 11:34:04 -07006267 std::unique_ptr<CFXJSE_Value> argOne = args.GetValue(0);
6268 FXJSE_Value_SetBoolean(args.GetReturnValue(),
6269 FXJSE_Value_IsObject(argOne.get()));
Dan Sinclair1770c022016-03-14 14:14:16 -04006270 } else {
6271 FXJSE_Value_SetBoolean(args.GetReturnValue(), FALSE);
6272 }
6273}
dsinclair48d91dd2016-05-31 11:54:01 -07006274
6275// static
dsinclair12a6b0c2016-05-26 11:14:08 -07006276void CXFA_FM2JSContext::is_fm_array(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04006277 const CFX_ByteStringC& szFuncName,
6278 CFXJSE_Arguments& args) {
dsinclair48d91dd2016-05-31 11:54:01 -07006279 if (args.GetLength() == 1) {
dsinclair86fad992016-05-31 11:34:04 -07006280 std::unique_ptr<CFXJSE_Value> argOne = args.GetValue(0);
6281 FX_BOOL bIsArray = FXJSE_Value_IsArray(argOne.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04006282 FXJSE_Value_SetBoolean(args.GetReturnValue(), bIsArray);
Dan Sinclair1770c022016-03-14 14:14:16 -04006283 } else {
6284 FXJSE_Value_SetBoolean(args.GetReturnValue(), FALSE);
6285 }
6286}
dsinclair48d91dd2016-05-31 11:54:01 -07006287
6288// static
dsinclair12a6b0c2016-05-26 11:14:08 -07006289void CXFA_FM2JSContext::get_fm_value(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04006290 const CFX_ByteStringC& szFuncName,
6291 CFXJSE_Arguments& args) {
dsinclairdd6a46c2016-05-26 08:41:45 -07006292 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07006293 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclairec3da5b2016-05-25 16:42:05 -07006294 v8::Isolate* pIsolate = pContext->GetScriptRuntime();
dsinclair48d91dd2016-05-31 11:54:01 -07006295 if (args.GetLength() == 1) {
dsinclair86fad992016-05-31 11:34:04 -07006296 std::unique_ptr<CFXJSE_Value> argOne = args.GetValue(0);
6297 if (FXJSE_Value_IsArray(argOne.get())) {
6298 std::unique_ptr<CFXJSE_Value> propertyValue(new CFXJSE_Value(pIsolate));
6299 std::unique_ptr<CFXJSE_Value> jsObjectValue(new CFXJSE_Value(pIsolate));
6300 FXJSE_Value_GetObjectPropByIdx(argOne.get(), 1, propertyValue.get());
6301 FXJSE_Value_GetObjectPropByIdx(argOne.get(), 2, jsObjectValue.get());
6302 if (FXJSE_Value_IsNull(propertyValue.get())) {
6303 GetObjectDefaultValue(jsObjectValue.get(), args.GetReturnValue());
Dan Sinclair1770c022016-03-14 14:14:16 -04006304 } else {
6305 CFX_ByteString propertyStr;
dsinclair86fad992016-05-31 11:34:04 -07006306 FXJSE_Value_ToUTF8String(propertyValue.get(), propertyStr);
6307 FXJSE_Value_GetObjectProp(jsObjectValue.get(), propertyStr.AsStringC(),
Dan Sinclair1770c022016-03-14 14:14:16 -04006308 args.GetReturnValue());
6309 }
dsinclair86fad992016-05-31 11:34:04 -07006310 } else if (FXJSE_Value_IsObject(argOne.get())) {
6311 GetObjectDefaultValue(argOne.get(), args.GetReturnValue());
Dan Sinclair1770c022016-03-14 14:14:16 -04006312 } else {
dsinclair86fad992016-05-31 11:34:04 -07006313 FXJSE_Value_Set(args.GetReturnValue(), argOne.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04006314 }
Dan Sinclair1770c022016-03-14 14:14:16 -04006315 } else {
dsinclair2235b7b2016-06-02 07:42:25 -07006316 pContext->ThrowException(XFA_IDS_COMPILER_ERROR);
Dan Sinclair1770c022016-03-14 14:14:16 -04006317 }
6318}
dsinclair48d91dd2016-05-31 11:54:01 -07006319
6320// static
dsinclair12a6b0c2016-05-26 11:14:08 -07006321void CXFA_FM2JSContext::get_fm_jsobj(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04006322 const CFX_ByteStringC& szFuncName,
6323 CFXJSE_Arguments& args) {
dsinclair48d91dd2016-05-31 11:54:01 -07006324 if (args.GetLength() == 1) {
dsinclair86fad992016-05-31 11:34:04 -07006325 std::unique_ptr<CFXJSE_Value> argOne = args.GetValue(0);
6326 if (FXJSE_Value_IsArray(argOne.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04006327#ifndef NDEBUG
dsinclair48d91dd2016-05-31 11:54:01 -07006328 CXFA_FM2JSContext* pContext =
6329 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclairec3da5b2016-05-25 16:42:05 -07006330 v8::Isolate* pIsolate = pContext->GetScriptRuntime();
dsinclair86fad992016-05-31 11:34:04 -07006331 std::unique_ptr<CFXJSE_Value> lengthValue(new CFXJSE_Value(pIsolate));
6332 FXJSE_Value_GetObjectProp(argOne.get(), "length", lengthValue.get());
6333 ASSERT(FXJSE_Value_ToInteger(lengthValue.get()) >= 3);
Dan Sinclair1770c022016-03-14 14:14:16 -04006334#endif
dsinclair86fad992016-05-31 11:34:04 -07006335 FXJSE_Value_GetObjectPropByIdx(argOne.get(), 2, args.GetReturnValue());
Dan Sinclair1770c022016-03-14 14:14:16 -04006336 } else {
dsinclair86fad992016-05-31 11:34:04 -07006337 FXJSE_Value_Set(args.GetReturnValue(), argOne.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04006338 }
Dan Sinclair1770c022016-03-14 14:14:16 -04006339 } else {
dsinclair48d91dd2016-05-31 11:54:01 -07006340 CXFA_FM2JSContext* pContext =
6341 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclair2235b7b2016-06-02 07:42:25 -07006342 pContext->ThrowException(XFA_IDS_COMPILER_ERROR);
Dan Sinclair1770c022016-03-14 14:14:16 -04006343 }
6344}
dsinclair48d91dd2016-05-31 11:54:01 -07006345
6346// static
dsinclair12a6b0c2016-05-26 11:14:08 -07006347void CXFA_FM2JSContext::fm_var_filter(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04006348 const CFX_ByteStringC& szFuncName,
6349 CFXJSE_Arguments& args) {
dsinclairdd6a46c2016-05-26 08:41:45 -07006350 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07006351 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclairec3da5b2016-05-25 16:42:05 -07006352 v8::Isolate* pIsolate = pContext->GetScriptRuntime();
dsinclair48d91dd2016-05-31 11:54:01 -07006353 if (args.GetLength() == 1) {
dsinclair86fad992016-05-31 11:34:04 -07006354 std::unique_ptr<CFXJSE_Value> argOne = args.GetValue(0);
6355 if (FXJSE_Value_IsArray(argOne.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04006356#ifndef NDEBUG
dsinclair86fad992016-05-31 11:34:04 -07006357 std::unique_ptr<CFXJSE_Value> lengthValue(new CFXJSE_Value(pIsolate));
6358 FXJSE_Value_GetObjectProp(argOne.get(), "length", lengthValue.get());
6359 ASSERT(FXJSE_Value_ToInteger(lengthValue.get()) >= 3);
Dan Sinclair1770c022016-03-14 14:14:16 -04006360#endif
dsinclair86fad992016-05-31 11:34:04 -07006361 std::unique_ptr<CFXJSE_Value> flagsValue(new CFXJSE_Value(pIsolate));
6362 FXJSE_Value_GetObjectPropByIdx(argOne.get(), 0, flagsValue.get());
6363 int32_t iFlags = FXJSE_Value_ToInteger(flagsValue.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04006364 if (iFlags == 4) {
dsinclair12a6b0c2016-05-26 11:14:08 -07006365 CFXJSE_Value* rgValues[3];
dsinclair86fad992016-05-31 11:34:04 -07006366 for (int32_t i = 0; i < 3; i++)
6367 rgValues[i] = new CFXJSE_Value(pIsolate);
6368
Dan Sinclair1770c022016-03-14 14:14:16 -04006369 FXJSE_Value_SetInteger(rgValues[0], 3);
6370 FXJSE_Value_SetNull(rgValues[1]);
6371 FXJSE_Value_SetNull(rgValues[2]);
6372 FXJSE_Value_SetArray(args.GetReturnValue(), 3, rgValues);
dsinclair86fad992016-05-31 11:34:04 -07006373 for (int32_t i = 0; i < 3; i++)
6374 delete rgValues[i];
Dan Sinclair1770c022016-03-14 14:14:16 -04006375 } else if (iFlags == 3) {
dsinclair86fad992016-05-31 11:34:04 -07006376 std::unique_ptr<CFXJSE_Value> objectValue(new CFXJSE_Value(pIsolate));
6377 FXJSE_Value_GetObjectPropByIdx(argOne.get(), 2, objectValue.get());
6378 if (!FXJSE_Value_IsNull(objectValue.get())) {
6379 FXJSE_Value_Set(args.GetReturnValue(), argOne.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04006380 } else {
dsinclair2235b7b2016-06-02 07:42:25 -07006381 pContext->ThrowException(XFA_IDS_COMPILER_ERROR);
Dan Sinclair1770c022016-03-14 14:14:16 -04006382 }
Dan Sinclair1770c022016-03-14 14:14:16 -04006383 } else {
dsinclair86fad992016-05-31 11:34:04 -07006384 std::unique_ptr<CFXJSE_Value> simpleValue =
6385 GetSimpleValue(pThis, args, 0);
6386 FXJSE_Value_Set(args.GetReturnValue(), simpleValue.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04006387 }
6388 } else {
dsinclair86fad992016-05-31 11:34:04 -07006389 std::unique_ptr<CFXJSE_Value> simpleValue =
6390 GetSimpleValue(pThis, args, 0);
6391 FXJSE_Value_Set(args.GetReturnValue(), simpleValue.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04006392 }
Dan Sinclair1770c022016-03-14 14:14:16 -04006393 } else {
dsinclair2235b7b2016-06-02 07:42:25 -07006394 pContext->ThrowException(XFA_IDS_COMPILER_ERROR);
Dan Sinclair1770c022016-03-14 14:14:16 -04006395 }
6396}
dsinclair48d91dd2016-05-31 11:54:01 -07006397
6398// static
dsinclair12a6b0c2016-05-26 11:14:08 -07006399void CXFA_FM2JSContext::concat_fm_object(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04006400 const CFX_ByteStringC& szFuncName,
6401 CFXJSE_Arguments& args) {
dsinclairdd6a46c2016-05-26 08:41:45 -07006402 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07006403 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclairec3da5b2016-05-25 16:42:05 -07006404 v8::Isolate* pIsolate = pContext->GetScriptRuntime();
Dan Sinclair1770c022016-03-14 14:14:16 -04006405 uint32_t iLength = 0;
dsinclair48d91dd2016-05-31 11:54:01 -07006406 int32_t argc = args.GetLength();
dsinclair86fad992016-05-31 11:34:04 -07006407 std::vector<std::unique_ptr<CFXJSE_Value>> argValues;
dsinclair48d91dd2016-05-31 11:54:01 -07006408 for (int32_t i = 0; i < argc; i++) {
dsinclair86fad992016-05-31 11:34:04 -07006409 argValues.push_back(args.GetValue(i));
6410 if (FXJSE_Value_IsArray(argValues[i].get())) {
6411 std::unique_ptr<CFXJSE_Value> lengthValue(new CFXJSE_Value(pIsolate));
6412 FXJSE_Value_GetObjectProp(argValues[i].get(), "length",
6413 lengthValue.get());
6414 int32_t length = FXJSE_Value_ToInteger(lengthValue.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04006415 iLength = iLength + ((length > 2) ? (length - 2) : 0);
Dan Sinclair1770c022016-03-14 14:14:16 -04006416 }
6417 iLength += 1;
6418 }
dsinclair12a6b0c2016-05-26 11:14:08 -07006419 CFXJSE_Value** returnValues = FX_Alloc(CFXJSE_Value*, iLength);
dsinclair86fad992016-05-31 11:34:04 -07006420 for (int32_t i = 0; i < (int32_t)iLength; i++)
6421 returnValues[i] = new CFXJSE_Value(pIsolate);
6422
Dan Sinclair1770c022016-03-14 14:14:16 -04006423 int32_t index = 0;
dsinclair48d91dd2016-05-31 11:54:01 -07006424 for (int32_t i = 0; i < argc; i++) {
dsinclair86fad992016-05-31 11:34:04 -07006425 if (FXJSE_Value_IsArray(argValues[i].get())) {
6426 std::unique_ptr<CFXJSE_Value> lengthValue(new CFXJSE_Value(pIsolate));
6427 FXJSE_Value_GetObjectProp(argValues[i].get(), "length",
6428 lengthValue.get());
6429 int32_t length = FXJSE_Value_ToInteger(lengthValue.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04006430 for (int32_t j = 2; j < length; j++) {
dsinclair86fad992016-05-31 11:34:04 -07006431 FXJSE_Value_GetObjectPropByIdx(argValues[i].get(), j,
6432 returnValues[index]);
Dan Sinclair1770c022016-03-14 14:14:16 -04006433 index++;
6434 }
Dan Sinclair1770c022016-03-14 14:14:16 -04006435 }
dsinclair86fad992016-05-31 11:34:04 -07006436 FXJSE_Value_Set(returnValues[index], argValues[i].get());
Dan Sinclair1770c022016-03-14 14:14:16 -04006437 index++;
6438 }
6439 FXJSE_Value_SetArray(args.GetReturnValue(), iLength, returnValues);
dsinclair86fad992016-05-31 11:34:04 -07006440 for (int32_t i = 0; i < (int32_t)iLength; i++)
6441 delete returnValues[i];
6442
Dan Sinclair1770c022016-03-14 14:14:16 -04006443 FX_Free(returnValues);
6444}
dsinclair48d91dd2016-05-31 11:54:01 -07006445
6446// static
dsinclair86fad992016-05-31 11:34:04 -07006447std::unique_ptr<CFXJSE_Value> CXFA_FM2JSContext::GetSimpleValue(
6448 CFXJSE_Value* pThis,
6449 CFXJSE_Arguments& args,
6450 uint32_t index) {
dsinclairdd6a46c2016-05-26 08:41:45 -07006451 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07006452 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclairec3da5b2016-05-25 16:42:05 -07006453 v8::Isolate* pIsolate = pContext->GetScriptRuntime();
dsinclair43854a52016-04-27 12:26:00 -07006454 ASSERT(index < (uint32_t)args.GetLength());
dsinclair86fad992016-05-31 11:34:04 -07006455 std::unique_ptr<CFXJSE_Value> argIndex = args.GetValue(index);
6456 if (FXJSE_Value_IsArray(argIndex.get())) {
6457 std::unique_ptr<CFXJSE_Value> lengthValue(new CFXJSE_Value(pIsolate));
6458 FXJSE_Value_GetObjectProp(argIndex.get(), "length", lengthValue.get());
6459 int32_t iLength = FXJSE_Value_ToInteger(lengthValue.get());
6460 std::unique_ptr<CFXJSE_Value> simpleValue(new CFXJSE_Value(pIsolate));
Dan Sinclair1770c022016-03-14 14:14:16 -04006461 if (iLength > 2) {
dsinclair86fad992016-05-31 11:34:04 -07006462 std::unique_ptr<CFXJSE_Value> propertyValue(new CFXJSE_Value(pIsolate));
6463 std::unique_ptr<CFXJSE_Value> jsObjectValue(new CFXJSE_Value(pIsolate));
6464 FXJSE_Value_GetObjectPropByIdx(argIndex.get(), 1, propertyValue.get());
6465 FXJSE_Value_GetObjectPropByIdx(argIndex.get(), 2, jsObjectValue.get());
6466 if (FXJSE_Value_IsNull(propertyValue.get())) {
6467 GetObjectDefaultValue(jsObjectValue.get(), simpleValue.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04006468 } else {
6469 CFX_ByteString propertyStr;
dsinclair86fad992016-05-31 11:34:04 -07006470 FXJSE_Value_ToUTF8String(propertyValue.get(), propertyStr);
6471 FXJSE_Value_GetObjectProp(jsObjectValue.get(), propertyStr.AsStringC(),
6472 simpleValue.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04006473 }
Dan Sinclair1770c022016-03-14 14:14:16 -04006474 } else {
dsinclair86fad992016-05-31 11:34:04 -07006475 FXJSE_Value_SetUndefined(simpleValue.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04006476 }
Dan Sinclair1770c022016-03-14 14:14:16 -04006477 return simpleValue;
dsinclair86fad992016-05-31 11:34:04 -07006478 } else if (FXJSE_Value_IsObject(argIndex.get())) {
6479 std::unique_ptr<CFXJSE_Value> defaultValue(new CFXJSE_Value(pIsolate));
6480 GetObjectDefaultValue(argIndex.get(), defaultValue.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04006481 return defaultValue;
6482 } else {
6483 return argIndex;
6484 }
6485}
dsinclair12a6b0c2016-05-26 11:14:08 -07006486
dsinclair48d91dd2016-05-31 11:54:01 -07006487// static
dsinclair12a6b0c2016-05-26 11:14:08 -07006488FX_BOOL CXFA_FM2JSContext::ValueIsNull(CFXJSE_Value* pThis, CFXJSE_Value* arg) {
dsinclairdd6a46c2016-05-26 08:41:45 -07006489 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07006490 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclairec3da5b2016-05-25 16:42:05 -07006491 v8::Isolate* pIsolate = pContext->GetScriptRuntime();
Dan Sinclair1770c022016-03-14 14:14:16 -04006492 FX_BOOL isNull = FALSE;
6493 if (FXJSE_Value_IsNull(arg)) {
6494 isNull = TRUE;
6495 } else if (FXJSE_Value_IsArray(arg)) {
dsinclair12a6b0c2016-05-26 11:14:08 -07006496 int32_t iLength = hvalue_get_array_length(pThis, arg);
Dan Sinclair1770c022016-03-14 14:14:16 -04006497 if (iLength > 2) {
dsinclair86fad992016-05-31 11:34:04 -07006498 std::unique_ptr<CFXJSE_Value> propertyValue(new CFXJSE_Value(pIsolate));
6499 std::unique_ptr<CFXJSE_Value> jsObjectValue(new CFXJSE_Value(pIsolate));
6500 FXJSE_Value_GetObjectPropByIdx(arg, 1, propertyValue.get());
6501 FXJSE_Value_GetObjectPropByIdx(arg, 2, jsObjectValue.get());
6502 if (FXJSE_Value_IsNull(propertyValue.get())) {
6503 std::unique_ptr<CFXJSE_Value> defaultValue(new CFXJSE_Value(pIsolate));
6504 GetObjectDefaultValue(jsObjectValue.get(), defaultValue.get());
6505 if (FXJSE_Value_IsNull(defaultValue.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04006506 isNull = TRUE;
6507 }
Dan Sinclair1770c022016-03-14 14:14:16 -04006508 } else {
6509 CFX_ByteString propertyStr;
dsinclair86fad992016-05-31 11:34:04 -07006510 FXJSE_Value_ToUTF8String(propertyValue.get(), propertyStr);
6511 std::unique_ptr<CFXJSE_Value> newPropertyValue(
6512 new CFXJSE_Value(pIsolate));
6513 FXJSE_Value_GetObjectProp(jsObjectValue.get(), propertyStr.AsStringC(),
6514 newPropertyValue.get());
6515 if (FXJSE_Value_IsNull(newPropertyValue.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04006516 isNull = TRUE;
6517 }
Dan Sinclair1770c022016-03-14 14:14:16 -04006518 }
Dan Sinclair1770c022016-03-14 14:14:16 -04006519 } else {
6520 isNull = TRUE;
6521 }
6522 } else if (FXJSE_Value_IsObject(arg)) {
dsinclair86fad992016-05-31 11:34:04 -07006523 std::unique_ptr<CFXJSE_Value> defaultValue(new CFXJSE_Value(pIsolate));
6524 GetObjectDefaultValue(arg, defaultValue.get());
6525 if (FXJSE_Value_IsNull(defaultValue.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04006526 isNull = TRUE;
6527 }
Dan Sinclair1770c022016-03-14 14:14:16 -04006528 }
6529 return isNull;
6530}
dsinclair12a6b0c2016-05-26 11:14:08 -07006531
dsinclair48d91dd2016-05-31 11:54:01 -07006532// static
dsinclair12a6b0c2016-05-26 11:14:08 -07006533int32_t CXFA_FM2JSContext::hvalue_get_array_length(CFXJSE_Value* pThis,
6534 CFXJSE_Value* arg) {
dsinclairdd6a46c2016-05-26 08:41:45 -07006535 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07006536 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclairec3da5b2016-05-25 16:42:05 -07006537 v8::Isolate* pIsolate = pContext->GetScriptRuntime();
Dan Sinclair1770c022016-03-14 14:14:16 -04006538 int32_t iLength = 0;
6539 if (FXJSE_Value_IsArray(arg)) {
dsinclair86fad992016-05-31 11:34:04 -07006540 std::unique_ptr<CFXJSE_Value> lengthValue(new CFXJSE_Value(pIsolate));
6541 FXJSE_Value_GetObjectProp(arg, "length", lengthValue.get());
6542 iLength = FXJSE_Value_ToInteger(lengthValue.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04006543 }
6544 return iLength;
6545}
dsinclair48d91dd2016-05-31 11:54:01 -07006546
6547// static
dsinclair12a6b0c2016-05-26 11:14:08 -07006548FX_BOOL CXFA_FM2JSContext::simpleValueCompare(CFXJSE_Value* pThis,
6549 CFXJSE_Value* firstValue,
6550 CFXJSE_Value* secondValue) {
Dan Sinclair1770c022016-03-14 14:14:16 -04006551 FX_BOOL bReturn = FALSE;
6552 if (FXJSE_Value_IsUTF8String(firstValue)) {
6553 CFX_ByteString firstString, secondString;
dsinclair12a6b0c2016-05-26 11:14:08 -07006554 ValueToUTF8String(firstValue, firstString);
6555 ValueToUTF8String(secondValue, secondString);
tsepez9f2970c2016-04-01 10:23:04 -07006556 bReturn = firstString == secondString;
Dan Sinclair1770c022016-03-14 14:14:16 -04006557 } else if (FXJSE_Value_IsNumber(firstValue)) {
dsinclair12a6b0c2016-05-26 11:14:08 -07006558 FX_FLOAT first = ValueToFloat(pThis, firstValue);
6559 FX_FLOAT second = ValueToFloat(pThis, secondValue);
Dan Sinclair1770c022016-03-14 14:14:16 -04006560 bReturn = (first == second);
6561 } else if (FXJSE_Value_IsBoolean(firstValue)) {
6562 bReturn = (FXJSE_Value_ToBoolean(firstValue) ==
6563 FXJSE_Value_ToBoolean(secondValue));
6564 } else if (FXJSE_Value_IsNull(firstValue) &&
6565 FXJSE_Value_IsNull(secondValue)) {
6566 bReturn = TRUE;
6567 }
6568 return bReturn;
6569}
dsinclair48d91dd2016-05-31 11:54:01 -07006570
6571// static
dsinclair12a6b0c2016-05-26 11:14:08 -07006572void CXFA_FM2JSContext::unfoldArgs(CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04006573 CFXJSE_Arguments& args,
dsinclair12a6b0c2016-05-26 11:14:08 -07006574 CFXJSE_Value**& resultValues,
Dan Sinclair1770c022016-03-14 14:14:16 -04006575 int32_t& iCount,
6576 int32_t iStart) {
dsinclairdd6a46c2016-05-26 08:41:45 -07006577 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07006578 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclairec3da5b2016-05-25 16:42:05 -07006579 v8::Isolate* pIsolate = pContext->GetScriptRuntime();
Dan Sinclair1770c022016-03-14 14:14:16 -04006580 iCount = 0;
6581 int32_t argc = args.GetLength();
dsinclair86fad992016-05-31 11:34:04 -07006582 std::vector<std::unique_ptr<CFXJSE_Value>> argsValue;
6583 for (int32_t i = 0; i < argc - iStart; i++) {
6584 argsValue.push_back(args.GetValue(i + iStart));
6585 if (FXJSE_Value_IsArray(argsValue[i].get())) {
6586 std::unique_ptr<CFXJSE_Value> lengthValue(new CFXJSE_Value(pIsolate));
6587 FXJSE_Value_GetObjectProp(argsValue[i].get(), "length",
6588 lengthValue.get());
6589 int32_t iLength = FXJSE_Value_ToInteger(lengthValue.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04006590 iCount += ((iLength > 2) ? (iLength - 2) : 0);
6591 } else {
6592 iCount += 1;
6593 }
6594 }
dsinclair12a6b0c2016-05-26 11:14:08 -07006595 resultValues = FX_Alloc(CFXJSE_Value*, iCount);
dsinclair86fad992016-05-31 11:34:04 -07006596 for (int32_t i = 0; i < iCount; i++)
6597 resultValues[i] = new CFXJSE_Value(pIsolate);
6598
Dan Sinclair1770c022016-03-14 14:14:16 -04006599 int32_t index = 0;
dsinclair86fad992016-05-31 11:34:04 -07006600 for (int32_t i = 0; i < argc - iStart; i++) {
6601 if (FXJSE_Value_IsArray(argsValue[i].get())) {
6602 std::unique_ptr<CFXJSE_Value> lengthValue(new CFXJSE_Value(pIsolate));
6603 FXJSE_Value_GetObjectProp(argsValue[i].get(), "length",
6604 lengthValue.get());
6605 int32_t iLength = FXJSE_Value_ToInteger(lengthValue.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04006606 if (iLength > 2) {
dsinclair86fad992016-05-31 11:34:04 -07006607 std::unique_ptr<CFXJSE_Value> propertyValue(new CFXJSE_Value(pIsolate));
6608 std::unique_ptr<CFXJSE_Value> jsObjectValue(new CFXJSE_Value(pIsolate));
6609 FXJSE_Value_GetObjectPropByIdx(argsValue[i].get(), 1,
6610 propertyValue.get());
6611 if (FXJSE_Value_IsNull(propertyValue.get())) {
Dan Sinclair1770c022016-03-14 14:14:16 -04006612 for (int32_t j = 2; j < iLength; j++) {
dsinclair86fad992016-05-31 11:34:04 -07006613 FXJSE_Value_GetObjectPropByIdx(argsValue[i].get(), j,
6614 jsObjectValue.get());
6615 GetObjectDefaultValue(jsObjectValue.get(), resultValues[index]);
Dan Sinclair1770c022016-03-14 14:14:16 -04006616 index++;
6617 }
6618 } else {
6619 CFX_ByteString propertyString;
dsinclair86fad992016-05-31 11:34:04 -07006620 FXJSE_Value_ToUTF8String(propertyValue.get(), propertyString);
Dan Sinclair1770c022016-03-14 14:14:16 -04006621 for (int32_t j = 2; j < iLength; j++) {
dsinclair86fad992016-05-31 11:34:04 -07006622 FXJSE_Value_GetObjectPropByIdx(argsValue[i].get(), j,
6623 jsObjectValue.get());
6624 FXJSE_Value_GetObjectProp(jsObjectValue.get(),
6625 propertyString.AsStringC(),
Dan Sinclair1770c022016-03-14 14:14:16 -04006626 resultValues[index]);
6627 index++;
6628 }
6629 }
Dan Sinclair1770c022016-03-14 14:14:16 -04006630 }
dsinclair86fad992016-05-31 11:34:04 -07006631 } else if (FXJSE_Value_IsObject(argsValue[i].get())) {
6632 GetObjectDefaultValue(argsValue[i].get(), resultValues[index]);
Dan Sinclair1770c022016-03-14 14:14:16 -04006633 index++;
6634 } else {
dsinclair86fad992016-05-31 11:34:04 -07006635 FXJSE_Value_Set(resultValues[index], argsValue[i].get());
Dan Sinclair1770c022016-03-14 14:14:16 -04006636 index++;
6637 }
6638 }
Dan Sinclair1770c022016-03-14 14:14:16 -04006639}
dsinclair86fad992016-05-31 11:34:04 -07006640
dsinclair48d91dd2016-05-31 11:54:01 -07006641// static
dsinclair12a6b0c2016-05-26 11:14:08 -07006642void CXFA_FM2JSContext::GetObjectDefaultValue(CFXJSE_Value* pObjectValue,
6643 CFXJSE_Value* pDefaultValue) {
dsinclairdd6a46c2016-05-26 08:41:45 -07006644 CXFA_Node* pNode =
dsinclair12a6b0c2016-05-26 11:14:08 -07006645 ToNode((CXFA_Object*)FXJSE_Value_ToObject(pObjectValue, nullptr));
Dan Sinclair1770c022016-03-14 14:14:16 -04006646 if (pNode) {
dsinclair12a6b0c2016-05-26 11:14:08 -07006647 pNode->Script_Som_DefaultValue(pDefaultValue, FALSE, (XFA_ATTRIBUTE)-1);
Dan Sinclair1770c022016-03-14 14:14:16 -04006648 } else {
dsinclair12a6b0c2016-05-26 11:14:08 -07006649 FXJSE_Value_SetNull(pDefaultValue);
Dan Sinclair1770c022016-03-14 14:14:16 -04006650 }
6651}
dsinclair48d91dd2016-05-31 11:54:01 -07006652
6653// static
dsinclair12a6b0c2016-05-26 11:14:08 -07006654FX_BOOL CXFA_FM2JSContext::SetObjectDefaultValue(CFXJSE_Value* pObjectValue,
6655 CFXJSE_Value* hNewValue) {
dsinclairdd6a46c2016-05-26 08:41:45 -07006656 CXFA_Node* pNode =
dsinclair12a6b0c2016-05-26 11:14:08 -07006657 ToNode((CXFA_Object*)FXJSE_Value_ToObject(pObjectValue, nullptr));
Dan Sinclair1770c022016-03-14 14:14:16 -04006658 if (pNode) {
6659 pNode->Script_Som_DefaultValue(hNewValue, TRUE, (XFA_ATTRIBUTE)-1);
6660 return TRUE;
6661 }
6662 return FALSE;
6663}
dsinclair48d91dd2016-05-31 11:54:01 -07006664
6665// static
Dan Sinclair1770c022016-03-14 14:14:16 -04006666void CXFA_FM2JSContext::GenerateSomExpression(const CFX_ByteStringC& szName,
6667 int32_t iIndexFlags,
6668 int32_t iIndexValue,
6669 FX_BOOL bIsStar,
6670 CFX_ByteString& szSomExp) {
6671 if (bIsStar) {
6672 szSomExp = szName + "[*]";
6673 return;
6674 }
6675 if (iIndexFlags == 0) {
6676 szSomExp = szName;
6677 return;
6678 }
6679 if (iIndexFlags == 1 || iIndexValue == 0) {
6680 szSomExp = szName + "[" +
6681 CFX_ByteString::FormatInteger(iIndexValue, FXFORMAT_SIGNED) +
6682 "]";
6683 } else if (iIndexFlags == 2) {
6684 szSomExp = (iIndexValue < 0) ? (szName + "[-") : (szName + "[+");
6685 iIndexValue = (iIndexValue < 0) ? (0 - iIndexValue) : iIndexValue;
6686 szSomExp += CFX_ByteString::FormatInteger(iIndexValue);
6687 szSomExp += "]";
6688 } else {
6689 szSomExp = (iIndexValue < 0) ? (szName + "[") : (szName + "[-");
6690 iIndexValue = (iIndexValue < 0) ? (0 - iIndexValue) : iIndexValue;
6691 szSomExp += CFX_ByteString::FormatInteger(iIndexValue);
6692 szSomExp += "]";
6693 }
6694}
dsinclair48d91dd2016-05-31 11:54:01 -07006695
6696// static
Dan Sinclair1770c022016-03-14 14:14:16 -04006697FX_BOOL CXFA_FM2JSContext::GetObjectByName(
dsinclair12a6b0c2016-05-26 11:14:08 -07006698 CFXJSE_Value* pThis,
6699 CFXJSE_Value* accessorValue,
Dan Sinclair1770c022016-03-14 14:14:16 -04006700 const CFX_ByteStringC& szAccessorName) {
6701 FX_BOOL bFlags = FALSE;
dsinclairdd6a46c2016-05-26 08:41:45 -07006702 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07006703 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
Dan Sinclair1770c022016-03-14 14:14:16 -04006704 CXFA_Document* pDoc = pContext->GetDocument();
6705 if (!pDoc) {
6706 return bFlags;
6707 }
dsinclairdf4bc592016-03-31 20:34:43 -07006708 CXFA_ScriptContext* pScriptContext = pDoc->GetScriptContext();
Dan Sinclair1770c022016-03-14 14:14:16 -04006709 XFA_RESOLVENODE_RS resoveNodeRS;
tsepez736f28a2016-03-25 14:19:51 -07006710 uint32_t dwFlags = XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Properties |
Dan Sinclair1770c022016-03-14 14:14:16 -04006711 XFA_RESOLVENODE_Siblings | XFA_RESOLVENODE_Parent;
6712 int32_t iRet = pScriptContext->ResolveObjects(
6713 pScriptContext->GetThisObject(),
tsepez4c3debb2016-04-08 12:20:38 -07006714 CFX_WideString::FromUTF8(szAccessorName).AsStringC(), resoveNodeRS,
tsepez6fe7d212016-04-06 10:51:14 -07006715 dwFlags);
Dan Sinclair1770c022016-03-14 14:14:16 -04006716 if (iRet >= 1 && resoveNodeRS.dwFlags == XFA_RESOVENODE_RSTYPE_Nodes) {
6717 FXJSE_Value_Set(accessorValue, pScriptContext->GetJSValueFromMap(
6718 resoveNodeRS.nodes.GetAt(0)));
6719 bFlags = TRUE;
6720 }
6721 return bFlags;
6722}
dsinclair48d91dd2016-05-31 11:54:01 -07006723
6724// static
dsinclair12a6b0c2016-05-26 11:14:08 -07006725int32_t CXFA_FM2JSContext::ResolveObjects(CFXJSE_Value* pThis,
6726 CFXJSE_Value* pRefValue,
Dan Sinclair1770c022016-03-14 14:14:16 -04006727 const CFX_ByteStringC& bsSomExp,
6728 XFA_RESOLVENODE_RS& resoveNodeRS,
6729 FX_BOOL bdotAccessor,
6730 FX_BOOL bHasNoResolveName) {
tsepez6fe7d212016-04-06 10:51:14 -07006731 CFX_WideString wsSomExpression = CFX_WideString::FromUTF8(bsSomExp);
Dan Sinclair1770c022016-03-14 14:14:16 -04006732 int32_t iRet = -1;
dsinclairdd6a46c2016-05-26 08:41:45 -07006733 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07006734 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
Dan Sinclair1770c022016-03-14 14:14:16 -04006735 CXFA_Document* pDoc = pContext->GetDocument();
6736 if (!pDoc) {
6737 return iRet;
6738 }
dsinclairdf4bc592016-03-31 20:34:43 -07006739 CXFA_ScriptContext* pScriptContext = pDoc->GetScriptContext();
dsinclair48d91dd2016-05-31 11:54:01 -07006740 CXFA_Object* pNode = nullptr;
tsepez736f28a2016-03-25 14:19:51 -07006741 uint32_t dFlags = 0UL;
Dan Sinclair1770c022016-03-14 14:14:16 -04006742 if (bdotAccessor) {
dsinclair12a6b0c2016-05-26 11:14:08 -07006743 if (FXJSE_Value_IsNull(pRefValue)) {
Dan Sinclair1770c022016-03-14 14:14:16 -04006744 pNode = pScriptContext->GetThisObject();
6745 dFlags = XFA_RESOLVENODE_Siblings | XFA_RESOLVENODE_Parent;
6746 } else {
dsinclair12a6b0c2016-05-26 11:14:08 -07006747 pNode = (CXFA_Object*)FXJSE_Value_ToObject(pRefValue, nullptr);
dsinclair43854a52016-04-27 12:26:00 -07006748 ASSERT(pNode);
Dan Sinclair1770c022016-03-14 14:14:16 -04006749 if (bHasNoResolveName) {
6750 CFX_WideString wsName;
6751 if (CXFA_Node* pXFANode = pNode->AsNode()) {
6752 pXFANode->GetAttribute(XFA_ATTRIBUTE_Name, wsName, FALSE);
6753 }
6754 if (wsName.IsEmpty()) {
6755 CFX_WideStringC className;
6756 pNode->GetClassName(className);
6757 wsName = FX_WSTRC(L"#") + className;
6758 }
6759 wsSomExpression = wsName + wsSomExpression;
6760 dFlags = XFA_RESOLVENODE_Siblings;
6761 } else {
6762 dFlags = (bsSomExp == "*")
6763 ? (XFA_RESOLVENODE_Children)
6764 : (XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Attributes |
6765 XFA_RESOLVENODE_Properties);
6766 }
6767 }
6768 } else {
dsinclair12a6b0c2016-05-26 11:14:08 -07006769 pNode = (CXFA_Object*)FXJSE_Value_ToObject(pRefValue, nullptr);
Dan Sinclair1770c022016-03-14 14:14:16 -04006770 dFlags = XFA_RESOLVENODE_AnyChild;
6771 }
tsepez4c3debb2016-04-08 12:20:38 -07006772 iRet = pScriptContext->ResolveObjects(pNode, wsSomExpression.AsStringC(),
tsepezfc58ad12016-04-05 12:22:15 -07006773 resoveNodeRS, dFlags);
Dan Sinclair1770c022016-03-14 14:14:16 -04006774 return iRet;
6775}
dsinclair48d91dd2016-05-31 11:54:01 -07006776
6777// static
Dan Sinclair1770c022016-03-14 14:14:16 -04006778void CXFA_FM2JSContext::ParseResolveResult(
dsinclair12a6b0c2016-05-26 11:14:08 -07006779 CFXJSE_Value* pThis,
Dan Sinclair1770c022016-03-14 14:14:16 -04006780 const XFA_RESOLVENODE_RS& resoveNodeRS,
dsinclair12a6b0c2016-05-26 11:14:08 -07006781 CFXJSE_Value* pParentValue,
6782 CFXJSE_Value**& resultValues,
Dan Sinclair1770c022016-03-14 14:14:16 -04006783 int32_t& iSize,
6784 FX_BOOL& bAttribute) {
dsinclairdd6a46c2016-05-26 08:41:45 -07006785 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07006786 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclairec3da5b2016-05-25 16:42:05 -07006787 v8::Isolate* pIsolate = pContext->GetScriptRuntime();
Dan Sinclair1770c022016-03-14 14:14:16 -04006788 iSize = 0;
dsinclair48d91dd2016-05-31 11:54:01 -07006789 resultValues = nullptr;
Dan Sinclair1770c022016-03-14 14:14:16 -04006790 if (resoveNodeRS.dwFlags == XFA_RESOVENODE_RSTYPE_Nodes) {
6791 bAttribute = FALSE;
6792 iSize = resoveNodeRS.nodes.GetSize();
dsinclair12a6b0c2016-05-26 11:14:08 -07006793 resultValues = FX_Alloc(CFXJSE_Value*, iSize);
Dan Sinclair1770c022016-03-14 14:14:16 -04006794 for (int32_t i = 0; i < iSize; i++) {
dsinclair86fad992016-05-31 11:34:04 -07006795 resultValues[i] = new CFXJSE_Value(pIsolate);
Dan Sinclair1770c022016-03-14 14:14:16 -04006796 FXJSE_Value_Set(
6797 resultValues[i],
6798 pContext->GetDocument()->GetScriptContext()->GetJSValueFromMap(
6799 resoveNodeRS.nodes.GetAt(i)));
6800 }
6801 } else {
dsinclair12a6b0c2016-05-26 11:14:08 -07006802 CXFA_ValueArray objectProperties(pIsolate);
Dan Sinclair1770c022016-03-14 14:14:16 -04006803 int32_t iRet = resoveNodeRS.GetAttributeResult(objectProperties);
6804 bAttribute = (iRet == 0);
6805 if (bAttribute) {
dsinclair12a6b0c2016-05-26 11:14:08 -07006806 if (FXJSE_Value_IsObject(pParentValue)) {
Dan Sinclair1770c022016-03-14 14:14:16 -04006807 iSize = 1;
dsinclair12a6b0c2016-05-26 11:14:08 -07006808 resultValues = FX_Alloc(CFXJSE_Value*, 1);
dsinclair86fad992016-05-31 11:34:04 -07006809 resultValues[0] = new CFXJSE_Value(pIsolate);
dsinclair12a6b0c2016-05-26 11:14:08 -07006810 FXJSE_Value_Set(resultValues[0], pParentValue);
Dan Sinclair1770c022016-03-14 14:14:16 -04006811 }
6812 } else {
6813 iSize = iRet;
dsinclair12a6b0c2016-05-26 11:14:08 -07006814 resultValues = FX_Alloc(CFXJSE_Value*, iSize);
Dan Sinclair1770c022016-03-14 14:14:16 -04006815 for (int32_t i = 0; i < iSize; i++) {
dsinclair86fad992016-05-31 11:34:04 -07006816 resultValues[i] = new CFXJSE_Value(pIsolate);
Dan Sinclair1770c022016-03-14 14:14:16 -04006817 FXJSE_Value_Set(resultValues[i], objectProperties[i]);
6818 }
6819 }
6820 }
6821}
dsinclair48d91dd2016-05-31 11:54:01 -07006822
6823// static
dsinclair12a6b0c2016-05-26 11:14:08 -07006824int32_t CXFA_FM2JSContext::ValueToInteger(CFXJSE_Value* pThis,
6825 CFXJSE_Value* pValue) {
dsinclairdd6a46c2016-05-26 08:41:45 -07006826 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07006827 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclairec3da5b2016-05-25 16:42:05 -07006828 v8::Isolate* pIsolate = pContext->GetScriptRuntime();
Dan Sinclair1770c022016-03-14 14:14:16 -04006829 int32_t iValue = 0;
dsinclair12a6b0c2016-05-26 11:14:08 -07006830 if (FXJSE_Value_IsArray(pValue)) {
dsinclair86fad992016-05-31 11:34:04 -07006831 std::unique_ptr<CFXJSE_Value> propertyValue(new CFXJSE_Value(pIsolate));
6832 std::unique_ptr<CFXJSE_Value> jsObjectValue(new CFXJSE_Value(pIsolate));
6833 std::unique_ptr<CFXJSE_Value> newPropertyValue(new CFXJSE_Value(pIsolate));
6834 FXJSE_Value_GetObjectPropByIdx(pValue, 1, propertyValue.get());
6835 FXJSE_Value_GetObjectPropByIdx(pValue, 2, jsObjectValue.get());
6836 if (FXJSE_Value_IsNull(propertyValue.get())) {
6837 GetObjectDefaultValue(jsObjectValue.get(), newPropertyValue.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04006838 } else {
6839 CFX_ByteString propertyStr;
dsinclair86fad992016-05-31 11:34:04 -07006840 FXJSE_Value_ToUTF8String(propertyValue.get(), propertyStr);
6841 FXJSE_Value_GetObjectProp(jsObjectValue.get(), propertyStr.AsStringC(),
6842 newPropertyValue.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04006843 }
dsinclair86fad992016-05-31 11:34:04 -07006844 iValue = ValueToInteger(pThis, newPropertyValue.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04006845 return iValue;
dsinclair12a6b0c2016-05-26 11:14:08 -07006846 } else if (FXJSE_Value_IsObject(pValue)) {
dsinclair86fad992016-05-31 11:34:04 -07006847 std::unique_ptr<CFXJSE_Value> newPropertyValue(new CFXJSE_Value(pIsolate));
6848 GetObjectDefaultValue(pValue, newPropertyValue.get());
6849 iValue = ValueToInteger(pThis, newPropertyValue.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04006850 return iValue;
dsinclair12a6b0c2016-05-26 11:14:08 -07006851 } else if (FXJSE_Value_IsUTF8String(pValue)) {
Dan Sinclair1770c022016-03-14 14:14:16 -04006852 CFX_ByteString szValue;
dsinclair12a6b0c2016-05-26 11:14:08 -07006853 FXJSE_Value_ToUTF8String(pValue, szValue);
tsepezb4c9f3f2016-04-13 15:41:21 -07006854 iValue = FXSYS_atoi(szValue.c_str());
Dan Sinclair1770c022016-03-14 14:14:16 -04006855 } else {
dsinclair12a6b0c2016-05-26 11:14:08 -07006856 iValue = FXJSE_Value_ToInteger(pValue);
Dan Sinclair1770c022016-03-14 14:14:16 -04006857 }
6858 return iValue;
6859}
dsinclair48d91dd2016-05-31 11:54:01 -07006860
6861// static
dsinclair12a6b0c2016-05-26 11:14:08 -07006862FX_FLOAT CXFA_FM2JSContext::ValueToFloat(CFXJSE_Value* pThis,
6863 CFXJSE_Value* arg) {
dsinclairdd6a46c2016-05-26 08:41:45 -07006864 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07006865 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclairec3da5b2016-05-25 16:42:05 -07006866 v8::Isolate* pIsolate = pContext->GetScriptRuntime();
Dan Sinclair1770c022016-03-14 14:14:16 -04006867 FX_FLOAT fRet = 0.0f;
6868 if (FXJSE_Value_IsArray(arg)) {
dsinclair86fad992016-05-31 11:34:04 -07006869 std::unique_ptr<CFXJSE_Value> propertyValue(new CFXJSE_Value(pIsolate));
6870 std::unique_ptr<CFXJSE_Value> jsObjectValue(new CFXJSE_Value(pIsolate));
6871 std::unique_ptr<CFXJSE_Value> newPropertyValue(new CFXJSE_Value(pIsolate));
6872 FXJSE_Value_GetObjectPropByIdx(arg, 1, propertyValue.get());
6873 FXJSE_Value_GetObjectPropByIdx(arg, 2, jsObjectValue.get());
6874 if (FXJSE_Value_IsNull(propertyValue.get())) {
6875 GetObjectDefaultValue(jsObjectValue.get(), newPropertyValue.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04006876 } else {
6877 CFX_ByteString propertyStr;
dsinclair86fad992016-05-31 11:34:04 -07006878 FXJSE_Value_ToUTF8String(propertyValue.get(), propertyStr);
6879 FXJSE_Value_GetObjectProp(jsObjectValue.get(), propertyStr.AsStringC(),
6880 newPropertyValue.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04006881 }
dsinclair86fad992016-05-31 11:34:04 -07006882 fRet = ValueToFloat(pThis, newPropertyValue.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04006883 } else if (FXJSE_Value_IsObject(arg)) {
dsinclair86fad992016-05-31 11:34:04 -07006884 std::unique_ptr<CFXJSE_Value> newPropertyValue(new CFXJSE_Value(pIsolate));
6885 GetObjectDefaultValue(arg, newPropertyValue.get());
6886 fRet = ValueToFloat(pThis, newPropertyValue.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04006887 } else if (FXJSE_Value_IsUTF8String(arg)) {
6888 CFX_ByteString bsOutput;
6889 FXJSE_Value_ToUTF8String(arg, bsOutput);
dsinclair48d91dd2016-05-31 11:54:01 -07006890 fRet = (FX_FLOAT)XFA_ByteStringToDouble(bsOutput.AsStringC());
Dan Sinclair1770c022016-03-14 14:14:16 -04006891 } else if (FXJSE_Value_IsUndefined(arg)) {
6892 fRet = 0;
6893 } else {
6894 fRet = FXJSE_Value_ToFloat(arg);
6895 }
6896 return fRet;
6897}
dsinclair48d91dd2016-05-31 11:54:01 -07006898
6899// static
dsinclair12a6b0c2016-05-26 11:14:08 -07006900FX_DOUBLE CXFA_FM2JSContext::ValueToDouble(CFXJSE_Value* pThis,
6901 CFXJSE_Value* arg) {
dsinclairdd6a46c2016-05-26 08:41:45 -07006902 CXFA_FM2JSContext* pContext =
tsepez29adee72016-05-31 14:22:09 -07006903 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
dsinclairec3da5b2016-05-25 16:42:05 -07006904 v8::Isolate* pIsolate = pContext->GetScriptRuntime();
Dan Sinclair1770c022016-03-14 14:14:16 -04006905 FX_DOUBLE dRet = 0;
6906 if (FXJSE_Value_IsArray(arg)) {
dsinclair86fad992016-05-31 11:34:04 -07006907 std::unique_ptr<CFXJSE_Value> propertyValue(new CFXJSE_Value(pIsolate));
6908 std::unique_ptr<CFXJSE_Value> jsObjectValue(new CFXJSE_Value(pIsolate));
6909 std::unique_ptr<CFXJSE_Value> newPropertyValue(new CFXJSE_Value(pIsolate));
6910 FXJSE_Value_GetObjectPropByIdx(arg, 1, propertyValue.get());
6911 FXJSE_Value_GetObjectPropByIdx(arg, 2, jsObjectValue.get());
6912 if (FXJSE_Value_IsNull(propertyValue.get())) {
6913 GetObjectDefaultValue(jsObjectValue.get(), newPropertyValue.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04006914 } else {
6915 CFX_ByteString propertyStr;
dsinclair86fad992016-05-31 11:34:04 -07006916 FXJSE_Value_ToUTF8String(propertyValue.get(), propertyStr);
6917 FXJSE_Value_GetObjectProp(jsObjectValue.get(), propertyStr.AsStringC(),
6918 newPropertyValue.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04006919 }
dsinclair86fad992016-05-31 11:34:04 -07006920 dRet = ValueToDouble(pThis, newPropertyValue.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04006921 } else if (FXJSE_Value_IsObject(arg)) {
dsinclair86fad992016-05-31 11:34:04 -07006922 std::unique_ptr<CFXJSE_Value> newPropertyValue(new CFXJSE_Value(pIsolate));
6923 GetObjectDefaultValue(arg, newPropertyValue.get());
6924 dRet = ValueToDouble(pThis, newPropertyValue.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04006925 } else if (FXJSE_Value_IsUTF8String(arg)) {
6926 CFX_ByteString bsOutput;
6927 FXJSE_Value_ToUTF8String(arg, bsOutput);
dsinclair48d91dd2016-05-31 11:54:01 -07006928 dRet = XFA_ByteStringToDouble(bsOutput.AsStringC());
Dan Sinclair1770c022016-03-14 14:14:16 -04006929 } else if (FXJSE_Value_IsUndefined(arg)) {
6930 dRet = 0;
6931 } else {
6932 dRet = FXJSE_Value_ToDouble(arg);
6933 }
6934 return dRet;
6935}
tsepez1c9cfe12016-05-26 13:30:56 -07006936
dsinclairdbdcb812016-06-01 20:07:22 -07006937// static.
6938double CXFA_FM2JSContext::ExtractDouble(CFXJSE_Value* pThis,
6939 CFXJSE_Value* src,
6940 bool* ret) {
6941 ASSERT(ret);
6942
6943 CXFA_FM2JSContext* pContext =
6944 static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(pThis, nullptr));
6945 v8::Isolate* pIsolate = pContext->GetScriptRuntime();
6946
6947 *ret = true;
6948
6949 if (FXJSE_Value_IsArray(src)) {
6950 std::unique_ptr<CFXJSE_Value> lengthValue(new CFXJSE_Value(pIsolate));
6951 FXJSE_Value_GetObjectProp(src, "length", lengthValue.get());
6952 int32_t iLength = FXJSE_Value_ToInteger(lengthValue.get());
6953 if (iLength <= 2) {
6954 *ret = false;
6955 return 0.0;
6956 }
6957
6958 std::unique_ptr<CFXJSE_Value> propertyValue(new CFXJSE_Value(pIsolate));
6959 std::unique_ptr<CFXJSE_Value> jsObjectValue(new CFXJSE_Value(pIsolate));
6960 FXJSE_Value_GetObjectPropByIdx(src, 1, propertyValue.get());
6961 FXJSE_Value_GetObjectPropByIdx(src, 2, jsObjectValue.get());
6962 if (FXJSE_Value_IsNull(propertyValue.get()))
6963 return ValueToDouble(pThis, jsObjectValue.get());
6964
6965 CFX_ByteString propertyStr;
6966 FXJSE_Value_ToUTF8String(propertyValue.get(), propertyStr);
6967 std::unique_ptr<CFXJSE_Value> newPropertyValue(new CFXJSE_Value(pIsolate));
6968 FXJSE_Value_GetObjectProp(jsObjectValue.get(), propertyStr.AsStringC(),
6969 newPropertyValue.get());
6970 return ValueToDouble(pThis, newPropertyValue.get());
6971 }
6972 return ValueToDouble(pThis, src);
6973}
6974
dsinclair48d91dd2016-05-31 11:54:01 -07006975// static
dsinclair12a6b0c2016-05-26 11:14:08 -07006976void CXFA_FM2JSContext::ValueToUTF8String(CFXJSE_Value* arg,
6977 CFX_ByteString& szOutputString) {
Dan Sinclair1770c022016-03-14 14:14:16 -04006978 if (FXJSE_Value_IsNull(arg) || FXJSE_Value_IsUndefined(arg)) {
6979 szOutputString = "";
6980 } else if (FXJSE_Value_IsBoolean(arg)) {
6981 szOutputString = FXJSE_Value_ToBoolean(arg) ? "1" : "0";
6982 } else {
6983 szOutputString = "";
6984 FXJSE_Value_ToUTF8String(arg, szOutputString);
6985 }
6986}
tsepez1c9cfe12016-05-26 13:30:56 -07006987
dsinclaire80e9f82016-06-01 06:10:04 -07006988// static.
6989int32_t CXFA_FM2JSContext::Translate(const CFX_WideStringC& wsFormcalc,
6990 CFX_WideTextBuf& wsJavascript,
6991 CFX_WideString& wsError) {
6992 if (wsFormcalc.IsEmpty()) {
6993 wsJavascript.Clear();
6994 wsError.clear();
6995 return 0;
6996 }
6997 int32_t status = 0;
6998 CXFA_FMProgram program;
6999 status = program.Init(wsFormcalc);
7000 if (status) {
7001 wsError = program.GetError().message;
7002 return status;
7003 }
7004 status = program.ParseProgram();
7005 if (status) {
7006 wsError = program.GetError().message;
7007 return status;
7008 }
7009 program.TranslateProgram(wsJavascript);
7010 return 0;
7011}
7012
dsinclair48d91dd2016-05-31 11:54:01 -07007013CXFA_FM2JSContext::CXFA_FM2JSContext(v8::Isolate* pScriptIsolate,
7014 CFXJSE_Context* pScriptContext,
7015 CXFA_Document* pDoc)
7016 : m_pIsolate(pScriptIsolate),
7017 m_pFMClass(FXJSE_DefineClass(pScriptContext, &formcalc_fm2js_descriptor)),
7018 m_pValue(new CFXJSE_Value(pScriptIsolate)),
7019 m_pDocument(pDoc) {
dsinclair86fad992016-05-31 11:34:04 -07007020 FXJSE_Value_SetNull(m_pValue.get());
7021 FXJSE_Value_SetObject(m_pValue.get(), this, m_pFMClass);
Dan Sinclair1770c022016-03-14 14:14:16 -04007022}
tsepez1c9cfe12016-05-26 13:30:56 -07007023
dsinclair48d91dd2016-05-31 11:54:01 -07007024CXFA_FM2JSContext::~CXFA_FM2JSContext() {}
7025
dsinclair12a6b0c2016-05-26 11:14:08 -07007026void CXFA_FM2JSContext::GlobalPropertyGetter(CFXJSE_Value* pValue) {
dsinclair86fad992016-05-31 11:34:04 -07007027 FXJSE_Value_Set(pValue, m_pValue.get());
Dan Sinclair1770c022016-03-14 14:14:16 -04007028}
tsepez5c4dd352016-05-26 13:57:58 -07007029
dsinclair2235b7b2016-06-02 07:42:25 -07007030void CXFA_FM2JSContext::ThrowException(int32_t iStringID, ...) {
Dan Sinclair1770c022016-03-14 14:14:16 -04007031 IXFA_AppProvider* pAppProvider = m_pDocument->GetNotify()->GetAppProvider();
dsinclair43854a52016-04-27 12:26:00 -07007032 ASSERT(pAppProvider);
Dan Sinclair1770c022016-03-14 14:14:16 -04007033 CFX_WideString wsFormat;
7034 pAppProvider->LoadString(iStringID, wsFormat);
7035 CFX_WideString wsMessage;
7036 va_list arg_ptr;
7037 va_start(arg_ptr, iStringID);
tsepezbd9748d2016-04-13 21:40:19 -07007038 wsMessage.FormatV(wsFormat.c_str(), arg_ptr);
Dan Sinclair1770c022016-03-14 14:14:16 -04007039 va_end(arg_ptr);
tsepez28f97ff2016-04-04 16:41:35 -07007040 FXJSE_ThrowMessage(
tsepezbd9748d2016-04-13 21:40:19 -07007041 "", FX_UTF8Encode(wsMessage.c_str(), wsMessage.GetLength()).AsStringC());
Dan Sinclair1770c022016-03-14 14:14:16 -04007042}