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