1 // 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_fm2js.h"
8 #include <time.h>
9 #define FINANCIAL_PRECISION 0.00000001
10 struct XFA_FMHtmlReserveCode {
11   uint32_t m_uCode;
12   const FX_WCHAR* m_htmlReserve;
13 };
14 struct XFA_FMHtmlHashedReserveCode {
15   uint32_t m_uHash;
16   const FX_WCHAR* m_htmlReserve;
17   uint32_t m_uCode;
18 };
19 static XFA_FMHtmlHashedReserveCode reservesForDecode[] = {
20     {0x00018b62, L"Mu", 924},       {0x00019083, L"Nu", 925},
21     {0x00019ab9, L"Pi", 928},       {0x0001c3c1, L"Xi", 926},
22     {0x000210ac, L"ge", 8805},      {0x000210bb, L"gt", 62},
23     {0x00022a51, L"le", 8804},      {0x00022a60, L"lt", 60},
24     {0x00022f82, L"mu", 956},       {0x00023493, L"ne", 8800},
25     {0x00023497, L"ni", 8715},      {0x000234a3, L"nu", 957},
26     {0x000239c1, L"or", 8744},      {0x00023ed9, L"pi", 960},
27     {0x000267e1, L"xi", 958},       {0x00c41789, L"lceil", 8968},
28     {0x00eef34f, L"thetasym", 977}, {0x012d7ead, L"lcirc", 206},
29     {0x01637b56, L"agrave", 224},   {0x020856da, L"crarr", 8629},
30     {0x022188c3, L"gamma", 947},    {0x033586d3, L"nbsp", 160},
31     {0x04f4c358, L"nsub", 8836},    {0x0581466a, L"dagger", 8224},
32     {0x06b1f790, L"oelig", 339},    {0x06e490d4, L"Chi", 935},
33     {0x0718c6a1, L"ETH", 208},      {0x07196ada, L"Eta", 919},
34     {0x07f667ca, L"Ugrave", 217},   {0x083a8a21, L"Phi", 934},
35     {0x083ac28c, L"Psi", 936},      {0x086f26a9, L"Rho", 929},
36     {0x089b5b51, L"aring", 229},    {0x08a39f4a, L"Tau", 932},
37     {0x08b6188b, L"THORN", 222},    {0x09ce792a, L"icirc", 238},
38     {0x09f9d61e, L"amp", 38},       {0x09f9db33, L"and", 8743},
39     {0x09f9db36, L"ang", 8736},     {0x0a2e3514, L"cap", 8745},
40     {0x0a2e58f4, L"chi", 967},      {0x0a2e9ba8, L"cup", 8746},
41     {0x0a4897d0, L"deg", 176},      {0x0a6332fa, L"eta", 951},
42     {0x0a633301, L"eth", 240},      {0x0acc4d4b, L"int", 8747},
43     {0x0b1b3d35, L"loz", 9674},     {0x0b1b4c8b, L"lrm", 8206},
44     {0x0b4fd9b1, L"not", 172},      {0x0b845241, L"phi", 966},
45     {0x0b84576f, L"piv", 982},      {0x0b848aac, L"psi", 968},
46     {0x0bb8df5e, L"reg", 174},      {0x0bb8eec9, L"rho", 961},
47     {0x0bb9034b, L"rlm", 8207},     {0x0bd33d14, L"shy", 173},
48     {0x0bd34229, L"sim", 8764},     {0x0bd37faa, L"sub", 8834},
49     {0x0bd37fb5, L"sum", 8721},     {0x0bd37fb8, L"sup", 8835},
50     {0x0bed676a, L"tau", 964},      {0x0c07f32e, L"uml", 168},
51     {0x0c71032c, L"yen", 165},      {0x0c7f2889, L"szlig", 223},
52     {0x0c8badbb, L"zwj", 8205},     {0x10ba4dba, L"Egrave", 200},
53     {0x10f1ea24, L"para", 182},     {0x10f1ea37, L"part", 8706},
54     {0x115b2337, L"perp", 8869},    {0x12b10d15, L"prod", 8719},
55     {0x12b10d21, L"prop", 8733},    {0x12dfa9f4, L"rfloor", 8971},
56     {0x12eb4736, L"Agrave", 192},   {0x12fff2b7, L"pund", 163},
57     {0x13fda9f2, L"tilde", 732},    {0x1417fd62, L"times", 215},
58     {0x154fc726, L"ecirc", 234},    {0x165aa451, L"sigma", 963},
59     {0x1709124a, L"Dagger", 8225},  {0x192f78d5, L"iexcl", 161},
60     {0x1b7ed8d7, L"rArr", 8658},    {0x1ec88c68, L"rang", 9002},
61     {0x1ec8a0f7, L"rarr", 8594},    {0x1eda07f3, L"atilde", 227},
62     {0x1f3182c4, L"real", 8476},    {0x1fc34f8b, L"yacute", 253},
63     {0x20d11522, L"acirc", 226},    {0x21933a9b, L"rsaquo", 8250},
64     {0x21f44907, L"uacute", 250},   {0x220cca72, L"acute", 180},
65     {0x242cded1, L"alefsym", 8501}, {0x2655c66a, L"delta", 948},
66     {0x269e4b4d, L"exist", 8707},   {0x273379fa, L"micro", 181},
67     {0x27a37440, L"forall", 8704},  {0x2854e62c, L"minus", 8722},
68     {0x28636f81, L"cedil", 184},    {0x2887357b, L"iacute", 237},
69     {0x2994d5ff, L"frac12", 189},   {0x2994d601, L"frac14", 188},
70     {0x2994e043, L"frac34", 190},   {0x2a1feb41, L"lambda", 955},
71     {0x2ab215f3, L"apos", 39},      {0x2ab82ef7, L"eacute", 233},
72     {0x2b3592ef, L"auml", 228},     {0x2ce92873, L"aacute", 225},
73     {0x2daff48a, L"oslash", 248},   {0x2ef68882, L"aelig", 230},
74     {0x3061d3d3, L"Atilde", 195},   {0x314b1b6b, L"Yacute", 221},
75     {0x337c14e7, L"Uacute", 218},   {0x37676aca, L"cent", 162},
76     {0x37d0b841, L"circ", 710},     {0x386e7947, L"cong", 8773},
77     {0x386e839b, L"copy", 169},     {0x3a0e225a, L"Epsilon", 917},
78     {0x3ba7b721, L"Lambda", 923},   {0x3bd9abe6, L"Alpha", 913},
79     {0x3c3ffad7, L"Eacute", 201},   {0x3cfaf69f, L"brvbar", 166},
80     {0x3d54a489, L"omega", 969},    {0x3e70f453, L"Aacute", 193},
81     {0x3f37c06a, L"Oslash", 216},   {0x40e1b34e, L"diams", 9830},
82     {0x416596df, L"plusmn", 177},   {0x4354ff16, L"Ucirc", 219},
83     {0x454fce6a, L"Upsilon", 933},  {0x4610ad35, L"emsp", 8195},
84     {0x462afb76, L"ensp", 8194},    {0x46e30073, L"euml", 235},
85     {0x46e31a1b, L"euro", 8364},    {0x46f2eada, L"lowast", 8727},
86     {0x4dca26cf, L"Auml", 196},     {0x4e2d6083, L"image", 8465},
87     {0x4f964ee8, L"notin", 8713},   {0x50917a7a, L"epsilon", 949},
88     {0x52f9a4cd, L"Kappa", 922},    {0x5496f410, L"Ocirc", 212},
89     {0x568cbf34, L"zeta", 950},     {0x57badd20, L"ntilde", 241},
90     {0x58662109, L"zwnj", 8204},    {0x5b39870f, L"empty", 8709},
91     {0x5bd3268a, L"upsilon", 965},  {0x5e2bf8a3, L"Gamma", 915},
92     {0x5f73c13a, L"rsquo", 8217},   {0x61f2bc4d, L"iota", 953},
93     {0x625bbcf3, L"isin", 8712},    {0x62906df7, L"iuml", 239},
94     {0x64a5cb31, L"Aring", 197},    {0x66f25c4a, L"sbquo", 8218},
95     {0x6851ab60, L"spades", 9824},  {0x6942a900, L"Ntilde", 209},
96     {0x69779453, L"Euml", 203},     {0x6cda6e23, L"current", 164},
97     {0x70b5b634, L"lsquo", 8216},   {0x715a3706, L"Ecirc", 202},
98     {0x71e8bf8d, L"tdquo", 8221},   {0x72651431, L"Sigma", 931},
99     {0x7569813b, L"iquest", 191},   {0x776a436a, L"equiv", 8801},
100     {0x79215314, L"Zeta", 918},     {0x79b81224, L"ograve", 242},
101     {0x7c2f8b23, L"macr", 175},     {0x7cdb8502, L"Acirc", 194},
102     {0x8185c62e, L"ndash", 8211},   {0x8260364a, L"Delta", 916},
103     {0x846619ad, L"mdash", 8212},   {0x8550fb50, L"OElig", 338},
104     {0x88eb5b85, L"ldquo", 8220},   {0x8b3fde04, L"Ograve", 210},
105     {0x8bc5794b, L"ordf", 170},     {0x8bc57952, L"ordm", 186},
106     {0x8c14923d, L"ouml", 246},     {0x8c5a7cd6, L"theta", 952},
107     {0x8d61812b, L"thorn", 254},    {0x912b95aa, L"asymp", 8776},
108     {0x947faf81, L"middot", 183},   {0x9629202e, L"lfloor", 8970},
109     {0x972e9ec1, L"otilde", 245},   {0x9748f231, L"otimes", 8855},
110     {0x995f1469, L"Omega", 937},    {0x99eb5349, L"quot", 34},
111     {0x9aeb639e, L"hellip", 8230},  {0xa0ae2f86, L"Scaron", 352},
112     {0xa4dcb0d5, L"lsaquo", 8249},  {0xa53dbf41, L"oacute", 243},
113     {0xa5ae9e7b, L"bdquo", 8222},   {0xa602d7ba, L"sdot", 8901},
114     {0xa61ce86f, L"sect", 167},     {0xa6e4c3d7, L"sigmaf", 962},
115     {0xa7c1c74f, L"sube", 8838},    {0xa7c20ee9, L"sup1", 185},
116     {0xa7c20eea, L"sup2", 178},     {0xa7c20eeb, L"sup3", 179},
117     {0xa7c20f1d, L"supe", 8839},    {0xa8b66aa1, L"Otilde", 213},
118     {0xad958c42, L"AElig", 198},    {0xaea9261d, L"Ouml", 214},
119     {0xb040eafa, L"uArr", 8657},    {0xb07c2e1c, L"beta", 946},
120     {0xb220e92f, L"bull", 8226},    {0xb22750c4, L"ccedil", 231},
121     {0xb38ab31a, L"uarr", 8593},    {0xb598b683, L"uuml", 252},
122     {0xb6c58b21, L"Oacute", 211},   {0xb6d2a617, L"oline", 8254},
123     {0xba9fd989, L"dArr", 8659},    {0xbb5ccd41, L"lgrave", 204},
124     {0xbd39b44c, L"weierp", 8472},  {0xbde9a1a9, L"darr", 8595},
125     {0xc027e329, L"permil", 8240},  {0xc2451389, L"upsih", 978},
126     {0xc3af1ca4, L"Ccedil", 199},   {0xcd164249, L"fnof", 402},
127     {0xcf6c8467, L"hearts", 9829},  {0xd1228390, L"trade", 8482},
128     {0xd1462407, L"yuml", 255},     {0xd2cf2253, L"oplus", 8853},
129     {0xd310c1fc, L"Beta", 914},     {0xd59c4d74, L"infin", 8734},
130     {0xd64d470d, L"hArr", 8660},    {0xd67d9c75, L"divide", 247},
131     {0xd698dd37, L"Omicron", 927},  {0xd82d4a63, L"Uuml", 220},
132     {0xd9970f2d, L"harr", 8596},    {0xda91fd99, L"clubs", 9827},
133     {0xdbe5bdcc, L"there4", 8756},  {0xdd7671bd, L"prime", 8242},
134     {0xdfcf3c06, L"alpha", 945},    {0xe0213063, L"saron", 353},
135     {0xe1911d83, L"radic", 8730},   {0xe2e75468, L"raquo", 187},
136     {0xe6e27a5e, L"lacute", 205},   {0xe74a8f36, L"ucirc", 251},
137     {0xe864ecb6, L"Theta", 920},    {0xecddde5e, L"nabla", 8711},
138     {0xed1c3557, L"omicron", 959},  {0xef82228f, L"rceil", 8969},
139     {0xf1fab491, L"lArr", 8656},    {0xf3dab7e7, L"Yuml", 376},
140     {0xf4294962, L"laquo", 171},    {0xf5446822, L"lang", 9001},
141     {0xf5447cb1, L"larr", 8592},    {0xf66e9bea, L"ugrave", 249},
142     {0xf6b4ce70, L"lota", 921},     {0xf6ef34ed, L"kappa", 954},
143     {0xf72a3a56, L"thinsp", 8201},  {0xf752801a, L"luml", 207},
144     {0xf88c8430, L"ocirc", 244},    {0xf9676178, L"frasl", 8260},
145     {0xfd01885e, L"igrave", 236},   {0xff3281da, L"egrave", 232},
146 };
147 static XFA_FMHtmlReserveCode reservesForEncode[] = {
148     {34, L"quot"},     {38, L"amp"},      {39, L"apos"},
149     {60, L"lt"},       {62, L"gt"},       {160, L"nbsp"},
150     {161, L"iexcl"},   {162, L"cent"},    {163, L"pund"},
151     {164, L"current"}, {165, L"yen"},     {166, L"brvbar"},
152     {167, L"sect"},    {168, L"uml"},     {169, L"copy"},
153     {170, L"ordf"},    {171, L"laquo"},   {172, L"not"},
154     {173, L"shy"},     {174, L"reg"},     {175, L"macr"},
155     {176, L"deg"},     {177, L"plusmn"},  {178, L"sup2"},
156     {179, L"sup3"},    {180, L"acute"},   {181, L"micro"},
157     {182, L"para"},    {183, L"middot"},  {184, L"cedil"},
158     {185, L"sup1"},    {186, L"ordm"},    {187, L"raquo"},
159     {188, L"frac14"},  {189, L"frac12"},  {190, L"frac34"},
160     {191, L"iquest"},  {192, L"Agrave"},  {193, L"Aacute"},
161     {194, L"Acirc"},   {195, L"Atilde"},  {196, L"Auml"},
162     {197, L"Aring"},   {198, L"AElig"},   {199, L"Ccedil"},
163     {200, L"Egrave"},  {201, L"Eacute"},  {202, L"Ecirc"},
164     {203, L"Euml"},    {204, L"lgrave"},  {205, L"lacute"},
165     {206, L"lcirc"},   {207, L"luml"},    {208, L"ETH"},
166     {209, L"Ntilde"},  {210, L"Ograve"},  {211, L"Oacute"},
167     {212, L"Ocirc"},   {213, L"Otilde"},  {214, L"Ouml"},
168     {215, L"times"},   {216, L"Oslash"},  {217, L"Ugrave"},
169     {218, L"Uacute"},  {219, L"Ucirc"},   {220, L"Uuml"},
170     {221, L"Yacute"},  {222, L"THORN"},   {223, L"szlig"},
171     {224, L"agrave"},  {225, L"aacute"},  {226, L"acirc"},
172     {227, L"atilde"},  {228, L"auml"},    {229, L"aring"},
173     {230, L"aelig"},   {231, L"ccedil"},  {232, L"egrave"},
174     {233, L"eacute"},  {234, L"ecirc"},   {235, L"euml"},
175     {236, L"igrave"},  {237, L"iacute"},  {238, L"icirc"},
176     {239, L"iuml"},    {240, L"eth"},     {241, L"ntilde"},
177     {242, L"ograve"},  {243, L"oacute"},  {244, L"ocirc"},
178     {245, L"otilde"},  {246, L"ouml"},    {247, L"divide"},
179     {248, L"oslash"},  {249, L"ugrave"},  {250, L"uacute"},
180     {251, L"ucirc"},   {252, L"uuml"},    {253, L"yacute"},
181     {254, L"thorn"},   {255, L"yuml"},    {338, L"OElig"},
182     {339, L"oelig"},   {352, L"Scaron"},  {353, L"saron"},
183     {376, L"Yuml"},    {402, L"fnof"},    {710, L"circ"},
184     {732, L"tilde"},   {913, L"Alpha"},   {914, L"Beta"},
185     {915, L"Gamma"},   {916, L"Delta"},   {917, L"Epsilon"},
186     {918, L"Zeta"},    {919, L"Eta"},     {920, L"Theta"},
187     {921, L"lota"},    {922, L"Kappa"},   {923, L"Lambda"},
188     {924, L"Mu"},      {925, L"Nu"},      {926, L"Xi"},
189     {927, L"Omicron"}, {928, L"Pi"},      {929, L"Rho"},
190     {931, L"Sigma"},   {932, L"Tau"},     {933, L"Upsilon"},
191     {934, L"Phi"},     {935, L"Chi"},     {936, L"Psi"},
192     {937, L"Omega"},   {945, L"alpha"},   {946, L"beta"},
193     {947, L"gamma"},   {948, L"delta"},   {949, L"epsilon"},
194     {950, L"zeta"},    {951, L"eta"},     {952, L"theta"},
195     {953, L"iota"},    {954, L"kappa"},   {955, L"lambda"},
196     {956, L"mu"},      {957, L"nu"},      {958, L"xi"},
197     {959, L"omicron"}, {960, L"pi"},      {961, L"rho"},
198     {962, L"sigmaf"},  {963, L"sigma"},   {964, L"tau"},
199     {965, L"upsilon"}, {966, L"phi"},     {967, L"chi"},
200     {968, L"psi"},     {969, L"omega"},   {977, L"thetasym"},
201     {978, L"upsih"},   {982, L"piv"},     {8194, L"ensp"},
202     {8195, L"emsp"},   {8201, L"thinsp"}, {8204, L"zwnj"},
203     {8205, L"zwj"},    {8206, L"lrm"},    {8207, L"rlm"},
204     {8211, L"ndash"},  {8212, L"mdash"},  {8216, L"lsquo"},
205     {8217, L"rsquo"},  {8218, L"sbquo"},  {8220, L"ldquo"},
206     {8221, L"tdquo"},  {8222, L"bdquo"},  {8224, L"dagger"},
207     {8225, L"Dagger"}, {8226, L"bull"},   {8230, L"hellip"},
208     {8240, L"permil"}, {8242, L"prime"},  {8249, L"lsaquo"},
209     {8250, L"rsaquo"}, {8254, L"oline"},  {8260, L"frasl"},
210     {8364, L"euro"},   {8465, L"image"},  {8472, L"weierp"},
211     {8476, L"real"},   {8482, L"trade"},  {8501, L"alefsym"},
212     {8592, L"larr"},   {8593, L"uarr"},   {8594, L"rarr"},
213     {8595, L"darr"},   {8596, L"harr"},   {8629, L"crarr"},
214     {8656, L"lArr"},   {8657, L"uArr"},   {8658, L"rArr"},
215     {8659, L"dArr"},   {8660, L"hArr"},   {8704, L"forall"},
216     {8706, L"part"},   {8707, L"exist"},  {8709, L"empty"},
217     {8711, L"nabla"},  {8712, L"isin"},   {8713, L"notin"},
218     {8715, L"ni"},     {8719, L"prod"},   {8721, L"sum"},
219     {8722, L"minus"},  {8727, L"lowast"}, {8730, L"radic"},
220     {8733, L"prop"},   {8734, L"infin"},  {8736, L"ang"},
221     {8743, L"and"},    {8744, L"or"},     {8745, L"cap"},
222     {8746, L"cup"},    {8747, L"int"},    {8756, L"there4"},
223     {8764, L"sim"},    {8773, L"cong"},   {8776, L"asymp"},
224     {8800, L"ne"},     {8801, L"equiv"},  {8804, L"le"},
225     {8805, L"ge"},     {8834, L"sub"},    {8835, L"sup"},
226     {8836, L"nsub"},   {8838, L"sube"},   {8839, L"supe"},
227     {8853, L"oplus"},  {8855, L"otimes"}, {8869, L"perp"},
228     {8901, L"sdot"},   {8968, L"lceil"},  {8969, L"rceil"},
229     {8970, L"lfloor"}, {8971, L"rfloor"}, {9001, L"lang"},
230     {9002, L"rang"},   {9674, L"loz"},    {9824, L"spades"},
231     {9827, L"clubs"},  {9829, L"hearts"}, {9830, L"diams"},
232 };
Abs(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)233 void CXFA_FM2JSContext::Abs(FXJSE_HOBJECT hThis,
234                             const CFX_ByteStringC& szFuncName,
235                             CFXJSE_Arguments& args) {
236   if (args.GetLength() == 1) {
237     FXJSE_HVALUE argOne = args.GetValue(0);
238     if (HValueIsNull(hThis, argOne)) {
239       FXJSE_Value_SetNull(args.GetReturnValue());
240     } else {
241       FX_DOUBLE dValue = HValueToDouble(hThis, argOne);
242       if (dValue < 0) {
243         dValue = -dValue;
244       }
245       FXJSE_Value_SetDouble(args.GetReturnValue(), dValue);
246     }
247     FXJSE_Value_Release(argOne);
248   } else {
249     CXFA_FM2JSContext* pContext =
250         (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
251     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
252                                       L"Abs");
253   }
254 }
Avg(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)255 void CXFA_FM2JSContext::Avg(FXJSE_HOBJECT hThis,
256                             const CFX_ByteStringC& szFuncName,
257                             CFXJSE_Arguments& args) {
258   CXFA_FM2JSContext* pContext =
259       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
260   FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
261   int32_t argc = args.GetLength();
262   uint32_t uCount = 0;
263   FX_DOUBLE dSum = 0.0;
264   if (argc >= 1) {
265     FXJSE_HVALUE argValue = 0;
266     for (int32_t i = 0; i < argc; i++) {
267       argValue = args.GetValue(i);
268       if (FXJSE_Value_IsNull(argValue)) {
269         FXJSE_Value_Release(argValue);
270         continue;
271       } else if (FXJSE_Value_IsArray(argValue)) {
272         FXJSE_HVALUE lengthValue = FXJSE_Value_Create(hruntime);
273         FXJSE_Value_GetObjectProp(argValue, "length", lengthValue);
274         int32_t iLength = FXJSE_Value_ToInteger(lengthValue);
275         FXJSE_Value_Release(lengthValue);
276         if (iLength > 2) {
277           FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
278           FXJSE_Value_GetObjectPropByIdx(argValue, 1, propertyValue);
279           FXJSE_HVALUE jsObjectValue = FXJSE_Value_Create(hruntime);
280           if (FXJSE_Value_IsNull(propertyValue)) {
281             for (int32_t j = 2; j < iLength; j++) {
282               FXJSE_Value_GetObjectPropByIdx(argValue, j, jsObjectValue);
283               FXJSE_HVALUE defaultPropValue = FXJSE_Value_Create(hruntime);
284               GetObjectDefaultValue(jsObjectValue, defaultPropValue);
285               if (!FXJSE_Value_IsNull(defaultPropValue)) {
286                 dSum += HValueToDouble(hThis, defaultPropValue);
287                 uCount++;
288               }
289               FXJSE_Value_Release(defaultPropValue);
290             }
291           } else {
292             CFX_ByteString propertyStr;
293             FXJSE_Value_ToUTF8String(propertyValue, propertyStr);
294             FXJSE_HVALUE newPropertyValue = FXJSE_Value_Create(hruntime);
295             for (int32_t j = 2; j < iLength; j++) {
296               FXJSE_Value_GetObjectPropByIdx(argValue, j, jsObjectValue);
297               FXJSE_Value_GetObjectProp(jsObjectValue, propertyStr,
298                                         newPropertyValue);
299               if (!FXJSE_Value_IsNull(newPropertyValue)) {
300                 dSum += HValueToDouble(hThis, newPropertyValue);
301                 uCount++;
302               }
303             }
304             FXJSE_Value_Release(newPropertyValue);
305           }
306           FXJSE_Value_Release(jsObjectValue);
307           FXJSE_Value_Release(propertyValue);
308         }
309       } else {
310         dSum += HValueToDouble(hThis, argValue);
311         uCount++;
312       }
313       FXJSE_Value_Release(argValue);
314     }
315     argValue = 0;
316   }
317   if (0 == uCount) {
318     FXJSE_Value_SetNull(args.GetReturnValue());
319   } else {
320     FXJSE_Value_SetDouble(args.GetReturnValue(), dSum / uCount);
321   }
322 }
Ceil(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)323 void CXFA_FM2JSContext::Ceil(FXJSE_HOBJECT hThis,
324                              const CFX_ByteStringC& szFuncName,
325                              CFXJSE_Arguments& args) {
326   CXFA_FM2JSContext* pContext =
327       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
328   if (args.GetLength() == 1) {
329     FXJSE_HVALUE argValue = GetSimpleHValue(hThis, args, 0);
330     if (HValueIsNull(hThis, argValue)) {
331       FXJSE_Value_SetNull(args.GetReturnValue());
332     } else {
333       FXJSE_Value_SetFloat(args.GetReturnValue(),
334                            FXSYS_ceil(HValueToFloat(hThis, argValue)));
335     }
336     FXJSE_Value_Release(argValue);
337   } else {
338     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
339                                       L"Ceil");
340   }
341 }
Count(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)342 void CXFA_FM2JSContext::Count(FXJSE_HOBJECT hThis,
343                               const CFX_ByteStringC& szFuncName,
344                               CFXJSE_Arguments& args) {
345   CXFA_FM2JSContext* pContext =
346       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
347   FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
348   int32_t argc = args.GetLength();
349   uint32_t uCount = 0;
350   FXJSE_HVALUE argValue = 0;
351   for (int32_t i = 0; i < argc; i++) {
352     argValue = args.GetValue(i);
353     if (FXJSE_Value_IsNull(argValue)) {
354       FXJSE_Value_Release(argValue);
355       continue;
356     } else if (FXJSE_Value_IsArray(argValue)) {
357       FXJSE_HVALUE lengthValue = FXJSE_Value_Create(hruntime);
358       FXJSE_Value_GetObjectProp(argValue, "length", lengthValue);
359       int32_t iLength = FXJSE_Value_ToInteger(lengthValue);
360       FXJSE_Value_Release(lengthValue);
361       if (iLength > 2) {
362         FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
363         FXJSE_HVALUE jsObjectValue = FXJSE_Value_Create(hruntime);
364         FXJSE_HVALUE newPropertyValue = FXJSE_Value_Create(hruntime);
365         FXJSE_Value_GetObjectPropByIdx(argValue, 1, propertyValue);
366         FXJSE_Value_GetObjectPropByIdx(argValue, 2, jsObjectValue);
367         if (FXJSE_Value_IsNull(propertyValue)) {
368           for (int32_t i = 2; i < iLength; i++) {
369             FXJSE_Value_GetObjectPropByIdx(argValue, i, jsObjectValue);
370             GetObjectDefaultValue(jsObjectValue, newPropertyValue);
371             if (!FXJSE_Value_IsNull(newPropertyValue)) {
372               uCount++;
373             }
374           }
375         } else {
376           CFX_ByteString propertyStr;
377           FXJSE_Value_ToUTF8String(propertyValue, propertyStr);
378           for (int32_t i = 2; i < iLength; i++) {
379             FXJSE_Value_GetObjectPropByIdx(argValue, i, jsObjectValue);
380             FXJSE_Value_GetObjectProp(jsObjectValue, propertyStr,
381                                       newPropertyValue);
382             uCount += (FXJSE_Value_IsNull(newPropertyValue) ? 0 : 1);
383           }
384         }
385         FXJSE_Value_Release(propertyValue);
386         FXJSE_Value_Release(jsObjectValue);
387         FXJSE_Value_Release(newPropertyValue);
388       } else {
389         pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
390       }
391     } else if (FXJSE_Value_IsObject(argValue)) {
392       FXJSE_HVALUE newPropertyValue = FXJSE_Value_Create(hruntime);
393       GetObjectDefaultValue(argValue, newPropertyValue);
394       if (!FXJSE_Value_IsNull(newPropertyValue)) {
395         uCount++;
396       }
397       FXJSE_Value_Release(newPropertyValue);
398     } else {
399       uCount++;
400     }
401     FXJSE_Value_Release(argValue);
402   }
403   argValue = 0;
404   FXJSE_Value_SetInteger(args.GetReturnValue(), (int32_t)uCount);
405 }
Floor(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)406 void CXFA_FM2JSContext::Floor(FXJSE_HOBJECT hThis,
407                               const CFX_ByteStringC& szFuncName,
408                               CFXJSE_Arguments& args) {
409   CXFA_FM2JSContext* pContext =
410       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
411   if (args.GetLength() == 1) {
412     FXJSE_HVALUE argValue = GetSimpleHValue(hThis, args, 0);
413     if (HValueIsNull(hThis, argValue)) {
414       FXJSE_Value_SetNull(args.GetReturnValue());
415     } else {
416       FXJSE_Value_SetFloat(args.GetReturnValue(),
417                            FXSYS_floor(HValueToFloat(hThis, argValue)));
418     }
419     FXJSE_Value_Release(argValue);
420   } else {
421     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
422                                       L"Floor");
423   }
424 }
Max(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)425 void CXFA_FM2JSContext::Max(FXJSE_HOBJECT hThis,
426                             const CFX_ByteStringC& szFuncName,
427                             CFXJSE_Arguments& args) {
428   CXFA_FM2JSContext* pContext =
429       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
430   FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
431   int32_t argc = args.GetLength();
432   uint32_t uCount = 0;
433   FX_DOUBLE dMaxValue = 0.0;
434   FXJSE_HVALUE argValue = 0;
435   for (int32_t i = 0; i < argc; i++) {
436     argValue = args.GetValue(i);
437     if (FXJSE_Value_IsNull(argValue)) {
438       FXJSE_Value_Release(argValue);
439       continue;
440     } else if (FXJSE_Value_IsArray(argValue)) {
441       FXJSE_HVALUE lengthValue = FXJSE_Value_Create(hruntime);
442       FXJSE_Value_GetObjectProp(argValue, "length", lengthValue);
443       int32_t iLength = FXJSE_Value_ToInteger(lengthValue);
444       FXJSE_Value_Release(lengthValue);
445       if (iLength > 2) {
446         FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
447         FXJSE_HVALUE jsObjectValue = FXJSE_Value_Create(hruntime);
448         FXJSE_HVALUE newPropertyValue = FXJSE_Value_Create(hruntime);
449         FXJSE_Value_GetObjectPropByIdx(argValue, 1, propertyValue);
450         FXJSE_Value_GetObjectPropByIdx(argValue, 2, jsObjectValue);
451         if (FXJSE_Value_IsNull(propertyValue)) {
452           for (int32_t i = 2; i < iLength; i++) {
453             FXJSE_Value_GetObjectPropByIdx(argValue, i, jsObjectValue);
454             GetObjectDefaultValue(jsObjectValue, newPropertyValue);
455             if (!FXJSE_Value_IsNull(newPropertyValue)) {
456               uCount++;
457               if (uCount == 1) {
458                 dMaxValue = HValueToDouble(hThis, newPropertyValue);
459               } else {
460                 FX_DOUBLE dValue = HValueToDouble(hThis, newPropertyValue);
461                 if (dMaxValue < dValue) {
462                   dMaxValue = dValue;
463                 }
464               }
465             }
466           }
467         } else {
468           CFX_ByteString propertyStr;
469           FXJSE_Value_ToUTF8String(propertyValue, propertyStr);
470           for (int32_t i = 2; i < iLength; i++) {
471             FXJSE_Value_GetObjectPropByIdx(argValue, i, jsObjectValue);
472             FXJSE_Value_GetObjectProp(jsObjectValue, propertyStr,
473                                       newPropertyValue);
474             if (!FXJSE_Value_IsNull(newPropertyValue)) {
475               uCount++;
476               if (uCount == 1) {
477                 dMaxValue = HValueToDouble(hThis, newPropertyValue);
478               } else {
479                 FX_DOUBLE dValue = HValueToDouble(hThis, newPropertyValue);
480                 if (dMaxValue < dValue) {
481                   dMaxValue = dValue;
482                 }
483               }
484             }
485           }
486         }
487         FXJSE_Value_Release(propertyValue);
488         FXJSE_Value_Release(jsObjectValue);
489         FXJSE_Value_Release(newPropertyValue);
490       } else {
491         pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
492       }
493     } else if (FXJSE_Value_IsObject(argValue)) {
494       FXJSE_HVALUE newPropertyValue = FXJSE_Value_Create(hruntime);
495       GetObjectDefaultValue(argValue, newPropertyValue);
496       if (!FXJSE_Value_IsNull(newPropertyValue)) {
497         uCount++;
498         if (uCount == 1) {
499           dMaxValue = HValueToDouble(hThis, newPropertyValue);
500         } else {
501           FX_DOUBLE dValue = HValueToDouble(hThis, newPropertyValue);
502           if (dMaxValue < dValue) {
503             dMaxValue = dValue;
504           }
505         }
506       }
507       FXJSE_Value_Release(newPropertyValue);
508     } else {
509       uCount++;
510       if (uCount == 1) {
511         dMaxValue = HValueToDouble(hThis, argValue);
512       } else {
513         FX_DOUBLE dValue = HValueToDouble(hThis, argValue);
514         if (dMaxValue < dValue) {
515           dMaxValue = dValue;
516         }
517       }
518     }
519     FXJSE_Value_Release(argValue);
520   }
521   argValue = 0;
522   if (uCount) {
523     FXJSE_Value_SetDouble(args.GetReturnValue(), dMaxValue);
524   } else {
525     FXJSE_Value_SetNull(args.GetReturnValue());
526   }
527 }
Min(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)528 void CXFA_FM2JSContext::Min(FXJSE_HOBJECT hThis,
529                             const CFX_ByteStringC& szFuncName,
530                             CFXJSE_Arguments& args) {
531   CXFA_FM2JSContext* pContext =
532       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
533   FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
534   int32_t argc = args.GetLength();
535   uint32_t uCount = 0;
536   FX_DOUBLE dMinValue = 0.0;
537   FXJSE_HVALUE argValue = 0;
538   for (int32_t i = 0; i < argc; i++) {
539     argValue = args.GetValue(i);
540     if (FXJSE_Value_IsNull(argValue)) {
541       FXJSE_Value_Release(argValue);
542       continue;
543     } else if (FXJSE_Value_IsArray(argValue)) {
544       FXJSE_HVALUE lengthValue = FXJSE_Value_Create(hruntime);
545       FXJSE_Value_GetObjectProp(argValue, "length", lengthValue);
546       int32_t iLength = FXJSE_Value_ToInteger(lengthValue);
547       FXJSE_Value_Release(lengthValue);
548       if (iLength > 2) {
549         FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
550         FXJSE_HVALUE jsObjectValue = FXJSE_Value_Create(hruntime);
551         FXJSE_HVALUE newPropertyValue = FXJSE_Value_Create(hruntime);
552         FXJSE_Value_GetObjectPropByIdx(argValue, 1, propertyValue);
553         FXJSE_Value_GetObjectPropByIdx(argValue, 2, jsObjectValue);
554         if (FXJSE_Value_IsNull(propertyValue)) {
555           for (int32_t i = 2; i < iLength; i++) {
556             FXJSE_Value_GetObjectPropByIdx(argValue, i, jsObjectValue);
557             GetObjectDefaultValue(jsObjectValue, newPropertyValue);
558             if (!FXJSE_Value_IsNull(newPropertyValue)) {
559               uCount++;
560               if (uCount == 1) {
561                 dMinValue = HValueToDouble(hThis, newPropertyValue);
562               } else {
563                 FX_DOUBLE dValue = HValueToDouble(hThis, newPropertyValue);
564                 if (dMinValue > dValue) {
565                   dMinValue = dValue;
566                 }
567               }
568             }
569           }
570         } else {
571           CFX_ByteString propertyStr;
572           FXJSE_Value_ToUTF8String(propertyValue, propertyStr);
573           for (int32_t i = 2; i < iLength; i++) {
574             FXJSE_Value_GetObjectPropByIdx(argValue, i, jsObjectValue);
575             FXJSE_Value_GetObjectProp(jsObjectValue, propertyStr,
576                                       newPropertyValue);
577             if (!FXJSE_Value_IsNull(newPropertyValue)) {
578               uCount++;
579               if (uCount == 1) {
580                 dMinValue = HValueToDouble(hThis, newPropertyValue);
581               } else {
582                 FX_DOUBLE dValue = HValueToDouble(hThis, newPropertyValue);
583                 if (dMinValue > dValue) {
584                   dMinValue = dValue;
585                 }
586               }
587             }
588           }
589         }
590         FXJSE_Value_Release(propertyValue);
591         FXJSE_Value_Release(jsObjectValue);
592         FXJSE_Value_Release(newPropertyValue);
593       } else {
594         pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
595       }
596     } else if (FXJSE_Value_IsObject(argValue)) {
597       FXJSE_HVALUE newPropertyValue = FXJSE_Value_Create(hruntime);
598       GetObjectDefaultValue(argValue, newPropertyValue);
599       if (!FXJSE_Value_IsNull(newPropertyValue)) {
600         uCount++;
601         if (uCount == 1) {
602           dMinValue = HValueToDouble(hThis, newPropertyValue);
603         } else {
604           FX_DOUBLE dValue = HValueToDouble(hThis, newPropertyValue);
605           if (dMinValue > dValue) {
606             dMinValue = dValue;
607           }
608         }
609       }
610       FXJSE_Value_Release(newPropertyValue);
611     } else {
612       uCount++;
613       if (uCount == 1) {
614         dMinValue = HValueToDouble(hThis, argValue);
615       } else {
616         FX_DOUBLE dValue = HValueToDouble(hThis, argValue);
617         if (dMinValue > dValue) {
618           dMinValue = dValue;
619         }
620       }
621     }
622     FXJSE_Value_Release(argValue);
623   }
624   argValue = 0;
625   if (uCount) {
626     FXJSE_Value_SetDouble(args.GetReturnValue(), dMinValue);
627   } else {
628     FXJSE_Value_SetNull(args.GetReturnValue());
629   }
630 }
Mod(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)631 void CXFA_FM2JSContext::Mod(FXJSE_HOBJECT hThis,
632                             const CFX_ByteStringC& szFuncName,
633                             CFXJSE_Arguments& args) {
634   CXFA_FM2JSContext* pContext =
635       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
636   FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
637   if (args.GetLength() == 2) {
638     FXJSE_HVALUE argOne = args.GetValue(0);
639     FXJSE_HVALUE argTwo = args.GetValue(1);
640     if (FXJSE_Value_IsNull(argOne) || FXJSE_Value_IsNull(argTwo)) {
641       FXJSE_Value_SetNull(args.GetReturnValue());
642     } else {
643       FX_DOUBLE dDividend = 0.0;
644       FX_DOUBLE dDividor = 0.0;
645       if (FXJSE_Value_IsArray(argOne)) {
646         FXJSE_HVALUE lengthValue = FXJSE_Value_Create(hruntime);
647         FXJSE_Value_GetObjectProp(argOne, "length", lengthValue);
648         int32_t iLength = FXJSE_Value_ToInteger(lengthValue);
649         FXJSE_Value_Release(lengthValue);
650         if (iLength > 2) {
651           FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
652           FXJSE_HVALUE jsObjectValue = FXJSE_Value_Create(hruntime);
653           FXJSE_Value_GetObjectPropByIdx(argOne, 1, propertyValue);
654           FXJSE_Value_GetObjectPropByIdx(argOne, 2, jsObjectValue);
655           if (FXJSE_Value_IsNull(propertyValue)) {
656             dDividend = HValueToDouble(hThis, jsObjectValue);
657           } else {
658             CFX_ByteString propertyStr;
659             FXJSE_Value_ToUTF8String(propertyValue, propertyStr);
660             FXJSE_HVALUE newPropertyValue = FXJSE_Value_Create(hruntime);
661             FXJSE_Value_GetObjectProp(jsObjectValue, propertyStr,
662                                       newPropertyValue);
663             dDividend = HValueToDouble(hThis, newPropertyValue);
664             FXJSE_Value_Release(newPropertyValue);
665           }
666           FXJSE_Value_Release(propertyValue);
667           FXJSE_Value_Release(jsObjectValue);
668         } else {
669           pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
670         }
671       } else {
672         dDividend = HValueToDouble(hThis, argOne);
673       }
674       if (FXJSE_Value_IsArray(argTwo)) {
675         FXJSE_HVALUE lengthValue = FXJSE_Value_Create(hruntime);
676         FXJSE_Value_GetObjectProp(argTwo, "length", lengthValue);
677         int32_t iLength = FXJSE_Value_ToInteger(lengthValue);
678         FXJSE_Value_Release(lengthValue);
679         if (iLength > 2) {
680           FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
681           FXJSE_HVALUE jsObjectValue = FXJSE_Value_Create(hruntime);
682           FXJSE_Value_GetObjectPropByIdx(argTwo, 1, propertyValue);
683           FXJSE_Value_GetObjectPropByIdx(argTwo, 2, jsObjectValue);
684           if (FXJSE_Value_IsNull(propertyValue)) {
685             dDividor = HValueToDouble(hThis, jsObjectValue);
686           } else {
687             CFX_ByteString propertyStr;
688             FXJSE_Value_ToUTF8String(propertyValue, propertyStr);
689             FXJSE_HVALUE newPropertyValue = FXJSE_Value_Create(hruntime);
690             FXJSE_Value_GetObjectProp(jsObjectValue, propertyStr,
691                                       newPropertyValue);
692             dDividor = HValueToDouble(hThis, newPropertyValue);
693             FXJSE_Value_Release(newPropertyValue);
694           }
695           FXJSE_Value_Release(propertyValue);
696           FXJSE_Value_Release(jsObjectValue);
697         } else {
698           pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
699         }
700       } else {
701         dDividor = HValueToDouble(hThis, argTwo);
702       }
703       if (dDividor) {
704         FXJSE_Value_SetDouble(
705             args.GetReturnValue(),
706             dDividend - dDividor * (int32_t)(dDividend / dDividor));
707       } else {
708         pContext->ThrowScriptErrorMessage(XFA_IDS_DIVIDE_ZERO);
709       }
710     }
711     FXJSE_Value_Release(argOne);
712     FXJSE_Value_Release(argTwo);
713   } else {
714     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
715                                       L"Mod");
716   }
717 }
Round(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)718 void CXFA_FM2JSContext::Round(FXJSE_HOBJECT hThis,
719                               const CFX_ByteStringC& szFuncName,
720                               CFXJSE_Arguments& args) {
721   CXFA_FM2JSContext* pContext =
722       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
723   FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
724   int32_t argc = args.GetLength();
725   uint8_t uPrecision = 0;
726   if (argc == 1) {
727     FXJSE_HVALUE argOne = args.GetValue(0);
728     if (FXJSE_Value_IsNull(argOne)) {
729       FXJSE_Value_SetNull(args.GetReturnValue());
730     } else {
731       FX_DOUBLE dValue = 0.0;
732       if (FXJSE_Value_IsArray(argOne)) {
733         FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
734         FXJSE_HVALUE jsObjectValue = FXJSE_Value_Create(hruntime);
735         FXJSE_Value_GetObjectPropByIdx(argOne, 1, propertyValue);
736         FXJSE_Value_GetObjectPropByIdx(argOne, 2, jsObjectValue);
737         if (FXJSE_Value_IsNull(propertyValue)) {
738           dValue = HValueToDouble(hThis, jsObjectValue);
739         } else {
740           CFX_ByteString propertyStr;
741           FXJSE_Value_ToUTF8String(propertyValue, propertyStr);
742           FXJSE_HVALUE newPropertyValue = FXJSE_Value_Create(hruntime);
743           FXJSE_Value_GetObjectProp(jsObjectValue, propertyStr,
744                                     newPropertyValue);
745           dValue = HValueToDouble(hThis, newPropertyValue);
746           FXJSE_Value_Release(newPropertyValue);
747         }
748         FXJSE_Value_Release(propertyValue);
749         FXJSE_Value_Release(jsObjectValue);
750       } else {
751         dValue = HValueToDouble(hThis, argOne);
752       }
753       CFX_Decimal decimalValue((FX_FLOAT)dValue, uPrecision);
754       CFX_WideString wsValue = decimalValue;
755       FXJSE_Value_SetUTF8String(args.GetReturnValue(), wsValue.UTF8Encode());
756     }
757     FXJSE_Value_Release(argOne);
758   } else if (argc == 2) {
759     FXJSE_HVALUE argOne = args.GetValue(0);
760     FXJSE_HVALUE argTwo = args.GetValue(1);
761     if (FXJSE_Value_IsNull(argOne) || FXJSE_Value_IsNull(argTwo)) {
762       FXJSE_Value_SetNull(args.GetReturnValue());
763     } else {
764       FX_DOUBLE dValue = 0.0;
765       if (FXJSE_Value_IsArray(argOne)) {
766         FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
767         FXJSE_HVALUE jsObjectValue = FXJSE_Value_Create(hruntime);
768         FXJSE_Value_GetObjectPropByIdx(argOne, 1, propertyValue);
769         FXJSE_Value_GetObjectPropByIdx(argOne, 2, jsObjectValue);
770         if (FXJSE_Value_IsNull(propertyValue)) {
771           dValue = HValueToDouble(hThis, jsObjectValue);
772         } else {
773           CFX_ByteString propertyStr;
774           FXJSE_Value_ToUTF8String(propertyValue, propertyStr);
775           FXJSE_HVALUE newPropertyValue = FXJSE_Value_Create(hruntime);
776           FXJSE_Value_GetObjectProp(jsObjectValue, propertyStr,
777                                     newPropertyValue);
778           dValue = HValueToDouble(hThis, newPropertyValue);
779           FXJSE_Value_Release(newPropertyValue);
780         }
781         FXJSE_Value_Release(propertyValue);
782         FXJSE_Value_Release(jsObjectValue);
783       } else {
784         dValue = HValueToDouble(hThis, argOne);
785       }
786       FX_DOUBLE dPrecision = 0.0;
787       if (FXJSE_Value_IsArray(argTwo)) {
788         FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
789         FXJSE_HVALUE jsObjectValue = FXJSE_Value_Create(hruntime);
790         FXJSE_Value_GetObjectPropByIdx(argTwo, 1, propertyValue);
791         FXJSE_Value_GetObjectPropByIdx(argTwo, 2, jsObjectValue);
792         if (FXJSE_Value_IsNull(propertyValue)) {
793           dPrecision = HValueToDouble(hThis, jsObjectValue);
794         } else {
795           CFX_ByteString propertyStr;
796           FXJSE_Value_ToUTF8String(propertyValue, propertyStr);
797           FXJSE_HVALUE newPropertyValue = FXJSE_Value_Create(hruntime);
798           FXJSE_Value_GetObjectProp(jsObjectValue, propertyStr,
799                                     newPropertyValue);
800           dPrecision = HValueToDouble(hThis, newPropertyValue);
801           FXJSE_Value_Release(newPropertyValue);
802         }
803         FXJSE_Value_Release(propertyValue);
804         FXJSE_Value_Release(jsObjectValue);
805       } else {
806         dPrecision = HValueToDouble(hThis, argTwo);
807       }
808       if (dPrecision < 0) {
809         uPrecision = 0;
810       } else if (dPrecision > 12.0) {
811         uPrecision = 12;
812       } else {
813         uPrecision = (uint8_t)dPrecision;
814       }
815       CFX_Decimal decimalValue((FX_FLOAT)dValue, uPrecision);
816       CFX_WideString wsValue = decimalValue;
817       FXJSE_Value_SetUTF8String(args.GetReturnValue(), wsValue.UTF8Encode());
818     }
819     FXJSE_Value_Release(argOne);
820     FXJSE_Value_Release(argTwo);
821   } else {
822     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
823                                       L"Round");
824   }
825 }
Sum(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)826 void CXFA_FM2JSContext::Sum(FXJSE_HOBJECT hThis,
827                             const CFX_ByteStringC& szFuncName,
828                             CFXJSE_Arguments& args) {
829   CXFA_FM2JSContext* pContext =
830       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
831   FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
832   int32_t argc = args.GetLength();
833   uint32_t uCount = 0;
834   FX_DOUBLE dSum = 0.0;
835   if (argc) {
836     FXJSE_HVALUE argValue = 0;
837     for (int32_t i = 0; i < argc; i++) {
838       argValue = args.GetValue(i);
839       if (FXJSE_Value_IsNull(argValue)) {
840         FXJSE_Value_Release(argValue);
841         continue;
842       } else if (FXJSE_Value_IsArray(argValue)) {
843         FXJSE_HVALUE lengthValue = FXJSE_Value_Create(hruntime);
844         FXJSE_Value_GetObjectProp(argValue, "length", lengthValue);
845         int32_t iLength = FXJSE_Value_ToInteger(lengthValue);
846         FXJSE_Value_Release(lengthValue);
847         if (iLength > 2) {
848           FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
849           FXJSE_Value_GetObjectPropByIdx(argValue, 1, propertyValue);
850           FXJSE_HVALUE jsObjectValue = FXJSE_Value_Create(hruntime);
851           FXJSE_HVALUE newPropertyValue = FXJSE_Value_Create(hruntime);
852           if (FXJSE_Value_IsNull(propertyValue)) {
853             for (int32_t j = 2; j < iLength; j++) {
854               FXJSE_Value_GetObjectPropByIdx(argValue, j, jsObjectValue);
855               GetObjectDefaultValue(jsObjectValue, newPropertyValue);
856               if (!FXJSE_Value_IsNull(newPropertyValue)) {
857                 dSum += HValueToDouble(hThis, jsObjectValue);
858                 uCount++;
859               }
860             }
861           } else {
862             CFX_ByteString propertyStr;
863             FXJSE_Value_ToUTF8String(propertyValue, propertyStr);
864             for (int32_t j = 2; j < iLength; j++) {
865               FXJSE_Value_GetObjectPropByIdx(argValue, j, jsObjectValue);
866               FXJSE_Value_GetObjectProp(jsObjectValue, propertyStr,
867                                         newPropertyValue);
868               if (!FXJSE_Value_IsNull(newPropertyValue)) {
869                 dSum += HValueToDouble(hThis, newPropertyValue);
870                 uCount++;
871               }
872             }
873           }
874           FXJSE_Value_Release(newPropertyValue);
875           FXJSE_Value_Release(jsObjectValue);
876           FXJSE_Value_Release(propertyValue);
877         } else {
878           pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
879         }
880       } else if (FXJSE_Value_IsObject(argValue)) {
881         FXJSE_HVALUE newPropertyValue = FXJSE_Value_Create(hruntime);
882         GetObjectDefaultValue(argValue, newPropertyValue);
883         if (!FXJSE_Value_IsNull(newPropertyValue)) {
884           dSum += HValueToDouble(hThis, argValue);
885           uCount++;
886         }
887         FXJSE_Value_Release(newPropertyValue);
888       } else {
889         dSum += HValueToDouble(hThis, argValue);
890         uCount++;
891       }
892       FXJSE_Value_Release(argValue);
893     }
894     argValue = 0;
895   }
896   if (uCount < 1) {
897     FXJSE_Value_SetNull(args.GetReturnValue());
898   } else {
899     FXJSE_Value_SetDouble(args.GetReturnValue(), dSum);
900   }
901 }
Date(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)902 void CXFA_FM2JSContext::Date(FXJSE_HOBJECT hThis,
903                              const CFX_ByteStringC& szFuncName,
904                              CFXJSE_Arguments& args) {
905   if (args.GetLength() == 0) {
906     struct tm* pTmStruct = 0;
907     time_t currentTime;
908     time(&currentTime);
909     pTmStruct = gmtime(&currentTime);
910     CFX_ByteString bufferYear;
911     CFX_ByteString bufferMon;
912     CFX_ByteString bufferDay;
913     bufferYear.Format("%d", pTmStruct->tm_year + 1900);
914     bufferMon.Format("%02d", pTmStruct->tm_mon + 1);
915     bufferDay.Format("%02d", pTmStruct->tm_mday);
916     CFX_ByteString bufferCurrent = bufferYear + bufferMon + bufferDay;
917     int32_t dDays = DateString2Num(bufferCurrent);
918     FXJSE_Value_SetInteger(args.GetReturnValue(), dDays);
919   } else {
920     CXFA_FM2JSContext* pContext =
921         (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
922     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
923                                       L"Date");
924   }
925 }
Date2Num(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)926 void CXFA_FM2JSContext::Date2Num(FXJSE_HOBJECT hThis,
927                                  const CFX_ByteStringC& szFuncName,
928                                  CFXJSE_Arguments& args) {
929   int32_t argc = args.GetLength();
930   if ((argc > 0) && (argc < 4)) {
931     FX_BOOL bFlags = FALSE;
932     CFX_ByteString dateString;
933     CFX_ByteString formatString;
934     CFX_ByteString localString;
935     FXJSE_HVALUE dateValue = GetSimpleHValue(hThis, args, 0);
936     FXJSE_HVALUE formatValue = 0;
937     FXJSE_HVALUE localValue = 0;
938     if (HValueIsNull(hThis, dateValue)) {
939       bFlags = TRUE;
940     } else {
941       HValueToUTF8String(dateValue, dateString);
942     }
943     if (argc > 1) {
944       formatValue = GetSimpleHValue(hThis, args, 1);
945       if (HValueIsNull(hThis, formatValue)) {
946         bFlags = TRUE;
947       } else {
948         HValueToUTF8String(formatValue, formatString);
949       }
950     }
951     if (argc == 3) {
952       localValue = GetSimpleHValue(hThis, args, 2);
953       if (HValueIsNull(hThis, localValue)) {
954         bFlags = TRUE;
955       } else {
956         HValueToUTF8String(localValue, localString);
957       }
958     }
959     if (!bFlags) {
960       CFX_ByteString szIsoDateString;
961       FX_BOOL bRet = Local2IsoDate(hThis, dateString, formatString, localString,
962                                    szIsoDateString);
963       if (bRet) {
964         FXJSE_Value_SetInteger(args.GetReturnValue(),
965                                DateString2Num(szIsoDateString));
966       } else {
967         FXJSE_Value_SetInteger(args.GetReturnValue(), 0);
968       }
969     } else {
970       FXJSE_Value_SetNull(args.GetReturnValue());
971     }
972     FXJSE_Value_Release(dateValue);
973     if (argc > 1) {
974       FXJSE_Value_Release(formatValue);
975       if (argc == 3) {
976         FXJSE_Value_Release(localValue);
977       }
978     }
979   } else {
980     CXFA_FM2JSContext* pContext =
981         (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
982     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
983                                       L"Date2Num");
984   }
985 }
DateFmt(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)986 void CXFA_FM2JSContext::DateFmt(FXJSE_HOBJECT hThis,
987                                 const CFX_ByteStringC& szFuncName,
988                                 CFXJSE_Arguments& args) {
989   int32_t argc = args.GetLength();
990   if (argc < 3) {
991     FX_BOOL bFlags = FALSE;
992     int32_t iStyle = 0;
993     CFX_ByteString szLocal;
994     FXJSE_HVALUE argStyle = 0;
995     FXJSE_HVALUE argLocal = 0;
996     if (argc > 0) {
997       argStyle = GetSimpleHValue(hThis, args, 0);
998       if (FXJSE_Value_IsNull(argStyle)) {
999         bFlags = TRUE;
1000       }
1001       iStyle = (int32_t)HValueToFloat(hThis, argStyle);
1002       if (iStyle > 4 || iStyle < 0) {
1003         iStyle = 0;
1004       }
1005     }
1006     if (argc == 2) {
1007       argLocal = GetSimpleHValue(hThis, args, 1);
1008       if (FXJSE_Value_IsNull(argLocal)) {
1009         bFlags = TRUE;
1010       } else {
1011         HValueToUTF8String(argLocal, szLocal);
1012       }
1013     }
1014     if (!bFlags) {
1015       CFX_ByteString formatStr;
1016       GetStandardDateFormat(hThis, iStyle, szLocal, formatStr);
1017       if (formatStr.IsEmpty()) {
1018         formatStr = "";
1019       }
1020       FXJSE_Value_SetUTF8String(args.GetReturnValue(), formatStr);
1021     } else {
1022       FXJSE_Value_SetNull(args.GetReturnValue());
1023     }
1024     if (argc > 0) {
1025       FXJSE_Value_Release(argStyle);
1026       if (argc == 2) {
1027         FXJSE_Value_Release(argLocal);
1028       }
1029     }
1030   } else {
1031     CXFA_FM2JSContext* pContext =
1032         (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
1033     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
1034                                       L"Date2Num");
1035   }
1036 }
IsoDate2Num(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)1037 void CXFA_FM2JSContext::IsoDate2Num(FXJSE_HOBJECT hThis,
1038                                     const CFX_ByteStringC& szFuncName,
1039                                     CFXJSE_Arguments& args) {
1040   if (args.GetLength() == 1) {
1041     FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
1042     if (FXJSE_Value_IsNull(argOne)) {
1043       FXJSE_Value_SetNull(args.GetReturnValue());
1044     } else {
1045       CFX_ByteString szArgString;
1046       HValueToUTF8String(argOne, szArgString);
1047       int32_t dDays = DateString2Num(szArgString);
1048       FXJSE_Value_SetInteger(args.GetReturnValue(), (int32_t)dDays);
1049     }
1050     FXJSE_Value_Release(argOne);
1051   } else {
1052     CXFA_FM2JSContext* pContext =
1053         (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
1054     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
1055                                       L"IsoDate2Num");
1056   }
1057 }
IsoTime2Num(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)1058 void CXFA_FM2JSContext::IsoTime2Num(FXJSE_HOBJECT hThis,
1059                                     const CFX_ByteStringC& szFuncName,
1060                                     CFXJSE_Arguments& args) {
1061   CXFA_FM2JSContext* pContext =
1062       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
1063   if (args.GetLength() == 1) {
1064     FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
1065     if (HValueIsNull(hThis, argOne)) {
1066       FXJSE_Value_SetNull(args.GetReturnValue());
1067     } else {
1068       CXFA_Document* pDoc = pContext->GetDocument();
1069       FXSYS_assert(pDoc);
1070       IFX_LocaleMgr* pMgr = (IFX_LocaleMgr*)pDoc->GetLocalMgr();
1071       CFX_ByteString szArgString;
1072       HValueToUTF8String(argOne, szArgString);
1073       szArgString = szArgString.Mid(szArgString.Find('T', 0) + 1);
1074       if (szArgString.IsEmpty()) {
1075         FXJSE_Value_SetInteger(args.GetReturnValue(), 0);
1076         FXJSE_Value_Release(argOne);
1077         return;
1078       }
1079       CXFA_LocaleValue timeValue(
1080           XFA_VT_TIME,
1081           CFX_WideString::FromUTF8(szArgString, szArgString.GetLength()),
1082           (CXFA_LocaleMgr*)pMgr);
1083       if (timeValue.IsValid()) {
1084         CFX_Unitime uniTime = timeValue.GetTime();
1085         int32_t hour = uniTime.GetHour();
1086         int32_t min = uniTime.GetMinute();
1087         int32_t second = uniTime.GetSecond();
1088         int32_t milSecond = uniTime.GetMillisecond();
1089         IFX_Locale* pDefLocale = pMgr->GetDefLocale();
1090         FXSYS_assert(pDefLocale);
1091         FX_TIMEZONE tzLocale;
1092         pDefLocale->GetTimeZone(tzLocale);
1093         int32_t mins = hour * 60 + min;
1094         mins -= (tzLocale.tzHour * 60);
1095         while (mins > 1440) {
1096           mins -= 1440;
1097         }
1098         while (mins < 0) {
1099           mins += 1440;
1100         }
1101         hour = mins / 60;
1102         min = mins % 60;
1103         int32_t iResult =
1104             hour * 3600000 + min * 60000 + second * 1000 + milSecond + 1;
1105         FXJSE_Value_SetInteger(args.GetReturnValue(), iResult);
1106       } else {
1107         FXJSE_Value_SetInteger(args.GetReturnValue(), 0);
1108       }
1109     }
1110     FXJSE_Value_Release(argOne);
1111   } else {
1112     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
1113                                       L"IsoTime2Num");
1114   }
1115 }
LocalDateFmt(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)1116 void CXFA_FM2JSContext::LocalDateFmt(FXJSE_HOBJECT hThis,
1117                                      const CFX_ByteStringC& szFuncName,
1118                                      CFXJSE_Arguments& args) {
1119   int32_t argc = args.GetLength();
1120   if (argc < 3) {
1121     FX_BOOL bFlags = FALSE;
1122     int32_t iStyle = 0;
1123     CFX_ByteString szLocal;
1124     FXJSE_HVALUE argStyle = 0;
1125     FXJSE_HVALUE argLocal = 0;
1126     if (argc > 0) {
1127       argStyle = GetSimpleHValue(hThis, args, 0);
1128       if (FXJSE_Value_IsNull(argStyle)) {
1129         bFlags = TRUE;
1130       }
1131       iStyle = (int32_t)HValueToFloat(hThis, argStyle);
1132       if (iStyle > 4 || iStyle < 0) {
1133         iStyle = 0;
1134       }
1135     }
1136     if (argc == 2) {
1137       argLocal = GetSimpleHValue(hThis, args, 1);
1138       if (FXJSE_Value_IsNull(argLocal)) {
1139         bFlags = TRUE;
1140       } else {
1141         HValueToUTF8String(argLocal, szLocal);
1142       }
1143     }
1144     if (!bFlags) {
1145       CFX_ByteString formatStr;
1146       GetLocalDateFormat(hThis, iStyle, szLocal, formatStr, FALSE);
1147       if (formatStr.IsEmpty()) {
1148         formatStr = "";
1149       }
1150       FXJSE_Value_SetUTF8String(args.GetReturnValue(), formatStr);
1151     } else {
1152       FXJSE_Value_SetNull(args.GetReturnValue());
1153     }
1154     if (argc > 0) {
1155       FXJSE_Value_Release(argStyle);
1156       if (argc == 2) {
1157         FXJSE_Value_Release(argLocal);
1158       }
1159     }
1160   } else {
1161     CXFA_FM2JSContext* pContext =
1162         (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
1163     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
1164                                       L"LocalDateFmt");
1165   }
1166 }
LocalTimeFmt(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)1167 void CXFA_FM2JSContext::LocalTimeFmt(FXJSE_HOBJECT hThis,
1168                                      const CFX_ByteStringC& szFuncName,
1169                                      CFXJSE_Arguments& args) {
1170   int32_t argc = args.GetLength();
1171   if (argc < 3) {
1172     FX_BOOL bFlags = FALSE;
1173     int32_t iStyle = 0;
1174     CFX_ByteString szLocal;
1175     FXJSE_HVALUE argStyle = 0;
1176     FXJSE_HVALUE argLocal = 0;
1177     if (argc > 0) {
1178       argStyle = GetSimpleHValue(hThis, args, 0);
1179       if (FXJSE_Value_IsNull(argStyle)) {
1180         bFlags = TRUE;
1181       }
1182       iStyle = (int32_t)HValueToFloat(hThis, argStyle);
1183       if (iStyle > 4 || iStyle < 0) {
1184         iStyle = 0;
1185       }
1186     }
1187     if (argc == 2) {
1188       argLocal = GetSimpleHValue(hThis, args, 1);
1189       if (FXJSE_Value_IsNull(argLocal)) {
1190         bFlags = TRUE;
1191       } else {
1192         HValueToUTF8String(argLocal, szLocal);
1193       }
1194     }
1195     if (!bFlags) {
1196       CFX_ByteString formatStr;
1197       GetLocalTimeFormat(hThis, iStyle, szLocal, formatStr, FALSE);
1198       if (formatStr.IsEmpty()) {
1199         formatStr = "";
1200       }
1201       FXJSE_Value_SetUTF8String(args.GetReturnValue(), formatStr);
1202     } else {
1203       FXJSE_Value_SetNull(args.GetReturnValue());
1204     }
1205     if (argc > 0) {
1206       FXJSE_Value_Release(argStyle);
1207       if (argc == 2) {
1208         FXJSE_Value_Release(argLocal);
1209       }
1210     }
1211   } else {
1212     CXFA_FM2JSContext* pContext =
1213         (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
1214     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
1215                                       L"LocalTimeFmt");
1216   }
1217 }
Num2Date(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)1218 void CXFA_FM2JSContext::Num2Date(FXJSE_HOBJECT hThis,
1219                                  const CFX_ByteStringC& szFuncName,
1220                                  CFXJSE_Arguments& args) {
1221   int32_t argc = args.GetLength();
1222   if ((argc > 0) && (argc < 4)) {
1223     FX_BOOL bFlags = FALSE;
1224     int32_t dDate;
1225     CFX_ByteString formatString;
1226     CFX_ByteString localString;
1227     FXJSE_HVALUE dateValue = GetSimpleHValue(hThis, args, 0);
1228     FXJSE_HVALUE formatValue = 0;
1229     FXJSE_HVALUE localValue = 0;
1230     if (HValueIsNull(hThis, dateValue)) {
1231       bFlags = TRUE;
1232     } else {
1233       dDate = (int32_t)HValueToFloat(hThis, dateValue);
1234       bFlags = dDate < 1;
1235     }
1236     if (argc > 1) {
1237       formatValue = GetSimpleHValue(hThis, args, 1);
1238       if (HValueIsNull(hThis, formatValue)) {
1239         bFlags = TRUE;
1240       } else {
1241         HValueToUTF8String(formatValue, formatString);
1242       }
1243     }
1244     if (argc == 3) {
1245       localValue = GetSimpleHValue(hThis, args, 2);
1246       if (HValueIsNull(hThis, localValue)) {
1247         bFlags = TRUE;
1248       } else {
1249         HValueToUTF8String(localValue, localString);
1250       }
1251     }
1252     if (!bFlags) {
1253       int32_t iYear = 1900;
1254       int32_t iMonth = 1;
1255       int32_t iDay = 1;
1256       int32_t i = 0;
1257       while (dDate > 0) {
1258         if (iMonth == 2) {
1259           if ((!((iYear + i) % 4) && ((iYear + i) % 100)) ||
1260               !((iYear + i) % 400)) {
1261             if (dDate > 29) {
1262               ++iMonth;
1263               if (iMonth > 12) {
1264                 iMonth = 1;
1265                 ++i;
1266               }
1267               iDay = 1;
1268               dDate -= 29;
1269             } else {
1270               iDay += static_cast<int32_t>(dDate) - 1;
1271               dDate = 0;
1272             }
1273           } else {
1274             if (dDate > 28) {
1275               ++iMonth;
1276               if (iMonth > 12) {
1277                 iMonth = 1;
1278                 ++i;
1279               }
1280               iDay = 1;
1281               dDate -= 28;
1282             } else {
1283               iDay += static_cast<int32_t>(dDate) - 1;
1284               dDate = 0;
1285             }
1286           }
1287         } else if (iMonth < 8) {
1288           if ((iMonth % 2 == 0)) {
1289             if (dDate > 30) {
1290               ++iMonth;
1291               if (iMonth > 12) {
1292                 iMonth = 1;
1293                 ++i;
1294               }
1295               iDay = 1;
1296               dDate -= 30;
1297             } else {
1298               iDay += static_cast<int32_t>(dDate) - 1;
1299               dDate = 0;
1300             }
1301           } else {
1302             if (dDate > 31) {
1303               ++iMonth;
1304               if (iMonth > 12) {
1305                 iMonth = 1;
1306                 ++i;
1307               }
1308               iDay = 1;
1309               dDate -= 31;
1310             } else {
1311               iDay += static_cast<int32_t>(dDate) - 1;
1312               dDate = 0;
1313             }
1314           }
1315         } else {
1316           if (iMonth % 2 != 0) {
1317             if (dDate > 30) {
1318               ++iMonth;
1319               if (iMonth > 12) {
1320                 iMonth = 1;
1321                 ++i;
1322               }
1323               iDay = 1;
1324               dDate -= 30;
1325             } else {
1326               iDay += static_cast<int32_t>(dDate) - 1;
1327               dDate = 0;
1328             }
1329           } else {
1330             if (dDate > 31) {
1331               ++iMonth;
1332               if (iMonth > 12) {
1333                 iMonth = 1;
1334                 ++i;
1335               }
1336               iDay = 1;
1337               dDate -= 31;
1338             } else {
1339               iDay += static_cast<int32_t>(dDate) - 1;
1340               dDate = 0;
1341             }
1342           }
1343         }
1344       }
1345       CFX_ByteString szIsoDateString;
1346       szIsoDateString.Format("%d%02d%02d", iYear + i, iMonth, iDay);
1347       CFX_ByteString szLocalDateString;
1348       IsoDate2Local(hThis, szIsoDateString, formatString,
1349                     localString, szLocalDateString);
1350       if (szLocalDateString.IsEmpty()) {
1351         szLocalDateString = "";
1352       }
1353       FXJSE_Value_SetUTF8String(args.GetReturnValue(), szLocalDateString);
1354     } else {
1355       FXJSE_Value_SetNull(args.GetReturnValue());
1356     }
1357     FXJSE_Value_Release(dateValue);
1358     if (argc > 1) {
1359       FXJSE_Value_Release(formatValue);
1360       if (argc == 3) {
1361         FXJSE_Value_Release(localValue);
1362       }
1363     }
1364   } else {
1365     CXFA_FM2JSContext* pContext =
1366         (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
1367     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
1368                                       L"Num2Date");
1369   }
1370 }
Num2GMTime(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)1371 void CXFA_FM2JSContext::Num2GMTime(FXJSE_HOBJECT hThis,
1372                                    const CFX_ByteStringC& szFuncName,
1373                                    CFXJSE_Arguments& args) {
1374   int32_t argc = args.GetLength();
1375   if ((argc > 0) && (argc < 4)) {
1376     FX_BOOL bFlags = FALSE;
1377     int32_t iTime;
1378     CFX_ByteString formatString;
1379     CFX_ByteString localString;
1380     FXJSE_HVALUE timeValue = GetSimpleHValue(hThis, args, 0);
1381     FXJSE_HVALUE formatValue = 0;
1382     FXJSE_HVALUE localValue = 0;
1383     if (FXJSE_Value_IsNull(timeValue)) {
1384       bFlags = TRUE;
1385     } else {
1386       iTime = (int32_t)HValueToFloat(hThis, timeValue);
1387       if (FXSYS_abs(iTime) < 1.0) {
1388         bFlags = TRUE;
1389       }
1390     }
1391     if (argc > 1) {
1392       formatValue = GetSimpleHValue(hThis, args, 1);
1393       if (FXJSE_Value_IsNull(formatValue)) {
1394         bFlags = TRUE;
1395       } else {
1396         HValueToUTF8String(formatValue, formatString);
1397       }
1398     }
1399     if (argc == 3) {
1400       localValue = GetSimpleHValue(hThis, args, 2);
1401       if (FXJSE_Value_IsNull(localValue)) {
1402         bFlags = TRUE;
1403       } else {
1404         HValueToUTF8String(localValue, localString);
1405       }
1406     }
1407     if (!bFlags) {
1408       CFX_ByteString szGMTTimeString;
1409       Num2AllTime(hThis, iTime, formatString, localString, TRUE,
1410                   szGMTTimeString);
1411       if (szGMTTimeString.IsEmpty()) {
1412         szGMTTimeString = "";
1413       }
1414       FXJSE_Value_SetUTF8String(args.GetReturnValue(), szGMTTimeString);
1415     } else {
1416       FXJSE_Value_SetNull(args.GetReturnValue());
1417     }
1418     FXJSE_Value_Release(timeValue);
1419     if (argc > 1) {
1420       FXJSE_Value_Release(formatValue);
1421       if (argc == 3) {
1422         FXJSE_Value_Release(localValue);
1423       }
1424     }
1425   } else {
1426     CXFA_FM2JSContext* pContext =
1427         (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
1428     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
1429                                       L"Num2GMTime");
1430   }
1431 }
Num2Time(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)1432 void CXFA_FM2JSContext::Num2Time(FXJSE_HOBJECT hThis,
1433                                  const CFX_ByteStringC& szFuncName,
1434                                  CFXJSE_Arguments& args) {
1435   int32_t argc = args.GetLength();
1436   if ((argc > 0) && (argc < 4)) {
1437     FX_BOOL bFlags = FALSE;
1438     FX_FLOAT fTime;
1439     CFX_ByteString formatString;
1440     CFX_ByteString localString;
1441     FXJSE_HVALUE timeValue = GetSimpleHValue(hThis, args, 0);
1442     FXJSE_HVALUE formatValue = 0;
1443     FXJSE_HVALUE localValue = 0;
1444     if (FXJSE_Value_IsNull(timeValue)) {
1445       bFlags = TRUE;
1446     } else {
1447       fTime = HValueToFloat(hThis, timeValue);
1448       if (FXSYS_fabs(fTime) < 1.0) {
1449         bFlags = TRUE;
1450       }
1451     }
1452     if (argc > 1) {
1453       formatValue = GetSimpleHValue(hThis, args, 1);
1454       if (FXJSE_Value_IsNull(formatValue)) {
1455         bFlags = TRUE;
1456       } else {
1457         HValueToUTF8String(formatValue, formatString);
1458       }
1459     }
1460     if (argc == 3) {
1461       localValue = GetSimpleHValue(hThis, args, 2);
1462       if (FXJSE_Value_IsNull(localValue)) {
1463         bFlags = TRUE;
1464       } else {
1465         HValueToUTF8String(localValue, localString);
1466       }
1467     }
1468     if (!bFlags) {
1469       CFX_ByteString szLocalTimeString;
1470       Num2AllTime(hThis, (int32_t)fTime, formatString, localString, FALSE,
1471                   szLocalTimeString);
1472       if (szLocalTimeString.IsEmpty()) {
1473         szLocalTimeString = "";
1474       }
1475       FXJSE_Value_SetUTF8String(args.GetReturnValue(), szLocalTimeString);
1476     } else {
1477       FXJSE_Value_SetNull(args.GetReturnValue());
1478     }
1479     FXJSE_Value_Release(timeValue);
1480     if (argc > 1) {
1481       FXJSE_Value_Release(formatValue);
1482       if (argc == 3) {
1483         FXJSE_Value_Release(localValue);
1484       }
1485     }
1486   } else {
1487     CXFA_FM2JSContext* pContext =
1488         (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
1489     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
1490                                       L"Num2Time");
1491   }
1492 }
Time(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)1493 void CXFA_FM2JSContext::Time(FXJSE_HOBJECT hThis,
1494                              const CFX_ByteStringC& szFuncName,
1495                              CFXJSE_Arguments& args) {
1496   if (args.GetLength() == 0) {
1497     time_t now;
1498     time(&now);
1499     struct tm* pGmt = gmtime(&now);
1500     int32_t iGMHour = pGmt->tm_hour;
1501     int32_t iGMMin = pGmt->tm_min;
1502     int32_t iGMSec = pGmt->tm_sec;
1503     FXJSE_Value_SetInteger(args.GetReturnValue(),
1504                            ((iGMHour * 3600 + iGMMin * 60 + iGMSec) * 1000));
1505   } else {
1506     CXFA_FM2JSContext* pContext =
1507         (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
1508     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
1509                                       L"Time");
1510   }
1511 }
Time2Num(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)1512 void CXFA_FM2JSContext::Time2Num(FXJSE_HOBJECT hThis,
1513                                  const CFX_ByteStringC& szFuncName,
1514                                  CFXJSE_Arguments& args) {
1515   int32_t argc = args.GetLength();
1516   if ((argc > 0) && (argc < 4)) {
1517     FX_BOOL bFlags = FALSE;
1518     CFX_ByteString timeString;
1519     CFX_ByteString formatString;
1520     CFX_ByteString localString;
1521     FXJSE_HVALUE timeValue = GetSimpleHValue(hThis, args, 0);
1522     FXJSE_HVALUE formatValue = 0;
1523     FXJSE_HVALUE localValue = 0;
1524     if (HValueIsNull(hThis, timeValue)) {
1525       bFlags = TRUE;
1526     } else {
1527       HValueToUTF8String(timeValue, timeString);
1528     }
1529     if (argc > 1) {
1530       formatValue = GetSimpleHValue(hThis, args, 1);
1531       if (HValueIsNull(hThis, formatValue)) {
1532         bFlags = TRUE;
1533       } else {
1534         HValueToUTF8String(formatValue, formatString);
1535       }
1536     }
1537     if (argc == 3) {
1538       localValue = GetSimpleHValue(hThis, args, 2);
1539       if (HValueIsNull(hThis, localValue)) {
1540         bFlags = TRUE;
1541       } else {
1542         HValueToUTF8String(localValue, localString);
1543       }
1544     }
1545     if (!bFlags) {
1546       CXFA_FM2JSContext* pContext =
1547           (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
1548       CXFA_Document* pDoc = pContext->GetDocument();
1549       IFX_LocaleMgr* pMgr = (IFX_LocaleMgr*)pDoc->GetLocalMgr();
1550       IFX_Locale* pLocale = NULL;
1551       if (localString.IsEmpty()) {
1552         CXFA_Object* pThisNode = pDoc->GetScriptContext()->GetThisObject();
1553         FXSYS_assert(pThisNode->IsNode());
1554         CXFA_WidgetData widgetData((CXFA_Node*)pThisNode);
1555         pLocale = widgetData.GetLocal();
1556       } else {
1557         pLocale = pMgr->GetLocaleByName(
1558             CFX_WideString::FromUTF8(localString, localString.GetLength()));
1559       }
1560       CFX_WideString wsFormat;
1561       if (formatString.IsEmpty()) {
1562         pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Default, wsFormat);
1563       } else {
1564         wsFormat =
1565             CFX_WideString::FromUTF8(formatString, formatString.GetLength());
1566       }
1567       wsFormat = FX_WSTRC(L"time{") + wsFormat;
1568       wsFormat += FX_WSTRC(L"}");
1569       CXFA_LocaleValue timeValue(
1570           XFA_VT_TIME,
1571           CFX_WideString::FromUTF8(timeString, timeString.GetLength()),
1572           wsFormat, pLocale, (CXFA_LocaleMgr*)pMgr);
1573       if (timeValue.IsValid()) {
1574         CFX_Unitime uniTime = timeValue.GetTime();
1575         int32_t hour = uniTime.GetHour();
1576         int32_t min = uniTime.GetMinute();
1577         int32_t second = uniTime.GetSecond();
1578         int32_t milSecond = uniTime.GetMillisecond();
1579         int32_t mins = hour * 60 + min;
1580         IXFA_TimeZoneProvider* pProvider = IXFA_TimeZoneProvider::Get();
1581         if (pProvider != NULL) {
1582           FX_TIMEZONE tz;
1583           pProvider->GetTimeZone(tz);
1584           mins -= (tz.tzHour * 60);
1585           while (mins > 1440) {
1586             mins -= 1440;
1587           }
1588           while (mins < 0) {
1589             mins += 1440;
1590           }
1591           hour = mins / 60;
1592           min = mins % 60;
1593         }
1594         int32_t iResult =
1595             hour * 3600000 + min * 60000 + second * 1000 + milSecond + 1;
1596         FXJSE_Value_SetInteger(args.GetReturnValue(), iResult);
1597       } else {
1598         FXJSE_Value_SetInteger(args.GetReturnValue(), 0);
1599       }
1600     } else {
1601       FXJSE_Value_SetNull(args.GetReturnValue());
1602     }
1603     FXJSE_Value_Release(timeValue);
1604     if (argc > 1) {
1605       FXJSE_Value_Release(formatValue);
1606       if (argc == 3) {
1607         FXJSE_Value_Release(localValue);
1608       }
1609     }
1610   } else {
1611     CXFA_FM2JSContext* pContext =
1612         (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
1613     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
1614                                       L"Time2Num");
1615   }
1616 }
TimeFmt(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)1617 void CXFA_FM2JSContext::TimeFmt(FXJSE_HOBJECT hThis,
1618                                 const CFX_ByteStringC& szFuncName,
1619                                 CFXJSE_Arguments& args) {
1620   int32_t argc = args.GetLength();
1621   if (argc < 3) {
1622     FX_BOOL bFlags = FALSE;
1623     int32_t iStyle = 0;
1624     CFX_ByteString szLocal;
1625     FXJSE_HVALUE argStyle = 0;
1626     FXJSE_HVALUE argLocal = 0;
1627     if (argc > 0) {
1628       argStyle = GetSimpleHValue(hThis, args, 0);
1629       if (FXJSE_Value_IsNull(argStyle)) {
1630         bFlags = TRUE;
1631       }
1632       iStyle = (int32_t)HValueToFloat(hThis, argStyle);
1633       if (iStyle > 4 || iStyle < 0) {
1634         iStyle = 0;
1635       }
1636     }
1637     if (argc == 2) {
1638       argLocal = GetSimpleHValue(hThis, args, 1);
1639       if (FXJSE_Value_IsNull(argLocal)) {
1640         bFlags = TRUE;
1641       } else {
1642         HValueToUTF8String(argLocal, szLocal);
1643       }
1644     }
1645     if (!bFlags) {
1646       CFX_ByteString formatStr;
1647       GetStandardTimeFormat(hThis, iStyle, szLocal, formatStr);
1648       if (formatStr.IsEmpty()) {
1649         formatStr = "";
1650       }
1651       FXJSE_Value_SetUTF8String(args.GetReturnValue(), formatStr);
1652     } else {
1653       FXJSE_Value_SetNull(args.GetReturnValue());
1654     }
1655     if (argc > 0) {
1656       FXJSE_Value_Release(argStyle);
1657       if (argc == 2) {
1658         FXJSE_Value_Release(argLocal);
1659       }
1660     }
1661   } else {
1662     CXFA_FM2JSContext* pContext =
1663         (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
1664     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
1665                                       L"TimeFmt");
1666   }
1667 }
IsIsoDateFormat(const FX_CHAR * pData,int32_t iLength,int32_t & iStyle,int32_t & iYear,int32_t & iMonth,int32_t & iDay)1668 FX_BOOL CXFA_FM2JSContext::IsIsoDateFormat(const FX_CHAR* pData,
1669                                            int32_t iLength,
1670                                            int32_t& iStyle,
1671                                            int32_t& iYear,
1672                                            int32_t& iMonth,
1673                                            int32_t& iDay) {
1674   iYear = 0;
1675   iMonth = 1;
1676   iDay = 1;
1677   FX_BOOL iRet = FALSE;
1678   if (iLength < 4) {
1679     return iRet;
1680   }
1681   FX_CHAR strYear[5];
1682   strYear[4] = '\0';
1683   for (int32_t i = 0; i < 4; ++i) {
1684     if (*(pData + i) <= '9' && *(pData + i) >= '0') {
1685       strYear[i] = *(pData + i);
1686     } else {
1687       return iRet;
1688     }
1689   }
1690   iYear = FXSYS_atoi(strYear);
1691   iStyle = 0;
1692   if (iLength > 4) {
1693     if (*(pData + 4) == '-') {
1694       iStyle = 1;
1695     } else {
1696       iStyle = 0;
1697     }
1698   } else {
1699     iRet = TRUE;
1700     return iRet;
1701   }
1702   FX_CHAR strTemp[3];
1703   strTemp[2] = '\0';
1704   int32_t iPosOff = 0;
1705   if (iStyle == 0) {
1706     iPosOff = 4;
1707     if (iLength == 4) {
1708       iRet = TRUE;
1709       return iRet;
1710     }
1711   } else {
1712     iPosOff = 5;
1713     if (iLength == 4) {
1714       iRet = TRUE;
1715       return iRet;
1716     }
1717   }
1718   if ((*(pData + iPosOff) > '9' || *(pData + iPosOff) < '0') ||
1719       (*(pData + iPosOff + 1) > '9' || *(pData + iPosOff + 1) < '0')) {
1720     return iRet;
1721   }
1722   strTemp[0] = *(pData + iPosOff);
1723   strTemp[1] = *(pData + iPosOff + 1);
1724   iMonth = FXSYS_atoi(strTemp);
1725   if (iMonth > 12 || iMonth < 1) {
1726     return iRet;
1727   }
1728   if (iStyle == 0) {
1729     iPosOff += 2;
1730     if (iLength == 6) {
1731       iRet = 1;
1732       return iRet;
1733     }
1734   } else {
1735     iPosOff += 3;
1736     if (iLength == 7) {
1737       iRet = 1;
1738       return iRet;
1739     }
1740   }
1741   if ((*(pData + iPosOff) > '9' || *(pData + iPosOff) < '0') ||
1742       (*(pData + iPosOff + 1) > '9' || *(pData + iPosOff + 1) < '0')) {
1743     return iRet;
1744   }
1745   strTemp[0] = *(pData + iPosOff);
1746   strTemp[1] = *(pData + iPosOff + 1);
1747   iDay = FXSYS_atoi(strTemp);
1748   if (iPosOff + 2 < iLength) {
1749     return iRet;
1750   }
1751   if ((!(iYear % 4) && (iYear % 100)) || !(iYear % 400)) {
1752     if (iMonth == 2) {
1753       if (iDay > 29) {
1754         return iRet;
1755       }
1756     } else {
1757       if (iMonth < 8) {
1758         if (iDay > (iMonth % 2 == 0 ? 30 : 31)) {
1759           return iRet;
1760         }
1761       } else {
1762         if (iDay > (iMonth % 2 == 0 ? 31 : 30)) {
1763           return iRet;
1764         }
1765       }
1766     }
1767   } else {
1768     if (iMonth == 2) {
1769       if (iDay > 28) {
1770         return iRet;
1771       }
1772     } else {
1773       if (iMonth < 8) {
1774         if (iDay > (iMonth % 2 == 0 ? 30 : 31)) {
1775           return iRet;
1776         }
1777       } else {
1778         if (iDay > (iMonth % 2 == 0 ? 31 : 30)) {
1779           return iRet;
1780         }
1781       }
1782     }
1783   }
1784   iRet = TRUE;
1785   return iRet;
1786 }
IsIsoTimeFormat(const FX_CHAR * pData,int32_t iLength,int32_t & iHour,int32_t & iMinute,int32_t & iSecond,int32_t & iMilliSecond,int32_t & iZoneHour,int32_t & iZoneMinute)1787 FX_BOOL CXFA_FM2JSContext::IsIsoTimeFormat(const FX_CHAR* pData,
1788                                            int32_t iLength,
1789                                            int32_t& iHour,
1790                                            int32_t& iMinute,
1791                                            int32_t& iSecond,
1792                                            int32_t& iMilliSecond,
1793                                            int32_t& iZoneHour,
1794                                            int32_t& iZoneMinute) {
1795   iHour = 0;
1796   iMinute = 0;
1797   iSecond = 0;
1798   iMilliSecond = 0;
1799   iZoneHour = 0;
1800   iZoneMinute = 0;
1801   if (!pData) {
1802     return FALSE;
1803   }
1804   int32_t iRet = FALSE;
1805   FX_CHAR strTemp[3];
1806   strTemp[2] = '\0';
1807   int32_t iIndex = 0;
1808   int32_t iZone = 0;
1809   int32_t i = iIndex;
1810   while (i < iLength) {
1811     if ((*(pData + i) > '9' || *(pData + i) < '0') && *(pData + i) != ':') {
1812       iZone = i;
1813       break;
1814     }
1815     ++i;
1816   }
1817   if (i == iLength) {
1818     iZone = iLength;
1819   }
1820   int32_t iPos = 0;
1821   while (iIndex < iZone) {
1822     if (iIndex >= iZone) {
1823       break;
1824     }
1825     if (*(pData + iIndex) > '9' || *(pData + iIndex) < '0') {
1826       return iRet;
1827     }
1828     strTemp[0] = *(pData + iIndex);
1829     if (*(pData + iIndex + 1) > '9' || *(pData + iIndex + 1) < '0') {
1830       return iRet;
1831     }
1832     strTemp[1] = *(pData + iIndex + 1);
1833     if (FXSYS_atoi(strTemp) > 60) {
1834       return iRet;
1835     }
1836     if (*(pData + 2) == ':') {
1837       if (iPos == 0) {
1838         iHour = FXSYS_atoi(strTemp);
1839         ++iPos;
1840       } else if (iPos == 1) {
1841         iMinute = FXSYS_atoi(strTemp);
1842         ++iPos;
1843       } else {
1844         iSecond = FXSYS_atoi(strTemp);
1845       }
1846       iIndex += 3;
1847     } else {
1848       if (iPos == 0) {
1849         iHour = FXSYS_atoi(strTemp);
1850         ++iPos;
1851       } else if (iPos == 1) {
1852         iMinute = FXSYS_atoi(strTemp);
1853         ++iPos;
1854       } else if (iPos == 2) {
1855         iSecond = FXSYS_atoi(strTemp);
1856         ++iPos;
1857       }
1858       iIndex += 2;
1859     }
1860   }
1861   if (*(pData + iIndex) == '.') {
1862     ++iIndex;
1863     FX_CHAR strTemp[4];
1864     strTemp[3] = '\0';
1865     if (*(pData + iIndex) > '9' || *(pData + iIndex) < '0') {
1866       return iRet;
1867     }
1868     strTemp[0] = *(pData + iIndex);
1869     if (*(pData + iIndex + 1) > '9' || *(pData + iIndex + 1) < '0') {
1870       return iRet;
1871     }
1872     strTemp[1] = *(pData + iIndex + 1);
1873     if (*(pData + iIndex + 2) > '9' || *(pData + iIndex + 2) < '0') {
1874       return iRet;
1875     }
1876     strTemp[2] = *(pData + iIndex + 2);
1877     iMilliSecond = FXSYS_atoi(strTemp);
1878     if (iMilliSecond > 100) {
1879       iMilliSecond = 0;
1880       return iRet;
1881     }
1882     iIndex += 3;
1883   }
1884   int32_t iSign = 1;
1885   if (*(pData + iIndex) == 'z' || *(pData + iIndex) == 'Z') {
1886     iRet = 1;
1887     return iRet;
1888   } else if (*(pData + iIndex) == '+') {
1889     ++iIndex;
1890   } else if (*(pData + iIndex) == '-') {
1891     iSign = -1;
1892     ++iIndex;
1893   }
1894   iPos = 0;
1895   while (iIndex < iLength) {
1896     if (iIndex >= iLength) {
1897       return iRet;
1898     }
1899     if (*(pData + iIndex) > '9' || *(pData + iIndex) < '0') {
1900       return iRet;
1901     }
1902     strTemp[0] = *(pData + iIndex);
1903     if (*(pData + iIndex + 1) > '9' || *(pData + iIndex + 1) < '0') {
1904       return iRet;
1905     }
1906     strTemp[1] = *(pData + iIndex + 1);
1907     if (FXSYS_atoi(strTemp) > 60) {
1908       return iRet;
1909     }
1910     if (*(pData + 2) == ':') {
1911       if (iPos == 0) {
1912         iZoneHour = FXSYS_atoi(strTemp);
1913       } else if (iPos == 1) {
1914         iZoneMinute = FXSYS_atoi(strTemp);
1915       }
1916       iIndex += 3;
1917     } else {
1918       if (!iPos) {
1919         iZoneHour = FXSYS_atoi(strTemp);
1920         ++iPos;
1921       } else if (iPos == 1) {
1922         iZoneMinute = FXSYS_atoi(strTemp);
1923         ++iPos;
1924       }
1925       iIndex += 2;
1926     }
1927   }
1928   if (iIndex < iLength) {
1929     return iRet;
1930   }
1931   iZoneHour *= iSign;
1932   iRet = TRUE;
1933   return iRet;
1934 }
IsIsoDateTimeFormat(const FX_CHAR * pData,int32_t iLength,int32_t & iYear,int32_t & iMonth,int32_t & iDay,int32_t & iHour,int32_t & iMinute,int32_t & iSecond,int32_t & iMillionSecond,int32_t & iZoneHour,int32_t & iZoneMinute)1935 FX_BOOL CXFA_FM2JSContext::IsIsoDateTimeFormat(const FX_CHAR* pData,
1936                                                int32_t iLength,
1937                                                int32_t& iYear,
1938                                                int32_t& iMonth,
1939                                                int32_t& iDay,
1940                                                int32_t& iHour,
1941                                                int32_t& iMinute,
1942                                                int32_t& iSecond,
1943                                                int32_t& iMillionSecond,
1944                                                int32_t& iZoneHour,
1945                                                int32_t& iZoneMinute) {
1946   iYear = 0;
1947   iMonth = 0;
1948   iDay = 0;
1949   iHour = 0;
1950   iMinute = 0;
1951   iSecond = 0;
1952   if (!pData) {
1953     return FALSE;
1954   }
1955   int32_t iRet = FALSE;
1956   int32_t iIndex = 0;
1957   while (*(pData + iIndex) != 'T' && *(pData + iIndex) != 't') {
1958     if (iIndex >= iLength) {
1959       return iRet;
1960     }
1961     ++iIndex;
1962   }
1963   if (iIndex != 8 && iIndex != 10) {
1964     return iRet;
1965   }
1966   int32_t iStyle = -1;
1967   iRet = IsIsoDateFormat(pData, iIndex, iStyle, iYear, iMonth, iDay);
1968   if (!iRet) {
1969     return iRet;
1970   }
1971   if (*(pData + iIndex) != 'T' && *(pData + iIndex) != 't') {
1972     return iRet;
1973   }
1974   ++iIndex;
1975   if (((iLength - iIndex > 13) && (iLength - iIndex < 6)) &&
1976       (iLength - iIndex != 15)) {
1977     return iRet;
1978   }
1979   iRet = IsIsoTimeFormat(pData + iIndex, iLength - iIndex, iHour, iMinute,
1980                          iSecond, iMillionSecond, iZoneHour, iZoneMinute);
1981   if (!iRet) {
1982     return iRet;
1983   }
1984   iRet = TRUE;
1985   return iRet;
1986 }
Local2IsoDate(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szDate,const CFX_ByteStringC & szFormat,const CFX_ByteStringC & szLocale,CFX_ByteString & strIsoDate)1987 FX_BOOL CXFA_FM2JSContext::Local2IsoDate(FXJSE_HOBJECT hThis,
1988                                          const CFX_ByteStringC& szDate,
1989                                          const CFX_ByteStringC& szFormat,
1990                                          const CFX_ByteStringC& szLocale,
1991                                          CFX_ByteString& strIsoDate) {
1992   CXFA_FM2JSContext* pContext =
1993       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
1994   CXFA_Document* pDoc = pContext->GetDocument();
1995   if (!pDoc) {
1996     return FALSE;
1997   }
1998   IFX_LocaleMgr* pMgr = (IFX_LocaleMgr*)pDoc->GetLocalMgr();
1999   IFX_Locale* pLocale = NULL;
2000   if (szLocale.IsEmpty()) {
2001     CXFA_Object* pThisNode = pDoc->GetScriptContext()->GetThisObject();
2002     FXSYS_assert(pThisNode->IsNode());
2003     CXFA_WidgetData widgetData((CXFA_Node*)pThisNode);
2004     pLocale = widgetData.GetLocal();
2005   } else {
2006     pLocale = pMgr->GetLocaleByName(
2007         CFX_WideString::FromUTF8(szLocale.GetCStr(), szLocale.GetLength()));
2008   }
2009   if (!pLocale) {
2010     return FALSE;
2011   }
2012   CFX_WideString wsFormat;
2013   if (szFormat.IsEmpty()) {
2014     pLocale->GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY_Default, wsFormat);
2015   } else {
2016     wsFormat =
2017         CFX_WideString::FromUTF8(szFormat.GetCStr(), szFormat.GetLength());
2018   }
2019   CXFA_LocaleValue widgetValue(
2020       XFA_VT_DATE,
2021       CFX_WideString::FromUTF8(szDate.GetCStr(), szDate.GetLength()), wsFormat,
2022       pLocale, (CXFA_LocaleMgr*)pMgr);
2023   CFX_Unitime dt = widgetValue.GetDate();
2024   strIsoDate.Format("%4d-%02d-%02d", dt.GetYear(), dt.GetMonth(), dt.GetDay());
2025   return TRUE;
2026 }
Local2IsoTime(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szTime,const CFX_ByteStringC & szFormat,const CFX_ByteStringC & szLocale,CFX_ByteString & strIsoTime)2027 FX_BOOL CXFA_FM2JSContext::Local2IsoTime(FXJSE_HOBJECT hThis,
2028                                          const CFX_ByteStringC& szTime,
2029                                          const CFX_ByteStringC& szFormat,
2030                                          const CFX_ByteStringC& szLocale,
2031                                          CFX_ByteString& strIsoTime) {
2032   CXFA_FM2JSContext* pContext =
2033       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
2034   CXFA_Document* pDoc = pContext->GetDocument();
2035   if (!pDoc) {
2036     return FALSE;
2037   }
2038   IFX_LocaleMgr* pMgr = (IFX_LocaleMgr*)pDoc->GetLocalMgr();
2039   IFX_Locale* pLocale = NULL;
2040   if (szLocale.IsEmpty()) {
2041     CXFA_Object* pThisNode = pDoc->GetScriptContext()->GetThisObject();
2042     FXSYS_assert(pThisNode->IsNode());
2043     CXFA_WidgetData widgetData((CXFA_Node*)pThisNode);
2044     pLocale = widgetData.GetLocal();
2045   } else {
2046     pLocale = pMgr->GetLocaleByName(
2047         CFX_WideString::FromUTF8(szLocale.GetCStr(), szLocale.GetLength()));
2048   }
2049   if (!pLocale) {
2050     return FALSE;
2051   }
2052   CFX_WideString wsFormat;
2053   if (szFormat.IsEmpty()) {
2054     pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Default, wsFormat);
2055   } else {
2056     wsFormat =
2057         CFX_WideString::FromUTF8(szFormat.GetCStr(), szFormat.GetLength());
2058   }
2059   wsFormat = FX_WSTRC(L"time{") + wsFormat;
2060   wsFormat += FX_WSTRC(L"}");
2061   CXFA_LocaleValue widgetValue(
2062       XFA_VT_TIME,
2063       CFX_WideString::FromUTF8(szTime.GetCStr(), szTime.GetLength()), wsFormat,
2064       pLocale, (CXFA_LocaleMgr*)pMgr);
2065   CFX_Unitime utime = widgetValue.GetTime();
2066   strIsoTime.Format("%02d:%02d:%02d.%03d", utime.GetHour(), utime.GetMinute(),
2067                     utime.GetSecond(), utime.GetMillisecond());
2068   return TRUE;
2069 }
IsoDate2Local(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szDate,const CFX_ByteStringC & szFormat,const CFX_ByteStringC & szLocale,CFX_ByteString & strLocalDate)2070 FX_BOOL CXFA_FM2JSContext::IsoDate2Local(FXJSE_HOBJECT hThis,
2071                                          const CFX_ByteStringC& szDate,
2072                                          const CFX_ByteStringC& szFormat,
2073                                          const CFX_ByteStringC& szLocale,
2074                                          CFX_ByteString& strLocalDate) {
2075   CXFA_FM2JSContext* pContext =
2076       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
2077   CXFA_Document* pDoc = pContext->GetDocument();
2078   if (!pDoc) {
2079     return FALSE;
2080   }
2081   IFX_LocaleMgr* pMgr = (IFX_LocaleMgr*)pDoc->GetLocalMgr();
2082   IFX_Locale* pLocale = NULL;
2083   if (szLocale.IsEmpty()) {
2084     CXFA_Object* pThisNode = pDoc->GetScriptContext()->GetThisObject();
2085     FXSYS_assert(pThisNode->IsNode());
2086     CXFA_WidgetData widgetData((CXFA_Node*)pThisNode);
2087     pLocale = widgetData.GetLocal();
2088   } else {
2089     pLocale = pMgr->GetLocaleByName(
2090         CFX_WideString::FromUTF8(szLocale.GetCStr(), szLocale.GetLength()));
2091   }
2092   if (!pLocale) {
2093     return FALSE;
2094   }
2095   CFX_WideString wsFormat;
2096   if (szFormat.IsEmpty()) {
2097     pLocale->GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY_Default, wsFormat);
2098   } else {
2099     wsFormat =
2100         CFX_WideString::FromUTF8(szFormat.GetCStr(), szFormat.GetLength());
2101   }
2102   CXFA_LocaleValue widgetValue(
2103       XFA_VT_DATE,
2104       CFX_WideString::FromUTF8(szDate.GetCStr(), szDate.GetLength()),
2105       (CXFA_LocaleMgr*)pMgr);
2106   CFX_WideString wsRet;
2107   widgetValue.FormatPatterns(wsRet, wsFormat, pLocale,
2108                              XFA_VALUEPICTURE_Display);
2109   strLocalDate = FX_UTF8Encode(wsRet, wsRet.GetLength());
2110   return TRUE;
2111 }
IsoTime2Local(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szTime,const CFX_ByteStringC & szFormat,const CFX_ByteStringC & szLocale,CFX_ByteString & strLocalTime)2112 FX_BOOL CXFA_FM2JSContext::IsoTime2Local(FXJSE_HOBJECT hThis,
2113                                          const CFX_ByteStringC& szTime,
2114                                          const CFX_ByteStringC& szFormat,
2115                                          const CFX_ByteStringC& szLocale,
2116                                          CFX_ByteString& strLocalTime) {
2117   CXFA_FM2JSContext* pContext =
2118       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
2119   CXFA_Document* pDoc = pContext->GetDocument();
2120   if (!pDoc) {
2121     return FALSE;
2122   }
2123   IFX_LocaleMgr* pMgr = (IFX_LocaleMgr*)pDoc->GetLocalMgr();
2124   IFX_Locale* pLocale = NULL;
2125   if (szLocale.IsEmpty()) {
2126     CXFA_Object* pThisNode = pDoc->GetScriptContext()->GetThisObject();
2127     FXSYS_assert(pThisNode->IsNode());
2128     CXFA_WidgetData widgetData((CXFA_Node*)pThisNode);
2129     pLocale = widgetData.GetLocal();
2130   } else {
2131     pLocale = pMgr->GetLocaleByName(
2132         CFX_WideString::FromUTF8(szLocale.GetCStr(), szLocale.GetLength()));
2133   }
2134   if (!pLocale) {
2135     return FALSE;
2136   }
2137   CFX_WideString wsFormat;
2138   if (szFormat.IsEmpty()) {
2139     pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Default, wsFormat);
2140   } else {
2141     wsFormat =
2142         CFX_WideString::FromUTF8(szFormat.GetCStr(), szFormat.GetLength());
2143   }
2144   wsFormat = FX_WSTRC(L"time{") + wsFormat;
2145   wsFormat += FX_WSTRC(L"}");
2146   CXFA_LocaleValue widgetValue(
2147       XFA_VT_TIME,
2148       CFX_WideString::FromUTF8(szTime.GetCStr(), szTime.GetLength()),
2149       (CXFA_LocaleMgr*)pMgr);
2150   CFX_WideString wsRet;
2151   widgetValue.FormatPatterns(wsRet, wsFormat, pLocale,
2152                              XFA_VALUEPICTURE_Display);
2153   strLocalTime = FX_UTF8Encode(wsRet, wsRet.GetLength());
2154   return TRUE;
2155 }
GetGMTTime(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szTime,const CFX_ByteStringC & szFormat,const CFX_ByteStringC & szLocale,CFX_ByteString & strGMTTime)2156 FX_BOOL CXFA_FM2JSContext::GetGMTTime(FXJSE_HOBJECT hThis,
2157                                       const CFX_ByteStringC& szTime,
2158                                       const CFX_ByteStringC& szFormat,
2159                                       const CFX_ByteStringC& szLocale,
2160                                       CFX_ByteString& strGMTTime) {
2161   CXFA_FM2JSContext* pContext =
2162       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
2163   CXFA_Document* pDoc = pContext->GetDocument();
2164   if (!pDoc) {
2165     return FALSE;
2166   }
2167   IFX_LocaleMgr* pMgr = (IFX_LocaleMgr*)pDoc->GetLocalMgr();
2168   IFX_Locale* pLocale = NULL;
2169   if (szLocale.IsEmpty()) {
2170     CXFA_Object* pThisNode = pDoc->GetScriptContext()->GetThisObject();
2171     FXSYS_assert(pThisNode->IsNode());
2172     CXFA_WidgetData widgetData((CXFA_Node*)pThisNode);
2173     pLocale = widgetData.GetLocal();
2174   } else {
2175     pLocale = pMgr->GetLocaleByName(
2176         CFX_WideString::FromUTF8(szLocale.GetCStr(), szLocale.GetLength()));
2177   }
2178   if (!pLocale) {
2179     return FALSE;
2180   }
2181   CFX_WideString wsFormat;
2182   if (szFormat.IsEmpty()) {
2183     pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Default, wsFormat);
2184   } else {
2185     wsFormat =
2186         CFX_WideString::FromUTF8(szFormat.GetCStr(), szFormat.GetLength());
2187   }
2188   wsFormat = FX_WSTRC(L"time{") + wsFormat;
2189   wsFormat += FX_WSTRC(L"}");
2190   CXFA_LocaleValue widgetValue(
2191       XFA_VT_TIME,
2192       CFX_WideString::FromUTF8(szTime.GetCStr(), szTime.GetLength()),
2193       (CXFA_LocaleMgr*)pMgr);
2194   CFX_WideString wsRet;
2195   widgetValue.FormatPatterns(wsRet, wsFormat, pLocale,
2196                              XFA_VALUEPICTURE_Display);
2197   strGMTTime = FX_UTF8Encode(wsRet, wsRet.GetLength());
2198   return TRUE;
2199 }
DateString2Num(const CFX_ByteStringC & szDateString)2200 int32_t CXFA_FM2JSContext::DateString2Num(const CFX_ByteStringC& szDateString) {
2201   FX_BOOL bFlags = FALSE;
2202   int32_t iLength = szDateString.GetLength();
2203   FX_BOOL iRet = FALSE;
2204   int32_t iStyle = -1;
2205   int32_t iYear = 0;
2206   int32_t iMonth = 0;
2207   int32_t iDay = 0;
2208   int32_t iHour = 0;
2209   int32_t iMinute = 0;
2210   int32_t iSecond = 0;
2211   int32_t iMillionSecond = 0;
2212   int32_t iZoneHour = 0;
2213   int32_t iZoneMinute = 0;
2214   if (iLength <= 10) {
2215     iRet = IsIsoDateFormat(szDateString.GetCStr(), iLength, iStyle, iYear,
2216                            iMonth, iDay);
2217   } else {
2218     iRet = IsIsoDateTimeFormat(szDateString.GetCStr(), iLength, iYear, iMonth,
2219                                iDay, iHour, iMinute, iSecond, iMillionSecond,
2220                                iZoneHour, iZoneMinute);
2221   }
2222   if (!iRet) {
2223     bFlags = TRUE;
2224   }
2225   FX_FLOAT dDays = 0;
2226   int32_t i = 1;
2227   if (iYear < 1900) {
2228     bFlags = TRUE;
2229   }
2230   if (!bFlags) {
2231     while (iYear - i >= 1900) {
2232       if ((!((iYear - i) % 4) && ((iYear - i) % 100)) || !((iYear - i) % 400)) {
2233         dDays += 366;
2234       } else {
2235         dDays += 365;
2236       }
2237       ++i;
2238     }
2239     i = 1;
2240     while (i < iMonth) {
2241       if (i == 2) {
2242         if ((!(iYear % 4) && (iYear % 100)) || !(iYear % 400)) {
2243           dDays += 29;
2244         } else {
2245           dDays += 28;
2246         }
2247       } else if (i <= 7) {
2248         if (i % 2 == 0) {
2249           dDays += 30;
2250         } else {
2251           dDays += 31;
2252         }
2253       } else {
2254         if (i % 2 == 0) {
2255           dDays += 31;
2256         } else {
2257           dDays += 30;
2258         }
2259       }
2260       ++i;
2261     }
2262     i = 0;
2263     while (iDay - i > 0) {
2264       dDays += 1;
2265       ++i;
2266     }
2267   } else {
2268     dDays = 0;
2269   }
2270   return (int32_t)dDays;
2271 }
2272 #define XFA_N 19
2273 static uint8_t g_sAltTable_Date[] = {
2274     XFA_N, XFA_N, XFA_N, 3,     9,     XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N,
2275     XFA_N, 2,     XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N,
2276     XFA_N, XFA_N, 1,     XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N,
2277     XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N,
2278     XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N,
2279     XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N,
2280 };
2281 static uint8_t g_sAltTable_Time[] = {
2282     14,    XFA_N, XFA_N, 3,     9,     XFA_N, XFA_N, 15,    XFA_N, XFA_N, XFA_N,
2283     XFA_N, 6,     XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, 7,     XFA_N, XFA_N, XFA_N,
2284     XFA_N, XFA_N, 1,     17,    XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N,
2285     XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, 15,    XFA_N, XFA_N, XFA_N, XFA_N,
2286     XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N,
2287     XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N,
2288 };
XFA_FM_AlternateDateTimeSymbols(CFX_WideString & wsPattern,const CFX_WideString & wsAltSymbols,uint8_t * pAltTable)2289 static void XFA_FM_AlternateDateTimeSymbols(CFX_WideString& wsPattern,
2290                                             const CFX_WideString& wsAltSymbols,
2291                                             uint8_t* pAltTable) {
2292   int32_t nLength = wsPattern.GetLength();
2293   FX_BOOL bInConstRange = FALSE;
2294   FX_BOOL bEscape = FALSE;
2295   int32_t i = 0, n = 0;
2296   while (i < nLength) {
2297     FX_WCHAR wc = wsPattern[i];
2298     if (wc == L'\'') {
2299       bInConstRange = !bInConstRange;
2300       if (bEscape) {
2301         i++;
2302       } else {
2303         wsPattern.Delete(i);
2304         nLength--;
2305       }
2306       bEscape = !bEscape;
2307       continue;
2308     }
2309     if (!bInConstRange && (n = wc - L'A') >= 0 && n <= (L'a' - L'A')) {
2310       int32_t nAlt = (int32_t)pAltTable[n];
2311       if (nAlt != XFA_N) {
2312         wsPattern.SetAt(i, wsAltSymbols[nAlt]);
2313       }
2314     }
2315     i++;
2316     bEscape = FALSE;
2317   }
2318 }
2319 #undef XFA_N
GetLocalDateFormat(FXJSE_HOBJECT hThis,int32_t iStyle,const CFX_ByteStringC & szLocalStr,CFX_ByteString & strFormat,FX_BOOL bStandard)2320 void CXFA_FM2JSContext::GetLocalDateFormat(FXJSE_HOBJECT hThis,
2321                                            int32_t iStyle,
2322                                            const CFX_ByteStringC& szLocalStr,
2323                                            CFX_ByteString& strFormat,
2324                                            FX_BOOL bStandard) {
2325   FX_LOCALEDATETIMESUBCATEGORY strStyle;
2326   switch (iStyle) {
2327     case 0:
2328       strStyle = FX_LOCALEDATETIMESUBCATEGORY_Medium;
2329       break;
2330     case 1:
2331       strStyle = FX_LOCALEDATETIMESUBCATEGORY_Short;
2332       break;
2333     case 2:
2334       strStyle = FX_LOCALEDATETIMESUBCATEGORY_Medium;
2335       break;
2336     case 3:
2337       strStyle = FX_LOCALEDATETIMESUBCATEGORY_Long;
2338       break;
2339     case 4:
2340       strStyle = FX_LOCALEDATETIMESUBCATEGORY_Full;
2341       break;
2342     default:
2343       strStyle = FX_LOCALEDATETIMESUBCATEGORY_Medium;
2344       break;
2345   }
2346   CXFA_FM2JSContext* pContext =
2347       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
2348   CXFA_Document* pDoc = pContext->GetDocument();
2349   if (!pDoc) {
2350     return;
2351   }
2352   IFX_LocaleMgr* pMgr = (IFX_LocaleMgr*)pDoc->GetLocalMgr();
2353   IFX_Locale* pLocale = NULL;
2354   if (szLocalStr.IsEmpty()) {
2355     CXFA_Object* pThisNode = pDoc->GetScriptContext()->GetThisObject();
2356     FXSYS_assert(pThisNode->IsNode());
2357     CXFA_WidgetData widgetData((CXFA_Node*)pThisNode);
2358     pLocale = widgetData.GetLocal();
2359   } else {
2360     pLocale = pMgr->GetLocaleByName(
2361         CFX_WideString::FromUTF8(szLocalStr.GetCStr(), szLocalStr.GetLength()));
2362   }
2363   if (!pLocale) {
2364     return;
2365   }
2366   CFX_WideString strRet;
2367   pLocale->GetDatePattern(strStyle, strRet);
2368   if (!bStandard) {
2369     CFX_WideString wsSymbols;
2370     pLocale->GetDateTimeSymbols(wsSymbols);
2371     XFA_FM_AlternateDateTimeSymbols(strRet, wsSymbols, g_sAltTable_Date);
2372   }
2373   strFormat = FX_UTF8Encode(strRet, strRet.GetLength());
2374 }
GetLocalTimeFormat(FXJSE_HOBJECT hThis,int32_t iStyle,const CFX_ByteStringC & szLocalStr,CFX_ByteString & strFormat,FX_BOOL bStandard)2375 void CXFA_FM2JSContext::GetLocalTimeFormat(FXJSE_HOBJECT hThis,
2376                                            int32_t iStyle,
2377                                            const CFX_ByteStringC& szLocalStr,
2378                                            CFX_ByteString& strFormat,
2379                                            FX_BOOL bStandard) {
2380   FX_LOCALEDATETIMESUBCATEGORY strStyle;
2381   switch (iStyle) {
2382     case 0:
2383       strStyle = FX_LOCALEDATETIMESUBCATEGORY_Medium;
2384       break;
2385     case 1:
2386       strStyle = FX_LOCALEDATETIMESUBCATEGORY_Short;
2387       break;
2388     case 2:
2389       strStyle = FX_LOCALEDATETIMESUBCATEGORY_Medium;
2390       break;
2391     case 3:
2392       strStyle = FX_LOCALEDATETIMESUBCATEGORY_Long;
2393       break;
2394     case 4:
2395       strStyle = FX_LOCALEDATETIMESUBCATEGORY_Full;
2396       break;
2397     default:
2398       strStyle = FX_LOCALEDATETIMESUBCATEGORY_Medium;
2399       break;
2400   }
2401   CXFA_FM2JSContext* pContext =
2402       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
2403   CXFA_Document* pDoc = pContext->GetDocument();
2404   if (!pDoc) {
2405     return;
2406   }
2407   IFX_LocaleMgr* pMgr = (IFX_LocaleMgr*)pDoc->GetLocalMgr();
2408   IFX_Locale* pLocale = NULL;
2409   if (szLocalStr.IsEmpty()) {
2410     CXFA_Object* pThisObject = pDoc->GetScriptContext()->GetThisObject();
2411     FXSYS_assert(pThisObject->IsNode());
2412     CXFA_Node* pThisNode = (CXFA_Node*)pThisObject;
2413     CXFA_WidgetData widgetData(pThisNode);
2414     pLocale = widgetData.GetLocal();
2415   } else {
2416     pLocale = pMgr->GetLocaleByName(
2417         CFX_WideString::FromUTF8(szLocalStr.GetCStr(), szLocalStr.GetLength()));
2418   }
2419   if (!pLocale) {
2420     return;
2421   }
2422   CFX_WideString strRet;
2423   pLocale->GetTimePattern(strStyle, strRet);
2424   if (!bStandard) {
2425     CFX_WideString wsSymbols;
2426     pLocale->GetDateTimeSymbols(wsSymbols);
2427     XFA_FM_AlternateDateTimeSymbols(strRet, wsSymbols, g_sAltTable_Time);
2428   }
2429   strFormat = FX_UTF8Encode(strRet, strRet.GetLength());
2430 }
GetStandardDateFormat(FXJSE_HOBJECT hThis,int32_t iStyle,const CFX_ByteStringC & szLocalStr,CFX_ByteString & strFormat)2431 void CXFA_FM2JSContext::GetStandardDateFormat(FXJSE_HOBJECT hThis,
2432                                               int32_t iStyle,
2433                                               const CFX_ByteStringC& szLocalStr,
2434                                               CFX_ByteString& strFormat) {
2435   GetLocalDateFormat(hThis, iStyle, szLocalStr, strFormat, TRUE);
2436 }
GetStandardTimeFormat(FXJSE_HOBJECT hThis,int32_t iStyle,const CFX_ByteStringC & szLocalStr,CFX_ByteString & strFormat)2437 void CXFA_FM2JSContext::GetStandardTimeFormat(FXJSE_HOBJECT hThis,
2438                                               int32_t iStyle,
2439                                               const CFX_ByteStringC& szLocalStr,
2440                                               CFX_ByteString& strFormat) {
2441   GetLocalTimeFormat(hThis, iStyle, szLocalStr, strFormat, TRUE);
2442 }
Num2AllTime(FXJSE_HOBJECT hThis,int32_t iTime,const CFX_ByteStringC & szFormat,const CFX_ByteStringC & szLocale,FX_BOOL bGM,CFX_ByteString & strTime)2443 void CXFA_FM2JSContext::Num2AllTime(FXJSE_HOBJECT hThis,
2444                                     int32_t iTime,
2445                                     const CFX_ByteStringC& szFormat,
2446                                     const CFX_ByteStringC& szLocale,
2447                                     FX_BOOL bGM,
2448                                     CFX_ByteString& strTime) {
2449   int32_t iHour = 0;
2450   int32_t iMin = 0;
2451   int32_t iSec = 0;
2452   int32_t iZoneHour = 0;
2453   int32_t iZoneMin = 0;
2454   int32_t iZoneSec = 0;
2455   iHour = static_cast<int>(iTime) / 3600000;
2456   iMin = (static_cast<int>(iTime) - iHour * 3600000) / 60000;
2457   iSec = (static_cast<int>(iTime) - iHour * 3600000 - iMin * 60000) / 1000;
2458   if (!bGM) {
2459     GetLocalTimeZone(iZoneHour, iZoneMin, iZoneSec);
2460     iHour += iZoneHour;
2461     iMin += iZoneMin;
2462     iSec += iZoneSec;
2463   }
2464   int32_t iRet = 0;
2465   CFX_ByteString strIsoTime;
2466   strIsoTime.Format("%02d:%02d:%02d", iHour, iMin, iSec);
2467   if (bGM) {
2468     iRet = GetGMTTime(hThis, strIsoTime, szFormat, szLocale, strTime);
2469   } else {
2470     iRet = IsoTime2Local(hThis, strIsoTime, szFormat, szLocale, strTime);
2471   }
2472   if (!iRet) {
2473     strTime = "";
2474   }
2475   return;
2476 }
GetLocalTimeZone(int32_t & iHour,int32_t & iMin,int32_t & iSec)2477 void CXFA_FM2JSContext::GetLocalTimeZone(int32_t& iHour,
2478                                          int32_t& iMin,
2479                                          int32_t& iSec) {
2480   time_t now;
2481   time(&now);
2482   struct tm* pGmt = gmtime(&now);
2483   int32_t iGMHour = pGmt->tm_hour;
2484   int32_t iGMMin = pGmt->tm_min;
2485   int32_t iGMSec = pGmt->tm_sec;
2486   struct tm* pLocal = localtime(&now);
2487   int32_t iLocalHour = pLocal->tm_hour;
2488   int32_t iLocalMin = pLocal->tm_min;
2489   int32_t iLocalSec = pLocal->tm_sec;
2490   iHour = iLocalHour - iGMHour;
2491   iMin = iLocalMin - iGMMin;
2492   iSec = iLocalSec - iGMSec;
2493 }
Apr(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)2494 void CXFA_FM2JSContext::Apr(FXJSE_HOBJECT hThis,
2495                             const CFX_ByteStringC& szFuncName,
2496                             CFXJSE_Arguments& args) {
2497   CXFA_FM2JSContext* pContext =
2498       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
2499   if (args.GetLength() == 3) {
2500     FX_BOOL bFlags = FALSE;
2501     FX_DOUBLE nPrincipal = 0;
2502     FX_DOUBLE nPayment = 0;
2503     FX_DOUBLE nPeriods = 0;
2504     FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
2505     FXJSE_HVALUE argTwo = GetSimpleHValue(hThis, args, 1);
2506     FXJSE_HVALUE argThree = GetSimpleHValue(hThis, args, 2);
2507     bFlags = (HValueIsNull(hThis, argOne) || HValueIsNull(hThis, argTwo) ||
2508               HValueIsNull(hThis, argThree));
2509     if (bFlags) {
2510       FXJSE_Value_SetNull(args.GetReturnValue());
2511     } else {
2512       nPrincipal = HValueToDouble(hThis, argOne);
2513       nPayment = HValueToDouble(hThis, argTwo);
2514       nPeriods = HValueToDouble(hThis, argThree);
2515       bFlags = ((nPrincipal <= 0) || (nPayment <= 0) || (nPeriods <= 0));
2516       if (bFlags) {
2517         pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
2518       } else {
2519         FX_DOUBLE r =
2520             2 * (nPeriods * nPayment - nPrincipal) / (nPeriods * nPrincipal);
2521         FX_DOUBLE nTemp = 1;
2522         for (int32_t i = 0; i < nPeriods; ++i) {
2523           nTemp *= (1 + r);
2524         }
2525         FX_DOUBLE nRet = r * nTemp / (nTemp - 1) - nPayment / nPrincipal;
2526         while ((nRet > FINANCIAL_PRECISION || nRet < -FINANCIAL_PRECISION) &&
2527                (!bFlags)) {
2528           FX_DOUBLE nDerivative = 0;
2529           nDerivative =
2530               ((nTemp + r * nPeriods * (nTemp / (1 + r))) * (nTemp - 1) -
2531                (r * nTemp * nPeriods * (nTemp / (1 + r)))) /
2532               ((nTemp - 1) * (nTemp - 1));
2533           if (nDerivative == 0) {
2534             bFlags = TRUE;
2535             continue;
2536           }
2537           r = r - nRet / nDerivative;
2538           nTemp = 1;
2539           for (int32_t i = 0; i < nPeriods; ++i) {
2540             nTemp *= (1 + r);
2541           }
2542           nRet = r * nTemp / (nTemp - 1) - nPayment / nPrincipal;
2543         }
2544         if (bFlags) {
2545           FXJSE_Value_SetNull(args.GetReturnValue());
2546         } else {
2547           r = r * 12;
2548           FXJSE_Value_SetDouble(args.GetReturnValue(), r);
2549         }
2550       }
2551     }
2552     FXJSE_Value_Release(argOne);
2553     FXJSE_Value_Release(argTwo);
2554     FXJSE_Value_Release(argThree);
2555   } else {
2556     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
2557                                       L"Apr");
2558   }
2559 }
CTerm(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)2560 void CXFA_FM2JSContext::CTerm(FXJSE_HOBJECT hThis,
2561                               const CFX_ByteStringC& szFuncName,
2562                               CFXJSE_Arguments& args) {
2563   CXFA_FM2JSContext* pContext =
2564       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
2565   if (args.GetLength() == 3) {
2566     FX_BOOL bFlags = FALSE;
2567     FX_FLOAT nRate = 0;
2568     FX_FLOAT nFutureValue = 0;
2569     FX_FLOAT nInitAmount = 0;
2570     FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
2571     FXJSE_HVALUE argTwo = GetSimpleHValue(hThis, args, 1);
2572     FXJSE_HVALUE argThree = GetSimpleHValue(hThis, args, 2);
2573     bFlags = (HValueIsNull(hThis, argOne) || HValueIsNull(hThis, argTwo) ||
2574               HValueIsNull(hThis, argThree));
2575     if (bFlags) {
2576       FXJSE_Value_SetNull(args.GetReturnValue());
2577     } else {
2578       nRate = HValueToFloat(hThis, argOne);
2579       nFutureValue = HValueToFloat(hThis, argTwo);
2580       nInitAmount = HValueToFloat(hThis, argThree);
2581       bFlags = ((nRate <= 0) || (nFutureValue <= 0) || (nInitAmount <= 0));
2582       if (bFlags) {
2583         pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
2584       } else {
2585         FXJSE_Value_SetFloat(args.GetReturnValue(),
2586                              FXSYS_log((FX_FLOAT)(nFutureValue / nInitAmount)) /
2587                                  FXSYS_log((FX_FLOAT)(1 + nRate)));
2588       }
2589     }
2590     FXJSE_Value_Release(argOne);
2591     FXJSE_Value_Release(argTwo);
2592     FXJSE_Value_Release(argThree);
2593   } else {
2594     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
2595                                       L"CTerm");
2596   }
2597 }
FV(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)2598 void CXFA_FM2JSContext::FV(FXJSE_HOBJECT hThis,
2599                            const CFX_ByteStringC& szFuncName,
2600                            CFXJSE_Arguments& args) {
2601   CXFA_FM2JSContext* pContext =
2602       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
2603   if (args.GetLength() == 3) {
2604     FX_BOOL bFlags = FALSE;
2605     FX_DOUBLE nAmount = 0;
2606     FX_DOUBLE nRate = 0;
2607     FX_DOUBLE nPeriod = 0;
2608     FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
2609     FXJSE_HVALUE argTwo = GetSimpleHValue(hThis, args, 1);
2610     FXJSE_HVALUE argThree = GetSimpleHValue(hThis, args, 2);
2611     bFlags = (HValueIsNull(hThis, argOne) || HValueIsNull(hThis, argTwo) ||
2612               HValueIsNull(hThis, argThree));
2613     if (bFlags) {
2614       FXJSE_Value_SetNull(args.GetReturnValue());
2615     } else {
2616       nAmount = HValueToDouble(hThis, argOne);
2617       nRate = HValueToDouble(hThis, argTwo);
2618       nPeriod = HValueToDouble(hThis, argThree);
2619       bFlags = ((nRate < 0) || (nPeriod <= 0) || (nAmount <= 0));
2620       if (bFlags) {
2621         pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
2622       } else {
2623         FX_DOUBLE dResult = 0;
2624         if (!nRate) {
2625           dResult = nAmount * nPeriod;
2626         } else {
2627           FX_DOUBLE nTemp = 1;
2628           for (int i = 0; i < nPeriod; ++i) {
2629             nTemp *= 1 + nRate;
2630           }
2631           dResult = nAmount * (nTemp - 1) / nRate;
2632         }
2633         FXJSE_Value_SetDouble(args.GetReturnValue(), dResult);
2634       }
2635     }
2636     FXJSE_Value_Release(argOne);
2637     FXJSE_Value_Release(argTwo);
2638     FXJSE_Value_Release(argThree);
2639   } else {
2640     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
2641                                       L"FV");
2642   }
2643 }
IPmt(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)2644 void CXFA_FM2JSContext::IPmt(FXJSE_HOBJECT hThis,
2645                              const CFX_ByteStringC& szFuncName,
2646                              CFXJSE_Arguments& args) {
2647   CXFA_FM2JSContext* pContext =
2648       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
2649   if (args.GetLength() == 5) {
2650     FX_BOOL bFlags = FALSE;
2651     FX_FLOAT nPrincpalAmount = 0;
2652     FX_FLOAT nRate = 0;
2653     FX_FLOAT nPayment = 0;
2654     FX_FLOAT nFirstMonth = 0;
2655     FX_FLOAT nNumberOfMonths = 0;
2656     FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
2657     FXJSE_HVALUE argTwo = GetSimpleHValue(hThis, args, 1);
2658     FXJSE_HVALUE argThree = GetSimpleHValue(hThis, args, 2);
2659     FXJSE_HVALUE argFour = GetSimpleHValue(hThis, args, 3);
2660     FXJSE_HVALUE argFive = GetSimpleHValue(hThis, args, 4);
2661     bFlags = (HValueIsNull(hThis, argOne) || HValueIsNull(hThis, argTwo) ||
2662               HValueIsNull(hThis, argThree) || HValueIsNull(hThis, argFour) ||
2663               HValueIsNull(hThis, argFive));
2664     if (bFlags) {
2665       FXJSE_Value_SetNull(args.GetReturnValue());
2666     } else {
2667       nPrincpalAmount = HValueToFloat(hThis, argOne);
2668       nRate = HValueToFloat(hThis, argTwo);
2669       nPayment = HValueToFloat(hThis, argThree);
2670       nFirstMonth = HValueToFloat(hThis, argFour);
2671       nNumberOfMonths = HValueToFloat(hThis, argFive);
2672       bFlags = ((nPrincpalAmount <= 0) || (nRate <= 0) || (nPayment <= 0) ||
2673                 (nFirstMonth < 0) || (nNumberOfMonths < 0));
2674       if (bFlags) {
2675         pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
2676       } else {
2677         FX_FLOAT fResult = 0;
2678         FX_FLOAT nRateOfMonth = nRate / 12;
2679         int32_t iNums =
2680             (int32_t)((FXSYS_log10((FX_FLOAT)(nPayment / nPrincpalAmount)) -
2681                        FXSYS_log10((FX_FLOAT)(nPayment / nPrincpalAmount -
2682                                               nRateOfMonth))) /
2683                       FXSYS_log10((FX_FLOAT)(1 + nRateOfMonth)));
2684         int32_t iEnd = (int32_t)(nFirstMonth + nNumberOfMonths - 1);
2685         if (iEnd > iNums) {
2686           iEnd = iNums;
2687         }
2688         FX_FLOAT nSum = 0;
2689         if (nPayment < nPrincpalAmount * nRateOfMonth) {
2690           bFlags = TRUE;
2691           fResult = 0;
2692         }
2693         if (!bFlags) {
2694           int32_t i = 0;
2695           for (i = 0; i < nFirstMonth - 1; ++i) {
2696             nPrincpalAmount -= nPayment - nPrincpalAmount * nRateOfMonth;
2697           }
2698           for (; i < iEnd; ++i) {
2699             nSum += nPrincpalAmount * nRateOfMonth;
2700             nPrincpalAmount -= nPayment - nPrincpalAmount * nRateOfMonth;
2701           }
2702           fResult = nSum;
2703         }
2704         FXJSE_Value_SetFloat(args.GetReturnValue(), fResult);
2705       }
2706     }
2707     FXJSE_Value_Release(argOne);
2708     FXJSE_Value_Release(argTwo);
2709     FXJSE_Value_Release(argThree);
2710     FXJSE_Value_Release(argFour);
2711     FXJSE_Value_Release(argFive);
2712   } else {
2713     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
2714                                       L"IPmt");
2715   }
2716 }
NPV(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)2717 void CXFA_FM2JSContext::NPV(FXJSE_HOBJECT hThis,
2718                             const CFX_ByteStringC& szFuncName,
2719                             CFXJSE_Arguments& args) {
2720   CXFA_FM2JSContext* pContext =
2721       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
2722   int32_t argc = args.GetLength();
2723   if (argc > 2) {
2724     FX_BOOL bFlags = FALSE;
2725     FXJSE_HVALUE* argValues = FX_Alloc(FXJSE_HVALUE, argc);
2726     for (int32_t i = 0; i < argc; i++) {
2727       argValues[i] = GetSimpleHValue(hThis, args, i);
2728       if (HValueIsNull(hThis, argValues[i])) {
2729         bFlags = TRUE;
2730       }
2731     }
2732     if (!bFlags) {
2733       FX_DOUBLE nRate = 0;
2734       nRate = HValueToDouble(hThis, argValues[0]);
2735       if (nRate <= 0) {
2736         pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
2737       } else {
2738         FX_DOUBLE* pData = FX_Alloc(FX_DOUBLE, argc - 1);
2739         for (int32_t i = 1; i < argc; i++) {
2740           pData[i - 1] = HValueToDouble(hThis, argValues[i]);
2741         }
2742         FX_DOUBLE nSum = 0;
2743         int32_t iIndex = 0;
2744         for (int32_t i = 0; i < argc - 1; i++) {
2745           FX_DOUBLE nTemp = 1;
2746           for (int32_t j = 0; j <= i; j++) {
2747             nTemp *= 1 + nRate;
2748           }
2749           FX_DOUBLE nNum = *(pData + iIndex++);
2750           nSum += nNum / nTemp;
2751         }
2752         FXJSE_Value_SetDouble(args.GetReturnValue(), nSum);
2753         FX_Free(pData);
2754         pData = 0;
2755       }
2756     } else {
2757       FXJSE_Value_SetNull(args.GetReturnValue());
2758     }
2759     for (int32_t i = 0; i < argc; i++) {
2760       FXJSE_Value_Release(argValues[i]);
2761     }
2762     FX_Free(argValues);
2763   } else {
2764     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
2765                                       L"NPV");
2766   }
2767 }
Pmt(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)2768 void CXFA_FM2JSContext::Pmt(FXJSE_HOBJECT hThis,
2769                             const CFX_ByteStringC& szFuncName,
2770                             CFXJSE_Arguments& args) {
2771   CXFA_FM2JSContext* pContext =
2772       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
2773   if (args.GetLength() == 3) {
2774     FX_BOOL bFlags = FALSE;
2775     FX_FLOAT nPrincipal = 0;
2776     FX_FLOAT nRate = 0;
2777     FX_FLOAT nPeriods = 0;
2778     FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
2779     FXJSE_HVALUE argTwo = GetSimpleHValue(hThis, args, 1);
2780     FXJSE_HVALUE argThree = GetSimpleHValue(hThis, args, 2);
2781     bFlags = (HValueIsNull(hThis, argOne) || HValueIsNull(hThis, argTwo) ||
2782               HValueIsNull(hThis, argThree));
2783     if (bFlags) {
2784       FXJSE_Value_SetNull(args.GetReturnValue());
2785     } else {
2786       nPrincipal = HValueToFloat(hThis, argOne);
2787       nRate = HValueToFloat(hThis, argTwo);
2788       nPeriods = HValueToFloat(hThis, argThree);
2789       bFlags = ((nPrincipal <= 0) || (nRate <= 0) || (nPeriods <= 0));
2790       if (bFlags) {
2791         pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
2792       } else {
2793         FX_FLOAT nSum = 0;
2794         FX_FLOAT nTmp = 1 + nRate;
2795         nSum = nTmp;
2796         for (int32_t i = 0; i < nPeriods - 1; ++i) {
2797           nSum *= nTmp;
2798         }
2799         FXJSE_Value_SetFloat(args.GetReturnValue(),
2800                              (nPrincipal * nRate * nSum) / (nSum - 1));
2801       }
2802     }
2803     FXJSE_Value_Release(argOne);
2804     FXJSE_Value_Release(argTwo);
2805     FXJSE_Value_Release(argThree);
2806   } else {
2807     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
2808                                       L"Pmt");
2809   }
2810 }
PPmt(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)2811 void CXFA_FM2JSContext::PPmt(FXJSE_HOBJECT hThis,
2812                              const CFX_ByteStringC& szFuncName,
2813                              CFXJSE_Arguments& args) {
2814   CXFA_FM2JSContext* pContext =
2815       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
2816   if (args.GetLength() == 5) {
2817     FX_BOOL bFlags = FALSE;
2818     FX_FLOAT nPrincpalAmount = 0;
2819     FX_FLOAT nRate = 0;
2820     FX_FLOAT nPayment = 0;
2821     FX_FLOAT nFirstMonth = 0;
2822     FX_FLOAT nNumberOfMonths = 0;
2823     FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
2824     FXJSE_HVALUE argTwo = GetSimpleHValue(hThis, args, 1);
2825     FXJSE_HVALUE argThree = GetSimpleHValue(hThis, args, 2);
2826     FXJSE_HVALUE argFour = GetSimpleHValue(hThis, args, 3);
2827     FXJSE_HVALUE argFive = GetSimpleHValue(hThis, args, 4);
2828     bFlags = (HValueIsNull(hThis, argOne) || HValueIsNull(hThis, argTwo) ||
2829               HValueIsNull(hThis, argThree) || HValueIsNull(hThis, argFour) ||
2830               HValueIsNull(hThis, argFive));
2831     if (bFlags) {
2832       FXJSE_Value_SetNull(args.GetReturnValue());
2833     } else {
2834       nPrincpalAmount = HValueToFloat(hThis, argOne);
2835       nRate = HValueToFloat(hThis, argTwo);
2836       nPayment = HValueToFloat(hThis, argThree);
2837       nFirstMonth = HValueToFloat(hThis, argFour);
2838       nNumberOfMonths = HValueToFloat(hThis, argFive);
2839       bFlags = ((nPrincpalAmount <= 0) || (nRate <= 0) || (nPayment <= 0) ||
2840                 (nFirstMonth < 0) || (nNumberOfMonths < 0));
2841       if (bFlags) {
2842         pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
2843       } else {
2844         int32_t iEnd = (int32_t)(nFirstMonth + nNumberOfMonths - 1);
2845         FX_FLOAT nSum = 0;
2846         FX_FLOAT nRateOfMonth = nRate / 12;
2847         int32_t iNums =
2848             (int32_t)((FXSYS_log10((FX_FLOAT)(nPayment / nPrincpalAmount)) -
2849                        FXSYS_log10((FX_FLOAT)(nPayment / nPrincpalAmount -
2850                                               nRateOfMonth))) /
2851                       FXSYS_log10((FX_FLOAT)(1 + nRateOfMonth)));
2852         if (iEnd > iNums) {
2853           iEnd = iNums;
2854         }
2855         if (nPayment < nPrincpalAmount * nRateOfMonth) {
2856           bFlags = TRUE;
2857         }
2858         if (!bFlags) {
2859           int32_t i = 0;
2860           for (i = 0; i < nFirstMonth - 1; ++i) {
2861             nPrincpalAmount -= nPayment - nPrincpalAmount * nRateOfMonth;
2862           }
2863           FX_FLOAT nTemp = 0;
2864           for (; i < iEnd; ++i) {
2865             nTemp = nPayment - nPrincpalAmount * nRateOfMonth;
2866             nSum += nTemp;
2867             nPrincpalAmount -= nTemp;
2868           }
2869           FXJSE_Value_SetFloat(args.GetReturnValue(), nSum);
2870         } else {
2871           pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
2872         }
2873       }
2874     }
2875     FXJSE_Value_Release(argOne);
2876     FXJSE_Value_Release(argTwo);
2877     FXJSE_Value_Release(argThree);
2878     FXJSE_Value_Release(argFour);
2879     FXJSE_Value_Release(argFive);
2880   } else {
2881     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
2882                                       L"PPmt");
2883   }
2884 }
PV(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)2885 void CXFA_FM2JSContext::PV(FXJSE_HOBJECT hThis,
2886                            const CFX_ByteStringC& szFuncName,
2887                            CFXJSE_Arguments& args) {
2888   CXFA_FM2JSContext* pContext =
2889       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
2890   if (args.GetLength() == 3) {
2891     FX_BOOL bFlags = FALSE;
2892     FX_DOUBLE nAmount = 0;
2893     FX_DOUBLE nRate = 0;
2894     FX_DOUBLE nPeriod = 0;
2895     FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
2896     FXJSE_HVALUE argTwo = GetSimpleHValue(hThis, args, 1);
2897     FXJSE_HVALUE argThree = GetSimpleHValue(hThis, args, 2);
2898     bFlags = (HValueIsNull(hThis, argOne) || HValueIsNull(hThis, argTwo) ||
2899               HValueIsNull(hThis, argThree));
2900     if (bFlags) {
2901       FXJSE_Value_SetNull(args.GetReturnValue());
2902     } else {
2903       nAmount = HValueToDouble(hThis, argOne);
2904       nRate = HValueToDouble(hThis, argTwo);
2905       nPeriod = HValueToDouble(hThis, argThree);
2906       bFlags = ((nAmount <= 0) || (nRate < 0) || (nPeriod <= 0));
2907       if (bFlags) {
2908         pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
2909       } else {
2910         FX_DOUBLE nTemp = 1;
2911         for (int32_t i = 0; i < nPeriod; ++i) {
2912           nTemp *= 1 + nRate;
2913         }
2914         nTemp = 1 / nTemp;
2915         FXJSE_Value_SetDouble(args.GetReturnValue(),
2916                               nAmount * ((1 - nTemp) / nRate));
2917       }
2918     }
2919     FXJSE_Value_Release(argOne);
2920     FXJSE_Value_Release(argTwo);
2921     FXJSE_Value_Release(argThree);
2922   } else {
2923     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
2924                                       L"PV");
2925   }
2926 }
Rate(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)2927 void CXFA_FM2JSContext::Rate(FXJSE_HOBJECT hThis,
2928                              const CFX_ByteStringC& szFuncName,
2929                              CFXJSE_Arguments& args) {
2930   CXFA_FM2JSContext* pContext =
2931       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
2932   if (args.GetLength() == 3) {
2933     FX_BOOL bFlags = FALSE;
2934     FX_FLOAT nFuture = 0;
2935     FX_FLOAT nPresent = 0;
2936     FX_FLOAT nTotalNumber = 0;
2937     FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
2938     FXJSE_HVALUE argTwo = GetSimpleHValue(hThis, args, 1);
2939     FXJSE_HVALUE argThree = GetSimpleHValue(hThis, args, 2);
2940     bFlags = (HValueIsNull(hThis, argOne) || HValueIsNull(hThis, argTwo) ||
2941               HValueIsNull(hThis, argThree));
2942     if (bFlags) {
2943       FXJSE_Value_SetNull(args.GetReturnValue());
2944     } else {
2945       nFuture = HValueToFloat(hThis, argOne);
2946       nPresent = HValueToFloat(hThis, argTwo);
2947       nTotalNumber = HValueToFloat(hThis, argThree);
2948       bFlags = ((nFuture <= 0) || (nPresent < 0) || (nTotalNumber <= 0));
2949       if (bFlags) {
2950         pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
2951       } else {
2952         FXJSE_Value_SetFloat(args.GetReturnValue(),
2953                              (FXSYS_pow((FX_FLOAT)(nFuture / nPresent),
2954                                         (FX_FLOAT)(1 / nTotalNumber)) -
2955                               1));
2956       }
2957     }
2958     FXJSE_Value_Release(argOne);
2959     FXJSE_Value_Release(argTwo);
2960     FXJSE_Value_Release(argThree);
2961   } else {
2962     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
2963                                       L"Rate");
2964   }
2965 }
Term(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)2966 void CXFA_FM2JSContext::Term(FXJSE_HOBJECT hThis,
2967                              const CFX_ByteStringC& szFuncName,
2968                              CFXJSE_Arguments& args) {
2969   CXFA_FM2JSContext* pContext =
2970       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
2971   if (args.GetLength() == 3) {
2972     FX_BOOL bFlags = FALSE;
2973     FX_FLOAT nMount = 0;
2974     FX_FLOAT nRate = 0;
2975     FX_FLOAT nFuture = 0;
2976     FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
2977     FXJSE_HVALUE argTwo = GetSimpleHValue(hThis, args, 1);
2978     FXJSE_HVALUE argThree = GetSimpleHValue(hThis, args, 2);
2979     bFlags = (FXJSE_Value_IsNull(argOne) || FXJSE_Value_IsNull(argTwo) ||
2980               FXJSE_Value_IsNull(argThree));
2981     if (bFlags) {
2982       FXJSE_Value_SetNull(args.GetReturnValue());
2983     } else {
2984       nMount = HValueToFloat(hThis, argOne);
2985       nRate = HValueToFloat(hThis, argTwo);
2986       nFuture = HValueToFloat(hThis, argThree);
2987       bFlags = ((nMount <= 0) || (nRate <= 0) || (nFuture <= 0));
2988       if (bFlags) {
2989         pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
2990       } else {
2991         FXJSE_Value_SetFloat(
2992             args.GetReturnValue(),
2993             (FXSYS_log((FX_FLOAT)(nFuture / nMount * nRate) + 1) /
2994              FXSYS_log((FX_FLOAT)(1 + nRate))));
2995       }
2996     }
2997     FXJSE_Value_Release(argOne);
2998     FXJSE_Value_Release(argTwo);
2999     FXJSE_Value_Release(argThree);
3000   } else {
3001     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
3002                                       L"Term");
3003   }
3004 }
Choose(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)3005 void CXFA_FM2JSContext::Choose(FXJSE_HOBJECT hThis,
3006                                const CFX_ByteStringC& szFuncName,
3007                                CFXJSE_Arguments& args) {
3008   CXFA_FM2JSContext* pContext =
3009       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
3010   FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
3011   int32_t argc = args.GetLength();
3012   if (argc > 1) {
3013     FXJSE_HVALUE argOne = args.GetValue(0);
3014     FX_BOOL argOneIsNull = FALSE;
3015     int32_t iIndex = 0;
3016     argOneIsNull = HValueIsNull(hThis, argOne);
3017     if (!argOneIsNull) {
3018       iIndex = (int32_t)HValueToFloat(hThis, argOne);
3019     }
3020     FXJSE_Value_Release(argOne);
3021     if (argOneIsNull) {
3022       FXJSE_Value_SetNull(args.GetReturnValue());
3023     } else if (iIndex < 1) {
3024       FXJSE_Value_SetUTF8String(args.GetReturnValue(), "");
3025     } else {
3026       FX_BOOL bFound = FALSE;
3027       FX_BOOL bStopCounterFlags = FALSE;
3028       int32_t iArgIndex = 1;
3029       int32_t iValueIndex = 0;
3030       while (!bFound && !bStopCounterFlags && (iArgIndex < argc)) {
3031         FXJSE_HVALUE argIndexValue = args.GetValue(iArgIndex);
3032         if (FXJSE_Value_IsArray(argIndexValue)) {
3033           FXJSE_HVALUE lengthValue = FXJSE_Value_Create(hruntime);
3034           FXJSE_Value_GetObjectProp(argIndexValue, "length", lengthValue);
3035           int32_t iLength = FXJSE_Value_ToInteger(lengthValue);
3036           FXJSE_Value_Release(lengthValue);
3037           if (iLength > 3) {
3038             bStopCounterFlags = TRUE;
3039           }
3040           iValueIndex += (iLength - 2);
3041           if (iValueIndex >= iIndex) {
3042             FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
3043             FXJSE_HVALUE jsobjectValue = FXJSE_Value_Create(hruntime);
3044             FXJSE_HVALUE newProperty = FXJSE_Value_Create(hruntime);
3045             FXJSE_Value_GetObjectPropByIdx(argIndexValue, 1, propertyValue);
3046             FXJSE_Value_GetObjectPropByIdx(
3047                 argIndexValue, ((iLength - 1) - (iValueIndex - iIndex)),
3048                 jsobjectValue);
3049             if (FXJSE_Value_IsNull(propertyValue)) {
3050               GetObjectDefaultValue(jsobjectValue, newProperty);
3051             } else {
3052               CFX_ByteString propStr;
3053               FXJSE_Value_ToUTF8String(propertyValue, propStr);
3054               FXJSE_Value_GetObjectProp(jsobjectValue, propStr, newProperty);
3055             }
3056             CFX_ByteString bsChoosed;
3057             HValueToUTF8String(newProperty, bsChoosed);
3058             FXJSE_Value_SetUTF8String(args.GetReturnValue(), bsChoosed);
3059             FXJSE_Value_Release(newProperty);
3060             FXJSE_Value_Release(jsobjectValue);
3061             FXJSE_Value_Release(propertyValue);
3062             bFound = TRUE;
3063           }
3064         } else {
3065           iValueIndex++;
3066           if (iValueIndex == iIndex) {
3067             CFX_ByteString bsChoosed;
3068             HValueToUTF8String(argIndexValue, bsChoosed);
3069             FXJSE_Value_SetUTF8String(args.GetReturnValue(), bsChoosed);
3070             bFound = TRUE;
3071           }
3072         }
3073         FXJSE_Value_Release(argIndexValue);
3074         iArgIndex++;
3075       }
3076       if (!bFound) {
3077         FXJSE_Value_SetUTF8String(args.GetReturnValue(), "");
3078       }
3079     }
3080   } else {
3081     CXFA_FM2JSContext* pContext =
3082         (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
3083     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
3084                                       L"Choose");
3085   }
3086 }
Exists(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)3087 void CXFA_FM2JSContext::Exists(FXJSE_HOBJECT hThis,
3088                                const CFX_ByteStringC& szFuncName,
3089                                CFXJSE_Arguments& args) {
3090   if (args.GetLength() == 1) {
3091     FXJSE_HVALUE argOne = args.GetValue(0);
3092     FXJSE_Value_SetInteger(args.GetReturnValue(), FXJSE_Value_IsObject(argOne));
3093     FXJSE_Value_Release(argOne);
3094   } else {
3095     CXFA_FM2JSContext* pContext =
3096         (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
3097     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
3098                                       L"Exists");
3099   }
3100 }
HasValue(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)3101 void CXFA_FM2JSContext::HasValue(FXJSE_HOBJECT hThis,
3102                                  const CFX_ByteStringC& szFuncName,
3103                                  CFXJSE_Arguments& args) {
3104   if (args.GetLength() == 1) {
3105     FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
3106     if (FXJSE_Value_IsUTF8String(argOne)) {
3107       CFX_ByteString valueStr;
3108       FXJSE_Value_ToUTF8String(argOne, valueStr);
3109       valueStr.TrimLeft();
3110       FXJSE_Value_SetInteger(args.GetReturnValue(), (!valueStr.IsEmpty()));
3111     } else if (FXJSE_Value_IsNumber(argOne) || FXJSE_Value_IsBoolean(argOne)) {
3112       FXJSE_Value_SetInteger(args.GetReturnValue(), TRUE);
3113     } else {
3114       FXJSE_Value_SetInteger(args.GetReturnValue(), FALSE);
3115     }
3116     FXJSE_Value_Release(argOne);
3117   } else {
3118     CXFA_FM2JSContext* pContext =
3119         (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
3120     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
3121                                       L"HasValue");
3122   }
3123 }
Oneof(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)3124 void CXFA_FM2JSContext::Oneof(FXJSE_HOBJECT hThis,
3125                               const CFX_ByteStringC& szFuncName,
3126                               CFXJSE_Arguments& args) {
3127   int32_t argc = args.GetLength();
3128   if (argc > 1) {
3129     FX_BOOL bFlags = FALSE;
3130     FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
3131     FXJSE_HVALUE* parametersValue = 0;
3132     int32_t iCount = 0;
3133     unfoldArgs(hThis, args, parametersValue, iCount, 1);
3134     for (int32_t i = 0; i < iCount; i++) {
3135       if (simpleValueCompare(hThis, argOne, parametersValue[i])) {
3136         bFlags = TRUE;
3137         break;
3138       }
3139     }
3140     FXJSE_Value_SetInteger(args.GetReturnValue(), bFlags);
3141     FXJSE_Value_Release(argOne);
3142     for (int32_t i = 0; i < iCount; i++) {
3143       FXJSE_Value_Release(parametersValue[i]);
3144     }
3145     FX_Free(parametersValue);
3146     parametersValue = 0;
3147   } else {
3148     CXFA_FM2JSContext* pContext =
3149         (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
3150     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
3151                                       L"Oneof");
3152   }
3153 }
Within(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)3154 void CXFA_FM2JSContext::Within(FXJSE_HOBJECT hThis,
3155                                const CFX_ByteStringC& szFuncName,
3156                                CFXJSE_Arguments& args) {
3157   int32_t argc = args.GetLength();
3158   if (argc == 3) {
3159     FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
3160     if (FXJSE_Value_IsNull(argOne)) {
3161       FXJSE_Value_SetUndefined(args.GetReturnValue());
3162     } else {
3163       FXJSE_HVALUE argLow = GetSimpleHValue(hThis, args, 1);
3164       FXJSE_HVALUE argHeight = GetSimpleHValue(hThis, args, 2);
3165       if (FXJSE_Value_IsNumber(argOne)) {
3166         FX_FLOAT oneNumber = HValueToFloat(hThis, argOne);
3167         FX_FLOAT lowNumber = HValueToFloat(hThis, argLow);
3168         FX_FLOAT heightNumber = HValueToFloat(hThis, argHeight);
3169         FXJSE_Value_SetInteger(
3170             args.GetReturnValue(),
3171             ((oneNumber >= lowNumber) && (oneNumber <= heightNumber)));
3172       } else {
3173         CFX_ByteString oneString;
3174         CFX_ByteString lowString;
3175         CFX_ByteString heightString;
3176         HValueToUTF8String(argOne, oneString);
3177         HValueToUTF8String(argLow, lowString);
3178         HValueToUTF8String(argHeight, heightString);
3179         FXJSE_Value_SetInteger(args.GetReturnValue(),
3180                                ((oneString.Compare(lowString) >= 0) &&
3181                                 (oneString.Compare(heightString) <= 0)));
3182       }
3183       FXJSE_Value_Release(argLow);
3184       FXJSE_Value_Release(argHeight);
3185     }
3186     FXJSE_Value_Release(argOne);
3187   } else {
3188     CXFA_FM2JSContext* pContext =
3189         (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
3190     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
3191                                       L"Within");
3192   }
3193 }
If(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)3194 void CXFA_FM2JSContext::If(FXJSE_HOBJECT hThis,
3195                            const CFX_ByteStringC& szFuncName,
3196                            CFXJSE_Arguments& args) {
3197   if (args.GetLength() == 3) {
3198     FXJSE_HVALUE argCondition = GetSimpleHValue(hThis, args, 0);
3199     FXJSE_HVALUE argFirstValue = GetSimpleHValue(hThis, args, 1);
3200     FXJSE_HVALUE argSecondValue = GetSimpleHValue(hThis, args, 2);
3201     FX_BOOL bCondition = FXJSE_Value_ToBoolean(argCondition);
3202     FXJSE_Value_Set(args.GetReturnValue(),
3203                     bCondition ? argFirstValue : argSecondValue);
3204     FXJSE_Value_Release(argSecondValue);
3205     FXJSE_Value_Release(argFirstValue);
3206     FXJSE_Value_Release(argCondition);
3207   } else {
3208     CXFA_FM2JSContext* pContext =
3209         (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
3210     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
3211                                       L"If");
3212   }
3213 }
Eval(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)3214 void CXFA_FM2JSContext::Eval(FXJSE_HOBJECT hThis,
3215                              const CFX_ByteStringC& szFuncName,
3216                              CFXJSE_Arguments& args) {
3217   CXFA_FM2JSContext* pContext =
3218       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
3219   FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
3220   if (args.GetLength() == 1) {
3221     FXJSE_HVALUE scriptValue = GetSimpleHValue(hThis, args, 0);
3222     CFX_ByteString utf8ScriptString;
3223     HValueToUTF8String(scriptValue, utf8ScriptString);
3224     if (utf8ScriptString.IsEmpty()) {
3225       FXJSE_Value_SetNull(args.GetReturnValue());
3226     } else {
3227       CFX_WideTextBuf wsJavaScriptBuf;
3228       CFX_WideString javaScript;
3229       CFX_WideString wsError;
3230       XFA_FM2JS_Translate(CFX_WideString::FromUTF8(
3231                               utf8ScriptString, utf8ScriptString.GetLength()),
3232                           wsJavaScriptBuf, wsError);
3233       FXJSE_HCONTEXT hContext = FXJSE_Context_Create(hruntime);
3234       FXJSE_HVALUE returnValue = FXJSE_Value_Create(hruntime);
3235       javaScript = wsJavaScriptBuf.GetWideString();
3236       FXJSE_ExecuteScript(hContext,
3237                           FX_UTF8Encode(javaScript, javaScript.GetLength()),
3238                           returnValue);
3239       FXJSE_Value_Set(args.GetReturnValue(), returnValue);
3240       FXJSE_Value_Release(returnValue);
3241       FXJSE_Context_Release(hContext);
3242     }
3243     FXJSE_Value_Release(scriptValue);
3244   } else {
3245     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
3246                                       L"Eval");
3247   }
3248 }
Ref(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)3249 void CXFA_FM2JSContext::Ref(FXJSE_HOBJECT hThis,
3250                             const CFX_ByteStringC& szFuncName,
3251                             CFXJSE_Arguments& args) {
3252   CXFA_FM2JSContext* pContext =
3253       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
3254   FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
3255   if (args.GetLength() == 1) {
3256     FXJSE_HVALUE argOne = args.GetValue(0);
3257     if (FXJSE_Value_IsNull(argOne)) {
3258       FXJSE_HVALUE rgValues[3];
3259       for (int32_t i = 0; i < 3; i++) {
3260         rgValues[i] = FXJSE_Value_Create(hruntime);
3261       }
3262       FXJSE_Value_SetInteger(rgValues[0], 4);
3263       FXJSE_Value_SetNull(rgValues[1]);
3264       FXJSE_Value_SetNull(rgValues[2]);
3265       FXJSE_Value_SetArray(args.GetReturnValue(), 3, rgValues);
3266       for (int32_t i = 0; i < 3; i++) {
3267         FXJSE_Value_Release(rgValues[i]);
3268       }
3269     } else if (FXJSE_Value_IsArray(argOne)) {
3270       FXJSE_HVALUE lengthValue = FXJSE_Value_Create(hruntime);
3271       FXJSE_Value_GetObjectProp(argOne, "length", lengthValue);
3272       int32_t iLength = FXJSE_Value_ToInteger(lengthValue);
3273       FXJSE_Value_Release(lengthValue);
3274       FXSYS_assert(iLength >= 3);
3275       FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
3276       FXJSE_HVALUE jsObjectValue = FXJSE_Value_Create(hruntime);
3277       FXJSE_Value_GetObjectPropByIdx(argOne, 1, propertyValue);
3278       FXJSE_Value_GetObjectPropByIdx(argOne, 2, jsObjectValue);
3279       if (FXJSE_Value_IsNull(jsObjectValue)) {
3280         pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
3281       } else if (FXJSE_Value_IsNull(propertyValue) &&
3282                  (!FXJSE_Value_IsNull(jsObjectValue))) {
3283         FXJSE_HVALUE rgValues[3];
3284         for (int32_t i = 0; i < 3; i++) {
3285           rgValues[i] = FXJSE_Value_Create(hruntime);
3286         }
3287         FXJSE_Value_SetInteger(rgValues[0], 3);
3288         FXJSE_Value_SetNull(rgValues[1]);
3289         FXJSE_Value_Set(rgValues[2], jsObjectValue);
3290         FXJSE_Value_SetArray(args.GetReturnValue(), 3, rgValues);
3291         for (int32_t i = 0; i < 3; i++) {
3292           FXJSE_Value_Release(rgValues[i]);
3293         }
3294       } else {
3295         pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
3296       }
3297       FXJSE_Value_Release(jsObjectValue);
3298       FXJSE_Value_Release(propertyValue);
3299     } else if (FXJSE_Value_IsObject(argOne)) {
3300       FXJSE_HVALUE rgValues[3];
3301       for (int32_t i = 0; i < 3; i++) {
3302         rgValues[i] = FXJSE_Value_Create(hruntime);
3303       }
3304       FXJSE_Value_SetInteger(rgValues[0], 3);
3305       FXJSE_Value_SetNull(rgValues[1]);
3306       FXJSE_Value_Set(rgValues[2], argOne);
3307       FXJSE_Value_SetArray(args.GetReturnValue(), 3, rgValues);
3308       for (int32_t i = 0; i < 3; i++) {
3309         FXJSE_Value_Release(rgValues[i]);
3310       }
3311     } else if (FXJSE_Value_IsBoolean(argOne) ||
3312                FXJSE_Value_IsUTF8String(argOne) ||
3313                FXJSE_Value_IsNumber(argOne)) {
3314       FXJSE_Value_Set(args.GetReturnValue(), argOne);
3315     } else {
3316       pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
3317     }
3318     FXJSE_Value_Release(argOne);
3319   } else {
3320     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
3321                                       L"Ref");
3322   }
3323 }
UnitType(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)3324 void CXFA_FM2JSContext::UnitType(FXJSE_HOBJECT hThis,
3325                                  const CFX_ByteStringC& szFuncName,
3326                                  CFXJSE_Arguments& args) {
3327   if (args.GetLength() == 1) {
3328     FXJSE_HVALUE unitspanValue = GetSimpleHValue(hThis, args, 0);
3329     if (FXJSE_Value_IsNull(unitspanValue)) {
3330       FXJSE_Value_SetNull(args.GetReturnValue());
3331       FXJSE_Value_Release(unitspanValue);
3332       return;
3333     }
3334     CFX_ByteString unitspanString;
3335     HValueToUTF8String(unitspanValue, unitspanString);
3336     if (unitspanString.IsEmpty()) {
3337       FXJSE_Value_SetUTF8String(args.GetReturnValue(), "in");
3338     } else {
3339       enum XFA_FM2JS_VALUETYPE_ParserStatus {
3340         VALUETYPE_START,
3341         VALUETYPE_HAVEINVALIDCHAR,
3342         VALUETYPE_HAVEDIGIT,
3343         VALUETYPE_HAVEDIGITWHITE,
3344         VALUETYPE_ISCM,
3345         VALUETYPE_ISMM,
3346         VALUETYPE_ISPT,
3347         VALUETYPE_ISMP,
3348         VALUETYPE_ISIN,
3349       };
3350       unitspanString.MakeLower();
3351       CFX_WideString wsTypeString =
3352           CFX_WideString::FromUTF8(unitspanString, unitspanString.GetLength());
3353       const FX_WCHAR* pData = wsTypeString;
3354       int32_t u = 0;
3355       int32_t uLen = wsTypeString.GetLength();
3356       while (*(pData + u) == 0x20 || *(pData + u) == 0x09 ||
3357              *(pData + u) == 0x0B || *(pData + u) == 0x0C ||
3358              *(pData + u) == 0x0A || *(pData + u) == 0x0D) {
3359         u++;
3360       }
3361       XFA_FM2JS_VALUETYPE_ParserStatus eParserStatus = VALUETYPE_START;
3362       FX_WCHAR typeChar;
3363       while (u < uLen) {
3364         typeChar = *(pData + u);
3365         if (typeChar == 0x20 || typeChar == 0x09 || typeChar == 0x0B ||
3366             typeChar == 0x0C || typeChar == 0x0A || typeChar == 0x0D) {
3367           if (eParserStatus == VALUETYPE_HAVEDIGIT ||
3368               eParserStatus == VALUETYPE_HAVEDIGITWHITE) {
3369             eParserStatus = VALUETYPE_HAVEDIGITWHITE;
3370           } else {
3371             eParserStatus = VALUETYPE_ISIN;
3372             break;
3373           }
3374         } else if ((typeChar >= '0' && typeChar <= '9') || typeChar == '-' ||
3375                    typeChar == '.') {
3376           if (eParserStatus == VALUETYPE_HAVEDIGITWHITE) {
3377             eParserStatus = VALUETYPE_ISIN;
3378             break;
3379           } else {
3380             eParserStatus = VALUETYPE_HAVEDIGIT;
3381           }
3382         } else if ((typeChar == 'c' || typeChar == 'p') && (u + 1 < uLen)) {
3383           FX_WCHAR nextChar = *(pData + u + 1);
3384           if ((eParserStatus == VALUETYPE_START ||
3385                eParserStatus == VALUETYPE_HAVEDIGIT ||
3386                eParserStatus == VALUETYPE_HAVEDIGITWHITE) &&
3387               (nextChar > '9' || nextChar < '0') && nextChar != '.' &&
3388               nextChar != '-') {
3389             eParserStatus = (typeChar == 'c') ? VALUETYPE_ISCM : VALUETYPE_ISPT;
3390             break;
3391           } else {
3392             eParserStatus = VALUETYPE_HAVEINVALIDCHAR;
3393           }
3394         } else if (typeChar == 'm' && (u + 1 < uLen)) {
3395           FX_WCHAR nextChar = *(pData + u + 1);
3396           if ((eParserStatus == VALUETYPE_START ||
3397                eParserStatus == VALUETYPE_HAVEDIGIT ||
3398                eParserStatus == VALUETYPE_HAVEDIGITWHITE) &&
3399               (nextChar > '9' || nextChar < '0') && nextChar != '.' &&
3400               nextChar != '-') {
3401             eParserStatus = VALUETYPE_ISMM;
3402             if (nextChar == 'p' ||
3403                 ((u + 5 < uLen) && *(pData + u + 1) == 'i' &&
3404                  *(pData + u + 2) == 'l' && *(pData + u + 3) == 'l' &&
3405                  *(pData + u + 4) == 'i' && *(pData + u + 5) == 'p')) {
3406               eParserStatus = VALUETYPE_ISMP;
3407             }
3408             break;
3409           }
3410         } else {
3411           eParserStatus = VALUETYPE_HAVEINVALIDCHAR;
3412         }
3413         u++;
3414       }
3415       switch (eParserStatus) {
3416         case VALUETYPE_ISCM:
3417           FXJSE_Value_SetUTF8String(args.GetReturnValue(), "cm");
3418           break;
3419         case VALUETYPE_ISMM:
3420           FXJSE_Value_SetUTF8String(args.GetReturnValue(), "mm");
3421           break;
3422         case VALUETYPE_ISPT:
3423           FXJSE_Value_SetUTF8String(args.GetReturnValue(), "pt");
3424           break;
3425         case VALUETYPE_ISMP:
3426           FXJSE_Value_SetUTF8String(args.GetReturnValue(), "mp");
3427           break;
3428         default:
3429           FXJSE_Value_SetUTF8String(args.GetReturnValue(), "in");
3430           break;
3431       }
3432     }
3433     FXJSE_Value_Release(unitspanValue);
3434   } else {
3435     CXFA_FM2JSContext* pContext =
3436         (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
3437     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
3438                                       L"UnitType");
3439   }
3440 }
UnitValue(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)3441 void CXFA_FM2JSContext::UnitValue(FXJSE_HOBJECT hThis,
3442                                   const CFX_ByteStringC& szFuncName,
3443                                   CFXJSE_Arguments& args) {
3444   int32_t argc = args.GetLength();
3445   if ((argc == 1) || (argc == 2)) {
3446     FXJSE_HVALUE unitspanValue = GetSimpleHValue(hThis, args, 0);
3447     FXJSE_HVALUE unitValue = 0;
3448     CFX_ByteString unitspanString;
3449     FX_DOUBLE dFirstNumber = 0;
3450     CFX_ByteString strFirstUnit;
3451     CFX_ByteString strUnit;
3452     if (FXJSE_Value_IsNull(unitspanValue)) {
3453       FXJSE_Value_SetNull(args.GetReturnValue());
3454     } else {
3455       HValueToUTF8String(unitspanValue, unitspanString);
3456       const FX_CHAR* pData = unitspanString;
3457       if (pData) {
3458         int32_t u = 0;
3459         while (*(pData + u) == 0x20 || *(pData + u) == 0x09 ||
3460                *(pData + u) == 0x0B || *(pData + u) == 0x0C ||
3461                *(pData + u) == 0x0A || *(pData + u) == 0x0D) {
3462           ++u;
3463         }
3464         while (u < unitspanString.GetLength()) {
3465           if ((*(pData + u) > '9' || *(pData + u) < '0') &&
3466               *(pData + u) != '.' && *(pData + u) != '-') {
3467             break;
3468           }
3469           ++u;
3470         }
3471         FX_CHAR* pTemp = NULL;
3472         dFirstNumber = strtod(pData, &pTemp);
3473         while (*(pData + u) == ' ' || *(pData + u) == 0x09 ||
3474                *(pData + u) == 0x0B || *(pData + u) == 0x0C ||
3475                *(pData + u) == 0x0A || *(pData + u) == 0x0D) {
3476           ++u;
3477         }
3478         int32_t uLen = unitspanString.GetLength();
3479         while (u < uLen) {
3480           if (*(pData + u) == ' ') {
3481             break;
3482           }
3483           strFirstUnit += (*(pData + u));
3484           ++u;
3485         }
3486         strFirstUnit.MakeLower();
3487         if (argc == 2) {
3488           unitValue = GetSimpleHValue(hThis, args, 1);
3489           CFX_ByteString unitTempString;
3490           HValueToUTF8String(unitValue, unitTempString);
3491           const FX_CHAR* pData = unitTempString;
3492           int32_t u = 0;
3493           while (*(pData + u) == ' ' || *(pData + u) == 0x09 ||
3494                  *(pData + u) == 0x0B || *(pData + u) == 0x0C ||
3495                  *(pData + u) == 0x0A || *(pData + u) == 0x0D) {
3496             ++u;
3497           }
3498           while (u < unitTempString.GetLength()) {
3499             if ((*(pData + u) > '9' || *(pData + u) < '0') &&
3500                 *(pData + u) != '.') {
3501               break;
3502             }
3503             ++u;
3504           }
3505           while (*(pData + u) == ' ' || *(pData + u) == 0x09 ||
3506                  *(pData + u) == 0x0B || *(pData + u) == 0x0C ||
3507                  *(pData + u) == 0x0A || *(pData + u) == 0x0D) {
3508             ++u;
3509           }
3510           int32_t uLen = unitTempString.GetLength();
3511           while (u < uLen) {
3512             if (*(pData + u) == ' ') {
3513               break;
3514             }
3515             strUnit += (*(pData + u));
3516             ++u;
3517           }
3518           strUnit.MakeLower();
3519         } else {
3520           strUnit = strFirstUnit;
3521         }
3522         FX_DOUBLE dResult = 0;
3523         if (strFirstUnit.Equal("in") || strFirstUnit.Equal("inches")) {
3524           if (strUnit.Equal("mm") || strUnit.Equal("millimeters")) {
3525             dResult = dFirstNumber * 25.4;
3526           } else if (strUnit.Equal("cm") || strUnit.Equal("centimeters")) {
3527             dResult = dFirstNumber * 2.54;
3528           } else if (strUnit.Equal("pt") || strUnit.Equal("points")) {
3529             dResult = dFirstNumber / 72;
3530           } else if (strUnit.Equal("mp") || strUnit.Equal("millipoints")) {
3531             dResult = dFirstNumber / 72000;
3532           } else {
3533             dResult = dFirstNumber;
3534           }
3535         } else if (strFirstUnit.Equal("mm") ||
3536                    strFirstUnit.Equal("millimeters")) {
3537           if (strUnit.Equal("mm") || strUnit.Equal("millimeters")) {
3538             dResult = dFirstNumber;
3539           } else if (strUnit.Equal("cm") || strUnit.Equal("centimeters")) {
3540             dResult = dFirstNumber / 10;
3541           } else if (strUnit.Equal("pt") || strUnit.Equal("points")) {
3542             dResult = dFirstNumber / 25.4 / 72;
3543           } else if (strUnit.Equal("mp") || strUnit.Equal("millipoints")) {
3544             dResult = dFirstNumber / 25.4 / 72000;
3545           } else {
3546             dResult = dFirstNumber / 25.4;
3547           }
3548         } else if (strFirstUnit.Equal("cm") ||
3549                    strFirstUnit.Equal("centimeters")) {
3550           if (strUnit.Equal("mm") || strUnit.Equal("millimeters")) {
3551             dResult = dFirstNumber * 10;
3552           } else if (strUnit.Equal("cm") || strUnit.Equal("centimeters")) {
3553             dResult = dFirstNumber;
3554           } else if (strUnit.Equal("pt") || strUnit.Equal("points")) {
3555             dResult = dFirstNumber / 2.54 / 72;
3556           } else if (strUnit.Equal("mp") || strUnit.Equal("millipoints")) {
3557             dResult = dFirstNumber / 2.54 / 72000;
3558           } else {
3559             dResult = dFirstNumber / 2.54;
3560           }
3561         } else if (strFirstUnit.Equal("pt") || strFirstUnit.Equal("points")) {
3562           if (strUnit.Equal("mm") || strUnit.Equal("millimeters")) {
3563             dResult = dFirstNumber / 72 * 25.4;
3564           } else if (strUnit.Equal("cm") || strUnit.Equal("centimeters")) {
3565             dResult = dFirstNumber / 72 * 2.54;
3566           } else if (strUnit.Equal("pt") || strUnit.Equal("points")) {
3567             dResult = dFirstNumber;
3568           } else if (strUnit.Equal("mp") || strUnit.Equal("millipoints")) {
3569             dResult = dFirstNumber * 1000;
3570           } else {
3571             dResult = dFirstNumber / 72;
3572           }
3573         } else if (strFirstUnit.Equal("mp") ||
3574                    strFirstUnit.Equal("millipoints")) {
3575           if (strUnit.Equal("mm") || strUnit.Equal("millimeters")) {
3576             dResult = dFirstNumber / 72000 * 25.4;
3577           } else if (strUnit.Equal("cm") || strUnit.Equal("centimeters")) {
3578             dResult = dFirstNumber / 72000 * 2.54;
3579           } else if (strUnit.Equal("pt") || strUnit.Equal("points")) {
3580             dResult = dFirstNumber / 1000;
3581           } else if (strUnit.Equal("mp") || strUnit.Equal("millipoints")) {
3582             dResult = dFirstNumber;
3583           } else {
3584             dResult = dFirstNumber / 72000;
3585           }
3586         }
3587         FXJSE_Value_SetDouble(args.GetReturnValue(), dResult);
3588       } else {
3589         FXJSE_Value_SetInteger(args.GetReturnValue(), 0);
3590       }
3591     }
3592     FXJSE_Value_Release(unitspanValue);
3593     if (argc == 2) {
3594       FXJSE_Value_Release(unitValue);
3595     }
3596   } else {
3597     CXFA_FM2JSContext* pContext =
3598         (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
3599     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
3600                                       L"UnitValue");
3601   }
3602 }
At(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)3603 void CXFA_FM2JSContext::At(FXJSE_HOBJECT hThis,
3604                            const CFX_ByteStringC& szFuncName,
3605                            CFXJSE_Arguments& args) {
3606   CXFA_FM2JSContext* pContext =
3607       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
3608   if (args.GetLength() == 2) {
3609     FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
3610     FXJSE_HVALUE argTwo = GetSimpleHValue(hThis, args, 1);
3611     if (HValueIsNull(hThis, argOne) || HValueIsNull(hThis, argTwo)) {
3612       FXJSE_Value_SetNull(args.GetReturnValue());
3613     } else {
3614       CFX_ByteString stringTwo;
3615       HValueToUTF8String(argTwo, stringTwo);
3616       if (stringTwo.IsEmpty()) {
3617         FXJSE_Value_SetInteger(args.GetReturnValue(), 1);
3618       } else {
3619         CFX_ByteString stringOne;
3620         HValueToUTF8String(argOne, stringOne);
3621         FX_STRSIZE iPosition = stringOne.Find(stringTwo);
3622         FXJSE_Value_SetInteger(args.GetReturnValue(), iPosition + 1);
3623       }
3624     }
3625     FXJSE_Value_Release(argOne);
3626     FXJSE_Value_Release(argTwo);
3627   } else {
3628     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
3629                                       L"At");
3630   }
3631 }
Concat(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)3632 void CXFA_FM2JSContext::Concat(FXJSE_HOBJECT hThis,
3633                                const CFX_ByteStringC& szFuncName,
3634                                CFXJSE_Arguments& args) {
3635   CXFA_FM2JSContext* pContext =
3636       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
3637   int32_t argc = args.GetLength();
3638   if (argc >= 1) {
3639     CFX_ByteString resultString;
3640     FX_BOOL bAllNull = TRUE;
3641     FXJSE_HVALUE* argValues = FX_Alloc(FXJSE_HVALUE, argc);
3642     for (int32_t i = 0; i < argc; i++) {
3643       argValues[i] = GetSimpleHValue(hThis, args, i);
3644       if (!HValueIsNull(hThis, argValues[i])) {
3645         CFX_ByteString valueStr;
3646         HValueToUTF8String(argValues[i], valueStr);
3647         resultString += valueStr;
3648         bAllNull = FALSE;
3649       }
3650     }
3651     for (int32_t i = 0; i < argc; i++) {
3652       FXJSE_Value_Release(argValues[i]);
3653     }
3654     FX_Free(argValues);
3655     if (bAllNull) {
3656       FXJSE_Value_SetNull(args.GetReturnValue());
3657     } else {
3658       FXJSE_Value_SetUTF8String(args.GetReturnValue(), resultString);
3659     }
3660   } else {
3661     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
3662                                       L"Concat");
3663   }
3664 }
Decode(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)3665 void CXFA_FM2JSContext::Decode(FXJSE_HOBJECT hThis,
3666                                const CFX_ByteStringC& szFuncName,
3667                                CFXJSE_Arguments& args) {
3668   CXFA_FM2JSContext* pContext =
3669       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
3670   int32_t argc = args.GetLength();
3671   if (argc == 1) {
3672     FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
3673     if (HValueIsNull(hThis, argOne)) {
3674       FXJSE_Value_SetNull(args.GetReturnValue());
3675     } else {
3676       CFX_ByteString toDecodeString;
3677       HValueToUTF8String(argOne, toDecodeString);
3678       CFX_ByteTextBuf resultBuf;
3679       DecodeURL(toDecodeString, resultBuf);
3680       FXJSE_Value_SetUTF8String(args.GetReturnValue(),
3681                                 resultBuf.GetByteString());
3682     }
3683     FXJSE_Value_Release(argOne);
3684   } else if (argc == 2) {
3685     FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
3686     FXJSE_HVALUE argTwo = GetSimpleHValue(hThis, args, 1);
3687     if (HValueIsNull(hThis, argOne) || HValueIsNull(hThis, argTwo)) {
3688       FXJSE_Value_SetNull(args.GetReturnValue());
3689     } else {
3690       CFX_ByteString toDecodeString;
3691       HValueToUTF8String(argOne, toDecodeString);
3692       CFX_ByteString identifyString;
3693       HValueToUTF8String(argTwo, identifyString);
3694       CFX_ByteTextBuf resultBuf;
3695       if (identifyString.EqualNoCase("html")) {
3696         DecodeHTML(toDecodeString, resultBuf);
3697       } else if (identifyString.EqualNoCase("xml")) {
3698         DecodeXML(toDecodeString, resultBuf);
3699       } else {
3700         DecodeURL(toDecodeString, resultBuf);
3701       }
3702       FXJSE_Value_SetUTF8String(args.GetReturnValue(),
3703                                 resultBuf.GetByteString());
3704     }
3705     FXJSE_Value_Release(argOne);
3706     FXJSE_Value_Release(argTwo);
3707   } else {
3708     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
3709                                       L"Decode");
3710   }
3711 }
DecodeURL(const CFX_ByteStringC & szURLString,CFX_ByteTextBuf & szResultString)3712 void CXFA_FM2JSContext::DecodeURL(const CFX_ByteStringC& szURLString,
3713                                   CFX_ByteTextBuf& szResultString) {
3714   CFX_WideString wsURLString =
3715       CFX_WideString::FromUTF8(szURLString.GetCStr(), szURLString.GetLength());
3716   const FX_WCHAR* pData = wsURLString;
3717   int32_t iLen = wsURLString.GetLength();
3718   int32_t i = 0;
3719   FX_WCHAR ch = 0;
3720   FX_WCHAR chTemp = 0;
3721   CFX_WideTextBuf wsResultBuf;
3722   while (i < iLen) {
3723     ch = *(pData + i);
3724     if ('%' == ch) {
3725       chTemp = 0;
3726       int32_t iCount = 0;
3727       while (iCount < 2) {
3728         ++i;
3729         ch = *(pData + i);
3730         if (ch <= '9' && ch >= '0') {
3731           if (!iCount) {
3732             chTemp += (ch - '0') * 16;
3733           } else {
3734             chTemp += (ch - '0');
3735           }
3736         } else {
3737           if (ch <= 'F' && ch >= 'A') {
3738             if (!iCount) {
3739               chTemp += (ch - 'A' + 10) * 16;
3740             } else {
3741               chTemp += (ch - 'A' + 10);
3742             }
3743           } else if (ch <= 'f' && ch >= 'a') {
3744             if (!iCount) {
3745               chTemp += (ch - 'a' + 10) * 16;
3746             } else {
3747               chTemp += (ch - 'a' + 10);
3748             }
3749           } else {
3750             wsResultBuf.Clear();
3751             return;
3752           }
3753         }
3754         ++iCount;
3755       }
3756       wsResultBuf.AppendChar(chTemp);
3757     } else {
3758       wsResultBuf.AppendChar(ch);
3759     }
3760     ++i;
3761   }
3762   wsResultBuf.AppendChar(0);
3763   szResultString =
3764       FX_UTF8Encode(wsResultBuf.GetBuffer(), wsResultBuf.GetLength());
3765 }
DecodeHTML(const CFX_ByteStringC & szHTMLString,CFX_ByteTextBuf & szResultString)3766 void CXFA_FM2JSContext::DecodeHTML(const CFX_ByteStringC& szHTMLString,
3767                                    CFX_ByteTextBuf& szResultString) {
3768   CFX_WideString wsHTMLString = CFX_WideString::FromUTF8(
3769       szHTMLString.GetCStr(), szHTMLString.GetLength());
3770   FX_WCHAR strString[9];
3771   int32_t iStrIndex = 0;
3772   int32_t iLen = wsHTMLString.GetLength();
3773   int32_t i = 0;
3774   int32_t iCode = 0;
3775   FX_WCHAR ch = 0;
3776   const FX_WCHAR* pData = wsHTMLString;
3777   CFX_WideTextBuf wsResultBuf;
3778   while (i < iLen) {
3779     ch = *(pData + i);
3780     if (ch == '&') {
3781       ++i;
3782       ch = *(pData + i);
3783       if (ch == '#') {
3784         ++i;
3785         ch = *(pData + i);
3786         if (ch == 'x' || ch == 'X') {
3787           ++i;
3788           ch = *(pData + i);
3789           if ((ch >= '0' && ch <= '9') || (ch <= 'f' && ch >= 'a') ||
3790               (ch <= 'F' && ch >= 'A')) {
3791             while (ch != ';' && i < iLen) {
3792               if (ch >= '0' && ch <= '9') {
3793                 iCode += ch - '0';
3794               } else if (ch <= 'f' && ch >= 'a') {
3795                 iCode += ch - 'a' + 10;
3796               } else if (ch <= 'F' && ch >= 'A') {
3797                 iCode += ch - 'A' + 10;
3798               } else {
3799                 wsResultBuf.Clear();
3800                 return;
3801               }
3802               ++i;
3803               iCode *= 16;
3804               ch = *(pData + i);
3805             }
3806             iCode /= 16;
3807           }
3808         } else {
3809           wsResultBuf.Clear();
3810           return;
3811         }
3812       } else {
3813         while (ch != ';' && i < iLen) {
3814           strString[iStrIndex++] = ch;
3815           ++i;
3816           ch = *(pData + i);
3817         }
3818         strString[iStrIndex] = 0;
3819       }
3820     } else {
3821       wsResultBuf.AppendChar(ch);
3822       ++i;
3823       continue;
3824     }
3825     uint32_t iData = 0;
3826     if (HTMLSTR2Code(strString, iData)) {
3827       wsResultBuf.AppendChar((FX_WCHAR)iData);
3828     } else {
3829       wsResultBuf.AppendChar(iCode);
3830     }
3831     iStrIndex = 0;
3832     strString[iStrIndex] = 0;
3833     ++i;
3834   }
3835   wsResultBuf.AppendChar(0);
3836   szResultString =
3837       FX_UTF8Encode(wsResultBuf.GetBuffer(), wsResultBuf.GetLength());
3838 }
DecodeXML(const CFX_ByteStringC & szXMLString,CFX_ByteTextBuf & szResultString)3839 void CXFA_FM2JSContext::DecodeXML(const CFX_ByteStringC& szXMLString,
3840                                   CFX_ByteTextBuf& szResultString) {
3841   CFX_WideString wsXMLString =
3842       CFX_WideString::FromUTF8(szXMLString.GetCStr(), szXMLString.GetLength());
3843   FX_WCHAR strString[9];
3844   int32_t iStrIndex = 0;
3845   int32_t iLen = wsXMLString.GetLength();
3846   int32_t i = 0;
3847   int32_t iCode = 0;
3848   FX_WCHAR ch = 0;
3849   const FX_WCHAR* pData = wsXMLString;
3850   CFX_WideTextBuf wsXMLBuf;
3851   while (i < iLen) {
3852     ch = *(pData + i);
3853     if (ch == '&') {
3854       ++i;
3855       ch = *(pData + i);
3856       if (ch == '#') {
3857         ++i;
3858         ch = *(pData + i);
3859         if (ch == 'x' || ch == 'X') {
3860           ++i;
3861           ch = *(pData + i);
3862           if ((ch >= '0' && ch <= '9') || (ch <= 'f' && ch >= 'a') ||
3863               (ch <= 'F' && ch >= 'A')) {
3864             while (ch != ';') {
3865               if (ch >= '0' && ch <= '9') {
3866                 iCode += ch - '0';
3867               } else if (ch <= 'f' && ch >= 'a') {
3868                 iCode += ch - 'a' + 10;
3869               } else if (ch <= 'F' && ch >= 'A') {
3870                 iCode += ch - 'A' + 10;
3871               } else {
3872                 wsXMLBuf.Clear();
3873                 return;
3874               }
3875               ++i;
3876               iCode *= 16;
3877               ch = *(pData + i);
3878             }
3879             iCode /= 16;
3880           }
3881         } else {
3882           wsXMLBuf.Clear();
3883           return;
3884         }
3885       } else {
3886         while (ch != ';' && i < iLen) {
3887           strString[iStrIndex++] = ch;
3888           ++i;
3889           ch = *(pData + i);
3890         }
3891         strString[iStrIndex] = 0;
3892       }
3893     } else {
3894       wsXMLBuf.AppendChar(ch);
3895       ++i;
3896       continue;
3897     }
3898     const FX_WCHAR* const strName[] = {L"quot", L"amp", L"apos", L"lt", L"gt"};
3899     int32_t iIndex = 0;
3900     while (iIndex < 5) {
3901       if (FXSYS_memcmp(strString, strName[iIndex],
3902                        FXSYS_wcslen(strName[iIndex])) == 0) {
3903         break;
3904       }
3905       ++iIndex;
3906     }
3907     switch (iIndex) {
3908       case 0:
3909         wsXMLBuf.AppendChar('"');
3910         break;
3911       case 1:
3912         wsXMLBuf.AppendChar('&');
3913         break;
3914       case 2:
3915         wsXMLBuf.AppendChar('\'');
3916         break;
3917       case 3:
3918         wsXMLBuf.AppendChar('<');
3919         break;
3920       case 4:
3921         wsXMLBuf.AppendChar('>');
3922         break;
3923       default:
3924         wsXMLBuf.AppendChar(iCode);
3925         break;
3926     }
3927     iStrIndex = 0;
3928     strString[iStrIndex] = 0;
3929     ++i;
3930     iCode = 0;
3931   }
3932   wsXMLBuf.AppendChar(0);
3933   szResultString = FX_UTF8Encode(wsXMLBuf.GetBuffer(), wsXMLBuf.GetLength());
3934 }
Encode(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)3935 void CXFA_FM2JSContext::Encode(FXJSE_HOBJECT hThis,
3936                                const CFX_ByteStringC& szFuncName,
3937                                CFXJSE_Arguments& args) {
3938   CXFA_FM2JSContext* pContext =
3939       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
3940   int32_t argc = args.GetLength();
3941   if (argc == 1) {
3942     FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
3943     if (HValueIsNull(hThis, argOne)) {
3944       FXJSE_Value_SetNull(args.GetReturnValue());
3945     } else {
3946       CFX_ByteString toEncodeString;
3947       HValueToUTF8String(argOne, toEncodeString);
3948       CFX_ByteTextBuf resultBuf;
3949       EncodeURL(toEncodeString, resultBuf);
3950       FXJSE_Value_SetUTF8String(args.GetReturnValue(),
3951                                 resultBuf.GetByteString());
3952     }
3953     FXJSE_Value_Release(argOne);
3954   } else if (argc == 2) {
3955     FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
3956     FXJSE_HVALUE argTwo = GetSimpleHValue(hThis, args, 1);
3957     if (HValueIsNull(hThis, argOne) || HValueIsNull(hThis, argTwo)) {
3958       FXJSE_Value_SetNull(args.GetReturnValue());
3959     } else {
3960       CFX_ByteString toEncodeString;
3961       HValueToUTF8String(argOne, toEncodeString);
3962       CFX_ByteString identifyString;
3963       HValueToUTF8String(argTwo, identifyString);
3964       CFX_ByteTextBuf resultBuf;
3965       if (identifyString.EqualNoCase("html")) {
3966         EncodeHTML(toEncodeString, resultBuf);
3967       } else if (identifyString.EqualNoCase("xml")) {
3968         EncodeXML(toEncodeString, resultBuf);
3969       } else {
3970         EncodeURL(toEncodeString, resultBuf);
3971       }
3972       FXJSE_Value_SetUTF8String(args.GetReturnValue(),
3973                                 resultBuf.GetByteString());
3974     }
3975     FXJSE_Value_Release(argOne);
3976     FXJSE_Value_Release(argTwo);
3977   } else {
3978     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
3979                                       L"Encode");
3980   }
3981 }
EncodeURL(const CFX_ByteStringC & szURLString,CFX_ByteTextBuf & szResultBuf)3982 void CXFA_FM2JSContext::EncodeURL(const CFX_ByteStringC& szURLString,
3983                                   CFX_ByteTextBuf& szResultBuf) {
3984   CFX_WideString wsURLString =
3985       CFX_WideString::FromUTF8(szURLString.GetCStr(), szURLString.GetLength());
3986   CFX_WideTextBuf wsResultBuf;
3987   FX_WCHAR ch = 0;
3988   int32_t iLength = wsURLString.GetLength();
3989   FX_WCHAR strEncode[4];
3990   strEncode[0] = '%';
3991   strEncode[3] = 0;
3992   FX_WCHAR strUnsafe[] = {' ', '<',  '>', '"', '#', '%', '{', '}',
3993                           '|', '\\', '^', '~', '[', ']', '`'};
3994   FX_WCHAR strReserved[] = {';', '/', '?', ':', '@', '=', '&'};
3995   FX_WCHAR strSpecial[] = {'$', '-', '+', '!', '*', '\'', '(', ')', ','};
3996   const FX_WCHAR* strCode = L"0123456789abcdef";
3997   for (int32_t u = 0; u < iLength; ++u) {
3998     ch = wsURLString.GetAt(u);
3999     int32_t i = 0;
4000     int32_t iCount = sizeof(strUnsafe) / sizeof(strUnsafe[0]);
4001     while (i < iCount) {
4002       if (ch == strUnsafe[i]) {
4003         int32_t iIndex = ch / 16;
4004         strEncode[1] = strCode[iIndex];
4005         strEncode[2] = strCode[ch - iIndex * 16];
4006         wsResultBuf << FX_WSTRC(strEncode);
4007         break;
4008       }
4009       ++i;
4010     }
4011     if (i < iCount) {
4012       continue;
4013     }
4014     i = 0;
4015     iCount = sizeof(strReserved) / sizeof(strReserved[0]);
4016     while (i < iCount) {
4017       if (ch == strReserved[i]) {
4018         int32_t iIndex = ch / 16;
4019         strEncode[1] = strCode[iIndex];
4020         strEncode[2] = strCode[ch - iIndex * 16];
4021         wsResultBuf << FX_WSTRC(strEncode);
4022         break;
4023       }
4024       ++i;
4025     }
4026     if (i < iCount) {
4027       continue;
4028     }
4029     i = 0;
4030     iCount = sizeof(strSpecial) / sizeof(strSpecial[0]);
4031     while (i < iCount) {
4032       if (ch == strSpecial[i]) {
4033         wsResultBuf.AppendChar(ch);
4034         break;
4035       }
4036       ++i;
4037     }
4038     if (i < iCount) {
4039       continue;
4040     }
4041     if (ch >= 0x80 && ch <= 0xff) {
4042       int32_t iIndex = ch / 16;
4043       strEncode[1] = strCode[iIndex];
4044       strEncode[2] = strCode[ch - iIndex * 16];
4045       wsResultBuf << FX_WSTRC(strEncode);
4046     } else if ((ch >= 0x0 && ch <= 0x1f) || ch == 0x7f) {
4047       int32_t iIndex = ch / 16;
4048       strEncode[1] = strCode[iIndex];
4049       strEncode[2] = strCode[ch - iIndex * 16];
4050       wsResultBuf << FX_WSTRC(strEncode);
4051     } else if (ch >= 0x20 && ch <= 0x7e) {
4052       wsResultBuf.AppendChar(ch);
4053     } else {
4054       int32_t iRadix = 16;
4055       CFX_WideString strTmp;
4056       while (ch >= iRadix) {
4057         FX_WCHAR tmp = strCode[ch % iRadix];
4058         ch /= iRadix;
4059         strTmp += tmp;
4060       }
4061       strTmp += strCode[ch];
4062       int32_t iLen = strTmp.GetLength();
4063       if (iLen < 2) {
4064         break;
4065       }
4066       int32_t iIndex = 0;
4067       if (iLen % 2 != 0) {
4068         strEncode[1] = '0';
4069         strEncode[2] = strTmp.GetAt(iLen - 1);
4070         iIndex = iLen - 2;
4071       } else {
4072         strEncode[1] = strTmp.GetAt(iLen - 1);
4073         strEncode[2] = strTmp.GetAt(iLen - 2);
4074         iIndex = iLen - 3;
4075       }
4076       wsResultBuf << FX_WSTRC(strEncode);
4077       while (iIndex > 0) {
4078         strEncode[1] = strTmp.GetAt(iIndex);
4079         strEncode[2] = strTmp.GetAt(iIndex - 1);
4080         iIndex -= 2;
4081         wsResultBuf << FX_WSTRC(strEncode);
4082       }
4083     }
4084   }
4085   wsResultBuf.AppendChar(0);
4086   szResultBuf = FX_UTF8Encode(wsResultBuf.GetBuffer(), wsResultBuf.GetLength());
4087 }
EncodeHTML(const CFX_ByteStringC & szHTMLString,CFX_ByteTextBuf & szResultBuf)4088 void CXFA_FM2JSContext::EncodeHTML(const CFX_ByteStringC& szHTMLString,
4089                                    CFX_ByteTextBuf& szResultBuf) {
4090   CFX_ByteString str = szHTMLString.GetCStr();
4091   CFX_WideString wsHTMLString = CFX_WideString::FromUTF8(str, str.GetLength());
4092   const FX_WCHAR* strCode = L"0123456789abcdef";
4093   FX_WCHAR strEncode[9];
4094   strEncode[0] = '&';
4095   strEncode[1] = '#';
4096   strEncode[2] = 'x';
4097   strEncode[5] = ';';
4098   strEncode[6] = 0;
4099   strEncode[7] = ';';
4100   strEncode[8] = 0;
4101   CFX_WideTextBuf wsResultBuf;
4102   uint32_t ch = 0;
4103   int32_t iLen = wsHTMLString.GetLength();
4104   int32_t i = 0;
4105   const FX_WCHAR* pData = wsHTMLString;
4106   int32_t iIndex = 0;
4107   CFX_WideString htmlReserve;
4108   while (i < iLen) {
4109     ch = *(pData + i);
4110     htmlReserve.Empty();
4111     if (HTMLCode2STR(ch, htmlReserve)) {
4112       wsResultBuf.AppendChar(L'&');
4113       wsResultBuf << htmlReserve;
4114       wsResultBuf.AppendChar(L';');
4115     } else {
4116       if (ch >= 32 && ch <= 126) {
4117         wsResultBuf.AppendChar((FX_WCHAR)ch);
4118       } else if (ch < 256) {
4119         iIndex = ch / 16;
4120         strEncode[3] = strCode[iIndex];
4121         strEncode[4] = strCode[ch - iIndex * 16];
4122         strEncode[5] = ';';
4123         strEncode[6] = 0;
4124         wsResultBuf << FX_WSTRC(strEncode);
4125       } else {
4126         int32_t iBigByte = ch / 256;
4127         int32_t iLittleByte = ch % 256;
4128         strEncode[3] = strCode[iBigByte / 16];
4129         strEncode[4] = strCode[iBigByte % 16];
4130         strEncode[5] = strCode[iLittleByte / 16];
4131         strEncode[6] = strCode[iLittleByte % 16];
4132         wsResultBuf << FX_WSTRC(strEncode);
4133       }
4134     }
4135     ++i;
4136   }
4137   wsResultBuf.AppendChar(0);
4138   szResultBuf = FX_UTF8Encode(wsResultBuf.GetBuffer(), wsResultBuf.GetLength());
4139 }
EncodeXML(const CFX_ByteStringC & szXMLString,CFX_ByteTextBuf & szResultBuf)4140 void CXFA_FM2JSContext::EncodeXML(const CFX_ByteStringC& szXMLString,
4141                                   CFX_ByteTextBuf& szResultBuf) {
4142   CFX_WideString wsXMLString =
4143       CFX_WideString::FromUTF8(szXMLString.GetCStr(), szXMLString.GetLength());
4144   CFX_WideTextBuf wsResultBuf;
4145   enum {
4146     QUOT,
4147     AMP,
4148     APOS,
4149     LT,
4150     GT,
4151   };
4152   FX_WCHAR strEncode[9];
4153   strEncode[0] = '&';
4154   strEncode[1] = '#';
4155   strEncode[2] = 'x';
4156   strEncode[5] = ';';
4157   strEncode[6] = 0;
4158   strEncode[7] = ';';
4159   strEncode[8] = 0;
4160   const FX_WCHAR* const strName[] = {L"quot", L"amp", L"apos", L"lt", L"gt"};
4161   const FX_WCHAR* strCode = L"0123456789abcdef";
4162   FX_WCHAR ch = 0;
4163   int32_t iLength = wsXMLString.GetLength();
4164   int32_t iIndex = 0;
4165   int32_t u = 0;
4166   const FX_WCHAR* pData = wsXMLString;
4167   for (u = 0; u < iLength; ++u) {
4168     ch = *(pData + u);
4169     switch (ch) {
4170       case '"':
4171         wsResultBuf.AppendChar('&');
4172         wsResultBuf << CFX_WideStringC(strName[QUOT]);
4173         wsResultBuf.AppendChar(';');
4174         break;
4175       case '&':
4176         wsResultBuf.AppendChar('&');
4177         wsResultBuf << CFX_WideStringC(strName[AMP]);
4178         wsResultBuf.AppendChar(';');
4179         break;
4180       case '\'':
4181         wsResultBuf.AppendChar('&');
4182         wsResultBuf << CFX_WideStringC(strName[APOS]);
4183         wsResultBuf.AppendChar(';');
4184         break;
4185       case '<':
4186         wsResultBuf.AppendChar('&');
4187         wsResultBuf << CFX_WideStringC(strName[LT]);
4188         wsResultBuf.AppendChar(';');
4189         break;
4190       case '>':
4191         wsResultBuf.AppendChar('&');
4192         wsResultBuf << CFX_WideStringC(strName[GT]);
4193         wsResultBuf.AppendChar(';');
4194         break;
4195       default: {
4196         if (ch >= 32 && ch <= 126) {
4197           wsResultBuf.AppendChar(ch);
4198         } else if (ch < 256) {
4199           iIndex = ch / 16;
4200           strEncode[3] = strCode[iIndex];
4201           strEncode[4] = strCode[ch - iIndex * 16];
4202           strEncode[5] = ';';
4203           strEncode[6] = 0;
4204           wsResultBuf << FX_WSTRC(strEncode);
4205         } else {
4206           int32_t iBigByte = ch / 256;
4207           int32_t iLittleByte = ch % 256;
4208           strEncode[3] = strCode[iBigByte / 16];
4209           strEncode[4] = strCode[iBigByte % 16];
4210           strEncode[5] = strCode[iLittleByte / 16];
4211           strEncode[6] = strCode[iLittleByte % 16];
4212           wsResultBuf << FX_WSTRC(strEncode);
4213         }
4214       } break;
4215     }
4216   }
4217   wsResultBuf.AppendChar(0);
4218   szResultBuf = FX_UTF8Encode(wsResultBuf.GetBuffer(), wsResultBuf.GetLength());
4219 }
HTMLSTR2Code(const CFX_WideStringC & pData,uint32_t & iCode)4220 FX_BOOL CXFA_FM2JSContext::HTMLSTR2Code(const CFX_WideStringC& pData,
4221                                         uint32_t& iCode) {
4222   int32_t iLength = pData.GetLength();
4223   uint32_t uHash = FX_HashCode_String_GetW(pData.GetPtr(), iLength);
4224   XFA_FMHtmlHashedReserveCode htmlhashedreservecode;
4225   int32_t iStart = 0,
4226           iEnd = (sizeof(reservesForDecode) / sizeof(reservesForDecode[0])) - 1;
4227   int32_t iMid = (iStart + iEnd) / 2;
4228   do {
4229     iMid = (iStart + iEnd) / 2;
4230     htmlhashedreservecode = reservesForDecode[iMid];
4231     if (uHash == htmlhashedreservecode.m_uHash) {
4232       iCode = htmlhashedreservecode.m_uCode;
4233       return TRUE;
4234     } else if (uHash < htmlhashedreservecode.m_uHash) {
4235       iEnd = iMid - 1;
4236     } else {
4237       iStart = iMid + 1;
4238     }
4239   } while (iStart <= iEnd);
4240   return FALSE;
4241 }
HTMLCode2STR(uint32_t iCode,CFX_WideString & wsHTMLReserve)4242 FX_BOOL CXFA_FM2JSContext::HTMLCode2STR(uint32_t iCode,
4243                                         CFX_WideString& wsHTMLReserve) {
4244   XFA_FMHtmlReserveCode htmlreservecode;
4245   int32_t iStart = 0,
4246           iEnd = (sizeof(reservesForEncode) / sizeof(reservesForEncode[0])) - 1;
4247   int32_t iMid = (iStart + iEnd) / 2;
4248   do {
4249     iMid = (iStart + iEnd) / 2;
4250     htmlreservecode = reservesForEncode[iMid];
4251     if (iCode == htmlreservecode.m_uCode) {
4252       wsHTMLReserve = htmlreservecode.m_htmlReserve;
4253       return TRUE;
4254     } else if (iCode < htmlreservecode.m_uCode) {
4255       iEnd = iMid - 1;
4256     } else {
4257       iStart = iMid + 1;
4258     }
4259   } while (iStart <= iEnd);
4260   return FALSE;
4261 }
XFA_PATTERN_STRING_Type(const CFX_ByteStringC & szPattern,FX_DWORD & patternType)4262 static FX_BOOL XFA_PATTERN_STRING_Type(const CFX_ByteStringC& szPattern,
4263                                        FX_DWORD& patternType) {
4264   CFX_WideString wsPattern =
4265       CFX_WideString::FromUTF8(szPattern.GetCStr(), szPattern.GetLength());
4266   if (FX_WSTRC(L"datetime") == wsPattern.Left(8)) {
4267     patternType = XFA_VT_DATETIME;
4268     return TRUE;
4269   } else if (FX_WSTRC(L"date") == wsPattern.Left(4)) {
4270     patternType = wsPattern.Find(L"time") > 0 ? XFA_VT_DATETIME : XFA_VT_DATE;
4271     return TRUE;
4272   } else if (FX_WSTRC(L"time") == wsPattern.Left(4)) {
4273     patternType = XFA_VT_TIME;
4274     return TRUE;
4275   } else if (FX_WSTRC(L"text") == wsPattern.Left(4)) {
4276     patternType = XFA_VT_TEXT;
4277     return TRUE;
4278   } else if (FX_WSTRC(L"num") == wsPattern.Left(3)) {
4279     if (FX_WSTRC(L"integer") == wsPattern.Mid(4, 7)) {
4280       patternType = XFA_VT_INTEGER;
4281     } else if (FX_WSTRC(L"decimal") == wsPattern.Mid(4, 7)) {
4282       patternType = XFA_VT_DECIMAL;
4283     } else if (FX_WSTRC(L"currency") == wsPattern.Mid(4, 8)) {
4284       patternType = XFA_VT_FLOAT;
4285     } else if (FX_WSTRC(L"percent") == wsPattern.Mid(4, 7)) {
4286       patternType = XFA_VT_FLOAT;
4287     } else {
4288       patternType = XFA_VT_FLOAT;
4289     }
4290     return TRUE;
4291   }
4292   patternType = XFA_VT_NULL;
4293   wsPattern.MakeLower();
4294   const FX_WCHAR* pData = wsPattern;
4295   int32_t iLength = wsPattern.GetLength();
4296   int32_t iIndex = 0;
4297   FX_BOOL bSingleQuotation = FALSE;
4298   FX_WCHAR patternChar;
4299   while (iIndex < iLength) {
4300     patternChar = *(pData + iIndex);
4301     if (patternChar == 0x27) {
4302       bSingleQuotation = !bSingleQuotation;
4303     } else if (!bSingleQuotation &&
4304                (patternChar == 'y' || patternChar == 'j')) {
4305       patternType = XFA_VT_DATE;
4306       iIndex++;
4307       FX_WCHAR timePatternChar;
4308       while (iIndex < iLength) {
4309         timePatternChar = *(pData + iIndex);
4310         if (timePatternChar == 0x27) {
4311           bSingleQuotation = !bSingleQuotation;
4312         } else if (!bSingleQuotation && timePatternChar == 't') {
4313           patternType = XFA_VT_DATETIME;
4314           break;
4315         }
4316         iIndex++;
4317       }
4318       break;
4319     } else if (!bSingleQuotation &&
4320                (patternChar == 'h' || patternChar == 'k')) {
4321       patternType = XFA_VT_TIME;
4322       break;
4323     } else if (!bSingleQuotation &&
4324                (patternChar == 'a' || patternChar == 'x' ||
4325                 patternChar == 'o' || patternChar == '0')) {
4326       patternType = XFA_VT_TEXT;
4327       if (patternChar == 'x' || patternChar == 'o' || patternChar == '0') {
4328         break;
4329       }
4330     } else if (!bSingleQuotation &&
4331                (patternChar == 'z' || patternChar == 's' ||
4332                 patternChar == 'e' || patternChar == 'v' ||
4333                 patternChar == '8' || patternChar == ',' ||
4334                 patternChar == '.' || patternChar == '$')) {
4335       patternType = XFA_VT_FLOAT;
4336       if (patternChar == 'v' || patternChar == '8' || patternChar == '$') {
4337         break;
4338       }
4339     }
4340     iIndex++;
4341   }
4342   if (patternType == XFA_VT_NULL) {
4343     patternType = XFA_VT_TEXT | XFA_VT_FLOAT;
4344   }
4345   return FALSE;
4346 }
Format(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)4347 void CXFA_FM2JSContext::Format(FXJSE_HOBJECT hThis,
4348                                const CFX_ByteStringC& szFuncName,
4349                                CFXJSE_Arguments& args) {
4350   CXFA_FM2JSContext* pContext =
4351       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
4352   int32_t argc = args.GetLength();
4353   if (argc >= 2) {
4354     FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
4355     FXJSE_HVALUE argTwo = GetSimpleHValue(hThis, args, 1);
4356     CFX_ByteString szPattern;
4357     HValueToUTF8String(argOne, szPattern);
4358     CFX_ByteString szValue;
4359     HValueToUTF8String(argTwo, szValue);
4360     CXFA_Document* pDoc = pContext->GetDocument();
4361     IFX_LocaleMgr* pMgr = (IFX_LocaleMgr*)pDoc->GetLocalMgr();
4362     CXFA_Object* pThisNode = pDoc->GetScriptContext()->GetThisObject();
4363     FXSYS_assert(pThisNode->IsNode());
4364     CXFA_WidgetData widgetData((CXFA_Node*)pThisNode);
4365     IFX_Locale* pLocale = widgetData.GetLocal();
4366     FX_DWORD patternType;
4367     FX_BOOL bCompelte = XFA_PATTERN_STRING_Type(szPattern, patternType);
4368     CFX_WideString wsPattern =
4369         CFX_WideString::FromUTF8(szPattern, szPattern.GetLength());
4370     CFX_WideString wsValue =
4371         CFX_WideString::FromUTF8(szValue, szValue.GetLength());
4372     if (!bCompelte) {
4373       switch (patternType) {
4374         case XFA_VT_DATETIME: {
4375           FX_STRSIZE iTChar = wsPattern.Find(L'T');
4376           CFX_WideString wsDatePattern = FX_WSTRC(L"date{");
4377           wsDatePattern += wsPattern.Left(iTChar);
4378           wsDatePattern += FX_WSTRC(L"} ");
4379           CFX_WideString wsTimePattern = FX_WSTRC(L"time{");
4380           wsTimePattern += wsPattern.Mid(iTChar + 1);
4381           wsTimePattern += FX_WSTRC(L"}");
4382           wsPattern = wsDatePattern + wsTimePattern;
4383         } break;
4384         case XFA_VT_DATE: {
4385           wsPattern = FX_WSTRC(L"date{") + wsPattern;
4386           wsPattern += FX_WSTRC(L"}");
4387         } break;
4388         case XFA_VT_TIME: {
4389           wsPattern = FX_WSTRC(L"time{") + wsPattern;
4390           wsPattern += FX_WSTRC(L"}");
4391         } break;
4392         case XFA_VT_TEXT: {
4393           wsPattern = FX_WSTRC(L"text{") + wsPattern;
4394           wsPattern += FX_WSTRC(L"}");
4395         } break;
4396         case XFA_VT_FLOAT: {
4397           wsPattern = FX_WSTRC(L"num{") + wsPattern;
4398           wsPattern += FX_WSTRC(L"}");
4399         } break;
4400         default: {
4401           CFX_WideString wsTestPattern;
4402           wsTestPattern = FX_WSTRC(L"num{") + wsPattern;
4403           wsTestPattern += FX_WSTRC(L"}");
4404           CXFA_LocaleValue tempLocaleValue(XFA_VT_FLOAT, wsValue, wsTestPattern,
4405                                            pLocale, (CXFA_LocaleMgr*)pMgr);
4406           if (tempLocaleValue.IsValid()) {
4407             wsPattern = wsTestPattern;
4408             patternType = XFA_VT_FLOAT;
4409           } else {
4410             wsTestPattern = FX_WSTRC(L"text{") + wsPattern;
4411             wsTestPattern += FX_WSTRC(L"}");
4412             wsPattern = wsTestPattern;
4413             patternType = XFA_VT_TEXT;
4414           }
4415         } break;
4416       }
4417     }
4418     CXFA_LocaleValue localeValue(patternType, wsValue, wsPattern, pLocale,
4419                                  (CXFA_LocaleMgr*)pMgr);
4420     CFX_WideString wsRet;
4421     if (localeValue.FormatPatterns(wsRet, wsPattern, pLocale,
4422                                    XFA_VALUEPICTURE_Display)) {
4423       FXJSE_Value_SetUTF8String(args.GetReturnValue(),
4424                                 FX_UTF8Encode(wsRet, wsRet.GetLength()));
4425     } else {
4426       FXJSE_Value_SetUTF8String(args.GetReturnValue(), "");
4427     }
4428     FXJSE_Value_Release(argOne);
4429     FXJSE_Value_Release(argTwo);
4430   } else {
4431     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
4432                                       L"Format");
4433   }
4434 }
Left(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)4435 void CXFA_FM2JSContext::Left(FXJSE_HOBJECT hThis,
4436                              const CFX_ByteStringC& szFuncName,
4437                              CFXJSE_Arguments& args) {
4438   CXFA_FM2JSContext* pContext =
4439       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
4440   if (args.GetLength() == 2) {
4441     FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
4442     FXJSE_HVALUE argTwo = GetSimpleHValue(hThis, args, 1);
4443     FX_BOOL argIsNull = FALSE;
4444     if ((HValueIsNull(hThis, argOne)) || (HValueIsNull(hThis, argTwo))) {
4445       argIsNull = TRUE;
4446     }
4447     if (argIsNull) {
4448       FXJSE_Value_SetNull(args.GetReturnValue());
4449     } else {
4450       CFX_ByteString sourceString;
4451       HValueToUTF8String(argOne, sourceString);
4452       int32_t count = HValueToInteger(hThis, argTwo);
4453       if (count < 0) {
4454         count = 0;
4455       }
4456       FXJSE_Value_SetUTF8String(args.GetReturnValue(),
4457                                 sourceString.Left(count));
4458     }
4459     FXJSE_Value_Release(argOne);
4460     FXJSE_Value_Release(argTwo);
4461   } else {
4462     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
4463                                       L"Left");
4464   }
4465 }
Len(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)4466 void CXFA_FM2JSContext::Len(FXJSE_HOBJECT hThis,
4467                             const CFX_ByteStringC& szFuncName,
4468                             CFXJSE_Arguments& args) {
4469   CXFA_FM2JSContext* pContext =
4470       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
4471   if (args.GetLength() == 1) {
4472     FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
4473     if (HValueIsNull(hThis, argOne)) {
4474       FXJSE_Value_SetNull(args.GetReturnValue());
4475     } else {
4476       CFX_ByteString sourceString;
4477       HValueToUTF8String(argOne, sourceString);
4478       FXJSE_Value_SetInteger(args.GetReturnValue(), sourceString.GetLength());
4479     }
4480     FXJSE_Value_Release(argOne);
4481   } else {
4482     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
4483                                       L"Len");
4484   }
4485 }
Lower(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)4486 void CXFA_FM2JSContext::Lower(FXJSE_HOBJECT hThis,
4487                               const CFX_ByteStringC& szFuncName,
4488                               CFXJSE_Arguments& args) {
4489   int32_t argc = args.GetLength();
4490   if ((argc > 0) && (argc < 3)) {
4491     CFX_ByteString argString;
4492     FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
4493     FXJSE_HVALUE localeValue = 0;
4494     if (HValueIsNull(hThis, argOne)) {
4495       FXJSE_Value_SetNull(args.GetReturnValue());
4496     } else {
4497       if (argc == 2) {
4498         localeValue = GetSimpleHValue(hThis, args, 1);
4499       }
4500       HValueToUTF8String(argOne, argString);
4501       CFX_WideTextBuf lowStringBuf;
4502       CFX_WideString wsArgString =
4503           CFX_WideString::FromUTF8(argString, argString.GetLength());
4504       const FX_WCHAR* pData = wsArgString;
4505       int32_t iLen = argString.GetLength();
4506       int32_t i = 0;
4507       int32_t ch = 0;
4508       while (i < iLen) {
4509         ch = *(pData + i);
4510         if (ch >= 0x41 && ch <= 0x5A) {
4511           ch += 32;
4512         } else if (ch >= 0xC0 && ch <= 0xDE) {
4513           ch += 32;
4514         } else if (ch == 0x100 || ch == 0x102 || ch == 0x104) {
4515           ch += 1;
4516         }
4517         lowStringBuf.AppendChar(ch);
4518         ++i;
4519       }
4520       lowStringBuf.AppendChar(0);
4521       FXJSE_Value_SetUTF8String(
4522           args.GetReturnValue(),
4523           FX_UTF8Encode(lowStringBuf.GetBuffer(), lowStringBuf.GetLength()));
4524       if (argc == 2) {
4525         FXJSE_Value_Release(localeValue);
4526       }
4527     }
4528     FXJSE_Value_Release(argOne);
4529   } else {
4530     CXFA_FM2JSContext* pContext =
4531         (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
4532     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
4533                                       L"Lower");
4534   }
4535 }
Ltrim(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)4536 void CXFA_FM2JSContext::Ltrim(FXJSE_HOBJECT hThis,
4537                               const CFX_ByteStringC& szFuncName,
4538                               CFXJSE_Arguments& args) {
4539   CXFA_FM2JSContext* pContext =
4540       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
4541   if (args.GetLength() == 1) {
4542     FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
4543     if (HValueIsNull(hThis, argOne)) {
4544       FXJSE_Value_SetNull(args.GetReturnValue());
4545     } else {
4546       CFX_ByteString sourceString;
4547       HValueToUTF8String(argOne, sourceString);
4548       sourceString.TrimLeft();
4549       FXJSE_Value_SetUTF8String(args.GetReturnValue(), sourceString);
4550     }
4551     FXJSE_Value_Release(argOne);
4552   } else {
4553     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
4554                                       L"Ltrim");
4555   }
4556 }
Parse(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)4557 void CXFA_FM2JSContext::Parse(FXJSE_HOBJECT hThis,
4558                               const CFX_ByteStringC& szFuncName,
4559                               CFXJSE_Arguments& args) {
4560   CXFA_FM2JSContext* pContext =
4561       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
4562   if (args.GetLength() == 2) {
4563     FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
4564     FXJSE_HVALUE argTwo = GetSimpleHValue(hThis, args, 1);
4565     if (HValueIsNull(hThis, argTwo)) {
4566       FXJSE_Value_SetNull(args.GetReturnValue());
4567     } else {
4568       CFX_ByteString szPattern;
4569       HValueToUTF8String(argOne, szPattern);
4570       CFX_ByteString szValue;
4571       HValueToUTF8String(argTwo, szValue);
4572       CXFA_Document* pDoc = pContext->GetDocument();
4573       IFX_LocaleMgr* pMgr = (IFX_LocaleMgr*)pDoc->GetLocalMgr();
4574       CXFA_Object* pThisNode = pDoc->GetScriptContext()->GetThisObject();
4575       FXSYS_assert(pThisNode->IsNode());
4576       CXFA_WidgetData widgetData((CXFA_Node*)pThisNode);
4577       IFX_Locale* pLocale = widgetData.GetLocal();
4578       FX_DWORD patternType;
4579       FX_BOOL bCompletePattern =
4580           XFA_PATTERN_STRING_Type(szPattern, patternType);
4581       CFX_WideString wsPattern =
4582           CFX_WideString::FromUTF8(szPattern, szPattern.GetLength());
4583       CFX_WideString wsValue =
4584           CFX_WideString::FromUTF8(szValue, szValue.GetLength());
4585       CFX_ByteString szParsedValue;
4586       if (bCompletePattern) {
4587         CXFA_LocaleValue localeValue(patternType, wsValue, wsPattern, pLocale,
4588                                      (CXFA_LocaleMgr*)pMgr);
4589         if (localeValue.IsValid()) {
4590           szParsedValue = FX_UTF8Encode(localeValue.GetValue());
4591           FXJSE_Value_SetUTF8String(args.GetReturnValue(), szParsedValue);
4592         } else {
4593           FXJSE_Value_SetUTF8String(args.GetReturnValue(), "");
4594         }
4595       } else {
4596         switch (patternType) {
4597           case XFA_VT_DATETIME: {
4598             FX_STRSIZE iTChar = wsPattern.Find(L'T');
4599             CFX_WideString wsDatePattern = FX_WSTRC(L"date{");
4600             wsDatePattern += wsPattern.Left(iTChar);
4601             wsDatePattern += FX_WSTRC(L"} ");
4602             CFX_WideString wsTimePattern = FX_WSTRC(L"time{");
4603             wsTimePattern += wsPattern.Mid(iTChar + 1);
4604             wsTimePattern += FX_WSTRC(L"}");
4605             wsPattern = wsDatePattern + wsTimePattern;
4606             CXFA_LocaleValue localeValue(patternType, wsValue, wsPattern,
4607                                          pLocale, (CXFA_LocaleMgr*)pMgr);
4608             if (localeValue.IsValid()) {
4609               szParsedValue = FX_UTF8Encode(localeValue.GetValue());
4610               FXJSE_Value_SetUTF8String(args.GetReturnValue(), szParsedValue);
4611             } else {
4612               FXJSE_Value_SetUTF8String(args.GetReturnValue(), "");
4613             }
4614           } break;
4615           case XFA_VT_DATE: {
4616             wsPattern = FX_WSTRC(L"date{") + wsPattern;
4617             wsPattern += FX_WSTRC(L"}");
4618             CXFA_LocaleValue localeValue(patternType, wsValue, wsPattern,
4619                                          pLocale, (CXFA_LocaleMgr*)pMgr);
4620             if (localeValue.IsValid()) {
4621               szParsedValue = FX_UTF8Encode(localeValue.GetValue());
4622               FXJSE_Value_SetUTF8String(args.GetReturnValue(), szParsedValue);
4623             } else {
4624               FXJSE_Value_SetUTF8String(args.GetReturnValue(), "");
4625             }
4626           } break;
4627           case XFA_VT_TIME: {
4628             wsPattern = FX_WSTRC(L"time{") + wsPattern;
4629             wsPattern += FX_WSTRC(L"}");
4630             CXFA_LocaleValue localeValue(patternType, wsValue, wsPattern,
4631                                          pLocale, (CXFA_LocaleMgr*)pMgr);
4632             if (localeValue.IsValid()) {
4633               szParsedValue = FX_UTF8Encode(localeValue.GetValue());
4634               FXJSE_Value_SetUTF8String(args.GetReturnValue(), szParsedValue);
4635             } else {
4636               FXJSE_Value_SetUTF8String(args.GetReturnValue(), "");
4637             }
4638           } break;
4639           case XFA_VT_TEXT: {
4640             wsPattern = FX_WSTRC(L"text{") + wsPattern;
4641             wsPattern += FX_WSTRC(L"}");
4642             CXFA_LocaleValue localeValue(XFA_VT_TEXT, wsValue, wsPattern,
4643                                          pLocale, (CXFA_LocaleMgr*)pMgr);
4644             if (localeValue.IsValid()) {
4645               szParsedValue = FX_UTF8Encode(localeValue.GetValue());
4646               FXJSE_Value_SetUTF8String(args.GetReturnValue(), szParsedValue);
4647             } else {
4648               FXJSE_Value_SetUTF8String(args.GetReturnValue(), "");
4649             }
4650           } break;
4651           case XFA_VT_FLOAT: {
4652             wsPattern = FX_WSTRC(L"num{") + wsPattern;
4653             wsPattern += FX_WSTRC(L"}");
4654             CXFA_LocaleValue localeValue(XFA_VT_FLOAT, wsValue, wsPattern,
4655                                          pLocale, (CXFA_LocaleMgr*)pMgr);
4656             if (localeValue.IsValid()) {
4657               FXJSE_Value_SetDouble(args.GetReturnValue(),
4658                                     localeValue.GetDoubleNum());
4659             } else {
4660               FXJSE_Value_SetUTF8String(args.GetReturnValue(), "");
4661             }
4662           } break;
4663           default: {
4664             CFX_WideString wsTestPattern;
4665             wsTestPattern = FX_WSTRC(L"num{") + wsPattern;
4666             wsTestPattern += FX_WSTRC(L"}");
4667             CXFA_LocaleValue localeValue(XFA_VT_FLOAT, wsValue, wsTestPattern,
4668                                          pLocale, (CXFA_LocaleMgr*)pMgr);
4669             if (localeValue.IsValid()) {
4670               FXJSE_Value_SetDouble(args.GetReturnValue(),
4671                                     localeValue.GetDoubleNum());
4672             } else {
4673               wsTestPattern = FX_WSTRC(L"text{") + wsPattern;
4674               wsTestPattern += FX_WSTRC(L"}");
4675               CXFA_LocaleValue localeValue(XFA_VT_TEXT, wsValue, wsTestPattern,
4676                                            pLocale, (CXFA_LocaleMgr*)pMgr);
4677               if (localeValue.IsValid()) {
4678                 szParsedValue = FX_UTF8Encode(localeValue.GetValue());
4679                 FXJSE_Value_SetUTF8String(args.GetReturnValue(), szParsedValue);
4680               } else {
4681                 FXJSE_Value_SetUTF8String(args.GetReturnValue(), "");
4682               }
4683             }
4684           } break;
4685         }
4686       }
4687     }
4688     FXJSE_Value_Release(argOne);
4689     FXJSE_Value_Release(argTwo);
4690   } else {
4691     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
4692                                       L"Parse");
4693   }
4694 }
Replace(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)4695 void CXFA_FM2JSContext::Replace(FXJSE_HOBJECT hThis,
4696                                 const CFX_ByteStringC& szFuncName,
4697                                 CFXJSE_Arguments& args) {
4698   int32_t argc = args.GetLength();
4699   if ((argc == 2) || (argc == 3)) {
4700     FX_BOOL bFlags = FALSE;
4701     FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
4702     FXJSE_HVALUE argTwo = GetSimpleHValue(hThis, args, 1);
4703     FXJSE_HVALUE argThree = 0;
4704     CFX_ByteString oneString;
4705     CFX_ByteString twoString;
4706     CFX_ByteString threeString;
4707     if ((HValueIsNull(hThis, argOne)) || (HValueIsNull(hThis, argTwo))) {
4708       bFlags = TRUE;
4709     } else {
4710       HValueToUTF8String(argOne, oneString);
4711       HValueToUTF8String(argTwo, twoString);
4712     }
4713     if (argc == 3) {
4714       argThree = GetSimpleHValue(hThis, args, 2);
4715       HValueToUTF8String(argThree, threeString);
4716     }
4717     int32_t iSrcLen = oneString.GetLength();
4718     int32_t iFindLen = twoString.GetLength();
4719     CFX_ByteTextBuf resultString;
4720     int32_t iFindIndex = 0;
4721     uint8_t ch = 0;
4722     for (int32_t u = 0; u < iSrcLen; ++u) {
4723       ch = oneString.GetAt(u);
4724       if (ch == twoString.GetAt(iFindIndex)) {
4725         int32_t iTemp = u + 1;
4726         ++iFindIndex;
4727         uint8_t chTemp = 0;
4728         while (iFindIndex < iFindLen) {
4729           chTemp = oneString.GetAt(iTemp);
4730           if (chTemp == twoString.GetAt(iFindIndex)) {
4731             ++iTemp;
4732             ++iFindIndex;
4733           } else {
4734             iFindIndex = 0;
4735             break;
4736           }
4737         }
4738         if (iFindIndex == iFindLen) {
4739           resultString << threeString;
4740           u += iFindLen - 1;
4741           iFindIndex = 0;
4742         } else {
4743           resultString.AppendChar(ch);
4744         }
4745       } else {
4746         resultString.AppendChar(ch);
4747       }
4748     }
4749     resultString.AppendChar(0);
4750     FXJSE_Value_SetUTF8String(args.GetReturnValue(),
4751                               resultString.GetByteString());
4752     FXJSE_Value_Release(argOne);
4753     FXJSE_Value_Release(argTwo);
4754     if (argc == 3) {
4755       FXJSE_Value_Release(argThree);
4756     }
4757   } else {
4758     CXFA_FM2JSContext* pContext =
4759         (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
4760     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
4761                                       L"Replace");
4762   }
4763 }
Right(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)4764 void CXFA_FM2JSContext::Right(FXJSE_HOBJECT hThis,
4765                               const CFX_ByteStringC& szFuncName,
4766                               CFXJSE_Arguments& args) {
4767   CXFA_FM2JSContext* pContext =
4768       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
4769   if (args.GetLength() == 2) {
4770     FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
4771     FXJSE_HVALUE argTwo = GetSimpleHValue(hThis, args, 1);
4772     FX_BOOL argIsNull = FALSE;
4773     if ((HValueIsNull(hThis, argOne)) || (HValueIsNull(hThis, argTwo))) {
4774       argIsNull = TRUE;
4775     }
4776     if (argIsNull) {
4777       FXJSE_Value_SetNull(args.GetReturnValue());
4778     } else {
4779       CFX_ByteString sourceString;
4780       HValueToUTF8String(argOne, sourceString);
4781       int32_t count = HValueToInteger(hThis, argTwo);
4782       if (count < 0) {
4783         count = 0;
4784       }
4785       FXJSE_Value_SetUTF8String(args.GetReturnValue(),
4786                                 sourceString.Right(count));
4787     }
4788     FXJSE_Value_Release(argOne);
4789     FXJSE_Value_Release(argTwo);
4790   } else {
4791     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
4792                                       L"Right");
4793   }
4794 }
Rtrim(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)4795 void CXFA_FM2JSContext::Rtrim(FXJSE_HOBJECT hThis,
4796                               const CFX_ByteStringC& szFuncName,
4797                               CFXJSE_Arguments& args) {
4798   CXFA_FM2JSContext* pContext =
4799       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
4800   if (args.GetLength() == 1) {
4801     FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
4802     if (HValueIsNull(hThis, argOne)) {
4803       FXJSE_Value_SetNull(args.GetReturnValue());
4804     } else {
4805       CFX_ByteString sourceString;
4806       HValueToUTF8String(argOne, sourceString);
4807       sourceString.TrimRight();
4808       FXJSE_Value_SetUTF8String(args.GetReturnValue(), sourceString);
4809     }
4810     FXJSE_Value_Release(argOne);
4811   } else {
4812     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
4813                                       L"Rtrim");
4814   }
4815 }
Space(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)4816 void CXFA_FM2JSContext::Space(FXJSE_HOBJECT hThis,
4817                               const CFX_ByteStringC& szFuncName,
4818                               CFXJSE_Arguments& args) {
4819   CXFA_FM2JSContext* pContext =
4820       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
4821   if (args.GetLength() == 1) {
4822     FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
4823     if (FXJSE_Value_IsNull(argOne)) {
4824       FXJSE_Value_SetNull(args.GetReturnValue());
4825     } else {
4826       int32_t count = 0;
4827       count = HValueToInteger(hThis, argOne);
4828       count = (count < 0) ? 0 : count;
4829       CFX_ByteTextBuf spaceString;
4830       int32_t index = 0;
4831       while (index < count) {
4832         spaceString.AppendByte(' ');
4833         index++;
4834       }
4835       spaceString.AppendByte(0);
4836       FXJSE_Value_SetUTF8String(args.GetReturnValue(),
4837                                 spaceString.GetByteString());
4838     }
4839     FXJSE_Value_Release(argOne);
4840   } else {
4841     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
4842                                       L"Space");
4843   }
4844 }
Str(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)4845 void CXFA_FM2JSContext::Str(FXJSE_HOBJECT hThis,
4846                             const CFX_ByteStringC& szFuncName,
4847                             CFXJSE_Arguments& args) {
4848   int32_t argc = args.GetLength();
4849   if ((argc > 0) && (argc < 4)) {
4850     FX_BOOL bFlags = FALSE;
4851     FX_FLOAT fNumber;
4852     int32_t iWidth = 10;
4853     int32_t iPrecision = 0;
4854     FXJSE_HVALUE numberValue = GetSimpleHValue(hThis, args, 0);
4855     FXJSE_HVALUE widthValue = 0;
4856     FXJSE_HVALUE precisionValue = 0;
4857     if (FXJSE_Value_IsNull(numberValue)) {
4858       bFlags = TRUE;
4859     } else {
4860       fNumber = HValueToFloat(hThis, numberValue);
4861     }
4862     if (argc > 1) {
4863       widthValue = GetSimpleHValue(hThis, args, 1);
4864       iWidth = (int32_t)HValueToFloat(hThis, widthValue);
4865     }
4866     if (argc == 3) {
4867       precisionValue = GetSimpleHValue(hThis, args, 2);
4868       iPrecision = (int32_t)HValueToFloat(hThis, precisionValue);
4869       if (iPrecision < 0) {
4870         iPrecision = 0;
4871       }
4872     }
4873     if (!bFlags) {
4874       CFX_ByteString numberString;
4875       CFX_ByteString formatStr = "%";
4876       if (iPrecision) {
4877         formatStr += ".";
4878         formatStr += CFX_ByteString::FormatInteger(iPrecision);
4879       }
4880       formatStr += "f";
4881       numberString.Format(formatStr, fNumber);
4882       const FX_CHAR* pData = numberString;
4883       int32_t iLength = numberString.GetLength();
4884       int32_t u = 0;
4885       while (u < iLength) {
4886         if (*(pData + u) == '.') {
4887           break;
4888         }
4889         ++u;
4890       }
4891       CFX_ByteTextBuf resultBuf;
4892       if (u > iWidth || (iPrecision + u) >= iWidth) {
4893         int32_t i = 0;
4894         while (i < iWidth) {
4895           resultBuf.AppendChar('*');
4896           ++i;
4897         }
4898         resultBuf.AppendChar(0);
4899       } else {
4900         if (u == iLength) {
4901           if (iLength > iWidth) {
4902             int32_t i = 0;
4903             while (i < iWidth) {
4904               resultBuf.AppendChar('*');
4905               ++i;
4906             }
4907           } else {
4908             int32_t i = 0;
4909             int32_t iSpace = iWidth - iLength;
4910             while (i < iSpace) {
4911               resultBuf.AppendChar(' ');
4912               ++i;
4913             }
4914             resultBuf << pData;
4915           }
4916         } else {
4917           int32_t iLeavingSpace = 0;
4918           if (iPrecision == 0) {
4919             iLeavingSpace = iWidth - (u + iPrecision);
4920           } else {
4921             iLeavingSpace = iWidth - (u + iPrecision + 1);
4922           }
4923           int32_t i = 0;
4924           while (i < iLeavingSpace) {
4925             resultBuf.AppendChar(' ');
4926             ++i;
4927           }
4928           i = 0;
4929           while (i < u) {
4930             resultBuf.AppendChar(*(pData + i));
4931             ++i;
4932           }
4933           if (iPrecision != 0) {
4934             resultBuf.AppendChar('.');
4935           }
4936           u++;
4937           i = 0;
4938           while (u < iLength) {
4939             if (i >= iPrecision) {
4940               break;
4941             }
4942             resultBuf.AppendChar(*(pData + u));
4943             ++i;
4944             ++u;
4945           }
4946           while (i < iPrecision) {
4947             resultBuf.AppendChar('0');
4948             ++i;
4949           }
4950           resultBuf.AppendChar(0);
4951         }
4952       }
4953       FXJSE_Value_SetUTF8String(args.GetReturnValue(),
4954                                 resultBuf.GetByteString());
4955     } else {
4956       FXJSE_Value_SetNull(args.GetReturnValue());
4957     }
4958     FXJSE_Value_Release(numberValue);
4959     if (argc > 1) {
4960       FXJSE_Value_Release(widthValue);
4961       if (argc == 3) {
4962         FXJSE_Value_Release(precisionValue);
4963       }
4964     }
4965   } else {
4966     CXFA_FM2JSContext* pContext =
4967         (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
4968     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
4969                                       L"Str");
4970   }
4971 }
Stuff(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)4972 void CXFA_FM2JSContext::Stuff(FXJSE_HOBJECT hThis,
4973                               const CFX_ByteStringC& szFuncName,
4974                               CFXJSE_Arguments& args) {
4975   int32_t argc = args.GetLength();
4976   if ((argc == 3) || (argc == 4)) {
4977     FX_BOOL bFlags = FALSE;
4978     CFX_ByteString sourceString;
4979     CFX_ByteString insertString;
4980     int32_t iLength = 0;
4981     int32_t iStart = 0;
4982     int32_t iDelete = 0;
4983     FXJSE_HVALUE sourceValue = GetSimpleHValue(hThis, args, 0);
4984     FXJSE_HVALUE startValue = GetSimpleHValue(hThis, args, 1);
4985     FXJSE_HVALUE deleteValue = GetSimpleHValue(hThis, args, 2);
4986     FXJSE_HVALUE insertValue = 0;
4987     if ((FXJSE_Value_IsNull(sourceValue)) || (FXJSE_Value_IsNull(startValue)) ||
4988         (FXJSE_Value_IsNull(deleteValue))) {
4989       bFlags = TRUE;
4990     } else {
4991       HValueToUTF8String(sourceValue, sourceString);
4992       iLength = sourceString.GetLength();
4993       iStart = (int32_t)HValueToFloat(hThis, startValue);
4994       if (iStart < 1) {
4995         iStart = 1;
4996       }
4997       if (iStart > iLength) {
4998         iStart = iLength;
4999       }
5000       iDelete = (int32_t)HValueToFloat(hThis, deleteValue);
5001       if (iDelete <= 0) {
5002         iDelete = 0;
5003       }
5004     }
5005     if (argc == 4) {
5006       insertValue = GetSimpleHValue(hThis, args, 3);
5007       HValueToUTF8String(insertValue, insertString);
5008     }
5009     iStart -= 1;
5010     CFX_ByteTextBuf resultString;
5011     int32_t i = 0;
5012     while (i < iStart) {
5013       resultString.AppendChar(sourceString.GetAt(i));
5014       ++i;
5015     }
5016     resultString << insertString;
5017     i = iStart + iDelete;
5018     while (i < iLength) {
5019       resultString.AppendChar(sourceString.GetAt(i));
5020       ++i;
5021     }
5022     resultString.AppendChar(0);
5023     FXJSE_Value_SetUTF8String(args.GetReturnValue(),
5024                               resultString.GetByteString());
5025     FXJSE_Value_Release(sourceValue);
5026     FXJSE_Value_Release(startValue);
5027     FXJSE_Value_Release(deleteValue);
5028     if (argc == 4) {
5029       FXJSE_Value_Release(insertValue);
5030     }
5031   } else {
5032     CXFA_FM2JSContext* pContext =
5033         (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
5034     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
5035                                       L"Stuff");
5036   }
5037 }
Substr(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)5038 void CXFA_FM2JSContext::Substr(FXJSE_HOBJECT hThis,
5039                                const CFX_ByteStringC& szFuncName,
5040                                CFXJSE_Arguments& args) {
5041   int32_t argc = args.GetLength();
5042   if (argc == 3) {
5043     FXJSE_HVALUE stringValue = GetSimpleHValue(hThis, args, 0);
5044     FXJSE_HVALUE startValue = GetSimpleHValue(hThis, args, 1);
5045     FXJSE_HVALUE endValue = GetSimpleHValue(hThis, args, 2);
5046     if (HValueIsNull(hThis, stringValue) || (HValueIsNull(hThis, startValue)) ||
5047         (HValueIsNull(hThis, endValue))) {
5048       FXJSE_Value_SetNull(args.GetReturnValue());
5049     } else {
5050       CFX_ByteString szSourceStr;
5051       int32_t iStart = 0;
5052       int32_t iCount = 0;
5053       HValueToUTF8String(stringValue, szSourceStr);
5054       int32_t iLength = szSourceStr.GetLength();
5055       if (iLength == 0) {
5056         FXJSE_Value_SetUTF8String(args.GetReturnValue(), "");
5057       } else {
5058         iStart = (int32_t)HValueToFloat(hThis, startValue);
5059         iCount = (int32_t)HValueToFloat(hThis, endValue);
5060         if (iStart < 1) {
5061           iStart = 1;
5062         }
5063         if (iStart > iLength) {
5064           iStart = iLength;
5065         }
5066         if (iCount <= 0) {
5067           iCount = 0;
5068         }
5069         iStart -= 1;
5070         FXJSE_Value_SetUTF8String(args.GetReturnValue(),
5071                                   szSourceStr.Mid(iStart, iCount));
5072       }
5073     }
5074     FXJSE_Value_Release(stringValue);
5075     FXJSE_Value_Release(startValue);
5076     FXJSE_Value_Release(endValue);
5077   } else {
5078     CXFA_FM2JSContext* pContext =
5079         (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
5080     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
5081                                       L"Substr");
5082   }
5083 }
Uuid(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)5084 void CXFA_FM2JSContext::Uuid(FXJSE_HOBJECT hThis,
5085                              const CFX_ByteStringC& szFuncName,
5086                              CFXJSE_Arguments& args) {
5087   int32_t argc = args.GetLength();
5088   if ((argc == 0) || (argc == 1)) {
5089     int32_t iNum = 0;
5090     FXJSE_HVALUE argOne = 0;
5091     if (argc == 1) {
5092       argOne = GetSimpleHValue(hThis, args, 0);
5093       iNum = (int32_t)HValueToFloat(hThis, argOne);
5094     }
5095     FX_GUID guid;
5096     FX_GUID_CreateV4(&guid);
5097     CFX_ByteString bsUId;
5098     FX_GUID_ToString(&guid, bsUId, iNum);
5099     FXJSE_Value_SetUTF8String(args.GetReturnValue(), bsUId);
5100     if (argc == 1) {
5101       FXJSE_Value_Release(argOne);
5102     }
5103   } else {
5104     CXFA_FM2JSContext* pContext =
5105         (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
5106     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
5107                                       L"Uuid");
5108   }
5109 }
Upper(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)5110 void CXFA_FM2JSContext::Upper(FXJSE_HOBJECT hThis,
5111                               const CFX_ByteStringC& szFuncName,
5112                               CFXJSE_Arguments& args) {
5113   int32_t argc = args.GetLength();
5114   if ((argc > 0) && (argc < 3)) {
5115     CFX_ByteString argString;
5116     FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
5117     FXJSE_HVALUE localeValue = 0;
5118     if (HValueIsNull(hThis, argOne)) {
5119       FXJSE_Value_SetNull(args.GetReturnValue());
5120     } else {
5121       if (argc == 2) {
5122         localeValue = GetSimpleHValue(hThis, args, 1);
5123       }
5124       HValueToUTF8String(argOne, argString);
5125       CFX_WideTextBuf upperStringBuf;
5126       CFX_WideString wsArgString =
5127           CFX_WideString::FromUTF8(argString, argString.GetLength());
5128       const FX_WCHAR* pData = wsArgString;
5129       int32_t iLen = wsArgString.GetLength();
5130       int32_t i = 0;
5131       int32_t ch = 0;
5132       while (i < iLen) {
5133         ch = *(pData + i);
5134         if (ch >= 0x61 && ch <= 0x7A) {
5135           ch -= 32;
5136         } else if (ch >= 0xE0 && ch <= 0xFE) {
5137           ch -= 32;
5138         } else if (ch == 0x101 || ch == 0x103 || ch == 0x105) {
5139           ch -= 1;
5140         }
5141         upperStringBuf.AppendChar(ch);
5142         ++i;
5143       }
5144       upperStringBuf.AppendChar(0);
5145       FXJSE_Value_SetUTF8String(args.GetReturnValue(),
5146                                 FX_UTF8Encode(upperStringBuf.GetBuffer(),
5147                                               upperStringBuf.GetLength()));
5148       if (argc == 2) {
5149         FXJSE_Value_Release(localeValue);
5150       }
5151     }
5152     FXJSE_Value_Release(argOne);
5153   } else {
5154     CXFA_FM2JSContext* pContext =
5155         (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
5156     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
5157                                       L"Upper");
5158   }
5159 }
WordNum(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)5160 void CXFA_FM2JSContext::WordNum(FXJSE_HOBJECT hThis,
5161                                 const CFX_ByteStringC& szFuncName,
5162                                 CFXJSE_Arguments& args) {
5163   int32_t argc = args.GetLength();
5164   if ((argc > 0) && (argc < 4)) {
5165     FX_BOOL bFlags = FALSE;
5166     FX_FLOAT fNumber;
5167     int32_t iIdentifier = 0;
5168     CFX_ByteString localeString;
5169     FXJSE_HVALUE numberValue = GetSimpleHValue(hThis, args, 0);
5170     FXJSE_HVALUE identifierValue = 0;
5171     FXJSE_HVALUE localeValue = 0;
5172     if (FXJSE_Value_IsNull(numberValue)) {
5173       bFlags = TRUE;
5174     } else {
5175       fNumber = HValueToFloat(hThis, numberValue);
5176     }
5177     if (argc > 1) {
5178       identifierValue = GetSimpleHValue(hThis, args, 1);
5179       if (FXJSE_Value_IsNull(identifierValue)) {
5180         bFlags = TRUE;
5181       } else {
5182         iIdentifier = (int32_t)HValueToFloat(hThis, identifierValue);
5183       }
5184     }
5185     if (argc == 3) {
5186       localeValue = GetSimpleHValue(hThis, args, 2);
5187       if (FXJSE_Value_IsNull(localeValue)) {
5188         bFlags = TRUE;
5189       } else {
5190         HValueToUTF8String(localeValue, localeString);
5191       }
5192     }
5193     if (!bFlags) {
5194       if ((fNumber < 0) || (fNumber > 922337203685477550)) {
5195         FXJSE_Value_SetUTF8String(args.GetReturnValue(), "*");
5196       } else {
5197         CFX_ByteTextBuf resultBuf;
5198         CFX_ByteString numberString;
5199         numberString.Format("%.2f", fNumber);
5200         WordUS(numberString, iIdentifier, resultBuf);
5201         FXJSE_Value_SetUTF8String(args.GetReturnValue(),
5202                                   resultBuf.GetByteString());
5203       }
5204     } else {
5205       FXJSE_Value_SetNull(args.GetReturnValue());
5206     }
5207     FXJSE_Value_Release(numberValue);
5208     if (argc > 1) {
5209       FXJSE_Value_Release(identifierValue);
5210       if (argc == 3) {
5211         FXJSE_Value_Release(localeValue);
5212       }
5213     }
5214   } else {
5215     CXFA_FM2JSContext* pContext =
5216         (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
5217     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
5218                                       L"WordNum");
5219   }
5220 }
TrillionUS(const CFX_ByteStringC & szData,CFX_ByteTextBuf & strBuf)5221 void CXFA_FM2JSContext::TrillionUS(const CFX_ByteStringC& szData,
5222                                    CFX_ByteTextBuf& strBuf) {
5223   CFX_ByteStringC pUnits[] = {"zero", "one", "two",   "three", "four",
5224                               "five", "six", "seven", "eight", "nine"};
5225   CFX_ByteStringC pCapUnits[] = {"Zero", "One", "Two",   "Three", "Four",
5226                                  "Five", "Six", "Seven", "Eight", "Nine"};
5227   CFX_ByteStringC pTens[] = {"Ten",      "Eleven",  "Twelve",  "Thirteen",
5228                              "Fourteen", "Fifteen", "Sixteen", "Seventeen",
5229                              "Eighteen", "Nineteen"};
5230   CFX_ByteStringC pLastTens[] = {"Twenty", "Thirty",  "Forty",  "Fifty",
5231                                  "Sixty",  "Seventy", "Eighty", "Ninety"};
5232   CFX_ByteStringC pComm[] = {" Hundred ", " Thousand ", " Million ",
5233                              " Billion ", "Trillion"};
5234   int32_t iComm = 0;
5235   const FX_CHAR* pData = szData.GetCStr();
5236   int32_t iLength = szData.GetLength();
5237   if (iLength > 12) {
5238     iComm = 4;
5239   } else if (iLength > 9) {
5240     iComm = 3;
5241   } else if (iLength > 6) {
5242     iComm = 2;
5243   } else if (iLength > 3) {
5244     iComm = 1;
5245   }
5246   int32_t iIndex = 0;
5247   int32_t iFirstCount = iLength % 3;
5248   if (iFirstCount == 0) {
5249     iFirstCount = 3;
5250   }
5251   if (iFirstCount == 3) {
5252     if (*(pData + iIndex) != '0') {
5253       strBuf << pCapUnits[*(pData + iIndex) - '0'];
5254       strBuf << pComm[0];
5255     }
5256     if (*(pData + iIndex + 1) == '0') {
5257       strBuf << pCapUnits[*(pData + iIndex + 2) - '0'];
5258     } else {
5259       if (*(pData + iIndex + 1) > '1') {
5260         strBuf << pLastTens[*(pData + iIndex + 1) - '2'];
5261         strBuf << "-";
5262         strBuf << pUnits[*(pData + iIndex + 2) - '0'];
5263       } else if (*(pData + iIndex + 1) == '1') {
5264         strBuf << pTens[*(pData + iIndex + 2) - '0'];
5265       } else if (*(pData + iIndex + 1) == '0') {
5266         strBuf << pCapUnits[*(pData + iIndex + 2) - '0'];
5267       }
5268     }
5269     iIndex += 3;
5270   } else if (iFirstCount == 2) {
5271     if (*(pData + iIndex) == '0') {
5272       strBuf << pCapUnits[*(pData + iIndex + 1) - '0'];
5273     } else {
5274       if (*(pData + iIndex) > '1') {
5275         strBuf << pLastTens[*(pData + iIndex) - '2'];
5276         strBuf << "-";
5277         strBuf << pUnits[*(pData + iIndex + 1) - '0'];
5278       } else if (*(pData + iIndex) == '1') {
5279         strBuf << pTens[*(pData + iIndex + 1) - '0'];
5280       } else if (*(pData + iIndex) == '0') {
5281         strBuf << pCapUnits[*(pData + iIndex + 1) - '0'];
5282       }
5283     }
5284     iIndex += 2;
5285   } else if (iFirstCount == 1) {
5286     strBuf << pCapUnits[*(pData + iIndex) - '0'];
5287     iIndex += 1;
5288   }
5289   if (iLength > 3 && iFirstCount > 0) {
5290     strBuf << pComm[iComm];
5291     --iComm;
5292   }
5293   while (iIndex < iLength) {
5294     if (*(pData + iIndex) != '0') {
5295       strBuf << pCapUnits[*(pData + iIndex) - '0'];
5296       strBuf << pComm[0];
5297     }
5298     if (*(pData + iIndex + 1) == '0') {
5299       strBuf << pCapUnits[*(pData + iIndex + 2) - '0'];
5300     } else {
5301       if (*(pData + iIndex + 1) > '1') {
5302         strBuf << pLastTens[*(pData + iIndex + 1) - '2'];
5303         strBuf << "-";
5304         strBuf << pUnits[*(pData + iIndex + 2) - '0'];
5305       } else if (*(pData + iIndex + 1) == '1') {
5306         strBuf << pTens[*(pData + iIndex + 2) - '0'];
5307       } else if (*(pData + iIndex + 1) == '0') {
5308         strBuf << pCapUnits[*(pData + iIndex + 2) - '0'];
5309       }
5310     }
5311     if (iIndex < iLength - 3) {
5312       strBuf << pComm[iComm];
5313       --iComm;
5314     }
5315     iIndex += 3;
5316   }
5317 }
WordUS(const CFX_ByteStringC & szData,int32_t iStyle,CFX_ByteTextBuf & strBuf)5318 void CXFA_FM2JSContext::WordUS(const CFX_ByteStringC& szData,
5319                                int32_t iStyle,
5320                                CFX_ByteTextBuf& strBuf) {
5321   const FX_CHAR* pData = szData.GetCStr();
5322   int32_t iLength = szData.GetLength();
5323   switch (iStyle) {
5324     case 0: {
5325       int32_t iIndex = 0;
5326       while (iIndex < iLength) {
5327         if (*(pData + iIndex) == '.') {
5328           break;
5329         }
5330         ++iIndex;
5331       }
5332       iLength = iIndex;
5333       iIndex = 0;
5334       int32_t iCount = 0;
5335       while (iIndex < iLength) {
5336         iCount = (iLength - iIndex) % 12;
5337         if (!iCount && iLength - iIndex > 0) {
5338           iCount = 12;
5339         }
5340         TrillionUS(CFX_ByteStringC(pData + iIndex, iCount), strBuf);
5341         iIndex += iCount;
5342         if (iIndex < iLength) {
5343           strBuf << " Trillion ";
5344         }
5345       }
5346     } break;
5347     case 1: {
5348       int32_t iIndex = 0;
5349       while (iIndex < iLength) {
5350         if (*(pData + iIndex) == '.') {
5351           break;
5352         }
5353         ++iIndex;
5354       }
5355       iLength = iIndex;
5356       iIndex = 0;
5357       int32_t iCount = 0;
5358       while (iIndex < iLength) {
5359         iCount = (iLength - iIndex) % 12;
5360         if (!iCount && iLength - iIndex > 0) {
5361           iCount = 12;
5362         }
5363         TrillionUS(CFX_ByteStringC(pData + iIndex, iCount), strBuf);
5364         iIndex += iCount;
5365         if (iIndex < iLength) {
5366           strBuf << " Trillion ";
5367         }
5368       }
5369       strBuf << " Dollars";
5370     } break;
5371     case 2: {
5372       int32_t iIndex = 0;
5373       while (iIndex < iLength) {
5374         if (*(pData + iIndex) == '.') {
5375           break;
5376         }
5377         ++iIndex;
5378       }
5379       int32_t iInteger = iIndex;
5380       iIndex = 0;
5381       int32_t iCount = 0;
5382       while (iIndex < iInteger) {
5383         iCount = (iInteger - iIndex) % 12;
5384         if (!iCount && iLength - iIndex > 0) {
5385           iCount = 12;
5386         }
5387         TrillionUS(CFX_ByteStringC(pData + iIndex, iCount), strBuf);
5388         iIndex += iCount;
5389         if (iIndex < iInteger) {
5390           strBuf << " Trillion ";
5391         }
5392       }
5393       strBuf << " Dollars";
5394       if (iInteger < iLength) {
5395         strBuf << " And ";
5396         iIndex = iInteger + 1;
5397         int32_t iCount = 0;
5398         while (iIndex < iLength) {
5399           iCount = (iLength - iIndex) % 12;
5400           if (!iCount && iLength - iIndex > 0) {
5401             iCount = 12;
5402           }
5403           TrillionUS(CFX_ByteStringC(pData + iIndex, iCount), strBuf);
5404           iIndex += iCount;
5405           if (iIndex < iLength) {
5406             strBuf << " Trillion ";
5407           }
5408         }
5409         strBuf << " Cents";
5410       }
5411     } break;
5412     default:
5413       break;
5414   }
5415 }
Get(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)5416 void CXFA_FM2JSContext::Get(FXJSE_HOBJECT hThis,
5417                             const CFX_ByteStringC& szFuncName,
5418                             CFXJSE_Arguments& args) {
5419   CXFA_FM2JSContext* pContext =
5420       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
5421   int32_t argc = args.GetLength();
5422   if (argc == 1) {
5423     CXFA_Document* pDoc = pContext->GetDocument();
5424     if (!pDoc) {
5425       return;
5426     }
5427     IXFA_AppProvider* pAppProvider =
5428         pDoc->GetParser()->GetNotify()->GetAppProvider();
5429     if (!pAppProvider) {
5430       return;
5431     }
5432     FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
5433     CFX_ByteString urlString;
5434     HValueToUTF8String(argOne, urlString);
5435     IFX_FileRead* pFile = pAppProvider->DownloadURL(
5436         CFX_WideString::FromUTF8(urlString, urlString.GetLength()));
5437     if (pFile) {
5438       int32_t size = pFile->GetSize();
5439       uint8_t* pData = FX_Alloc(uint8_t, size);
5440       pFile->ReadBlock(pData, size);
5441       FXJSE_Value_SetUTF8String(args.GetReturnValue(),
5442                                 CFX_ByteStringC(pData, size));
5443       FX_Free(pData);
5444       pFile->Release();
5445     }
5446     FXJSE_Value_Release(argOne);
5447   } else {
5448     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
5449                                       L"Get");
5450   }
5451 }
Post(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)5452 void CXFA_FM2JSContext::Post(FXJSE_HOBJECT hThis,
5453                              const CFX_ByteStringC& szFuncName,
5454                              CFXJSE_Arguments& args) {
5455   CXFA_FM2JSContext* pContext =
5456       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
5457   int32_t argc = args.GetLength();
5458   if ((argc >= 2) && (argc <= 5)) {
5459     CXFA_Document* pDoc = pContext->GetDocument();
5460     if (!pDoc) {
5461       return;
5462     }
5463     IXFA_AppProvider* pAppProvider =
5464         pDoc->GetParser()->GetNotify()->GetAppProvider();
5465     if (!pAppProvider) {
5466       return;
5467     }
5468     CFX_ByteString bsURL;
5469     CFX_ByteString bsData;
5470     CFX_ByteString bsContentType;
5471     CFX_ByteString bsEncode;
5472     CFX_ByteString bsHeader;
5473     FXJSE_HVALUE argOne;
5474     FXJSE_HVALUE argTwo;
5475     FXJSE_HVALUE argThree;
5476     FXJSE_HVALUE argFour;
5477     FXJSE_HVALUE argFive;
5478     argOne = GetSimpleHValue(hThis, args, 0);
5479     HValueToUTF8String(argOne, bsURL);
5480     argTwo = GetSimpleHValue(hThis, args, 1);
5481     HValueToUTF8String(argTwo, bsData);
5482     if (argc > 2) {
5483       argThree = GetSimpleHValue(hThis, args, 2);
5484       HValueToUTF8String(argThree, bsContentType);
5485     }
5486     if (argc > 3) {
5487       argFour = GetSimpleHValue(hThis, args, 3);
5488       HValueToUTF8String(argFour, bsEncode);
5489     }
5490     if (argc > 4) {
5491       argFive = GetSimpleHValue(hThis, args, 4);
5492       HValueToUTF8String(argFive, bsHeader);
5493     }
5494     CFX_WideString decodedResponse;
5495     FX_BOOL bFlags = pAppProvider->PostRequestURL(
5496         CFX_WideString::FromUTF8(bsURL, bsURL.GetLength()),
5497         CFX_WideString::FromUTF8(bsData, bsData.GetLength()),
5498         CFX_WideString::FromUTF8(bsContentType, bsContentType.GetLength()),
5499         CFX_WideString::FromUTF8(bsEncode, bsEncode.GetLength()),
5500         CFX_WideString::FromUTF8(bsHeader, bsHeader.GetLength()),
5501         decodedResponse);
5502     FXJSE_Value_Release(argOne);
5503     FXJSE_Value_Release(argTwo);
5504     if (argc > 2) {
5505       FXJSE_Value_Release(argThree);
5506     }
5507     if (argc > 3) {
5508       FXJSE_Value_Release(argFour);
5509     }
5510     if (argc > 4) {
5511       FXJSE_Value_Release(argFive);
5512     }
5513     if (bFlags) {
5514       FXJSE_Value_SetUTF8String(
5515           args.GetReturnValue(),
5516           FX_UTF8Encode(decodedResponse, decodedResponse.GetLength()));
5517     } else {
5518       pContext->ThrowScriptErrorMessage(XFA_IDS_SERVER_DENY);
5519     }
5520   } else {
5521     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
5522                                       L"Post");
5523   }
5524 }
Put(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)5525 void CXFA_FM2JSContext::Put(FXJSE_HOBJECT hThis,
5526                             const CFX_ByteStringC& szFuncName,
5527                             CFXJSE_Arguments& args) {
5528   CXFA_FM2JSContext* pContext =
5529       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
5530   int32_t argc = args.GetLength();
5531   if ((argc == 2) || (argc == 3)) {
5532     CXFA_Document* pDoc = pContext->GetDocument();
5533     if (!pDoc) {
5534       return;
5535     }
5536     IXFA_AppProvider* pAppProvider =
5537         pDoc->GetParser()->GetNotify()->GetAppProvider();
5538     if (!pAppProvider) {
5539       return;
5540     }
5541     CFX_ByteString bsURL;
5542     CFX_ByteString bsData;
5543     CFX_ByteString bsEncode;
5544     FXJSE_HVALUE argOne;
5545     FXJSE_HVALUE argTwo;
5546     FXJSE_HVALUE argThree;
5547     argOne = GetSimpleHValue(hThis, args, 0);
5548     HValueToUTF8String(argOne, bsURL);
5549     argTwo = GetSimpleHValue(hThis, args, 1);
5550     HValueToUTF8String(argTwo, bsData);
5551     if (argc > 2) {
5552       argThree = GetSimpleHValue(hThis, args, 2);
5553       HValueToUTF8String(argThree, bsEncode);
5554     }
5555     FX_BOOL bFlags = pAppProvider->PutRequestURL(
5556         CFX_WideString::FromUTF8(bsURL, bsURL.GetLength()),
5557         CFX_WideString::FromUTF8(bsData, bsData.GetLength()),
5558         CFX_WideString::FromUTF8(bsEncode, bsEncode.GetLength()));
5559     FXJSE_Value_Release(argOne);
5560     FXJSE_Value_Release(argTwo);
5561     if (argc > 2) {
5562       FXJSE_Value_Release(argThree);
5563     }
5564     if (bFlags) {
5565       FXJSE_Value_SetUTF8String(args.GetReturnValue(), "");
5566     } else {
5567       pContext->ThrowScriptErrorMessage(XFA_IDS_SERVER_DENY);
5568     }
5569   } else {
5570     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
5571                                       L"Put");
5572   }
5573 }
assign_value_operator(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)5574 void CXFA_FM2JSContext::assign_value_operator(FXJSE_HOBJECT hThis,
5575                                               const CFX_ByteStringC& szFuncName,
5576                                               CFXJSE_Arguments& args) {
5577   CXFA_FM2JSContext* pContext =
5578       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
5579   FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
5580   if (args.GetLength() == 2) {
5581     FXJSE_HVALUE lValue = args.GetValue(0);
5582     FXJSE_HVALUE rValue = GetSimpleHValue(hThis, args, 1);
5583     FX_BOOL bSetStatus = TRUE;
5584     if (FXJSE_Value_IsArray(lValue)) {
5585       FXJSE_HVALUE leftLengthValue = FXJSE_Value_Create(hruntime);
5586       FXJSE_Value_GetObjectProp(lValue, "length", leftLengthValue);
5587       int32_t iLeftLength = FXJSE_Value_ToInteger(leftLengthValue);
5588       FXJSE_Value_Release(leftLengthValue);
5589       FXJSE_HVALUE jsObjectValue = FXJSE_Value_Create(hruntime);
5590       FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
5591       FXJSE_Value_GetObjectPropByIdx(lValue, 1, propertyValue);
5592       if (FXJSE_Value_IsNull(propertyValue)) {
5593         for (int32_t i = 2; i < iLeftLength; i++) {
5594           FXJSE_Value_GetObjectPropByIdx(lValue, i, jsObjectValue);
5595           bSetStatus = SetObjectDefaultValue(jsObjectValue, rValue);
5596           if (!bSetStatus) {
5597             pContext->ThrowScriptErrorMessage(XFA_IDS_NOT_DEFAUL_VALUE);
5598             break;
5599           }
5600         }
5601       } else {
5602         CFX_ByteString propertyStr;
5603         FXJSE_Value_ToUTF8String(propertyValue, propertyStr);
5604         for (int32_t i = 2; i < iLeftLength; i++) {
5605           FXJSE_Value_GetObjectPropByIdx(lValue, i, jsObjectValue);
5606           FXJSE_Value_SetObjectProp(jsObjectValue, propertyStr, rValue);
5607         }
5608       }
5609       FXJSE_Value_Release(jsObjectValue);
5610       FXJSE_Value_Release(propertyValue);
5611     } else if (FXJSE_Value_IsObject(lValue)) {
5612       bSetStatus = SetObjectDefaultValue(lValue, rValue);
5613       if (!bSetStatus) {
5614         pContext->ThrowScriptErrorMessage(XFA_IDS_NOT_DEFAUL_VALUE);
5615       }
5616     }
5617     FXJSE_Value_Set(args.GetReturnValue(), rValue);
5618     FXJSE_Value_Release(lValue);
5619     FXJSE_Value_Release(rValue);
5620   } else {
5621     pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
5622   }
5623 }
logical_or_operator(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)5624 void CXFA_FM2JSContext::logical_or_operator(FXJSE_HOBJECT hThis,
5625                                             const CFX_ByteStringC& szFuncName,
5626                                             CFXJSE_Arguments& args) {
5627   if (args.GetLength() == 2) {
5628     FXJSE_HVALUE argFirst = GetSimpleHValue(hThis, args, 0);
5629     FXJSE_HVALUE argSecond = GetSimpleHValue(hThis, args, 1);
5630     if (FXJSE_Value_IsNull(argFirst) && FXJSE_Value_IsNull(argSecond)) {
5631       FXJSE_Value_SetNull(args.GetReturnValue());
5632     } else {
5633       FX_FLOAT first = HValueToFloat(hThis, argFirst);
5634       FX_FLOAT second = HValueToFloat(hThis, argSecond);
5635       FXJSE_Value_SetInteger(args.GetReturnValue(), (first || second) ? 1 : 0);
5636     }
5637     FXJSE_Value_Release(argFirst);
5638     FXJSE_Value_Release(argSecond);
5639   } else {
5640     CXFA_FM2JSContext* pContext =
5641         (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
5642     pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
5643   }
5644 }
logical_and_operator(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)5645 void CXFA_FM2JSContext::logical_and_operator(FXJSE_HOBJECT hThis,
5646                                              const CFX_ByteStringC& szFuncName,
5647                                              CFXJSE_Arguments& args) {
5648   if (args.GetLength() == 2) {
5649     FXJSE_HVALUE argFirst = GetSimpleHValue(hThis, args, 0);
5650     FXJSE_HVALUE argSecond = GetSimpleHValue(hThis, args, 1);
5651     if (FXJSE_Value_IsNull(argFirst) && FXJSE_Value_IsNull(argSecond)) {
5652       FXJSE_Value_SetNull(args.GetReturnValue());
5653     } else {
5654       FX_FLOAT first = HValueToFloat(hThis, argFirst);
5655       FX_FLOAT second = HValueToFloat(hThis, argSecond);
5656       FXJSE_Value_SetInteger(args.GetReturnValue(), (first && second) ? 1 : 0);
5657     }
5658     FXJSE_Value_Release(argFirst);
5659     FXJSE_Value_Release(argSecond);
5660   } else {
5661     CXFA_FM2JSContext* pContext =
5662         (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
5663     pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
5664   }
5665 }
equality_operator(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)5666 void CXFA_FM2JSContext::equality_operator(FXJSE_HOBJECT hThis,
5667                                           const CFX_ByteStringC& szFuncName,
5668                                           CFXJSE_Arguments& args) {
5669   if (args.GetLength() == 2) {
5670     if (fm_ref_equal(hThis, args)) {
5671       FXJSE_Value_SetInteger(args.GetReturnValue(), 1);
5672     } else {
5673       FXJSE_HVALUE argFirst = GetSimpleHValue(hThis, args, 0);
5674       FXJSE_HVALUE argSecond = GetSimpleHValue(hThis, args, 1);
5675       if (FXJSE_Value_IsNull(argFirst) || FXJSE_Value_IsNull(argSecond)) {
5676         FXJSE_Value_SetInteger(
5677             args.GetReturnValue(),
5678             (FXJSE_Value_IsNull(argFirst) && FXJSE_Value_IsNull(argSecond))
5679                 ? 1
5680                 : 0);
5681       } else if (FXJSE_Value_IsUTF8String(argFirst) &&
5682                  FXJSE_Value_IsUTF8String(argSecond)) {
5683         CFX_ByteString firstOutput;
5684         CFX_ByteString secondOutput;
5685         FXJSE_Value_ToUTF8String(argFirst, firstOutput);
5686         FXJSE_Value_ToUTF8String(argSecond, secondOutput);
5687         FXJSE_Value_SetInteger(args.GetReturnValue(),
5688                                firstOutput.Equal(secondOutput) ? 1 : 0);
5689       } else {
5690         FX_DOUBLE first = HValueToDouble(hThis, argFirst);
5691         FX_DOUBLE second = HValueToDouble(hThis, argSecond);
5692         FXJSE_Value_SetInteger(args.GetReturnValue(),
5693                                (first == second) ? 1 : 0);
5694       }
5695       FXJSE_Value_Release(argFirst);
5696       FXJSE_Value_Release(argSecond);
5697     }
5698   } else {
5699     CXFA_FM2JSContext* pContext =
5700         (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
5701     pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
5702   }
5703 }
notequality_operator(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)5704 void CXFA_FM2JSContext::notequality_operator(FXJSE_HOBJECT hThis,
5705                                              const CFX_ByteStringC& szFuncName,
5706                                              CFXJSE_Arguments& args) {
5707   if (args.GetLength() == 2) {
5708     if (fm_ref_equal(hThis, args)) {
5709       FXJSE_Value_SetInteger(args.GetReturnValue(), 0);
5710     } else {
5711       FXJSE_HVALUE argFirst = GetSimpleHValue(hThis, args, 0);
5712       FXJSE_HVALUE argSecond = GetSimpleHValue(hThis, args, 1);
5713       if (FXJSE_Value_IsNull(argFirst) || FXJSE_Value_IsNull(argSecond)) {
5714         FXJSE_Value_SetInteger(
5715             args.GetReturnValue(),
5716             (FXJSE_Value_IsNull(argFirst) && FXJSE_Value_IsNull(argSecond))
5717                 ? 0
5718                 : 1);
5719       } else if (FXJSE_Value_IsUTF8String(argFirst) &&
5720                  FXJSE_Value_IsUTF8String(argSecond)) {
5721         CFX_ByteString firstOutput;
5722         CFX_ByteString secondOutput;
5723         FXJSE_Value_ToUTF8String(argFirst, firstOutput);
5724         FXJSE_Value_ToUTF8String(argSecond, secondOutput);
5725         FXJSE_Value_SetInteger(args.GetReturnValue(),
5726                                firstOutput.Equal(secondOutput) ? 0 : 1);
5727       } else {
5728         FX_DOUBLE first = HValueToDouble(hThis, argFirst);
5729         FX_DOUBLE second = HValueToDouble(hThis, argSecond);
5730         FXJSE_Value_SetInteger(args.GetReturnValue(),
5731                                (first == second) ? 0 : 1);
5732       }
5733       FXJSE_Value_Release(argFirst);
5734       FXJSE_Value_Release(argSecond);
5735     }
5736   } else {
5737     CXFA_FM2JSContext* pContext =
5738         (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
5739     pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
5740   }
5741 }
fm_ref_equal(FXJSE_HOBJECT hThis,CFXJSE_Arguments & args)5742 FX_BOOL CXFA_FM2JSContext::fm_ref_equal(FXJSE_HOBJECT hThis,
5743                                         CFXJSE_Arguments& args) {
5744   FX_BOOL bRet = FALSE;
5745   CXFA_FM2JSContext* pContext =
5746       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
5747   FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
5748   FXJSE_HVALUE argFirst = args.GetValue(0);
5749   FXJSE_HVALUE argSecond = args.GetValue(0);
5750   if (FXJSE_Value_IsArray(argFirst) && FXJSE_Value_IsArray(argSecond)) {
5751     FXJSE_HVALUE firstFlagValue = FXJSE_Value_Create(hruntime);
5752     FXJSE_HVALUE secondFlagValue = FXJSE_Value_Create(hruntime);
5753     FXJSE_Value_GetObjectPropByIdx(argFirst, 0, firstFlagValue);
5754     FXJSE_Value_GetObjectPropByIdx(argSecond, 0, secondFlagValue);
5755     if ((FXJSE_Value_ToInteger(firstFlagValue) == 3) &&
5756         (FXJSE_Value_ToInteger(secondFlagValue) == 3)) {
5757       FXJSE_HVALUE firstJSObject = FXJSE_Value_Create(hruntime);
5758       FXJSE_HVALUE secondJSObject = FXJSE_Value_Create(hruntime);
5759       FXJSE_Value_GetObjectPropByIdx(argFirst, 2, firstJSObject);
5760       FXJSE_Value_GetObjectPropByIdx(argSecond, 2, secondJSObject);
5761       if (!FXJSE_Value_IsNull(firstJSObject) &&
5762           !FXJSE_Value_IsNull(secondJSObject)) {
5763         bRet = (FXJSE_Value_ToObject(firstJSObject, NULL) ==
5764                 FXJSE_Value_ToObject(secondJSObject, NULL));
5765       }
5766       FXJSE_Value_Release(firstJSObject);
5767       FXJSE_Value_Release(secondJSObject);
5768     }
5769     FXJSE_Value_Release(firstFlagValue);
5770     FXJSE_Value_Release(secondFlagValue);
5771   }
5772   FXJSE_Value_Release(argFirst);
5773   FXJSE_Value_Release(argSecond);
5774   return bRet;
5775 }
less_operator(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)5776 void CXFA_FM2JSContext::less_operator(FXJSE_HOBJECT hThis,
5777                                       const CFX_ByteStringC& szFuncName,
5778                                       CFXJSE_Arguments& args) {
5779   if (args.GetLength() == 2) {
5780     FXJSE_HVALUE argFirst = GetSimpleHValue(hThis, args, 0);
5781     FXJSE_HVALUE argSecond = GetSimpleHValue(hThis, args, 1);
5782     if (FXJSE_Value_IsNull(argFirst) || FXJSE_Value_IsNull(argSecond)) {
5783       FXJSE_Value_SetInteger(args.GetReturnValue(), 0);
5784     } else if (FXJSE_Value_IsUTF8String(argFirst) &&
5785                FXJSE_Value_IsUTF8String(argSecond)) {
5786       CFX_ByteString firstOutput;
5787       CFX_ByteString secondOutput;
5788       FXJSE_Value_ToUTF8String(argFirst, firstOutput);
5789       FXJSE_Value_ToUTF8String(argSecond, secondOutput);
5790       FXJSE_Value_SetInteger(args.GetReturnValue(),
5791                              (firstOutput.Compare(secondOutput) == -1) ? 1 : 0);
5792     } else {
5793       FX_DOUBLE first = HValueToDouble(hThis, argFirst);
5794       FX_DOUBLE second = HValueToDouble(hThis, argSecond);
5795       FXJSE_Value_SetInteger(args.GetReturnValue(), (first < second) ? 1 : 0);
5796     }
5797     FXJSE_Value_Release(argFirst);
5798     FXJSE_Value_Release(argSecond);
5799   } else {
5800     CXFA_FM2JSContext* pContext =
5801         (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
5802     pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
5803   }
5804 }
lessequal_operator(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)5805 void CXFA_FM2JSContext::lessequal_operator(FXJSE_HOBJECT hThis,
5806                                            const CFX_ByteStringC& szFuncName,
5807                                            CFXJSE_Arguments& args) {
5808   if (args.GetLength() == 2) {
5809     FXJSE_HVALUE argFirst = GetSimpleHValue(hThis, args, 0);
5810     FXJSE_HVALUE argSecond = GetSimpleHValue(hThis, args, 1);
5811     if (FXJSE_Value_IsNull(argFirst) || FXJSE_Value_IsNull(argSecond)) {
5812       FXJSE_Value_SetInteger(
5813           args.GetReturnValue(),
5814           (FXJSE_Value_IsNull(argFirst) && FXJSE_Value_IsNull(argSecond)) ? 1
5815                                                                           : 0);
5816     } else if (FXJSE_Value_IsUTF8String(argFirst) &&
5817                FXJSE_Value_IsUTF8String(argSecond)) {
5818       CFX_ByteString firstOutput;
5819       CFX_ByteString secondOutput;
5820       FXJSE_Value_ToUTF8String(argFirst, firstOutput);
5821       FXJSE_Value_ToUTF8String(argSecond, secondOutput);
5822       FXJSE_Value_SetInteger(args.GetReturnValue(),
5823                              (firstOutput.Compare(secondOutput) != 1) ? 1 : 0);
5824     } else {
5825       FX_DOUBLE first = HValueToDouble(hThis, argFirst);
5826       FX_DOUBLE second = HValueToDouble(hThis, argSecond);
5827       FXJSE_Value_SetInteger(args.GetReturnValue(), (first <= second) ? 1 : 0);
5828     }
5829     FXJSE_Value_Release(argFirst);
5830     FXJSE_Value_Release(argSecond);
5831   } else {
5832     CXFA_FM2JSContext* pContext =
5833         (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
5834     pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
5835   }
5836 }
greater_operator(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)5837 void CXFA_FM2JSContext::greater_operator(FXJSE_HOBJECT hThis,
5838                                          const CFX_ByteStringC& szFuncName,
5839                                          CFXJSE_Arguments& args) {
5840   if (args.GetLength() == 2) {
5841     FXJSE_HVALUE argFirst = GetSimpleHValue(hThis, args, 0);
5842     FXJSE_HVALUE argSecond = GetSimpleHValue(hThis, args, 1);
5843     if (FXJSE_Value_IsNull(argFirst) || FXJSE_Value_IsNull(argSecond)) {
5844       FXJSE_Value_SetInteger(args.GetReturnValue(), 0);
5845     } else if (FXJSE_Value_IsUTF8String(argFirst) &&
5846                FXJSE_Value_IsUTF8String(argSecond)) {
5847       CFX_ByteString firstOutput;
5848       CFX_ByteString secondOutput;
5849       FXJSE_Value_ToUTF8String(argFirst, firstOutput);
5850       FXJSE_Value_ToUTF8String(argSecond, secondOutput);
5851       FXJSE_Value_SetInteger(args.GetReturnValue(),
5852                              (firstOutput.Compare(secondOutput) == 1) ? 1 : 0);
5853     } else {
5854       FX_DOUBLE first = HValueToDouble(hThis, argFirst);
5855       FX_DOUBLE second = HValueToDouble(hThis, argSecond);
5856       FXJSE_Value_SetInteger(args.GetReturnValue(), (first > second) ? 1 : 0);
5857     }
5858     FXJSE_Value_Release(argFirst);
5859     FXJSE_Value_Release(argSecond);
5860   } else {
5861     CXFA_FM2JSContext* pContext =
5862         (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
5863     pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
5864   }
5865 }
greaterequal_operator(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)5866 void CXFA_FM2JSContext::greaterequal_operator(FXJSE_HOBJECT hThis,
5867                                               const CFX_ByteStringC& szFuncName,
5868                                               CFXJSE_Arguments& args) {
5869   if (args.GetLength() == 2) {
5870     FXJSE_HVALUE argFirst = GetSimpleHValue(hThis, args, 0);
5871     FXJSE_HVALUE argSecond = GetSimpleHValue(hThis, args, 1);
5872     if (FXJSE_Value_IsNull(argFirst) || FXJSE_Value_IsNull(argSecond)) {
5873       FXJSE_Value_SetInteger(
5874           args.GetReturnValue(),
5875           (FXJSE_Value_IsNull(argFirst) && FXJSE_Value_IsNull(argSecond)) ? 1
5876                                                                           : 0);
5877     } else if (FXJSE_Value_IsUTF8String(argFirst) &&
5878                FXJSE_Value_IsUTF8String(argSecond)) {
5879       CFX_ByteString firstOutput;
5880       CFX_ByteString secondOutput;
5881       FXJSE_Value_ToUTF8String(argFirst, firstOutput);
5882       FXJSE_Value_ToUTF8String(argSecond, secondOutput);
5883       FXJSE_Value_SetInteger(args.GetReturnValue(),
5884                              (firstOutput.Compare(secondOutput) != -1) ? 1 : 0);
5885     } else {
5886       FX_DOUBLE first = HValueToDouble(hThis, argFirst);
5887       FX_DOUBLE second = HValueToDouble(hThis, argSecond);
5888       FXJSE_Value_SetInteger(args.GetReturnValue(), (first >= second) ? 1 : 0);
5889     }
5890     FXJSE_Value_Release(argFirst);
5891     FXJSE_Value_Release(argSecond);
5892   } else {
5893     CXFA_FM2JSContext* pContext =
5894         (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
5895     pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
5896   }
5897 }
plus_operator(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)5898 void CXFA_FM2JSContext::plus_operator(FXJSE_HOBJECT hThis,
5899                                       const CFX_ByteStringC& szFuncName,
5900                                       CFXJSE_Arguments& args) {
5901   if (args.GetLength() == 2) {
5902     FXJSE_HVALUE argFirst = args.GetValue(0);
5903     FXJSE_HVALUE argSecond = args.GetValue(1);
5904     if (HValueIsNull(hThis, argFirst) && HValueIsNull(hThis, argSecond)) {
5905       FXJSE_Value_SetNull(args.GetReturnValue());
5906     } else {
5907       FX_DOUBLE first = HValueToDouble(hThis, argFirst);
5908       FX_DOUBLE second = HValueToDouble(hThis, argSecond);
5909       FXJSE_Value_SetDouble(args.GetReturnValue(), first + second);
5910     }
5911     FXJSE_Value_Release(argFirst);
5912     FXJSE_Value_Release(argSecond);
5913   } else {
5914     CXFA_FM2JSContext* pContext =
5915         (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
5916     pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
5917   }
5918 }
minus_operator(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)5919 void CXFA_FM2JSContext::minus_operator(FXJSE_HOBJECT hThis,
5920                                        const CFX_ByteStringC& szFuncName,
5921                                        CFXJSE_Arguments& args) {
5922   if (args.GetLength() == 2) {
5923     FXJSE_HVALUE argFirst = GetSimpleHValue(hThis, args, 0);
5924     FXJSE_HVALUE argSecond = GetSimpleHValue(hThis, args, 1);
5925     if (FXJSE_Value_IsNull(argFirst) && FXJSE_Value_IsNull(argSecond)) {
5926       FXJSE_Value_SetNull(args.GetReturnValue());
5927     } else {
5928       FX_DOUBLE first = HValueToDouble(hThis, argFirst);
5929       FX_DOUBLE second = HValueToDouble(hThis, argSecond);
5930       FXJSE_Value_SetDouble(args.GetReturnValue(), first - second);
5931     }
5932     FXJSE_Value_Release(argFirst);
5933     FXJSE_Value_Release(argSecond);
5934   } else {
5935     CXFA_FM2JSContext* pContext =
5936         (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
5937     pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
5938   }
5939 }
multiple_operator(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)5940 void CXFA_FM2JSContext::multiple_operator(FXJSE_HOBJECT hThis,
5941                                           const CFX_ByteStringC& szFuncName,
5942                                           CFXJSE_Arguments& args) {
5943   if (args.GetLength() == 2) {
5944     FXJSE_HVALUE argFirst = GetSimpleHValue(hThis, args, 0);
5945     FXJSE_HVALUE argSecond = GetSimpleHValue(hThis, args, 1);
5946     if (FXJSE_Value_IsNull(argFirst) && FXJSE_Value_IsNull(argSecond)) {
5947       FXJSE_Value_SetNull(args.GetReturnValue());
5948     } else {
5949       FX_DOUBLE first = HValueToDouble(hThis, argFirst);
5950       FX_DOUBLE second = HValueToDouble(hThis, argSecond);
5951       FXJSE_Value_SetDouble(args.GetReturnValue(), first * second);
5952     }
5953     FXJSE_Value_Release(argFirst);
5954     FXJSE_Value_Release(argSecond);
5955   } else {
5956     CXFA_FM2JSContext* pContext =
5957         (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
5958     pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
5959   }
5960 }
divide_operator(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)5961 void CXFA_FM2JSContext::divide_operator(FXJSE_HOBJECT hThis,
5962                                         const CFX_ByteStringC& szFuncName,
5963                                         CFXJSE_Arguments& args) {
5964   CXFA_FM2JSContext* pContext =
5965       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
5966   if (args.GetLength() == 2) {
5967     FXJSE_HVALUE argFirst = GetSimpleHValue(hThis, args, 0);
5968     FXJSE_HVALUE argSecond = GetSimpleHValue(hThis, args, 1);
5969     if (FXJSE_Value_IsNull(argFirst) && FXJSE_Value_IsNull(argSecond)) {
5970       FXJSE_Value_SetNull(args.GetReturnValue());
5971     } else {
5972       FX_DOUBLE first = HValueToDouble(hThis, argFirst);
5973       FX_DOUBLE second = HValueToDouble(hThis, argSecond);
5974       if (second == 0.0) {
5975         pContext->ThrowScriptErrorMessage(XFA_IDS_DIVIDE_ZERO);
5976       } else {
5977         FXJSE_Value_SetDouble(args.GetReturnValue(), first / second);
5978       }
5979     }
5980     FXJSE_Value_Release(argFirst);
5981     FXJSE_Value_Release(argSecond);
5982   } else {
5983     pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
5984   }
5985 }
positive_operator(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)5986 void CXFA_FM2JSContext::positive_operator(FXJSE_HOBJECT hThis,
5987                                           const CFX_ByteStringC& szFuncName,
5988                                           CFXJSE_Arguments& args) {
5989   int32_t iLength = args.GetLength();
5990   if (iLength == 1) {
5991     FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
5992     if (FXJSE_Value_IsNull(argOne)) {
5993       FXJSE_Value_SetNull(args.GetReturnValue());
5994     } else {
5995       FXJSE_Value_SetDouble(args.GetReturnValue(),
5996                             0.0 + HValueToDouble(hThis, argOne));
5997     }
5998     FXJSE_Value_Release(argOne);
5999   } else {
6000     CXFA_FM2JSContext* pContext =
6001         (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
6002     pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
6003   }
6004 }
negative_operator(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)6005 void CXFA_FM2JSContext::negative_operator(FXJSE_HOBJECT hThis,
6006                                           const CFX_ByteStringC& szFuncName,
6007                                           CFXJSE_Arguments& args) {
6008   int32_t iLength = args.GetLength();
6009   if (iLength == 1) {
6010     FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
6011     if (FXJSE_Value_IsNull(argOne)) {
6012       FXJSE_Value_SetNull(args.GetReturnValue());
6013     } else {
6014       FXJSE_Value_SetDouble(args.GetReturnValue(),
6015                             0.0 - HValueToDouble(hThis, argOne));
6016     }
6017     FXJSE_Value_Release(argOne);
6018   } else {
6019     CXFA_FM2JSContext* pContext =
6020         (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
6021     pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
6022   }
6023 }
logical_not_operator(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)6024 void CXFA_FM2JSContext::logical_not_operator(FXJSE_HOBJECT hThis,
6025                                              const CFX_ByteStringC& szFuncName,
6026                                              CFXJSE_Arguments& args) {
6027   int32_t iLength = args.GetLength();
6028   if (iLength == 1) {
6029     FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
6030     if (FXJSE_Value_IsNull(argOne)) {
6031       FXJSE_Value_SetNull(args.GetReturnValue());
6032     } else {
6033       FX_DOUBLE first = HValueToDouble(hThis, argOne);
6034       FXJSE_Value_SetInteger(args.GetReturnValue(), (first == 0.0) ? 1 : 0);
6035     }
6036     FXJSE_Value_Release(argOne);
6037   } else {
6038     CXFA_FM2JSContext* pContext =
6039         (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
6040     pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
6041   }
6042 }
dot_accessor(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)6043 void CXFA_FM2JSContext::dot_accessor(FXJSE_HOBJECT hThis,
6044                                      const CFX_ByteStringC& szFuncName,
6045                                      CFXJSE_Arguments& args) {
6046   CXFA_FM2JSContext* pContext =
6047       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
6048   FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
6049   int32_t argc = args.GetLength();
6050   if ((argc == 4) || (argc == 5)) {
6051     FX_BOOL bIsStar = TRUE;
6052     FXJSE_HVALUE argAccessor = args.GetValue(0);
6053     CFX_ByteString bsAccessorName = args.GetUTF8String(1);
6054     CFX_ByteString szName = args.GetUTF8String(2);
6055     int32_t iIndexFlags = args.GetInt32(3);
6056     int32_t iIndexValue = 0;
6057     FXJSE_HVALUE argIndex = NULL;
6058     if (argc == 5) {
6059       bIsStar = FALSE;
6060       argIndex = args.GetValue(4);
6061       iIndexValue = HValueToInteger(hThis, argIndex);
6062     }
6063     CFX_ByteString szSomExp;
6064     GenerateSomExpression(szName, iIndexFlags, iIndexValue, bIsStar, szSomExp);
6065     if (FXJSE_Value_IsArray(argAccessor)) {
6066       FXJSE_HVALUE hLengthValue = FXJSE_Value_Create(hruntime);
6067       FXJSE_Value_GetObjectProp(argAccessor, "length", hLengthValue);
6068       int32_t iLength = FXJSE_Value_ToInteger(hLengthValue);
6069       FXJSE_Value_Release(hLengthValue);
6070       int32_t iCounter = 0;
6071       FXJSE_HVALUE** hResolveValues = FX_Alloc(FXJSE_HVALUE*, iLength - 2);
6072       int32_t* iSizes = FX_Alloc(int32_t, iLength - 2);
6073       for (int32_t i = 0; i < (iLength - 2); i++) {
6074         iSizes[i] = 0;
6075       }
6076       FXJSE_HVALUE hJSObjValue = FXJSE_Value_Create(hruntime);
6077       FX_BOOL bAttribute = FALSE;
6078       for (int32_t i = 2; i < iLength; i++) {
6079         FXJSE_Value_GetObjectPropByIdx(argAccessor, i, hJSObjValue);
6080         XFA_RESOLVENODE_RS resoveNodeRS;
6081         int32_t iRet = ResolveObjects(hThis, hJSObjValue, szSomExp,
6082                                       resoveNodeRS, TRUE, szName.IsEmpty());
6083         if (iRet > 0) {
6084           ParseResolveResult(hThis, resoveNodeRS, hJSObjValue,
6085                              hResolveValues[i - 2], iSizes[i - 2], bAttribute);
6086           iCounter += iSizes[i - 2];
6087         }
6088       }
6089       FXJSE_Value_Release(hJSObjValue);
6090       if (iCounter > 0) {
6091         FXJSE_HVALUE* rgValues = FX_Alloc(FXJSE_HVALUE, iCounter + 2);
6092         for (int32_t i = 0; i < (iCounter + 2); i++) {
6093           rgValues[i] = FXJSE_Value_Create(hruntime);
6094         }
6095         FXJSE_Value_SetInteger(rgValues[0], 1);
6096         if (bAttribute) {
6097           FXJSE_Value_SetUTF8String(rgValues[1], szName);
6098         } else {
6099           FXJSE_Value_SetNull(rgValues[1]);
6100         }
6101         int32_t iIndex = 2;
6102         for (int32_t i = 0; i < iLength - 2; i++) {
6103           for (int32_t j = 0; j < iSizes[i]; j++) {
6104             FXJSE_Value_Set(rgValues[iIndex], hResolveValues[i][j]);
6105             iIndex++;
6106           }
6107         }
6108         FXJSE_Value_SetArray(args.GetReturnValue(), (iCounter + 2), rgValues);
6109         for (int32_t i = 0; i < (iCounter + 2); i++) {
6110           FXJSE_Value_Release(rgValues[i]);
6111         }
6112         FX_Free(rgValues);
6113       } else {
6114         CFX_WideString wsPropertyName =
6115             CFX_WideString::FromUTF8(szName, szName.GetLength());
6116         CFX_WideString wsSomExpression =
6117             CFX_WideString::FromUTF8(szSomExp, szSomExp.GetLength());
6118         pContext->ThrowScriptErrorMessage(XFA_IDS_ACCESS_PROPERTY_IN_NOT_OBJECT,
6119                                           (const FX_WCHAR*)wsPropertyName,
6120                                           (const FX_WCHAR*)wsSomExpression);
6121       }
6122       for (int32_t i = 0; i < iLength - 2; i++) {
6123         for (int32_t j = 0; j < iSizes[i]; j++) {
6124           FXJSE_Value_Release(hResolveValues[i][j]);
6125         }
6126         if (iSizes[i] > 0) {
6127           FX_Free(hResolveValues[i]);
6128         }
6129       }
6130       FX_Free(hResolveValues);
6131       FX_Free(iSizes);
6132     } else {
6133       XFA_RESOLVENODE_RS resoveNodeRS;
6134       int32_t iRet = 0;
6135       if (FXJSE_Value_IsObject(argAccessor) ||
6136           (FXJSE_Value_IsNull(argAccessor) && bsAccessorName.IsEmpty())) {
6137         iRet = ResolveObjects(hThis, argAccessor, szSomExp, resoveNodeRS, TRUE,
6138                               szName.IsEmpty());
6139       } else if (!FXJSE_Value_IsObject(argAccessor) &&
6140                  !bsAccessorName.IsEmpty()) {
6141         FX_BOOL bGetObject =
6142             GetObjectByName(hThis, argAccessor, bsAccessorName);
6143         if (bGetObject) {
6144           iRet = ResolveObjects(hThis, argAccessor, szSomExp, resoveNodeRS,
6145                                 TRUE, szName.IsEmpty());
6146         }
6147       }
6148       if (iRet > 0) {
6149         FXJSE_HVALUE* hResolveValues;
6150         int32_t iSize = 0;
6151         FX_BOOL bAttribute = FALSE;
6152         ParseResolveResult(hThis, resoveNodeRS, argAccessor, hResolveValues,
6153                            iSize, bAttribute);
6154         FXJSE_HVALUE* rgValues = FX_Alloc(FXJSE_HVALUE, iSize + 2);
6155         for (int32_t i = 0; i < (iSize + 2); i++) {
6156           rgValues[i] = FXJSE_Value_Create(hruntime);
6157         }
6158         FXJSE_Value_SetInteger(rgValues[0], 1);
6159         if (bAttribute) {
6160           FXJSE_Value_SetUTF8String(rgValues[1], szName);
6161         } else {
6162           FXJSE_Value_SetNull(rgValues[1]);
6163         }
6164         for (int32_t i = 0; i < iSize; i++) {
6165           FXJSE_Value_Set(rgValues[i + 2], hResolveValues[i]);
6166         }
6167         FXJSE_Value_SetArray(args.GetReturnValue(), (iSize + 2), rgValues);
6168         for (int32_t i = 0; i < (iSize + 2); i++) {
6169           FXJSE_Value_Release(rgValues[i]);
6170         }
6171         FX_Free(rgValues);
6172         for (int32_t i = 0; i < iSize; i++) {
6173           FXJSE_Value_Release(hResolveValues[i]);
6174         }
6175         FX_Free(hResolveValues);
6176       } else {
6177         CFX_WideString wsPropertyName =
6178             CFX_WideString::FromUTF8(szName, szName.GetLength());
6179         CFX_WideString wsSomExpression =
6180             CFX_WideString::FromUTF8(szSomExp, szSomExp.GetLength());
6181         pContext->ThrowScriptErrorMessage(XFA_IDS_ACCESS_PROPERTY_IN_NOT_OBJECT,
6182                                           (const FX_WCHAR*)wsPropertyName,
6183                                           (const FX_WCHAR*)wsSomExpression);
6184       }
6185     }
6186     if (argc == 5) {
6187       FXJSE_Value_Release(argIndex);
6188     }
6189     FXJSE_Value_Release(argAccessor);
6190   } else {
6191     pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
6192   }
6193 }
dotdot_accessor(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)6194 void CXFA_FM2JSContext::dotdot_accessor(FXJSE_HOBJECT hThis,
6195                                         const CFX_ByteStringC& szFuncName,
6196                                         CFXJSE_Arguments& args) {
6197   CXFA_FM2JSContext* pContext =
6198       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
6199   FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
6200   int32_t argc = args.GetLength();
6201   if ((argc == 4) || (argc == 5)) {
6202     FX_BOOL bIsStar = TRUE;
6203     FXJSE_HVALUE argAccessor = args.GetValue(0);
6204     CFX_ByteString bsAccessorName = args.GetUTF8String(1);
6205     CFX_ByteString szName = args.GetUTF8String(2);
6206     int32_t iIndexFlags = args.GetInt32(3);
6207     int32_t iIndexValue = 0;
6208     FXJSE_HVALUE argIndex = NULL;
6209     if (argc == 5) {
6210       bIsStar = FALSE;
6211       argIndex = args.GetValue(4);
6212       iIndexValue = HValueToInteger(hThis, argIndex);
6213     }
6214     CFX_ByteString szSomExp;
6215     GenerateSomExpression(szName, iIndexFlags, iIndexValue, bIsStar, szSomExp);
6216     if (FXJSE_Value_IsArray(argAccessor)) {
6217       FXJSE_HVALUE hLengthValue = FXJSE_Value_Create(hruntime);
6218       FXJSE_Value_GetObjectProp(argAccessor, "length", hLengthValue);
6219       int32_t iLength = FXJSE_Value_ToInteger(hLengthValue);
6220       int32_t iCounter = 0;
6221       FXJSE_HVALUE** hResolveValues = FX_Alloc(FXJSE_HVALUE*, iLength - 2);
6222       int32_t* iSizes = FX_Alloc(int32_t, iLength - 2);
6223       FXJSE_HVALUE hJSObjValue = FXJSE_Value_Create(hruntime);
6224       FX_BOOL bAttribute = FALSE;
6225       for (int32_t i = 2; i < iLength; i++) {
6226         FXJSE_Value_GetObjectPropByIdx(argAccessor, i, hJSObjValue);
6227         XFA_RESOLVENODE_RS resoveNodeRS;
6228         int32_t iRet =
6229             ResolveObjects(hThis, hJSObjValue, szSomExp, resoveNodeRS, FALSE);
6230         if (iRet > 0) {
6231           ParseResolveResult(hThis, resoveNodeRS, hJSObjValue,
6232                              hResolveValues[i - 2], iSizes[i - 2], bAttribute);
6233           iCounter += iSizes[i - 2];
6234         }
6235       }
6236       FXJSE_Value_Release(hJSObjValue);
6237       if (iCounter > 0) {
6238         FXJSE_HVALUE* rgValues = FX_Alloc(FXJSE_HVALUE, iCounter + 2);
6239         for (int32_t i = 0; i < (iCounter + 2); i++) {
6240           rgValues[i] = FXJSE_Value_Create(hruntime);
6241         }
6242         FXJSE_Value_SetInteger(rgValues[0], 1);
6243         if (bAttribute) {
6244           FXJSE_Value_SetUTF8String(rgValues[1], szName);
6245         } else {
6246           FXJSE_Value_SetNull(rgValues[1]);
6247         }
6248         int32_t iIndex = 2;
6249         for (int32_t i = 0; i < iLength - 2; i++) {
6250           for (int32_t j = 0; j < iSizes[i]; j++) {
6251             FXJSE_Value_Set(rgValues[iIndex], hResolveValues[i][j]);
6252             iIndex++;
6253           }
6254         }
6255         FXJSE_Value_SetArray(args.GetReturnValue(), (iCounter + 2), rgValues);
6256         for (int32_t i = 0; i < (iCounter + 2); i++) {
6257           FXJSE_Value_Release(rgValues[i]);
6258         }
6259         FX_Free(rgValues);
6260       } else {
6261         CFX_WideString wsPropertyName =
6262             CFX_WideString::FromUTF8(szName, szName.GetLength());
6263         CFX_WideString wsSomExpression =
6264             CFX_WideString::FromUTF8(szSomExp, szSomExp.GetLength());
6265         pContext->ThrowScriptErrorMessage(XFA_IDS_ACCESS_PROPERTY_IN_NOT_OBJECT,
6266                                           (const FX_WCHAR*)wsPropertyName,
6267                                           (const FX_WCHAR*)wsSomExpression);
6268       }
6269       for (int32_t i = 0; i < iLength - 2; i++) {
6270         for (int32_t j = 0; j < iSizes[i]; j++) {
6271           FXJSE_Value_Release(hResolveValues[i][j]);
6272         }
6273         FX_Free(hResolveValues[i]);
6274       }
6275       FX_Free(hResolveValues);
6276       FX_Free(iSizes);
6277       FXJSE_Value_Release(hLengthValue);
6278     } else {
6279       XFA_RESOLVENODE_RS resoveNodeRS;
6280       int32_t iRet = 0;
6281       if (FXJSE_Value_IsObject(argAccessor) ||
6282           (FXJSE_Value_IsNull(argAccessor) && bsAccessorName.IsEmpty())) {
6283         iRet =
6284             ResolveObjects(hThis, argAccessor, szSomExp, resoveNodeRS, FALSE);
6285       } else if (!FXJSE_Value_IsObject(argAccessor) &&
6286                  !bsAccessorName.IsEmpty()) {
6287         FX_BOOL bGetObject =
6288             GetObjectByName(hThis, argAccessor, bsAccessorName);
6289         if (bGetObject) {
6290           iRet =
6291               ResolveObjects(hThis, argAccessor, szSomExp, resoveNodeRS, FALSE);
6292         }
6293       }
6294       if (iRet > 0) {
6295         FXJSE_HVALUE* hResolveValues;
6296         int32_t iSize = 0;
6297         FX_BOOL bAttribute = FALSE;
6298         ParseResolveResult(hThis, resoveNodeRS, argAccessor, hResolveValues,
6299                            iSize, bAttribute);
6300         FXJSE_HVALUE* rgValues = FX_Alloc(FXJSE_HVALUE, iSize + 2);
6301         for (int32_t i = 0; i < (iSize + 2); i++) {
6302           rgValues[i] = FXJSE_Value_Create(hruntime);
6303         }
6304         FXJSE_Value_SetInteger(rgValues[0], 1);
6305         if (bAttribute) {
6306           FXJSE_Value_SetUTF8String(rgValues[1], szName);
6307         } else {
6308           FXJSE_Value_SetNull(rgValues[1]);
6309         }
6310         for (int32_t i = 0; i < iSize; i++) {
6311           FXJSE_Value_Set(rgValues[i + 2], hResolveValues[i]);
6312         }
6313         FXJSE_Value_SetArray(args.GetReturnValue(), (iSize + 2), rgValues);
6314         for (int32_t i = 0; i < (iSize + 2); i++) {
6315           FXJSE_Value_Release(rgValues[i]);
6316         }
6317         FX_Free(rgValues);
6318         for (int32_t i = 0; i < iSize; i++) {
6319           FXJSE_Value_Release(hResolveValues[i]);
6320         }
6321         FX_Free(hResolveValues);
6322       } else {
6323         CFX_WideString wsPropertyName =
6324             CFX_WideString::FromUTF8(szName, szName.GetLength());
6325         CFX_WideString wsSomExpression =
6326             CFX_WideString::FromUTF8(szSomExp, szSomExp.GetLength());
6327         pContext->ThrowScriptErrorMessage(XFA_IDS_ACCESS_PROPERTY_IN_NOT_OBJECT,
6328                                           (const FX_WCHAR*)wsPropertyName,
6329                                           (const FX_WCHAR*)wsSomExpression);
6330       }
6331     }
6332     if (argc == 5) {
6333       FXJSE_Value_Release(argIndex);
6334     }
6335     FXJSE_Value_Release(argAccessor);
6336   } else {
6337     pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
6338   }
6339 }
eval_translation(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)6340 void CXFA_FM2JSContext::eval_translation(FXJSE_HOBJECT hThis,
6341                                          const CFX_ByteStringC& szFuncName,
6342                                          CFXJSE_Arguments& args) {
6343   CXFA_FM2JSContext* pContext =
6344       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
6345   int32_t argc = args.GetLength();
6346   if (argc == 1) {
6347     FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
6348     CFX_ByteString argString;
6349     HValueToUTF8String(argOne, argString);
6350     if (argString.IsEmpty()) {
6351       pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
6352     } else {
6353       CFX_WideString scriptString =
6354           CFX_WideString::FromUTF8(argString, argString.GetLength());
6355       CFX_WideTextBuf wsJavaScriptBuf;
6356       CFX_WideString wsError;
6357       XFA_FM2JS_Translate(scriptString, wsJavaScriptBuf, wsError);
6358       if (wsError.IsEmpty()) {
6359         CFX_WideString javaScript = wsJavaScriptBuf.GetWideString();
6360         FXJSE_Value_SetUTF8String(
6361             args.GetReturnValue(),
6362             FX_UTF8Encode(javaScript, javaScript.GetLength()));
6363       } else {
6364         pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
6365       }
6366     }
6367     FXJSE_Value_Release(argOne);
6368   } else {
6369     pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
6370                                       L"Eval");
6371   }
6372 }
is_fm_object(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)6373 void CXFA_FM2JSContext::is_fm_object(FXJSE_HOBJECT hThis,
6374                                      const CFX_ByteStringC& szFuncName,
6375                                      CFXJSE_Arguments& args) {
6376   int32_t iLength = args.GetLength();
6377   if (iLength == 1) {
6378     FXJSE_HVALUE argOne = args.GetValue(0);
6379     FXJSE_Value_SetBoolean(args.GetReturnValue(), FXJSE_Value_IsObject(argOne));
6380     FXJSE_Value_Release(argOne);
6381   } else {
6382     FXJSE_Value_SetBoolean(args.GetReturnValue(), FALSE);
6383   }
6384 }
is_fm_array(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)6385 void CXFA_FM2JSContext::is_fm_array(FXJSE_HOBJECT hThis,
6386                                     const CFX_ByteStringC& szFuncName,
6387                                     CFXJSE_Arguments& args) {
6388   int32_t iLength = args.GetLength();
6389   if (iLength == 1) {
6390     FXJSE_HVALUE argOne = args.GetValue(0);
6391     FX_BOOL bIsArray = FXJSE_Value_IsArray(argOne);
6392     FXJSE_Value_SetBoolean(args.GetReturnValue(), bIsArray);
6393     FXJSE_Value_Release(argOne);
6394   } else {
6395     FXJSE_Value_SetBoolean(args.GetReturnValue(), FALSE);
6396   }
6397 }
get_fm_value(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)6398 void CXFA_FM2JSContext::get_fm_value(FXJSE_HOBJECT hThis,
6399                                      const CFX_ByteStringC& szFuncName,
6400                                      CFXJSE_Arguments& args) {
6401   CXFA_FM2JSContext* pContext =
6402       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
6403   FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
6404   int32_t iLength = args.GetLength();
6405   if (iLength == 1) {
6406     FXJSE_HVALUE argOne = args.GetValue(0);
6407     if (FXJSE_Value_IsArray(argOne)) {
6408       FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
6409       FXJSE_HVALUE jsobjectValue = FXJSE_Value_Create(hruntime);
6410       FXJSE_Value_GetObjectPropByIdx(argOne, 1, propertyValue);
6411       FXJSE_Value_GetObjectPropByIdx(argOne, 2, jsobjectValue);
6412       if (FXJSE_Value_IsNull(propertyValue)) {
6413         GetObjectDefaultValue(jsobjectValue, args.GetReturnValue());
6414       } else {
6415         CFX_ByteString propertyStr;
6416         FXJSE_Value_ToUTF8String(propertyValue, propertyStr);
6417         FXJSE_Value_GetObjectProp(jsobjectValue, propertyStr,
6418                                   args.GetReturnValue());
6419       }
6420       FXJSE_Value_Release(propertyValue);
6421       FXJSE_Value_Release(jsobjectValue);
6422     } else if (FXJSE_Value_IsObject(argOne)) {
6423       GetObjectDefaultValue(argOne, args.GetReturnValue());
6424     } else {
6425       FXJSE_Value_Set(args.GetReturnValue(), argOne);
6426     }
6427     FXJSE_Value_Release(argOne);
6428   } else {
6429     pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
6430   }
6431 }
get_fm_jsobj(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)6432 void CXFA_FM2JSContext::get_fm_jsobj(FXJSE_HOBJECT hThis,
6433                                      const CFX_ByteStringC& szFuncName,
6434                                      CFXJSE_Arguments& args) {
6435   CXFA_FM2JSContext* pContext =
6436       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
6437   FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
6438   int32_t argc = args.GetLength();
6439   if (argc == 1) {
6440     FXJSE_HVALUE argOne = args.GetValue(0);
6441     if (FXJSE_Value_IsArray(argOne)) {
6442       FXJSE_HVALUE lengthValue = FXJSE_Value_Create(hruntime);
6443       FXJSE_Value_GetObjectProp(argOne, "length", lengthValue);
6444       int32_t iLength = FXJSE_Value_ToInteger(lengthValue);
6445       FXSYS_assert(iLength >= 3);
6446       FXJSE_Value_Release(lengthValue);
6447       FXJSE_Value_GetObjectPropByIdx(argOne, 2, args.GetReturnValue());
6448     } else {
6449       FXJSE_Value_Set(args.GetReturnValue(), argOne);
6450     }
6451     FXJSE_Value_Release(argOne);
6452   } else {
6453     pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
6454   }
6455 }
fm_var_filter(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)6456 void CXFA_FM2JSContext::fm_var_filter(FXJSE_HOBJECT hThis,
6457                                       const CFX_ByteStringC& szFuncName,
6458                                       CFXJSE_Arguments& args) {
6459   CXFA_FM2JSContext* pContext =
6460       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
6461   FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
6462   int32_t argc = args.GetLength();
6463   if (argc == 1) {
6464     FXJSE_HVALUE argOne = args.GetValue(0);
6465     if (FXJSE_Value_IsArray(argOne)) {
6466       FXJSE_HVALUE lengthValue = FXJSE_Value_Create(hruntime);
6467       FXJSE_Value_GetObjectProp(argOne, "length", lengthValue);
6468       int32_t iLength = FXJSE_Value_ToInteger(lengthValue);
6469       FXSYS_assert(iLength >= 3);
6470       FXJSE_Value_Release(lengthValue);
6471       FXJSE_HVALUE flagsValue = FXJSE_Value_Create(hruntime);
6472       FXJSE_Value_GetObjectPropByIdx(argOne, 0, flagsValue);
6473       int32_t iFlags = FXJSE_Value_ToInteger(flagsValue);
6474       FXJSE_Value_Release(flagsValue);
6475       if (iFlags == 4) {
6476         FXJSE_HVALUE rgValues[3];
6477         for (int32_t i = 0; i < 3; i++) {
6478           rgValues[i] = FXJSE_Value_Create(hruntime);
6479         }
6480         FXJSE_Value_SetInteger(rgValues[0], 3);
6481         FXJSE_Value_SetNull(rgValues[1]);
6482         FXJSE_Value_SetNull(rgValues[2]);
6483         FXJSE_Value_SetArray(args.GetReturnValue(), 3, rgValues);
6484         for (int32_t i = 0; i < 3; i++) {
6485           FXJSE_Value_Release(rgValues[i]);
6486         }
6487       } else if (iFlags == 3) {
6488         FXJSE_HVALUE objectValue = FXJSE_Value_Create(hruntime);
6489         FXJSE_Value_GetObjectPropByIdx(argOne, 2, objectValue);
6490         if (!FXJSE_Value_IsNull(objectValue)) {
6491           FXJSE_Value_Set(args.GetReturnValue(), argOne);
6492         } else {
6493           pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
6494         }
6495         FXJSE_Value_Release(objectValue);
6496       } else {
6497         FXJSE_HVALUE simpleValue = GetSimpleHValue(hThis, args, 0);
6498         FXJSE_Value_Set(args.GetReturnValue(), simpleValue);
6499         FXJSE_Value_Release(simpleValue);
6500       }
6501     } else {
6502       FXJSE_HVALUE simpleValue = GetSimpleHValue(hThis, args, 0);
6503       FXJSE_Value_Set(args.GetReturnValue(), simpleValue);
6504       FXJSE_Value_Release(simpleValue);
6505     }
6506     FXJSE_Value_Release(argOne);
6507   } else {
6508     pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
6509   }
6510 }
concat_fm_object(FXJSE_HOBJECT hThis,const CFX_ByteStringC & szFuncName,CFXJSE_Arguments & args)6511 void CXFA_FM2JSContext::concat_fm_object(FXJSE_HOBJECT hThis,
6512                                          const CFX_ByteStringC& szFuncName,
6513                                          CFXJSE_Arguments& args) {
6514   CXFA_FM2JSContext* pContext =
6515       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
6516   FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
6517   uint32_t iLength = 0;
6518   int32_t argCount = args.GetLength();
6519   FXJSE_HVALUE* argValues = FX_Alloc(FXJSE_HVALUE, argCount);
6520   for (int32_t i = 0; i < argCount; i++) {
6521     argValues[i] = args.GetValue(i);
6522     if (FXJSE_Value_IsArray(argValues[i])) {
6523       FXJSE_HVALUE lengthValue = FXJSE_Value_Create(hruntime);
6524       FXJSE_Value_GetObjectProp(argValues[i], "length", lengthValue);
6525       int32_t length = FXJSE_Value_ToInteger(lengthValue);
6526       iLength = iLength + ((length > 2) ? (length - 2) : 0);
6527       FXJSE_Value_Release(lengthValue);
6528     }
6529     iLength += 1;
6530   }
6531   FXJSE_HVALUE* returnValues = FX_Alloc(FXJSE_HVALUE, iLength);
6532   for (int32_t i = 0; i < (int32_t)iLength; i++) {
6533     returnValues[i] = FXJSE_Value_Create(hruntime);
6534   }
6535   int32_t index = 0;
6536   for (int32_t i = 0; i < argCount; i++) {
6537     if (FXJSE_Value_IsArray(argValues[i])) {
6538       FXJSE_HVALUE lengthValue = FXJSE_Value_Create(hruntime);
6539       FXJSE_Value_GetObjectProp(argValues[i], "length", lengthValue);
6540       int32_t length = FXJSE_Value_ToInteger(lengthValue);
6541       for (int32_t j = 2; j < length; j++) {
6542         FXJSE_Value_GetObjectPropByIdx(argValues[i], j, returnValues[index]);
6543         index++;
6544       }
6545       FXJSE_Value_Release(lengthValue);
6546     }
6547     FXJSE_Value_Set(returnValues[index], argValues[i]);
6548     index++;
6549   }
6550   FXJSE_Value_SetArray(args.GetReturnValue(), iLength, returnValues);
6551   for (int32_t i = 0; i < argCount; i++) {
6552     FXJSE_Value_Release(argValues[i]);
6553   }
6554   FX_Free(argValues);
6555   for (int32_t i = 0; i < (int32_t)iLength; i++) {
6556     FXJSE_Value_Release(returnValues[i]);
6557   }
6558   FX_Free(returnValues);
6559 }
GetSimpleHValue(FXJSE_HOBJECT hThis,CFXJSE_Arguments & args,uint32_t index)6560 FXJSE_HVALUE CXFA_FM2JSContext::GetSimpleHValue(FXJSE_HOBJECT hThis,
6561                                                 CFXJSE_Arguments& args,
6562                                                 uint32_t index) {
6563   CXFA_FM2JSContext* pContext =
6564       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
6565   FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
6566   FXSYS_assert(index < (uint32_t)args.GetLength());
6567   FXJSE_HVALUE argIndex = args.GetValue(index);
6568   if (FXJSE_Value_IsArray(argIndex)) {
6569     FXJSE_HVALUE lengthValue = FXJSE_Value_Create(hruntime);
6570     FXJSE_Value_GetObjectProp(argIndex, "length", lengthValue);
6571     int32_t iLength = FXJSE_Value_ToInteger(lengthValue);
6572     FXJSE_Value_Release(lengthValue);
6573     FXJSE_HVALUE simpleValue = FXJSE_Value_Create(hruntime);
6574     if (iLength > 2) {
6575       FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
6576       FXJSE_HVALUE jsobjectValue = FXJSE_Value_Create(hruntime);
6577       FXJSE_Value_GetObjectPropByIdx(argIndex, 1, propertyValue);
6578       FXJSE_Value_GetObjectPropByIdx(argIndex, 2, jsobjectValue);
6579       if (FXJSE_Value_IsNull(propertyValue)) {
6580         GetObjectDefaultValue(jsobjectValue, simpleValue);
6581       } else {
6582         CFX_ByteString propertyStr;
6583         FXJSE_Value_ToUTF8String(propertyValue, propertyStr);
6584         FXJSE_Value_GetObjectProp(jsobjectValue, propertyStr, simpleValue);
6585       }
6586       FXJSE_Value_Release(propertyValue);
6587       FXJSE_Value_Release(jsobjectValue);
6588     } else {
6589       FXJSE_Value_SetUndefined(simpleValue);
6590     }
6591     FXJSE_Value_Release(argIndex);
6592     return simpleValue;
6593   } else if (FXJSE_Value_IsObject(argIndex)) {
6594     FXJSE_HVALUE defaultValue = FXJSE_Value_Create(hruntime);
6595     GetObjectDefaultValue(argIndex, defaultValue);
6596     FXJSE_Value_Release(argIndex);
6597     return defaultValue;
6598   } else {
6599     return argIndex;
6600   }
6601 }
HValueIsNull(FXJSE_HOBJECT hThis,FXJSE_HVALUE arg)6602 FX_BOOL CXFA_FM2JSContext::HValueIsNull(FXJSE_HOBJECT hThis, FXJSE_HVALUE arg) {
6603   CXFA_FM2JSContext* pContext =
6604       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
6605   FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
6606   FX_BOOL isNull = FALSE;
6607   if (FXJSE_Value_IsNull(arg)) {
6608     isNull = TRUE;
6609   } else if (FXJSE_Value_IsArray(arg)) {
6610     int32_t iLength = hvalue_get_array_length(hThis, arg);
6611     if (iLength > 2) {
6612       FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
6613       FXJSE_HVALUE jsObjectValue = FXJSE_Value_Create(hruntime);
6614       FXJSE_Value_GetObjectPropByIdx(arg, 1, propertyValue);
6615       FXJSE_Value_GetObjectPropByIdx(arg, 2, jsObjectValue);
6616       if (FXJSE_Value_IsNull(propertyValue)) {
6617         FXJSE_HVALUE defaultValue = FXJSE_Value_Create(hruntime);
6618         GetObjectDefaultValue(jsObjectValue, defaultValue);
6619         if (FXJSE_Value_IsNull(defaultValue)) {
6620           isNull = TRUE;
6621         }
6622         FXJSE_Value_Release(defaultValue);
6623       } else {
6624         CFX_ByteString propertyStr;
6625         FXJSE_Value_ToUTF8String(propertyValue, propertyStr);
6626         FXJSE_HVALUE newPropertyValue = FXJSE_Value_Create(hruntime);
6627         FXJSE_Value_GetObjectProp(jsObjectValue, propertyStr, newPropertyValue);
6628         if (FXJSE_Value_IsNull(newPropertyValue)) {
6629           isNull = TRUE;
6630         }
6631         FXJSE_Value_Release(newPropertyValue);
6632       }
6633       FXJSE_Value_Release(propertyValue);
6634       FXJSE_Value_Release(jsObjectValue);
6635     } else {
6636       isNull = TRUE;
6637     }
6638   } else if (FXJSE_Value_IsObject(arg)) {
6639     FXJSE_HVALUE defaultValue = FXJSE_Value_Create(hruntime);
6640     GetObjectDefaultValue(arg, defaultValue);
6641     if (FXJSE_Value_IsNull(defaultValue)) {
6642       isNull = TRUE;
6643     }
6644     FXJSE_Value_Release(defaultValue);
6645   }
6646   return isNull;
6647 }
hvalue_get_array_length(FXJSE_HOBJECT hThis,FXJSE_HVALUE arg)6648 int32_t CXFA_FM2JSContext::hvalue_get_array_length(FXJSE_HOBJECT hThis,
6649                                                    FXJSE_HVALUE arg) {
6650   CXFA_FM2JSContext* pContext =
6651       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
6652   FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
6653   int32_t iLength = 0;
6654   if (FXJSE_Value_IsArray(arg)) {
6655     FXJSE_HVALUE lengthValue = FXJSE_Value_Create(hruntime);
6656     FXJSE_Value_GetObjectProp(arg, "length", lengthValue);
6657     iLength = FXJSE_Value_ToInteger(lengthValue);
6658     FXJSE_Value_Release(lengthValue);
6659   }
6660   return iLength;
6661 }
simpleValueCompare(FXJSE_HOBJECT hThis,FXJSE_HVALUE firstValue,FXJSE_HVALUE secondValue)6662 FX_BOOL CXFA_FM2JSContext::simpleValueCompare(FXJSE_HOBJECT hThis,
6663                                               FXJSE_HVALUE firstValue,
6664                                               FXJSE_HVALUE secondValue) {
6665   FX_BOOL bReturn = FALSE;
6666   if (FXJSE_Value_IsUTF8String(firstValue)) {
6667     CFX_ByteString firstString, secondString;
6668     HValueToUTF8String(firstValue, firstString);
6669     HValueToUTF8String(secondValue, secondString);
6670     bReturn = firstString.Equal(secondString);
6671   } else if (FXJSE_Value_IsNumber(firstValue)) {
6672     FX_FLOAT first = HValueToFloat(hThis, firstValue);
6673     FX_FLOAT second = HValueToFloat(hThis, secondValue);
6674     bReturn = (first == second);
6675   } else if (FXJSE_Value_IsBoolean(firstValue)) {
6676     bReturn = (FXJSE_Value_ToBoolean(firstValue) ==
6677                FXJSE_Value_ToBoolean(secondValue));
6678   } else if (FXJSE_Value_IsNull(firstValue) &&
6679              FXJSE_Value_IsNull(secondValue)) {
6680     bReturn = TRUE;
6681   }
6682   return bReturn;
6683 }
unfoldArgs(FXJSE_HOBJECT hThis,CFXJSE_Arguments & args,FXJSE_HVALUE * & resultValues,int32_t & iCount,int32_t iStart)6684 void CXFA_FM2JSContext::unfoldArgs(FXJSE_HOBJECT hThis,
6685                                    CFXJSE_Arguments& args,
6686                                    FXJSE_HVALUE*& resultValues,
6687                                    int32_t& iCount,
6688                                    int32_t iStart) {
6689   CXFA_FM2JSContext* pContext =
6690       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
6691   FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
6692   iCount = 0;
6693   int32_t argc = args.GetLength();
6694   FXJSE_HVALUE* argsValue = FX_Alloc(FXJSE_HVALUE, argc);
6695   for (int32_t i = iStart; i < argc; i++) {
6696     argsValue[i] = args.GetValue(i);
6697     if (FXJSE_Value_IsArray(argsValue[i])) {
6698       FXJSE_HVALUE lengthValue = FXJSE_Value_Create(hruntime);
6699       FXJSE_Value_GetObjectProp(argsValue[i], "length", lengthValue);
6700       int32_t iLength = FXJSE_Value_ToInteger(lengthValue);
6701       FXJSE_Value_Release(lengthValue);
6702       iCount += ((iLength > 2) ? (iLength - 2) : 0);
6703     } else {
6704       iCount += 1;
6705     }
6706   }
6707   resultValues = FX_Alloc(FXJSE_HVALUE, iCount);
6708   for (int32_t i = 0; i < iCount; i++) {
6709     resultValues[i] = FXJSE_Value_Create(hruntime);
6710   }
6711   int32_t index = 0;
6712   for (int32_t i = iStart; i < argc; i++) {
6713     if (FXJSE_Value_IsArray(argsValue[i])) {
6714       FXJSE_HVALUE lengthValue = FXJSE_Value_Create(hruntime);
6715       FXJSE_Value_GetObjectProp(argsValue[i], "length", lengthValue);
6716       int32_t iLength = FXJSE_Value_ToInteger(lengthValue);
6717       FXJSE_Value_Release(lengthValue);
6718       if (iLength > 2) {
6719         FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
6720         FXJSE_HVALUE jsObjectValue = FXJSE_Value_Create(hruntime);
6721         FXJSE_Value_GetObjectPropByIdx(argsValue[i], 1, propertyValue);
6722         if (FXJSE_Value_IsNull(propertyValue)) {
6723           for (int32_t j = 2; j < iLength; j++) {
6724             FXJSE_Value_GetObjectPropByIdx(argsValue[i], j, jsObjectValue);
6725             GetObjectDefaultValue(jsObjectValue, resultValues[index]);
6726             index++;
6727           }
6728         } else {
6729           CFX_ByteString propertyString;
6730           FXJSE_Value_ToUTF8String(propertyValue, propertyString);
6731           for (int32_t j = 2; j < iLength; j++) {
6732             FXJSE_Value_GetObjectPropByIdx(argsValue[i], j, jsObjectValue);
6733             FXJSE_Value_GetObjectProp(jsObjectValue, propertyString,
6734                                       resultValues[index]);
6735             index++;
6736           }
6737         }
6738         FXJSE_Value_Release(propertyValue);
6739         FXJSE_Value_Release(jsObjectValue);
6740       }
6741     } else if (FXJSE_Value_IsObject(argsValue[i])) {
6742       GetObjectDefaultValue(argsValue[i], resultValues[index]);
6743       index++;
6744     } else {
6745       FXJSE_Value_Set(resultValues[index], argsValue[i]);
6746       index++;
6747     }
6748   }
6749   for (int32_t i = iStart; i < argc; i++) {
6750     FXJSE_Value_Release(argsValue[i]);
6751   }
6752   FX_Free(argsValue);
6753 }
GetObjectDefaultValue(FXJSE_HVALUE hObjectValue,FXJSE_HVALUE hDefaultValue)6754 void CXFA_FM2JSContext::GetObjectDefaultValue(FXJSE_HVALUE hObjectValue,
6755                                               FXJSE_HVALUE hDefaultValue) {
6756   CXFA_Object* pNode = (CXFA_Object*)FXJSE_Value_ToObject(hObjectValue, NULL);
6757   if (pNode && pNode->IsNode()) {
6758     ((CXFA_Node*)pNode)
6759         ->Script_Som_DefaultValue(hDefaultValue, FALSE, (XFA_ATTRIBUTE)-1);
6760   } else {
6761     FXJSE_Value_SetNull(hDefaultValue);
6762   }
6763 }
SetObjectDefaultValue(FXJSE_HVALUE hObjectValue,FXJSE_HVALUE hNewValue)6764 FX_BOOL CXFA_FM2JSContext::SetObjectDefaultValue(FXJSE_HVALUE hObjectValue,
6765                                                  FXJSE_HVALUE hNewValue) {
6766   FX_BOOL bSuccess = FALSE;
6767   CXFA_Object* pNode = (CXFA_Object*)FXJSE_Value_ToObject(hObjectValue, NULL);
6768   if (pNode && pNode->IsNode()) {
6769     ((CXFA_Node*)pNode)
6770         ->Script_Som_DefaultValue(hNewValue, TRUE, (XFA_ATTRIBUTE)-1);
6771     bSuccess = TRUE;
6772   }
6773   return bSuccess;
6774 }
GenerateSomExpression(const CFX_ByteStringC & szName,int32_t iIndexFlags,int32_t iIndexValue,FX_BOOL bIsStar,CFX_ByteString & szSomExp)6775 void CXFA_FM2JSContext::GenerateSomExpression(const CFX_ByteStringC& szName,
6776                                               int32_t iIndexFlags,
6777                                               int32_t iIndexValue,
6778                                               FX_BOOL bIsStar,
6779                                               CFX_ByteString& szSomExp) {
6780   if (bIsStar) {
6781     szSomExp = szName + "[*]";
6782     return;
6783   }
6784   if (iIndexFlags == 0) {
6785     szSomExp = szName;
6786     return;
6787   }
6788   if (iIndexFlags == 1 || iIndexValue == 0) {
6789     szSomExp = szName + "[" +
6790                CFX_ByteString::FormatInteger(iIndexValue, FXFORMAT_SIGNED) +
6791                "]";
6792   } else if (iIndexFlags == 2) {
6793     szSomExp = (iIndexValue < 0) ? (szName + "[-") : (szName + "[+");
6794     iIndexValue = (iIndexValue < 0) ? (0 - iIndexValue) : iIndexValue;
6795     szSomExp += CFX_ByteString::FormatInteger(iIndexValue);
6796     szSomExp += "]";
6797   } else {
6798     szSomExp = (iIndexValue < 0) ? (szName + "[") : (szName + "[-");
6799     iIndexValue = (iIndexValue < 0) ? (0 - iIndexValue) : iIndexValue;
6800     szSomExp += CFX_ByteString::FormatInteger(iIndexValue);
6801     szSomExp += "]";
6802   }
6803 }
GetObjectByName(FXJSE_HOBJECT hThis,FXJSE_HVALUE accessorValue,const CFX_ByteStringC & szAccessorName)6804 FX_BOOL CXFA_FM2JSContext::GetObjectByName(
6805     FXJSE_HOBJECT hThis,
6806     FXJSE_HVALUE accessorValue,
6807     const CFX_ByteStringC& szAccessorName) {
6808   FX_BOOL bFlags = FALSE;
6809   CXFA_FM2JSContext* pContext =
6810       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
6811   CXFA_Document* pDoc = pContext->GetDocument();
6812   if (!pDoc) {
6813     return bFlags;
6814   }
6815   IXFA_ScriptContext* pScriptContext = pDoc->GetScriptContext();
6816   XFA_RESOLVENODE_RS resoveNodeRS;
6817   FX_DWORD dwFlags = XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Properties |
6818                      XFA_RESOLVENODE_Siblings | XFA_RESOLVENODE_Parent;
6819   int32_t iRet = pScriptContext->ResolveObjects(
6820       pScriptContext->GetThisObject(),
6821       CFX_WideString::FromUTF8(szAccessorName.GetCStr(),
6822                                szAccessorName.GetLength()),
6823       resoveNodeRS, dwFlags);
6824   if (iRet >= 1 && resoveNodeRS.dwFlags == XFA_RESOVENODE_RSTYPE_Nodes) {
6825     FXJSE_Value_Set(accessorValue, pScriptContext->GetJSValueFromMap(
6826                                        resoveNodeRS.nodes.GetAt(0)));
6827     bFlags = TRUE;
6828   }
6829   return bFlags;
6830 }
ResolveObjects(FXJSE_HOBJECT hThis,FXJSE_HVALUE hRefValue,const CFX_ByteStringC & bsSomExp,XFA_RESOLVENODE_RS & resoveNodeRS,FX_BOOL bdotAccessor,FX_BOOL bHasNoResolveName)6831 int32_t CXFA_FM2JSContext::ResolveObjects(FXJSE_HOBJECT hThis,
6832                                           FXJSE_HVALUE hRefValue,
6833                                           const CFX_ByteStringC& bsSomExp,
6834                                           XFA_RESOLVENODE_RS& resoveNodeRS,
6835                                           FX_BOOL bdotAccessor,
6836                                           FX_BOOL bHasNoResolveName) {
6837   CFX_WideString wsSomExpression =
6838       CFX_WideString::FromUTF8(bsSomExp.GetCStr(), bsSomExp.GetLength());
6839   int32_t iRet = -1;
6840   CXFA_FM2JSContext* pContext =
6841       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
6842   CXFA_Document* pDoc = pContext->GetDocument();
6843   if (!pDoc) {
6844     return iRet;
6845   }
6846   IXFA_ScriptContext* pScriptContext = pDoc->GetScriptContext();
6847   CXFA_Object* pNode = NULL;
6848   FX_DWORD dFlags = 0UL;
6849   if (bdotAccessor) {
6850     if (FXJSE_Value_IsNull(hRefValue)) {
6851       pNode = pScriptContext->GetThisObject();
6852       dFlags = XFA_RESOLVENODE_Siblings | XFA_RESOLVENODE_Parent;
6853     } else {
6854       pNode = (CXFA_Object*)FXJSE_Value_ToObject(hRefValue, NULL);
6855       FXSYS_assert(pNode);
6856       if (bHasNoResolveName) {
6857         CFX_WideString wsName;
6858         if (pNode->IsNode()) {
6859           CXFA_Node* pXFANode = (CXFA_Node*)pNode;
6860           pXFANode->GetAttribute(XFA_ATTRIBUTE_Name, wsName, FALSE);
6861         }
6862         if (wsName.IsEmpty()) {
6863           CFX_WideStringC className;
6864           pNode->GetClassName(className);
6865           wsName = FX_WSTRC(L"#") + className;
6866         }
6867         wsSomExpression = wsName + wsSomExpression;
6868         dFlags = XFA_RESOLVENODE_Siblings;
6869       } else {
6870         dFlags = (bsSomExp == "*")
6871                      ? (XFA_RESOLVENODE_Children)
6872                      : (XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Attributes |
6873                         XFA_RESOLVENODE_Properties);
6874       }
6875     }
6876   } else {
6877     pNode = (CXFA_Object*)FXJSE_Value_ToObject(hRefValue, NULL);
6878     dFlags = XFA_RESOLVENODE_AnyChild;
6879   }
6880   iRet = pScriptContext->ResolveObjects(pNode, wsSomExpression, resoveNodeRS,
6881                                         dFlags);
6882   return iRet;
6883 }
ParseResolveResult(FXJSE_HOBJECT hThis,const XFA_RESOLVENODE_RS & resoveNodeRS,FXJSE_HVALUE hParentValue,FXJSE_HVALUE * & resultValues,int32_t & iSize,FX_BOOL & bAttribute)6884 void CXFA_FM2JSContext::ParseResolveResult(
6885     FXJSE_HOBJECT hThis,
6886     const XFA_RESOLVENODE_RS& resoveNodeRS,
6887     FXJSE_HVALUE hParentValue,
6888     FXJSE_HVALUE*& resultValues,
6889     int32_t& iSize,
6890     FX_BOOL& bAttribute) {
6891   CXFA_FM2JSContext* pContext =
6892       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
6893   FXJSE_HRUNTIME hRuntime = pContext->GetScriptRuntime();
6894   iSize = 0;
6895   resultValues = NULL;
6896   if (resoveNodeRS.dwFlags == XFA_RESOVENODE_RSTYPE_Nodes) {
6897     bAttribute = FALSE;
6898     iSize = resoveNodeRS.nodes.GetSize();
6899     resultValues = FX_Alloc(FXJSE_HVALUE, iSize);
6900     for (int32_t i = 0; i < iSize; i++) {
6901       resultValues[i] = FXJSE_Value_Create(hRuntime);
6902       FXJSE_Value_Set(
6903           resultValues[i],
6904           pContext->GetDocument()->GetScriptContext()->GetJSValueFromMap(
6905               resoveNodeRS.nodes.GetAt(i)));
6906     }
6907   } else {
6908     CXFA_HVALUEArray objectProperties(hRuntime);
6909     int32_t iRet = resoveNodeRS.GetAttributeResult(objectProperties);
6910     bAttribute = (iRet == 0);
6911     if (bAttribute) {
6912       if (FXJSE_Value_IsObject(hParentValue)) {
6913         iSize = 1;
6914         resultValues = FX_Alloc(FXJSE_HVALUE, 1);
6915         resultValues[0] = FXJSE_Value_Create(hRuntime);
6916         FXJSE_Value_Set(resultValues[0], hParentValue);
6917       }
6918     } else {
6919       iSize = iRet;
6920       resultValues = FX_Alloc(FXJSE_HVALUE, iSize);
6921       for (int32_t i = 0; i < iSize; i++) {
6922         resultValues[i] = FXJSE_Value_Create(hRuntime);
6923         FXJSE_Value_Set(resultValues[i], objectProperties[i]);
6924       }
6925     }
6926   }
6927 }
HValueToInteger(FXJSE_HOBJECT hThis,FXJSE_HVALUE hValue)6928 int32_t CXFA_FM2JSContext::HValueToInteger(FXJSE_HOBJECT hThis,
6929                                            FXJSE_HVALUE hValue) {
6930   CXFA_FM2JSContext* pContext =
6931       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
6932   FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
6933   int32_t iValue = 0;
6934   if (FXJSE_Value_IsArray(hValue)) {
6935     FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
6936     FXJSE_HVALUE jsobjectValue = FXJSE_Value_Create(hruntime);
6937     FXJSE_HVALUE newProperty = FXJSE_Value_Create(hruntime);
6938     FXJSE_Value_GetObjectPropByIdx(hValue, 1, propertyValue);
6939     FXJSE_Value_GetObjectPropByIdx(hValue, 2, jsobjectValue);
6940     if (FXJSE_Value_IsNull(propertyValue)) {
6941       GetObjectDefaultValue(jsobjectValue, newProperty);
6942     } else {
6943       CFX_ByteString propertyStr;
6944       FXJSE_Value_ToUTF8String(propertyValue, propertyStr);
6945       FXJSE_Value_GetObjectProp(jsobjectValue, propertyStr, newProperty);
6946     }
6947     iValue = HValueToInteger(hThis, newProperty);
6948     FXJSE_Value_Release(newProperty);
6949     FXJSE_Value_Release(jsobjectValue);
6950     FXJSE_Value_Release(propertyValue);
6951     return iValue;
6952   } else if (FXJSE_Value_IsObject(hValue)) {
6953     FXJSE_HVALUE newProperty = FXJSE_Value_Create(hruntime);
6954     GetObjectDefaultValue(hValue, newProperty);
6955     iValue = HValueToInteger(hThis, newProperty);
6956     FXJSE_Value_Release(newProperty);
6957     return iValue;
6958   } else if (FXJSE_Value_IsUTF8String(hValue)) {
6959     CFX_ByteString szValue;
6960     FXJSE_Value_ToUTF8String(hValue, szValue);
6961     iValue = FXSYS_atoi(szValue);
6962   } else {
6963     iValue = FXJSE_Value_ToInteger(hValue);
6964   }
6965   return iValue;
6966 }
StringToDouble(const CFX_ByteStringC & szStringVal)6967 FX_DOUBLE CXFA_FM2JSContext::StringToDouble(
6968     const CFX_ByteStringC& szStringVal) {
6969   return XFA_ByteStringToDouble(szStringVal);
6970 }
HValueToFloat(FXJSE_HOBJECT hThis,FXJSE_HVALUE arg)6971 FX_FLOAT CXFA_FM2JSContext::HValueToFloat(FXJSE_HOBJECT hThis,
6972                                           FXJSE_HVALUE arg) {
6973   CXFA_FM2JSContext* pContext =
6974       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
6975   FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
6976   FX_FLOAT fRet = 0.0f;
6977   if (FXJSE_Value_IsArray(arg)) {
6978     FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
6979     FXJSE_HVALUE jsobjectValue = FXJSE_Value_Create(hruntime);
6980     FXJSE_HVALUE newProperty = FXJSE_Value_Create(hruntime);
6981     FXJSE_Value_GetObjectPropByIdx(arg, 1, propertyValue);
6982     FXJSE_Value_GetObjectPropByIdx(arg, 2, jsobjectValue);
6983     if (FXJSE_Value_IsNull(propertyValue)) {
6984       GetObjectDefaultValue(jsobjectValue, newProperty);
6985     } else {
6986       CFX_ByteString propertyStr;
6987       FXJSE_Value_ToUTF8String(propertyValue, propertyStr);
6988       FXJSE_Value_GetObjectProp(jsobjectValue, propertyStr, newProperty);
6989     }
6990     fRet = HValueToFloat(hThis, newProperty);
6991     FXJSE_Value_Release(newProperty);
6992     FXJSE_Value_Release(jsobjectValue);
6993     FXJSE_Value_Release(propertyValue);
6994   } else if (FXJSE_Value_IsObject(arg)) {
6995     FXJSE_HVALUE newProperty = FXJSE_Value_Create(hruntime);
6996     GetObjectDefaultValue(arg, newProperty);
6997     fRet = HValueToFloat(hThis, newProperty);
6998     FXJSE_Value_Release(newProperty);
6999   } else if (FXJSE_Value_IsUTF8String(arg)) {
7000     CFX_ByteString bsOutput;
7001     FXJSE_Value_ToUTF8String(arg, bsOutput);
7002     fRet = (FX_FLOAT)StringToDouble(bsOutput);
7003   } else if (FXJSE_Value_IsUndefined(arg)) {
7004     fRet = 0;
7005   } else {
7006     fRet = FXJSE_Value_ToFloat(arg);
7007   }
7008   return fRet;
7009 }
HValueToDouble(FXJSE_HOBJECT hThis,FXJSE_HVALUE arg)7010 FX_DOUBLE CXFA_FM2JSContext::HValueToDouble(FXJSE_HOBJECT hThis,
7011                                             FXJSE_HVALUE arg) {
7012   CXFA_FM2JSContext* pContext =
7013       (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
7014   FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
7015   FX_DOUBLE dRet = 0;
7016   if (FXJSE_Value_IsArray(arg)) {
7017     FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
7018     FXJSE_HVALUE jsobjectValue = FXJSE_Value_Create(hruntime);
7019     FXJSE_HVALUE newProperty = FXJSE_Value_Create(hruntime);
7020     FXJSE_Value_GetObjectPropByIdx(arg, 1, propertyValue);
7021     FXJSE_Value_GetObjectPropByIdx(arg, 2, jsobjectValue);
7022     if (FXJSE_Value_IsNull(propertyValue)) {
7023       GetObjectDefaultValue(jsobjectValue, newProperty);
7024     } else {
7025       CFX_ByteString propertyStr;
7026       FXJSE_Value_ToUTF8String(propertyValue, propertyStr);
7027       FXJSE_Value_GetObjectProp(jsobjectValue, propertyStr, newProperty);
7028     }
7029     dRet = HValueToDouble(hThis, newProperty);
7030     FXJSE_Value_Release(newProperty);
7031     FXJSE_Value_Release(jsobjectValue);
7032     FXJSE_Value_Release(propertyValue);
7033   } else if (FXJSE_Value_IsObject(arg)) {
7034     FXJSE_HVALUE newProperty = FXJSE_Value_Create(hruntime);
7035     GetObjectDefaultValue(arg, newProperty);
7036     dRet = HValueToDouble(hThis, newProperty);
7037     FXJSE_Value_Release(newProperty);
7038   } else if (FXJSE_Value_IsUTF8String(arg)) {
7039     CFX_ByteString bsOutput;
7040     FXJSE_Value_ToUTF8String(arg, bsOutput);
7041     dRet = StringToDouble(bsOutput);
7042   } else if (FXJSE_Value_IsUndefined(arg)) {
7043     dRet = 0;
7044   } else {
7045     dRet = FXJSE_Value_ToDouble(arg);
7046   }
7047   return dRet;
7048 }
HValueToUTF8String(FXJSE_HVALUE arg,CFX_ByteString & szOutputString)7049 void CXFA_FM2JSContext::HValueToUTF8String(FXJSE_HVALUE arg,
7050                                            CFX_ByteString& szOutputString) {
7051   if (FXJSE_Value_IsNull(arg) || FXJSE_Value_IsUndefined(arg)) {
7052     szOutputString = "";
7053   } else if (FXJSE_Value_IsBoolean(arg)) {
7054     szOutputString = FXJSE_Value_ToBoolean(arg) ? "1" : "0";
7055   } else {
7056     szOutputString = "";
7057     FXJSE_Value_ToUTF8String(arg, szOutputString);
7058   }
7059 }
7060 static FXJSE_FUNCTION formcalc_fm2js_functions[] = {
7061     {"Abs", CXFA_FM2JSContext::Abs},
7062     {"Avg", CXFA_FM2JSContext::Avg},
7063     {"Ceil", CXFA_FM2JSContext::Ceil},
7064     {"Count", CXFA_FM2JSContext::Count},
7065     {"Floor", CXFA_FM2JSContext::Floor},
7066     {"Max", CXFA_FM2JSContext::Max},
7067     {"Min", CXFA_FM2JSContext::Min},
7068     {"Mod", CXFA_FM2JSContext::Mod},
7069     {"Round", CXFA_FM2JSContext::Round},
7070     {"Sum", CXFA_FM2JSContext::Sum},
7071     {"Date", CXFA_FM2JSContext::Date},
7072     {"Date2Num", CXFA_FM2JSContext::Date2Num},
7073     {"DateFmt", CXFA_FM2JSContext::DateFmt},
7074     {"IsoDate2Num", CXFA_FM2JSContext::IsoDate2Num},
7075     {"IsoTime2Num", CXFA_FM2JSContext::IsoTime2Num},
7076     {"LocalDateFmt", CXFA_FM2JSContext::LocalDateFmt},
7077     {"LocalTimeFmt", CXFA_FM2JSContext::LocalTimeFmt},
7078     {"Num2Date", CXFA_FM2JSContext::Num2Date},
7079     {"Num2GMTime", CXFA_FM2JSContext::Num2GMTime},
7080     {"Num2Time", CXFA_FM2JSContext::Num2Time},
7081     {"Time", CXFA_FM2JSContext::Time},
7082     {"Time2Num", CXFA_FM2JSContext::Time2Num},
7083     {"TimeFmt", CXFA_FM2JSContext::TimeFmt},
7084     {"Apr", CXFA_FM2JSContext::Apr},
7085     {"Cterm", CXFA_FM2JSContext::CTerm},
7086     {"FV", CXFA_FM2JSContext::FV},
7087     {"Ipmt", CXFA_FM2JSContext::IPmt},
7088     {"NPV", CXFA_FM2JSContext::NPV},
7089     {"Pmt", CXFA_FM2JSContext::Pmt},
7090     {"PPmt", CXFA_FM2JSContext::PPmt},
7091     {"PV", CXFA_FM2JSContext::PV},
7092     {"Rate", CXFA_FM2JSContext::Rate},
7093     {"Term", CXFA_FM2JSContext::Term},
7094     {"Choose", CXFA_FM2JSContext::Choose},
7095     {"Exists", CXFA_FM2JSContext::Exists},
7096     {"HasValue", CXFA_FM2JSContext::HasValue},
7097     {"Oneof", CXFA_FM2JSContext::Oneof},
7098     {"Within", CXFA_FM2JSContext::Within},
7099     {"If", CXFA_FM2JSContext::If},
7100     {"Eval", CXFA_FM2JSContext::Eval},
7101     {"Translate", CXFA_FM2JSContext::eval_translation},
7102     {"Ref", CXFA_FM2JSContext::Ref},
7103     {"UnitType", CXFA_FM2JSContext::UnitType},
7104     {"UnitValue", CXFA_FM2JSContext::UnitValue},
7105     {"At", CXFA_FM2JSContext::At},
7106     {"Concat", CXFA_FM2JSContext::Concat},
7107     {"Decode", CXFA_FM2JSContext::Decode},
7108     {"Encode", CXFA_FM2JSContext::Encode},
7109     {"Format", CXFA_FM2JSContext::Format},
7110     {"Left", CXFA_FM2JSContext::Left},
7111     {"Len", CXFA_FM2JSContext::Len},
7112     {"Lower", CXFA_FM2JSContext::Lower},
7113     {"Ltrim", CXFA_FM2JSContext::Ltrim},
7114     {"Parse", CXFA_FM2JSContext::Parse},
7115     {"Replace", CXFA_FM2JSContext::Replace},
7116     {"Right", CXFA_FM2JSContext::Right},
7117     {"Rtrim", CXFA_FM2JSContext::Rtrim},
7118     {"Space", CXFA_FM2JSContext::Space},
7119     {"Str", CXFA_FM2JSContext::Str},
7120     {"Stuff", CXFA_FM2JSContext::Stuff},
7121     {"Substr", CXFA_FM2JSContext::Substr},
7122     {"Uuid", CXFA_FM2JSContext::Uuid},
7123     {"Upper", CXFA_FM2JSContext::Upper},
7124     {"WordNum", CXFA_FM2JSContext::WordNum},
7125     {"Get", CXFA_FM2JSContext::Get},
7126     {"Post", CXFA_FM2JSContext::Post},
7127     {"Put", CXFA_FM2JSContext::Put},
7128     {"positive_operator", CXFA_FM2JSContext::positive_operator},
7129     {"negative_operator", CXFA_FM2JSContext::negative_operator},
7130     {"logical_or_operator", CXFA_FM2JSContext::logical_or_operator},
7131     {"logical_and_operator", CXFA_FM2JSContext::logical_and_operator},
7132     {"logical_not_operator", CXFA_FM2JSContext::logical_not_operator},
7133     {"equality_operator", CXFA_FM2JSContext::equality_operator},
7134     {"notequality_operator", CXFA_FM2JSContext::notequality_operator},
7135     {"less_operator", CXFA_FM2JSContext::less_operator},
7136     {"lessequal_operator", CXFA_FM2JSContext::lessequal_operator},
7137     {"greater_operator", CXFA_FM2JSContext::greater_operator},
7138     {"greaterequal_operator", CXFA_FM2JSContext::greaterequal_operator},
7139     {"plus_operator", CXFA_FM2JSContext::plus_operator},
7140     {"minus_operator", CXFA_FM2JSContext::minus_operator},
7141     {"multiple_operator", CXFA_FM2JSContext::multiple_operator},
7142     {"divide_operator", CXFA_FM2JSContext::divide_operator},
7143     {"assign_value_operator", CXFA_FM2JSContext::assign_value_operator},
7144     {"dot_accessor", CXFA_FM2JSContext::dot_accessor},
7145     {"dotdot_accessor", CXFA_FM2JSContext::dotdot_accessor},
7146     {"concat_fm_object", CXFA_FM2JSContext::concat_fm_object},
7147     {"is_fm_object", CXFA_FM2JSContext::is_fm_object},
7148     {"is_fm_array", CXFA_FM2JSContext::is_fm_array},
7149     {"get_fm_value", CXFA_FM2JSContext::get_fm_value},
7150     {"get_fm_jsobj", CXFA_FM2JSContext::get_fm_jsobj},
7151     {"fm_var_filter", CXFA_FM2JSContext::fm_var_filter},
7152 };
CXFA_FM2JSContext()7153 CXFA_FM2JSContext::CXFA_FM2JSContext()
7154     : m_hFMClass(nullptr), m_pDocument(nullptr) {
7155   FX_memset(&m_fmClass, 0, sizeof(FXJSE_CLASS));
7156 }
~CXFA_FM2JSContext()7157 CXFA_FM2JSContext::~CXFA_FM2JSContext() {
7158   m_pDocument = NULL;
7159   if (m_hValue) {
7160     FXJSE_Value_Release(m_hValue);
7161     m_hValue = NULL;
7162   }
7163   m_hScriptRuntime = NULL;
7164 }
Create()7165 CXFA_FM2JSContext* CXFA_FM2JSContext::Create() {
7166   return new CXFA_FM2JSContext;
7167 }
Initialize(FXJSE_HRUNTIME hScriptRuntime,FXJSE_HCONTEXT hScriptContext,CXFA_Document * pDoc)7168 void CXFA_FM2JSContext::Initialize(FXJSE_HRUNTIME hScriptRuntime,
7169                                    FXJSE_HCONTEXT hScriptContext,
7170                                    CXFA_Document* pDoc) {
7171   m_pDocument = pDoc;
7172   m_hScriptRuntime = hScriptRuntime;
7173   m_fmClass.name = "XFA_FM2JS_FormCalcClass";
7174   m_fmClass.constructor = NULL;
7175   m_fmClass.properties = NULL;
7176   m_fmClass.methods = formcalc_fm2js_functions;
7177   m_fmClass.propNum = 0;
7178   m_fmClass.methNum =
7179       sizeof(formcalc_fm2js_functions) / sizeof(formcalc_fm2js_functions[0]);
7180   m_hFMClass = FXJSE_DefineClass(hScriptContext, &m_fmClass);
7181   m_hValue = FXJSE_Value_Create(hScriptRuntime);
7182   FXJSE_Value_SetNull(m_hValue);
7183   FXJSE_Value_SetObject(m_hValue, this, m_hFMClass);
7184 }
GlobalPropertyGetter(FXJSE_HVALUE hValue)7185 void CXFA_FM2JSContext::GlobalPropertyGetter(FXJSE_HVALUE hValue) {
7186   FXJSE_Value_Set(hValue, m_hValue);
7187 }
Release()7188 void CXFA_FM2JSContext::Release() {
7189   delete this;
7190 }
ThrowScriptErrorMessage(int32_t iStringID,...)7191 void CXFA_FM2JSContext::ThrowScriptErrorMessage(int32_t iStringID, ...) {
7192   IXFA_AppProvider* pAppProvider = m_pDocument->GetNotify()->GetAppProvider();
7193   FXSYS_assert(pAppProvider);
7194   CFX_WideString wsFormat;
7195   pAppProvider->LoadString(iStringID, wsFormat);
7196   CFX_WideString wsMessage;
7197   va_list arg_ptr;
7198   va_start(arg_ptr, iStringID);
7199   wsMessage.FormatV((const FX_WCHAR*)wsFormat, arg_ptr);
7200   va_end(arg_ptr);
7201   FXJSE_ThrowMessage("", FX_UTF8Encode(wsMessage, wsMessage.GetLength()));
7202 }
7203