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.

217 lines
5.1 KiB

  1. #ifndef _HEADER_H_
  2. #define _HEADER_H_
  3. // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  4. //
  5. // HEADER.H
  6. //
  7. // Header for HTTP header cache class.
  8. // This cache is meant to hold pairs of strings, indexed by the first
  9. // string in the pair. The indexing string will be treated
  10. // as case-insensitive (Content-Type and content-type are treated as
  11. // the same slot in the cache).
  12. //
  13. // NOTE: Header names are NOT localized strings -- they are always 7-bit ASCII,
  14. // and should NEVER be treated as MBCS strings.
  15. // Later, this cache might make optimizations that depend on the indexing
  16. // string being 7-bit ASCII.
  17. //
  18. // Copyright 1997 Microsoft Corporation, All Rights Reserved
  19. //
  20. // ========================================================================
  21. //
  22. // CLASS CHeaderCache
  23. //
  24. #include "gencache.h"
  25. template<class _T>
  26. class CHeaderCache
  27. {
  28. typedef CCache<CRCSzi, const _T *> CHdrCache;
  29. // String data storage area.
  30. //
  31. ChainedStringBuffer<_T> m_sb;
  32. protected:
  33. // Cache of header values, keyed by CRC'd name
  34. //
  35. CHdrCache m_cache;
  36. // NOT IMPLEMENTED
  37. //
  38. CHeaderCache& operator=( const CHeaderCache& );
  39. CHeaderCache( const CHeaderCache& );
  40. public:
  41. // CREATORS
  42. //
  43. CHeaderCache()
  44. {
  45. // If this fails, our allocators will throw for us.
  46. (void)m_cache.FInit();
  47. }
  48. // ACCESSORS
  49. //
  50. // ------------------------------------------------------------------------
  51. //
  52. // CHeaderCache::LpszGetHeader()
  53. //
  54. // Fetch a header from the cache. Return the header value if found,
  55. // NULL otherwise.
  56. //
  57. const _T * LpszGetHeader( LPCSTR pszName ) const
  58. {
  59. const _T ** ppszValue;
  60. Assert( pszName );
  61. ppszValue = m_cache.Lookup( CRCSzi(pszName) );
  62. if ( !ppszValue )
  63. return NULL;
  64. return *ppszValue;
  65. }
  66. // MANIPULATORS
  67. //
  68. // ------------------------------------------------------------------------
  69. //
  70. // CHeaderCache::ClearHeaders()
  71. //
  72. // Clear all headers from the cache.
  73. //
  74. void ClearHeaders()
  75. {
  76. // Clear all data from the map.
  77. //
  78. m_cache.Clear();
  79. // Also clear out the string buffer.
  80. //
  81. m_sb.Clear();
  82. }
  83. // ------------------------------------------------------------------------
  84. //
  85. // CHeaderCache::DeleteHeader()
  86. //
  87. // Remove a header from the cache.
  88. //
  89. void DeleteHeader( LPCSTR pszName )
  90. {
  91. //
  92. // Note: this just removes the cache item (i.e. the header
  93. // name/value pair). It DOES NOT free up the memory used by the
  94. // header name/value strings which are stored in our string buffer.
  95. // We would need a string buffer class which supports deletion
  96. // (and a smarter string class) for that.
  97. //
  98. m_cache.Remove( CRCSzi(pszName) );
  99. }
  100. // ------------------------------------------------------------------------
  101. //
  102. // CHeaderCache::SetHeader()
  103. //
  104. // Set a header in the cache.
  105. // If pszValue NULL, just set NULL as the header value.
  106. // If pszValue is the empty string, just set the header string to the
  107. // empty string.
  108. // Return the string's cache placement (same as GetHeader) for convenience.
  109. //
  110. // NOTE:
  111. // fMultiple is an optional param that defaults to FALSE
  112. //
  113. const _T * SetHeader( LPCSTR pszName, const _T * pszValue, BOOL fMultiple = FALSE)
  114. {
  115. Assert( pszName );
  116. pszName = reinterpret_cast<LPCSTR>(m_sb.Append( static_cast<UINT>(strlen(pszName) + 1), reinterpret_cast<const _T *>(pszName) ));
  117. if ( pszValue )
  118. {
  119. if (sizeof(_T) == sizeof(WCHAR))
  120. {
  121. pszValue = m_sb.Append( static_cast<UINT>(CbSizeWsz(wcslen(reinterpret_cast<LPCWSTR>(pszValue)))), pszValue );
  122. }
  123. else
  124. {
  125. pszValue = m_sb.Append( static_cast<UINT>(strlen(reinterpret_cast<LPCSTR>(pszValue)) + 1), pszValue );
  126. }
  127. }
  128. if (fMultiple)
  129. (void)m_cache.FAdd( CRCSzi(pszName), pszValue );
  130. else
  131. (void)m_cache.FSet( CRCSzi(pszName), pszValue );
  132. return pszValue;
  133. }
  134. };
  135. class CHeaderCacheForResponse : public CHeaderCache<CHAR>
  136. {
  137. // ========================================================================
  138. //
  139. // CLASS CEmit
  140. //
  141. // Functional class to emit a header name/value pair to a buffer
  142. //
  143. class CEmit : public CHdrCache::IOp
  144. {
  145. StringBuffer<CHAR>& m_bufData;
  146. // NOT IMPLEMENTED
  147. //
  148. CEmit& operator=( const CEmit& );
  149. public:
  150. CEmit( StringBuffer<CHAR>& bufData ) : m_bufData(bufData) {}
  151. virtual BOOL operator()( const CRCSzi& crcsziName,
  152. const LPCSTR& pszValue )
  153. {
  154. // Throw in the header name string.
  155. //
  156. m_bufData.Append( crcsziName.m_lpsz );
  157. // Throw in a colon delimiter.
  158. //
  159. m_bufData.Append( gc_szColonSp );
  160. // Throw in the header value string.
  161. //
  162. m_bufData.Append( pszValue );
  163. // Terminate the header line (CRLF).
  164. //
  165. m_bufData.Append( gc_szCRLF );
  166. // Tell the cache to keep iterating.
  167. //
  168. return TRUE;
  169. }
  170. };
  171. // NOT IMPLEMENTED
  172. //
  173. CHeaderCacheForResponse& operator=( const CHeaderCacheForResponse& );
  174. CHeaderCacheForResponse( const CHeaderCacheForResponse& );
  175. public:
  176. // CREATORS
  177. //
  178. CHeaderCacheForResponse()
  179. {
  180. }
  181. void DumpData( StringBuffer<CHAR>& bufData ) const;
  182. };
  183. #endif // !_HEADER_H_