DString.hpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607
  1. #pragma once
  2. #ifdef DSTRING_EXPORTS
  3. #define DSTRING_API _declspec(dllexport)
  4. #else
  5. #define DSTRING_API _declspec(dllimport)
  6. #endif
  7. class InBuffer;
  8. class OutBuffer;
  9. struct DStringData
  10. {
  11. long nRefs; // reference count
  12. int nDataLength; // length of data (including terminator)
  13. int nAllocLength; // length of allocation
  14. // char data[nAllocLength]
  15. char * data () // char* to managed data
  16. { return (char*) (this+1); }
  17. };
  18. class DSTRING_API DString
  19. {
  20. public:
  21. // Constructors
  22. // constructs empty DString
  23. DString ();
  24. // copy constructor
  25. DString (const DString& stringSrc);
  26. // move constructor
  27. DString (DString && stringSrc);
  28. // from an ANSI string (converts to char)
  29. DString (const char * lpsz);
  30. // subset of characters from an ANSI string (converts to char)
  31. DString (const char * lpch, int nLength);
  32. // from unsigned characters
  33. DString (const unsigned char * lpsz) { Init(); *this = (const char *) lpsz; }
  34. // Attributes & Operations
  35. // get data length
  36. int GetLength () const { return GetData ()->nDataLength; }
  37. int GetByteLength () const { return GetLength (); }
  38. // TRUE if zero length
  39. bool IsEmpty () const { return (GetData ()->nDataLength == 0); }
  40. // clear contents to empty
  41. void Empty ();
  42. // free all data
  43. void Release ();
  44. // return single character at zero-based index
  45. char GetAt (int nIndex) const
  46. {
  47. // ASSERT(nIndex >= 0);
  48. // ASSERT(nIndex < GetData()->nDataLength);
  49. return m_pchData[nIndex];
  50. }
  51. // return single character at zero-based index
  52. char operator [] (int nIndex) const { return GetAt (nIndex); }
  53. // set a single character at zero-based index
  54. void SetAt (int nIndex, char ch);
  55. // Number of ch
  56. int Count (char ch) const;
  57. // Number of lpszSub
  58. int Count (const char * lpszSub) const;
  59. // overloaded assignment
  60. // ref-counted copy from another DString
  61. DString & operator = (const DString & stringSrc);
  62. // set string content to single character
  63. DString & operator = (char ch);
  64. // copy string content from ANSI string (converts to char)
  65. DString & operator = (const char * lpsz);
  66. // copy string content from unsigned chars
  67. DString & operator = (const unsigned char * lpsz) { *this = (const char *) lpsz; return *this; }
  68. DString & operator = (DString && stringSrc);
  69. // string concatenation
  70. // concatenate from another DString
  71. DString & Append (const DString & string)
  72. {
  73. ConcatInPlace (string.GetData ()->nDataLength, string.m_pchData);
  74. return *this;
  75. }
  76. // concatenate a single character
  77. DString & Append (char ch)
  78. {
  79. ConcatInPlace (1, &ch);
  80. return *this;
  81. }
  82. DString & Append (const char * lpsz)
  83. {
  84. ConcatInPlace ((int)strlen (lpsz), lpsz);
  85. return *this;
  86. }
  87. // concatenate from another DString
  88. DString & operator += (const DString & string)
  89. {
  90. return Append (string);
  91. }
  92. // concatenate a single character
  93. DString & operator += (char ch)
  94. {
  95. return Append (ch);
  96. }
  97. DString & operator += (const char * lpsz)
  98. {
  99. return Append (lpsz);
  100. }
  101. DString & operator << (const DString & string)
  102. {
  103. return Append (string);
  104. }
  105. DString & operator << (char ch)
  106. {
  107. return Append (ch);
  108. }
  109. DString & operator << (const char * lpsz)
  110. {
  111. return Append (lpsz);
  112. }
  113. DSTRING_API friend DString operator + (const DString & string1, const DString & string2);
  114. DSTRING_API friend DString operator + (const DString & string, char ch);
  115. DSTRING_API friend DString operator + (char ch, const DString & string);
  116. DSTRING_API friend DString operator + (const DString & string, const char * lpsz);
  117. DSTRING_API friend DString operator + (const char * lpsz, const DString & string);
  118. // string comparison
  119. // straight character comparison
  120. int Compare (const char * lpsz) const;
  121. // compare ignoring case
  122. int CompareNoCase (const char * lpsz) const;
  123. // NLS aware comparison, case sensitive
  124. int Collate (const char * lpsz) const;
  125. // NLS aware comparison, case insensitive
  126. int CollateNoCase (const char * lpsz) const;
  127. // Returns the similarity between 2 strings
  128. float Similar (const char * lpsz) const;
  129. float Similar (const DString & str) const;
  130. // simple sub-string extraction
  131. // return nCount characters starting at zero-based nFirst
  132. DString Mid (int nFirst, int nCount) const;
  133. // return all characters starting at zero-based nFirst
  134. DString Mid (int nFirst) const;
  135. // return first nCount characters in string
  136. DString Left (int nCount) const;
  137. // return nCount characters from end of string
  138. DString Right (int nCount) const;
  139. // characters from beginning that are also in passed string
  140. DString SpanIncluding (const char * lpszCharSet) const;
  141. // characters from beginning that are not also in passed string
  142. DString SpanExcluding (const char * lpszCharSet) const;
  143. // upper/lower/reverse conversion
  144. // NLS aware conversion to uppercase
  145. void MakeUpper ();
  146. // NLS aware conversion to lowercase
  147. void MakeLower ();
  148. // reverse string right-to-left
  149. void MakeReverse ();
  150. // trimming whitespace (either side)
  151. // remove whitespace starting from right edge
  152. void TrimRight ();
  153. // remove whitespace starting from left side
  154. void TrimLeft ();
  155. // remove continuous occurrences of chTarget starting from right
  156. void TrimRight (char chTarget);
  157. // remove continuous occcurrences of characters in passed string,
  158. // starting from right
  159. void TrimRight (const char * lpszTargets);
  160. // remove continuous occurrences of chTarget starting from left
  161. void TrimLeft (char chTarget);
  162. // remove continuous occcurrences of characters in
  163. // passed string, starting from left
  164. void TrimLeft (const char * lpszTargets);
  165. // trimming anything (either side)
  166. DString Trim () const { DString copy = *this; copy.TrimRight (); copy.TrimLeft (); return copy; }
  167. // advanced manipulation
  168. // replace occurrences of chOld with chNew
  169. int Replace (char chOld, char chNew);
  170. // replace occurrences of substring lpszOld with lpszNew;
  171. // empty lpszNew removes instances of lpszOld
  172. int Replace (const char * lpszOld, const char * lpszNew);
  173. // replace, compare no case
  174. int NCReplace (const char * lpszOld, const char * lpszNew);
  175. // remove occurrences of lpszSub, just same as Replace (lpszSub, nullptr);
  176. int Remove (const char * lpszSub);
  177. // remove occurrences of chRemove
  178. int Remove (char chRemove);
  179. // remove space character
  180. int RemoveSpace ();
  181. // remove punctuation character
  182. int RemovePunctuation ();
  183. // remove control character
  184. int RemoveControl ();
  185. // remove occurrences of lpszSub, compare no case
  186. int NCRemove (const char * lpszSub);
  187. // remove occurrences of chRemove, compare no case
  188. int NCRemove (char chRemove);
  189. // replace tabs to space;
  190. int ReplaceTabs (int abstand);
  191. // insert character at zero-based index; concatenates
  192. // if index is past end of string
  193. int Insert (int nIndex, char ch);
  194. // insert substring at zero-based index; concatenates
  195. // if index is past end of string
  196. int Insert (int nIndex, const char * pstr);
  197. // delete nCount characters starting at zero-based index
  198. int Delete (int nIndex, int nCount = 1);
  199. // insert character n times
  200. void Repeat (char ch, int n);
  201. // insert string n times;
  202. void Repeat (const char * lpszStr, int n);
  203. // searching
  204. // find character starting at left, -1 if not found
  205. int Find (char ch) const;
  206. // find character starting at right
  207. int ReverseFind (char ch) const;
  208. // find character starting at zero-based index and going right
  209. int Find (char ch, int nStart) const;
  210. // find first instance of any character in passed string
  211. int FindOneOf (const char * lpszCharSet) const;
  212. // find first instance of substring
  213. int Find (const char * lpszSub) const;
  214. // find first instance of substring starting at zero-based index
  215. int Find (const char * lpszSub, int nStart) const;
  216. int NCFind (char ch) const;
  217. int NCFind (const char * lpszSub) const;
  218. // Cast
  219. public:
  220. // return pointer to const string
  221. operator const char * () const { return m_pchData; }
  222. const char * constBuffer (void) const { return m_pchData; }
  223. operator bool () const = delete;
  224. public:
  225. static DString From (const int i);
  226. static DString From (const long i);
  227. static DString From (const unsigned int u);
  228. static DString From (const unsigned long u);
  229. static DString From (const __int64 i);
  230. static DString From (const unsigned __int64 u);
  231. static DString From (const double d);
  232. // simple formatting
  233. static DString FromFormat (const char * szFormat, ...);
  234. // repeat a single character
  235. static DString FromRepeat (char ch, int nRepeat);
  236. protected:
  237. // make a guess at the maximum length of the resulting string
  238. static int __cdecl GetFormattedLength (const char * pszFormat, va_list argList);
  239. static int __cdecl VFormat (char * lpzBuffer, const char * pszFormat, va_list argList);
  240. public:
  241. // printf-like formatting using passed string
  242. void Format (const char * lpszFormat, ...);
  243. // printf-like formatting using referenced string resource
  244. void FormatV (const char * lpszFormat, va_list argList);
  245. // append with the formatted string
  246. void AppendFormat (const char * lpszFormat, ...);
  247. void AppendFormatV (const char * lpszFormat, va_list argList);
  248. void FormatMsg (unsigned long errcode, const char * fmt, ...);
  249. // Access to string implementation buffer as "C" character array
  250. // get pointer to modifiable buffer at least as long as nMinBufLength
  251. char * GetBuffer (int nMinBufLength);
  252. // release buffer, setting length to nNewLength (or to first nul if -1)
  253. void ReleaseBuffer (int nNewLength = -1);
  254. // get pointer to modifiable buffer exactly as long as nNewLength
  255. char * GetBufferSetLength (int nNewLength);
  256. //==============================================================================
  257. // Functions for Element-Strings
  258. //==============================================================================
  259. DString Elements (int start, int stop, char sep) const;
  260. DString Element (int i, char sep) const;
  261. int IndexOfElement (const char * lpszSuch, char sep) const;
  262. int IndexOfElement (double such, char sep) const;
  263. int IndexOfElement (int such, char sep) const;
  264. int IndexOfElement (char such, char sep) const;
  265. int IndexOfElement (bool such, char sep) const;
  266. // release memory allocated to but unused by string
  267. void FreeExtra ();
  268. // Use LockBuffer/UnlockBuffer to turn refcounting off
  269. // turn refcounting back on
  270. char * LockBuffer ();
  271. // turn refcounting off
  272. void UnlockBuffer ();
  273. // input and output
  274. friend InBuffer & operator >> (InBuffer & ib, DString& string);
  275. friend OutBuffer & operator << (OutBuffer & ob, const DString& string);
  276. // Implementation
  277. public:
  278. ~DString ();
  279. int GetAllocLength () const { return GetData ()->nAllocLength; }
  280. // The following code is stealed from CStringEx
  281. public:
  282. DString operator -- ()
  283. {
  284. *this = Left (GetLength () - 1);
  285. return *this;
  286. }
  287. DString operator -- (int)
  288. {
  289. DString copy (*this);
  290. *this = Left (GetLength () - 1);
  291. return copy;
  292. }
  293. public:
  294. // 转换函数
  295. double Double () const { return atof (m_pchData); }
  296. int Int () const { int i = atoi (m_pchData); if (i) return i; return strtol (m_pchData, nullptr, 16); }
  297. long Long () const { long l = atol (m_pchData); if (l) return l; return strtol (m_pchData, nullptr, 16); }
  298. char Char () const { return m_pchData[0]; }
  299. bool Bool () const;
  300. __int64 Int64 () const { __int64 i = _atoi64 (m_pchData); if (i) return i; return _strtoi64 (m_pchData, nullptr, 16); }
  301. template <typename T> T To () const { }
  302. template <> int To () const { return Int (); }
  303. template <> double To () const { return Double (); }
  304. template <> float To () const { return (float) Double (); }
  305. template <> long To () const { return Long (); }
  306. template <> bool To () const { return Bool (); }
  307. template <> __int64 To () const { return Int64 (); }
  308. template <> unsigned int To () const { return Int (); }
  309. template <> unsigned __int64 To () const { return Int64 (); }
  310. template <> unsigned long To () const { return Long (); }
  311. public:
  312. // 判断整个字符串是否是某一类字符组成
  313. bool IsDigit () const;
  314. bool IsAlNum () const;
  315. bool IsAlpha () const;
  316. bool IsUpper () const;
  317. bool IsLower () const;
  318. bool IsSpace () const;
  319. // 判断某个字符是否是某一类字符组成
  320. bool IsDigit (int nPos) const;
  321. bool IsAlNum (int nPos) const;
  322. bool IsAlpha (int nPos) const;
  323. bool IsUpper (int nPos) const;
  324. bool IsLower (int nPos) const;
  325. bool IsSpace (int nPos) const;
  326. public:
  327. bool ToCharacterSet (unsigned int CodePage);
  328. bool FromCharacterSet (unsigned int CodePage);
  329. // End of stealed code
  330. protected:
  331. char * m_pchData; // pointer to ref counted string data
  332. // implementation helpers
  333. DStringData * DString::GetData() const
  334. {
  335. return ((DStringData *) m_pchData)-1;
  336. }
  337. void Init ();
  338. void AllocCopy (DString& dest, int nCopyLen, int nCopyIndex, int nExtraLen) const;
  339. void AllocBuffer (int nLen);
  340. void AssignCopy (int nSrcLen, const char * lpszSrcData);
  341. void ConcatCopy (int nSrc1Len, const char * lpszSrc1Data, int nSrc2Len, const char * lpszSrc2Data);
  342. void ConcatInPlace (int nSrcLen, const char * lpszSrcData);
  343. void CopyBeforeWrite ();
  344. void AllocBeforeWrite (int nLen);
  345. void MoveAssign (DString & Src);
  346. static void Release (DStringData * pData);
  347. static void FreeData (DStringData * pData);
  348. //-----------------------------------------------------------------------------
  349. // Token类用来对字符串进行标识符切分
  350. //-----------------------------------------------------------------------------
  351. public:
  352. class DSTRING_API Token
  353. {
  354. public:
  355. Token (const DString & str, bool bSkipPunctuation = false) :
  356. m_Str (str),
  357. m_bSkipPunctuation (bSkipPunctuation)
  358. {
  359. // 在Restart之前先初始化这个变量,因为Restart之后需要立即调用Next,
  360. // 而Next函数需要这个变量
  361. Restart ();
  362. }
  363. public:
  364. operator bool () const { return m_bContinue; };
  365. operator DString () const { return Current (); };
  366. public:
  367. // 定位到下一个标识符
  368. bool Next (void);
  369. // 定位到下一个标识符,但是以出作为分割符
  370. bool Next (char sep);
  371. // 定位到行尾,Current返回直到行尾的所有字符,但是不包括行尾的回车或换行
  372. bool NextLine (void);
  373. DString Current (void) const; // 获得当前标识符,或者当前行
  374. bool IsValid () const { return (m_nL <= m_nR); };
  375. void Clear (void)
  376. {
  377. m_nL = 0;
  378. m_nR = -1;
  379. m_nNext = 0;
  380. m_bContinue = true;
  381. m_nStrLength = 0;
  382. }
  383. void Restart (void) // 重新开始
  384. {
  385. m_szDoc = m_Str;
  386. Clear ();
  387. m_nStrLength = (int) strlen (m_szDoc);
  388. Next ();
  389. }
  390. bool SkipPunctuation (bool bSkipPunctuation)
  391. {
  392. bool tmp = m_bSkipPunctuation;
  393. m_bSkipPunctuation =bSkipPunctuation;
  394. return tmp;
  395. }
  396. void operator ++ () // ++Token; prevfix
  397. {
  398. Next ();
  399. }
  400. void operator ++ (int) // Token++; postfix
  401. {
  402. Next ();
  403. }
  404. DString operator () (void) const
  405. {
  406. return Current ();
  407. }
  408. protected:
  409. int FindWhitespace (int nChar) const; // 从nChar开始,定位到下一个非空字符,并返回这个位置的索引,如果找不到,返回-1
  410. int FindChar (int nChar, char ch) const; // 从nChar开始,在字符串中寻找与ch相同的下一个ch,并返回这个位置的索引,如果找不到,返回-1
  411. protected:
  412. const DString & m_Str;
  413. const char * m_szDoc;
  414. int m_nL; // 当前标识符的左边界
  415. int m_nR; // 当前标识符的右边界
  416. int m_nNext; // 下一个标识符的初始位置
  417. bool m_bContinue; // 可用继续迭代吗?
  418. int m_nStrLength; // 字符串长度;
  419. bool m_bSkipPunctuation; // Next()时跳过标点符号,即Current()不会返回遇到的标点符号
  420. };
  421. #if 0
  422. //-----------------------------------------------------------------------------
  423. // DFileName类用来对Windows的文件名进行切分和组合
  424. //-----------------------------------------------------------------------------
  425. class DSTRING_API DFileName
  426. {
  427. public:
  428. DFileName (const char * FileName) { Init (FileName); }
  429. public:
  430. const char * FullFileName () const // 获得全文件名
  431. {
  432. return m_szFullFileName;
  433. }
  434. const char * FileName () const // 获得文件名
  435. {
  436. return m_szFileName;
  437. }
  438. const char * FileExt () const // 获得扩展名
  439. {
  440. return m_ext;
  441. }
  442. const char * Drive () const // 获得驱动器名
  443. {
  444. return m_drive;
  445. }
  446. const char * FilePath () const; // 获得全路径名
  447. bool IsFile (const char * FileName) const; // 判断是否是某个文件,FileName必须是文件名,不能含有路径
  448. void SetPath (const char * Path); // 将路径设置为Path
  449. protected:
  450. void Init (const char * FileName);
  451. protected:
  452. char m_szFileName [_MAX_PATH + _MAX_PATH];
  453. char m_szFullFileName [_MAX_PATH + _MAX_PATH];
  454. mutable char m_szFilePath [_MAX_PATH + _MAX_PATH];
  455. char m_drive [_MAX_PATH];
  456. char m_path [_MAX_PATH];
  457. char m_filename [_MAX_PATH];
  458. char m_ext [_MAX_PATH];
  459. };
  460. #endif
  461. };
  462. // Compare helpers
  463. DSTRING_API inline bool __stdcall operator == (const DString& s1, const DString& s2) { return s1.Compare (s2) == 0; }
  464. DSTRING_API inline bool __stdcall operator == (const DString& s1, const char * s2) { return s1.Compare (s2) == 0; }
  465. DSTRING_API inline bool __stdcall operator == (const char * s1 , const DString& s2) { return s2.Compare (s1) == 0; }
  466. DSTRING_API inline bool __stdcall operator != (const DString& s1, const DString& s2) { return s1.Compare (s2) != 0; }
  467. DSTRING_API inline bool __stdcall operator != (const DString& s1, const char * s2) { return s1.Compare (s2) != 0; }
  468. DSTRING_API inline bool __stdcall operator != (const char * s1 , const DString& s2) { return s2.Compare (s1) != 0; }
  469. DSTRING_API inline bool __stdcall operator < (const DString& s1, const DString& s2) { return s1.Compare (s2) < 0; }
  470. DSTRING_API inline bool __stdcall operator < (const DString& s1, const char * s2) { return s1.Compare (s2) < 0; }
  471. DSTRING_API inline bool __stdcall operator < (const char * s1 , const DString& s2) { return s2.Compare (s1) > 0; }
  472. DSTRING_API inline bool __stdcall operator > (const DString& s1, const DString& s2) { return s1.Compare (s2) > 0; }
  473. DSTRING_API inline bool __stdcall operator > (const DString& s1, const char * s2) { return s1.Compare (s2) > 0; }
  474. DSTRING_API inline bool __stdcall operator > (const char * s1 , const DString& s2) { return s2.Compare (s1) < 0; }
  475. DSTRING_API inline bool __stdcall operator <= (const DString& s1, const DString& s2) { return s1.Compare (s2) <= 0; }
  476. DSTRING_API inline bool __stdcall operator <= (const DString& s1, const char * s2) { return s1.Compare (s2) <= 0; }
  477. DSTRING_API inline bool __stdcall operator <= (const char * s1 , const DString& s2) { return s2.Compare (s1) >= 0; }
  478. DSTRING_API inline bool __stdcall operator >= (const DString& s1, const DString& s2) { return s1.Compare (s2) >= 0; }
  479. DSTRING_API inline bool __stdcall operator >= (const DString& s1, const char * s2) { return s1.Compare (s2) >= 0; }
  480. DSTRING_API inline bool __stdcall operator >= (const char * s1 , const DString& s2) { return s2.Compare (s1) <= 0; }