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