OLD | NEW |
1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
6 | 6 |
7 #include "PublicMethods.h" | 7 #include "PublicMethods.h" |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 | 10 |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
187 while (p > pStr && *(p - 1) == L' ') | 187 while (p > pStr && *(p - 1) == L' ') |
188 p--; | 188 p--; |
189 | 189 |
190 return CFX_ByteString(pStr, p - pStr); | 190 return CFX_ByteString(pStr, p - pStr); |
191 } | 191 } |
192 | 192 |
193 CFX_ByteString CJS_PublicMethods::StrTrim(const FX_CHAR* pStr) { | 193 CFX_ByteString CJS_PublicMethods::StrTrim(const FX_CHAR* pStr) { |
194 return StrRTrim(StrLTrim(pStr)); | 194 return StrRTrim(StrLTrim(pStr)); |
195 } | 195 } |
196 | 196 |
197 double CJS_PublicMethods::ParseNumber(const FX_WCHAR* swSource, | |
198 FX_BOOL& bAllDigits, | |
199 FX_BOOL& bDot, | |
200 FX_BOOL& bSign, | |
201 FX_BOOL& bKXJS) { | |
202 bDot = FALSE; | |
203 bSign = FALSE; | |
204 bKXJS = FALSE; | |
205 | |
206 FX_BOOL bDigitExist = FALSE; | |
207 | |
208 const FX_WCHAR* p = swSource; | |
209 wchar_t c; | |
210 | |
211 const FX_WCHAR* pStart = NULL; | |
212 const FX_WCHAR* pEnd = NULL; | |
213 | |
214 while ((c = *p)) { | |
215 if (!pStart && c != L' ') { | |
216 pStart = p; | |
217 } | |
218 | |
219 pEnd = p; | |
220 p++; | |
221 } | |
222 | |
223 if (!pStart) { | |
224 bAllDigits = FALSE; | |
225 return 0; | |
226 } | |
227 | |
228 while (pEnd != pStart) { | |
229 if (*pEnd == L' ') | |
230 pEnd--; | |
231 else | |
232 break; | |
233 } | |
234 | |
235 double dRet = 0; | |
236 p = pStart; | |
237 bAllDigits = TRUE; | |
238 CFX_WideString swDigits; | |
239 | |
240 while (p <= pEnd) { | |
241 c = *p; | |
242 | |
243 if (FXSYS_iswdigit(c)) { | |
244 swDigits += c; | |
245 bDigitExist = TRUE; | |
246 } else { | |
247 switch (c) { | |
248 case L' ': | |
249 bAllDigits = FALSE; | |
250 break; | |
251 case L'.': | |
252 case L',': | |
253 if (!bDot) { | |
254 if (bDigitExist) { | |
255 swDigits += L'.'; | |
256 } else { | |
257 swDigits += L'0'; | |
258 swDigits += L'.'; | |
259 bDigitExist = TRUE; | |
260 } | |
261 | |
262 bDot = TRUE; | |
263 break; | |
264 } | |
265 case 'e': | |
266 case 'E': | |
267 if (!bKXJS) { | |
268 p++; | |
269 c = *p; | |
270 if (c == '+' || c == '-') { | |
271 bKXJS = TRUE; | |
272 swDigits += 'e'; | |
273 swDigits += c; | |
274 } | |
275 break; | |
276 } | |
277 case L'-': | |
278 if (!bDigitExist && !bSign) { | |
279 swDigits += c; | |
280 bSign = TRUE; | |
281 break; | |
282 } | |
283 default: | |
284 bAllDigits = FALSE; | |
285 | |
286 if (p != pStart && !bDot && bDigitExist) { | |
287 swDigits += L'.'; | |
288 bDot = TRUE; | |
289 } else { | |
290 bDot = FALSE; | |
291 bDigitExist = FALSE; | |
292 swDigits = L""; | |
293 } | |
294 break; | |
295 } | |
296 } | |
297 | |
298 p++; | |
299 } | |
300 | |
301 if (swDigits.GetLength() > 0 && swDigits.GetLength() < 17) { | |
302 CFX_ByteString sDigits = swDigits.UTF8Encode(); | |
303 | |
304 if (bKXJS) { | |
305 dRet = atof(sDigits); | |
306 } else { | |
307 if (bDot) { | |
308 char* pStopString; | |
309 dRet = ::strtod(sDigits, &pStopString); | |
310 } else { | |
311 dRet = atol(sDigits); | |
312 } | |
313 } | |
314 } | |
315 | |
316 return dRet; | |
317 } | |
318 | |
319 double CJS_PublicMethods::ParseStringToNumber(const FX_WCHAR* swSource) { | |
320 FX_BOOL bAllDigits = FALSE; | |
321 FX_BOOL bDot = FALSE; | |
322 FX_BOOL bSign = FALSE; | |
323 FX_BOOL bKXJS = FALSE; | |
324 | |
325 return ParseNumber(swSource, bAllDigits, bDot, bSign, bKXJS); | |
326 } | |
327 | |
328 FX_BOOL CJS_PublicMethods::ConvertStringToNumber(const FX_WCHAR* swSource, | |
329 double& dRet, | |
330 FX_BOOL& bDot) { | |
331 FX_BOOL bAllDigits = FALSE; | |
332 FX_BOOL bSign = FALSE; | |
333 FX_BOOL bKXJS = FALSE; | |
334 | |
335 dRet = ParseNumber(swSource, bAllDigits, bDot, bSign, bKXJS); | |
336 | |
337 return bAllDigits; | |
338 } | |
339 | |
340 CJS_Array CJS_PublicMethods::AF_MakeArrayFromList(CJS_Runtime* pRuntime, | 197 CJS_Array CJS_PublicMethods::AF_MakeArrayFromList(CJS_Runtime* pRuntime, |
341 CJS_Value val) { | 198 CJS_Value val) { |
342 CJS_Array StrArray(pRuntime); | 199 CJS_Array StrArray(pRuntime); |
343 if (val.IsArrayObject()) { | 200 if (val.IsArrayObject()) { |
344 val.ConvertToArray(StrArray); | 201 val.ConvertToArray(StrArray); |
345 return StrArray; | 202 return StrArray; |
346 } | 203 } |
347 CFX_WideString wsStr = val.ToCFXWideString(); | 204 CFX_WideString wsStr = val.ToCFXWideString(); |
348 CFX_ByteString t = CFX_ByteString::FromUnicode(wsStr); | 205 CFX_ByteString t = CFX_ByteString::FromUnicode(wsStr); |
349 const char* p = (const char*)t; | 206 const char* p = (const char*)t; |
(...skipping 987 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1337 sFormat.c_str()); | 1194 sFormat.c_str()); |
1338 Alert(pContext, swMsg.c_str()); | 1195 Alert(pContext, swMsg.c_str()); |
1339 return FALSE; | 1196 return FALSE; |
1340 } | 1197 } |
1341 | 1198 |
1342 val = MakeFormatDate(dDate, sFormat); | 1199 val = MakeFormatDate(dDate, sFormat); |
1343 return TRUE; | 1200 return TRUE; |
1344 } | 1201 } |
1345 | 1202 |
1346 double CJS_PublicMethods::MakeInterDate(CFX_WideString strValue) { | 1203 double CJS_PublicMethods::MakeInterDate(CFX_WideString strValue) { |
1347 int nHour; | |
1348 int nMin; | |
1349 int nSec; | |
1350 int nYear; | |
1351 int nMonth; | |
1352 int nDay; | |
1353 | |
1354 CFX_WideStringArray wsArray; | 1204 CFX_WideStringArray wsArray; |
1355 CFX_WideString sMonth = L""; | |
1356 CFX_WideString sTemp = L""; | 1205 CFX_WideString sTemp = L""; |
1357 int nSize = strValue.GetLength(); | 1206 for (int i = 0; i < strValue.GetLength(); ++i) { |
1358 | |
1359 for (int i = 0; i < nSize; i++) { | |
1360 FX_WCHAR c = strValue.GetAt(i); | 1207 FX_WCHAR c = strValue.GetAt(i); |
1361 if (c == L' ' || c == L':') { | 1208 if (c == L' ' || c == L':') { |
1362 wsArray.Add(sTemp); | 1209 wsArray.Add(sTemp); |
1363 sTemp = L""; | 1210 sTemp = L""; |
1364 continue; | 1211 continue; |
1365 } | 1212 } |
1366 | |
1367 sTemp += c; | 1213 sTemp += c; |
1368 } | 1214 } |
1369 | |
1370 wsArray.Add(sTemp); | 1215 wsArray.Add(sTemp); |
1371 if (wsArray.GetSize() != 8) | 1216 if (wsArray.GetSize() != 8) |
1372 return 0; | 1217 return 0; |
1373 | 1218 |
| 1219 int nMonth = 1; |
1374 sTemp = wsArray[1]; | 1220 sTemp = wsArray[1]; |
1375 if (sTemp.Compare(L"Jan") == 0) | 1221 if (sTemp.Compare(L"Jan") == 0) |
1376 nMonth = 1; | 1222 nMonth = 1; |
1377 if (sTemp.Compare(L"Feb") == 0) | 1223 else if (sTemp.Compare(L"Feb") == 0) |
1378 nMonth = 2; | 1224 nMonth = 2; |
1379 if (sTemp.Compare(L"Mar") == 0) | 1225 else if (sTemp.Compare(L"Mar") == 0) |
1380 nMonth = 3; | 1226 nMonth = 3; |
1381 if (sTemp.Compare(L"Apr") == 0) | 1227 else if (sTemp.Compare(L"Apr") == 0) |
1382 nMonth = 4; | 1228 nMonth = 4; |
1383 if (sTemp.Compare(L"May") == 0) | 1229 else if (sTemp.Compare(L"May") == 0) |
1384 nMonth = 5; | 1230 nMonth = 5; |
1385 if (sTemp.Compare(L"Jun") == 0) | 1231 else if (sTemp.Compare(L"Jun") == 0) |
1386 nMonth = 6; | 1232 nMonth = 6; |
1387 if (sTemp.Compare(L"Jul") == 0) | 1233 else if (sTemp.Compare(L"Jul") == 0) |
1388 nMonth = 7; | 1234 nMonth = 7; |
1389 if (sTemp.Compare(L"Aug") == 0) | 1235 else if (sTemp.Compare(L"Aug") == 0) |
1390 nMonth = 8; | 1236 nMonth = 8; |
1391 if (sTemp.Compare(L"Sep") == 0) | 1237 else if (sTemp.Compare(L"Sep") == 0) |
1392 nMonth = 9; | 1238 nMonth = 9; |
1393 if (sTemp.Compare(L"Oct") == 0) | 1239 else if (sTemp.Compare(L"Oct") == 0) |
1394 nMonth = 10; | 1240 nMonth = 10; |
1395 if (sTemp.Compare(L"Nov") == 0) | 1241 else if (sTemp.Compare(L"Nov") == 0) |
1396 nMonth = 11; | 1242 nMonth = 11; |
1397 if (sTemp.Compare(L"Dec") == 0) | 1243 else if (sTemp.Compare(L"Dec") == 0) |
1398 nMonth = 12; | 1244 nMonth = 12; |
1399 | 1245 |
1400 nDay = (int)ParseStringToNumber(wsArray[2].c_str()); | 1246 int nDay = FX_atof(wsArray[2]); |
1401 nHour = (int)ParseStringToNumber(wsArray[3].c_str()); | 1247 int nHour = FX_atof(wsArray[3]); |
1402 nMin = (int)ParseStringToNumber(wsArray[4].c_str()); | 1248 int nMin = FX_atof(wsArray[4]); |
1403 nSec = (int)ParseStringToNumber(wsArray[5].c_str()); | 1249 int nSec = FX_atof(wsArray[5]); |
1404 nYear = (int)ParseStringToNumber(wsArray[7].c_str()); | 1250 int nYear = FX_atof(wsArray[7]); |
1405 | |
1406 double dRet = JS_MakeDate(JS_MakeDay(nYear, nMonth - 1, nDay), | 1251 double dRet = JS_MakeDate(JS_MakeDay(nYear, nMonth - 1, nDay), |
1407 JS_MakeTime(nHour, nMin, nSec, 0)); | 1252 JS_MakeTime(nHour, nMin, nSec, 0)); |
1408 | 1253 if (JS_PortIsNan(dRet)) |
1409 if (JS_PortIsNan(dRet)) { | |
1410 dRet = JS_DateParse(strValue.c_str()); | 1254 dRet = JS_DateParse(strValue.c_str()); |
1411 } | |
1412 | 1255 |
1413 return dRet; | 1256 return dRet; |
1414 } | 1257 } |
1415 | 1258 |
1416 // AFDate_KeystrokeEx(cFormat) | 1259 // AFDate_KeystrokeEx(cFormat) |
1417 FX_BOOL CJS_PublicMethods::AFDate_KeystrokeEx( | 1260 FX_BOOL CJS_PublicMethods::AFDate_KeystrokeEx( |
1418 IJS_Context* cc, | 1261 IJS_Context* cc, |
1419 const std::vector<CJS_Value>& params, | 1262 const std::vector<CJS_Value>& params, |
1420 CJS_Value& vRet, | 1263 CJS_Value& vRet, |
1421 CFX_WideString& sError) { | 1264 CFX_WideString& sError) { |
(...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1859 | 1702 |
1860 vRet = (double)AF_Simple(params[0].ToCFXWideString().c_str(), | 1703 vRet = (double)AF_Simple(params[0].ToCFXWideString().c_str(), |
1861 params[1].ToDouble(), params[2].ToDouble()); | 1704 params[1].ToDouble(), params[2].ToDouble()); |
1862 return TRUE; | 1705 return TRUE; |
1863 } | 1706 } |
1864 | 1707 |
1865 FX_BOOL CJS_PublicMethods::AFMakeNumber(IJS_Context* cc, | 1708 FX_BOOL CJS_PublicMethods::AFMakeNumber(IJS_Context* cc, |
1866 const std::vector<CJS_Value>& params, | 1709 const std::vector<CJS_Value>& params, |
1867 CJS_Value& vRet, | 1710 CJS_Value& vRet, |
1868 CFX_WideString& sError) { | 1711 CFX_WideString& sError) { |
| 1712 CJS_Context* pContext = (CJS_Context*)cc; |
1869 if (params.size() != 1) { | 1713 if (params.size() != 1) { |
1870 CJS_Context* pContext = (CJS_Context*)cc; | |
1871 ASSERT(pContext); | |
1872 | |
1873 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR); | 1714 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR); |
1874 return FALSE; | 1715 return FALSE; |
1875 } | 1716 } |
1876 vRet = ParseStringToNumber(params[0].ToCFXWideString().c_str()); | 1717 CFX_WideString ws = params[0].ToCFXWideString(); |
| 1718 ws.Replace(L",", L"."); |
| 1719 vRet = ws; |
| 1720 vRet.MaybeCoerceToNumber(); |
| 1721 if (vRet.GetType() != CJS_Value::VT_number) |
| 1722 vRet = 0; |
1877 return TRUE; | 1723 return TRUE; |
1878 } | 1724 } |
1879 | 1725 |
1880 FX_BOOL CJS_PublicMethods::AFSimple_Calculate( | 1726 FX_BOOL CJS_PublicMethods::AFSimple_Calculate( |
1881 IJS_Context* cc, | 1727 IJS_Context* cc, |
1882 const std::vector<CJS_Value>& params, | 1728 const std::vector<CJS_Value>& params, |
1883 CJS_Value& vRet, | 1729 CJS_Value& vRet, |
1884 CFX_WideString& sError) { | 1730 CFX_WideString& sError) { |
1885 CJS_Context* pContext = (CJS_Context*)cc; | 1731 CJS_Context* pContext = (CJS_Context*)cc; |
1886 if (params.size() != 2) { | 1732 if (params.size() != 2) { |
(...skipping 19 matching lines...) Expand all Loading... |
1906 int nFieldsCount = 0; | 1752 int nFieldsCount = 0; |
1907 | 1753 |
1908 for (int i = 0, isz = FieldNameArray.GetLength(); i < isz; i++) { | 1754 for (int i = 0, isz = FieldNameArray.GetLength(); i < isz; i++) { |
1909 CJS_Value jsValue(pRuntime); | 1755 CJS_Value jsValue(pRuntime); |
1910 FieldNameArray.GetElement(i, jsValue); | 1756 FieldNameArray.GetElement(i, jsValue); |
1911 CFX_WideString wsFieldName = jsValue.ToCFXWideString(); | 1757 CFX_WideString wsFieldName = jsValue.ToCFXWideString(); |
1912 | 1758 |
1913 for (int j = 0, jsz = pInterForm->CountFields(wsFieldName); j < jsz; j++) { | 1759 for (int j = 0, jsz = pInterForm->CountFields(wsFieldName); j < jsz; j++) { |
1914 if (CPDF_FormField* pFormField = pInterForm->GetField(j, wsFieldName)) { | 1760 if (CPDF_FormField* pFormField = pInterForm->GetField(j, wsFieldName)) { |
1915 double dTemp = 0.0; | 1761 double dTemp = 0.0; |
1916 | |
1917 switch (pFormField->GetFieldType()) { | 1762 switch (pFormField->GetFieldType()) { |
1918 case FIELDTYPE_TEXTFIELD: | 1763 case FIELDTYPE_TEXTFIELD: |
1919 case FIELDTYPE_COMBOBOX: { | 1764 case FIELDTYPE_COMBOBOX: { |
1920 dTemp = ParseStringToNumber(pFormField->GetValue().c_str()); | 1765 CFX_WideString trimmed = pFormField->GetValue(); |
1921 break; | 1766 trimmed.TrimRight(); |
1922 } | 1767 trimmed.TrimLeft(); |
| 1768 dTemp = FX_atof(trimmed); |
| 1769 } break; |
1923 case FIELDTYPE_PUSHBUTTON: { | 1770 case FIELDTYPE_PUSHBUTTON: { |
1924 dTemp = 0.0; | 1771 dTemp = 0.0; |
1925 break; | 1772 } break; |
1926 } | |
1927 case FIELDTYPE_CHECKBOX: | 1773 case FIELDTYPE_CHECKBOX: |
1928 case FIELDTYPE_RADIOBUTTON: { | 1774 case FIELDTYPE_RADIOBUTTON: { |
1929 dTemp = 0.0; | 1775 dTemp = 0.0; |
1930 for (int c = 0, csz = pFormField->CountControls(); c < csz; c++) { | 1776 for (int c = 0, csz = pFormField->CountControls(); c < csz; c++) { |
1931 if (CPDF_FormControl* pFormCtrl = pFormField->GetControl(c)) { | 1777 if (CPDF_FormControl* pFormCtrl = pFormField->GetControl(c)) { |
1932 if (pFormCtrl->IsChecked()) { | 1778 if (pFormCtrl->IsChecked()) { |
1933 dTemp += | 1779 CFX_WideString trimmed = pFormCtrl->GetExportValue(); |
1934 ParseStringToNumber(pFormCtrl->GetExportValue().c_str()); | 1780 trimmed.TrimRight(); |
| 1781 trimmed.TrimLeft(); |
| 1782 dTemp = FX_atof(trimmed); |
1935 break; | 1783 break; |
1936 } | 1784 } |
1937 } | 1785 } |
1938 } | 1786 } |
1939 break; | 1787 } break; |
1940 } | |
1941 case FIELDTYPE_LISTBOX: { | 1788 case FIELDTYPE_LISTBOX: { |
1942 if (pFormField->CountSelectedItems() > 1) | 1789 if (pFormField->CountSelectedItems() <= 1) { |
1943 break; | 1790 CFX_WideString trimmed = pFormField->GetValue(); |
1944 | 1791 trimmed.TrimRight(); |
1945 dTemp = ParseStringToNumber(pFormField->GetValue().c_str()); | 1792 trimmed.TrimLeft(); |
1946 break; | 1793 dTemp = FX_atof(trimmed); |
1947 } | 1794 } |
| 1795 } break; |
1948 default: | 1796 default: |
1949 break; | 1797 break; |
1950 } | 1798 } |
1951 | 1799 |
1952 if (i == 0 && j == 0 && (wcscmp(sFunction.c_str(), L"MIN") == 0 || | 1800 if (i == 0 && j == 0 && (wcscmp(sFunction.c_str(), L"MIN") == 0 || |
1953 wcscmp(sFunction.c_str(), L"MAX") == 0)) | 1801 wcscmp(sFunction.c_str(), L"MAX") == 0)) |
1954 dValue = dTemp; | 1802 dValue = dTemp; |
1955 | 1803 |
1956 dValue = AF_Simple(sFunction.c_str(), dValue, dTemp); | 1804 dValue = AF_Simple(sFunction.c_str(), dValue, dTemp); |
1957 | 1805 |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2058 nums.SetElement(nIndex, CJS_Value(pRuntime, sPart.c_str())); | 1906 nums.SetElement(nIndex, CJS_Value(pRuntime, sPart.c_str())); |
2059 } | 1907 } |
2060 | 1908 |
2061 if (nums.GetLength() > 0) | 1909 if (nums.GetLength() > 0) |
2062 vRet = nums; | 1910 vRet = nums; |
2063 else | 1911 else |
2064 vRet.SetNull(); | 1912 vRet.SetNull(); |
2065 | 1913 |
2066 return TRUE; | 1914 return TRUE; |
2067 } | 1915 } |
OLD | NEW |