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