Revert "FX_BOOL considered harmful, part 2."
[pdfium.git] / core / src / fxcrt / fx_basic_wstring.cpp
index 0945d2f..b6b5955 100644 (file)
@@ -4,66 +4,42 @@
 
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
+#include <stddef.h>  // For offsetof().
+
 #include "../../include/fxcrt/fx_basic.h"
-#include "../../../third_party/numerics/safe_math.h"
+#include "../../../third_party/base/numerics/safe_math.h"
 
-static CFX_StringDataW* FX_AllocStringW(int nLen)
+// static
+CFX_WideString::StringData* CFX_WideString::StringData::Create(int nLen)
 {
+    // TODO(palmer): |nLen| should really be declared as |size_t|, or
+    // at least unsigned.
     if (nLen == 0 || nLen < 0) {
         return NULL;
     }
 
-    base::CheckedNumeric<int> iSize = static_cast<int>(sizeof(FX_WCHAR));
-    iSize *= nLen + 1;
-    iSize += sizeof(long) * 3;
-    CFX_StringDataW* pData = (CFX_StringDataW*)FX_Alloc(FX_BYTE, iSize.ValueOrDie());
-    if (!pData) {
-        return NULL;
-    }
+    // Fixed portion of header plus a NUL wide char not in m_nAllocLength.
+    int overhead = offsetof(StringData, m_String) + sizeof(FX_WCHAR);
+    pdfium::base::CheckedNumeric<int> iSize = nLen;
+    iSize *= sizeof(FX_WCHAR);
+    iSize += overhead;
 
-    // TODO(palmer): |nLen| should really be declared as |size_t|, but for
-    // now I just want to fix the overflow without changing any interfaces.
-    // Declaring |nLen| as |size_t| will also simplify the above code
-    // somewhat.
-    pData->m_nAllocLength = nLen;
-    pData->m_nDataLength = nLen;
-    pData->m_nRefs = 1;
-    pData->m_String[nLen] = 0;
-    return pData;
-}
-static void FX_ReleaseStringW(CFX_StringDataW* pData)
-{
-    if (pData == NULL) {
-        return;
-    }
-    pData->m_nRefs --;
-    if (pData->m_nRefs <= 0) {
-        FX_Free(pData);
-    }
+    // Now round to an 8-byte boundary. We'd expect that this is the minimum
+    // granularity of any of the underlying allocators, so there may be cases
+    // where we can save a re-alloc when adding a few characters to a string
+    // by using this otherwise wasted space.
+    iSize += 7;
+    int totalSize = iSize.ValueOrDie() & ~7;
+    int usableLen = (totalSize - overhead) / sizeof(FX_WCHAR);
+    FXSYS_assert(usableLen >= nLen);
+
+    void* pData = FX_Alloc(uint8_t, iSize.ValueOrDie());
+    return new (pData) StringData(nLen, usableLen);
 }
 CFX_WideString::~CFX_WideString()
 {
-    if (m_pData == NULL) {
-        return;
-    }
-    m_pData->m_nRefs --;
-    if (m_pData->m_nRefs < 1) {
-        FX_Free(m_pData);
-    }
-}
-void CFX_WideString::InitStr(FX_LPCWSTR lpsz, FX_STRSIZE nLen)
-{
-    if (nLen < 0) {
-        nLen = lpsz ? (FX_STRSIZE)FXSYS_wcslen(lpsz) : 0;
-    }
-    if (nLen) {
-        m_pData = FX_AllocStringW(nLen);
-        if (!m_pData) {
-            return;
-        }
-        FXSYS_memcpy32(m_pData->m_String, lpsz, nLen * sizeof(FX_WCHAR));
-    } else {
-        m_pData = NULL;
+    if (m_pData) {
+        m_pData->Release();
     }
 }
 CFX_WideString::CFX_WideString(const CFX_WideString& stringSrc)
@@ -74,15 +50,28 @@ CFX_WideString::CFX_WideString(const CFX_WideString& stringSrc)
     }
     if (stringSrc.m_pData->m_nRefs >= 0) {
         m_pData = stringSrc.m_pData;
-        m_pData->m_nRefs ++;
+        m_pData->Retain();
     } else {
         m_pData = NULL;
         *this = stringSrc;
     }
 }
+CFX_WideString::CFX_WideString(const FX_WCHAR* lpsz, FX_STRSIZE nLen) {
+    if (nLen < 0) {
+        nLen = lpsz ? FXSYS_wcslen(lpsz) : 0;
+    }
+    if (nLen) {
+        m_pData = StringData::Create(nLen);
+        if (m_pData) {
+            FXSYS_memcpy(m_pData->m_String, lpsz, nLen * sizeof(FX_WCHAR));
+        }
+    } else {
+        m_pData = NULL;
+    }
+}
 CFX_WideString::CFX_WideString(FX_WCHAR ch)
 {
-    m_pData = FX_AllocStringW(1);
+    m_pData = StringData::Create(1);
     if (m_pData) {
         m_pData->m_String[0] = ch;
     }
@@ -93,9 +82,9 @@ CFX_WideString::CFX_WideString(const CFX_WideStringC& str)
         m_pData = NULL;
         return;
     }
