Source code of Windows XP (NT5)
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.

365 lines
9.0 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows NT **/
  3. /** Copyright(c) Microsoft Corp., 1997 **/
  4. /**********************************************************************/
  5. /*
  6. string.hxx
  7. This module contains a light weight string class
  8. FILE HISTORY:
  9. 4/8/97 michth created
  10. */
  11. #ifndef _STRINGAU_HXX_
  12. #define _STRINGAU_HXX_
  13. # include <buffer.hxx>
  14. class dllexp STRAU;
  15. /*
  16. Class STRAU
  17. String Ascii-Unicode
  18. This class transparently converts between ANSI and Unicode.
  19. All members can take/return string in either ANSI or Unicode.
  20. For members which have a parameter of bUnicode, the actual string
  21. type must match the flag, even though it gets passed in as the
  22. declared type.
  23. Strings are sync'd on an as needed basis. If a string is set in
  24. ANSI, then a UNICODE version will only be created if a get for
  25. UNICODE is done, or if a UNICODE string is appended.
  26. All conversions are done using Latin-1. This is because the intended
  27. use of this class is for converting HTML pages, which are defined to
  28. be Latin-1.
  29. */
  30. class dllexp STRAU
  31. {
  32. public:
  33. STRAU()
  34. : m_bufAnsi (0),
  35. m_bufUnicode(0),
  36. m_cchUnicodeLen ( 0),
  37. m_cbMultiByteLen ( 0),
  38. m_bInSync (TRUE),
  39. m_bUnicode (FALSE),
  40. m_bIsValid (TRUE)
  41. {}
  42. STRAU( const LPSTR pchInit )
  43. : m_bufAnsi (0),
  44. m_bufUnicode(0),
  45. m_cchUnicodeLen ( 0),
  46. m_cbMultiByteLen ( 0),
  47. m_bInSync (TRUE),
  48. m_bUnicode (FALSE),
  49. m_bIsValid (TRUE)
  50. { AuxInit(pchInit); }
  51. STRAU( const LPSTR pchInit,
  52. BOOL bUnicode )
  53. : m_bufAnsi (0),
  54. m_bufUnicode(0),
  55. m_cchUnicodeLen ( 0),
  56. m_cbMultiByteLen ( 0),
  57. m_bInSync (TRUE),
  58. m_bUnicode (FALSE),
  59. m_bIsValid (TRUE)
  60. {
  61. if (bUnicode) {
  62. AuxInit((LPWSTR)pchInit);
  63. }
  64. else {
  65. AuxInit((LPSTR)pchInit);
  66. }
  67. }
  68. STRAU( const LPWSTR pchInit )
  69. : m_bufAnsi (0),
  70. m_bufUnicode(0),
  71. m_cchUnicodeLen ( 0),
  72. m_cbMultiByteLen ( 0),
  73. m_bInSync (TRUE),
  74. m_bUnicode (FALSE),
  75. m_bIsValid (TRUE)
  76. { AuxInit(pchInit); }
  77. STRAU( STRAU & str )
  78. : m_bufAnsi(0),
  79. m_bufUnicode(0),
  80. m_cchUnicodeLen ( 0),
  81. m_cbMultiByteLen ( 0),
  82. m_bInSync (TRUE),
  83. m_bUnicode (FALSE),
  84. m_bIsValid (TRUE)
  85. {
  86. if (str.IsCurrentUnicode()) {
  87. AuxInit((const LPWSTR)str.QueryStr(TRUE));
  88. }
  89. else {
  90. AuxInit((const LPSTR)str.QueryStr(FALSE));
  91. }
  92. }
  93. BOOL IsValid(VOID) { return m_bIsValid; }
  94. //
  95. // Checks and returns TRUE if this string has no valid data else FALSE
  96. //
  97. BOOL IsEmpty( VOID)
  98. {
  99. return ( (m_bUnicode) ?
  100. *(LPWSTR)(QueryStr(m_bUnicode)) == (WCHAR)'\0' :
  101. *(LPSTR)(QueryStr(m_bUnicode)) == '\0'); }
  102. BOOL Append( const LPSTR pchInit ) {
  103. return ((pchInit != NULL) ? (AuxAppend( (const LPSTR ) pchInit,
  104. ::strlen(pchInit))) :
  105. TRUE);
  106. }
  107. BOOL Append( const LPWSTR pchInit ) {
  108. return ((pchInit != NULL) ? (AuxAppend( (const LPWSTR ) pchInit,
  109. ::wcslen(pchInit))) :
  110. TRUE);
  111. }
  112. BOOL Append( const LPSTR pchInit, DWORD cbLen ) {
  113. return ((pchInit != NULL) ? (AuxAppend( (const LPSTR ) pchInit,
  114. cbLen)) :
  115. TRUE);
  116. }
  117. BOOL Append( const LPWSTR pchInit, DWORD cchLen ) {
  118. return ((pchInit != NULL) ? (AuxAppend( (const LPWSTR ) pchInit,
  119. cchLen)) :
  120. TRUE);
  121. }
  122. BOOL Append( STRAU & str )
  123. {
  124. if (m_bUnicode || str.IsCurrentUnicode()) {
  125. return AuxAppend( str.QueryStrW(), str.QueryCCH());
  126. }
  127. else {
  128. return AuxAppend( str.QueryStrA(), str.QueryCCH());
  129. }
  130. }
  131. //
  132. // SaveState and RestoreState are used to undo the
  133. // effects of Reset on error conditions. They are put here
  134. // to be with Reset. They must be macros since SaveState declares
  135. // variables which RestoreState uses.
  136. //
  137. #define SaveState() \
  138. DBG_ASSERT( m_bufAnsi.QueryPtr() != NULL); \
  139. DBG_ASSERT( m_bufUnicode.QueryPtr() != NULL); \
  140. CHAR cFirstChar = *(LPSTR)(m_bufAnsi.QueryPtr()); \
  141. WCHAR wFirstChar = *(LPWSTR)(m_bufUnicode.QueryPtr()); \
  142. DWORD cchUnicodeLen = m_cchUnicodeLen; \
  143. DWORD cbMultiByteLen = m_cbMultiByteLen; \
  144. BOOL bUnicode = m_bUnicode; \
  145. BOOL bInSync = m_bInSync; \
  146. #define RestoreState() \
  147. *(LPSTR)(m_bufAnsi.QueryPtr()) = cFirstChar; \
  148. *(LPWSTR)(m_bufUnicode.QueryPtr()) = wFirstChar; \
  149. m_cchUnicodeLen = cchUnicodeLen; \
  150. m_cbMultiByteLen = cbMultiByteLen; \
  151. m_bUnicode = bUnicode; \
  152. m_bInSync = bInSync; \
  153. //
  154. // Resets the internal string to be NULL string. Buffer remains cached.
  155. //
  156. VOID Reset( VOID)
  157. {
  158. DBG_ASSERT( m_bufAnsi.QueryPtr() != NULL);
  159. DBG_ASSERT( m_bufUnicode.QueryPtr() != NULL);
  160. *(LPSTR)(m_bufAnsi.QueryPtr()) = '\0';
  161. *(LPWSTR)(m_bufUnicode.QueryPtr()) = (WCHAR)'\0';
  162. m_bUnicode = FALSE;
  163. m_bInSync = TRUE;
  164. m_cchUnicodeLen = 0;
  165. m_cbMultiByteLen = 0;
  166. }
  167. BOOL SetLen( IN DWORD cchLen);
  168. BOOL Copy( const LPSTR pchInit )
  169. {
  170. Reset();
  171. return ( (pchInit != NULL) ?
  172. AuxAppend( pchInit, ::strlen( pchInit ), FALSE ):
  173. TRUE);
  174. }
  175. BOOL Copy( const LPWSTR pchInit ) {
  176. Reset();
  177. return ( (pchInit != NULL) ?
  178. AuxAppend( (const LPWSTR) pchInit, ::wcslen( pchInit ), FALSE ):
  179. TRUE);
  180. }
  181. BOOL SafeCopy( const LPSTR pchInit );
  182. BOOL SafeCopy( const LPWSTR pchInit );
  183. BOOL Copy( const LPSTR pchInit, IN DWORD cbLen ) {
  184. Reset();
  185. return ( (pchInit != NULL) ?
  186. AuxAppend( (LPSTR) pchInit, cbLen, FALSE ):
  187. TRUE);
  188. }
  189. BOOL Copy( const LPWSTR pchInit, IN DWORD cchLen ) {
  190. Reset();
  191. return ( (pchInit != NULL) ?
  192. AuxAppend( (LPWSTR) pchInit, cchLen, FALSE ):
  193. TRUE);
  194. }
  195. BOOL Copy( STRAU & str )
  196. {
  197. BOOL bReturn;
  198. if (str.IsCurrentUnicode()) {
  199. bReturn = Copy((LPWSTR)str.QueryStr(TRUE), str.QueryCCH());
  200. }
  201. else {
  202. bReturn = Copy((LPSTR)str.QueryStr(FALSE), str.QueryCB(FALSE));
  203. }
  204. return bReturn;
  205. }
  206. //
  207. // Returns the number of bytes in the string excluding the terminating
  208. // NULL
  209. //
  210. #ifdef UNICODE
  211. UINT QueryCB(BOOL bUnicode = TRUE)
  212. #else
  213. UINT QueryCB(BOOL bUnicode = FALSE)
  214. #endif
  215. {
  216. if (bUnicode) {
  217. return QueryCBW();
  218. }
  219. else {
  220. return QueryCBA();
  221. }
  222. }
  223. //
  224. // Return # of bytes in the string excluding the teminating NULL
  225. //
  226. UINT QueryCBA()
  227. {
  228. if (m_bUnicode && !m_bInSync) {
  229. //
  230. // Force sync to set m_cbMultiByteLen
  231. //
  232. QueryStrA();
  233. }
  234. return (m_cbMultiByteLen * sizeof(CHAR));
  235. }
  236. //
  237. // Return # of bytes in the string excluding the teminating NULL
  238. //
  239. UINT QueryCBW()
  240. {
  241. if (!m_bUnicode && !m_bInSync) {
  242. //
  243. // Force sync to set m_cchUnicodeLen
  244. //
  245. QueryStrW();
  246. }
  247. return (m_cchUnicodeLen * sizeof(WCHAR));
  248. }
  249. //
  250. // Returns # of characters in the string excluding the terminating NULL
  251. //
  252. UINT QueryCCH( VOID )
  253. {
  254. //
  255. // Unicode Len is same as # characters,
  256. // but Multibyte Len is not, so use
  257. // Unicode Len
  258. //
  259. if (!m_bUnicode && !m_bInSync) {
  260. //
  261. // Force sync to set m_cchUnicodeLen
  262. //
  263. QueryStrW();
  264. }
  265. return (m_cchUnicodeLen);
  266. }
  267. //
  268. // Return the string buffer
  269. //
  270. #ifdef UNICODE
  271. LPTSTR QueryStr(BOOL bUnicode = TRUE);
  272. #else
  273. LPTSTR QueryStr(BOOL bUnicode = FALSE);
  274. #endif
  275. LPSTR QueryStrA( VOID ) { return ( (LPSTR)QueryStr(FALSE)); }
  276. LPWSTR QueryStrW( VOID ) { return ( (LPWSTR)QueryStr(TRUE)); }
  277. BOOL IsCurrentUnicode(void)
  278. {
  279. return m_bUnicode;
  280. }
  281. private:
  282. DWORD m_cchUnicodeLen;
  283. DWORD m_cbMultiByteLen;
  284. VOID AuxInit( const LPSTR pInit );
  285. VOID AuxInit( const LPWSTR pInit );
  286. BOOL AuxAppend( const LPSTR pInit,
  287. UINT cchStr,
  288. BOOL fAddSlop = TRUE );
  289. BOOL AuxAppend( const LPWSTR pInit,
  290. UINT cchStr,
  291. BOOL fAddSlop = TRUE );
  292. BUFFER m_bufAnsi;
  293. BUFFER m_bufUnicode;
  294. BOOL m_bInSync;
  295. BOOL m_bUnicode;
  296. BOOL m_bIsValid;
  297. };
  298. #endif // !_STRINGAU_HXX_