123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307 |
- #pragma once
- #ifdef DSTRING_EXPORTS
- #define DSTRING_API _declspec(dllexport)
- #else
- #define DSTRING_API _declspec(dllimport)
- #endif
- #ifndef _OLEAUTO_H_
- typedef LPWSTR BSTR;// must (semantically) match typedef in oleauto.h
- #endif
- struct WStringData
- {
- long nRefs; // reference count
- int nDataLength; // length of data (including terminator)
- int nAllocLength; // length of allocation
- // wchar_t data[nAllocLength]
- wchar_t * data () // wchar_t* to managed data
- { return (wchar_t *) (this+1); }
- };
- class DSTRING_API WString
- {
- public:
- WString ();
- WString (const wchar_t * lpsz);
- WString (const BSTR bstr);
- // WString (const DString & From, UINT CodePage);
- explicit WString (const DString & From);
- explicit WString (const char * lpsz);
- WString (const WString & Src);
- WString (WString && Src);
- ~WString ();
- // 返回的是字符数, 而不是真正的长度 ! 真正的长度要乘以 2
- int GetLength () const { return GetData ()->nDataLength; }
- int GetByteLength () const { return GetLength () << 1; }
- bool IsEmpty () const { return (GetData ()->nDataLength == 0); }
- void Empty ();
- void Release ();
- wchar_t GetAt (int nIndex) const
- {
- return m_pchData [nIndex];
- }
- wchar_t operator [] (int nIndex) const { return GetAt (nIndex); }
- void SetAt (int nIndex, wchar_t ch);
- // Number of ch
- int Count (wchar_t ch) const;
- // Number of lpszSub
- int Count (const wchar_t * lpszSub) const;
- // ref-counted copy from another WString
- WString & operator = (const WString & stringSrc);
- WString & operator = (const DString & stringSrc);
- WString & operator = (wchar_t ch);
- WString & operator = (const wchar_t * lpsz);
- WString & operator = (WString && Src);
- // string concatenation
- WString & Append (const WString & string)
- {
- ConcatInPlace (string.GetData ()->nDataLength, string.m_pchData);
- return *this;
- }
- WString & Append (const DString & string)
- {
- return Append (WString (string));
- }
- WString & Append (wchar_t ch)
- {
- ConcatInPlace (1, &ch);
- return *this;
- }
- WString & Append (const wchar_t * lpsz)
- {
- ConcatInPlace ((int)wcslen (lpsz), lpsz);
- return *this;
- }
- WString & operator += (const WString & string) { return Append (string); }
- WString & operator += (wchar_t ch) { return Append (ch); }
- WString & operator += (const wchar_t * lpsz) { return Append (lpsz); }
- WString & operator += (const DString & string) { return Append (WString (string)); }
- WString & operator << (const DString & string) { return Append (WString (string)); }
- WString & operator << (const char * string) { return Append (WString (string)); }
- WString & operator << (const WString & string) { return Append (string); }
- WString & operator << (wchar_t ch) { return Append (ch); }
- WString & operator << (const wchar_t * lpsz) { return Append (lpsz); }
- WString & operator << (short v) { return Append (From (v)); }
- WString & operator << (int v) { return Append (From (v)); }
- WString & operator << (long v) { return Append (From (v)); }
- WString & operator << (UINT16 v) { return Append (From (v)); }
- WString & operator << (UINT32 v) { return Append (From (v)); }
- #if 0
- template <typename T>
- WString & operator << (const T t)
- {
- return Append (WString::From (t));
- }
- #endif
- DSTRING_API friend WString operator + (const WString & string1, const char * string2);
- DSTRING_API friend WString operator + (const WString & string1, const DString & string2);
- DSTRING_API friend WString operator + (const WString & string1, const WString & string2);
- DSTRING_API friend WString operator + (const WString & string, wchar_t ch);
- DSTRING_API friend WString operator + (wchar_t ch, const WString & string);
- DSTRING_API friend WString operator + (const WString & string, const wchar_t * lpsz);
- DSTRING_API friend WString operator + (const wchar_t * lpsz, const WString & string);
- // string comparison
- int Compare (const wchar_t * lpsz) const;
- int CompareNoCase (const wchar_t * lpsz) const;
- // simple sub-string extraction
- WString Mid (int nFirst, int nCount) const;
- WString Mid (int nFirst) const;
- WString Left (int nCount) const;
- WString Right (int nCount) const;
- // upper/lower/reverse conversion
- void MakeUpper ();
- void MakeLower ();
- void MakeReverse ();
- // trimming whitespace (either side)
- void TrimRight ();
- void TrimLeft ();
- void TrimRight (wchar_t chTarget);
- void TrimRight (const wchar_t * lpszTargets);
- void TrimLeft (wchar_t chTarget);
- void TrimLeft (const wchar_t * lpszTargets);
- WString Trim () const { WString copy = *this; copy.TrimRight (); copy.TrimLeft (); return copy; }
- // advanced manipulation
- int Replace (wchar_t chOld, wchar_t chNew);
- int Replace (const wchar_t * lpszOld, const wchar_t * lpszNew);
- int Remove (const wchar_t * lpszSub);
- int Remove (wchar_t chRemove);
- int RemoveSpace ();
- int RemovePunctuation ();
- int RemoveControl ();
- int NCRemove (const wchar_t * lpszSub);
- int NCRemove (wchar_t chRemove);
- // searching
- int Find (wchar_t ch) const;
- int ReverseFind (wchar_t ch) const;
- int Find (wchar_t ch, int nStart) const;
- int FindOneOf (const wchar_t * lpszCharSet) const;
- int Find (const wchar_t * lpszSub) const;
- int Find (const wchar_t * lpszSub, int nStart) const;
- int NCFind (wchar_t ch) const;
- int NCFind (const wchar_t * lpszSub) const;
- public:
- WString Elements (int start, int stop, wchar_t sep) const;
- WString Element (int i, wchar_t sep) const;
- public:
- // get pointer to modifiable buffer at least as long as nMinBufLength
- wchar_t * GetBuffer (int nMinBufLength);
- // release buffer, setting length to nNewLength (or to first nul if -1)
- void ReleaseBuffer (int nNewLength = -1);
- // get pointer to modifiable buffer exactly as long as nNewLength
- wchar_t * GetBufferSetLength (int nNewLength);
- // release memory allocated to but unused by string
- void FreeExtra ();
- public:
- int GetAllocLength () const { return GetData ()->nAllocLength; }
- public:
- double Double () const { return _wtof (m_pchData); }
- int Int () const { int i = _wtoi (m_pchData); if (i) return i; return wcstol (m_pchData, NULL, 16); }
- long Long () const { long l = _wtol (m_pchData); if (l) return l; return wcstol (m_pchData, NULL, 16); }
- wchar_t Char () const { return m_pchData[0]; }
- bool Bool () const;
- __int64 Int64 () const { __int64 i = _wtoi64 (m_pchData); if (i) return i; return _wcstoi64 (m_pchData, NULL, 16); }
- protected:
- static int __cdecl GetFormattedLength (const wchar_t * pszFormat, va_list argList);
- static int __cdecl VFormat (wchar_t * lpzBuffer, const wchar_t * pszFormat, va_list argList);
- public:
- static WString From (const int i);
- static WString From (const long i);
- static WString From (const unsigned int u);
- static WString From (const unsigned long u);
- static WString From (const __int64 i);
- static WString From (const unsigned __int64 u);
- static WString From (const double d);
- static WString FromCodePage (const DString & from, UINT CodePage);
- static WString FromCodePage (const char * from, UINT CodePage);
- // repeat a single character
- static WString FromRepeat (wchar_t ch, int nRepeat);
- protected:
- static WString _FromCodePage (const char * from, int len, UINT CodePage);
- protected:
- void FormatV (const wchar_t * lpszFormat, va_list argList);
- void AppendFormatV (const wchar_t * lpszFormat, va_list argList);
- protected:
- // 对于字符串,代码中很容易忘记 L 前缀, 导致传入的是 char *, 而期望的是 wchar_t *
- // 比如, 正确的写法是: Format ("%s", L"abcd"); 但是很容易写成 Format ("%s", "abcd");
- // 为了避免出现这种 BUG, 把这几个函数改成 protected
- static WString FromFormat (const wchar_t * szFormat, ...);
- void Format (const wchar_t * lpszFormat, ...);
- void AppendFormat (const wchar_t * lpszFormat, ...);
- // Cast
- public:
- operator const wchar_t * () const { return m_pchData; }
- const wchar_t * constBuffer (void) const { return m_pchData; }
- DString ToDString () const;
- DString ToDString (UINT CodePage) const;
- // explicit operator const DString () const { return ToDString (); }
- operator const DString () const = delete;
- operator bool () const = delete;
- protected:
- wchar_t * m_pchData; // pointer to ref counted string data
- WStringData * WString::GetData() const
- {
- return ((WStringData *) m_pchData)-1;
- }
- void Init ();
- void AllocCopy (WString& dest, int nCopyLen, int nCopyIndex, int nExtraLen) const;
- void AllocBuffer (int nLen);
- void AssignCopy (int nSrcLen, const wchar_t * lpszSrcData);
- void ConcatCopy (int nSrc1Len, const wchar_t * lpszSrc1Data, int nSrc2Len, const wchar_t * lpszSrc2Data);
- void ConcatInPlace (int nSrcLen, const wchar_t * lpszSrcData);
- void CopyBeforeWrite ();
- void AllocBeforeWrite (int nLen);
- void MoveAssign (WString & Src);
- static void Release (WStringData * pData);
- static void FreeData (WStringData * pData);
- };
- // Compare helpers
- DSTRING_API inline bool __stdcall operator == (const WString& s1, const WString& s2) { return s1.Compare (s2) == 0; }
- DSTRING_API inline bool __stdcall operator == (const WString& s1, const wchar_t * s2) { return s1.Compare (s2) == 0; }
- DSTRING_API inline bool __stdcall operator == (const wchar_t * s1 , const WString& s2) { return s2.Compare (s1) == 0; }
- DSTRING_API inline bool __stdcall operator != (const WString& s1, const WString& s2) { return s1.Compare (s2) != 0; }
- DSTRING_API inline bool __stdcall operator != (const WString& s1, const wchar_t * s2) { return s1.Compare (s2) != 0; }
- DSTRING_API inline bool __stdcall operator != (const wchar_t * s1 , const WString& s2) { return s2.Compare (s1) != 0; }
- DSTRING_API inline bool __stdcall operator < (const WString& s1, const WString& s2) { return s1.Compare (s2) < 0; }
- DSTRING_API inline bool __stdcall operator < (const WString& s1, const wchar_t * s2) { return s1.Compare (s2) < 0; }
- DSTRING_API inline bool __stdcall operator < (const wchar_t * s1 , const WString& s2) { return s2.Compare (s1) > 0; }
- DSTRING_API inline bool __stdcall operator > (const WString& s1, const WString& s2) { return s1.Compare (s2) > 0; }
- DSTRING_API inline bool __stdcall operator > (const WString& s1, const wchar_t * s2) { return s1.Compare (s2) > 0; }
- DSTRING_API inline bool __stdcall operator > (const wchar_t * s1 , const WString& s2) { return s2.Compare (s1) < 0; }
- DSTRING_API inline bool __stdcall operator <= (const WString& s1, const WString& s2) { return s1.Compare (s2) <= 0; }
- DSTRING_API inline bool __stdcall operator <= (const WString& s1, const wchar_t * s2) { return s1.Compare (s2) <= 0; }
- DSTRING_API inline bool __stdcall operator <= (const wchar_t * s1 , const WString& s2) { return s2.Compare (s1) >= 0; }
- DSTRING_API inline bool __stdcall operator >= (const WString& s1, const WString& s2) { return s1.Compare (s2) >= 0; }
- DSTRING_API inline bool __stdcall operator >= (const WString& s1, const wchar_t * s2) { return s1.Compare (s2) >= 0; }
- DSTRING_API inline bool __stdcall operator >= (const wchar_t * s1 , const WString& s2) { return s2.Compare (s1) <= 0; }
|