Merge "[Native][25/11/2013][Add]Adding BigInteger class" into tizen
[platform/framework/native/appfw.git] / src / base / FBaseString.cpp
index ed75249..abb38f1 100644 (file)
@@ -36,7 +36,7 @@
 #include <FBaseResult.h>
 #include <FBaseSysLog.h>
 #include <unique_ptr.h>
-#include "FBase_String.h"
+#include "FBaseUtil_AtomicOperations.h"
 #include "FBaseUtil_IcuConverter.h"
 
 namespace Tizen { namespace Base
@@ -98,11 +98,6 @@ String::String(const wchar_t* pValue)
        , __pValue(null)
        , __pStringImpl(null)
 {
-       int length = (pValue != null) ? wcslen(pValue) : 0;
-
-       SysTryReturnVoidResult(NID_BASE, length >= 0, E_OUT_OF_RANGE,
-               "String has wrong length. The length has to be more bigger than 0.");
-
        if (pValue == null)
        {
                result r = InitializeToDefault(DEFAULT_CAPACITY);
@@ -110,6 +105,7 @@ String::String(const wchar_t* pValue)
        }
        else
        {
+               int length = wcslen(pValue);
                result r = InitializeToDefault(length + DEFAULT_CAPACITY);
                SysTryReturnVoidResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
 
@@ -156,11 +152,9 @@ String::String(const String& value)
        , __pValue(null)
        , __pStringImpl(null)
 {
-       SysTryReturnVoidResult(NID_BASE, value.__length >= 0, E_OUT_OF_RANGE, "The length has to be greater than 0.");
-
        if (*(value.__pRefCount) != UNSHAREABLE)
        {
-               _String::AtomicInc(value.__pRefCount);
+               Utility::_AtomicOperations::AtomicInc(value.__pRefCount);
                __pRefCount = value.__pRefCount;
                __pValue = value.__pValue;
                __capacity = value.__capacity;
@@ -171,9 +165,6 @@ String::String(const String& value)
        {
                int length = wcslen(value.__pValue);
 
-               SysTryReturnVoidResult(NID_BASE, length >= 0, E_OUT_OF_RANGE,
-                       "String has wrong length. The length has to be more bigger than 0.");
-
                result r = InitializeToDefault(length + DEFAULT_CAPACITY);
                SysTryReturnVoidResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
 
@@ -192,7 +183,7 @@ String::~String(void)
        }
        else
        {
-               _String::AtomicDec(__pRefCount);
+               Utility::_AtomicOperations::AtomicDec(__pRefCount);
                __pRefCount = null;
        }
 }
@@ -293,7 +284,6 @@ String::operator ==(const String& rhs) const
        {
                return false;
        }
-
        return(CompareTo(rhs) == 0);
 }
 
@@ -396,7 +386,7 @@ String::Append(const wchar_t* p)
                SysTryReturnResult(NID_BASE, pRefCntTemp != null, E_OUT_OF_MEMORY, "Memory allocation failed");
 
                wcsncpy(__pValue, pValue, __length);
-               _String::AtomicDec(__pRefCount);
+               Utility::_AtomicOperations::AtomicDec(__pRefCount);
                __pRefCount = pRefCntTemp.release();
        }
 
@@ -567,23 +557,29 @@ String::Format(int length, const wchar_t* pFormat, ...)
 int
 String::GetHashCode(void) const
 {
-       int hash = 0;
+       if (__length == 0)
+       {
+               return 0;
+       }
 
        if (__hash == 0)
        {
+               const int DEFAULT_HASH_VALUE = 352654597;
+               const int HASH_MULTIPLIER = 1566083941;
+
+               int num = DEFAULT_HASH_VALUE;
+               int num2 = DEFAULT_HASH_VALUE;
                wchar_t* pStr = __pValue;
-               for (int i = 0; i < __length; ++i)
+               for (int i = __length; i >= 2 ; i -= 4)
                {
-                       hash = (hash << 5) - hash + (int) *pStr++;
+                   num = (((num << 5) + num) + (num >> 27)) ^ pStr[0];
+                   num2 = (((num2 << 5) + num2) + (num2 >> 27)) ^ pStr[1];
+                   pStr += 2;
                }
-               __hash = hash;
+               num = (((num << 5) + num) + (num >> 27)) ^ pStr[0];
+               __hash = num + (num2 * HASH_MULTIPLIER);
        }
-       else
-       {
-               hash = __hash;
-       }
-
-       return hash;
+       return __hash;
 }
 
 result
@@ -625,9 +621,9 @@ String::IndexOf(wchar_t ch, int startIndex, int& indexOf) const
 result
 String::IndexOf(const String& str, int startIndex, int& indexOf) const
 {
-       SysTryReturnResult(NID_BASE, (startIndex < __length), E_OUT_OF_RANGE,
+       SysTryReturnResult(NID_BASE, startIndex < __length, E_OUT_OF_RANGE,
                "The startIndex(%d) MUST be less than the length of this string(%d).", startIndex, __length);
-       SysTryReturnResult(NID_BASE, (startIndex >= 0), E_OUT_OF_RANGE,
+       SysTryReturnResult(NID_BASE, startIndex >= 0, E_OUT_OF_RANGE,
                "The startIndex(%d) MUST be greater than or equal to 0.", startIndex);
 
        if (str.IsEmpty())
@@ -902,7 +898,7 @@ result
 String::Replace(const String& org, const String& rep)
 {
        result r = Replace(org, rep, 0);
-       SysTryReturn(NID_BASE, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
+       SysTryReturnResult(NID_BASE, r == E_SUCCESS, r, "Propagating.");
 
        return r;
 }
@@ -910,8 +906,7 @@ String::Replace(const String& org, const String& rep)
 result
 String::Replace(const String& org, const String& rep, int startIndex)
 {
-       const int orgLen = org.__length;
-       SysTryReturnResult(NID_BASE, orgLen > 0, E_INVALID_ARG, "The length of org(%d) MUST be greater than 0.", orgLen);
+       SysTryReturnResult(NID_BASE, org.__length > 0, E_INVALID_ARG, "The length of org MUST be greater than 0.");
 
        SysTryReturnResult(NID_BASE,
                startIndex >= 0 && startIndex < __length, E_OUT_OF_RANGE,
@@ -923,68 +918,55 @@ String::Replace(const String& org, const String& rep, int startIndex)
                return E_SUCCESS;
        }
 
+       int orgLen = org.__length;
+       int repLen = rep.__length;
        if ((orgLen == __length) && (*this == org))
        {
-               const int newLength = rep.__length;
-               if (EnsureCapacity(newLength) != E_SUCCESS)
-               {
-                       SetCapacity(newLength);
-               }
+               result r = AboutToModify(__capacity);
+               SysTryReturnResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
+
+               r = EnsureCapacity(repLen);
+               SysTryReturnResult(NID_BASE, r == E_SUCCESS, r, "Propagating.");
 
-               wcsncpy(__pValue, rep.__pValue, rep.__length);
+               wcsncpy(__pValue, rep.__pValue, repLen);
 
-               __length = rep.__length;
+               __length = repLen;
                __pValue[__length] = '\0';
                __hash = 0;
 
                return E_SUCCESS;
        }
 
-       int repLen = rep.__length;
+       int matchedCount = 0;
 
-       wchar_t* pOrg = org.__pValue;
-       wchar_t* pRep = rep.__pValue;
+       wchar_t* pBeg = __pValue + startIndex;
+       wchar_t* pMatch = null;
 
-       int count = 0;
+       while ((pMatch = wcsstr(pBeg, org.__pValue)) != null)
        {
-               wchar_t* pBeg = (__pValue + startIndex);
-               wchar_t* pEnd = pBeg + __length;
-               while (pBeg < pEnd)
-               {
-                       wchar_t* pTarget = null;
-                       while ((pTarget = (wchar_t*) wcsstr(pBeg, pOrg)) != null)
-                       {
-                               ++count;
-                               pBeg = pTarget + orgLen;
-                       }
-                       pBeg += wcslen(pBeg) + 1;
-               }
+               ++matchedCount;
+               pBeg = pMatch + orgLen;
        }
 
-       if (count > 0)
+       if (matchedCount > 0)
        {
                result r = AboutToModify(__capacity);
                SysTryReturnResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
 
-               const int newLength = (count * (repLen - orgLen)) + __length;
+               const int newLength = (matchedCount * (repLen - orgLen)) + __length;
                r = EnsureCapacity(newLength);
-               SysTryReturn(NID_BASE, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
+               SysTryReturnResult(NID_BASE, r == E_SUCCESS, r, "Propagating.");
 
-               wchar_t* pBeg = (__pValue + startIndex);
-               wchar_t* pEnd = pBeg + __length;
-               while (pBeg < pEnd)
+               pBeg = __pValue + startIndex;
+               while ((pMatch = wcsstr(pBeg, org.__pValue)) != null)
                {
-                       wchar_t* pTarget = null;
-                       while ((pTarget = (wchar_t*) wcsstr(pBeg, pOrg)) != null)
-                       {
-                               int balance = __length - int(pTarget - (__pValue + startIndex) + orgLen);
-                               wmemmove(pTarget + repLen, pTarget + orgLen, balance);
-                               wmemcpy(pTarget, pRep, repLen);
-                               pBeg = pTarget + repLen;
-                               pTarget[repLen + balance] = 0;
-                               __length += (repLen - orgLen);
-                       }
-                       pBeg += (wcslen(pBeg) + 1);
+                       int count = __length - (pMatch - __pValue) - orgLen;
+                       wmemmove(pMatch + repLen, pMatch + orgLen, count);
+                       wmemcpy(pMatch, rep.__pValue, repLen);
+
+                       pBeg = pMatch + repLen;
+                       pMatch[repLen + count] = '\0';
+                       __length += (repLen - orgLen);
                }
 
                __length = newLength;
@@ -1044,7 +1026,7 @@ String::SetCapacity(int capacity)
                {
                        std::unique_ptr< int > pRefCntTemp(new (std::nothrow) int(1));
                        SysTryReturnResult(NID_BASE, pRefCntTemp != null, E_OUT_OF_MEMORY, "Memory allocation failed");
-                       _String::AtomicDec(__pRefCount);
+                       Utility::_AtomicOperations::AtomicDec(__pRefCount);
                        __pRefCount = pRefCntTemp.release();
                }
        }
@@ -1434,18 +1416,7 @@ String::Contains(const String& str) const
                return true;
        }
 
-       wchar_t* pStart = __pValue;
-       wchar_t* pEnd = pStart + __length;
-       while (pStart < pEnd)
-       {
-               while (wcsstr(pStart, str.__pValue) != null)
-               {
-                       return true;
-               }
-               ++pStart;
-       }
-
-       return false;
+       return (wcsstr(__pValue, str.__pValue) != null);
 }
 
 bool
@@ -1493,7 +1464,7 @@ String::ExpandCapacity(int minCapacity)
                        std::unique_ptr< int > pRefCntTemp(new (std::nothrow) int(1));
                        SysTryReturn(NID_BASE, pRefCntTemp != null, false, E_OUT_OF_MEMORY, "[%s] Memory allocation failed",
                                GetErrorMessage(E_OUT_OF_MEMORY));
-                       _String::AtomicDec(__pRefCount);
+                       Utility::_AtomicOperations::AtomicDec(__pRefCount);
                        __pRefCount = pRefCntTemp.release();
                }
        }
@@ -1528,7 +1499,7 @@ String::AboutToModify(int capacity, bool isUnshareable)
                wcsncpy(__pValue, pValue, __length);
                __pValue[__length] = '\0';
 
-               _String::AtomicDec(__pRefCount);
+               Utility::_AtomicOperations::AtomicDec(__pRefCount);
                __pRefCount = pRefCntTemp.release();
        }