-    m_pData = FX_AllocStringW(str.GetLength());
+    m_pData = StringData::Create(str.GetLength());
     if (m_pData) {
-        FXSYS_memcpy32(m_pData->m_String, str.GetPtr(), str.GetLength()*sizeof(FX_WCHAR));
+        FXSYS_memcpy(m_pData->m_String, str.GetPtr(), str.GetLength()*sizeof(FX_WCHAR));
     }
 }
 CFX_WideString::CFX_WideString(const CFX_WideStringC& str1, const CFX_WideStringC& str2)
@@ -105,10 +94,10 @@ CFX_WideString::CFX_WideString(const CFX_WideStringC& str1, const CFX_WideString
     if (nNewLen == 0) {
         return;
     }
-    m_pData = FX_AllocStringW(nNewLen);
+    m_pData = StringData::Create(nNewLen);
     if (m_pData) {
-        FXSYS_memcpy32(m_pData->m_String, str1.GetPtr(), str1.GetLength()*sizeof(FX_WCHAR));
-        FXSYS_memcpy32(m_pData->m_String + str1.GetLength(), str2.GetPtr(), str2.GetLength()*sizeof(FX_WCHAR));
+        FXSYS_memcpy(m_pData->m_String, str1.GetPtr(), str1.GetLength()*sizeof(FX_WCHAR));
+        FXSYS_memcpy(m_pData->m_String + str1.GetLength(), str2.GetPtr(), str2.GetLength()*sizeof(FX_WCHAR));
     }
 }
 void CFX_WideString::ReleaseBuffer(FX_STRSIZE nNewLength)
@@ -118,7 +107,7 @@ void CFX_WideString::ReleaseBuffer(FX_STRSIZE nNewLength)
     }
     CopyBeforeWrite();
     if (nNewLength == -1) {
-        nNewLength = m_pData ? (FX_STRSIZE)FXSYS_wcslen(m_pData->m_String) : 0;
+        nNewLength = m_pData ? FXSYS_wcslen(m_pData->m_String) : 0;
     }
     if (nNewLength == 0) {
         Empty();
@@ -128,12 +117,12 @@ void CFX_WideString::ReleaseBuffer(FX_STRSIZE nNewLength)
     m_pData->m_nDataLength = nNewLength;
     m_pData->m_String[nNewLength] = 0;
 }
-const CFX_WideString& CFX_WideString::operator=(FX_LPCWSTR lpsz)
+const CFX_WideString& CFX_WideString::operator=(const FX_WCHAR* lpsz)
 {
     if (lpsz == NULL || lpsz[0] == 0) {
         Empty();
     } else {
-        AssignCopy((FX_STRSIZE)FXSYS_wcslen(lpsz), lpsz);
+        AssignCopy(FXSYS_wcslen(lpsz), lpsz);
     }
     return *this;
 }
@@ -160,7 +149,7 @@ const CFX_WideString& CFX_WideString::operator=(const CFX_WideString& stringSrc)
         Empty();
         m_pData = stringSrc.m_pData;
         if (m_pData) {
-            m_pData->m_nRefs ++;
+            m_pData->Retain();
         }
     }
     return *this;
@@ -170,10 +159,10 @@ const CFX_WideString& CFX_WideString::operator+=(FX_WCHAR ch)
     ConcatInPlace(1, &ch);
     return *this;
 }
-const CFX_WideString& CFX_WideString::operator+=(FX_LPCWSTR lpsz)
+const CFX_WideString& CFX_WideString::operator+=(const FX_WCHAR* lpsz)
 {
     if (lpsz) {
-        ConcatInPlace((FX_STRSIZE)FXSYS_wcslen(lpsz), lpsz);
+        ConcatInPlace(FXSYS_wcslen(lpsz), lpsz);
     }
     return *this;
 }
@@ -193,41 +182,16 @@ const CFX_WideString& CFX_WideString::operator+=(const CFX_WideStringC& string)
     ConcatInPlace(string.GetLength(), string.GetPtr());
     return *this;
 }
-bool operator==(const CFX_WideString& s1, FX_LPCWSTR s2)
-{
-    return s1.Equal(s2);
-}
-bool operator==(FX_LPCWSTR s1, const CFX_WideString& s2)
-{
-    return s2.Equal(s1);
-}
-bool operator==(const CFX_WideString& s1, const CFX_WideString& s2)
-{
-    return s1.Equal(s2);
-}
-bool operator==(const CFX_WideString& s1, const CFX_WideStringC& s2)
-{
-    return s1.Equal(s2);
-}
-bool operator==(const CFX_WideStringC& s1, const CFX_WideString& s2)
-{
-    return s2.Equal(s1);
-}
-bool operator != (const CFX_WideString& s1, FX_LPCWSTR s2)
-{
-    return !s1.Equal(s2);
-}
-bool operator!=(const CFX_WideString& s1, const CFX_WideString& s2)
-{
-    return !s1.Equal(s2);
-}
-bool operator!=(const CFX_WideString& s1, const CFX_WideStringC& s2)
+bool CFX_WideString::Equal(const wchar_t* ptr) const
 {
-    return !s1.Equal(s2);
-}
-bool operator!=(const CFX_WideStringC& s1, const CFX_WideString& s2)
-{
-    return !s2.Equal(s1);
+    if (!m_pData) {
+        return !ptr || ptr[0] == L'\0';
+    }
+    if (!ptr) {
+        return m_pData->m_nDataLength == 0;
+    }
+    return wcslen(ptr) == m_pData->m_nDataLength &&
+            wmemcmp(ptr, m_pData->m_String, m_pData->m_nDataLength) == 0;
 }
 bool CFX_WideString::Equal(const CFX_WideStringC& str) const
 {
@@ -235,66 +199,75 @@ bool CFX_WideString::Equal(const CFX_WideStringC& str) const
         return str.IsEmpty();
     }
     return str.GetLength() == m_pData->m_nDataLength &&
