2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
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
9 // http://www.apache.org/licenses/LICENSE-2.0
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.
19 * @file FBaseString.cpp
20 * @brief This is the implementation for String class.
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"
43 namespace Tizen { namespace Base
46 const float String::GROWTH_FACTOR = 1.5;
56 result r = InitializeToDefault(DEFAULT_CAPACITY);
57 SysTryReturnVoidResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
60 String::String(int capacity)
70 capacity = DEFAULT_CAPACITY;
73 result r = InitializeToDefault(capacity);
74 SysTryReturnVoidResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
77 String::String(wchar_t ch)
85 result r = InitializeToDefault(DEFAULT_CAPACITY);
86 SysTryReturnVoidResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
93 String::String(const wchar_t* pValue)
101 int length = (pValue != null) ? wcslen(pValue) : 0;
103 SysTryReturnVoidResult(NID_BASE, length >= 0, E_OUT_OF_RANGE,
104 "String has wrong length. The length has to be more bigger than 0.");
108 result r = InitializeToDefault(DEFAULT_CAPACITY);
109 SysTryReturnVoidResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
113 result r = InitializeToDefault(length + DEFAULT_CAPACITY);
114 SysTryReturnVoidResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
116 wcsncpy(__pValue, pValue, length);
117 __pValue[length] = '\0';
122 String::String(const char* pValue)
128 , __pStringImpl(null)
130 if (pValue == null || strlen(pValue) == 0)
132 result r = InitializeToDefault(DEFAULT_CAPACITY);
133 SysTryReturnVoidResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
137 std::unique_ptr< wchar_t[] > pStr(Tizen::Base::Utility::ConvertMbsToWcsN(pValue));
138 SysTryReturnVoidResult(NID_BASE, pStr != null, GetLastResult(), "Propagating.");
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();
146 __capacity = strLen + 1;
150 String::String(const String& value)
151 : __capacity(value.__capacity)
152 , __length(value.__length)
153 , __hash(value.__hash)
155 , __pValue(value.__pValue)
156 , __pStringImpl(null)
158 SysTryReturnVoidResult(NID_BASE, value.__length >= 0, E_OUT_OF_RANGE, "The length has to be greater than 0.");
160 ++(*value.__pRefCount);
161 __pRefCount = value.__pRefCount;
164 String::~String(void)
166 if (*__pRefCount == 1)
179 String::operator [](int index) const
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];
189 String::operator [](int index)
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);
196 if (*__pRefCount > 1)
198 result r = CopyOnWrite(__capacity);
199 SysTryReturn(NID_BASE, r == E_SUCCESS, ch, E_OUT_OF_MEMORY, "Memory allocation failed.");
203 return __pValue[index];
207 String::operator =(const wchar_t* pRhs)
221 String::operator =(const String& rhs)
235 String::operator +=(const wchar_t* pRhs)
248 String::operator +=(const String& rhs)
255 Append(rhs.__pValue);
261 operator +(const String& lhs, const String& rhs)
265 str.Append(rhs.__pValue);
271 String::operator ==(const String& rhs) const
273 if (__length != rhs.__length)
278 return(CompareTo(rhs) == 0);
282 String::operator !=(const String& rhs) const
284 return(!(*this).operator ==(rhs));
288 String::IsEmpty(void) const
290 return(__length == 0);
294 String::Append(wchar_t ch)
296 result r = Append(Character::ToString(ch));
297 SysTryReturn(NID_BASE, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
303 String::Append(char ch)
305 result r = Append((wchar_t) ch);
306 SysTryReturn(NID_BASE, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
312 String::Append(int i)
314 result r = Append(Integer::ToString(i));
315 SysTryReturn(NID_BASE, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
321 String::Append(short s)
323 result r = Append(Short::ToString(s));
324 SysTryReturn(NID_BASE, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
330 String::Append(long l)
332 result r = Append(Long::ToString(l));
333 SysTryReturn(NID_BASE, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
339 String::Append(long long ll)
341 result r = Append(LongLong::ToString(ll));
342 SysTryReturn(NID_BASE, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
348 String::Append(float f)
350 result r = Append(Float::ToString(f));
351 SysTryReturn(NID_BASE, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
357 String::Append(double d)
359 result r = Append(Double::ToString(d));
360 SysTryReturn(NID_BASE, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
366 String::Append(const wchar_t* p)
368 SysTryReturnResult(NID_BASE, p != null, E_INVALID_ARG, "p is null.");
370 int length = (wcslen(p) + __length);
372 if (*__pRefCount > 1)
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");
379 wcsncpy(__pValue, pValue, __length);
381 __pRefCount = pRefCntTemp.release();
384 result r = EnsureCapacity(length);
385 SysTryReturn(NID_BASE, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
387 wcsncpy((__pValue + __length), p, wcslen(p));
389 __pValue[length] = '\0';
397 String::Append(const String& str)
404 result r = Append(str.__pValue);
405 SysTryReturn(NID_BASE, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
418 String::Compare(const String& str0, const String& str1)
420 if (str0.__pValue == str1.__pValue)
425 return(wcscmp(str0.__pValue, str1.__pValue));
429 String::CompareTo(const String& str) const
431 if (__pValue == str.__pValue)
436 return(wcscmp(__pValue, str.__pValue));
440 String::EnsureCapacity(int minCapacity)
442 SysTryReturnResult(NID_BASE, minCapacity >= 0, E_INVALID_ARG, "The minCapacity(%d) MUST be greater than or equal to 0.",
445 if (minCapacity > __capacity)
447 SysTryReturnResult(NID_BASE, ExpandCapacity(minCapacity), E_OUT_OF_MEMORY, "Memory allocation failed.");
453 String::Equals(const Object& obj) const
455 const String* pOther = dynamic_cast <const String*>(&obj);
462 return(*this == *pOther);
466 String::Equals(const String& str, bool caseSensitive) const
470 return(*this == str);
474 if (__length != str.__length)
479 if (__pValue == str.__pValue)
484 if (wcscasecmp(__pValue, str.__pValue) == 0)
494 String::Format(int length, const wchar_t* pFormat, ...)
497 result r = E_SUCCESS;
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.",
503 String tempStr(pFormat);
504 if (tempStr.IsEmpty() || length == 0)
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);
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);
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.");
524 va_start(args, pFormat);
526 vswprintf(pStr.get(), length, tempStr.__pValue, args);
532 int len = wcslen(this->__pValue);
535 this->__pValue[len] = '\0';
536 this->__length = len;
540 this->__pValue[length - 1] = '\0';
541 this->__length = length - 1;
549 String::GetHashCode(void) const
555 wchar_t* pStr = __pValue;
556 for (int i = 0; i < __length; ++i)
558 hash = (hash << 5) - hash + (int) *pStr++;
571 String::GetCharAt(int indexAt, wchar_t& ret) const
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);
578 ret = __pValue[indexAt];
584 String::IndexOf(wchar_t ch, int startIndex, int& indexOf) const
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);
591 wchar_t* pBeg = __pValue + startIndex;
592 wchar_t* pFound = (wchar_t*) wcschr((const wchar_t*) pBeg, (wchar_t) ch);
598 return E_OBJ_NOT_FOUND;
601 indexOf = int(pFound - __pValue);
607 String::IndexOf(const String& str, int startIndex, int& indexOf) const
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);
616 indexOf = startIndex;
620 if (__length < str.__length)
623 return E_OBJ_NOT_FOUND;
628 p = (wchar_t*) wcsstr((__pValue + startIndex), str.__pValue);
633 return E_OBJ_NOT_FOUND;
636 indexOf = int(p - __pValue);
642 String::Insert(wchar_t ch, int indexAt)
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).",
649 if (*__pRefCount > 1)
651 result r = CopyOnWrite(__capacity);
652 SysTryReturnResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
655 int length = (__length + 1);
657 result r = EnsureCapacity(length);
658 SysTryReturn(NID_BASE, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
660 wmemmove((__pValue + indexAt + 1), (__pValue + indexAt), ((__length + 1) - indexAt));
662 __pValue[indexAt] = ch;
670 String::Insert(char ch, int indexAt)
672 wchar_t wideChar = (wchar_t) ch;
674 result r = Insert(wideChar, indexAt);
675 SysTryReturn(NID_BASE, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
681 String::Insert(short s, int indexAt)
683 result r = Insert(Short::ToString(s), indexAt);
684 SysTryReturn(NID_BASE, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
690 String::Insert(int i, int indexAt)
692 result r = Insert(Integer::ToString(i), indexAt);
693 SysTryReturn(NID_BASE, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
699 String::Insert(long l, int indexAt)
701 result r = Insert(Long::ToString(l), indexAt);
702 SysTryReturn(NID_BASE, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
708 String::Insert(long long ll, int indexAt)
710 result r = Insert(LongLong::ToString(ll), indexAt);
711 SysTryReturn(NID_BASE, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
717 String::Insert(float f, int indexAt)
719 result r = Insert(Float::ToString(f), indexAt);
720 SysTryReturn(NID_BASE, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
726 String::Insert(double d, int indexAt)
728 result r = Insert(Double::ToString(d), indexAt);
729 SysTryReturn(NID_BASE, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
734 String::Insert(const wchar_t* p, int indexAt)
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).",
742 int length = wcslen(p);
748 if (*__pRefCount > 1)
750 result r = CopyOnWrite(__capacity);
751 SysTryReturnResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
754 result r = EnsureCapacity(__length + length);
755 SysTryReturn(NID_BASE, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
757 wmemmove((__pValue + indexAt + length), (__pValue + indexAt), ((__length + 1) - indexAt));
758 wmemcpy((__pValue + indexAt), p, length);
766 String::Insert(const String& str, int indexAt)
768 result r = Insert(str.__pValue, indexAt);
769 SysTryReturn(NID_BASE, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
775 String::LastIndexOf(wchar_t ch, int startIndex, int& indexOf) const
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);
782 wchar_t* pBeg = __pValue + startIndex;
783 wchar_t* pEnd = __pValue;
788 indexOf = int(pBeg - __pValue);
797 return E_OBJ_NOT_FOUND;
801 String::LastIndexOf(const String& str, int startIndex, int& indexOf) const
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);
810 indexOf = startIndex;
814 if (__length < str.__length)
818 return E_OBJ_NOT_FOUND;
821 const wchar_t* pStr = str.__pValue;
823 int length = str.__length;
824 if (length > startIndex)
828 return E_OBJ_NOT_FOUND;
832 wchar_t* pBeg = __pValue + startIndex;
833 wchar_t* pEnd = __pValue;
837 if (wcsncmp(pBeg, pStr, length) == 0)
839 indexOf = (pBeg - __pValue);
846 return E_OBJ_NOT_FOUND;
850 String::Remove(int startIndex, int count)
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);
861 if (*__pRefCount > 1)
863 result r = CopyOnWrite(__capacity);
864 SysTryReturnResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
867 wmemmove(__pValue + startIndex, __pValue + moveIndex, (__length - moveIndex) + 1);
869 __pValue[__length] = '\0';
876 String::Replace(wchar_t original, wchar_t replace)
878 if (*__pRefCount > 1)
880 result r = CopyOnWrite(__capacity);
881 SysTryReturnVoidResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
884 for (int length = __length; length >= 0; --length)
886 if (__pValue[length] == original)
888 __pValue[length] = replace;
895 String::Replace(const String& org, const String& rep)
897 result r = Replace(org, rep, 0);
898 SysTryReturn(NID_BASE, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
904 String::Replace(const String& org, const String& rep, int startIndex)
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);
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);
919 if ((orgLen == __length) && (*this == org))
921 const int newLength = rep.__length;
922 if (EnsureCapacity(newLength) != E_SUCCESS)
924 SetCapacity(newLength);
927 wcsncpy(__pValue, rep.__pValue, rep.__length);
929 __length = rep.__length;
930 __pValue[__length] = '\0';
936 int repLen = rep.__length;
938 wchar_t* pOrg = org.__pValue;
939 wchar_t* pRep = rep.__pValue;
943 wchar_t* pBeg = (__pValue + startIndex);
944 wchar_t* pEnd = pBeg + __length;
947 wchar_t* pTarget = null;
948 while ((pTarget = (wchar_t*) wcsstr(pBeg, pOrg)) != null)
951 pBeg = pTarget + orgLen;
953 pBeg += wcslen(pBeg) + 1;
959 if (*__pRefCount > 1)
961 result r = CopyOnWrite(__capacity);
962 SysTryReturnResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
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));
969 wchar_t* pBeg = (__pValue + startIndex);
970 wchar_t* pEnd = pBeg + __length;
973 wchar_t* pTarget = null;
974 while ((pTarget = (wchar_t*) wcsstr(pBeg, pOrg)) != null)
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);
983 pBeg += (wcslen(pBeg) + 1);
986 __length = newLength;
994 String::Reverse(void)
996 if (*__pRefCount > 0)
998 result r = CopyOnWrite(__capacity);
999 SysTryReturnVoidResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
1002 wchar_t* pBeg = __pValue;
1003 wchar_t* pEnd = __pValue + __length - 1;
1006 for (; pBeg < pEnd; ++pBeg, --pEnd)
1016 String::SetCapacity(int capacity)
1018 SysTryReturnResult(NID_BASE, capacity >= 0, E_INVALID_ARG,
1019 "The capacity(%d) MUST be greater than or equal to 0.", capacity);
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.");
1024 if (__pValue != null)
1026 if (__length < capacity)
1028 wmemcpy(pValue.get(), __pValue, (__length + 1));
1032 wmemcpy(pValue.get(), __pValue, capacity);
1033 pValue[capacity] = '\0';
1034 __length = capacity;
1038 if (*__pRefCount == 1)
1044 std::unique_ptr<int> pRefCntTemp(new (std::nothrow) int(1));
1045 SysTryReturnResult(NID_BASE, pRefCntTemp != null, E_OUT_OF_MEMORY, "Memory allocation failed");
1047 __pRefCount = pRefCntTemp.release();
1051 __pValue = pValue.release();
1052 __capacity = capacity;
1058 String::SetCharAt(wchar_t ch, int indexAt)
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);
1064 if (*__pRefCount > 1)
1066 result r = CopyOnWrite(__capacity);
1067 SysTryReturnResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
1070 __pValue[indexAt] = ch;
1077 String::SetLength(int newLength)
1079 SysTryReturnResult(NID_BASE, newLength >= 0, E_INVALID_ARG, "The newLength(%d) MUST be greater than or equal to 0.",
1082 if (*__pRefCount > 1)
1084 result r = CopyOnWrite(__capacity);
1085 SysTryReturnResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
1088 static const wchar_t SPACE = 0x0020;
1090 result r = EnsureCapacity(newLength);
1091 SysTryReturn(NID_BASE, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
1093 if (newLength > __length)
1095 wmemset(__pValue + __length, SPACE, newLength - __length);
1098 __pValue[newLength] = '\0';
1099 __length = newLength;
1106 String::SubString(int startIndex, String& out) const
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);
1113 out = __pValue + startIndex;
1119 String::SubString(int startIndex, int length, String& out) const
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);
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';
1139 else if (length == 0)
1148 String::StartsWith(const String& str, int startIndex) const
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);
1157 if (str.__length > __length)
1162 if ((wcsncmp(__pValue + startIndex, str.__pValue, str.__length) == 0))
1171 String::EndsWith(const String& str) const
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);
1182 int curLen = __length;
1183 if (strLen > curLen || curLen == 0)
1187 else if (wcscmp(__pValue + (curLen - strLen), str.__pValue) == 0)
1196 String::ToLower(String& out) const
1198 String str(__length + 1);
1200 wchar_t* pDst = str.__pValue;
1201 wchar_t* pSrc = __pValue;
1203 for (; *pSrc != 0; ++pSrc, ++pDst)
1205 *pDst = Character::ToLower(*pSrc);
1210 str.__length = __length;
1217 String::ToLowerCase(String& out) const
1219 String str(__length + 1);
1221 wchar_t* pDst = str.__pValue;
1222 wchar_t* pSrc = __pValue;
1224 for (; *pSrc != 0; ++pSrc, ++pDst)
1226 *pDst = Character::ToLowerCase(*pSrc);
1231 str.__length = __length;
1238 String::ToUpper(String& out) const
1240 String str(__length + 1);
1242 wchar_t* pDst = str.__pValue;
1243 wchar_t* pSrc = __pValue;
1245 for (; *pSrc != 0; ++pSrc, ++pDst)
1247 *pDst = Character::ToUpper(*pSrc);
1252 str.__length = __length;
1259 String::ToUpperCase(String& out) const
1261 String str(__length + 1);
1263 wchar_t* pDst = str.__pValue;
1264 wchar_t* pSrc = __pValue;
1265 for (; *pSrc != 0; ++pSrc, ++pDst)
1267 *pDst = Character::ToUpperCase(*pSrc);
1272 str.__length = __length;
1279 String::ToLower(void)
1281 if (*__pRefCount > 1)
1283 result r = CopyOnWrite(__capacity);
1284 SysTryReturnVoidResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
1287 String str(__length + 1);
1289 wchar_t* pDst = str.__pValue;
1290 wchar_t* pSrc = __pValue;
1292 for (; *pSrc != 0; ++pSrc, ++pDst)
1294 *pDst = Character::ToLower(*pSrc);
1297 wcsncpy(__pValue, str.__pValue, __length);
1298 __pValue[__length] = '\0';
1303 String::ToLowerCase(void)
1305 if (*__pRefCount > 0)
1307 result r = CopyOnWrite(__capacity);
1308 SysTryReturnVoidResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
1311 String str(__length + 1);
1313 wchar_t* pDst = str.__pValue;
1314 wchar_t* pSrc = __pValue;
1316 for (; *pSrc != 0; ++pSrc, ++pDst)
1318 *pDst = Character::ToLowerCase(*pSrc);
1321 wcsncpy(__pValue, str.__pValue, __length);
1322 __pValue[__length] = '\0';
1327 String::ToUpper(void)
1329 if (*__pRefCount > 1)
1331 result r = CopyOnWrite(__capacity);
1332 SysTryReturnVoidResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
1335 String str(__length + 1);
1337 wchar_t* pDst = str.__pValue;
1338 wchar_t* pSrc = __pValue;
1340 for (; *pSrc != 0; ++pSrc, ++pDst)
1342 *pDst = Character::ToUpper(*pSrc);
1345 wcsncpy(__pValue, str.__pValue, __length);
1346 __pValue[__length] = '\0';
1351 String::ToUpperCase(void)
1353 if (*__pRefCount > 1)
1355 result r = CopyOnWrite(__capacity);
1356 SysTryReturnVoidResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
1359 String str(__length + 1);
1361 wchar_t* pDst = str.__pValue;
1362 wchar_t* pSrc = __pValue;
1364 for (; *pSrc != 0; ++pSrc, ++pDst)
1366 *pDst = Character::ToUpperCase(*pSrc);
1369 wcsncpy(__pValue, str.__pValue, __length);
1370 __pValue[__length] = '\0';
1383 int lastIndex = __length;
1385 const wchar_t* pStr = __pValue;
1387 while ((startIndex < lastIndex) && (*(pStr + startIndex) <= L' '))
1392 while ((startIndex < lastIndex) && (*(pStr + lastIndex - 1) <= L' '))
1398 if (lastIndex < __length)
1400 Remove(lastIndex, __length - lastIndex);
1406 Remove(0, startIndex);
1411 String::GetCapacity(void) const
1413 return __capacity; // REMARK: the actual allocated size of buffer is __capacity + 1
1417 String::GetLength(void) const
1423 String::GetPointer(void) const
1430 String::Contains(const String& str) const
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);
1440 else if ((__length == str.__length) && (*this == str))
1445 wchar_t* pStart = __pValue;
1446 wchar_t* pEnd = pStart + __length;
1447 while (pStart < pEnd)
1449 while (wcsstr(pStart, str.__pValue) != null)
1460 String::AllocateCapacity(int capacity)
1462 __pValue = new (std::nothrow) wchar_t[capacity + 1]; // + 1 for null character
1463 if (__pValue == null)
1465 SysLogException(NID_BASE, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
1470 __pValue[capacity] = '\0';
1471 __capacity = capacity;
1477 String::ExpandCapacity(int minCapacity)
1479 int capacity = (__capacity ? (4 * (((int) (GROWTH_FACTOR * __capacity) - 1) / 4 + 1)) : 0); // nearest multiple of 4
1481 if (minCapacity > capacity)
1483 capacity = minCapacity;
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));
1490 if (__pValue != null)
1492 wmemcpy(pNewValue.get(), __pValue, __length);
1493 pNewValue[__length] = '\0';
1495 if (*__pRefCount == 1)
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));
1505 __pRefCount = pRefCntTemp.release();
1508 __pValue = pNewValue.release();
1509 __pValue[capacity] = '\0';
1510 __capacity = capacity;
1516 String::InitializeToDefault(int capacity)
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.");
1522 __pRefCount = pRefCntTemp.release();
1527 String::CopyOnWrite(int capacity)
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.");
1534 wcsncpy(__pValue, pValue, __length);
1535 __pValue[__length] = '\0';
1537 __pRefCount = pRefCntTemp.release();
1542 String::Swap(String& str)
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);