Merge "Applied sizeof operator on fixed sized array to calculate size." into tizen_2.2
[platform/framework/native/appfw.git] / src / base / FBaseString.cpp
1 //
2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
3 //
4 // Licensed under the Apache License, Version 2.0 (the License);
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //     http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 /**
18 * @file         FBaseString.cpp
19 * @brief        This is the implementation for String class.
20 */
21 #include <wchar.h>
22 #include <math.h>
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <stdarg.h>
26 #include <new>
27 #include <FBaseString.h>
28 #include <FBaseInt8.h>
29 #include <FBaseShort.h>
30 #include <FBaseInteger.h>
31 #include <FBaseLong.h>
32 #include <FBaseLongLong.h>
33 #include <FBaseFloat.h>
34 #include <FBaseDouble.h>
35 #include <FBaseCharacter.h>
36 #include <FBaseResult.h>
37 #include <FBaseSysLog.h>
38 #include <unique_ptr.h>
39 #include "FBaseUtil_AtomicOperations.h"
40 #include "FBaseUtil_IcuConverter.h"
41
42 namespace Tizen { namespace Base
43 {
44
45 const float String::GROWTH_FACTOR = 1.5;
46 const int String::UNSHAREABLE = Integer::VALUE_MAX;
47
48 String::String(void)
49         : __capacity(0)
50         , __length(0)
51         , __hash(0)
52         , __pRefCount(null)
53         , __pValue(null)
54         , __pStringImpl(null)
55 {
56         result r = InitializeToDefault(DEFAULT_CAPACITY);
57         SysTryReturnVoidResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
58 }
59
60 String::String(int capacity)
61         : __capacity(0)
62         , __length(0)
63         , __hash(0)
64         , __pRefCount(null)
65         , __pValue(null)
66         , __pStringImpl(null)
67 {
68         if (capacity <= 0)
69         {
70                 capacity = DEFAULT_CAPACITY;
71         }
72
73         result r = InitializeToDefault(capacity);
74         SysTryReturnVoidResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
75 }
76
77 String::String(wchar_t ch)
78         : __capacity(0)
79         , __length(0)
80         , __hash(0)
81         , __pRefCount(null)
82         , __pValue(null)
83         , __pStringImpl(null)
84 {
85         result r = InitializeToDefault(DEFAULT_CAPACITY);
86         SysTryReturnVoidResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
87
88         __pValue[0] = ch;
89         __pValue[1] = '\0';
90         __length = 1;
91 }
92
93 String::String(const wchar_t* pValue)
94         : __capacity(0)
95         , __length(0)
96         , __hash(0)
97         , __pRefCount(null)
98         , __pValue(null)
99         , __pStringImpl(null)
100 {
101         if (pValue == null)
102         {
103                 result r = InitializeToDefault(DEFAULT_CAPACITY);
104                 SysTryReturnVoidResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
105         }
106         else
107         {
108                 int length = wcslen(pValue);
109                 result r = InitializeToDefault(length + DEFAULT_CAPACITY);
110                 SysTryReturnVoidResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
111
112                 wcsncpy(__pValue, pValue, length);
113                 __pValue[length] = '\0';
114                 __length = length;
115         }
116 }
117
118 String::String(const char* pValue)
119         : __capacity(0)
120         , __length(0)
121         , __hash(0)
122         , __pRefCount(null)
123         , __pValue(null)
124         , __pStringImpl(null)
125 {
126         if (pValue == null || strlen(pValue) == 0)
127         {
128                 result r = InitializeToDefault(DEFAULT_CAPACITY);
129                 SysTryReturnVoidResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
130         }
131         else
132         {
133                 std::unique_ptr< int > pRefCntTemp(new (std::nothrow) int(1));
134                 SysTryReturnVoidResult(NID_BASE, pRefCntTemp != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
135
136                 std::unique_ptr< wchar_t[] > pStr(Tizen::Base::Utility::Utf8ToWcharN(pValue));
137                 SysTryReturnVoidResult(NID_BASE, pStr != null, GetLastResult(), "[%ls] Propagating.", GetErrorMessage(GetLastResult()));
138
139                 __pRefCount = pRefCntTemp.release();
140                 __pValue = pStr.release();
141                 __length = wcslen(__pValue);
142                 __capacity = __length + DEFAULT_CAPACITY;
143                 __pValue[__length] = '\0';
144         }
145 }
146
147 String::String(const String& value)
148         : __capacity(0)
149         , __length(0)
150         , __hash(0)
151         , __pRefCount(null)
152         , __pValue(null)
153         , __pStringImpl(null)
154 {
155         if (*(value.__pRefCount) != UNSHAREABLE)
156         {
157                 Utility::_AtomicOperations::AtomicInc(value.__pRefCount);
158                 __pRefCount = value.__pRefCount;
159                 __pValue = value.__pValue;
160                 __capacity = value.__capacity;
161                 __length = value.__length;
162                 __hash = value.__hash;
163         }
164         else
165         {
166                 int length = wcslen(value.__pValue);
167
168                 result r = InitializeToDefault(length + DEFAULT_CAPACITY);
169                 SysTryReturnVoidResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
170
171                 wcsncpy(__pValue, value.__pValue, length);
172                 __pValue[length] = '\0';
173                 __length = length;
174         }
175 }
176
177 String::~String(void)
178 {
179         if (*__pRefCount == 1 || *__pRefCount == UNSHAREABLE)
180         {
181                 delete[] __pValue;
182                 delete __pRefCount;
183         }
184         else
185         {
186                 Utility::_AtomicOperations::AtomicDec(__pRefCount);
187                 __pRefCount = null;
188         }
189 }
190
191 const wchar_t&
192 String::operator [](int index) const
193 {
194         static wchar_t ch = -1;
195         SysTryReturn(NID_BASE, (index < __length && index >= 0), ch, E_OUT_OF_RANGE,
196                 "[%s] The index(%d) MUST be greater than or equal to 0, and less than the length of this string(%d).",
197                 GetErrorMessage(E_OUT_OF_RANGE), index, __length);
198         return __pValue[index];
199 }
200
201 wchar_t&
202 String::operator [](int index)
203 {
204         static wchar_t ch = -1;
205         SysTryReturn(NID_BASE, (index < __length && index >= 0), ch, E_OUT_OF_RANGE,
206                 "[%s] The index(%d) MUST be greater than or equal to 0, and less than the length of this string(%d).",
207                 GetErrorMessage(E_OUT_OF_RANGE), index, __length);
208
209         result r = AboutToModify(__capacity, true);
210         SysTryReturn(NID_BASE, r == E_SUCCESS, ch, E_OUT_OF_MEMORY, "Memory allocation failed.");
211
212         __hash = 0;
213         return __pValue[index];
214 }
215
216 String&
217 String::operator =(const wchar_t* pRhs)
218 {
219         if (pRhs == null)
220         {
221                 return *this;
222         }
223
224         String tStr(pRhs);
225         tStr.Swap(*this);
226
227         return *this;
228 }
229
230 String&
231 String::operator =(const String& rhs)
232 {
233         if (&rhs == this)
234         {
235                 return *this;
236         }
237
238         String tStr(rhs);
239         tStr.Swap(*this);
240
241         return *this;
242 }
243
244 String&
245 String::operator +=(const wchar_t* pRhs)
246 {
247         if (pRhs == null)
248         {
249                 return *this;
250         }
251
252         Append(pRhs);
253
254         return *this;
255 }
256
257 String&
258 String::operator +=(const String& rhs)
259 {
260         if (rhs.IsEmpty())
261         {
262                 return *this;
263         }
264
265         Append(rhs.__pValue);
266
267         return *this;
268 }
269
270 String
271 operator +(const String& lhs, const String& rhs)
272 {
273         String str(lhs);
274
275         str.Append(rhs.__pValue);
276
277         return str;
278 }
279
280 bool
281 String::operator ==(const String& rhs) const
282 {
283         if (__length != rhs.__length)
284         {
285                 return false;
286         }
287
288         return(CompareTo(rhs) == 0);
289 }
290
291 bool
292 String::operator !=(const String& rhs) const
293 {
294         return(!(*this).operator ==(rhs));
295 }
296
297 bool
298 String::IsEmpty(void) const
299 {
300         return(__length == 0);
301 }
302
303 result
304 String::Append(wchar_t ch)
305 {
306         result r = Append(Character::ToString(ch));
307         SysTryReturn(NID_BASE, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
308
309         return r;
310 }
311
312 result
313 String::Append(char ch)
314 {
315         result r = Append((wchar_t) ch);
316         SysTryReturn(NID_BASE, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
317
318         return r;
319 }
320
321 result
322 String::Append(int i)
323 {
324         result r = Append(Integer::ToString(i));
325         SysTryReturn(NID_BASE, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
326
327         return r;
328 }
329
330 result
331 String::Append(short s)
332 {
333         result r = Append(Short::ToString(s));
334         SysTryReturn(NID_BASE, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
335
336         return r;
337 }
338
339 result
340 String::Append(long l)
341 {
342         result r = Append(Long::ToString(l));
343         SysTryReturn(NID_BASE, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
344
345         return r;
346 }
347
348 result
349 String::Append(long long ll)
350 {
351         result r = Append(LongLong::ToString(ll));
352         SysTryReturn(NID_BASE, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
353
354         return r;
355 }
356
357 result
358 String::Append(float f)
359 {
360         result r = Append(Float::ToString(f));
361         SysTryReturn(NID_BASE, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
362
363         return r;
364 }
365
366 result
367 String::Append(double d)
368 {
369         result r = Append(Double::ToString(d));
370         SysTryReturn(NID_BASE, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
371
372         return r;
373 }
374
375 result
376 String::Append(const wchar_t* p)
377 {
378         SysTryReturnResult(NID_BASE, p != null, E_INVALID_ARG, "p is null.");
379
380         int length = (wcslen(p) + __length);
381
382         if (*__pRefCount > 1 && *__pRefCount != UNSHAREABLE)
383         {
384                 wchar_t* pValue = __pValue;
385                 SysTryReturnResult(NID_BASE, AllocateCapacity(length) != false, E_OUT_OF_MEMORY, "Memory allocation failed.");
386                 std::unique_ptr< int > pRefCntTemp(new (std::nothrow) int(1));
387                 SysTryReturnResult(NID_BASE, pRefCntTemp != null, E_OUT_OF_MEMORY, "Memory allocation failed");
388
389                 wcsncpy(__pValue, pValue, __length);
390                 Utility::_AtomicOperations::AtomicDec(__pRefCount);
391                 __pRefCount = pRefCntTemp.release();
392         }
393
394         result r = EnsureCapacity(length);
395         SysTryReturn(NID_BASE, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
396
397         wcsncpy((__pValue + __length), p, wcslen(p));
398
399         __pValue[length] = '\0';
400         __length = length;
401         __hash = 0;
402
403         return E_SUCCESS;
404 }
405
406 result
407 String::Append(const String& str)
408 {
409         if (str.IsEmpty())
410         {
411                 return E_SUCCESS;
412         }
413
414         result r = Append(str.__pValue);
415         SysTryReturn(NID_BASE, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
416
417         return r;
418 }
419
420 void
421 String::Clear(void)
422 {
423         String tStr;
424         tStr.Swap(*this);
425 }
426
427 int
428 String::Compare(const String& str0, const String& str1)
429 {
430         if (str0.__pValue == str1.__pValue)
431         {
432                 return 0;
433         }
434
435         return(wcscmp(str0.__pValue, str1.__pValue));
436 }
437
438 int
439 String::CompareTo(const String& str) const
440 {
441         if (__pValue == str.__pValue)
442         {
443                 return 0;
444         }
445
446         return(wcscmp(__pValue, str.__pValue));
447 }
448
449 result
450 String::EnsureCapacity(int minCapacity)
451 {
452         SysTryReturnResult(NID_BASE, minCapacity >= 0, E_INVALID_ARG, "The minCapacity(%d) MUST be greater than or equal to 0.",
453                 minCapacity);
454
455         if (minCapacity > __capacity)
456         {
457                 SysTryReturnResult(NID_BASE, ExpandCapacity(minCapacity), E_OUT_OF_MEMORY, "Memory allocation failed.");
458         }
459         return E_SUCCESS;
460 }
461
462 bool
463 String::Equals(const Object& obj) const
464 {
465         const String* pOther = dynamic_cast< const String* >(&obj);
466
467         if (pOther == null)
468         {
469                 return false;
470         }
471
472         return(*this == *pOther);
473 }
474
475 bool
476 String::Equals(const String& str, bool caseSensitive) const
477 {
478         if (caseSensitive)
479         {
480                 return(*this == str);
481         }
482         else
483         {
484                 if (__length != str.__length)
485                 {
486                         return false;
487                 }
488
489                 if (__pValue == str.__pValue)
490                 {
491                         return true;
492                 }
493
494                 if (wcscasecmp(__pValue, str.__pValue) == 0)
495                 {
496                         return true;
497                 }
498
499                 return false;
500         }
501 }
502
503 result
504 String::Format(int length, const wchar_t* pFormat, ...)
505 {
506         int index = -1;
507         result r = E_SUCCESS;
508
509         SysTryReturnResult(NID_BASE, pFormat != null, E_INVALID_ARG, "The pFormat is null.");
510         SysTryReturnResult(NID_BASE, length >= 0, E_INVALID_ARG, "The length(%d) MUST be greater than or equal to 0.",
511                 length);
512
513         String tempStr(pFormat);
514         if (tempStr.IsEmpty() || length == 0)
515         {
516                 Clear();
517                 return E_SUCCESS;
518         }
519
520         // Check "%n" and "%hn"
521         r = tempStr.IndexOf(L"%n", 0, index);
522         SysTryReturnResult(NID_BASE, r == E_OBJ_NOT_FOUND, E_INVALID_ARG, "(%ls) is not supported format.", pFormat);
523
524         r = tempStr.IndexOf(L"%hn", 0, index);
525         SysTryReturnResult(NID_BASE, r == E_OBJ_NOT_FOUND, E_INVALID_ARG, "(%ls) is not supported format.", pFormat);
526
527         Clear();
528
529         std::unique_ptr< wchar_t[] > pStr(new (std::nothrow) wchar_t[length + 1]);
530         SysTryReturnResult(NID_BASE, pStr != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
531         pStr[length] = '\0';
532
533         va_list args;
534         va_start(args, pFormat);
535
536         vswprintf(pStr.get(), length, tempStr.__pValue, args);
537
538         va_end(args);
539
540         *this = pStr.get();
541
542         int len = wcslen(this->__pValue);
543         if (length > len)
544         {
545                 this->__pValue[len] = '\0';
546                 this->__length = len;
547         }
548         else
549         {
550                 this->__pValue[length - 1] = '\0';
551                 this->__length = length - 1;
552         }
553         this->__hash = 0;
554
555         return E_SUCCESS;
556 }
557
558 int
559 String::GetHashCode(void) const
560 {
561         int hash = 0;
562
563         if (__hash == 0)
564         {
565                 wchar_t* pStr = __pValue;
566                 for (int i = 0; i < __length; ++i)
567                 {
568                         hash = (hash << 5) - hash + (int) *pStr++;
569                 }
570                 __hash = hash;
571         }
572         else
573         {
574                 hash = __hash;
575         }
576
577         return hash;
578 }
579
580 result
581 String::GetCharAt(int indexAt, wchar_t& ret) const
582 {
583         SysTryReturnResult(NID_BASE, (indexAt < __length), E_OUT_OF_RANGE,
584                 "The indexAt(%d) MUST be less than the length of this string(%d).", indexAt, __length);
585         SysTryReturnResult(NID_BASE, (indexAt >= 0), E_OUT_OF_RANGE,
586                 "The indexAt(%d) MUST be greater than or equal to 0.", indexAt);
587
588         ret = __pValue[indexAt];
589
590         return E_SUCCESS;
591 }
592
593 result
594 String::IndexOf(wchar_t ch, int startIndex, int& indexOf) const
595 {
596         SysTryReturnResult(NID_BASE, startIndex < __length, E_OUT_OF_RANGE,
597                 "The startIndex(%d) MUST be less than the length of this string(%d).", startIndex, __length);
598         SysTryReturnResult(NID_BASE, startIndex >= 0, E_OUT_OF_RANGE,
599                 "The startIndex(%d) MUST be greater than or equal to 0.", startIndex);
600
601         wchar_t* pBeg = __pValue + startIndex;
602         wchar_t* pFound = (wchar_t*) wcschr((const wchar_t*) pBeg, (wchar_t) ch);
603
604         if (pFound == null)
605         {
606                 indexOf = -1;
607
608                 return E_OBJ_NOT_FOUND;
609         }
610
611         indexOf = int(pFound - __pValue);
612
613         return E_SUCCESS;
614 }
615
616 result
617 String::IndexOf(const String& str, int startIndex, int& indexOf) const
618 {
619         SysTryReturnResult(NID_BASE, startIndex < __length, E_OUT_OF_RANGE,
620                 "The startIndex(%d) MUST be less than the length of this string(%d).", startIndex, __length);
621         SysTryReturnResult(NID_BASE, startIndex >= 0, E_OUT_OF_RANGE,
622                 "The startIndex(%d) MUST be greater than or equal to 0.", startIndex);
623
624         if (str.IsEmpty())
625         {
626                 indexOf = startIndex;
627                 return E_SUCCESS;
628         }
629
630         if (__length < str.__length)
631         {
632                 indexOf = -1;
633                 return E_OBJ_NOT_FOUND;
634         }
635
636         wchar_t* p = null;
637
638         p = (wchar_t*) wcsstr((__pValue + startIndex), str.__pValue);
639         if (p == null)
640         {
641                 indexOf = -1;
642
643                 return E_OBJ_NOT_FOUND;
644         }
645
646         indexOf = int(p - __pValue);
647
648         return E_SUCCESS;
649 }
650
651 result
652 String::Insert(wchar_t ch, int indexAt)
653 {
654         SysTryReturnResult(NID_BASE,
655                 indexAt >= 0 && indexAt <= __length, E_OUT_OF_RANGE,
656                 "The indexAt(%d) MUST be greater than or equal to 0, and less than or equal to the length of this string(%d).",
657                 indexAt, __length);
658
659         result r = AboutToModify(__capacity);
660         SysTryReturnResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
661
662         int length = (__length + 1);
663
664         r = EnsureCapacity(length);
665         SysTryReturn(NID_BASE, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
666
667         wmemmove((__pValue + indexAt + 1), (__pValue + indexAt), ((__length + 1) - indexAt));
668
669         __pValue[indexAt] = ch;
670         __length = length;
671         __hash = 0;
672
673         return E_SUCCESS;
674 }
675
676 result
677 String::Insert(char ch, int indexAt)
678 {
679         wchar_t wideChar = (wchar_t) ch;
680
681         result r = Insert(wideChar, indexAt);
682         SysTryReturn(NID_BASE, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
683
684         return r;
685 }
686
687 result
688 String::Insert(short s, int indexAt)
689 {
690         result r = Insert(Short::ToString(s), indexAt);
691         SysTryReturn(NID_BASE, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
692
693         return r;
694 }
695
696 result
697 String::Insert(int i, int indexAt)
698 {
699         result r = Insert(Integer::ToString(i), indexAt);
700         SysTryReturn(NID_BASE, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
701
702         return r;
703 }
704
705 result
706 String::Insert(long l, int indexAt)
707 {
708         result r = Insert(Long::ToString(l), indexAt);
709         SysTryReturn(NID_BASE, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
710
711         return r;
712 }
713
714 result
715 String::Insert(long long ll, int indexAt)
716 {
717         result r = Insert(LongLong::ToString(ll), indexAt);
718         SysTryReturn(NID_BASE, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
719
720         return r;
721 }
722
723 result
724 String::Insert(float f, int indexAt)
725 {
726         result r = Insert(Float::ToString(f), indexAt);
727         SysTryReturn(NID_BASE, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
728
729         return r;
730 }
731
732 result
733 String::Insert(double d, int indexAt)
734 {
735         result r = Insert(Double::ToString(d), indexAt);
736         SysTryReturn(NID_BASE, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
737         return r;
738 }
739
740 result
741 String::Insert(const wchar_t* p, int indexAt)
742 {
743         SysTryReturnResult(NID_BASE, p != null, E_INVALID_ARG, "The p is null.");
744         SysTryReturnResult(NID_BASE,
745                 indexAt >= 0 && indexAt <= __length, E_OUT_OF_RANGE,
746                 "The indexAt(%d) MUST be greater than or equal to 0, and less than or equal to the length of this string(%d).",
747                 indexAt, __length);
748
749         int length = wcslen(p);
750         if (length == 0)
751         {
752                 return E_SUCCESS;
753         }
754
755         result r = AboutToModify(__capacity);
756         SysTryReturnResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
757
758         r = EnsureCapacity(__length + length);
759         SysTryReturn(NID_BASE, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
760
761         wmemmove((__pValue + indexAt + length), (__pValue + indexAt), ((__length + 1) - indexAt));
762         wmemcpy((__pValue + indexAt), p, length);
763
764         __length += length;
765         __hash = 0;
766         return E_SUCCESS;
767 }
768
769 result
770 String::Insert(const String& str, int indexAt)
771 {
772         result r = Insert(str.__pValue, indexAt);
773         SysTryReturn(NID_BASE, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
774
775         return r;
776 }
777
778 result
779 String::LastIndexOf(wchar_t ch, int startIndex, int& indexOf) const
780 {
781         SysTryReturnResult(NID_BASE,
782                 startIndex >= 0 && startIndex < __length, E_OUT_OF_RANGE,
783                 "The startIndex(%d) MUST be greater than or equal to 0, and less than the length of this string(%d).",
784                 startIndex, __length);
785
786         wchar_t* pBeg = __pValue + startIndex;
787         wchar_t* pEnd = __pValue;
788         while (pEnd <= pBeg)
789         {
790                 if (*pBeg == ch)
791                 {
792                         indexOf = int(pBeg - __pValue);
793
794                         return E_SUCCESS;
795                 }
796                 --pBeg;
797         }
798
799         indexOf = -1;
800
801         return E_OBJ_NOT_FOUND;
802 }
803
804 result
805 String::LastIndexOf(const String& str, int startIndex, int& indexOf) const
806 {
807         SysTryReturnResult(NID_BASE,
808                 startIndex >= 0 && startIndex < __length, E_OUT_OF_RANGE,
809                 "The startIndex(%d) MUST be greater than or equal to 0, and less than the length of this string(%d).",
810                 startIndex, __length);
811
812         if (str.IsEmpty())
813         {
814                 indexOf = startIndex;
815                 return E_SUCCESS;
816         }
817
818         if (__length < str.__length)
819         {
820                 indexOf = -1;
821
822                 return E_OBJ_NOT_FOUND;
823         }
824
825         const wchar_t* pStr = str.__pValue;
826
827         int length = str.__length;
828         if (length > startIndex)
829         {
830                 indexOf = -1;
831
832                 return E_OBJ_NOT_FOUND;
833         }
834
835         indexOf = -1;
836         wchar_t* pBeg = __pValue + startIndex;
837         wchar_t* pEnd = __pValue;
838
839         while (pBeg >= pEnd)
840         {
841                 if (wcsncmp(pBeg, pStr, length) == 0)
842                 {
843                         indexOf = (pBeg - __pValue);
844
845                         return E_SUCCESS;
846                 }
847                 --pBeg;
848         }
849
850         return E_OBJ_NOT_FOUND;
851 }
852
853 result
854 String::Remove(int startIndex, int count)
855 {
856         SysTryReturnResult(NID_BASE,
857                 startIndex >= 0 && startIndex < __length, E_OUT_OF_RANGE,
858                 "The startIndex(%d) MUST be greater than or equal to 0, and less than the length of this string(%d).",
859                 startIndex, __length);
860         int moveIndex = startIndex + count;
861         SysTryReturnResult(NID_BASE, moveIndex <= __length, E_OUT_OF_RANGE,
862                 "The startIndex(%d) + count(%d) MUST be less than or equal to the length of this string(%d).",
863                 startIndex, count, __length);
864
865         result r = AboutToModify(__capacity);
866         SysTryReturnResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
867
868         wmemmove(__pValue + startIndex, __pValue + moveIndex, (__length - moveIndex) + 1);
869         __length -= count;
870         __pValue[__length] = '\0';
871         __hash = 0;
872
873         return E_SUCCESS;
874 }
875
876 void
877 String::Replace(wchar_t original, wchar_t replace)
878 {
879         result r = AboutToModify(__capacity);
880         SysTryReturnVoidResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
881
882         for (int length = __length; length >= 0; --length)
883         {
884                 if (__pValue[length] == original)
885                 {
886                         __pValue[length] = replace;
887                 }
888         }
889         __hash = 0;
890 }
891
892 result
893 String::Replace(const String& org, const String& rep)
894 {
895         result r = Replace(org, rep, 0);
896         SysTryReturnResult(NID_BASE, r == E_SUCCESS, r, "Propagating.");
897
898         return r;
899 }
900
901 result
902 String::Replace(const String& org, const String& rep, int startIndex)
903 {
904         SysTryReturnResult(NID_BASE, org.__length > 0, E_INVALID_ARG, "The length of org MUST be greater than 0.");
905
906         SysTryReturnResult(NID_BASE,
907                 startIndex >= 0 && startIndex < __length, E_OUT_OF_RANGE,
908                 "The startIndex(%d) MUST be greater than or equal to 0, and less than the length of this string(%d).",
909                 startIndex, __length);
910
911         if (__length == 0)
912         {
913                 return E_SUCCESS;
914         }
915
916         int orgLen = org.__length;
917         int repLen = rep.__length;
918         if ((orgLen == __length) && (*this == org))
919         {
920                 result r = AboutToModify(__capacity);
921                 SysTryReturnResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
922
923                 r = EnsureCapacity(repLen);
924                 SysTryReturnResult(NID_BASE, r == E_SUCCESS, r, "Propagating.");
925
926                 wcsncpy(__pValue, rep.__pValue, repLen);
927
928                 __length = repLen;
929                 __pValue[__length] = '\0';
930                 __hash = 0;
931
932                 return E_SUCCESS;
933         }
934
935         int matchedCount = 0;
936
937         wchar_t* pBeg = __pValue + startIndex;
938         wchar_t* pMatch = null;
939
940         while ((pMatch = wcsstr(pBeg, org.__pValue)) != null)
941         {
942                 ++matchedCount;
943                 pBeg = pMatch + orgLen;
944         }
945
946         if (matchedCount > 0)
947         {
948                 result r = AboutToModify(__capacity);
949                 SysTryReturnResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
950
951                 const int newLength = (matchedCount * (repLen - orgLen)) + __length;
952                 r = EnsureCapacity(newLength);
953                 SysTryReturnResult(NID_BASE, r == E_SUCCESS, r, "Propagating.");
954
955                 pBeg = __pValue + startIndex;
956                 while ((pMatch = wcsstr(pBeg, org.__pValue)) != null)
957                 {
958                         int count = __length - (pMatch - __pValue) - orgLen;
959                         wmemmove(pMatch + repLen, pMatch + orgLen, count);
960                         wmemcpy(pMatch, rep.__pValue, repLen);
961
962                         pBeg = pMatch + repLen;
963                         pMatch[repLen + count] = '\0';
964                         __length += (repLen - orgLen);
965                 }
966
967                 __length = newLength;
968                 __hash = 0;
969         }
970
971         return E_SUCCESS;
972 }
973
974 void
975 String::Reverse(void)
976 {
977         result r = AboutToModify(__capacity);
978         SysTryReturnVoidResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
979
980         wchar_t* pBeg = __pValue;
981         wchar_t* pEnd = __pValue + __length - 1;
982         wchar_t ch = 0x00;
983
984         for (; pBeg < pEnd; ++pBeg, --pEnd)
985         {
986                 ch = *pBeg;
987                 *pBeg = *pEnd;
988                 *pEnd = ch;
989         }
990         __hash = 0;
991 }
992
993 result
994 String::SetCapacity(int capacity)
995 {
996         SysTryReturnResult(NID_BASE, capacity >= 0, E_INVALID_ARG,
997                 "The capacity(%d) MUST be greater than or equal to 0.", capacity);
998
999         std::unique_ptr< wchar_t[] > pValue(new (std::nothrow) wchar_t[capacity + 1]);
1000         SysTryReturnResult(NID_BASE, pValue != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
1001
1002         if (__pValue != null)
1003         {
1004                 if (__length < capacity)
1005                 {
1006                         wmemcpy(pValue.get(), __pValue, (__length + 1));
1007                 }
1008                 else
1009                 {
1010                         wmemcpy(pValue.get(), __pValue, capacity);
1011                         pValue[capacity] = '\0';
1012                         __length = capacity;
1013                         __hash = 0;
1014                 }
1015
1016                 if (*__pRefCount == 1)
1017                 {
1018                         delete[] __pValue;
1019                 }
1020                 else
1021                 {
1022                         std::unique_ptr< int > pRefCntTemp(new (std::nothrow) int(1));
1023                         SysTryReturnResult(NID_BASE, pRefCntTemp != null, E_OUT_OF_MEMORY, "Memory allocation failed");
1024                         Utility::_AtomicOperations::AtomicDec(__pRefCount);
1025                         __pRefCount = pRefCntTemp.release();
1026                 }
1027         }
1028
1029         __pValue = pValue.release();
1030         __capacity = capacity;
1031
1032         return E_SUCCESS;
1033 }
1034
1035 result
1036 String::SetCharAt(wchar_t ch, int indexAt)
1037 {
1038         SysTryReturn(NID_BASE, indexAt >= 0 && indexAt < __length, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
1039                 "[%s] The indexAt(%d) MUST be greater than or equal to 0, and less then the length of this string(%d).",
1040                 GetErrorMessage(E_OUT_OF_RANGE), indexAt, __length);
1041
1042         result r = AboutToModify(__capacity);
1043         SysTryReturnResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
1044
1045         __pValue[indexAt] = ch;
1046         __hash = 0;
1047
1048         return E_SUCCESS;
1049 }
1050
1051 result
1052 String::SetLength(int newLength)
1053 {
1054         SysTryReturnResult(NID_BASE, newLength >= 0, E_INVALID_ARG, "The newLength(%d) MUST be greater than or equal to 0.",
1055                 newLength);
1056
1057         result r = AboutToModify(__capacity);
1058         SysTryReturnResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
1059
1060         static const wchar_t SPACE = 0x0020;
1061
1062         r = EnsureCapacity(newLength);
1063         SysTryReturn(NID_BASE, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
1064
1065         if (newLength > __length)
1066         {
1067                 wmemset(__pValue + __length, SPACE, newLength - __length);
1068         }
1069
1070         __pValue[newLength] = '\0';
1071         __length = newLength;
1072         __hash = 0;
1073
1074         return E_SUCCESS;
1075 }
1076
1077 result
1078 String::SubString(int startIndex, String& out) const
1079 {
1080         SysTryReturnResult(NID_BASE,
1081                 startIndex >= 0 && startIndex < __length, E_OUT_OF_RANGE,
1082                 "The startIndex(%d) MUST be greater than or equal to 0, and less than the length of this string(%d).",
1083                 startIndex, __length);
1084
1085         out = __pValue + startIndex;
1086
1087         return E_SUCCESS;
1088 }
1089
1090 result
1091 String::SubString(int startIndex, int length, String& out) const
1092 {
1093         SysTryReturnResult(NID_BASE,
1094                 startIndex >= 0 && startIndex < __length, E_OUT_OF_RANGE,
1095                 "The startIndex(%d) MUST be greater than or equal to 0, and less than the length of this string(%d).",
1096                 startIndex, __length);
1097         SysTryReturnResult(NID_BASE, length >= 0, E_OUT_OF_RANGE, "The length(%d) MUST be greater than 0.", length);
1098         SysTryReturnResult(NID_BASE, startIndex + length <= __length, E_OUT_OF_RANGE,
1099                 "The startIndex(%d) + length(%d) MUST be less than or equal to the length of this string(%d).",
1100                 startIndex, length, __length);
1101
1102         if (length > 0)
1103         {
1104                 std::unique_ptr< wchar_t[] > pTemp(new (std::nothrow) wchar_t[length + 1]);
1105                 SysTryReturnResult(NID_BASE, pTemp != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
1106                 wcsncpy(pTemp.get(), __pValue + startIndex, length);
1107                 pTemp[length] = '\0';
1108
1109                 out = pTemp.get();
1110         }
1111         else if (length == 0)
1112         {
1113                 out.Clear();
1114         }
1115
1116         return E_SUCCESS;
1117 }
1118
1119 bool
1120 String::StartsWith(const String& str, int startIndex) const
1121 {
1122         SysTryReturn(NID_BASE, startIndex >= 0 && startIndex < __length, false, E_OUT_OF_RANGE,
1123                 "[%s] The startIndex(%d) MUST be greater than or equal to 0, and less than the length of this string(%d).",
1124                 GetErrorMessage(E_OUT_OF_RANGE), startIndex, __length);
1125         SysTryReturn(NID_BASE, str.__length > 0, false, E_INVALID_ARG,
1126                 "[%s] Invalid argument is used. The length of str(%d) MUST be greater than 0.",
1127                 GetErrorMessage(E_INVALID_ARG), str.__length);
1128
1129         if (str.__length > __length)
1130         {
1131                 return false;
1132         }
1133
1134         if ((wcsncmp(__pValue + startIndex, str.__pValue, str.__length) == 0))
1135         {
1136                 return true;
1137         }
1138
1139         return false;
1140 }
1141
1142 bool
1143 String::EndsWith(const String& str) const
1144 {
1145         if (this == &str)
1146         {
1147                 return true;
1148         }
1149
1150         int strLen = str.__length;
1151         SysTryReturn(NID_BASE, strLen > 0, false, E_INVALID_ARG,
1152                 "[%s] Invalid argument is used. The length of str(%d) MUST be greater than 0.", GetErrorMessage(E_INVALID_ARG), strLen);
1153
1154         int curLen = __length;
1155         if (strLen > curLen || curLen == 0)
1156         {
1157                 return false;
1158         }
1159         else if (wcscmp(__pValue + (curLen - strLen), str.__pValue) == 0)
1160         {
1161                 return true;
1162         }
1163
1164         return false;
1165 }
1166
1167 result
1168 String::ToLower(String& out) const
1169 {
1170         String str(__length + 1);
1171
1172         wchar_t* pDst = str.__pValue;
1173         wchar_t* pSrc = __pValue;
1174
1175         for (; *pSrc != 0; ++pSrc, ++pDst)
1176         {
1177                 *pDst = Character::ToLower(*pSrc);
1178         }
1179
1180         *pDst = '\0';
1181
1182         str.__length = __length;
1183         out = str;
1184
1185         return E_SUCCESS;
1186 }
1187
1188 result
1189 String::ToLowerCase(String& out) const
1190 {
1191         String str(__length + 1);
1192
1193         wchar_t* pDst = str.__pValue;
1194         wchar_t* pSrc = __pValue;
1195
1196         for (; *pSrc != 0; ++pSrc, ++pDst)
1197         {
1198                 *pDst = Character::ToLowerCase(*pSrc);
1199         }
1200
1201         *pDst = '\0';
1202
1203         str.__length = __length;
1204         out = str;
1205
1206         return E_SUCCESS;
1207 }
1208
1209 result
1210 String::ToUpper(String& out) const
1211 {
1212         String str(__length + 1);
1213
1214         wchar_t* pDst = str.__pValue;
1215         wchar_t* pSrc = __pValue;
1216
1217         for (; *pSrc != 0; ++pSrc, ++pDst)
1218         {
1219                 *pDst = Character::ToUpper(*pSrc);
1220         }
1221
1222         *pDst = '\0';
1223
1224         str.__length = __length;
1225         out = str;
1226
1227         return E_SUCCESS;
1228 }
1229
1230 result
1231 String::ToUpperCase(String& out) const
1232 {
1233         String str(__length + 1);
1234
1235         wchar_t* pDst = str.__pValue;
1236         wchar_t* pSrc = __pValue;
1237         for (; *pSrc != 0; ++pSrc, ++pDst)
1238         {
1239                 *pDst = Character::ToUpperCase(*pSrc);
1240         }
1241
1242         *pDst = '\0';
1243
1244         str.__length = __length;
1245         out = str;
1246
1247         return E_SUCCESS;
1248 }
1249
1250 void
1251 String::ToLower(void)
1252 {
1253         result r = AboutToModify(__capacity);
1254         SysTryReturnVoidResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
1255
1256         String str(__length + 1);
1257
1258         wchar_t* pDst = str.__pValue;
1259         wchar_t* pSrc = __pValue;
1260
1261         for (; *pSrc != 0; ++pSrc, ++pDst)
1262         {
1263                 *pDst = Character::ToLower(*pSrc);
1264         }
1265
1266         wcsncpy(__pValue, str.__pValue, __length);
1267         __pValue[__length] = '\0';
1268         __hash = 0;
1269 }
1270
1271 void
1272 String::ToLowerCase(void)
1273 {
1274         result r = AboutToModify(__capacity);
1275         SysTryReturnVoidResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
1276
1277         String str(__length + 1);
1278
1279         wchar_t* pDst = str.__pValue;
1280         wchar_t* pSrc = __pValue;
1281
1282         for (; *pSrc != 0; ++pSrc, ++pDst)
1283         {
1284                 *pDst = Character::ToLowerCase(*pSrc);
1285         }
1286
1287         wcsncpy(__pValue, str.__pValue, __length);
1288         __pValue[__length] = '\0';
1289         __hash = 0;
1290 }
1291
1292 void
1293 String::ToUpper(void)
1294 {
1295         result r = AboutToModify(__capacity);
1296         SysTryReturnVoidResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
1297
1298         String str(__length + 1);
1299
1300         wchar_t* pDst = str.__pValue;
1301         wchar_t* pSrc = __pValue;
1302
1303         for (; *pSrc != 0; ++pSrc, ++pDst)
1304         {
1305                 *pDst = Character::ToUpper(*pSrc);
1306         }
1307
1308         wcsncpy(__pValue, str.__pValue, __length);
1309         __pValue[__length] = '\0';
1310         __hash = 0;
1311 }
1312
1313 void
1314 String::ToUpperCase(void)
1315 {
1316         result r = AboutToModify(__capacity);
1317         SysTryReturnVoidResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
1318
1319         String str(__length + 1);
1320
1321         wchar_t* pDst = str.__pValue;
1322         wchar_t* pSrc = __pValue;
1323
1324         for (; *pSrc != 0; ++pSrc, ++pDst)
1325         {
1326                 *pDst = Character::ToUpperCase(*pSrc);
1327         }
1328
1329         wcsncpy(__pValue, str.__pValue, __length);
1330         __pValue[__length] = '\0';
1331         __hash = 0;
1332
1333 }
1334
1335 void
1336 String::Trim(void)
1337 {
1338         if (__length == 0)
1339         {
1340                 return;
1341         }
1342
1343         int lastIndex = __length;
1344         int startIndex = 0;
1345         const wchar_t* pStr = __pValue;
1346
1347         while ((startIndex < lastIndex) && (*(pStr + startIndex) <= L' '))
1348         {
1349                 ++startIndex;
1350         }
1351
1352         while ((startIndex < lastIndex) && (*(pStr + lastIndex - 1) <= L' '))
1353         {
1354                 --lastIndex;
1355         }
1356
1357         bool trimRight = lastIndex < __length;
1358         bool trimLeft = startIndex > 0;
1359
1360         if (!trimRight && !trimLeft)    // nothing to trim
1361         {
1362                 return;
1363         }
1364
1365         result r = AboutToModify(__capacity);
1366         SysTryReturnVoidResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed");
1367
1368         if (trimRight)
1369         {
1370                 Remove(lastIndex, __length - lastIndex);
1371         }
1372
1373         if (trimLeft)
1374         {
1375                 Remove(0, startIndex);
1376         }
1377 }
1378
1379 int
1380 String::GetCapacity(void) const
1381 {
1382         return __capacity; // REMARK: the actual allocated size of buffer is __capacity + 1
1383 }
1384
1385 int
1386 String::GetLength(void) const
1387 {
1388         return __length;
1389 }
1390
1391 const wchar_t*
1392 String::GetPointer(void) const
1393 {
1394         return __pValue;
1395 }
1396
1397
1398 bool
1399 String::Contains(const String& str) const
1400 {
1401         SysTryReturn(NID_BASE, str.__length > 0, false, E_INVALID_ARG,
1402                 "[%s] Invalid argument is used. The length of str(%d) MUST be greater than 0.",
1403                 GetErrorMessage(E_INVALID_ARG), str.__length);
1404
1405         if (__length == 0)
1406         {
1407                 return false;
1408         }
1409         else if ((__length == str.__length) && (*this == str))
1410         {
1411                 return true;
1412         }
1413
1414         return (wcsstr(__pValue, str.__pValue) != null);
1415 }
1416
1417 bool
1418 String::AllocateCapacity(int capacity)
1419 {
1420         __pValue = new (std::nothrow) wchar_t[capacity + 1]; // + 1 for null character
1421         if (__pValue == null)
1422         {
1423                 SysLogException(NID_BASE, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
1424                 return false;
1425         }
1426
1427         __pValue[0] = '\0';
1428         __pValue[capacity] = '\0';
1429         __capacity = capacity;
1430
1431         return true;
1432 }
1433
1434 bool
1435 String::ExpandCapacity(int minCapacity)
1436 {
1437         int capacity = (__capacity ? (4 * (((int) (GROWTH_FACTOR * __capacity) - 1) / 4 + 1)) : 0); // nearest multiple of 4
1438
1439         if (minCapacity > capacity)
1440         {
1441                 capacity = minCapacity;
1442         }
1443
1444         std::unique_ptr< wchar_t[] > pNewValue(new (std::nothrow) wchar_t[capacity + 1]); // + 1 for null character
1445         SysTryReturn(NID_BASE, pNewValue != null, false, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.",
1446                 GetErrorMessage(E_OUT_OF_MEMORY));
1447
1448         if (__pValue != null)
1449         {
1450                 wmemcpy(pNewValue.get(), __pValue, __length);
1451                 pNewValue[__length] = '\0';
1452
1453                 if (*__pRefCount == 1)
1454                 {
1455                         delete[] __pValue;
1456                 }
1457                 else
1458                 {
1459                         std::unique_ptr< int > pRefCntTemp(new (std::nothrow) int(1));
1460                         SysTryReturn(NID_BASE, pRefCntTemp != null, false, E_OUT_OF_MEMORY, "[%s] Memory allocation failed",
1461                                 GetErrorMessage(E_OUT_OF_MEMORY));
1462                         Utility::_AtomicOperations::AtomicDec(__pRefCount);
1463                         __pRefCount = pRefCntTemp.release();
1464                 }
1465         }
1466         __pValue = pNewValue.release();
1467         __pValue[capacity] = '\0';
1468         __capacity = capacity;
1469
1470         return true;
1471 }
1472
1473 result
1474 String::InitializeToDefault(int capacity)
1475 {
1476         std::unique_ptr< int > pRefCntTemp(new (std::nothrow) int(1));
1477         SysTryReturnResult(NID_BASE, pRefCntTemp != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
1478         SysTryReturnResult(NID_BASE, AllocateCapacity(capacity) != false, E_OUT_OF_MEMORY, "Memory allocation failed.");
1479
1480         __pRefCount = pRefCntTemp.release();
1481         return E_SUCCESS;
1482 }
1483
1484 result
1485 String::AboutToModify(int capacity, bool isUnshareable)
1486 {
1487         if (*__pRefCount > 1 && *__pRefCount != UNSHAREABLE)
1488         {
1489                 wchar_t* pValue = __pValue;
1490                 std::unique_ptr< int > pRefCntTemp(new (std::nothrow) int(1));
1491                 SysTryReturnResult(NID_BASE, pRefCntTemp != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
1492                 SysTryReturnResult(NID_BASE, AllocateCapacity(capacity), E_OUT_OF_MEMORY, "Memory allocation failed.");
1493
1494                 wcsncpy(__pValue, pValue, __length);
1495                 __pValue[__length] = '\0';
1496
1497                 Utility::_AtomicOperations::AtomicDec(__pRefCount);
1498                 __pRefCount = pRefCntTemp.release();
1499         }
1500
1501         if (isUnshareable)
1502         {
1503                 *__pRefCount = UNSHAREABLE;
1504         }
1505
1506         return E_SUCCESS;
1507 }
1508
1509 void
1510 String::Swap(String& str)
1511 {
1512         std::swap(__capacity, str.__capacity);
1513         std::swap(__length, str.__length);
1514         std::swap(__hash, str.__hash);
1515         std::swap(__pRefCount, str.__pRefCount);
1516         std::swap(__pValue, str.__pValue);
1517         std::swap(__pStringImpl, str.__pStringImpl);
1518 }
1519
1520 }} //Tizen::Base