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.

417 lines
11 KiB

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