2 // Copyright (c) 2013 Samsung Electronics Co., Ltd.
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
8 // http://www.apache.org/licenses/LICENSE-2.0
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.
18 * @file FBaseImmutableString.cpp
19 * @brief This is the implementation for ImmutableString class.
24 #include <FBaseImmutableString.h>
25 #include <FBase_StringBuffer.h>
26 #include <FBaseResult.h>
27 #include <FBaseSysLog.h>
28 #include <unique_ptr.h>
29 #include "FBaseUtil_AtomicOperations.h"
31 namespace Tizen { namespace Base
34 ImmutableString::ImmutableString(const wchar_t* pStr)
35 : __pImpl(new (std::nothrow) _StringBuffer(pStr))
37 SysTryReturnVoidResult(NID_BASE, __pImpl != null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
40 ImmutableString::ImmutableString(const char* pStr)
41 : __pImpl(new (std::nothrow) _StringBuffer(pStr))
43 SysTryReturnVoidResult(NID_BASE, __pImpl != null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
46 ImmutableString::ImmutableString(const String& value)
47 : __pImpl(new (std::nothrow) _StringBuffer(value))
49 SysTryReturnVoidResult(NID_BASE, __pImpl != null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
52 ImmutableString::ImmutableString(const ImmutableString& value)
55 Utility::_AtomicOperations::AtomicInc(&(value.__pImpl->__refCount));
56 __pImpl = value.__pImpl;
59 ImmutableString::~ImmutableString(void)
61 if (__pImpl->__refCount > 1)
63 Utility::_AtomicOperations::AtomicDec(&(__pImpl->__refCount));
73 ImmutableString::operator [](int index) const
75 return __pImpl->__pValue[index];
79 ImmutableString::Append(const ImmutableString& str) const
82 return ImmutableString(__pImpl->__pValue, str.GetPointer());
86 ImmutableString::CompareTo(const ImmutableString& str) const
88 if (__pImpl->__pValue == str.__pImpl->__pValue)
93 return wcscmp(__pImpl->__pValue, str.__pImpl->__pValue);
97 ImmutableString::Contains(const ImmutableString& str) const
99 return (wcsstr(__pImpl->__pValue, str.__pImpl->__pValue) != null);
103 ImmutableString::EndsWith(const ImmutableString& str) const
105 int strLen = str.__pImpl->__length;
106 SysTryReturn(NID_BASE, strLen > 0, false, E_INVALID_ARG,
107 "[%s] Invalid argument is used. The length of str(%d) MUST be greater than 0.", GetErrorMessage(E_INVALID_ARG), strLen);
109 SetLastResult(E_SUCCESS);
111 int curLen = __pImpl->__length;
112 if (strLen > curLen || curLen == 0)
116 else if (wcscmp(__pImpl->__pValue + (curLen - strLen), str.__pImpl->__pValue) == 0)
125 ImmutableString::Equals(const Object& obj) const
127 const ImmutableString* pOther = dynamic_cast< const ImmutableString* >(&obj);
134 if (__pImpl->__length != pOther->__pImpl->__length)
139 return (CompareTo(*pOther) == 0);
143 ImmutableString::EqualsCaseInsensitive(const ImmutableString& str) const
145 if (__pImpl->__length != str.__pImpl->__length)
150 if (__pImpl->__pValue == str.__pImpl->__pValue)
155 if (wcscasecmp(__pImpl->__pValue, str.__pImpl->__pValue) == 0)
164 ImmutableString::Format(int length, const wchar_t* pFormat, ...)
167 SysTryReturn(NID_BASE, pFormat != null, ImmutableString(L""), E_INVALID_ARG, "[%s] The pFormat is null.", GetErrorMessage(E_INVALID_ARG));
168 SysTryReturn(NID_BASE, length >= 0, ImmutableString(L""), E_INVALID_ARG,
169 "[%s] The length(%d) MUST be greater than or equal to 0.", GetErrorMessage(E_INVALID_ARG), length);
171 if ((*pFormat == L'\0') || (length == 0))
173 return ImmutableString(L"");
176 // Check "%n" and "%hn"
177 SysTryReturn(NID_BASE, wcsstr(pFormat, L"%n") == null, ImmutableString(L""), E_INVALID_ARG,
178 "[%s] (%ls) is not supported format.", GetErrorMessage(E_INVALID_ARG), pFormat);
179 SysTryReturn(NID_BASE, wcsstr(pFormat, L"%hn") == null, ImmutableString(L""), E_INVALID_ARG,
180 "[%s] (%ls) is not supported format.", GetErrorMessage(E_INVALID_ARG), pFormat);
183 va_start(args, pFormat);
185 _StringBuffer* pBuf = _StringBuffer::Format(length, pFormat, args);
189 SysTryReturn(NID_BASE, pBuf != null, ImmutableString(pBuf), E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
191 return ImmutableString(pBuf);
195 ImmutableString::GetCharAt(int indexAt, wchar_t& ret) const
197 SysTryReturnResult(NID_BASE, indexAt < __pImpl->__length, E_OUT_OF_RANGE,
198 "The indexAt(%d) MUST be less than the length of this ImmutableString(%d).", indexAt, __pImpl->__length);
199 SysTryReturnResult(NID_BASE, indexAt >= 0, E_OUT_OF_RANGE,
200 "The indexAt(%d) MUST be greater than or equal to 0.", indexAt);
202 ret = __pImpl->__pValue[indexAt];
207 ImmutableString::GetHashCode(void) const
209 if (__pImpl->__length == 0)
214 if (__pImpl->__hash == 0)
216 __pImpl->__hash = __pImpl->GetHashCode(__pImpl->__pValue);
218 return __pImpl->__hash;
222 ImmutableString::GetLength(void) const
224 return __pImpl->__length;
228 ImmutableString::GetPointer(void) const
230 return __pImpl->__pValue;
234 ImmutableString::IndexOf(wchar_t ch, int startIndex, int& indexOf) const
236 SysTryReturnResult(NID_BASE, startIndex < __pImpl->__length, E_OUT_OF_RANGE,
237 "The startIndex(%d) MUST be less than the length of this ImmutableString(%d).", startIndex, __pImpl->__length);
238 SysTryReturnResult(NID_BASE, startIndex >= 0, E_OUT_OF_RANGE,
239 "The startIndex(%d) MUST be greater than or equal to 0.", startIndex);
241 wchar_t* pBeg = __pImpl->__pValue + startIndex;
242 wchar_t* pFound = wcschr(pBeg, ch);
245 SysTryReturnResult(NID_BASE, pFound, E_OBJ_NOT_FOUND, "[%s] The expected wchar_t character is not found.",
246 GetErrorMessage(E_OBJ_NOT_FOUND), ch);
249 indexOf = static_cast< int >(pFound - __pImpl->__pValue);
254 ImmutableString::IndexOf(const ImmutableString& str, int startIndex, int& indexOf) const
256 SysTryReturnResult(NID_BASE, startIndex < __pImpl->__length, E_OUT_OF_RANGE,
257 "The startIndex(%d) MUST be less than the length of this ImmutableString(%d).", startIndex, __pImpl->__length);
258 SysTryReturnResult(NID_BASE, startIndex >= 0, E_OUT_OF_RANGE,
259 "The startIndex(%d) MUST be greater than or equal to 0.", startIndex);
263 indexOf = startIndex;
267 SysTryReturnResult(NID_BASE, __pImpl->__length >= str.__pImpl->__length, E_OBJ_NOT_FOUND, "[%s] The expected wchar_t string is not found.",
268 GetErrorMessage(E_OBJ_NOT_FOUND), str.GetPointer());
270 wchar_t* pStr = wcsstr(__pImpl->__pValue + startIndex, str.__pImpl->__pValue);
272 SysTryReturnResult(NID_BASE, pStr, E_OBJ_NOT_FOUND, "[%s] The expected wchar_t string is not found.",
273 GetErrorMessage(E_OBJ_NOT_FOUND), str.GetPointer());
275 indexOf = static_cast< int >(pStr - __pImpl->__pValue);
280 ImmutableString::Insert(const ImmutableString& str, int indexAt) const
283 SysTryReturn(NID_BASE, (indexAt >= 0) && (indexAt <= __pImpl->__length), ImmutableString(L""), E_OUT_OF_RANGE,
284 "[%s] The index(%d) MUST be greater than or equal to 0, and less than the length of this ImmutableString(%d).",
285 GetErrorMessage(E_OUT_OF_RANGE), indexAt, __pImpl->__length);
287 _StringBuffer* pBuf = __pImpl->Insert(str.__pImpl, indexAt);
289 SysTryReturn(NID_BASE, pBuf != null, ImmutableString(pBuf), E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
291 return ImmutableString(pBuf);
295 ImmutableString::IsEmpty(void) const
297 return (__pImpl->__length == 0);
301 ImmutableString::LastIndexOf(wchar_t ch, int startIndex, int& indexOf) const
303 SysTryReturnResult(NID_BASE, startIndex >= 0 && startIndex < __pImpl->__length, E_OUT_OF_RANGE,
304 "The startIndex(%d) MUST be greater than or equal to 0, and less than the length of this ImmutableString(%d).",
305 startIndex, __pImpl->__length);
307 wchar_t* pBeg = __pImpl->__pValue + startIndex;
308 wchar_t* pEnd = __pImpl->__pValue;
313 indexOf = static_cast< int >(pBeg - __pImpl->__pValue);
319 SysTryReturnResult(NID_BASE, false, E_OBJ_NOT_FOUND, "[%s] The expected wchar_t character is not found.",
320 GetErrorMessage(E_OBJ_NOT_FOUND), ch);
324 ImmutableString::LastIndexOf(const ImmutableString& str, int startIndex, int& indexOf) const
326 SysTryReturnResult(NID_BASE, startIndex >= 0 && startIndex < __pImpl->__length, E_OUT_OF_RANGE,
327 "The startIndex(%d) MUST be greater than or equal to 0, and less than the length of this ImmutableString(%d).",
328 startIndex, __pImpl->__length);
332 indexOf = startIndex;
336 SysTryReturnResult(NID_BASE, __pImpl->__length >= str.__pImpl->__length, E_OBJ_NOT_FOUND, "[%s] The expected wchar_t string is not found.",
337 GetErrorMessage(E_OBJ_NOT_FOUND), str.GetPointer());
339 const wchar_t* pStr = str.__pImpl->__pValue;
341 int length = str.__pImpl->__length;
343 SysTryReturnResult(NID_BASE, length <= startIndex, E_OBJ_NOT_FOUND, "[%s] The expected wchar_t string is not found.",
344 GetErrorMessage(E_OBJ_NOT_FOUND), str.GetPointer());
346 wchar_t* pBeg = __pImpl->__pValue + startIndex;
347 wchar_t* pEnd = __pImpl->__pValue;
351 if (wcsncmp(pBeg, pStr, length) == 0)
353 indexOf = (pBeg - __pImpl->__pValue);
360 SysTryReturnResult(NID_BASE, false, E_OBJ_NOT_FOUND, "[%s] The expected wchar_t string is not found.",
361 GetErrorMessage(E_OBJ_NOT_FOUND), str.GetPointer());
365 ImmutableString::Remove(int startIndex, int length) const
368 SysTryReturn(NID_BASE, ((startIndex >= 0) && (startIndex < __pImpl->__length)), ImmutableString(L""), E_OUT_OF_RANGE,
369 "[%s] The startIndex(%d) MUST be greater than or equal to 0, and less than the length of this ImmutableString(%d).",
370 GetErrorMessage(E_OUT_OF_RANGE), startIndex, __pImpl->__length);
372 SysTryReturn(NID_BASE, length >= 0, ImmutableString(L""), E_OUT_OF_RANGE,
373 "[%s] The length(%d) MUST be geater than or equal to 0.", GetErrorMessage(E_OUT_OF_RANGE), length);
375 int moveIndex = startIndex + length;
376 SysTryReturn(NID_BASE, moveIndex <= __pImpl->__length, ImmutableString(L""), E_OUT_OF_RANGE,
377 "[%s] The startIndex(%d) + length(%d) MUST be less than or equal to the length of this ImmutableString(%d).",
378 GetErrorMessage(E_OUT_OF_RANGE), startIndex, length, __pImpl->__length);
380 _StringBuffer* pBuf = __pImpl->Remove(startIndex, length);
382 SysTryReturn(NID_BASE, pBuf != null, ImmutableString(pBuf), E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
384 return ImmutableString(pBuf);
388 ImmutableString::Replace(wchar_t original, wchar_t replace) const
391 _StringBuffer* pBuf = __pImpl->Replace(original, replace);
393 SysTryReturn(NID_BASE, pBuf != null, ImmutableString(pBuf), E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
395 return ImmutableString(pBuf);
399 ImmutableString::Replace(const ImmutableString& org, const ImmutableString& rep, int startIndex) const
402 const int orgLen = org.__pImpl->__length;
403 SysTryReturn(NID_BASE, orgLen > 0, ImmutableString(L""), E_INVALID_ARG, "[%s] The length of org(%d) MUST be greater than 0.",
404 GetErrorMessage(E_INVALID_ARG), orgLen);
406 SysTryReturn(NID_BASE, startIndex >= 0 && startIndex < __pImpl->__length, ImmutableString(L""), E_OUT_OF_RANGE,
407 "[%s] The startIndex(%d) MUST be greater than or equal to 0, and less than the length of this ImmutableString(%d).",
408 GetErrorMessage(E_OUT_OF_RANGE), startIndex, __pImpl->__length);
410 SysTryReturn(NID_BASE, orgLen + startIndex <= __pImpl->__length, ImmutableString(L""), E_OUT_OF_RANGE,
411 "[%s] The length of org(%d) + startIndex(%d) MUST be less than or equal to the length of this ImmutableString(%d).",
412 GetErrorMessage(E_OUT_OF_RANGE), org.__pImpl->__length, startIndex, __pImpl->__length);
414 _StringBuffer* pBuf = __pImpl->Replace(org.__pImpl, rep.__pImpl, startIndex);
416 SysTryReturn(NID_BASE, pBuf != null, ImmutableString(pBuf), E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
418 return ImmutableString(pBuf);
422 ImmutableString::Replace(const ImmutableString& org, const ImmutableString& rep) const
424 return Replace(org, rep, 0);
428 ImmutableString::Reverse(void) const
431 _StringBuffer* pBuf = __pImpl->Reverse();
433 SysTryReturn(NID_BASE, pBuf != null, ImmutableString(pBuf), E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
435 return ImmutableString(pBuf);
439 ImmutableString::SetCharAt(wchar_t ch, int indexAt) const
442 SysTryReturn(NID_BASE, indexAt >= 0 && indexAt < __pImpl->__length, ImmutableString(L""), E_OUT_OF_RANGE,
443 "[%s] The indexAt(%d) MUST be greater than or equal to 0, and less then the length of this string(%d).",
444 GetErrorMessage(E_OUT_OF_RANGE), indexAt, __pImpl->__length);
446 _StringBuffer* pBuf = __pImpl->SetCharAt(ch, indexAt);
448 SysTryReturn(NID_BASE, pBuf != null, ImmutableString(pBuf), E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
450 return ImmutableString(pBuf);
454 ImmutableString::StartsWith(const ImmutableString& str, int startIndex) const
457 SysTryReturn(NID_BASE, startIndex >= 0 && startIndex < __pImpl->__length, false, E_OUT_OF_RANGE,
458 "[%s] The startIndex(%d) MUST be greater than or equal to 0, and less than the length of this string(%d).",
459 GetErrorMessage(E_OUT_OF_RANGE), startIndex, __pImpl->__length);
461 if (str.__pImpl->__length > __pImpl->__length)
466 if ((wcsncmp(__pImpl->__pValue + startIndex, str.__pImpl->__pValue, str.__pImpl->__length) == 0))
474 ImmutableString::StartsWith(const ImmutableString& str) const
476 return StartsWith(str, 0);
480 ImmutableString::SubString(int startIndex) const
483 SysTryReturn(NID_BASE, startIndex >= 0 && startIndex < __pImpl->__length, ImmutableString(L""), E_OUT_OF_RANGE,
484 "[%s] The startIndex(%d) MUST be greater than or equal to 0, and less than the length of this ImmutableString(%d).",
485 GetErrorMessage(E_OUT_OF_RANGE), startIndex, __pImpl->__length);
487 return SubString(startIndex, __pImpl->__length - startIndex);
491 ImmutableString::SubString(int startIndex, int length) const
494 SysTryReturn(NID_BASE, startIndex >= 0 && startIndex < __pImpl->__length, ImmutableString(L""), E_OUT_OF_RANGE,
495 "[%s] The startIndex(%d) MUST be greater than or equal to 0, and less than the length of this ImmutableString(%d).",
496 GetErrorMessage(E_OUT_OF_RANGE), startIndex, __pImpl->__length);
497 SysTryReturn(NID_BASE, length >= 0, ImmutableString(L""), E_OUT_OF_RANGE,
498 "[%s] The length(%d) MUST be greater than 0.", GetErrorMessage(E_OUT_OF_RANGE), length);
499 SysTryReturn(NID_BASE, startIndex + length <= __pImpl->__length, ImmutableString(L""), E_OUT_OF_RANGE,
500 "[%s] The startIndex(%d) + length(%d) MUST be less than or equal to the length of this ImmutableString(%d).",
501 GetErrorMessage(E_OUT_OF_RANGE), startIndex, length, __pImpl->__length);
503 _StringBuffer* pBuf = __pImpl->SubString(startIndex, length);
505 SysTryReturn(NID_BASE, pBuf != null, ImmutableString(pBuf), E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
507 return ImmutableString(pBuf);
511 ImmutableString::ToUpperCase(void) const
514 _StringBuffer* pBuf = __pImpl->ToUpperCase();
516 SysTryReturn(NID_BASE, pBuf != null, ImmutableString(pBuf), E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
518 return ImmutableString(pBuf);
522 ImmutableString::ToLowerCase(void) const
525 _StringBuffer* pBuf = __pImpl->ToLowerCase();
527 SysTryReturn(NID_BASE, pBuf != null, ImmutableString(pBuf), E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
529 return ImmutableString(pBuf);
533 ImmutableString::Trim(void) const
536 _StringBuffer* pBuf = __pImpl->Trim();
538 SysTryReturn(NID_BASE, pBuf != null, ImmutableString(pBuf), E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
540 return ImmutableString(pBuf);
543 ImmutableString::ImmutableString(const wchar_t* pStr1, const wchar_t* pStr2)
544 : __pImpl(new (std::nothrow) _StringBuffer(pStr1, pStr2))
546 SysTryReturnVoidResult(NID_BASE, __pImpl != null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
549 ImmutableString::ImmutableString(_StringBuffer* pBuf)