-           FXSYS_memcmp32(str.GetPtr(), m_pData->m_String, m_pData->m_nDataLength * sizeof(FX_WCHAR)) == 0;
+        wmemcmp(str.GetPtr(), m_pData->m_String, m_pData->m_nDataLength) == 0;
 }
-void CFX_WideString::Empty()
+bool CFX_WideString::Equal(const CFX_WideString& other) const
 {
-    if (m_pData == NULL) {
-        return;
+    if (IsEmpty()) {
+        return other.IsEmpty();
     }
-    if (m_pData->m_nRefs > 1) {
-        m_pData->m_nRefs --;
-    } else {
-        FX_Free(m_pData);
+    if (other.IsEmpty()) {
+        return false;
     }
-    m_pData = NULL;
+    return other.m_pData->m_nDataLength == m_pData->m_nDataLength &&
+        wmemcmp(other.m_pData->m_String,
+                m_pData->m_String,
+                m_pData->m_nDataLength) == 0;
 }
-void CFX_WideString::ConcatInPlace(FX_STRSIZE nSrcLen, FX_LPCWSTR lpszSrcData)
+void CFX_WideString::Empty()
+{
+    if (m_pData) {
+        m_pData->Release();
+        m_pData = NULL;
+    }
+}
+void CFX_WideString::ConcatInPlace(FX_STRSIZE nSrcLen, const FX_WCHAR* lpszSrcData)
 {
     if (nSrcLen == 0 || lpszSrcData == NULL) {
         return;
     }
     if (m_pData == NULL) {
-        m_pData = FX_AllocStringW(nSrcLen);
+        m_pData = StringData::Create(nSrcLen);
         if (m_pData) {
-            FXSYS_memcpy32(m_pData->m_String, lpszSrcData, nSrcLen * sizeof(FX_WCHAR));
+            FXSYS_memcpy(m_pData->m_String, lpszSrcData, nSrcLen * sizeof(FX_WCHAR));
         }
         return;
     }
     if (m_pData->m_nRefs > 1 || m_pData->m_nDataLength + nSrcLen > m_pData->m_nAllocLength) {
-        CFX_StringDataW* pOldData = m_pData;
         ConcatCopy(m_pData->m_nDataLength, m_pData->m_String, nSrcLen, lpszSrcData);
-        FX_ReleaseStringW(pOldData);
     } else {
-        FXSYS_memcpy32(m_pData->m_String + m_pData->m_nDataLength, lpszSrcData, nSrcLen * sizeof(FX_WCHAR));
+        FXSYS_memcpy(m_pData->m_String + m_pData->m_nDataLength, lpszSrcData, nSrcLen * sizeof(FX_WCHAR));
         m_pData->m_nDataLength += nSrcLen;
         m_pData->m_String[m_pData->m_nDataLength] = 0;
     }
 }
-void CFX_WideString::ConcatCopy(FX_STRSIZE nSrc1Len, FX_LPCWSTR lpszSrc1Data,
-                                FX_STRSIZE nSrc2Len, FX_LPCWSTR lpszSrc2Data)
+void CFX_WideString::ConcatCopy(FX_STRSIZE nSrc1Len, const FX_WCHAR* lpszSrc1Data,
+                                FX_STRSIZE nSrc2Len, const FX_WCHAR* lpszSrc2Data)
 {
     FX_STRSIZE nNewLen = nSrc1Len + nSrc2Len;
-    if (nNewLen == 0) {
+    if (nNewLen <= 0) {
         return;
     }
-    m_pData = FX_AllocStringW(nNewLen);
+    // Don't release until done copying, might be one of the arguments.
+    StringData* pOldData = m_pData;
+    m_pData = StringData::Create(nNewLen);
     if (m_pData) {
-        FXSYS_memcpy32(m_pData->m_String, lpszSrc1Data, nSrc1Len * sizeof(FX_WCHAR));
-        FXSYS_memcpy32(m_pData->m_String + nSrc1Len, lpszSrc2Data, nSrc2Len * sizeof(FX_WCHAR));
+        wmemcpy(m_pData->m_String, lpszSrc1Data, nSrc1Len);
+        wmemcpy(m_pData->m_String + nSrc1Len, lpszSrc2Data, nSrc2Len);
     }
+    pOldData->Release();
 }
 void CFX_WideString::CopyBeforeWrite()
 {
     if (m_pData == NULL || m_pData->m_nRefs <= 1) {
         return;
     }
-    CFX_StringDataW* pData = m_pData;
-    m_pData->m_nRefs --;
+    StringData* pData = m_pData;
+    m_pData->Release();
     FX_STRSIZE nDataLength = pData->m_nDataLength;
-    m_pData = FX_AllocStringW(nDataLength);
+    m_pData = StringData::Create(nDataLength);
     if (m_pData != NULL) {
-        FXSYS_memcpy32(m_pData->m_String, pData->m_String, (nDataLength + 1) * sizeof(FX_WCHAR));
+        FXSYS_memcpy(m_pData->m_String, pData->m_String, (nDataLength + 1) * sizeof(FX_WCHAR));
     }
 }
 void CFX_WideString::AllocBeforeWrite(FX_STRSIZE nLen)
@@ -303,16 +276,16 @@ void CFX_WideString::AllocBeforeWrite(FX_STRSIZE nLen)
         return;
     }
     Empty();
-    m_pData = FX_AllocStringW(nLen);
+    m_pData = StringData::Create(nLen);
 }
-void CFX_WideString::AssignCopy(FX_STRSIZE nSrcLen, FX_LPCWSTR lpszSrcData)
+void CFX_WideString::AssignCopy(FX_STRSIZE nSrcLen, const FX_WCHAR* lpszSrcData)
 {
     AllocBeforeWrite(nSrcLen);
-    FXSYS_memcpy32(m_pData->m_String, lpszSrcData, nSrcLen * sizeof(FX_WCHAR));
+    FXSYS_memcpy(m_pData->m_String, lpszSrcData, nSrcLen * sizeof(FX_WCHAR));
     m_pData->m_nDataLength = nSrcLen;
     m_pData->m_String[nSrcLen] = 0;
 }
-int CFX_WideString::Compare(FX_LPCWSTR lpsz) const
+int CFX_WideString::Compare(const FX_WCHAR* lpsz) const
 {
     if (m_pData == NULL) {
         return (lpsz == NULL || lpsz[0] == 0) ? 0 : -1;
@@ -330,7 +303,7 @@ CFX_ByteString CFX_WideString::UTF16LE_Encode() const
     }
     int len = m_pData->m_nDataLength;
     CFX_ByteString result;
-    FX_LPSTR buffer = result.GetBuffer(len * 2 + 2);
+    FX_CHAR* buffer = result.GetBuffer(len * 2 + 2);
     for (int i = 0; i < len; i ++) {
         buffer[i * 2] = m_pData->m_String[i] & 0xff;
         buffer[i * 2 + 1] = m_pData->m_String[i] >> 8;
@@ -352,7 +325,7 @@ void CFX_WideString::Reserve(FX_STRSIZE len)
     GetBuffer(len);
     ReleaseBuffer(GetLength());
 }
-FX_LPWSTR CFX_WideString::GetBuffer(FX_STRSIZE nMinBufLength)
+FX_WCHAR* CFX_WideString::GetBuffer(FX_STRSIZE nMinBufLength)
 {
     if (m_pData == NULL && nMinBufLength == 0) {
         return NULL;
@@ -361,7 +334,7 @@ FX_LPWSTR CFX_WideString::GetBuffer(FX_STRSIZE nMinBufLength)
         return m_pData->m_String;
     }
     if (m_pData == NULL) {
-        m_pData = FX_AllocStringW(nMinBufLength);
+        m_pData = StringData::Create(nMinBufLength);
         if (!m_pData) {
             return NULL;
         }
@@ -369,21 +342,18 @@ FX_LPWSTR CFX_WideString::GetBuffer(FX_STRSIZE nMinBufLength)
         m_pData->m_String[0] = 0;
         return m_pData->m_String;
     }
-    CFX_StringDataW* pOldData = m_pData;
+    StringData* pOldData = m_pData;
     FX_STRSIZE nOldLen = pOldData->m_nDataLength;
     if (nMinBufLength < nOldLen) {
         nMinBufLength = nOldLen;
     }
-    m_pData = FX_AllocStringW(nMinBufLength);
+    m_pData = StringData::Create(nMinBufLength);
     if (!m_pData) {
         return NULL;
     }
-    FXSYS_memcpy32(m_pData->m_String, pOldData->m_String, (nOldLen + 1)*sizeof(FX_WCHAR));
+    FXSYS_memcpy(m_pData->m_String, pOldData->m_String, (nOldLen + 1)*sizeof(FX_WCHAR));
     m_pData->m_nDataLength = nOldLen;
-    pOldData->m_nRefs --;
-    if (pOldData->m_nRefs <= 0) {
-        FX_Free(pOldData);
-    }
+    pOldData->Release();
     return m_pData->m_String;
 }
 CFX_WideString CFX_WideString::FromLocal(const char* str, FX_STRSIZE len)
@@ -435,12 +405,12 @@ void CFX_WideString::AllocCopy(CFX_WideString& dest, FX_STRSIZE nCopyLen, FX_STR
     if (nCopyLen == 0 || nCopyLen < 0) {
         return;
     }
-    base::CheckedNumeric<FX_STRSIZE> iSize = static_cast<FX_STRSIZE>(sizeof(FX_WCHAR));
+    pdfium::base::CheckedNumeric<FX_STRSIZE> iSize = static_cast<FX_STRSIZE>(sizeof(FX_WCHAR));
     iSize *= nCopyLen;
     ASSERT(dest.m_pData == NULL);
-    dest.m_pData = FX_AllocStringW(nCopyLen);
+    dest.m_pData = StringData::Create(nCopyLen);
     if (dest.m_pData) {
-        FXSYS_memcpy32(dest.m_pData->m_String, m_pData->m_String + nCopyIndex, iSize.ValueOrDie());
+        FXSYS_memcpy(dest.m_pData->m_String, m_pData->m_String + nCopyIndex, iSize.ValueOrDie());
     }
 }
 CFX_WideString CFX_WideString::Left(FX_STRSIZE nCount) const
@@ -501,7 +471,7 @@ CFX_WideString CFX_WideString::Right(FX_STRSIZE nCount) const
     AllocCopy(dest, nCount, m_pData->m_nDataLength - nCount);
     return dest;
 }
-int CFX_WideString::CompareNoCase(FX_LPCWSTR lpsz) const
+int CFX_WideString::CompareNoCase(const FX_WCHAR* lpsz) const
 {
     if (m_pData == NULL) {
         return (lpsz == NULL || lpsz[0] == 0) ? 0 : -1;
@@ -515,7 +485,8 @@ int CFX_WideString::Compare(const CFX_WideString& str) const
             return 0;
         }
         return -1;
-    } else if (str.m_pData == NULL) {
+    }
+    if (str.m_pData == NULL) {
         return 1;
     }
     int this_len = m_pData->m_nDataLength;
@@ -524,26 +495,19 @@ int CFX_WideString::Compare(const CFX_WideString& str) const
     for (int i = 0; i < min_len; i ++) {
         if (m_pData->m_String[i] < str.m_pData->m_String[i]) {
             return -1;
-        } else if (m_pData->m_String[i] > str.m_pData->m_String[i]) {
+        }
+        if (m_pData->m_String[i] > str.m_pData->m_String[i]) {
             return 1;
         }
     }
     if (this_len < that_len) {
         return -1;
-    } else if (this_len > that_len) {
+    }
+    if (this_len > that_len) {
         return 1;
     }
     return 0;
 }
