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