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