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.

298 lines
6.6 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows NT **/
  3. /** Copyright(c) Microsoft Corp., 1997 **/
  4. /**********************************************************************/
  5. /*
  6. multisz.cxx
  7. This module contains a light weight multi-string class
  8. FILE HISTORY:
  9. KeithMo 20-Jan-1997 Created from string.cxx
  10. */
  11. #include "precomp.hxx"
  12. # include <dbgutil.h>
  13. # include <multisz.hxx>
  14. # include <auxctrs.h>
  15. # include <tchar.h>
  16. //
  17. // Private Definitions
  18. //
  19. //
  20. // When appending data, this is the extra amount we request to avoid
  21. // reallocations
  22. //
  23. #define STR_SLOP 128
  24. DWORD
  25. MULTISZ::CalcLength( const CHAR * str,
  26. LPDWORD pcStrings )
  27. {
  28. DWORD count = 0;
  29. DWORD total = 1;
  30. DWORD len;
  31. while( *str ) {
  32. len = ::strlen( str ) + 1;
  33. total += len;
  34. str += len;
  35. count++;
  36. }
  37. if( pcStrings != NULL ) {
  38. *pcStrings = count;
  39. }
  40. return total;
  41. } // MULTISZ::CalcLength
  42. BOOL
  43. MULTISZ::FindString( const CHAR * str )
  44. {
  45. CHAR * multisz;
  46. //
  47. // Sanity check.
  48. //
  49. DBG_ASSERT( QueryStr() != NULL );
  50. DBG_ASSERT( str != NULL );
  51. DBG_ASSERT( *str != '\0' );
  52. //
  53. // Scan it.
  54. //
  55. multisz = QueryStr();
  56. while( *multisz != '\0' ) {
  57. if( !::strcmp( multisz, str ) ) {
  58. return TRUE;
  59. }
  60. multisz += ::strlen( multisz ) + 1;
  61. }
  62. return FALSE;
  63. } // MULTISZ::FindString
  64. VOID
  65. MULTISZ::AuxInit( const BYTE * pInit )
  66. {
  67. BOOL fRet;
  68. if ( pInit )
  69. {
  70. DWORD cStrings;
  71. int cbCopy = CalcLength( (const CHAR *)pInit, &cStrings ) * sizeof(CHAR);
  72. fRet = Resize( cbCopy );
  73. if ( fRet ) {
  74. CopyMemory( QueryPtr(), pInit, cbCopy );
  75. m_cchLen = (cbCopy)/sizeof(CHAR);
  76. m_cStrings = cStrings;
  77. } else {
  78. BUFFER::SetValid( FALSE);
  79. }
  80. } else {
  81. Reset();
  82. }
  83. } // MULTISZ::AuxInit()
  84. /*******************************************************************
  85. NAME: MULTISZ::AuxAppend
  86. SYNOPSIS: Appends the string onto the multisz.
  87. ENTRY: Object to append
  88. ********************************************************************/
  89. BOOL MULTISZ::AuxAppend( const BYTE * pStr, UINT cbStr, BOOL fAddSlop )
  90. {
  91. DBG_ASSERT( pStr != NULL );
  92. UINT cbThis = QueryCB();
  93. DBG_ASSERT( cbThis >= 2 );
  94. if( cbThis == 2 ) {
  95. //
  96. // It's empty, so start at the beginning.
  97. //
  98. cbThis = 0;
  99. } else {
  100. //
  101. // It's not empty, so back up over the final terminating NULL.
  102. //
  103. cbThis--;
  104. }
  105. //
  106. // Only resize when we have to. When we do resize, we tack on
  107. // some extra space to avoid extra reallocations.
  108. //
  109. // Note: QuerySize returns the requested size of the string buffer,
  110. // *not* the strlen of the buffer
  111. //
  112. AcIncrement( CacMultiszAppend);
  113. if ( QuerySize() < cbThis + cbStr + 1)
  114. {
  115. if ( !Resize( cbThis + cbStr + 1 + (fAddSlop ? STR_SLOP : 0 )) )
  116. return FALSE;
  117. }
  118. // copy the exact string and tack on the double terminator
  119. memcpy( (BYTE *) QueryPtr() + cbThis,
  120. pStr,
  121. cbStr);
  122. *((BYTE *)QueryPtr() + cbThis + cbStr) = '\0';
  123. m_cchLen = CalcLength( (const CHAR *)QueryPtr(), &m_cStrings );
  124. return TRUE;
  125. } // MULTISZ::AuxAppend()
  126. #if 0
  127. BOOL
  128. MULTISZ::CopyToBuffer( WCHAR * lpszBuffer, LPDWORD lpcch) const
  129. /*++
  130. Description:
  131. Copies the string into the WCHAR buffer passed in if the buffer
  132. is sufficient to hold the translated string.
  133. If the buffer is small, the function returns small and sets *lpcch
  134. to contain the required number of characters.
  135. Arguments:
  136. lpszBuffer pointer to WCHAR buffer which on return contains
  137. the UNICODE version of string on success.
  138. lpcch pointer to DWORD containing the length of the buffer.
  139. If *lpcch == 0 then the function returns TRUE with
  140. the count of characters required stored in *lpcch.
  141. Also in this case lpszBuffer is not affected.
  142. Returns:
  143. TRUE on success.
  144. FALSE on failure. Use GetLastError() for further details.
  145. History:
  146. MuraliK 11-30-94
  147. --*/
  148. {
  149. BOOL fReturn = TRUE;
  150. if ( lpcch == NULL) {
  151. SetLastError( ERROR_INVALID_PARAMETER);
  152. return ( FALSE);
  153. }
  154. if ( *lpcch == 0) {
  155. //
  156. // Inquiring the size of buffer alone
  157. //
  158. *lpcch = QueryCCH() + 1; // add one character for terminating null
  159. } else {
  160. //
  161. // Copy after conversion from ANSI to Unicode
  162. //
  163. int iRet;
  164. iRet = MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED,
  165. QueryStrA(), QueryCCH() + 1,
  166. lpszBuffer, (int )*lpcch);
  167. if ( iRet == 0 || iRet != (int ) *lpcch) {
  168. //
  169. // Error in conversion.
  170. //
  171. fReturn = FALSE;
  172. }
  173. }
  174. return ( fReturn);
  175. } // MULTISZ::CopyToBuffer()
  176. #endif
  177. BOOL
  178. MULTISZ::CopyToBuffer( CHAR * lpszBuffer, LPDWORD lpcch) const
  179. /*++
  180. Description:
  181. Copies the string into the CHAR buffer passed in if the buffer
  182. is sufficient to hold the translated string.
  183. If the buffer is small, the function returns small and sets *lpcch
  184. to contain the required number of characters.
  185. Arguments:
  186. lpszBuffer pointer to CHAR buffer which on return contains
  187. the string on success.
  188. lpcch pointer to DWORD containing the length of the buffer.
  189. If *lpcch == 0 then the function returns TRUE with
  190. the count of characters required stored in *lpcch.
  191. Also in this case lpszBuffer is not affected.
  192. Returns:
  193. TRUE on success.
  194. FALSE on failure. Use GetLastError() for further details.
  195. History:
  196. MuraliK 20-Nov-1996
  197. --*/
  198. {
  199. BOOL fReturn = TRUE;
  200. if ( lpcch == NULL) {
  201. SetLastError( ERROR_INVALID_PARAMETER);
  202. return ( FALSE);
  203. }
  204. register DWORD cch = QueryCCH() + 1;
  205. if ( *lpcch >= cch) {
  206. DBG_ASSERT( lpszBuffer);
  207. CopyMemory( lpszBuffer, QueryStrA(), cch);
  208. } else {
  209. DBG_ASSERT( *lpcch < cch);
  210. SetLastError( ERROR_INSUFFICIENT_BUFFER);
  211. fReturn = FALSE;
  212. }
  213. *lpcch = cch;
  214. return ( fReturn);
  215. } // MULTISZ::CopyToBuffer()