Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(114)

Side by Side Diff: xfa/src/fxfa/parser/xfa_localevalue.cpp

Issue 1803723002: Move xfa/src up to xfa/. (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: Rebase to master Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « xfa/src/fxfa/parser/xfa_localevalue.h ('k') | xfa/src/fxfa/parser/xfa_object.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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/src/fxfa/parser/xfa_localevalue.h"
8
9 #include "xfa/src/fxfa/fm2js/xfa_fm2jsapi.h"
10 #include "xfa/src/fxfa/parser/xfa_docdata.h"
11 #include "xfa/src/fxfa/parser/xfa_doclayout.h"
12 #include "xfa/src/fxfa/parser/xfa_document.h"
13 #include "xfa/src/fxfa/parser/xfa_localemgr.h"
14 #include "xfa/src/fxfa/parser/xfa_object.h"
15 #include "xfa/src/fxfa/parser/xfa_parser.h"
16 #include "xfa/src/fxfa/parser/xfa_script.h"
17 #include "xfa/src/fxfa/parser/xfa_utils.h"
18
19 static const FX_DOUBLE fraction_scales[] = {0.1,
20 0.01,
21 0.001,
22 0.0001,
23 0.00001,
24 0.000001,
25 0.0000001,
26 0.00000001,
27 0.000000001,
28 0.0000000001,
29 0.00000000001,
30 0.000000000001,
31 0.0000000000001,
32 0.00000000000001,
33 0.000000000000001,
34 0.0000000000000001};
35 CXFA_LocaleValue::CXFA_LocaleValue() {
36 m_dwType = XFA_VT_NULL;
37 m_bValid = TRUE;
38 m_pLocaleMgr = NULL;
39 }
40 CXFA_LocaleValue::CXFA_LocaleValue(const CXFA_LocaleValue& value) {
41 m_dwType = XFA_VT_NULL;
42 m_bValid = TRUE;
43 m_pLocaleMgr = NULL;
44 *this = value;
45 }
46 CXFA_LocaleValue::CXFA_LocaleValue(FX_DWORD dwType,
47 CXFA_LocaleMgr* pLocaleMgr) {
48 m_dwType = dwType;
49 m_bValid = (m_dwType != XFA_VT_NULL);
50 m_pLocaleMgr = pLocaleMgr;
51 }
52 CXFA_LocaleValue::CXFA_LocaleValue(FX_DWORD dwType,
53 const CFX_WideString& wsValue,
54 CXFA_LocaleMgr* pLocaleMgr) {
55 m_wsValue = wsValue;
56 m_dwType = dwType;
57 m_pLocaleMgr = pLocaleMgr;
58 m_bValid = ValidateCanonicalValue(wsValue, dwType);
59 }
60 CXFA_LocaleValue::CXFA_LocaleValue(FX_DWORD dwType,
61 const CFX_WideString& wsValue,
62 const CFX_WideString& wsFormat,
63 IFX_Locale* pLocale,
64 CXFA_LocaleMgr* pLocaleMgr) {
65 m_pLocaleMgr = pLocaleMgr;
66 m_bValid = TRUE;
67 m_dwType = dwType;
68 m_bValid = ParsePatternValue(wsValue, wsFormat, pLocale);
69 }
70 CXFA_LocaleValue& CXFA_LocaleValue::operator=(const CXFA_LocaleValue& value) {
71 m_wsValue = value.m_wsValue;
72 m_dwType = value.m_dwType;
73 m_bValid = value.m_bValid;
74 m_pLocaleMgr = value.m_pLocaleMgr;
75 return *this;
76 }
77 CXFA_LocaleValue::~CXFA_LocaleValue() {}
78 static FX_LOCALECATEGORY XFA_ValugeCategory(FX_LOCALECATEGORY eCategory,
79 FX_DWORD dwValueType) {
80 if (eCategory == FX_LOCALECATEGORY_Unknown) {
81 switch (dwValueType) {
82 case XFA_VT_BOOLEAN:
83 case XFA_VT_INTEGER:
84 case XFA_VT_DECIMAL:
85 case XFA_VT_FLOAT:
86 return FX_LOCALECATEGORY_Num;
87 case XFA_VT_TEXT:
88 return FX_LOCALECATEGORY_Text;
89 case XFA_VT_DATE:
90 return FX_LOCALECATEGORY_Date;
91 case XFA_VT_TIME:
92 return FX_LOCALECATEGORY_Time;
93 case XFA_VT_DATETIME:
94 return FX_LOCALECATEGORY_DateTime;
95 }
96 }
97 return eCategory;
98 }
99 FX_BOOL CXFA_LocaleValue::ValidateValue(const CFX_WideString& wsValue,
100 const CFX_WideString& wsPattern,
101 IFX_Locale* pLocale,
102 CFX_WideString* pMatchFormat) {
103 CFX_WideString wsOutput;
104 IFX_Locale* locale = m_pLocaleMgr->GetDefLocale();
105 if (pLocale) {
106 m_pLocaleMgr->SetDefLocale(pLocale);
107 }
108 IFX_FormatString* pFormat = IFX_FormatString::Create(m_pLocaleMgr, FALSE);
109 CFX_WideStringArray wsPatterns;
110 pFormat->SplitFormatString(wsPattern, wsPatterns);
111 FX_BOOL bRet = FALSE;
112 int32_t iCount = wsPatterns.GetSize();
113 int32_t i = 0;
114 for (; i < iCount && !bRet; i++) {
115 CFX_WideString wsFormat = wsPatterns[i];
116 FX_LOCALECATEGORY eCategory = pFormat->GetCategory(wsFormat);
117 eCategory = XFA_ValugeCategory(eCategory, m_dwType);
118 switch (eCategory) {
119 case FX_LOCALECATEGORY_Null:
120 bRet = pFormat->ParseNull(wsValue, wsFormat);
121 if (!bRet) {
122 bRet = wsValue.IsEmpty();
123 }
124 break;
125 case FX_LOCALECATEGORY_Zero:
126 bRet = pFormat->ParseZero(wsValue, wsFormat);
127 if (!bRet) {
128 bRet = wsValue == FX_WSTRC(L"0");
129 }
130 break;
131 case FX_LOCALECATEGORY_Num: {
132 CFX_WideString fNum;
133 bRet = pFormat->ParseNum(wsValue, wsFormat, fNum);
134 if (!bRet) {
135 bRet = pFormat->FormatNum(wsValue, wsFormat, wsOutput);
136 }
137 break;
138 }
139 case FX_LOCALECATEGORY_Text:
140 bRet = pFormat->ParseText(wsValue, wsFormat, wsOutput);
141 wsOutput.Empty();
142 if (!bRet) {
143 bRet = pFormat->FormatText(wsValue, wsFormat, wsOutput);
144 }
145 break;
146 case FX_LOCALECATEGORY_Date: {
147 CFX_Unitime dt;
148 bRet = ValidateCanonicalDate(wsValue, dt);
149 if (!bRet) {
150 bRet = pFormat->ParseDateTime(wsValue, wsFormat, FX_DATETIMETYPE_Date,
151 dt);
152 if (!bRet) {
153 bRet = pFormat->FormatDateTime(wsValue, wsFormat, wsOutput,
154 FX_DATETIMETYPE_Date);
155 }
156 }
157 break;
158 }
159 case FX_LOCALECATEGORY_Time: {
160 CFX_Unitime dt;
161 bRet =
162 pFormat->ParseDateTime(wsValue, wsFormat, FX_DATETIMETYPE_Time, dt);
163 if (!bRet) {
164 bRet = pFormat->FormatDateTime(wsValue, wsFormat, wsOutput,
165 FX_DATETIMETYPE_Time);
166 }
167 break;
168 }
169 case FX_LOCALECATEGORY_DateTime: {
170 CFX_Unitime dt;
171 bRet = pFormat->ParseDateTime(wsValue, wsFormat,
172 FX_DATETIMETYPE_DateTime, dt);
173 if (!bRet) {
174 bRet = pFormat->FormatDateTime(wsValue, wsFormat, wsOutput,
175 FX_DATETIMETYPE_DateTime);
176 }
177 break;
178 }
179 default:
180 bRet = FALSE;
181 break;
182 }
183 }
184 if (bRet && pMatchFormat) {
185 *pMatchFormat = wsPatterns[i - 1];
186 }
187 pFormat->Release();
188 if (pLocale) {
189 m_pLocaleMgr->SetDefLocale(locale);
190 }
191 return bRet;
192 }
193 CFX_WideString CXFA_LocaleValue::GetValue() const {
194 return m_wsValue;
195 }
196 FX_DWORD CXFA_LocaleValue::GetType() const {
197 return m_dwType;
198 }
199 void CXFA_LocaleValue::SetValue(const CFX_WideString& wsValue,
200 FX_DWORD dwType) {
201 m_wsValue = wsValue;
202 m_dwType = dwType;
203 }
204 CFX_WideString CXFA_LocaleValue::GetText() const {
205 if (m_bValid && m_dwType == XFA_VT_TEXT) {
206 return m_wsValue;
207 }
208 return CFX_WideString();
209 }
210 FX_FLOAT CXFA_LocaleValue::GetNum() const {
211 if (m_bValid && (m_dwType == XFA_VT_BOOLEAN || m_dwType == XFA_VT_INTEGER ||
212 m_dwType == XFA_VT_DECIMAL || m_dwType == XFA_VT_FLOAT)) {
213 int64_t nIntegral = 0;
214 FX_DWORD dwFractional = 0;
215 int32_t nExponent = 0;
216 int cc = 0;
217 FX_BOOL bNegative = FALSE, bExpSign = FALSE;
218 const FX_WCHAR* str = (const FX_WCHAR*)m_wsValue;
219 int len = m_wsValue.GetLength();
220 while (XFA_IsSpace(str[cc]) && cc < len) {
221 cc++;
222 }
223 if (cc >= len) {
224 return 0;
225 }
226 if (str[0] == '+') {
227 cc++;
228 } else if (str[0] == '-') {
229 bNegative = TRUE;
230 cc++;
231 }
232 int nIntegralLen = 0;
233 while (cc < len) {
234 if (str[cc] == '.' || !XFA_IsDigit(str[cc]) || nIntegralLen > 17) {
235 break;
236 }
237 nIntegral = nIntegral * 10 + str[cc] - '0';
238 cc++;
239 nIntegralLen++;
240 }
241 nIntegral = bNegative ? -nIntegral : nIntegral;
242 int scale = 0;
243 double fraction = 0.0;
244 if (cc < len && str[cc] == '.') {
245 cc++;
246 while (cc < len) {
247 fraction += fraction_scales[scale] * (str[cc] - '0');
248 scale++;
249 cc++;
250 if (scale == sizeof fraction_scales / sizeof(double) ||
251 !XFA_IsDigit(str[cc])) {
252 break;
253 }
254 }
255 dwFractional = (FX_DWORD)(fraction * 4294967296.0);
256 }
257 if (cc < len && (str[cc] == 'E' || str[cc] == 'e')) {
258 cc++;
259 if (cc < len) {
260 if (str[cc] == '+') {
261 cc++;
262 } else if (str[cc] == '-') {
263 bExpSign = TRUE;
264 cc++;
265 }
266 }
267 while (cc < len) {
268 if (str[cc] == '.' || !XFA_IsDigit(str[cc])) {
269 break;
270 }
271 nExponent = nExponent * 10 + str[cc] - '0';
272 cc++;
273 }
274 nExponent = bExpSign ? -nExponent : nExponent;
275 }
276 FX_FLOAT fValue = (FX_FLOAT)(dwFractional / 4294967296.0);
277 fValue = nIntegral + (nIntegral >= 0 ? fValue : -fValue);
278 if (nExponent != 0) {
279 fValue *= FXSYS_pow(10, (FX_FLOAT)nExponent);
280 }
281 return fValue;
282 }
283 return 0;
284 }
285 FX_DOUBLE CXFA_LocaleValue::GetDoubleNum() const {
286 if (m_bValid && (m_dwType == XFA_VT_BOOLEAN || m_dwType == XFA_VT_INTEGER ||
287 m_dwType == XFA_VT_DECIMAL || m_dwType == XFA_VT_FLOAT)) {
288 int64_t nIntegral = 0;
289 FX_DWORD dwFractional = 0;
290 int32_t nExponent = 0;
291 int32_t cc = 0;
292 FX_BOOL bNegative = FALSE, bExpSign = FALSE;
293 const FX_WCHAR* str = (const FX_WCHAR*)m_wsValue;
294 int len = m_wsValue.GetLength();
295 while (XFA_IsSpace(str[cc]) && cc < len) {
296 cc++;
297 }
298 if (cc >= len) {
299 return 0;
300 }
301 if (str[0] == '+') {
302 cc++;
303 } else if (str[0] == '-') {
304 bNegative = TRUE;
305 cc++;
306 }
307 int32_t nIntegralLen = 0;
308 while (cc < len) {
309 if (str[cc] == '.' || !XFA_IsDigit(str[cc]) || nIntegralLen > 17) {
310 break;
311 }
312 nIntegral = nIntegral * 10 + str[cc] - '0';
313 cc++;
314 nIntegralLen++;
315 }
316 nIntegral = bNegative ? -nIntegral : nIntegral;
317 int32_t scale = 0;
318 FX_DOUBLE fraction = 0.0;
319 if (cc < len && str[cc] == '.') {
320 cc++;
321 while (cc < len) {
322 fraction += fraction_scales[scale] * (str[cc] - '0');
323 scale++;
324 cc++;
325 if (scale == sizeof fraction_scales / sizeof(FX_DOUBLE) ||
326 !XFA_IsDigit(str[cc])) {
327 break;
328 }
329 }
330 dwFractional = (FX_DWORD)(fraction * 4294967296.0);
331 }
332 if (cc < len && (str[cc] == 'E' || str[cc] == 'e')) {
333 cc++;
334 if (cc < len) {
335 if (str[cc] == '+') {
336 cc++;
337 } else if (str[cc] == '-') {
338 bExpSign = TRUE;
339 cc++;
340 }
341 }
342 while (cc < len) {
343 if (str[cc] == '.' || !XFA_IsDigit(str[cc])) {
344 break;
345 }
346 nExponent = nExponent * 10 + str[cc] - '0';
347 cc++;
348 }
349 nExponent = bExpSign ? -nExponent : nExponent;
350 }
351 FX_DOUBLE dValue = (dwFractional / 4294967296.0);
352 dValue = nIntegral + (nIntegral >= 0 ? dValue : -dValue);
353 if (nExponent != 0) {
354 dValue *= FXSYS_pow(10, (FX_FLOAT)nExponent);
355 }
356 return dValue;
357 }
358 return 0;
359 }
360 CFX_Unitime CXFA_LocaleValue::GetDate() const {
361 if (m_bValid && m_dwType == XFA_VT_DATE) {
362 CFX_Unitime dt;
363 FX_DateFromCanonical(m_wsValue, dt);
364 return dt;
365 }
366 return CFX_Unitime();
367 }
368 CFX_Unitime CXFA_LocaleValue::GetTime() const {
369 if (m_bValid && m_dwType == XFA_VT_TIME) {
370 CFX_Unitime dt(0);
371 FXSYS_assert(m_pLocaleMgr);
372 FX_TimeFromCanonical(m_wsValue, dt, m_pLocaleMgr->GetDefLocale());
373 return dt;
374 }
375 return CFX_Unitime();
376 }
377 CFX_Unitime CXFA_LocaleValue::GetDateTime() const {
378 if (m_bValid && m_dwType == XFA_VT_DATETIME) {
379 int32_t index = m_wsValue.Find('T');
380 CFX_Unitime dt;
381 FX_DateFromCanonical(m_wsValue.Left(index), dt);
382 FXSYS_assert(m_pLocaleMgr);
383 FX_TimeFromCanonical(m_wsValue.Right(m_wsValue.GetLength() - index - 1), dt,
384 m_pLocaleMgr->GetDefLocale());
385 return dt;
386 }
387 return CFX_Unitime();
388 }
389 FX_BOOL CXFA_LocaleValue::SetText(const CFX_WideString& wsText) {
390 m_dwType = XFA_VT_TEXT;
391 m_wsValue = wsText;
392 return TRUE;
393 }
394 FX_BOOL CXFA_LocaleValue::SetText(const CFX_WideString& wsText,
395 const CFX_WideString& wsFormat,
396 IFX_Locale* pLocale) {
397 m_dwType = XFA_VT_TEXT;
398 return m_bValid = ParsePatternValue(wsText, wsFormat, pLocale);
399 }
400 FX_BOOL CXFA_LocaleValue::SetNum(FX_FLOAT fNum) {
401 m_dwType = XFA_VT_FLOAT;
402 m_wsValue.Format(L"%.8g", (FX_DOUBLE)fNum);
403 return TRUE;
404 }
405 FX_BOOL CXFA_LocaleValue::SetNum(const CFX_WideString& wsNum,
406 const CFX_WideString& wsFormat,
407 IFX_Locale* pLocale) {
408 m_dwType = XFA_VT_FLOAT;
409 return m_bValid = ParsePatternValue(wsNum, wsFormat, pLocale);
410 }
411 FX_BOOL CXFA_LocaleValue::SetDate(const CFX_Unitime& d) {
412 m_dwType = XFA_VT_DATE;
413 m_wsValue.Format(L"%04d-%02d-%02d", d.GetYear(), d.GetMonth(), d.GetDay());
414 return TRUE;
415 }
416 FX_BOOL CXFA_LocaleValue::SetDate(const CFX_WideString& wsDate,
417 const CFX_WideString& wsFormat,
418 IFX_Locale* pLocale) {
419 m_dwType = XFA_VT_DATE;
420 return m_bValid = ParsePatternValue(wsDate, wsFormat, pLocale);
421 }
422 FX_BOOL CXFA_LocaleValue::SetTime(const CFX_Unitime& t) {
423 m_dwType = XFA_VT_TIME;
424 m_wsValue.Format(L"%02d:%02d:%02d", t.GetHour(), t.GetMinute(),
425 t.GetSecond());
426 if (t.GetMillisecond() > 0) {
427 CFX_WideString wsTemp;
428 wsTemp.Format(L"%:03d", t.GetMillisecond());
429 m_wsValue += wsTemp;
430 }
431 return TRUE;
432 }
433 FX_BOOL CXFA_LocaleValue::SetTime(const CFX_WideString& wsTime,
434 const CFX_WideString& wsFormat,
435 IFX_Locale* pLocale) {
436 m_dwType = XFA_VT_TIME;
437 return m_bValid = ParsePatternValue(wsTime, wsFormat, pLocale);
438 }
439 FX_BOOL CXFA_LocaleValue::SetDateTime(const CFX_Unitime& dt) {
440 m_dwType = XFA_VT_DATETIME;
441 m_wsValue.Format(L"%04d-%02d-%02dT%02d:%02d:%02d", dt.GetYear(),
442 dt.GetMonth(), dt.GetDay(), dt.GetHour(), dt.GetMinute(),
443 dt.GetSecond());
444 if (dt.GetMillisecond() > 0) {
445 CFX_WideString wsTemp;
446 wsTemp.Format(L"%:03d", dt.GetMillisecond());
447 m_wsValue += wsTemp;
448 }
449 return TRUE;
450 }
451 FX_BOOL CXFA_LocaleValue::SetDateTime(const CFX_WideString& wsDateTime,
452 const CFX_WideString& wsFormat,
453 IFX_Locale* pLocale) {
454 m_dwType = XFA_VT_DATETIME;
455 return m_bValid = ParsePatternValue(wsDateTime, wsFormat, pLocale);
456 }
457 FX_BOOL CXFA_LocaleValue::FormatPatterns(CFX_WideString& wsResult,
458 const CFX_WideString& wsFormat,
459 IFX_Locale* pLocale,
460 XFA_VALUEPICTURE eValueType) const {
461 wsResult.Empty();
462 FX_BOOL bRet = FALSE;
463 IFX_FormatString* pFormat = IFX_FormatString::Create(m_pLocaleMgr, FALSE);
464 CFX_WideStringArray wsPatterns;
465 pFormat->SplitFormatString(wsFormat, wsPatterns);
466 int32_t iCount = wsPatterns.GetSize();
467 for (int32_t i = 0; i < iCount; i++) {
468 bRet = FormatSinglePattern(wsResult, wsPatterns[i], pLocale, eValueType);
469 if (bRet) {
470 break;
471 }
472 }
473 pFormat->Release();
474 return bRet;
475 }
476 FX_BOOL CXFA_LocaleValue::FormatSinglePattern(
477 CFX_WideString& wsResult,
478 const CFX_WideString& wsFormat,
479 IFX_Locale* pLocale,
480 XFA_VALUEPICTURE eValueType) const {
481 IFX_Locale* locale = m_pLocaleMgr->GetDefLocale();
482 if (pLocale) {
483 m_pLocaleMgr->SetDefLocale(pLocale);
484 }
485 wsResult.Empty();
486 FX_BOOL bRet = FALSE;
487 IFX_FormatString* pFormat = IFX_FormatString::Create(m_pLocaleMgr, FALSE);
488 FX_LOCALECATEGORY eCategory = pFormat->GetCategory(wsFormat);
489 eCategory = XFA_ValugeCategory(eCategory, m_dwType);
490 switch (eCategory) {
491 case FX_LOCALECATEGORY_Null:
492 if (m_wsValue.IsEmpty()) {
493 bRet = pFormat->FormatNull(wsFormat, wsResult);
494 }
495 break;
496 case FX_LOCALECATEGORY_Zero:
497 if (m_wsValue == FX_WSTRC(L"0")) {
498 bRet = pFormat->FormatZero(wsFormat, wsResult);
499 }
500 break;
501 case FX_LOCALECATEGORY_Num:
502 bRet = pFormat->FormatNum(m_wsValue, wsFormat, wsResult);
503 break;
504 case FX_LOCALECATEGORY_Text:
505 bRet = pFormat->FormatText(m_wsValue, wsFormat, wsResult);
506 break;
507 case FX_LOCALECATEGORY_Date:
508 bRet = pFormat->FormatDateTime(m_wsValue, wsFormat, wsResult,
509 FX_DATETIMETYPE_Date);
510 break;
511 case FX_LOCALECATEGORY_Time:
512 bRet = pFormat->FormatDateTime(m_wsValue, wsFormat, wsResult,
513 FX_DATETIMETYPE_Time);
514 break;
515 case FX_LOCALECATEGORY_DateTime:
516 bRet = pFormat->FormatDateTime(m_wsValue, wsFormat, wsResult,
517 FX_DATETIMETYPE_DateTime);
518 break;
519 default:
520 wsResult = m_wsValue;
521 bRet = TRUE;
522 }
523 pFormat->Release();
524 if (!bRet && (eCategory != FX_LOCALECATEGORY_Num ||
525 eValueType != XFA_VALUEPICTURE_Display)) {
526 wsResult = m_wsValue;
527 }
528 if (pLocale) {
529 m_pLocaleMgr->SetDefLocale(locale);
530 }
531 return bRet;
532 }
533 static FX_BOOL XFA_ValueSplitDateTime(const CFX_WideString& wsDateTime,
534 CFX_WideString& wsDate,
535 CFX_WideString& wsTime) {
536 wsDate = L"";
537 wsTime = L"";
538 if (wsDateTime.IsEmpty()) {
539 return FALSE;
540 }
541 int nSplitIndex = -1;
542 nSplitIndex = wsDateTime.Find('T');
543 if (nSplitIndex < 0) {
544 nSplitIndex = wsDateTime.Find(' ');
545 }
546 if (nSplitIndex < 0) {
547 return FALSE;
548 }
549 wsDate = wsDateTime.Left(nSplitIndex);
550 wsTime = wsDateTime.Right(wsDateTime.GetLength() - nSplitIndex - 1);
551 return TRUE;
552 }
553 FX_BOOL CXFA_LocaleValue::ValidateCanonicalValue(const CFX_WideString& wsValue,
554 FX_DWORD dwVType) {
555 if (wsValue.IsEmpty()) {
556 return TRUE;
557 }
558 CFX_Unitime dt;
559 switch (dwVType) {
560 case XFA_VT_DATE: {
561 if (ValidateCanonicalDate(wsValue, dt)) {
562 return TRUE;
563 }
564 CFX_WideString wsDate, wsTime;
565 if (XFA_ValueSplitDateTime(wsValue, wsDate, wsTime) &&
566 ValidateCanonicalDate(wsDate, dt)) {
567 return TRUE;
568 }
569 return FALSE;
570 }
571 case XFA_VT_TIME: {
572 if (ValidateCanonicalTime(wsValue)) {
573 return TRUE;
574 }
575 CFX_WideString wsDate, wsTime;
576 if (XFA_ValueSplitDateTime(wsValue, wsDate, wsTime) &&
577 ValidateCanonicalTime(wsTime)) {
578 return TRUE;
579 }
580 return FALSE;
581 }
582 case XFA_VT_DATETIME: {
583 CFX_WideString wsDate, wsTime;
584 if (XFA_ValueSplitDateTime(wsValue, wsDate, wsTime) &&
585 ValidateCanonicalDate(wsDate, dt) && ValidateCanonicalTime(wsTime)) {
586 return TRUE;
587 }
588 } break;
589 }
590 return TRUE;
591 }
592 FX_BOOL CXFA_LocaleValue::ValidateCanonicalDate(const CFX_WideString& wsDate,
593 CFX_Unitime& unDate) {
594 const FX_WORD LastDay[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
595 const FX_WORD wCountY = 4, wCountM = 2, wCountD = 2;
596 int nLen = wsDate.GetLength();
597 if (nLen < wCountY || nLen > wCountY + wCountM + wCountD + 2) {
598 return FALSE;
599 }
600 const bool bSymbol = wsDate.Find(0x2D) != -1;
601 FX_WORD wYear = 0;
602 FX_WORD wMonth = 0;
603 FX_WORD wDay = 0;
604 const FX_WCHAR* pDate = (const FX_WCHAR*)wsDate;
605 int nIndex = 0, nStart = 0;
606 while (pDate[nIndex] != '\0' && nIndex < wCountY) {
607 if (!XFA_IsDigit(pDate[nIndex])) {
608 return FALSE;
609 }
610 wYear = (pDate[nIndex] - '0') + wYear * 10;
611 nIndex++;
612 }
613 if (bSymbol) {
614 if (pDate[nIndex] != 0x2D) {
615 return FALSE;
616 }
617 nIndex++;
618 }
619 nStart = nIndex;
620 while (pDate[nIndex] != '\0' && nIndex - nStart < wCountM && nIndex < nLen) {
621 if (!XFA_IsDigit(pDate[nIndex])) {
622 return FALSE;
623 }
624 wMonth = (pDate[nIndex] - '0') + wMonth * 10;
625 nIndex++;
626 }
627 if (bSymbol) {
628 if (pDate[nIndex] != 0x2D) {
629 return FALSE;
630 }
631 nIndex++;
632 }
633 nStart = nIndex;
634 while (pDate[nIndex] != '\0' && nIndex - nStart < wCountD && nIndex < nLen) {
635 if (!XFA_IsDigit(pDate[nIndex])) {
636 return FALSE;
637 }
638 wDay = (pDate[nIndex] - '0') + wDay * 10;
639 nIndex++;
640 }
641 if (nIndex != nLen) {
642 return FALSE;
643 }
644 if (wYear < 1900 || wYear > 2029) {
645 return FALSE;
646 }
647 if (wMonth < 1 || wMonth > 12) {
648 if (wMonth == 0 && nLen == wCountY) {
649 return TRUE;
650 }
651 return FALSE;
652 }
653 if (wDay < 1) {
654 if (wDay == 0 && (nLen == wCountY + wCountM)) {
655 return TRUE;
656 }
657 return FALSE;
658 }
659 if (wMonth == 2) {
660 if (wYear % 400 == 0 || (wYear % 100 != 0 && wYear % 4 == 0)) {
661 if (wDay > 29) {
662 return FALSE;
663 }
664 } else {
665 if (wDay > 28) {
666 return FALSE;
667 }
668 }
669 } else if (wDay > LastDay[wMonth - 1]) {
670 return FALSE;
671 }
672 CFX_Unitime ut;
673 ut.Set(wYear, static_cast<uint8_t>(wMonth), static_cast<uint8_t>(wDay));
674 unDate = unDate + ut;
675 return TRUE;
676 }
677 FX_BOOL CXFA_LocaleValue::ValidateCanonicalTime(const CFX_WideString& wsTime) {
678 int nLen = wsTime.GetLength();
679 if (nLen < 2)
680 return FALSE;
681 const FX_WORD wCountH = 2;
682 const FX_WORD wCountM = 2;
683 const FX_WORD wCountS = 2;
684 const FX_WORD wCountF = 3;
685 const bool bSymbol = wsTime.Find(':') != -1;
686 FX_WORD wHour = 0;
687 FX_WORD wMinute = 0;
688 FX_WORD wSecond = 0;
689 FX_WORD wFraction = 0;
690 const FX_WCHAR* pTime = (const FX_WCHAR*)wsTime;
691 int nIndex = 0;
692 int nStart = 0;
693 while (nIndex - nStart < wCountH && pTime[nIndex]) {
694 if (!XFA_IsDigit(pTime[nIndex]))
695 return FALSE;
696 wHour = pTime[nIndex] - '0' + wHour * 10;
697 nIndex++;
698 }
699 if (bSymbol) {
700 if (nIndex < nLen && pTime[nIndex] != ':')
701 return FALSE;
702 nIndex++;
703 }
704 nStart = nIndex;
705 while (nIndex - nStart < wCountM && nIndex < nLen && pTime[nIndex]) {
706 if (!XFA_IsDigit(pTime[nIndex]))
707 return FALSE;
708 wMinute = pTime[nIndex] - '0' + wMinute * 10;
709 nIndex++;
710 }
711 if (bSymbol) {
712 if (nIndex < nLen && pTime[nIndex] != ':')
713 return FALSE;
714 nIndex++;
715 }
716 nStart = nIndex;
717 while (nIndex - nStart < wCountS && nIndex < nLen && pTime[nIndex]) {
718 if (!XFA_IsDigit(pTime[nIndex]))
719 return FALSE;
720 wSecond = pTime[nIndex] - '0' + wSecond * 10;
721 nIndex++;
722 }
723 if (wsTime.Find('.') > 0) {
724 if (pTime[nIndex] != '.')
725 return FALSE;
726 nIndex++;
727 nStart = nIndex;
728 while (nIndex - nStart < wCountF && nIndex < nLen && pTime[nIndex]) {
729 if (!XFA_IsDigit(pTime[nIndex]))
730 return FALSE;
731 wFraction = pTime[nIndex] - '0' + wFraction * 10;
732 nIndex++;
733 }
734 }
735 if (nIndex < nLen) {
736 if (pTime[nIndex] == 'Z') {
737 nIndex++;
738 } else if (pTime[nIndex] == '-' || pTime[nIndex] == '+') {
739 int16_t nOffsetH = 0;
740 int16_t nOffsetM = 0;
741 nIndex++;
742 nStart = nIndex;
743 while (nIndex - nStart < wCountH && nIndex < nLen && pTime[nIndex]) {
744 if (!XFA_IsDigit(pTime[nIndex]))
745 return FALSE;
746 nOffsetH = pTime[nIndex] - '0' + nOffsetH * 10;
747 nIndex++;
748 }
749 if (bSymbol) {
750 if (nIndex < nLen && pTime[nIndex] != ':')
751 return FALSE;
752 nIndex++;
753 }
754 nStart = nIndex;
755 while (nIndex - nStart < wCountM && nIndex < nLen && pTime[nIndex]) {
756 if (!XFA_IsDigit(pTime[nIndex]))
757 return FALSE;
758 nOffsetM = pTime[nIndex] - '0' + nOffsetM * 10;
759 nIndex++;
760 }
761 if (nOffsetH > 12 || nOffsetM >= 60)
762 return FALSE;
763 }
764 }
765 return nIndex == nLen && wHour < 24 && wMinute < 60 && wSecond < 60 &&
766 wFraction <= 999;
767 }
768 FX_BOOL CXFA_LocaleValue::ValidateCanonicalDateTime(
769 const CFX_WideString& wsDateTime) {
770 CFX_WideString wsDate, wsTime;
771 if (wsDateTime.IsEmpty()) {
772 return FALSE;
773 }
774 int nSplitIndex = -1;
775 nSplitIndex = wsDateTime.Find('T');
776 if (nSplitIndex < 0) {
777 nSplitIndex = wsDateTime.Find(' ');
778 }
779 if (nSplitIndex < 0) {
780 return FALSE;
781 }
782 wsDate = wsDateTime.Left(nSplitIndex);
783 wsTime = wsDateTime.Right(wsDateTime.GetLength() - nSplitIndex - 1);
784 CFX_Unitime dt;
785 return ValidateCanonicalDate(wsDate, dt) && ValidateCanonicalTime(wsTime);
786 }
787 FX_BOOL CXFA_LocaleValue::ParsePatternValue(const CFX_WideString& wsValue,
788 const CFX_WideString& wsPattern,
789 IFX_Locale* pLocale) {
790 IFX_Locale* locale = m_pLocaleMgr->GetDefLocale();
791 if (pLocale) {
792 m_pLocaleMgr->SetDefLocale(pLocale);
793 }
794 IFX_FormatString* pFormat = IFX_FormatString::Create(m_pLocaleMgr, FALSE);
795 CFX_WideStringArray wsPatterns;
796 pFormat->SplitFormatString(wsPattern, wsPatterns);
797 FX_BOOL bRet = FALSE;
798 int32_t iCount = wsPatterns.GetSize();
799 for (int32_t i = 0; i < iCount && !bRet; i++) {
800 CFX_WideString wsFormat = wsPatterns[i];
801 FX_LOCALECATEGORY eCategory = pFormat->GetCategory(wsFormat);
802 eCategory = XFA_ValugeCategory(eCategory, m_dwType);
803 switch (eCategory) {
804 case FX_LOCALECATEGORY_Null:
805 bRet = pFormat->ParseNull(wsValue, wsFormat);
806 if (bRet) {
807 m_wsValue.Empty();
808 }
809 break;
810 case FX_LOCALECATEGORY_Zero:
811 bRet = pFormat->ParseZero(wsValue, wsFormat);
812 if (bRet) {
813 m_wsValue = FX_WSTRC(L"0");
814 }
815 break;
816 case FX_LOCALECATEGORY_Num: {
817 CFX_WideString fNum;
818 bRet = pFormat->ParseNum(wsValue, wsFormat, fNum);
819 if (bRet) {
820 m_wsValue = fNum;
821 }
822 break;
823 }
824 case FX_LOCALECATEGORY_Text:
825 bRet = pFormat->ParseText(wsValue, wsFormat, m_wsValue);
826 break;
827 case FX_LOCALECATEGORY_Date: {
828 CFX_Unitime dt;
829 bRet = ValidateCanonicalDate(wsValue, dt);
830 if (!bRet) {
831 bRet = pFormat->ParseDateTime(wsValue, wsFormat, FX_DATETIMETYPE_Date,
832 dt);
833 }
834 if (bRet) {
835 SetDate(dt);
836 }
837 break;
838 }
839 case FX_LOCALECATEGORY_Time: {
840 CFX_Unitime dt;
841 bRet =
842 pFormat->ParseDateTime(wsValue, wsFormat, FX_DATETIMETYPE_Time, dt);
843 if (bRet) {
844 SetTime(dt);
845 }
846 break;
847 }
848 case FX_LOCALECATEGORY_DateTime: {
849 CFX_Unitime dt;
850 bRet = pFormat->ParseDateTime(wsValue, wsFormat,
851 FX_DATETIMETYPE_DateTime, dt);
852 if (bRet) {
853 SetDateTime(dt);
854 }
855 break;
856 }
857 default:
858 m_wsValue = wsValue;
859 bRet = TRUE;
860 break;
861 }
862 }
863 if (!bRet) {
864 m_wsValue = wsValue;
865 }
866 pFormat->Release();
867 if (pLocale) {
868 m_pLocaleMgr->SetDefLocale(locale);
869 }
870 return bRet;
871 }
872 void CXFA_LocaleValue::GetNumbericFormat(CFX_WideString& wsFormat,
873 int32_t nIntLen,
874 int32_t nDecLen,
875 FX_BOOL bSign) {
876 FXSYS_assert(wsFormat.IsEmpty());
877 FXSYS_assert(nIntLen >= -1 && nDecLen >= -1);
878 int32_t nTotalLen = (nIntLen >= 0 ? nIntLen : 2) + (bSign ? 1 : 0) +
879 (nDecLen >= 0 ? nDecLen : 2) + (nDecLen == 0 ? 0 : 1);
880 FX_WCHAR* lpBuf = wsFormat.GetBuffer(nTotalLen);
881 int32_t nPos = 0;
882 if (bSign) {
883 lpBuf[nPos++] = L's';
884 }
885 if (nIntLen == -1) {
886 lpBuf[nPos++] = L'z';
887 lpBuf[nPos++] = L'*';
888 } else {
889 while (nIntLen) {
890 lpBuf[nPos++] = L'z';
891 nIntLen--;
892 }
893 }
894 if (nDecLen != 0) {
895 lpBuf[nPos++] = L'.';
896 }
897 if (nDecLen == -1) {
898 lpBuf[nPos++] = L'z';
899 lpBuf[nPos++] = L'*';
900 } else {
901 while (nDecLen) {
902 lpBuf[nPos++] = L'z';
903 nDecLen--;
904 }
905 }
906 wsFormat.ReleaseBuffer(nTotalLen);
907 }
908 FX_BOOL CXFA_LocaleValue::ValidateNumericTemp(CFX_WideString& wsNumeric,
909 CFX_WideString& wsFormat,
910 IFX_Locale* pLocale,
911 int32_t* pos) {
912 if (wsFormat.IsEmpty() || wsNumeric.IsEmpty()) {
913 return TRUE;
914 }
915 const FX_WCHAR* pNum = wsNumeric.c_str();
916 const FX_WCHAR* pFmt = wsFormat.c_str();
917 int32_t n = 0, nf = 0;
918 FX_WCHAR c = pNum[n];
919 FX_WCHAR cf = pFmt[nf];
920 if (cf == L's') {
921 if (c == L'-' || c == L'+') {
922 ++n;
923 }
924 ++nf;
925 }
926 FX_BOOL bLimit = TRUE;
927 int32_t nCount = wsNumeric.GetLength();
928 int32_t nCountFmt = wsFormat.GetLength();
929 while (n < nCount && (bLimit ? nf < nCountFmt : TRUE) &&
930 XFA_IsDigit(c = pNum[n])) {
931 if (bLimit == TRUE) {
932 if ((cf = pFmt[nf]) == L'*') {
933 bLimit = FALSE;
934 } else if (cf == L'z') {
935 nf++;
936 } else {
937 return FALSE;
938 }
939 }
940 n++;
941 }
942 if (n == nCount) {
943 return TRUE;
944 }
945 if (nf == nCountFmt) {
946 return FALSE;
947 }
948 while (nf < nCountFmt && (cf = pFmt[nf]) != L'.') {
949 FXSYS_assert(cf == L'z' || cf == L'*');
950 ++nf;
951 }
952 CFX_WideString wsDecimalSymbol;
953 if (pLocale) {
954 pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Decimal, wsDecimalSymbol);
955 } else {
956 wsDecimalSymbol = CFX_WideString(L'.');
957 }
958 if (pFmt[nf] != L'.') {
959 return FALSE;
960 }
961 if (wsDecimalSymbol != CFX_WideStringC(c) && c != L'.') {
962 return FALSE;
963 }
964 ++nf;
965 ++n;
966 bLimit = TRUE;
967 while (n < nCount && (bLimit ? nf < nCountFmt : TRUE) &&
968 XFA_IsDigit(c = pNum[n])) {
969 if (bLimit == TRUE) {
970 if ((cf = pFmt[nf]) == L'*') {
971 bLimit = FALSE;
972 } else if (cf == L'z') {
973 nf++;
974 } else {
975 return FALSE;
976 }
977 }
978 n++;
979 }
980 return n == nCount;
981 }
OLDNEW
« no previous file with comments | « xfa/src/fxfa/parser/xfa_localevalue.h ('k') | xfa/src/fxfa/parser/xfa_object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698