-FX_LPWSTR CFX_WideString::LockBuffer()
-{
-    if (m_pData == NULL) {
-        return NULL;
-    }
-    FX_LPWSTR lpsz = GetBuffer(0);
-    m_pData->m_nRefs = -1;
-    return lpsz;
-}
 void CFX_WideString::SetAt(FX_STRSIZE nIndex, FX_WCHAR ch)
 {
     if (m_pData == NULL) {
@@ -576,13 +540,13 @@ void CFX_WideString::MakeUpper()
     }
     FXSYS_wcsupr(m_pData->m_String);
 }
-FX_STRSIZE CFX_WideString::Find(FX_LPCWSTR lpszSub, FX_STRSIZE nStart) const
+FX_STRSIZE CFX_WideString::Find(const FX_WCHAR* lpszSub, FX_STRSIZE nStart) const
 {
     FX_STRSIZE nLength = GetLength();
     if (nLength < 1 || nStart > nLength) {
         return -1;
     }
-    FX_LPCWSTR lpsz = FXSYS_wcsstr(m_pData->m_String + nStart, lpszSub);
+    const FX_WCHAR* lpsz = FXSYS_wcsstr(m_pData->m_String + nStart, lpszSub);
     return (lpsz == NULL) ? -1 : (int)(lpsz - m_pData->m_String);
 }
 FX_STRSIZE CFX_WideString::Find(FX_WCHAR ch, FX_STRSIZE nStart) const
