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 FX_BOOL CJS_PublicMethods::ConvertStringToNumber(const FX_WCHAR* swSource, | 197 double CJS_PublicMethods::ParseNumber(const FX_WCHAR* swSource, |
198 double& dRet) { | 198 FX_BOOL& bAllDigits, |
199 CFX_ByteString sDigits = CFX_WideString(swSource).UTF8Encode(); | 199 FX_BOOL& bDot, |
| 200 FX_BOOL& bSign, |
| 201 FX_BOOL& bKXJS) { |
| 202 bDot = FALSE; |
| 203 bSign = FALSE; |
| 204 bKXJS = FALSE; |
200 | 205 |
201 // Always interpret "," as "." independent of the locale. | 206 FX_BOOL bDigitExist = FALSE; |
202 for (FX_STRSIZE k = 0; k < sDigits.GetLength(); k++) { | 207 |
203 if (sDigits[k] == ',') | 208 const FX_WCHAR* p = swSource; |
204 sDigits.SetAt(k, '.'); | 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++; |
205 } | 221 } |
206 | 222 |
207 // Parse a number, ignoring leading and trailing whitespace. | 223 if (!pStart) { |
208 // Fail if there is trailing garbage. | 224 bAllDigits = FALSE; |
209 const char* pStart = sDigits.c_str(); | 225 return 0; |
210 const char* pEnd = NULL; | |
211 dRet = strtod(pStart, const_cast<char**>(&pEnd)); | |
212 if (pEnd == pStart) { | |
213 return FALSE; | |
214 } | 226 } |
215 for (; *pEnd; pEnd++) { | 227 |
216 if (!isspace(*pEnd)) { | 228 while (pEnd != pStart) { |
217 dRet = 0; | 229 if (*pEnd == L' ') |
218 return FALSE; | 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 } |
219 } | 313 } |
220 } | 314 } |
221 | 315 |
222 return TRUE; | 316 return dRet; |
223 } | 317 } |
224 | 318 |
225 double CJS_PublicMethods::ParseStringToNumber(const FX_WCHAR* swSource) { | 319 double CJS_PublicMethods::ParseStringToNumber(const FX_WCHAR* swSource) { |
226 double dRet; | 320 FX_BOOL bAllDigits = FALSE; |
227 ConvertStringToNumber(swSource, dRet); | 321 FX_BOOL bDot = FALSE; |
228 return dRet; | 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; |
229 } | 338 } |
230 | 339 |
231 CJS_Array CJS_PublicMethods::AF_MakeArrayFromList(CJS_Runtime* pRuntime, | 340 CJS_Array CJS_PublicMethods::AF_MakeArrayFromList(CJS_Runtime* pRuntime, |
232 CJS_Value val) { | 341 CJS_Value val) { |
233 CJS_Array StrArray(pRuntime); | 342 CJS_Array StrArray(pRuntime); |
234 if (val.IsArrayObject()) { | 343 if (val.IsArrayObject()) { |
235 val.ConvertToArray(StrArray); | 344 val.ConvertToArray(StrArray); |
236 return StrArray; | 345 return StrArray; |
237 } | 346 } |
238 CFX_WideString wsStr = val.ToCFXWideString(); | 347 CFX_WideString wsStr = val.ToCFXWideString(); |
(...skipping 1710 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1949 nums.SetElement(nIndex, CJS_Value(pRuntime, sPart.c_str())); | 2058 nums.SetElement(nIndex, CJS_Value(pRuntime, sPart.c_str())); |
1950 } | 2059 } |
1951 | 2060 |
1952 if (nums.GetLength() > 0) | 2061 if (nums.GetLength() > 0) |
1953 vRet = nums; | 2062 vRet = nums; |
1954 else | 2063 else |
1955 vRet.SetNull(); | 2064 vRet.SetNull(); |
1956 | 2065 |
1957 return TRUE; | 2066 return TRUE; |
1958 } | 2067 } |
OLD | NEW |