Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

537 lines
19 KiB

  1. /*++
  2. Copyright (c) 1998 Microsoft Corporation
  3. Module Name:
  4. bsstring.h
  5. Abstract:
  6. This module defines the CBsString class. This class manages character
  7. arrays in a similar manner as the CString class in VC++. In fact, this
  8. class is a copy of the CString class with the MFC specific stuff ripped
  9. out since LTS doesn't use MTF.
  10. Added methods in addition to CString:
  11. c_str() - returns a C string pointer ala the STL string class
  12. size() - returns length of string ala the STL string class
  13. Author:
  14. Stefan R. Steiner [SSteiner] 1-Mar-1998
  15. Revision History:
  16. Stefan R. Steiner [SSteiner] 10-Apr-2000
  17. Added fixed allocator code and resynced with MFC 6 SR-1 code
  18. --*/
  19. #ifndef __H_BSSTRING_
  20. #define __H_BSSTRING_
  21. #ifndef __cplusplus
  22. #error requires C++ compilation
  23. #endif
  24. /////////////////////////////////////////////////////////////////////////////
  25. // Other includes from standard "C" runtimes
  26. #ifndef _INC_STRING
  27. #include <string.h>
  28. #endif
  29. #ifndef _INC_STDIO
  30. #include <stdio.h>
  31. #endif
  32. #ifndef _INC_STDLIB
  33. #include <stdlib.h>
  34. #endif
  35. #ifndef _INC_TIME
  36. #include <time.h>
  37. #endif
  38. #ifndef _INC_LIMITS
  39. #include <limits.h>
  40. #endif
  41. #ifndef _INC_STDDEF
  42. #include <stddef.h>
  43. #endif
  44. #ifndef _INC_STDARG
  45. #include <stdarg.h>
  46. #endif
  47. #ifndef _INC_ASSERT
  48. #include <assert.h>
  49. #endif
  50. #ifndef ASSERT
  51. #define ASSERT assert
  52. #endif
  53. #include "bsfixalloc.h"
  54. class CBsString;
  55. //
  56. // The purpose of this class is to generate a compiler error when different string classes
  57. // are used in bad contexts (example: CBsWString used if _UNICODE is not defined)
  58. //
  59. // [aoltean] I introduce this small class to hide a class of LINT warnings.
  60. //
  61. class CBsStringErrorGenerator
  62. {}; // Private constructor
  63. // CBsString only operates on string that are TCHAR arrays. Programs should use
  64. // the following types to make sure they are getting what they are expecting.
  65. #ifdef _UNICODE
  66. #define CBsWString CBsString
  67. #define CBsAString CBsStringErrorGenerator // trigger a compile time bug
  68. #else
  69. #define CBsAString CBsString
  70. #define CBsWString CBsStringErrorGenerator // trigger a compile time bug
  71. #endif
  72. #include <tchar.h>
  73. #ifndef BSAFXAPI
  74. #define BSAFXAPI __cdecl
  75. #define BSAFX_CDECL __cdecl
  76. #endif
  77. // FASTCALL is used for static member functions with little or no params
  78. #ifndef FASTCALL
  79. #define FASTCALL __fastcall
  80. #endif
  81. /////////////////////////////////////////////////////////////////////////////
  82. // Turn off warnings for /W4
  83. // To resume any of these warning: #pragma warning(default: 4xxx)
  84. // which should be placed after the BSAFX include files
  85. #ifndef ALL_WARNINGS
  86. // warnings generated with common MFC/Windows code
  87. #pragma warning(disable: 4127) // constant expression for TRACE/ASSERT
  88. #pragma warning(disable: 4134) // message map member fxn casts
  89. #pragma warning(disable: 4201) // nameless unions are part of C++
  90. #pragma warning(disable: 4511) // private copy constructors are good to have
  91. #pragma warning(disable: 4512) // private operator= are good to have
  92. #pragma warning(disable: 4514) // unreferenced inlines are common
  93. #pragma warning(disable: 4710) // private constructors are disallowed
  94. #pragma warning(disable: 4705) // statement has no effect in optimized code
  95. #pragma warning(disable: 4191) // pointer-to-function casting
  96. // warnings caused by normal optimizations
  97. #ifndef _DEBUG
  98. #pragma warning(disable: 4701) // local variable *may* be used without init
  99. #pragma warning(disable: 4702) // unreachable code caused by optimizations
  100. #pragma warning(disable: 4791) // loss of debugging info in release version
  101. #pragma warning(disable: 4189) // initialized but unused variable
  102. #pragma warning(disable: 4390) // empty controlled statement
  103. #endif
  104. // warnings specific to _BSAFXDLL version
  105. #ifdef _BSAFXDLL
  106. #pragma warning(disable: 4204) // non-constant aggregate initializer
  107. #endif
  108. #ifdef _BSAFXDLL
  109. #pragma warning(disable: 4275) // deriving exported class from non-exported
  110. #pragma warning(disable: 4251) // using non-exported as public in exported
  111. #endif
  112. #endif //!ALL_WARNINGS
  113. #ifdef _DEBUG
  114. #define UNUSED(x)
  115. #else
  116. #define UNUSED(x) x
  117. #endif
  118. #define UNUSED_ALWAYS(x) x
  119. /////////////////////////////////////////////////////////////////////////////
  120. // Strings
  121. #ifndef _OLEAUTO_H_
  122. #ifdef OLE2ANSI
  123. typedef LPSTR BSTR;
  124. #else
  125. typedef LPWSTR BSTR;// must (semantically) match typedef in oleauto.h
  126. #endif
  127. #endif
  128. struct CBsStringData
  129. {
  130. long nRefs; // reference count
  131. int nDataLength; // length of data (including terminator)
  132. int nAllocLength; // length of allocation
  133. // TCHAR data[nAllocLength]
  134. TCHAR* data() // TCHAR* to managed data
  135. { return (TCHAR*)(this+1); }
  136. };
  137. class CBsString
  138. {
  139. public:
  140. // Constructors
  141. // constructs empty CBsString
  142. CBsString();
  143. // copy constructor
  144. CBsString(const CBsString& stringSrc);
  145. // from a single character
  146. CBsString(TCHAR ch, int nRepeat = 1);
  147. // from an ANSI string (converts to TCHAR)
  148. CBsString(LPCSTR lpsz);
  149. // from a UNICODE string (converts to TCHAR)
  150. CBsString(LPCWSTR lpsz);
  151. // subset of characters from an ANSI string (converts to TCHAR)
  152. CBsString(LPCSTR lpch, int nLength);
  153. // subset of characters from a UNICODE string (converts to TCHAR)
  154. CBsString(LPCWSTR lpch, int nLength);
  155. // from unsigned characters
  156. CBsString(const unsigned char* psz);
  157. CBsString(GUID guid);
  158. // Attributes & Operations
  159. // get data length
  160. int GetLength() const;
  161. // TRUE if zero length
  162. BOOL IsEmpty() const;
  163. // clear contents to empty
  164. void Empty();
  165. int size() const; // ala STL string class size()
  166. // return single character at zero-based index
  167. TCHAR GetAt(int nIndex) const;
  168. // return single character at zero-based index
  169. TCHAR operator[](int nIndex) const;
  170. // set a single character at zero-based index
  171. void SetAt(int nIndex, TCHAR ch);
  172. // return pointer to const string
  173. operator LPCTSTR() const;
  174. const LPCTSTR c_str() const; // as a C string in STL string style
  175. // overloaded assignment
  176. // ref-counted copy from another CBsString
  177. const CBsString& operator=(const CBsString& stringSrc);
  178. // set string content to single character
  179. const CBsString& operator=(TCHAR ch);
  180. #ifdef _UNICODE
  181. const CBsString& operator=(char ch);
  182. #endif
  183. // copy string content from ANSI string (converts to TCHAR)
  184. const CBsString& operator=(LPCSTR lpsz);
  185. // copy string content from UNICODE string (converts to TCHAR)
  186. const CBsString& operator=(LPCWSTR lpsz);
  187. // copy string content from unsigned chars
  188. const CBsString& operator=(const unsigned char* psz);
  189. // string concatenation
  190. // concatenate from another CBsString
  191. const CBsString& operator+=(const CBsString& string);
  192. // concatenate a single character
  193. const CBsString& operator+=(TCHAR ch);
  194. #ifdef _UNICODE
  195. // concatenate an ANSI character after converting it to TCHAR
  196. const CBsString& operator+=(char ch);
  197. #endif
  198. // concatenate a UNICODE character after converting it to TCHAR
  199. const CBsString& operator+=(LPCTSTR lpsz);
  200. friend CBsString BSAFXAPI operator+(const CBsString& string1,
  201. const CBsString& string2);
  202. friend CBsString BSAFXAPI operator+(const CBsString& string, TCHAR ch);
  203. friend CBsString BSAFXAPI operator+(TCHAR ch, const CBsString& string);
  204. #ifdef _UNICODE
  205. friend CBsString BSAFXAPI operator+(const CBsString& string, char ch);
  206. friend CBsString BSAFXAPI operator+(char ch, const CBsString& string);
  207. #endif
  208. friend CBsString BSAFXAPI operator+(const CBsString& string, LPCTSTR lpsz);
  209. friend CBsString BSAFXAPI operator+(LPCTSTR lpsz, const CBsString& string);
  210. // string comparison
  211. // straight character comparison
  212. int Compare(LPCTSTR lpsz) const;
  213. // compare ignoring case
  214. int CompareNoCase(LPCTSTR lpsz) const;
  215. // NLS aware comparison, case sensitive
  216. int Collate(LPCTSTR lpsz) const;
  217. // NLS aware comparison, case insensitive
  218. int CollateNoCase(LPCTSTR lpsz) const;
  219. // simple sub-string extraction
  220. // return nCount characters starting at zero-based nFirst
  221. CBsString Mid(int nFirst, int nCount) const;
  222. // return all characters starting at zero-based nFirst
  223. CBsString Mid(int nFirst) const;
  224. // return first nCount characters in string
  225. CBsString Left(int nCount) const;
  226. // return nCount characters from end of string
  227. CBsString Right(int nCount) const;
  228. // characters from beginning that are also in passed string
  229. CBsString SpanIncluding(LPCTSTR lpszCharSet) const;
  230. // characters from beginning that are not also in passed string
  231. CBsString SpanExcluding(LPCTSTR lpszCharSet) const;
  232. // upper/lower/reverse conversion
  233. // NLS aware conversion to uppercase
  234. void MakeUpper();
  235. // NLS aware conversion to lowercase
  236. void MakeLower();
  237. // reverse string right-to-left
  238. void MakeReverse();
  239. // trimming whitespace (either side)
  240. // remove whitespace starting from right edge
  241. void TrimRight();
  242. // remove whitespace starting from left side
  243. void TrimLeft();
  244. // trimming anything (either side)
  245. // remove continuous occurrences of chTarget starting from right
  246. void TrimRight(TCHAR chTarget);
  247. // remove continuous occcurrences of characters in passed string,
  248. // starting from right
  249. void TrimRight(LPCTSTR lpszTargets);
  250. // remove continuous occurrences of chTarget starting from left
  251. void TrimLeft(TCHAR chTarget);
  252. // remove continuous occcurrences of characters in
  253. // passed string, starting from left
  254. void TrimLeft(LPCTSTR lpszTargets);
  255. // advanced manipulation
  256. // replace occurrences of chOld with chNew
  257. int Replace(TCHAR chOld, TCHAR chNew);
  258. // replace occurrences of substring lpszOld with lpszNew;
  259. // empty lpszNew removes instances of lpszOld
  260. int Replace(LPCTSTR lpszOld, LPCTSTR lpszNew);
  261. // remove occurrences of chRemove
  262. int Remove(TCHAR chRemove);
  263. // insert character at zero-based index; concatenates
  264. // if index is past end of string
  265. int Insert(int nIndex, TCHAR ch);
  266. // insert substring at zero-based index; concatenates
  267. // if index is past end of string
  268. int Insert(int nIndex, LPCTSTR pstr);
  269. // delete nCount characters starting at zero-based index
  270. int Delete(int nIndex, int nCount = 1);
  271. // searching
  272. // find character starting at left, -1 if not found
  273. int Find(TCHAR ch) const;
  274. // find character starting at right
  275. int ReverseFind(TCHAR ch) const;
  276. // find character starting at zero-based index and going right
  277. int Find(TCHAR ch, int nStart) const;
  278. // find first instance of any character in passed string
  279. int FindOneOf(LPCTSTR lpszCharSet) const;
  280. // find first instance of substring
  281. int Find(LPCTSTR lpszSub) const;
  282. // find first instance of substring starting at zero-based index
  283. int Find(LPCTSTR lpszSub, int nStart) const;
  284. // simple formatting
  285. // printf-like formatting using passed string
  286. void BSAFX_CDECL Format(LPCTSTR lpszFormat, ...);
  287. // printf-like formatting using variable arguments parameter
  288. void FormatV(LPCTSTR lpszFormat, va_list argList);
  289. #ifndef _UNICODE
  290. // ANSI <-> OEM support (convert string in place)
  291. // convert string from ANSI to OEM in-place
  292. void AnsiToOem();
  293. // convert string from OEM to ANSI in-place
  294. void OemToAnsi();
  295. #endif
  296. #ifndef _BSAFX_NO_BSTR_SUPPORT
  297. // OLE BSTR support (use for OLE automation)
  298. // return a BSTR initialized with this CBsString's data
  299. BSTR AllocSysString() const;
  300. // reallocates the passed BSTR, copies content of this CBsString to it
  301. BSTR SetSysString(BSTR* pbstr) const;
  302. #endif
  303. // Access to string implementation buffer as "C" character array
  304. // get pointer to modifiable buffer at least as long as nMinBufLength
  305. LPTSTR GetBuffer(int nMinBufLength);
  306. // release buffer, setting length to nNewLength (or to first nul if -1)
  307. void ReleaseBuffer(int nNewLength = -1);
  308. // get pointer to modifiable buffer exactly as long as nNewLength
  309. LPTSTR GetBufferSetLength(int nNewLength);
  310. // release memory allocated to but unused by string
  311. void FreeExtra();
  312. // Use LockBuffer/UnlockBuffer to turn refcounting off
  313. // turn refcounting back on
  314. LPTSTR LockBuffer();
  315. // turn refcounting off
  316. void UnlockBuffer();
  317. // Implementation
  318. public:
  319. ~CBsString();
  320. int GetAllocLength() const;
  321. protected:
  322. LPTSTR m_pchData; // Pointer to ref counted string data. This is actually
  323. // a pointer to memory after the CBsStringData structure.
  324. // implementation helpers
  325. CBsStringData* GetData() const;
  326. void Init();
  327. void AllocCopy(CBsString& dest, int nCopyLen, int nCopyIndex, int nExtraLen) const;
  328. void AllocBuffer(int nLen);
  329. void AssignCopy(int nSrcLen, LPCTSTR lpszSrcData);
  330. void ConcatCopy(int nSrc1Len, LPCTSTR lpszSrc1Data, int nSrc2Len, LPCTSTR lpszSrc2Data);
  331. void ConcatInPlace(int nSrcLen, LPCTSTR lpszSrcData);
  332. void CopyBeforeWrite();
  333. void AllocBeforeWrite(int nLen);
  334. void Release();
  335. static void PASCAL Release(CBsStringData* pData);
  336. static int PASCAL SafeStrlen(LPCTSTR lpsz);
  337. static void FASTCALL FreeData(CBsStringData* pData);
  338. };
  339. // Compare helpers
  340. bool BSAFXAPI operator==(const CBsString& s1, const CBsString& s2);
  341. bool BSAFXAPI operator==(const CBsString& s1, LPCTSTR s2);
  342. bool BSAFXAPI operator==(LPCTSTR s1, const CBsString& s2);
  343. bool BSAFXAPI operator!=(const CBsString& s1, const CBsString& s2);
  344. bool BSAFXAPI operator!=(const CBsString& s1, LPCTSTR s2);
  345. bool BSAFXAPI operator!=(LPCTSTR s1, const CBsString& s2);
  346. bool BSAFXAPI operator<(const CBsString& s1, const CBsString& s2);
  347. bool BSAFXAPI operator<(const CBsString& s1, LPCTSTR s2);
  348. bool BSAFXAPI operator<(LPCTSTR s1, const CBsString& s2);
  349. bool BSAFXAPI operator>(const CBsString& s1, const CBsString& s2);
  350. bool BSAFXAPI operator>(const CBsString& s1, LPCTSTR s2);
  351. bool BSAFXAPI operator>(LPCTSTR s1, const CBsString& s2);
  352. bool BSAFXAPI operator<=(const CBsString& s1, const CBsString& s2);
  353. bool BSAFXAPI operator<=(const CBsString& s1, LPCTSTR s2);
  354. bool BSAFXAPI operator<=(LPCTSTR s1, const CBsString& s2);
  355. bool BSAFXAPI operator>=(const CBsString& s1, const CBsString& s2);
  356. bool BSAFXAPI operator>=(const CBsString& s1, LPCTSTR s2);
  357. bool BSAFXAPI operator>=(LPCTSTR s1, const CBsString& s2);
  358. // conversion helpers
  359. int BSAFX_CDECL _wcstombsz(char* mbstr, const wchar_t* wcstr, size_t count);
  360. int BSAFX_CDECL _mbstowcsz(wchar_t* wcstr, const char* mbstr, size_t count);
  361. // valid address test helpers
  362. BOOL BSAFXAPI BsAfxIsValidString(LPCWSTR lpsz, int nLength = -1);
  363. BOOL BSAFXAPI BsAfxIsValidString(LPCSTR lpsz, int nLength = -1);
  364. BOOL BSAFXAPI BsAfxIsValidAddress(const void* lp, UINT nBytes, BOOL bReadWrite = TRUE);
  365. // Globals
  366. extern TCHAR bsafxChNil;
  367. const CBsString& BSAFXAPI BsAfxGetEmptyString();
  368. #define bsafxEmptyString BsAfxGetEmptyString()
  369. inline CBsStringData* CBsString::GetData() const
  370. { ASSERT(m_pchData != NULL); return ((CBsStringData*)m_pchData)-1; }
  371. inline void CBsString::Init()
  372. { m_pchData = bsafxEmptyString.m_pchData; }
  373. inline CBsString::CBsString(const unsigned char* lpsz)
  374. { Init(); *this = (LPCSTR)lpsz; }
  375. inline const CBsString& CBsString::operator=(const unsigned char* lpsz)
  376. { *this = (LPCSTR)lpsz; return *this; }
  377. #ifdef _UNICODE
  378. inline const CBsString& CBsString::operator+=(char ch)
  379. { *this += (TCHAR)ch; return *this; }
  380. inline const CBsString& CBsString::operator=(char ch)
  381. { *this = (TCHAR)ch; return *this; }
  382. inline CBsString BSAFXAPI operator+(const CBsString& string, char ch)
  383. { return string + (TCHAR)ch; }
  384. inline CBsString BSAFXAPI operator+(char ch, const CBsString& string)
  385. { return (TCHAR)ch + string; }
  386. #endif
  387. inline int CBsString::GetLength() const
  388. { return GetData()->nDataLength; }
  389. inline int CBsString::size() const
  390. { return GetData()->nDataLength; }
  391. inline int CBsString::GetAllocLength() const
  392. { return GetData()->nAllocLength; }
  393. inline BOOL CBsString::IsEmpty() const
  394. { return GetData()->nDataLength == 0; }
  395. inline CBsString::operator LPCTSTR() const
  396. { return m_pchData; }
  397. inline const LPCTSTR CBsString::c_str() const
  398. { return m_pchData; }
  399. inline int PASCAL CBsString::SafeStrlen(LPCTSTR lpsz)
  400. { return (lpsz == NULL) ? 0 : lstrlen(lpsz); }
  401. // CBsString support (windows specific)
  402. inline int CBsString::Compare(LPCTSTR lpsz) const
  403. { ASSERT(BsAfxIsValidString(lpsz)); return _tcscmp(m_pchData, lpsz); } // MBCS/Unicode aware
  404. inline int CBsString::CompareNoCase(LPCTSTR lpsz) const
  405. { ASSERT(BsAfxIsValidString(lpsz)); return _tcsicmp(m_pchData, lpsz); } // MBCS/Unicode aware
  406. // CBsString::Collate is often slower than Compare but is MBSC/Unicode
  407. // aware as well as locale-sensitive with respect to sort order.
  408. inline int CBsString::Collate(LPCTSTR lpsz) const
  409. { ASSERT(BsAfxIsValidString(lpsz)); return _tcscoll(m_pchData, lpsz); } // locale sensitive
  410. inline int CBsString::CollateNoCase(LPCTSTR lpsz) const
  411. { ASSERT(BsAfxIsValidString(lpsz)); return _tcsicoll(m_pchData, lpsz); } // locale sensitive
  412. inline TCHAR CBsString::GetAt(int nIndex) const
  413. {
  414. ASSERT(nIndex >= 0);
  415. ASSERT(nIndex < GetData()->nDataLength);
  416. return m_pchData[nIndex];
  417. }
  418. inline TCHAR CBsString::operator[](int nIndex) const
  419. {
  420. // same as GetAt
  421. ASSERT(nIndex >= 0);
  422. ASSERT(nIndex < GetData()->nDataLength);
  423. return m_pchData[nIndex];
  424. }
  425. inline bool BSAFXAPI operator==(const CBsString& s1, const CBsString& s2)
  426. { return s1.Compare(s2) == 0; }
  427. inline bool BSAFXAPI operator==(const CBsString& s1, LPCTSTR s2)
  428. { return s1.Compare(s2) == 0; }
  429. inline bool BSAFXAPI operator==(LPCTSTR s1, const CBsString& s2)
  430. { return s2.Compare(s1) == 0; }
  431. inline bool BSAFXAPI operator!=(const CBsString& s1, const CBsString& s2)
  432. { return s1.Compare(s2) != 0; }
  433. inline bool BSAFXAPI operator!=(const CBsString& s1, LPCTSTR s2)
  434. { return s1.Compare(s2) != 0; }
  435. inline bool BSAFXAPI operator!=(LPCTSTR s1, const CBsString& s2)
  436. { return s2.Compare(s1) != 0; }
  437. inline bool BSAFXAPI operator<(const CBsString& s1, const CBsString& s2)
  438. { return s1.Compare(s2) < 0; }
  439. inline bool BSAFXAPI operator<(const CBsString& s1, LPCTSTR s2)
  440. { return s1.Compare(s2) < 0; }
  441. inline bool BSAFXAPI operator<(LPCTSTR s1, const CBsString& s2)
  442. { return s2.Compare(s1) > 0; }
  443. inline bool BSAFXAPI operator>(const CBsString& s1, const CBsString& s2)
  444. { return s1.Compare(s2) > 0; }
  445. inline bool BSAFXAPI operator>(const CBsString& s1, LPCTSTR s2)
  446. { return s1.Compare(s2) > 0; }
  447. inline bool BSAFXAPI operator>(LPCTSTR s1, const CBsString& s2)
  448. { return s2.Compare(s1) < 0; }
  449. inline bool BSAFXAPI operator<=(const CBsString& s1, const CBsString& s2)
  450. { return s1.Compare(s2) <= 0; }
  451. inline bool BSAFXAPI operator<=(const CBsString& s1, LPCTSTR s2)
  452. { return s1.Compare(s2) <= 0; }
  453. inline bool BSAFXAPI operator<=(LPCTSTR s1, const CBsString& s2)
  454. { return s2.Compare(s1) >= 0; }
  455. inline bool BSAFXAPI operator>=(const CBsString& s1, const CBsString& s2)
  456. { return s1.Compare(s2) >= 0; }
  457. inline bool BSAFXAPI operator>=(const CBsString& s1, LPCTSTR s2)
  458. { return s1.Compare(s2) >= 0; }
  459. inline bool BSAFXAPI operator>=(LPCTSTR s1, const CBsString& s2)
  460. { return s2.Compare(s1) <= 0; }
  461. #endif // __H_BSSTRING_