blob: 8ae1773c4976b0a483b747ead4d98ef2d93baa26 [file] [log] [blame]
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001// 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.
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07004
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07005// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
Dan Sinclairf766ad22016-03-14 13:51:24 -04007#include "fpdfsdk/javascript/util.h"
Tom Sepez37458412015-10-06 11:33:46 -07008
Lei Zhang6b37a5f2015-12-25 00:20:59 -08009#include <time.h>
10
tsepez86a61dc2016-03-25 10:00:11 -070011#include <algorithm>
Dan Sinclair3ebd1212016-03-09 09:59:23 -050012#include <string>
13#include <vector>
14
dsinclaira52ab742016-09-29 13:59:29 -070015#include "core/fxcrt/fx_ext.h"
Dan Sinclairf766ad22016-03-14 13:51:24 -040016#include "fpdfsdk/javascript/JS_Define.h"
17#include "fpdfsdk/javascript/JS_EventHandler.h"
18#include "fpdfsdk/javascript/JS_Object.h"
Dan Sinclairf766ad22016-03-14 13:51:24 -040019#include "fpdfsdk/javascript/JS_Value.h"
20#include "fpdfsdk/javascript/PublicMethods.h"
Tom Sepezd6ae2af2017-02-16 11:49:55 -080021#include "fpdfsdk/javascript/cjs_event_context.h"
dsinclair64376be2016-03-31 20:03:24 -070022#include "fpdfsdk/javascript/cjs_runtime.h"
Dan Sinclairf766ad22016-03-14 13:51:24 -040023#include "fpdfsdk/javascript/resource.h"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070024
Nico Weber9d8ec5a2015-08-04 13:00:21 -070025#if _FX_OS_ == _FX_ANDROID_
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070026#include <ctype.h>
27#endif
28
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070029BEGIN_JS_STATIC_CONST(CJS_Util)
30END_JS_STATIC_CONST()
31
32BEGIN_JS_STATIC_PROP(CJS_Util)
33END_JS_STATIC_PROP()
34
35BEGIN_JS_STATIC_METHOD(CJS_Util)
Nico Weber9d8ec5a2015-08-04 13:00:21 -070036JS_STATIC_METHOD_ENTRY(printd)
37JS_STATIC_METHOD_ENTRY(printf)
38JS_STATIC_METHOD_ENTRY(printx)
39JS_STATIC_METHOD_ENTRY(scand)
40JS_STATIC_METHOD_ENTRY(byteToChar)
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070041END_JS_STATIC_METHOD()
42
Nico Weber9d8ec5a2015-08-04 13:00:21 -070043IMPLEMENT_JS_CLASS(CJS_Util, util)
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070044
Nico Weber9d8ec5a2015-08-04 13:00:21 -070045#define UTIL_INT 0
46#define UTIL_DOUBLE 1
47#define UTIL_STRING 2
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070048
tsepez86a61dc2016-03-25 10:00:11 -070049namespace {
50
51// Map PDF-style directives to equivalent wcsftime directives. Not
52// all have direct equivalents, though.
53struct TbConvert {
54 const FX_WCHAR* lpszJSMark;
55 const FX_WCHAR* lpszCppMark;
56};
57
58// Map PDF-style directives lacking direct wcsftime directives to
59// the value with which they will be replaced.
60struct TbConvertAdditional {
61 const FX_WCHAR* lpszJSMark;
62 int iValue;
63};
64
65const TbConvert TbConvertTable[] = {
66 {L"mmmm", L"%B"}, {L"mmm", L"%b"}, {L"mm", L"%m"}, {L"dddd", L"%A"},
67 {L"ddd", L"%a"}, {L"dd", L"%d"}, {L"yyyy", L"%Y"}, {L"yy", L"%y"},
68 {L"HH", L"%H"}, {L"hh", L"%I"}, {L"MM", L"%M"}, {L"ss", L"%S"},
69 {L"TT", L"%p"},
70#if defined(_WIN32)
71 {L"tt", L"%p"}, {L"h", L"%#I"},
72#else
73 {L"tt", L"%P"}, {L"h", L"%l"},
74#endif
75};
76
77int ParseDataType(std::wstring* sFormat) {
tsepez4cf55152016-11-02 14:37:54 -070078 bool bPercent = false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070079 for (size_t i = 0; i < sFormat->length(); ++i) {
80 wchar_t c = (*sFormat)[i];
81 if (c == L'%') {
82 bPercent = true;
83 continue;
Tom Sepez2f2ffec2015-07-23 14:42:09 -070084 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070085
Nico Weber9d8ec5a2015-08-04 13:00:21 -070086 if (bPercent) {
87 if (c == L'c' || c == L'C' || c == L'd' || c == L'i' || c == L'o' ||
88 c == L'u' || c == L'x' || c == L'X') {
89 return UTIL_INT;
90 }
91 if (c == L'e' || c == L'E' || c == L'f' || c == L'g' || c == L'G') {
92 return UTIL_DOUBLE;
93 }
94 if (c == L's' || c == L'S') {
95 // Map s to S since we always deal internally
96 // with wchar_t strings.
97 (*sFormat)[i] = L'S';
98 return UTIL_STRING;
99 }
100 if (c == L'.' || c == L'+' || c == L'-' || c == L'#' || c == L' ' ||
Lei Zhang9559b7a2015-12-21 11:12:20 -0800101 FXSYS_iswdigit(c)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700102 continue;
103 }
104 break;
105 }
106 }
107
108 return -1;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700109}
110
tsepez86a61dc2016-03-25 10:00:11 -0700111} // namespace
112
113util::util(CJS_Object* pJSObject) : CJS_EmbedObj(pJSObject) {}
114
115util::~util() {}
116
Tom Sepezb1670b52017-02-16 17:01:00 -0800117bool util::printf(CJS_Runtime* pRuntime,
tsepez4cf55152016-11-02 14:37:54 -0700118 const std::vector<CJS_Value>& params,
119 CJS_Value& vRet,
120 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700121 int iSize = params.size();
122 if (iSize < 1)
tsepez4cf55152016-11-02 14:37:54 -0700123 return false;
tsepezb4694242016-08-15 16:44:55 -0700124 std::wstring c_ConvChar(params[0].ToCFXWideString(pRuntime).c_str());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700125 std::vector<std::wstring> c_strConvers;
126 int iOffset = 0;
127 int iOffend = 0;
128 c_ConvChar.insert(c_ConvChar.begin(), L'S');
129 while (iOffset != -1) {
130 iOffend = c_ConvChar.find(L"%", iOffset + 1);
131 std::wstring strSub;
132 if (iOffend == -1)
133 strSub = c_ConvChar.substr(iOffset);
134 else
135 strSub = c_ConvChar.substr(iOffset, iOffend - iOffset);
136 c_strConvers.push_back(strSub);
137 iOffset = iOffend;
138 }
139
140 std::wstring c_strResult;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700141 std::wstring c_strFormat;
142 for (int iIndex = 0; iIndex < (int)c_strConvers.size(); iIndex++) {
143 c_strFormat = c_strConvers[iIndex];
144 if (iIndex == 0) {
145 c_strResult = c_strFormat;
146 continue;
147 }
148
149 CFX_WideString strSegment;
150 if (iIndex >= iSize) {
151 c_strResult += c_strFormat;
152 continue;
153 }
154
tsepez86a61dc2016-03-25 10:00:11 -0700155 switch (ParseDataType(&c_strFormat)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700156 case UTIL_INT:
tsepezb4694242016-08-15 16:44:55 -0700157 strSegment.Format(c_strFormat.c_str(), params[iIndex].ToInt(pRuntime));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700158 break;
159 case UTIL_DOUBLE:
tsepezf3dc8c62016-08-10 06:29:29 -0700160 strSegment.Format(c_strFormat.c_str(),
tsepezb4694242016-08-15 16:44:55 -0700161 params[iIndex].ToDouble(pRuntime));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700162 break;
163 case UTIL_STRING:
tsepezb4694242016-08-15 16:44:55 -0700164 strSegment.Format(c_strFormat.c_str(),
165 params[iIndex].ToCFXWideString(pRuntime).c_str());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700166 break;
167 default:
168 strSegment.Format(L"%S", c_strFormat.c_str());
169 break;
170 }
171 c_strResult += strSegment.GetBuffer(strSegment.GetLength() + 1);
172 }
173
174 c_strResult.erase(c_strResult.begin());
tsepezf3dc8c62016-08-10 06:29:29 -0700175 vRet = CJS_Value(pRuntime, c_strResult.c_str());
tsepez4cf55152016-11-02 14:37:54 -0700176 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700177}
178
Tom Sepezb1670b52017-02-16 17:01:00 -0800179bool util::printd(CJS_Runtime* pRuntime,
tsepez4cf55152016-11-02 14:37:54 -0700180 const std::vector<CJS_Value>& params,
181 CJS_Value& vRet,
182 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700183 int iSize = params.size();
184 if (iSize < 2)
tsepez4cf55152016-11-02 14:37:54 -0700185 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700186
tsepez86a61dc2016-03-25 10:00:11 -0700187 CJS_Value p1 = params[0];
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700188 CJS_Value p2 = params[1];
tsepezf3c88322016-08-09 07:30:38 -0700189 CJS_Date jsDate;
tsepezb4694242016-08-15 16:44:55 -0700190 if (!p2.ConvertToDate(pRuntime, jsDate)) {
tsepezcd5dc852016-09-08 11:23:24 -0700191 sError = JSGetStringFromID(IDS_STRING_JSPRINT1);
tsepez4cf55152016-11-02 14:37:54 -0700192 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700193 }
194
tsepezb4694242016-08-15 16:44:55 -0700195 if (!jsDate.IsValidDate(pRuntime)) {
tsepezcd5dc852016-09-08 11:23:24 -0700196 sError = JSGetStringFromID(IDS_STRING_JSPRINT2);
tsepez4cf55152016-11-02 14:37:54 -0700197 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700198 }
199
Tom Sepez39bfe122015-09-17 15:25:23 -0700200 if (p1.GetType() == CJS_Value::VT_number) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700201 CFX_WideString swResult;
tsepezb4694242016-08-15 16:44:55 -0700202 switch (p1.ToInt(pRuntime)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700203 case 0:
tsepezb4694242016-08-15 16:44:55 -0700204 swResult.Format(L"D:%04d%02d%02d%02d%02d%02d", jsDate.GetYear(pRuntime),
205 jsDate.GetMonth(pRuntime) + 1, jsDate.GetDay(pRuntime),
206 jsDate.GetHours(pRuntime), jsDate.GetMinutes(pRuntime),
207 jsDate.GetSeconds(pRuntime));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700208 break;
209 case 1:
tsepezf3c88322016-08-09 07:30:38 -0700210 swResult.Format(L"%04d.%02d.%02d %02d:%02d:%02d",
tsepezb4694242016-08-15 16:44:55 -0700211 jsDate.GetYear(pRuntime), jsDate.GetMonth(pRuntime) + 1,
212 jsDate.GetDay(pRuntime), jsDate.GetHours(pRuntime),
213 jsDate.GetMinutes(pRuntime),
214 jsDate.GetSeconds(pRuntime));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700215 break;
216 case 2:
tsepezf3c88322016-08-09 07:30:38 -0700217 swResult.Format(L"%04d/%02d/%02d %02d:%02d:%02d",
tsepezb4694242016-08-15 16:44:55 -0700218 jsDate.GetYear(pRuntime), jsDate.GetMonth(pRuntime) + 1,
219 jsDate.GetDay(pRuntime), jsDate.GetHours(pRuntime),
220 jsDate.GetMinutes(pRuntime),
221 jsDate.GetSeconds(pRuntime));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700222 break;
223 default:
tsepezcd5dc852016-09-08 11:23:24 -0700224 sError = JSGetStringFromID(IDS_STRING_JSVALUEERROR);
tsepez4cf55152016-11-02 14:37:54 -0700225 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700226 }
227
tsepezf3dc8c62016-08-10 06:29:29 -0700228 vRet = CJS_Value(pRuntime, swResult.c_str());
tsepez4cf55152016-11-02 14:37:54 -0700229 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700230 }
tsepez86a61dc2016-03-25 10:00:11 -0700231
Tom Sepez39bfe122015-09-17 15:25:23 -0700232 if (p1.GetType() == CJS_Value::VT_string) {
tsepezb4694242016-08-15 16:44:55 -0700233 if (iSize > 2 && params[2].ToBool(pRuntime)) {
tsepezcd5dc852016-09-08 11:23:24 -0700234 sError = JSGetStringFromID(IDS_STRING_JSNOTSUPPORT);
tsepez4cf55152016-11-02 14:37:54 -0700235 return false; // currently, it doesn't support XFAPicture.
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700236 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700237
tsepez86a61dc2016-03-25 10:00:11 -0700238 // Convert PDF-style format specifiers to wcsftime specifiers. Remove any
239 // pre-existing %-directives before inserting our own.
tsepezb4694242016-08-15 16:44:55 -0700240 std::basic_string<wchar_t> cFormat = p1.ToCFXWideString(pRuntime).c_str();
tsepez86a61dc2016-03-25 10:00:11 -0700241 cFormat.erase(std::remove(cFormat.begin(), cFormat.end(), '%'),
242 cFormat.end());
243
244 for (size_t i = 0; i < FX_ArraySize(TbConvertTable); ++i) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700245 int iStart = 0;
246 int iEnd;
tsepez86a61dc2016-03-25 10:00:11 -0700247 while ((iEnd = cFormat.find(TbConvertTable[i].lpszJSMark, iStart)) !=
248 -1) {
249 cFormat.replace(iEnd, FXSYS_wcslen(TbConvertTable[i].lpszJSMark),
250 TbConvertTable[i].lpszCppMark);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700251 iStart = iEnd;
252 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700253 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700254
tsepezb4694242016-08-15 16:44:55 -0700255 int iYear = jsDate.GetYear(pRuntime);
256 int iMonth = jsDate.GetMonth(pRuntime);
257 int iDay = jsDate.GetDay(pRuntime);
258 int iHour = jsDate.GetHours(pRuntime);
259 int iMin = jsDate.GetMinutes(pRuntime);
260 int iSec = jsDate.GetSeconds(pRuntime);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700261
tsepez86a61dc2016-03-25 10:00:11 -0700262 TbConvertAdditional cTableAd[] = {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700263 {L"m", iMonth + 1}, {L"d", iDay},
264 {L"H", iHour}, {L"h", iHour > 12 ? iHour - 12 : iHour},
265 {L"M", iMin}, {L"s", iSec},
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700266 };
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700267
tsepez86a61dc2016-03-25 10:00:11 -0700268 for (size_t i = 0; i < FX_ArraySize(cTableAd); ++i) {
269 wchar_t tszValue[16];
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700270 CFX_WideString sValue;
Lei Zhangb9c31972015-08-11 14:09:35 -0700271 sValue.Format(L"%d", cTableAd[i].iValue);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700272 memcpy(tszValue, (wchar_t*)sValue.GetBuffer(sValue.GetLength() + 1),
273 (sValue.GetLength() + 1) * sizeof(wchar_t));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700274
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700275 int iStart = 0;
276 int iEnd;
Lei Zhangb9c31972015-08-11 14:09:35 -0700277 while ((iEnd = cFormat.find(cTableAd[i].lpszJSMark, iStart)) != -1) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700278 if (iEnd > 0) {
279 if (cFormat[iEnd - 1] == L'%') {
280 iStart = iEnd + 1;
281 continue;
282 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700283 }
Lei Zhangb9c31972015-08-11 14:09:35 -0700284 cFormat.replace(iEnd, FXSYS_wcslen(cTableAd[i].lpszJSMark), tszValue);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700285 iStart = iEnd;
286 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700287 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700288
tsepez86a61dc2016-03-25 10:00:11 -0700289 struct tm time = {};
290 time.tm_year = iYear - 1900;
291 time.tm_mon = iMonth;
292 time.tm_mday = iDay;
293 time.tm_hour = iHour;
294 time.tm_min = iMin;
295 time.tm_sec = iSec;
296
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700297 wchar_t buf[64] = {};
tsepez86a61dc2016-03-25 10:00:11 -0700298 wcsftime(buf, 64, cFormat.c_str(), &time);
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700299 cFormat = buf;
tsepezf3dc8c62016-08-10 06:29:29 -0700300 vRet = CJS_Value(pRuntime, cFormat.c_str());
tsepez4cf55152016-11-02 14:37:54 -0700301 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700302 }
tsepez86a61dc2016-03-25 10:00:11 -0700303
tsepezcd5dc852016-09-08 11:23:24 -0700304 sError = JSGetStringFromID(IDS_STRING_JSTYPEERROR);
tsepez4cf55152016-11-02 14:37:54 -0700305 return false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700306}
307
Tom Sepezb1670b52017-02-16 17:01:00 -0800308bool util::printx(CJS_Runtime* pRuntime,
tsepez4cf55152016-11-02 14:37:54 -0700309 const std::vector<CJS_Value>& params,
310 CJS_Value& vRet,
311 CFX_WideString& sError) {
tsepez4f1f41f2016-03-28 14:13:16 -0700312 if (params.size() < 2) {
tsepezcd5dc852016-09-08 11:23:24 -0700313 sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
tsepez4cf55152016-11-02 14:37:54 -0700314 return false;
tsepez4f1f41f2016-03-28 14:13:16 -0700315 }
tsepezf3dc8c62016-08-10 06:29:29 -0700316
tsepezb4694242016-08-15 16:44:55 -0700317 vRet = CJS_Value(pRuntime, printx(params[0].ToCFXWideString(pRuntime),
318 params[1].ToCFXWideString(pRuntime))
319 .c_str());
tsepezf3dc8c62016-08-10 06:29:29 -0700320
tsepez4cf55152016-11-02 14:37:54 -0700321 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700322}
323
tsepez4f1f41f2016-03-28 14:13:16 -0700324enum CaseMode { kPreserveCase, kUpperCase, kLowerCase };
325
326static FX_WCHAR TranslateCase(FX_WCHAR input, CaseMode eMode) {
327 if (eMode == kLowerCase && input >= 'A' && input <= 'Z')
328 return input | 0x20;
329 if (eMode == kUpperCase && input >= 'a' && input <= 'z')
330 return input & ~0x20;
331 return input;
332}
333
334CFX_WideString util::printx(const CFX_WideString& wsFormat,
335 const CFX_WideString& wsSource) {
336 CFX_WideString wsResult;
337 FX_STRSIZE iSourceIdx = 0;
338 FX_STRSIZE iFormatIdx = 0;
339 CaseMode eCaseMode = kPreserveCase;
340 bool bEscaped = false;
341 while (iFormatIdx < wsFormat.GetLength()) {
342 if (bEscaped) {
343 bEscaped = false;
344 wsResult += wsFormat[iFormatIdx];
345 ++iFormatIdx;
346 continue;
347 }
348 switch (wsFormat[iFormatIdx]) {
349 case '\\': {
350 bEscaped = true;
351 ++iFormatIdx;
352 } break;
353 case '<': {
354 eCaseMode = kLowerCase;
355 ++iFormatIdx;
356 } break;
357 case '>': {
358 eCaseMode = kUpperCase;
359 ++iFormatIdx;
360 } break;
361 case '=': {
362 eCaseMode = kPreserveCase;
363 ++iFormatIdx;
364 } break;
365 case '?': {
366 if (iSourceIdx < wsSource.GetLength()) {
367 wsResult += TranslateCase(wsSource[iSourceIdx], eCaseMode);
368 ++iSourceIdx;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700369 }
tsepez4f1f41f2016-03-28 14:13:16 -0700370 ++iFormatIdx;
371 } break;
372 case 'X': {
373 if (iSourceIdx < wsSource.GetLength()) {
374 if ((wsSource[iSourceIdx] >= '0' && wsSource[iSourceIdx] <= '9') ||
375 (wsSource[iSourceIdx] >= 'a' && wsSource[iSourceIdx] <= 'z') ||
376 (wsSource[iSourceIdx] >= 'A' && wsSource[iSourceIdx] <= 'Z')) {
377 wsResult += TranslateCase(wsSource[iSourceIdx], eCaseMode);
378 ++iFormatIdx;
379 }
380 ++iSourceIdx;
381 } else {
382 ++iFormatIdx;
383 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700384 } break;
385 case 'A': {
tsepez4f1f41f2016-03-28 14:13:16 -0700386 if (iSourceIdx < wsSource.GetLength()) {
387 if ((wsSource[iSourceIdx] >= 'a' && wsSource[iSourceIdx] <= 'z') ||
388 (wsSource[iSourceIdx] >= 'A' && wsSource[iSourceIdx] <= 'Z')) {
389 wsResult += TranslateCase(wsSource[iSourceIdx], eCaseMode);
390 ++iFormatIdx;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700391 }
tsepez4f1f41f2016-03-28 14:13:16 -0700392 ++iSourceIdx;
393 } else {
394 ++iFormatIdx;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700395 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700396 } break;
397 case '9': {
tsepez4f1f41f2016-03-28 14:13:16 -0700398 if (iSourceIdx < wsSource.GetLength()) {
399 if (wsSource[iSourceIdx] >= '0' && wsSource[iSourceIdx] <= '9') {
400 wsResult += wsSource[iSourceIdx];
401 ++iFormatIdx;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700402 }
tsepez4f1f41f2016-03-28 14:13:16 -0700403 ++iSourceIdx;
404 } else {
405 ++iFormatIdx;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700406 }
tsepez4f1f41f2016-03-28 14:13:16 -0700407 } break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700408 case '*': {
tsepez4f1f41f2016-03-28 14:13:16 -0700409 if (iSourceIdx < wsSource.GetLength()) {
410 wsResult += TranslateCase(wsSource[iSourceIdx], eCaseMode);
411 ++iSourceIdx;
412 } else {
413 ++iFormatIdx;
414 }
415 } break;
416 default: {
417 wsResult += wsFormat[iFormatIdx];
418 ++iFormatIdx;
419 } break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700420 }
421 }
tsepez4f1f41f2016-03-28 14:13:16 -0700422 return wsResult;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700423}
424
Tom Sepezb1670b52017-02-16 17:01:00 -0800425bool util::scand(CJS_Runtime* pRuntime,
tsepez4cf55152016-11-02 14:37:54 -0700426 const std::vector<CJS_Value>& params,
427 CJS_Value& vRet,
428 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700429 int iSize = params.size();
430 if (iSize < 2)
tsepez4cf55152016-11-02 14:37:54 -0700431 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700432
tsepezb4694242016-08-15 16:44:55 -0700433 CFX_WideString sFormat = params[0].ToCFXWideString(pRuntime);
434 CFX_WideString sDate = params[1].ToCFXWideString(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700435 double dDate = JS_GetDateTime();
436 if (sDate.GetLength() > 0) {
Lei Zhang9559b7a2015-12-21 11:12:20 -0800437 dDate = CJS_PublicMethods::MakeRegularDate(sDate, sFormat, nullptr);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700438 }
439
440 if (!JS_PortIsNan(dDate)) {
tsepezb4694242016-08-15 16:44:55 -0700441 vRet = CJS_Value(pRuntime, CJS_Date(pRuntime, dDate));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700442 } else {
tsepezf3dc8c62016-08-10 06:29:29 -0700443 vRet.SetNull(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700444 }
445
tsepez4cf55152016-11-02 14:37:54 -0700446 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700447}
448
Tom Sepezb1670b52017-02-16 17:01:00 -0800449bool util::byteToChar(CJS_Runtime* pRuntime,
tsepez4cf55152016-11-02 14:37:54 -0700450 const std::vector<CJS_Value>& params,
451 CJS_Value& vRet,
452 CFX_WideString& sError) {
tsepez90d87792016-03-29 09:21:54 -0700453 if (params.size() < 1) {
tsepezcd5dc852016-09-08 11:23:24 -0700454 sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
tsepez4cf55152016-11-02 14:37:54 -0700455 return false;
tsepez90d87792016-03-29 09:21:54 -0700456 }
tsepezf3dc8c62016-08-10 06:29:29 -0700457
tsepezb4694242016-08-15 16:44:55 -0700458 int arg = params[0].ToInt(pRuntime);
tsepez90d87792016-03-29 09:21:54 -0700459 if (arg < 0 || arg > 255) {
tsepezcd5dc852016-09-08 11:23:24 -0700460 sError = JSGetStringFromID(IDS_STRING_JSVALUEERROR);
tsepez4cf55152016-11-02 14:37:54 -0700461 return false;
tsepez90d87792016-03-29 09:21:54 -0700462 }
tsepezf3dc8c62016-08-10 06:29:29 -0700463
tsepez90d87792016-03-29 09:21:54 -0700464 CFX_WideString wStr(static_cast<FX_WCHAR>(arg));
tsepezf3dc8c62016-08-10 06:29:29 -0700465 vRet = CJS_Value(pRuntime, wStr.c_str());
tsepez4cf55152016-11-02 14:37:54 -0700466 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700467}