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