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