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.

217 lines
6.0 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows NT **/
  3. /** Copyright(c) Microsoft Corp., 1994 **/
  4. /**********************************************************************/
  5. /*
  6. multisz.hxx
  7. This module contains a light weight multi-string class
  8. FILE HISTORY:
  9. KeithMo 20-Jan-1997 Created from string.hxx.
  10. */
  11. #ifndef _MULTISZ_HXX_
  12. #define _MULTISZ_HXX_
  13. # include <string.hxx>
  14. /*++
  15. class MULTISZ:
  16. Intention:
  17. A light-weight multi-string class supporting encapsulated string class.
  18. This object is derived from BUFFER class.
  19. It maintains following state:
  20. m_fValid - whether this object is valid -
  21. used only by MULTISZ() init functions
  22. * NYI: I need to kill this someday *
  23. m_cchLen - string length cached when we update the string.
  24. m_cStrings - number of strings.
  25. Member Functions:
  26. There are two categories of functions:
  27. 1) Safe Functions - which do integrity checking of state
  28. 2) UnSafe Functions - which do not do integrity checking, but
  29. enable writing to the data stream freely.
  30. (someday this will be enabled as Safe versions without
  31. problem for users)
  32. --*/
  33. class dllexp MULTISZ : public BUFFER
  34. {
  35. public:
  36. MULTISZ()
  37. : BUFFER (),
  38. m_cchLen ( 0),
  39. m_cStrings(0)
  40. {}
  41. // creates a stack version of the MULTISZ object - uses passed in stack buffer
  42. // MULTISZ does not free this pbInit on its own.
  43. MULTISZ( CHAR * pbInit, DWORD cbInit)
  44. : BUFFER( (BYTE *) pbInit, cbInit),
  45. m_cchLen (0),
  46. m_cStrings(0)
  47. {}
  48. MULTISZ( const CHAR * pchInit )
  49. : BUFFER (),
  50. m_cchLen ( 0),
  51. m_cStrings(0)
  52. { AuxInit( (const BYTE * ) pchInit); }
  53. MULTISZ( const MULTISZ & str )
  54. : BUFFER (),
  55. m_cchLen ( 0),
  56. m_cStrings(0)
  57. { AuxInit( (const BYTE * ) str.QueryStr()); }
  58. BOOL IsValid(VOID) const { return ( BUFFER::IsValid()) ; }
  59. //
  60. // Checks and returns TRUE if this string has no valid data else FALSE
  61. //
  62. BOOL IsEmpty( VOID) const { return ( *QueryStr() == '\0'); }
  63. BOOL Append( const CHAR * pchInit ) {
  64. return ((pchInit != NULL) ? (AuxAppend( (const BYTE * ) pchInit,
  65. (::strlen(pchInit) + 1) * sizeof(CHAR)
  66. )) :
  67. TRUE);
  68. }
  69. BOOL Append( const CHAR * pchInit, DWORD cchLen ) {
  70. return ((pchInit != NULL) ? (AuxAppend( (const BYTE * ) pchInit,
  71. cchLen * sizeof(CHAR))) :
  72. TRUE);
  73. }
  74. BOOL Append( const STR & str )
  75. { return AuxAppend( (const BYTE * ) str.QueryStr(),
  76. (str.QueryCCH() + 1) * sizeof(CHAR)); }
  77. // Resets the internal string to be NULL string. Buffer remains cached.
  78. VOID Reset( VOID)
  79. { DBG_ASSERT( QueryPtr() != NULL);
  80. QueryStr()[0] = '\0';
  81. QueryStr()[1] = '\0';
  82. m_cchLen = 2;
  83. m_cStrings = 0;
  84. }
  85. BOOL Copy( const CHAR * pchInit, IN DWORD cchLen ) {
  86. if ( QueryPtr() ) { Reset(); }
  87. return ( (pchInit != NULL) ?
  88. AuxAppend( (const BYTE *) pchInit, cchLen, FALSE ):
  89. TRUE);
  90. }
  91. BOOL Copy( const MULTISZ & str )
  92. { return ( Copy(str.QueryStr(), str.QueryCCH())); }
  93. //
  94. // Returns the number of bytes in the string including the terminating
  95. // NULLs
  96. //
  97. UINT QueryCB( VOID ) const
  98. { return ( m_cchLen * sizeof(CHAR)); }
  99. //
  100. // Returns # of characters in the string including the terminating NULLs
  101. //
  102. UINT QueryCCH( VOID ) const { return (m_cchLen); }
  103. //
  104. // Returns # of strings in the multisz.
  105. //
  106. DWORD QueryStringCount( VOID ) const { return m_cStrings; }
  107. //
  108. // Makes a copy of the stored string in given buffer
  109. //
  110. BOOL CopyToBuffer( CHAR * lpszBuffer, LPDWORD lpcch) const;
  111. //
  112. // Return the string buffer
  113. //
  114. CHAR * QueryStrA( VOID ) const { return ( QueryStr()); }
  115. CHAR * QueryStr( VOID ) const { return ((CHAR *) QueryPtr()); }
  116. //
  117. // Makes a clone of the current string in the string pointer passed in.
  118. //
  119. BOOL
  120. Clone( OUT MULTISZ * pstrClone) const
  121. {
  122. return ((pstrClone == NULL) ?
  123. (SetLastError(ERROR_INVALID_PARAMETER), FALSE) :
  124. (pstrClone->Copy( *this))
  125. );
  126. } // MULTISZ::Clone()
  127. //
  128. // Recalculates the length of *this because we've modified the buffers
  129. // directly
  130. //
  131. VOID RecalcLen( VOID )
  132. { m_cchLen = MULTISZ::CalcLength( QueryStr(), &m_cStrings ); }
  133. //
  134. // Calculate total character length of a MULTI_SZ, including the
  135. // terminating NULLs.
  136. //
  137. static DWORD CalcLength( const CHAR * str,
  138. LPDWORD pcStrings = NULL );
  139. //
  140. // Determine if the MULTISZ contains a specific string.
  141. //
  142. BOOL FindString( const CHAR * str );
  143. BOOL FindString( const STR & str )
  144. { return FindString( str.QueryStr() ); }
  145. //
  146. // Used for scanning a multisz.
  147. //
  148. const CHAR * First( VOID ) const
  149. { return *QueryStr() == '\0' ? NULL : QueryStr(); }
  150. const CHAR * Next( const CHAR * Current ) const
  151. { Current += ::strlen( Current ) + 1;
  152. return *Current == '\0' ? NULL : Current; }
  153. private:
  154. DWORD m_cchLen;
  155. DWORD m_cStrings;
  156. VOID AuxInit( const BYTE * pInit );
  157. BOOL AuxAppend( const BYTE * pInit,
  158. UINT cbStr, BOOL fAddSlop = TRUE );
  159. };
  160. //
  161. // Quick macro for declaring a MULTISZ that will use stack memory of <size>
  162. // bytes. If the buffer overflows then a heap buffer will be allocated
  163. //
  164. #define STACK_MULTISZ( name, size ) CHAR __ach##name[size]; \
  165. MULTISZ name( __ach##name, sizeof( __ach##name ))
  166. #endif // !_MULTISZ_HXX_
  167.