Merge "Revert "Fix prevent defect for locales"" into devel_3.0_main
[platform/framework/native/appfw.git] / src / base / utility / FBaseUtil_ScannerImpl.cpp
1 #include <sys/stat.h>
2 #include <stdio.h>
3 #include <errno.h>
4 #include <wchar.h>
5
6 #include <FBaseCharacter.h>
7 #include <FBaseInt8.h>
8 #include <FBaseInteger.h>
9 #include <FBaseShort.h>
10 #include <FBaseLong.h>
11 #include <FBaseLongLong.h>
12 #include <FBaseFloat.h>
13 #include <FBaseDouble.h>
14 #include <FBaseResult.h>
15 #include "FBaseUtil_ScannerImpl.h"
16 #include "FBaseUtilRegularExpression.h"
17 #include <FBaseColArrayList.h>
18 #include <FBaseSysLog.h>
19 #include "FBaseUtil_RegularExpressionImpl.h"
20 #include "FBase_StringConverter.h"
21 #include "FBaseUtil_IcuConverter.h"
22 #include "FBase_NativeError.h"
23
24 #define ANY_PATTERN L"\\s*[^\\s]*"
25 #define DEFAULT_DELIMITER_PATTERN L"\\s+"
26 #define DEFAULT_DELIMITER_PATTERN_ZERO_OR_MORE L"\\s*"
27 #define COMPLETE_LINE_PATTERN L".*(\r\n|[\u000A\n\r\u2028\u2029\u0085])|.+$"
28 #define DEFAULT_LINE_SEPARATOR_PATTERN L"[\u000A\n\r\u2028\u2029\u0085]*"
29
30
31 #define DEFAULT_GROUP_SEPARATOR L","
32 #define DEFAULT_DECIMAL_SEPARATOR L"."
33 #define DEFAULT_NEGATIVE_PREFIX L"-"
34
35 using namespace Tizen::Base::Collection;
36 using namespace Tizen::Base::Utility;
37 using namespace Tizen::Base;
38
39 namespace Tizen { namespace Base { namespace Utility
40 {
41 _ScannerImpl::_ScannerImpl(void)
42         :__radix(10),
43          __delimiter(DEFAULT_DELIMITER_PATTERN),
44          __pParseStr(null),
45          __isAllocatedOnHeap(false),
46          __position(0)
47 {
48
49 }
50
51 _ScannerImpl::~_ScannerImpl()
52 {
53         if(__isAllocatedOnHeap == true)
54         {
55                 delete[] __pParseStr;
56                 __pParseStr = null;
57         }
58 }
59
60 result _ScannerImpl::Construct(const String& str)
61 {
62         result r = E_SUCCESS;
63         __pParseStr = str.GetPointer();
64         return r;
65 }
66
67 result _ScannerImpl::Construct(const String& filePath, const String& encodingScheme)
68 {
69         result r = E_SUCCESS;
70         FILE* pFile = null;
71         char* pFilePath = null;
72         bool res =  false;
73         _ICUConverter converter;
74         struct stat st;
75         off_t fileSize = 0;
76         char* buffer = null;
77         int retVal = 0;
78         long int readCnt = 0;
79
80         pFilePath = _StringConverter::CopyToCharArrayN(filePath);
81         SysTryReturnResult(NID_BASE_UTIL, pFilePath != null, GetLastResult(), "File path length < 0 or E_OUT_OF_MEMORY");
82
83         res = converter.OpenConverter(encodingScheme);
84         r = GetLastResult();
85         SysTryCatch(NID_BASE_UTIL, res == true, , r, "[%s] Encoding scheme not supported", GetErrorMessage(r));
86
87         pFile = fopen(pFilePath, "r");
88         SysTryCatch(NID_BASE_UTIL, pFile != null, r = E_FILE_NOT_FOUND, E_FILE_NOT_FOUND,
89                         "[%s] Failed to open the file.", GetErrorMessage(__ConvertNativeErrorToResult(errno)));
90
91         retVal = stat(pFilePath, &st);
92         SysTryCatch(NID_BASE_UTIL, retVal == 0, r = E_IO, E_IO,
93                         "[%s] Failed to get information about the file.", GetErrorMessage(__ConvertNativeErrorToResult(errno)));
94
95         fileSize = st.st_size + 1;      // +1 for null-terminated string
96
97         buffer = static_cast<char*>(calloc(fileSize, sizeof(char)));
98         SysTryCatch(NID_BASE_UTIL, buffer != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY]");
99         readCnt = fread(buffer, 1, fileSize - 1, pFile);
100
101         if (readCnt < fileSize)
102         {
103                 int ret = ferror(pFile);
104                 SysTryCatch(NID_BASE_UTIL, ret == 0, r = E_IO, E_IO, "[%s] Failed to perform read operation.", GetErrorMessage(E_IO));
105         }
106
107         __pParseStr = converter.ConvertToUcharN(buffer, fileSize);
108         SysTryCatch(NID_BASE_UTIL, __pParseStr != null, r = E_IO, E_IO , "[%s] charcater conversion failed.", GetErrorMessage(E_IO));
109         __isAllocatedOnHeap = true;
110
111 CATCH:
112         delete[] pFilePath;
113         pFilePath = null;
114
115         delete[] buffer;
116         buffer = null;
117
118         if(pFile != null)
119         {
120                 fclose(pFile);
121                 pFile = null;
122         }
123
124         return r;
125 }
126
127 bool _ScannerImpl::HasNextToken(void)
128 {
129         String token;
130         int length = 0;
131
132         result r = GetNextTokenWithoutPattern(token, length);
133         SysTryLogReturn(NID_BASE_UTIL, r == E_SUCCESS, false, "Can not get the next token");
134
135         return true;
136 }
137
138 bool _ScannerImpl::HasNextToken(const RegularExpression& pattern)
139 {
140         String patStr(pattern.GetPattern());
141         return HasNextToken(patStr);
142 }
143
144 bool _ScannerImpl::HasNextToken(const String& pattern)
145 {
146         RegularExpression regex;
147         ArrayList matchedStrList;
148         int length = 0;
149         String out;
150
151         result r = GetNextTokenWithoutPattern(out, length);
152         SysTryLogReturn(NID_BASE_UTIL, r != E_DATA_NOT_ENOUGH, false, "Input has no remaining tokens");
153
154         SysTryLogReturn(NID_BASE_UTIL, r == E_SUCCESS, false, "The next token does not match to the pattern");
155
156         r = regex.Construct(pattern, REGEX_UNICODE);
157         SysTryLogReturn(NID_BASE_UTIL, r == E_SUCCESS, false, "Regular expression construction failed");
158
159         r = matchedStrList.Construct();
160         SysTryLogReturn(NID_BASE_UTIL, r == E_SUCCESS, false, "Arraylist construction failed");
161
162         bool res = regex.Match(out, true, &matchedStrList);
163         SysTryLogReturn(NID_BASE_UTIL, res, res, "Match Failed");
164
165         return true;
166 }
167
168
169 result _ScannerImpl::GetNextToken(String& nextStr)
170 {
171         int length = 0;
172
173         result r = GetNextTokenWithoutPattern(nextStr, length);
174         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, E_DATA_NOT_ENOUGH, "Can not get the next token");
175
176         __position =  __position + length;
177
178         return r;
179 }
180
181 result _ScannerImpl::GetNextToken(const RegularExpression& pattern, String& nextStr)
182 {
183         String patStr(pattern.GetPattern());
184         return GetNextToken(patStr, nextStr);
185 }
186
187 result _ScannerImpl::GetNextToken(const String& pattern, String& nextStr)
188 {
189         RegularExpression regex;
190         ArrayList matchedStrList;
191         int length = 0;
192         String out;
193
194         result r = GetNextTokenWithoutPattern(out, length);
195         SysTryReturnResult(NID_BASE_UTIL, r != E_DATA_NOT_ENOUGH, E_DATA_NOT_ENOUGH, "Input has no remaining tokens");
196
197         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, E_DATA_NOT_FOUND, "The next token does not match to the pattern");
198
199         r = regex.Construct(pattern, REGEX_UNICODE);
200         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, E_DATA_NOT_FOUND, "Regular expression construction failed");
201
202         r = matchedStrList.Construct();
203         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, E_DATA_NOT_FOUND, "Arraylist construction failed");
204
205         bool res = regex.Match(out, true, &matchedStrList);
206         SysTryReturnResult(NID_BASE_UTIL, res, E_DATA_NOT_FOUND, "Match Failed");
207
208         nextStr = out;
209         __position =  __position + length;
210         return E_SUCCESS;
211 }
212
213 result _ScannerImpl::GetNextSignedChar(signed char& nextSignedChar)
214 {
215         return GetNextSignedChar(nextSignedChar, __radix);
216 }
217
218 result _ScannerImpl::GetNextSignedChar(signed char& nextSignedChar, int radix)
219 {
220         String out;
221         int length = 0;
222         char ch = 0x00;
223
224         result r = GetNextTokenWithoutPattern(out, length);
225         SysTryReturnResult(NID_BASE_UTIL, r != E_DATA_NOT_ENOUGH, E_DATA_NOT_ENOUGH, "Input has no remaining tokens");
226         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, E_NUM_FORMAT, "Can not parse the token to signed char");
227
228         r = Int8::Parse(out, radix, ch);
229         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, E_NUM_FORMAT, "Can not parse the token to signed char");
230
231         nextSignedChar = static_cast<signed char>(ch);
232         __position =  __position + length;
233
234         return r;
235 }
236
237 bool _ScannerImpl::IsNextTokenConvertibleToSignedChar(void)
238 {
239         return IsNextTokenConvertibleToSignedChar(__radix);
240 }
241
242 bool _ScannerImpl::IsNextTokenConvertibleToSignedChar(int radix)
243 {
244         String out;
245         int length = 0;
246         char ch = 0;
247
248         result r = GetNextTokenWithoutPattern(out, length);
249         SysTryReturn(NID_BASE_UTIL, r == E_SUCCESS, false, E_NUM_FORMAT, "[%s] Can not get the next token as signed char", GetErrorMessage(E_NUM_FORMAT));
250
251         r = Int8::Parse(out, radix, ch);
252         SysTryReturn(NID_BASE_UTIL, r == E_SUCCESS, false, E_NUM_FORMAT, "[%s] Can not parse the token to signed char", GetErrorMessage(E_NUM_FORMAT));
253
254         return true;
255 }
256
257 result _ScannerImpl::GetNextInt(int& nextInt)
258 {
259         return GetNextInt(nextInt, __radix);
260 }
261
262 result _ScannerImpl::GetNextInt(int& nextInt, int radix)
263 {
264         String out;
265         int length = 0;
266
267         result r = GetNextTokenWithoutPattern(out, length);
268         SysTryReturnResult(NID_BASE_UTIL, r != E_DATA_NOT_ENOUGH, E_DATA_NOT_ENOUGH, "Input has no remaining tokens");
269         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, E_NUM_FORMAT, "Can not parse the token to integer");
270
271         out.Replace(DEFAULT_GROUP_SEPARATOR, L"");
272         r = Integer::Parse(out, radix, nextInt);
273         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, E_NUM_FORMAT, "Can not parse the token to integer");
274
275         __position =  __position + length;
276
277         return r;
278 }
279
280 bool _ScannerImpl::IsNextTokenConvertibleToInt(void)
281 {
282         return IsNextTokenConvertibleToInt(__radix);
283 }
284
285 bool _ScannerImpl::IsNextTokenConvertibleToInt(int radix)
286 {
287         String out;
288         int val = 0;
289         int length = 0;
290
291         result r = GetNextTokenWithoutPattern(out, length);
292         SysTryReturn(NID_BASE_UTIL, r == E_SUCCESS, false, E_NUM_FORMAT, "[%s] Can not get the next token as integer", GetErrorMessage(E_NUM_FORMAT));
293
294         out.Replace(DEFAULT_GROUP_SEPARATOR, L"");
295         r = Integer::Parse(out, radix, val);
296         SysTryReturn(NID_BASE_UTIL, r == E_SUCCESS, false, E_NUM_FORMAT, "[%s] Can not get next Integer", GetErrorMessage(E_NUM_FORMAT));
297
298         return true;
299 }
300
301 result _ScannerImpl::GetNextShort(short& nextShort)
302 {
303         return GetNextShort(nextShort, __radix);
304 }
305
306 result _ScannerImpl::GetNextShort(short& nextShort, int radix)
307 {
308         String out;
309         int length = 0;
310
311         result r = GetNextTokenWithoutPattern(out, length);
312         SysTryReturnResult(NID_BASE_UTIL, r != E_DATA_NOT_ENOUGH, E_DATA_NOT_ENOUGH, "Input has no remaining tokens");
313         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, E_NUM_FORMAT, "Can not parse the token to short");
314
315         out.Replace(DEFAULT_GROUP_SEPARATOR, L"");
316         r = Short::Parse(out, radix, nextShort);
317         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, E_NUM_FORMAT, "Can not parse the token to short");
318
319         __position =  __position + length;
320
321         return r;
322 }
323
324 bool _ScannerImpl::IsNextTokenConvertibleToShort(void)
325 {
326         return IsNextTokenConvertibleToShort(__radix);
327 }
328
329 bool _ScannerImpl::IsNextTokenConvertibleToShort(int radix)
330 {
331         String out;
332         short val = 0;
333         int length = 0;
334
335         result r = GetNextTokenWithoutPattern(out, length);
336         SysTryReturn(NID_BASE_UTIL, r == E_SUCCESS, false, E_NUM_FORMAT, "[%s] Can not get next token as short", GetErrorMessage(E_NUM_FORMAT));
337
338         out.Replace(DEFAULT_GROUP_SEPARATOR, L"");
339         r = Short::Parse(out, radix, val);
340         SysTryReturn(NID_BASE_UTIL, r == E_SUCCESS, false, E_NUM_FORMAT, "[%s] Can not get next short", GetErrorMessage(E_NUM_FORMAT));
341
342         return true;
343 }
344
345 result _ScannerImpl::GetNextLongLong(long long& nextLongLong)
346 {
347         return GetNextLongLong(nextLongLong, __radix);
348 }
349
350 result _ScannerImpl::GetNextLongLong(long long& nextLongLong, int radix)
351 {
352         String out;
353         int length = 0;
354
355         result r = GetNextTokenWithoutPattern(out, length);
356         SysTryReturnResult(NID_BASE_UTIL, r != E_DATA_NOT_ENOUGH, E_DATA_NOT_ENOUGH, "Input has no remaining tokens");
357         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, E_NUM_FORMAT, "Can not parse the token to long long");
358
359         out.Replace(DEFAULT_GROUP_SEPARATOR, L"");
360         r = LongLong::Parse(out, radix, nextLongLong);
361         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, E_NUM_FORMAT, "Can not parse the token to long long");
362
363         __position =  __position + length;
364
365         return r;
366 }
367
368 bool _ScannerImpl::IsNextTokenConvertibleToLongLong(void)
369 {
370         String out;
371         long long val = 0;
372         int length = 0;
373
374         result r = GetNextTokenWithoutPattern(out, length);
375         SysTryReturn(NID_BASE_UTIL, r == E_SUCCESS, false, E_NUM_FORMAT, "[E_NUM_FORMAT] Can not get next token as long long");
376
377         r = LongLong::Parse(out, val);
378         SysTryReturn(NID_BASE_UTIL, r == E_SUCCESS, false, E_NUM_FORMAT, "[E_NUM_FORMAT] Can not get next long long");
379
380         return true;
381 }
382
383 result _ScannerImpl::GetNextFloat(float& nextFloat)
384 {
385         String out;
386         int length = 0;
387
388         result r = GetNextTokenWithoutPattern(out, length);
389         SysTryReturnResult(NID_BASE_UTIL, r != E_DATA_NOT_ENOUGH, E_DATA_NOT_ENOUGH, "Input has no remaining tokens");
390         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, E_NUM_FORMAT, "Can not parse the token to float");
391
392         out.Replace(DEFAULT_GROUP_SEPARATOR, L"");
393         r = Float::Parse(out, nextFloat);
394         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, E_NUM_FORMAT, "Can not parse the token to float");
395
396         __position =  __position + length;
397
398         return r;
399 }
400
401
402 bool _ScannerImpl::IsNextTokenConvertibleToFloat(void)
403 {
404         String out;
405         RegularExpression re;
406         float val = 0.0f;
407         int length = 0;
408
409         result r = GetNextTokenWithoutPattern(out, length);
410         SysTryReturn(NID_BASE_UTIL, r == E_SUCCESS, false, E_NUM_FORMAT, "[%s] Can not get next token as float", GetErrorMessage(E_NUM_FORMAT));
411
412         out.Replace(DEFAULT_GROUP_SEPARATOR, L"");
413         r = Float::Parse(out, val);
414         SysTryReturn(NID_BASE_UTIL, r == E_SUCCESS, false, E_NUM_FORMAT, "[%s] Can not get next float", GetErrorMessage(E_NUM_FORMAT));
415
416         return true;
417 }
418
419 result _ScannerImpl::GetNextDouble(double& nextDouble)
420 {
421         String out;
422         int length = 0;
423
424         result r = GetNextTokenWithoutPattern(out, length);
425         SysTryReturnResult(NID_BASE_UTIL, r != E_DATA_NOT_ENOUGH, E_DATA_NOT_ENOUGH, "Input has no remaining tokens");
426         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, E_NUM_FORMAT, "Can not parse the token to double");
427
428         out.Replace(DEFAULT_GROUP_SEPARATOR, L"");
429         r = Double::Parse(out, nextDouble);
430         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, E_NUM_FORMAT, "Can not parse the token to double");
431
432         __position =  __position + length;
433
434         return r;
435 }
436
437 bool _ScannerImpl::IsNextTokenConvertibleToDouble(void)
438 {
439         String out;
440         double val = 0.0f;
441         int length = 0;
442
443         result r = GetNextTokenWithoutPattern(out, length);
444         SysTryReturn(NID_BASE_UTIL, r == E_SUCCESS, false, E_NUM_FORMAT, "[%s] Can not get next token as double", GetErrorMessage(E_NUM_FORMAT));
445
446         out.Replace(DEFAULT_GROUP_SEPARATOR, L"");
447         r = Double::Parse(out, val);
448         SysTryReturn(NID_BASE_UTIL, r == E_SUCCESS, false, E_NUM_FORMAT, "[%s] Can not get next token", GetErrorMessage(E_NUM_FORMAT));
449
450         return true;
451 }
452
453 result _ScannerImpl::GetNextBool(bool& nextBool)
454 {
455         String out;
456         int length = 0;
457
458         result r = GetNextTokenWithoutPattern(out, length);
459         SysTryReturnResult(NID_BASE_UTIL, r != E_DATA_NOT_ENOUGH, E_DATA_NOT_ENOUGH, "Input has no remaining tokens");
460         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, E_NUM_FORMAT, "Can not parse the token to bool");
461
462         String temp;
463         r = out.ToUpper(temp);
464         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, E_NUM_FORMAT, "Can not get next bool");
465
466         if(!temp.CompareTo(L"TRUE"))
467         {
468                 nextBool = true;
469                 __position =  __position + length;
470         }
471         else if(!temp.CompareTo(L"FALSE"))
472         {
473                 nextBool = false;
474                 __position =  __position + length;
475         }
476         else
477         {
478                 r =  E_NUM_FORMAT;
479         }
480
481         return r;
482 }
483
484 bool _ScannerImpl::IsNextTokenConvertibleToBool(void)
485 {
486         String out;
487         int length = 0;
488
489         result r = GetNextTokenWithoutPattern(out, length);
490         SysTryReturn(NID_BASE_UTIL, r == E_SUCCESS, false, E_NUM_FORMAT, "[%s] Can not get next token as bool", GetErrorMessage(E_NUM_FORMAT));
491
492         String temp;
493         out.ToUpper(temp);
494         return ((!temp.CompareTo(L"TRUE")) || (!temp.CompareTo(L"FALSE")));
495 }
496
497 bool _ScannerImpl::HasNextLine(void)
498 {
499         String pattern(DEFAULT_LINE_SEPARATOR_PATTERN);
500         RegularExpression regex;
501         ArrayList matchedStrList;
502
503         result r = regex.Construct(pattern, REGEX_UNICODE);
504         SysTryReturn(NID_BASE_UTIL, r == E_SUCCESS, false, E_DATA_NOT_ENOUGH, "[%s] Regular expression construction failed", GetErrorMessage(E_DATA_NOT_ENOUGH));
505
506         r = matchedStrList.Construct();
507         SysTryReturn(NID_BASE_UTIL, r == E_SUCCESS, false, E_DATA_NOT_ENOUGH, "[%s] Arraylist construction failed", GetErrorMessage(E_DATA_NOT_ENOUGH));
508
509         bool res = regex.Match(String(__pParseStr + __position), false, &matchedStrList);
510         SysTryReturn(NID_BASE_UTIL, res == true, false, E_DATA_NOT_ENOUGH, "[%s] Match Failed", GetErrorMessage(E_DATA_NOT_ENOUGH));
511
512         return res;
513 }
514
515
516 result _ScannerImpl::GetNextLine(String& nextLine)
517 {
518         String pattern(COMPLETE_LINE_PATTERN);
519         RegularExpression regex;
520         ArrayList matchedStrList;
521
522         result r = regex.Construct(pattern, REGEX_UNICODE);
523         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, E_DATA_NOT_ENOUGH, "Regular expression construction failed");
524
525         r = matchedStrList.Construct();
526         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, E_DATA_NOT_ENOUGH, "Arraylist construction failed");
527
528         bool res = regex.Match(String(__pParseStr + __position), false, &matchedStrList);
529         SysTryReturnResult(NID_BASE_UTIL, res == true, E_DATA_NOT_ENOUGH, "Match Failed");
530
531         int matches = matchedStrList.GetCount();
532         SysTryReturnResult(NID_BASE_UTIL,matches > 0, E_DATA_NOT_FOUND, "Match Failed");
533         
534         String temp = *(String *)matchedStrList.GetAt(0);
535         __position = __position + temp.GetLength();
536
537         RegularExpression re;
538         r = re.Construct(DEFAULT_LINE_SEPARATOR_PATTERN, REGEX_UNICODE);
539         re.Replace(temp, L"", true);
540         nextLine = temp;
541         matchedStrList.RemoveAll();
542
543         return E_SUCCESS;
544 }
545
546 result _ScannerImpl::FindInLine(const String& str, String& MatchedStr)
547 {
548         _RegularExpressionImpl regex;
549         ArrayList matchedStrList;
550
551         result r = regex.Construct(str, REGEX_UNICODE);
552         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, E_DATA_NOT_FOUND, "Regular expression construction failed");
553
554         r = matchedStrList.Construct();
555         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, E_DATA_NOT_FOUND, "Arraylist construction failed");
556
557         bool res = regex.Match(String(__pParseStr + __position), false, &matchedStrList);
558         SysTryReturnResult(NID_BASE_UTIL, res == true, E_DATA_NOT_FOUND, "Match Failed");
559
560         int matches = matchedStrList.GetCount();
561         SysTryReturnResult(NID_BASE_UTIL,matches > 0, E_DATA_NOT_FOUND, "Match Failed");
562
563         MatchedStr = *(String *)matchedStrList.GetAt(0);
564         int matchEnd = regex.GetLastMatchEnd();
565         __position = __position + matchEnd;
566         matchedStrList.RemoveAll();
567
568         return E_SUCCESS;
569 }
570
571 result _ScannerImpl::FindInLine(const RegularExpression& pattern, String& MatchedStr)
572 {
573         String patStr(pattern.GetPattern());
574         return FindInLine(patStr, MatchedStr);
575 }
576
577 void _ScannerImpl::Skip(const String& str)
578 {
579         RegularExpression regex;
580         ArrayList matchedStrList;
581         String inputStr(__pParseStr + __position);
582
583         result r = regex.Construct(str, REGEX_UNICODE);
584         SysTryReturnVoidResult(NID_BASE_UTIL, r == E_SUCCESS, r,"Regular expression construction failed");
585
586         r = matchedStrList.Construct();
587         SysTryReturnVoidResult(NID_BASE_UTIL, r == E_SUCCESS, r, "ArrayList construction failed");
588
589         bool res = regex.Match(inputStr, false, &matchedStrList);
590         SysTryReturnVoidResult(NID_BASE_UTIL, res == true, E_SYSTEM, "Regular expression match failed");
591
592         int matches = matchedStrList.GetCount();
593         SysTryReturnVoidResult(NID_BASE_UTIL, matches > 0, E_SYSTEM,"Regular expression construction failed");
594
595         String skipToken = *(dynamic_cast< String* >(matchedStrList.GetAt(0)));
596         int length = skipToken.GetLength();
597         const wchar_t* wstr1 = skipToken.GetPointer();
598         const wchar_t* wstr2 = __pParseStr + __position;
599         bool isSame = true;
600
601         while (*wstr1 != 0x0000)
602         {
603                 if (*wstr1++ != *wstr2++)
604                 {
605                         isSame =  false;
606                         break;
607                 }
608         }
609         if (isSame)
610         {
611                 __position = __position + length;
612         }
613         matchedStrList.RemoveAll();
614
615         //Skip if there is any delimiters before the next token
616         RegularExpression re;
617         if (__delimiter == DEFAULT_DELIMITER_PATTERN)
618         {
619                 r = re.Construct(DEFAULT_DELIMITER_PATTERN_ZERO_OR_MORE, REGEX_UNICODE);
620         }
621         else
622         {
623                 r = re.Construct(__delimiter, REGEX_UNICODE);
624         }
625
626         res = re.Match(String(__pParseStr + __position), false, &matchedStrList);
627         matches = matchedStrList.GetCount();
628         if (matches > 0)
629         {
630                 String temp = *(dynamic_cast< String* >(matchedStrList.GetAt(0)));
631                 int length = temp.GetLength();
632                 __position = __position + length;
633                 matchedStrList.RemoveAll();
634         }
635
636 }
637
638 void _ScannerImpl::Skip(const RegularExpression& pattern)
639 {
640         String patStr(pattern.GetPattern());
641         return Skip(patStr);
642 }
643
644 int _ScannerImpl::GetRadix(void)
645 {
646         return __radix;
647 }
648
649 String _ScannerImpl::GetDelimiter(void)
650 {
651         return __delimiter;
652 }
653
654 void _ScannerImpl::SetDelimiter(const String& delimiter)
655 {
656         __delimiter = delimiter;
657 }
658
659 void _ScannerImpl::SetDelimiter(const RegularExpression& pattern)
660 {
661         __delimiter = pattern.GetPattern();
662 }
663
664 void _ScannerImpl::SetRadix(int radix)
665 {
666         if(((radix == Character::RADIX_BINARY) || (radix == Character::RADIX_OCTAL) ||
667                 (radix == Character::RADIX_DECIMAL) || (radix == Character::RADIX_HEXADECIMAL)))
668         {
669                 __radix = radix;
670         }
671 }
672
673
674 result _ScannerImpl::GetNextTokenWithoutPattern(String& ret, int& length)
675 {
676         SysTryReturnResult(NID_BASE_UTIL, ((__pParseStr + __position) != null) && ((*(__pParseStr + __position) != 0x0000)),
677                         E_DATA_NOT_ENOUGH, "Input has no remaining tokens.");
678
679         RegularExpression regDelim;
680         result r = regDelim.Construct(__delimiter, REGEX_UNICODE);
681         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, E_DATA_NOT_FOUND, "Regular expression construction failed");
682
683         ArrayList matchedStrList;
684         r = matchedStrList.Construct();
685         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, E_DATA_NOT_FOUND, "Arraylist construction failed");
686
687         String inputStr(__pParseStr + __position);
688         bool res = regDelim.Match(inputStr, false, &matchedStrList);
689
690         int matches = matchedStrList.GetCount();
691         if (matches > 0)
692         {
693                 String delimiter1 = *(dynamic_cast< String* >(matchedStrList.GetAt(0)));
694
695                 if (!delimiter1.IsEmpty())      // 1st delimiter is not empty
696                 {
697                         int delimLength1 = delimiter1.GetLength();
698                         int index1 = 0;
699                         inputStr.IndexOf(delimiter1, 0, index1);
700
701                         // When the delimiter exists in first position, find the 2nd delimiter
702                         if ((index1 == 0) && (__position == 0))
703                         {
704                                 length += delimLength1;
705                                 String tmpStr(__pParseStr + length);
706
707                                 matchedStrList.RemoveAll();
708                                 res = regDelim.Match(tmpStr, false, &matchedStrList);
709                                 matches = matchedStrList.GetCount();
710                                 if (matches > 0)
711                                 {
712                                         String delimiter2 = *(dynamic_cast< String* >(matchedStrList.GetAt(0)));
713
714                                         // If the 2nd delimiter is empty, the token will be one character followed by 1st delimiter.
715                                         if (delimiter2.IsEmpty())
716                                         {
717                                                 ret.Clear();
718                                                 ret.Append(*(__pParseStr + length));
719                                                 length += 1;
720                                                 // Though 2nd delimiter is empty, if 3rd non-empty delimiter exists right after the token, length to be moved should be added by 3rd delimiter.
721                                                 matchedStrList.RemoveAll();
722                                                 String tmpStr1(__pParseStr + length);
723                                                 res = regDelim.Match(tmpStr1, false, &matchedStrList);
724                                                 matches = matchedStrList.GetCount();
725                                                 SysTryReturnResult(NID_BASE_UTIL, matches > 0, E_SUCCESS, "It's a last token.");
726
727                                                 String delimiter3 = *(dynamic_cast< String* >(matchedStrList.GetAt(0)));
728                                                 int index3 = 0;
729                                                 tmpStr1.IndexOf(delimiter3, 0, index3);
730                                                 if (!delimiter3.IsEmpty() && index3 == 0)
731                                                 {
732                                                         length += delimiter3.GetLength();
733                                                 }
734                                         }
735                                         else
736                                         {
737                                                 int delimLength2 = delimiter2.GetLength();
738                                                 int index2 = 0;
739                                                 tmpStr.IndexOf(delimiter2, 0, index2);
740                                                 tmpStr.SubString(0, index2, ret);       // Extract the string in between first and second delimiter
741                                                 length += index2 + delimLength2;
742                                         }
743                                 }
744                         }
745                         else
746                         {
747                                 inputStr.SubString(0, index1, ret);
748                                 length = index1 + delimLength1;
749                         }
750                 }
751                 else    // 1st delimiter is empty
752                 {
753                         // Find 2nd delimiter from "__pParseStr + __position + 1"
754                         String tmpStr(__pParseStr + __position + 1);
755                         if (tmpStr == null)     // When InputStr is last token, extract the token.
756                         {
757                                 ret.Clear();
758                                 ret.Append(__pParseStr + __position);
759                                 length = ret.GetLength();
760                         }
761                         else
762                         {
763                                 matchedStrList.RemoveAll();
764                                 res = regDelim.Match(tmpStr, false, &matchedStrList);
765                                 matches = matchedStrList.GetCount();
766                                 if (matches > 0)
767                                 {
768                                         String delimiter2 = *(dynamic_cast< String* >(matchedStrList.GetAt(0)));
769                                         if (delimiter2.IsEmpty())       // If the 2nd delimiter is also empty, the token will be one character followed by 1st delimiter.
770                                         {
771                                                 ret.Clear();
772                                                 ret.Append(*(__pParseStr + __position));
773                                                 length = 1;
774                                         }
775                                         else
776                                         {
777                                                 int delimLength2 = delimiter2.GetLength();
778                                                 int index2 = 0;
779                                                 inputStr.IndexOf(delimiter2, 0, index2);
780                                                 inputStr.SubString(0, index2, ret);
781                                                 length = index2 + delimLength2;
782                                         }
783                                 }
784                         }
785                 }
786         }
787         else    //There are no delimiters
788         {
789                 ret.Clear();
790                 ret.Append(__pParseStr + __position);
791                 length = ret.GetLength();
792                 if (length <= 0)
793                 {
794                         return E_DATA_NOT_FOUND;
795                 }
796         }
797
798         return r;
799 }
800
801 result _ScannerImpl::GetNextMatchingString(const String& pattern, String& ret, int& length)
802 {
803         result r = E_SUCCESS;
804         RegularExpression regex;
805         ArrayList matchedStrList;
806
807         bool res = false;
808         int matches = 0;
809         String nextToken;
810         String matchToken;
811
812         String strPat(ANY_PATTERN);
813         strPat.Append(DEFAULT_DELIMITER_PATTERN);
814
815         r = regex.Construct(strPat, REGEX_UNICODE);
816         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, E_OPERATION_FAILED, "Regular expression construction failed");
817
818         r = matchedStrList.Construct();
819         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, E_OPERATION_FAILED, "Arraylist construction failed");
820
821         res = regex.Match(String(__pParseStr + __position), false, &matchedStrList);
822
823         SysTryReturnResult(NID_BASE_UTIL, res == true, E_OPERATION_FAILED, "Match Failed");
824
825         matches = matchedStrList.GetCount();
826         if(matches > 0)
827         {
828                 nextToken = *(String *)matchedStrList.GetAt(0);
829                 matchedStrList.RemoveAll();
830         }
831
832         strPat = pattern;
833         strPat.Append(DEFAULT_DELIMITER_PATTERN);
834         r = regex.Construct(strPat, REGEX_UNICODE);
835         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, E_OPERATION_FAILED, "Regular expression construction failed");
836
837         r = matchedStrList.Construct();
838         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, E_OPERATION_FAILED, "Arraylist construction failed");
839
840         res = regex.Match(String(__pParseStr + __position), false, &matchedStrList);
841         SysTryReturnResult(NID_BASE_UTIL, res == true, E_OPERATION_FAILED, "Match Failed");
842
843         matches = matchedStrList.GetCount();
844         if(matches > 0)
845         {
846                 matchToken = *(String *)matchedStrList.GetAt(0);
847                 matchedStrList.RemoveAll();
848
849                 if((nextToken == matchToken) == true)
850                 {
851                         length = matchToken.GetLength();
852                         RegularExpression re;
853                         r = re.Construct(DEFAULT_DELIMITER_PATTERN, REGEX_UNICODE);
854                         re.Replace(matchToken, L"", true);
855                         ret = matchToken;
856                 }
857                 else
858                 {
859                         r = E_OPERATION_FAILED;
860                 }
861         }
862
863         return r;
864 }
865
866 }}}   // Osp::Base::Utility