@@ -594,10 +558,10 @@ FX_STRSIZE CFX_WideString::Find(FX_WCHAR ch, FX_STRSIZE nStart) const
     if (nStart >= nLength) {
         return -1;
     }
-    FX_LPCWSTR lpsz = FXSYS_wcschr(m_pData->m_String + nStart, ch);
+    const FX_WCHAR* lpsz = FXSYS_wcschr(m_pData->m_String + nStart, ch);
     return (lpsz == NULL) ? -1 : (int)(lpsz - m_pData->m_String);
 }
-void CFX_WideString::TrimRight(FX_LPCWSTR lpszTargetList)
+void CFX_WideString::TrimRight(const FX_WCHAR* lpszTargetList)
 {
     FXSYS_assert(lpszTargetList != NULL);
     if (m_pData == NULL || *lpszTargetList == 0) {
@@ -629,7 +593,7 @@ void CFX_WideString::TrimRight()
 {
     TrimRight(L"\x09\x0a\x0b\x0c\x0d\x20");
 }
-void CFX_WideString::TrimLeft(FX_LPCWSTR lpszTargets)
+void CFX_WideString::TrimLeft(const FX_WCHAR* lpszTargets)
 {
     FXSYS_assert(lpszTargets != NULL);
     if (m_pData == NULL || *lpszTargets == 0) {
@@ -639,7 +603,7 @@ void CFX_WideString::TrimLeft(FX_LPCWSTR lpszTargets)
     if (GetLength() < 1) {
         return;
     }
-    FX_LPCWSTR lpsz = m_pData->m_String;
+    const FX_WCHAR* lpsz = m_pData->m_String;
     while (*lpsz != 0) {
         if (FXSYS_wcschr(lpszTargets, *lpsz) == NULL) {
             break;
@@ -648,7 +612,7 @@ void CFX_WideString::TrimLeft(FX_LPCWSTR lpszTargets)
     }
     if (lpsz != m_pData->m_String) {
         int nDataLength = m_pData->m_nDataLength - (FX_STRSIZE)(lpsz - m_pData->m_String);
-        FXSYS_memmove32(m_pData->m_String, lpsz, (nDataLength + 1)*sizeof(FX_WCHAR));
+        FXSYS_memmove(m_pData->m_String, lpsz, (nDataLength + 1)*sizeof(FX_WCHAR));
         m_pData->m_nDataLength = nDataLength;
     }
 }
@@ -661,7 +625,7 @@ void CFX_WideString::TrimLeft()
 {
     TrimLeft(L"\x09\x0a\x0b\x0c\x0d\x20");
 }
-FX_STRSIZE CFX_WideString::Replace(FX_LPCWSTR lpszOld, FX_LPCWSTR lpszNew)
+FX_STRSIZE CFX_WideString::Replace(const FX_WCHAR* lpszOld, const FX_WCHAR* lpszNew)
 {
     if (GetLength() < 1) {
         return 0;
@@ -669,17 +633,17 @@ FX_STRSIZE CFX_WideString::Replace(FX_LPCWSTR lpszOld, FX_LPCWSTR lpszNew)
     if (lpszOld == NULL) {
         return 0;
     }
-    FX_STRSIZE nSourceLen = (FX_STRSIZE)FXSYS_wcslen(lpszOld);
+    FX_STRSIZE nSourceLen = FXSYS_wcslen(lpszOld);
     if (nSourceLen == 0) {
         return 0;
     }
-    FX_STRSIZE nReplacementLen = lpszNew ? (FX_STRSIZE)FXSYS_wcslen(lpszNew) : 0;
+    FX_STRSIZE nReplacementLen = lpszNew ? FXSYS_wcslen(lpszNew) : 0;
     FX_STRSIZE nCount = 0;
-    FX_LPWSTR lpszStart = m_pData->m_String;
-    FX_LPWSTR lpszEnd = m_pData->m_String + m_pData->m_nDataLength;
-    FX_LPWSTR lpszTarget;
+    FX_WCHAR* lpszStart = m_pData->m_String;
+    FX_WCHAR* lpszEnd = m_pData->m_String + m_pData->m_nDataLength;
+    FX_WCHAR* lpszTarget;
     {
-        while ((lpszTarget = (FX_LPWSTR)FXSYS_wcsstr(lpszStart, lpszOld)) != NULL && lpszStart < lpszEnd) {
+        while ((lpszTarget = (FX_WCHAR*)FXSYS_wcsstr(lpszStart, lpszOld)) != NULL && lpszStart < lpszEnd) {
             nCount++;
             lpszStart = lpszTarget + nSourceLen;
         }
@@ -689,22 +653,22 @@ FX_STRSIZE CFX_WideString::Replace(FX_LPCWSTR lpszOld, FX_LPCWSTR lpszNew)
         FX_STRSIZE nOldLength = m_pData->m_nDataLength;
         FX_STRSIZE nNewLength =  nOldLength + (nReplacementLen - nSourceLen) * nCount;
         if (m_pData->m_nAllocLength < nNewLength || m_pData->m_nRefs > 1) {
-            CFX_StringDataW* pOldData = m_pData;
-            FX_LPCWSTR pstr = m_pData->m_String;
-            m_pData = FX_AllocStringW(nNewLength);
+            StringData* pOldData = m_pData;
+            const FX_WCHAR* pstr = m_pData->m_String;
+            m_pData = StringData::Create(nNewLength);
             if (!m_pData) {
                 return 0;
             }
-            FXSYS_memcpy32(m_pData->m_String, pstr, pOldData->m_nDataLength * sizeof(FX_WCHAR));
-            FX_ReleaseStringW(pOldData);
+            FXSYS_memcpy(m_pData->m_String, pstr, pOldData->m_nDataLength * sizeof(FX_WCHAR));
+            pOldData->Release();
         }
         lpszStart = m_pData->m_String;
         lpszEnd = m_pData->m_String + FX_MAX(m_pData->m_nDataLength, nNewLength);
         {
-            while ((lpszTarget = (FX_LPWSTR)FXSYS_wcsstr(lpszStart, lpszOld)) != NULL && lpszStart < lpszEnd) {
+            while ((lpszTarget = (FX_WCHAR*)FXSYS_wcsstr(lpszStart, lpszOld)) != NULL && lpszStart < lpszEnd) {
                 FX_STRSIZE nBalance = nOldLength - (FX_STRSIZE)(lpszTarget - m_pData->m_String + nSourceLen);
-                FXSYS_memmove32(lpszTarget + nReplacementLen, lpszTarget + nSourceLen, nBalance * sizeof(FX_WCHAR));
-                FXSYS_memcpy32(lpszTarget, lpszNew, nReplacementLen * sizeof(FX_WCHAR));
+                FXSYS_memmove(lpszTarget + nReplacementLen, lpszTarget + nSourceLen, nBalance * sizeof(FX_WCHAR));
+                FXSYS_memcpy(lpszTarget, lpszNew, nReplacementLen * sizeof(FX_WCHAR));
                 lpszStart = lpszTarget + nReplacementLen;
                 lpszStart[nBalance] = 0;
                 nOldLength += (nReplacementLen - nSourceLen);
@@ -727,20 +691,20 @@ FX_STRSIZE CFX_WideString::Insert(FX_STRSIZE nIndex, FX_WCHAR ch)
     }
     nNewLength++;
     if (m_pData == NULL || m_pData->m_nAllocLength < nNewLength) {
-        CFX_StringDataW* pOldData = m_pData;
-        FX_LPCWSTR pstr = m_pData->m_String;
-        m_pData = FX_AllocStringW(nNewLength);
+        StringData* pOldData = m_pData;
+        const FX_WCHAR* pstr = m_pData->m_String;
+        m_pData = StringData::Create(nNewLength);
         if (!m_pData) {
             return 0;
         }
         if(pOldData != NULL) {
-            FXSYS_memmove32(m_pData->m_String, pstr, (pOldData->m_nDataLength + 1)*sizeof(FX_WCHAR));
-            FX_ReleaseStringW(pOldData);
+            FXSYS_memmove(m_pData->m_String, pstr, (pOldData->m_nDataLength + 1)*sizeof(FX_WCHAR));
+            pOldData->Release();
         } else {
             m_pData->m_String[0] = 0;
         }
     }
-    FXSYS_memmove32(m_pData->m_String + nIndex + 1,
+    FXSYS_memmove(m_pData->m_String + nIndex + 1,
                     m_pData->m_String + nIndex, (nNewLength - nIndex)*sizeof(FX_WCHAR));
     m_pData->m_String[nIndex] = ch;
     m_pData->m_nDataLength = nNewLength;
@@ -758,7 +722,7 @@ FX_STRSIZE CFX_WideString::Delete(FX_STRSIZE nIndex, FX_STRSIZE nCount)
     if (nCount > 0 && nIndex < nOldLength) {
         CopyBeforeWrite();
         int nBytesToCopy = nOldLength - (nIndex + nCount) + 1;
-        FXSYS_memmove32(m_pData->m_String + nIndex,
+        FXSYS_memmove(m_pData->m_String + nIndex,
                         m_pData->m_String + nIndex + nCount, nBytesToCopy * sizeof(FX_WCHAR));
         m_pData->m_nDataLength = nOldLength - nCount;
     }
@@ -773,9 +737,9 @@ FX_STRSIZE CFX_WideString::Remove(FX_WCHAR chRemove)
     if (GetLength() < 1) {
         return 0;
     }
-    FX_LPWSTR pstrSource = m_pData->m_String;
-    FX_LPWSTR pstrDest = m_pData->m_String;
-    FX_LPWSTR pstrEnd = m_pData->m_String + m_pData->m_nDataLength;
+    FX_WCHAR* pstrSource = m_pData->m_String;
+    FX_WCHAR* pstrDest = m_pData->m_String;
+    FX_WCHAR* pstrEnd = m_pData->m_String + m_pData->m_nDataLength;
     while (pstrSource < pstrEnd) {
         if (*pstrSource != chRemove) {
             *pstrDest = *pstrSource;
@@ -791,7 +755,7 @@ FX_STRSIZE CFX_WideString::Remove(FX_WCHAR chRemove)
 #define FORCE_ANSI      0x10000
 #define FORCE_UNICODE   0x20000
 #define FORCE_INT64     0x40000
-void CFX_WideString::FormatV(FX_LPCWSTR lpszFormat, va_list argList)
+void CFX_WideString::FormatV(const FX_WCHAR* lpszFormat, va_list argList)
 {
     va_list argListSave;
 #if defined(__ARMCC_VERSION) || (!defined(_MSC_VER) && (_FX_CPU_ == _FX_X64_ || _FX_CPU_ == _FX_IA64_ || _FX_CPU_ == _FX_ARM64_)) || defined(__native_client__)
@@ -800,9 +764,9 @@ void CFX_WideString::FormatV(FX_LPCWSTR lpszFormat, va_list argList)
     argListSave = argList;
 #endif
     int nMaxLen = 0;
-    for (FX_LPCWSTR lpsz = lpszFormat; *lpsz != 0; lpsz ++) {
+    for (const FX_WCHAR* lpsz = lpszFormat; *lpsz != 0; lpsz ++) {
         if (*lpsz != '%' || *(lpsz = lpsz + 1) == '%') {
-            nMaxLen += (FX_STRSIZE)FXSYS_wcslen(lpsz);
+            nMaxLen += FXSYS_wcslen(lpsz);
             continue;
         }
         int nItemLen = 0;
@@ -884,11 +848,11 @@ void CFX_WideString::FormatV(FX_LPCWSTR lpszFormat, va_list argList)
                 va_arg(argList, int);
                 break;
             case 's': {
-                    FX_LPCWSTR pstrNextArg = va_arg(argList, FX_LPCWSTR);
+                    const FX_WCHAR* pstrNextArg = va_arg(argList, const FX_WCHAR*);
                     if (pstrNextArg == NULL) {
                         nItemLen = 6;
                     } else {
-                        nItemLen = (FX_STRSIZE)FXSYS_wcslen(pstrNextArg);
+                        nItemLen = FXSYS_wcslen(pstrNextArg);
                         if (nItemLen < 1) {
                             nItemLen = 1;
                         }
@@ -896,11 +860,11 @@ void CFX_WideString::FormatV(FX_LPCWSTR lpszFormat, va_list argList)
                 }
                 break;
             case 'S': {
-                    FX_LPCSTR pstrNextArg = va_arg(argList, FX_LPCSTR);
+                    const FX_CHAR* pstrNextArg = va_arg(argList, const FX_CHAR*);
                     if (pstrNextArg == NULL) {
                         nItemLen = 6;
                     } else {
-                        nItemLen = (FX_STRSIZE)FXSYS_strlen(pstrNextArg);
+                        nItemLen = FXSYS_strlen(pstrNextArg);
                         if (nItemLen < 1) {
                             nItemLen = 1;
                         }
@@ -909,11 +873,11 @@ void CFX_WideString::FormatV(FX_LPCWSTR lpszFormat, va_list argList)
                 break;
             case 's'|FORCE_ANSI:
             case 'S'|FORCE_ANSI: {
-                    FX_LPCSTR pstrNextArg = va_arg(argList, FX_LPCSTR);
+                    const FX_CHAR* pstrNextArg = va_arg(argList, const FX_CHAR*);
                     if (pstrNextArg == NULL) {
                         nItemLen = 6;
                     } else {
-                        nItemLen = (FX_STRSIZE)FXSYS_strlen(pstrNextArg);
+                        nItemLen = FXSYS_strlen(pstrNextArg);
                         if (nItemLen < 1) {
                             nItemLen = 1;
                         }
@@ -922,11 +886,11 @@ void CFX_WideString::FormatV(FX_LPCWSTR lpszFormat, va_list argList)
                 break;
             case 's'|FORCE_UNICODE:
             case 'S'|FORCE_UNICODE: {
-                    FX_LPWSTR pstrNextArg = va_arg(argList, FX_LPWSTR);
+                    FX_WCHAR* pstrNextArg = va_arg(argList, FX_WCHAR*);
                     if (pstrNextArg == NULL) {
                         nItemLen = 6;
                     } else {
-                        nItemLen = (FX_STRSIZE)FXSYS_wcslen(pstrNextArg);
+                        nItemLen = FXSYS_wcslen(pstrNextArg);
                         if (nItemLen < 1) {
                             nItemLen = 1;
                         }
@@ -950,7 +914,7 @@ void CFX_WideString::FormatV(FX_LPCWSTR lpszFormat, va_list argList)
                 case 'X':
                 case 'o':
                     if (nModifier & FORCE_INT64) {
-                        va_arg(argList, FX_INT64);
+                        va_arg(argList, int64_t);
                     } else {
                         va_arg(argList, int);
                     }
@@ -979,7 +943,7 @@ void CFX_WideString::FormatV(FX_LPCWSTR lpszFormat, va_list argList)
                         char pszTemp[256];
                         f = va_arg(argList, double);
                         FXSYS_snprintf(pszTemp, sizeof(pszTemp), "%*.*f", nWidth, nPrecision + 6, f );
-                        nItemLen = (FX_STRSIZE)FXSYS_strlen(pszTemp);
+                        nItemLen = FXSYS_strlen(pszTemp);
                     }
                     break;
                 case 'p':
@@ -1003,14 +967,14 @@ void CFX_WideString::FormatV(FX_LPCWSTR lpszFormat, va_list argList)
     }
     va_end(argListSave);
 }
-void CFX_WideString::Format(FX_LPCWSTR lpszFormat, ...)
+void CFX_WideString::Format(const FX_WCHAR* lpszFormat, ...)
 {
     va_list argList;
     va_start(argList, lpszFormat);
     FormatV(lpszFormat, argList);
     va_end(argList);
 }
-FX_FLOAT FX_wtof(FX_LPCWSTR str, int len)
+FX_FLOAT FX_wtof(const FX_WCHAR* str, int len)
 {
     if (len == 0) {
         return 0.0;
@@ -1062,13 +1026,13 @@ static CFX_ByteString _DefMap_GetByteString(CFX_CharMap* pCharMap, const CFX_Wid
 {
     int src_len = widestr.GetLength();
     int codepage = pCharMap->m_GetCodePage ? pCharMap->m_GetCodePage() : 0;
-    int dest_len = FXSYS_WideCharToMultiByte(codepage, 0, widestr, src_len, NULL, 0, NULL, NULL);
+    int dest_len = FXSYS_WideCharToMultiByte(codepage, 0, widestr.c_str(), src_len, NULL, 0, NULL, NULL);
     if (dest_len == 0) {
         return CFX_ByteString();
     }
     CFX_ByteString bytestr;
-    FX_LPSTR dest_buf = bytestr.GetBuffer(dest_len);
-    FXSYS_WideCharToMultiByte(codepage, 0, widestr, src_len, dest_buf, dest_len, NULL, NULL);
+    FX_CHAR* dest_buf = bytestr.GetBuffer(dest_len);
+    FXSYS_WideCharToMultiByte(codepage, 0, widestr.c_str(), src_len, dest_buf, dest_len, NULL, NULL);
     bytestr.ReleaseBuffer(dest_len);
     return bytestr;
 }
@@ -1081,7 +1045,7 @@ static CFX_WideString _DefMap_GetWideString(CFX_CharMap* pCharMap, const CFX_Byt
         return CFX_WideString();
     }
     CFX_WideString widestr;
-    FX_LPWSTR dest_buf = widestr.GetBuffer(dest_len);
+    FX_WCHAR* dest_buf = widestr.GetBuffer(dest_len);
     FXSYS_MultiByteToWideChar(codepage, 0, bytestr, src_len, dest_buf, dest_len);
     widestr.ReleaseBuffer(dest_len);
     return widestr;
@@ -1107,7 +1071,7 @@ static const CFX_CharMap g_DefaultGBKMapper = {&_DefMap_GetWideString, &_DefMap_
 static const CFX_CharMap g_DefaultJISMapper = {&_DefMap_GetWideString, &_DefMap_GetByteString, &_DefMap_GetJISCodePage};
 static const CFX_CharMap g_DefaultUHCMapper = {&_DefMap_GetWideString, &_DefMap_GetByteString, &_DefMap_GetUHCCodePage};
 static const CFX_CharMap g_DefaultBig5Mapper = {&_DefMap_GetWideString, &_DefMap_GetByteString, &_DefMap_GetBig5CodePage};
-CFX_CharMap* CFX_CharMap::GetDefaultMapper(FX_INT32 codepage)
+CFX_CharMap* CFX_CharMap::GetDefaultMapper(int32_t codepage)
 {
     switch (codepage) {
         case 0: