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.

511 lines
13 KiB

  1. /*++
  2. Copyright (C) 1996-1999 Microsoft Corporation
  3. Module Name:
  4. PASSTR.INL
  5. History:
  6. --*/
  7. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  8. //
  9. // Default constructor for a Pascal string. Sets the length to zero, with
  10. // no storage.
  11. //
  12. //-----------------------------------------------------------------------------
  13. inline
  14. CPascalString::CPascalString()
  15. {
  16. //
  17. // The string data class is initialized by it's constructor.
  18. //
  19. LTASSERT(m_blbData.GetBlobSize() == 0);
  20. DEBUGONLY(++m_UsageCounter);
  21. }
  22. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  23. //
  24. // Casting operator to convert a CPascalString to a blob.
  25. //
  26. //-----------------------------------------------------------------------------
  27. inline
  28. CPascalString::operator const CLocCOWBlob &(void)
  29. const
  30. {
  31. return m_blbData;
  32. }
  33. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  34. //
  35. // Assignment operator - CPascalString to CPascalString.
  36. //
  37. //-----------------------------------------------------------------------------
  38. inline
  39. const CPascalString & // Allows a=b=c;
  40. CPascalString::operator=(
  41. const CPascalString &pstrSource) // Source string
  42. {
  43. DEBUGONLY(m_StorageCounter -= m_blbData.GetBlobSize());
  44. m_blbData = ((const CLocCOWBlob &)pstrSource);
  45. DEBUGONLY(m_StorageCounter += m_blbData.GetBlobSize());
  46. return *this;
  47. }
  48. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  49. //
  50. // Copy constructor for CPascalString's
  51. //
  52. //-----------------------------------------------------------------------------
  53. inline
  54. CPascalString::CPascalString(
  55. const CPascalString &pstrSource)
  56. {
  57. LTASSERT(pstrSource.m_blbData.GetWriteCount() == 0);
  58. operator=(pstrSource);
  59. DEBUGONLY(++m_UsageCounter);
  60. }
  61. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  62. //
  63. // Assignment operator - Wide character C String to CPascalString. The string
  64. // is COPIED into the CPascalString.
  65. //
  66. //-----------------------------------------------------------------------------
  67. inline
  68. const CPascalString & // Allows a=b=c;
  69. CPascalString::operator=(
  70. const WCHAR *wszSource) // Source, zero terminated string
  71. {
  72. SetString(wszSource, wcslen(wszSource));
  73. return *this;
  74. }
  75. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  76. //
  77. // Appends a CPascalString to the current string.
  78. //
  79. //-----------------------------------------------------------------------------
  80. inline
  81. const CPascalString & // Allows a=b+=c syntax
  82. CPascalString::operator+=(
  83. const CPascalString &pstrTail) // Pascal string to append
  84. {
  85. AppendBuffer(pstrTail, pstrTail.GetStringLength());
  86. return *this;
  87. }
  88. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  89. //
  90. // Append a NUL terminated Unicode string to a Pascal string.
  91. //
  92. //-----------------------------------------------------------------------------
  93. inline
  94. const CPascalString & // Allows a-b+=L"Hi There" syntax
  95. CPascalString::operator+=(
  96. const WCHAR *szTail) // NUL terminated string to append
  97. {
  98. AppendBuffer(szTail, wcslen(szTail));
  99. return *this;
  100. }
  101. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  102. //
  103. // Append a Unicode character to a Pascal string.
  104. //
  105. //-----------------------------------------------------------------------------
  106. inline
  107. const CPascalString & // Allows a-b+=L"Hi There" syntax
  108. CPascalString::operator+=(
  109. const WCHAR wch) // WCHAR to append
  110. {
  111. AppendBuffer(&wch, 1);
  112. return *this;
  113. }
  114. //-----------------------------------------------------------------------------
  115. //
  116. // Comparison function for Pascal strings.
  117. //
  118. //-----------------------------------------------------------------------------
  119. inline
  120. BOOL // TRUE (1) if the same
  121. CPascalString::IsEqualTo(
  122. const CPascalString &pstrOtherString) const // String to compare to
  123. {
  124. return m_blbData == (const CLocCOWBlob &)pstrOtherString;
  125. }
  126. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  127. //
  128. // Operator == version of IsEqualTo
  129. //
  130. //-----------------------------------------------------------------------------
  131. inline
  132. int // TRUE (1) if equal
  133. CPascalString::operator==(
  134. const CPascalString &pstrOtherString) // String to compare
  135. const
  136. {
  137. return IsEqualTo(pstrOtherString);
  138. }
  139. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  140. //
  141. // Operator != - just the negative of IsEqualTo
  142. //
  143. //-----------------------------------------------------------------------------
  144. inline
  145. int // TRUE (1) if *not* equal
  146. CPascalString::operator!=(
  147. const CPascalString &pstrOtherString) const // String to compare
  148. {
  149. return !IsEqualTo(pstrOtherString);
  150. }
  151. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  152. //
  153. // Comparison operator for NUL terminated WCHAR strings.
  154. //
  155. //-----------------------------------------------------------------------------
  156. inline
  157. int
  158. CPascalString::operator==(
  159. const WCHAR *pwch)
  160. const
  161. {
  162. return (wcscmp(*this, pwch) == 0);
  163. }
  164. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  165. //
  166. // Comparison operator for NUL termninated WCHAR strings.
  167. //
  168. //-----------------------------------------------------------------------------
  169. inline int
  170. CPascalString::operator!=(
  171. const WCHAR *pwch)
  172. const
  173. {
  174. return (wcscmp(*this, pwch) != 0);
  175. }
  176. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  177. //
  178. // Is there anything in the string? This is different from a string of zero
  179. // length.
  180. //
  181. //-----------------------------------------------------------------------------
  182. inline
  183. BOOL
  184. CPascalString::IsNull(void)
  185. const
  186. {
  187. return ((const void *)m_blbData == NULL);
  188. }
  189. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  190. //
  191. // Get the length of the pascal string. If the length is zero, there may be
  192. // no storage associated with the string. Use IsNull to check for storage.
  193. //
  194. //-----------------------------------------------------------------------------
  195. inline
  196. UINT // length of the string.
  197. CPascalString::GetStringLength(void) const
  198. {
  199. UINT uiBufferSize;
  200. uiBufferSize = m_blbData.GetBlobSize();
  201. LTASSERT((uiBufferSize % sizeof(WCHAR)) == 0);
  202. return (uiBufferSize != 0 ? (uiBufferSize/sizeof(WCHAR)-1): 0);
  203. }
  204. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  205. //
  206. // Set the length of the pascal string. String contents are not preserved
  207. //
  208. //-----------------------------------------------------------------------------
  209. inline
  210. void // length of the string.
  211. CPascalString::SetStringLength(UINT uNewSize)
  212. {
  213. DEBUGONLY(m_StorageCounter -= m_blbData.GetBlobSize());
  214. m_blbData.SetBlobSize((uNewSize + 1) * sizeof(WCHAR));
  215. DEBUGONLY(m_StorageCounter += m_blbData.GetBlobSize());
  216. *(GetStringPointer() + uNewSize) = L'\0';
  217. ReleaseStringPointer();
  218. }
  219. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  220. //
  221. // Realloc a string - set true size
  222. //
  223. //-----------------------------------------------------------------------------
  224. inline
  225. void // length of the string.
  226. CPascalString::ReallocString(UINT uNewSize)
  227. {
  228. DEBUGONLY(m_StorageCounter -= m_blbData.GetBlobSize());
  229. m_blbData.ReallocBlob((uNewSize + 1) * sizeof(WCHAR));
  230. DEBUGONLY(m_StorageCounter += m_blbData.GetBlobSize());
  231. *(GetStringPointer() + uNewSize) = L'\0';
  232. ReleaseStringPointer();
  233. }
  234. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  235. //
  236. // As an optimization, the user can ask the Pascal string to reserve some
  237. // memory for future growth. This would allow incremental additions to be
  238. // very efficent. The reported size of the string is not changed - only the
  239. // amount of storage reserved for the string.
  240. //
  241. // If the user requests less space than is already allocated, nothing
  242. // happens.
  243. //
  244. //-----------------------------------------------------------------------------
  245. inline
  246. void
  247. CPascalString::ReserveStorage(
  248. UINT nMinSize) // Size (in chars) to reserve for
  249. {
  250. if (nMinSize > GetStringLength())
  251. {
  252. UINT uiCurSize;
  253. uiCurSize = GetStringLength();
  254. ReallocString(nMinSize);
  255. ReallocString(uiCurSize);
  256. }
  257. }
  258. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  259. //
  260. // Get a pointer to the storage for the string. This may be NULL if the
  261. // string has length 0. This pointer should be considered INVALID if any
  262. // other assignment operation is performed on the Pascal string. Calling
  263. // this dis-ables teh COW behavior of the CPascalString.
  264. //
  265. //-----------------------------------------------------------------------------
  266. inline
  267. WCHAR *
  268. CPascalString::GetStringPointer(void)
  269. {
  270. return (WCHAR *)m_blbData.GetPointer();
  271. }
  272. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  273. //
  274. // Anytime you do a GetStringPointer, use ReleaseStringPointer to allow
  275. // the PascalString to revert to COW behavior. Once you call this, the
  276. // pointer from GetStringPointer is INVALID.
  277. //
  278. //-----------------------------------------------------------------------------
  279. inline
  280. void
  281. CPascalString::ReleaseStringPointer(void)
  282. {
  283. m_blbData.ReleasePointer();
  284. }
  285. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  286. //
  287. // Casting operator version of GetString pointer. Cast a CPascalString to
  288. // const WCHAR *, and you get a pointer to the string.
  289. //
  290. //-----------------------------------------------------------------------------
  291. inline
  292. CPascalString::operator const WCHAR *(void) const
  293. {
  294. return (const WCHAR *)(const void *)(m_blbData);
  295. }
  296. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  297. //
  298. // Cleanup on the string. Sets the length to zero, and remove all storage.
  299. // This is different than assigning a NULL string - that is a string of
  300. // length 1, consisting of the NUL (zero) character.
  301. //
  302. //-----------------------------------------------------------------------------
  303. inline
  304. void
  305. CPascalString::ClearString(void)
  306. {
  307. DEBUGONLY(m_StorageCounter -= m_blbData.GetBlobSize());
  308. m_blbData.SetBlobSize(0);
  309. }
  310. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  311. //
  312. // Destructor for a Pascal string. Frees up the current storage. After
  313. // a Pascal string goes out of scope, all pointers to the internal storage
  314. // are invalid.
  315. //
  316. //-----------------------------------------------------------------------------
  317. inline
  318. CPascalString::~CPascalString()
  319. {
  320. LTASSERTONLY(AssertValid());
  321. DEBUGONLY(--m_UsageCounter);
  322. DEBUGONLY(m_StorageCounter -= m_blbData.GetBlobSize());
  323. }
  324. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  325. //
  326. // Serialize for a Pascal string.
  327. //
  328. //-----------------------------------------------------------------------------
  329. inline
  330. void CPascalString::Serialize(CArchive &ar)
  331. {
  332. if (ar.IsStoring())
  333. {
  334. Store(ar);
  335. }
  336. else
  337. {
  338. Load(ar);
  339. }
  340. }
  341. inline
  342. void
  343. CPascalString::Store(
  344. CArchive &ar)
  345. const
  346. {
  347. LTASSERT(ar.IsStoring());
  348. LTASSERTONLY(AssertValid());
  349. //
  350. // HACK HACK HACK
  351. // Emulate Old Espresso 3.0 serialization.
  352. m_blbData.Store(ar);
  353. }
  354. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  355. //
  356. // Helper function - comparison operator for a NUL terminated WCHAR string
  357. // and a CPascalString.
  358. //
  359. //-----------------------------------------------------------------------------
  360. inline
  361. int
  362. operator==(
  363. const WCHAR *pwch,
  364. const CPascalString &pstr)
  365. {
  366. return (wcscmp(pwch, pstr) == 0);
  367. }
  368. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  369. //
  370. // Helper function - comparison operator for a NUL terminated WCHAR string
  371. // and a CPascalString.
  372. //
  373. //-----------------------------------------------------------------------------
  374. inline
  375. int
  376. operator!=(
  377. const WCHAR *pwch,
  378. const CPascalString &pstr)
  379. {
  380. return (wcscmp(pwch, pstr) != 0);
  381. }
  382. inline
  383. int CPascalString::operator!=(
  384. const _bstr_t &bsOther)
  385. const
  386. {
  387. return !(operator==(bsOther));
  388. }
  389. inline
  390. int
  391. operator==(
  392. const _bstr_t &bsOther,
  393. const CPascalString &pstr)
  394. {
  395. return pstr == bsOther;
  396. }
  397. inline
  398. int
  399. operator!=(
  400. const _bstr_t &bsOther,
  401. const CPascalString &pstr)
  402. {
  403. return pstr != bsOther;
  404. }