Index: core/include/fxcrt/fx_string.h |
diff --git a/core/include/fxcrt/fx_string.h b/core/include/fxcrt/fx_string.h |
index 8bb29dabd64a4f592fe22b820766ef9490b125cc..a7b9a23e2552483d7f5c8dad5dc131192ca8a4ad 100644 |
--- a/core/include/fxcrt/fx_string.h |
+++ b/core/include/fxcrt/fx_string.h |
@@ -171,19 +171,6 @@ typedef const CFX_ByteStringC& FX_BSTR; |
#define FX_BSTRC(str) CFX_ByteStringC(str, sizeof str-1) |
#define FXBSTR_ID(c1, c2, c3, c4) ((c1 << 24) | (c2 << 16) | (c3 << 8) | (c4)) |
-// To ensure ref counts do not overflow, consider the worst possible case: |
-// the entire address space contains nothing but pointers to this object. |
-// Since the count increments with each new pointer, the largest value is |
-// the number of pointers that can fit into the address space. The size of |
-// the address space itself is a good upper bound on it; we need not go |
-// larger. |
-struct CFX_StringData { |
- intptr_t m_nRefs; // Would prefer ssize_t, but no windows support. |
- FX_STRSIZE m_nDataLength; |
- FX_STRSIZE m_nAllocLength; |
- FX_CHAR m_String[1]; |
-}; |
- |
// A mutable string with shared buffers using copy-on-write semantics that |
// avoids the cost of std::string's iterator stability guarantees. |
class CFX_ByteString |
@@ -363,17 +350,45 @@ public: |
#define FXFORMAT_CAPITAL 4 |
static CFX_ByteString FormatInteger(int i, FX_DWORD flags = 0); |
- |
static CFX_ByteString FormatFloat(FX_FLOAT f, int precision = 0); |
+ |
protected: |
+ // To ensure ref counts do not overflow, consider the worst possible case: |
+ // the entire address space contains nothing but pointers to this object. |
+ // Since the count increments with each new pointer, the largest value is |
+ // the number of pointers that can fit into the address space. The size of |
+ // the address space itself is a good upper bound on it; we need not go |
+ // larger. |
+ class StringData { |
+ public: |
+ static StringData* Create(int nLen); |
+ void Retain() { ++m_nRefs; } |
+ void Release() { if (--m_nRefs <= 0) FX_Free(this); } |
+ |
+ intptr_t m_nRefs; // Would prefer ssize_t, but no windows support. |
+ FX_STRSIZE m_nDataLength; |
+ FX_STRSIZE m_nAllocLength; |
+ FX_CHAR m_String[1]; |
+ |
+ private: |
+ StringData(FX_STRSIZE dataLen, FX_STRSIZE allocLen) |
+ : m_nRefs(1), m_nDataLength(dataLen), m_nAllocLength(allocLen) { |
+ FXSYS_assert(dataLen >= 0); |
+ FXSYS_assert(allocLen >= 0); |
+ FXSYS_assert(dataLen <= allocLen); |
+ m_String[dataLen] = 0; |
+ } |
+ ~StringData() = delete; |
+ }; |
- struct CFX_StringData* m_pData; |
void AllocCopy(CFX_ByteString& dest, FX_STRSIZE nCopyLen, FX_STRSIZE nCopyIndex) const; |
void AssignCopy(FX_STRSIZE nSrcLen, FX_LPCSTR lpszSrcData); |
void ConcatCopy(FX_STRSIZE nSrc1Len, FX_LPCSTR lpszSrc1Data, FX_STRSIZE nSrc2Len, FX_LPCSTR lpszSrc2Data); |
void ConcatInPlace(FX_STRSIZE nSrcLen, FX_LPCSTR lpszSrcData); |
void CopyBeforeWrite(); |
void AllocBeforeWrite(FX_STRSIZE nLen); |
+ |
+ StringData* m_pData; |
}; |
inline CFX_ByteStringC::CFX_ByteStringC(const CFX_ByteString& src) |
{ |
@@ -600,13 +615,6 @@ inline bool operator!= (const wchar_t* lhs, const CFX_WideStringC& rhs) { |
typedef const CFX_WideStringC& FX_WSTR; |
#define FX_WSTRC(wstr) CFX_WideStringC(wstr, FX_ArraySize(wstr) - 1) |
-struct CFX_StringDataW { |
- intptr_t m_nRefs; // Would prefer ssize_t, but no windows support. |
- FX_STRSIZE m_nDataLength; |
- FX_STRSIZE m_nAllocLength; |
- FX_WCHAR m_String[1]; |
-}; |
- |
// A mutable string with shared buffers using copy-on-write semantics that |
// avoids the cost of std::string's iterator stability guarantees. |
class CFX_WideString |
@@ -777,14 +785,36 @@ public: |
void ConvertFrom(const CFX_ByteString& str, CFX_CharMap* pCharMap = NULL); |
protected: |
- void CopyBeforeWrite(); |
- void AllocBeforeWrite(FX_STRSIZE nLen); |
- void ConcatInPlace(FX_STRSIZE nSrcLen, FX_LPCWSTR lpszSrcData); |
- void ConcatCopy(FX_STRSIZE nSrc1Len, FX_LPCWSTR lpszSrc1Data, FX_STRSIZE nSrc2Len, FX_LPCWSTR lpszSrc2Data); |
- void AssignCopy(FX_STRSIZE nSrcLen, FX_LPCWSTR lpszSrcData); |
- void AllocCopy(CFX_WideString& dest, FX_STRSIZE nCopyLen, FX_STRSIZE nCopyIndex) const; |
+ class StringData { |
+ public: |
+ static StringData* Create(int nLen); |
+ void Retain() { ++m_nRefs; } |
+ void Release() { if (--m_nRefs <= 0) FX_Free(this); } |
+ |
+ intptr_t m_nRefs; // Would prefer ssize_t, but no windows support. |
+ FX_STRSIZE m_nDataLength; |
+ FX_STRSIZE m_nAllocLength; |
+ FX_WCHAR m_String[1]; |
+ |
+ private: |
+ StringData(FX_STRSIZE dataLen, FX_STRSIZE allocLen) |
+ : m_nRefs(1), m_nDataLength(dataLen), m_nAllocLength(allocLen) { |
+ FXSYS_assert(dataLen >= 0); |
+ FXSYS_assert(allocLen >= 0); |
+ FXSYS_assert(dataLen <= allocLen); |
+ m_String[dataLen] = 0; |
+ } |
+ ~StringData() = delete; |
+ }; |
+ |
+ void CopyBeforeWrite(); |
+ void AllocBeforeWrite(FX_STRSIZE nLen); |
+ void ConcatInPlace(FX_STRSIZE nSrcLen, FX_LPCWSTR lpszSrcData); |
+ void ConcatCopy(FX_STRSIZE nSrc1Len, FX_LPCWSTR lpszSrc1Data, FX_STRSIZE nSrc2Len, FX_LPCWSTR lpszSrc2Data); |
+ void AssignCopy(FX_STRSIZE nSrcLen, FX_LPCWSTR lpszSrcData); |
+ void AllocCopy(CFX_WideString& dest, FX_STRSIZE nCopyLen, FX_STRSIZE nCopyIndex) const; |
- CFX_StringDataW* m_pData; |
+ StringData* m_pData; |
}; |
inline CFX_WideStringC::CFX_WideStringC(const CFX_WideString& src) |
{ |