{
const float String::GROWTH_FACTOR = 1.5;
+const int String::UNSHAREABLE = Integer::VALUE_MAX;
String::String(void)
: __capacity(0)
}
String::String(const String& value)
- : __capacity(value.__capacity)
- , __length(value.__length)
- , __hash(value.__hash)
+ : __capacity(0)
+ , __length(0)
+ , __hash(0)
, __pRefCount(null)
- , __pValue(value.__pValue)
+ , __pValue(null)
, __pStringImpl(null)
{
SysTryReturnVoidResult(NID_BASE, value.__length >= 0, E_OUT_OF_RANGE, "The length has to be greater than 0.");
- _String::AtomicInc(value.__pRefCount);
- __pRefCount = value.__pRefCount;
+ if (*(value.__pRefCount) != UNSHAREABLE)
+ {
+ _String::AtomicInc(value.__pRefCount);
+ __pRefCount = value.__pRefCount;
+ __pValue = value.__pValue;
+ __capacity = value.__capacity;
+ __length = value.__length;
+ __hash = value.__hash;
+ }
+ else
+ {
+ 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.");
+
+ wcsncpy(__pValue, value.__pValue, length);
+ __pValue[length] = '\0';
+ __length = length;
+ }
}
String::~String(void)
{
- if (*__pRefCount == 1)
+ if (*__pRefCount == 1 || *__pRefCount == UNSHAREABLE)
{
delete[] __pValue;
delete __pRefCount;
"[%s] The index(%d) MUST be greater than or equal to 0, and less than the length of this string(%d).",
GetErrorMessage(E_OUT_OF_RANGE), index, __length);
- if (*__pRefCount > 1)
- {
- result r = CopyOnWrite(__capacity);
- SysTryReturn(NID_BASE, r == E_SUCCESS, ch, E_OUT_OF_MEMORY, "Memory allocation failed.");
- }
+ result r = AboutToModify(__capacity, true);
+ SysTryReturn(NID_BASE, r == E_SUCCESS, ch, E_OUT_OF_MEMORY, "Memory allocation failed.");
__hash = 0;
return __pValue[index];
int length = (wcslen(p) + __length);
- if (*__pRefCount > 1)
+ if (*__pRefCount > 1 && *__pRefCount != UNSHAREABLE)
{
wchar_t* pValue = __pValue;
SysTryReturnResult(NID_BASE, AllocateCapacity(length) != false, E_OUT_OF_MEMORY, "Memory allocation failed.");
"The indexAt(%d) MUST be greater than or equal to 0, and less than or equal to the length of this string(%d).",
indexAt, __length);
- if (*__pRefCount > 1)
- {
- result r = CopyOnWrite(__capacity);
- SysTryReturnResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
- }
+ result r = AboutToModify(__capacity);
+ SysTryReturnResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
int length = (__length + 1);
- result r = EnsureCapacity(length);
+ r = EnsureCapacity(length);
SysTryReturn(NID_BASE, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
wmemmove((__pValue + indexAt + 1), (__pValue + indexAt), ((__length + 1) - indexAt));
return E_SUCCESS;
}
- if (*__pRefCount > 1)
- {
- result r = CopyOnWrite(__capacity);
- SysTryReturnResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
- }
+ result r = AboutToModify(__capacity);
+ SysTryReturnResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
- result r = EnsureCapacity(__length + length);
+ r = EnsureCapacity(__length + length);
SysTryReturn(NID_BASE, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
wmemmove((__pValue + indexAt + length), (__pValue + indexAt), ((__length + 1) - indexAt));
"The startIndex(%d) + count(%d) MUST be less than or equal to the length of this string(%d).",
startIndex, count, __length);
- if (*__pRefCount > 1)
- {
- result r = CopyOnWrite(__capacity);
- SysTryReturnResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
- }
+ result r = AboutToModify(__capacity);
+ SysTryReturnResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
wmemmove(__pValue + startIndex, __pValue + moveIndex, (__length - moveIndex) + 1);
__length -= count;
void
String::Replace(wchar_t original, wchar_t replace)
{
- if (*__pRefCount > 1)
- {
- result r = CopyOnWrite(__capacity);
- SysTryReturnVoidResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
- }
+ result r = AboutToModify(__capacity);
+ SysTryReturnVoidResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
for (int length = __length; length >= 0; --length)
{
if (count > 0)
{
- if (*__pRefCount > 1)
- {
- result r = CopyOnWrite(__capacity);
- SysTryReturnResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
- }
+ result r = AboutToModify(__capacity);
+ SysTryReturnResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
const int newLength = (count * (repLen - orgLen)) + __length;
- result r = EnsureCapacity(newLength);
+ r = EnsureCapacity(newLength);
SysTryReturn(NID_BASE, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
wchar_t* pBeg = (__pValue + startIndex);
void
String::Reverse(void)
{
- if (*__pRefCount > 1)
- {
- result r = CopyOnWrite(__capacity);
- SysTryReturnVoidResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
- }
+ result r = AboutToModify(__capacity);
+ SysTryReturnVoidResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
wchar_t* pBeg = __pValue;
wchar_t* pEnd = __pValue + __length - 1;
"[%s] The indexAt(%d) MUST be greater than or equal to 0, and less then the length of this string(%d).",
GetErrorMessage(E_OUT_OF_RANGE), indexAt, __length);
- if (*__pRefCount > 1)
- {
- result r = CopyOnWrite(__capacity);
- SysTryReturnResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
- }
+ result r = AboutToModify(__capacity);
+ SysTryReturnResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
__pValue[indexAt] = ch;
__hash = 0;
SysTryReturnResult(NID_BASE, newLength >= 0, E_INVALID_ARG, "The newLength(%d) MUST be greater than or equal to 0.",
newLength);
- if (*__pRefCount > 1)
- {
- result r = CopyOnWrite(__capacity);
- SysTryReturnResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
- }
+ result r = AboutToModify(__capacity);
+ SysTryReturnResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
static const wchar_t SPACE = 0x0020;
- result r = EnsureCapacity(newLength);
+ r = EnsureCapacity(newLength);
SysTryReturn(NID_BASE, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
if (newLength > __length)
void
String::ToLower(void)
{
- if (*__pRefCount > 1)
- {
- result r = CopyOnWrite(__capacity);
- SysTryReturnVoidResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
- }
+ result r = AboutToModify(__capacity);
+ SysTryReturnVoidResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
String str(__length + 1);
void
String::ToLowerCase(void)
{
- if (*__pRefCount > 1)
- {
- result r = CopyOnWrite(__capacity);
- SysTryReturnVoidResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
- }
+ result r = AboutToModify(__capacity);
+ SysTryReturnVoidResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
String str(__length + 1);
void
String::ToUpper(void)
{
- if (*__pRefCount > 1)
- {
- result r = CopyOnWrite(__capacity);
- SysTryReturnVoidResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
- }
+ result r = AboutToModify(__capacity);
+ SysTryReturnVoidResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
String str(__length + 1);
void
String::ToUpperCase(void)
{
- if (*__pRefCount > 1)
- {
- result r = CopyOnWrite(__capacity);
- SysTryReturnVoidResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
- }
+ result r = AboutToModify(__capacity);
+ SysTryReturnVoidResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
String str(__length + 1);
return;
}
- if (*__pRefCount > 1)
- {
- result r = CopyOnWrite(__capacity);
- SysTryReturnVoidResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed");
- }
+ result r = AboutToModify(__capacity);
+ SysTryReturnVoidResult(NID_BASE, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed");
if (trimRight)
{
}
result
-String::CopyOnWrite(int capacity)
+String::AboutToModify(int capacity, bool isUnshareable)
{
- wchar_t* pValue = __pValue;
- std::unique_ptr< int > pRefCntTemp(new (std::nothrow) int(1));
- SysTryReturnResult(NID_BASE, pRefCntTemp != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
- SysTryReturnResult(NID_BASE, AllocateCapacity(capacity) != false, E_OUT_OF_MEMORY, "Memory allocation failed.");
+ if (*__pRefCount > 1 && *__pRefCount != UNSHAREABLE)
+ {
+ wchar_t* pValue = __pValue;
+ std::unique_ptr< int > pRefCntTemp(new (std::nothrow) int(1));
+ SysTryReturnResult(NID_BASE, pRefCntTemp != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
+ SysTryReturnResult(NID_BASE, AllocateCapacity(capacity), E_OUT_OF_MEMORY, "Memory allocation failed.");
+
+ wcsncpy(__pValue, pValue, __length);
+ __pValue[__length] = '\0';
+
+ _String::AtomicDec(__pRefCount);
+ __pRefCount = pRefCntTemp.release();
+ }
+
+ if (isUnshareable)
+ {
+ *__pRefCount = UNSHAREABLE;
+ }
- wcsncpy(__pValue, pValue, __length);
- __pValue[__length] = '\0';
- _String::AtomicDec(__pRefCount);
- __pRefCount = pRefCntTemp.release();
return E_SUCCESS;
}