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.

268 lines
6.0 KiB

  1. /*++
  2. Copyright (c) 2001 Microsoft Corporation
  3. Module Name:
  4. chunkflt.hxx
  5. Abstract:
  6. Contains a filter for encoding and decoding chunked transfers.
  7. Contents:
  8. BaseFilter
  9. FILTER_LIST
  10. ChunkDecodeContext
  11. ChunkFilter
  12. Author:
  13. Oliver Wallace (oliverw) 13-Feb-2001
  14. Revision History:
  15. 13-Feb-2001 oliverw
  16. Created
  17. --*/
  18. // Base class meant for when additional filters will be available.
  19. class BaseFilter
  20. {
  21. public:
  22. virtual HRESULT Reset(DWORD_PTR dwContext)
  23. {
  24. return E_NOTIMPL;
  25. }
  26. virtual HRESULT
  27. Decode(
  28. IN DWORD_PTR dwContext,
  29. IN OUT LPBYTE pInBuffer,
  30. IN DWORD dwInBufSize,
  31. IN OUT LPBYTE *ppOutBuffer,
  32. IN OUT LPDWORD pdwOutBufSize,
  33. OUT LPDWORD pdwBytesRead,
  34. OUT LPDWORD pdwBytesWritten
  35. )
  36. {
  37. return E_NOTIMPL;
  38. }
  39. virtual HRESULT
  40. Encode(
  41. DWORD_PTR dwContext,
  42. IN OUT LPBYTE pInBuffer,
  43. IN DWORD dwInBufSize,
  44. IN OUT LPBYTE *ppOutBuffer,
  45. IN OUT LPDWORD pdwOutBufSize,
  46. OUT LPDWORD pdwBytesRead,
  47. OUT LPDWORD pdwBytesWritten
  48. )
  49. {
  50. return E_NOTIMPL;
  51. }
  52. virtual HRESULT RegisterContext(OUT DWORD_PTR *pdwContext)
  53. {
  54. return E_NOTIMPL;
  55. }
  56. virtual HRESULT UnregisterContext(IN DWORD_PTR dwContext)
  57. {
  58. return E_NOTIMPL;
  59. }
  60. virtual BOOL IsFinished(IN DWORD_PTR dwContext)
  61. {
  62. return FALSE;
  63. }
  64. };
  65. typedef struct FILTER_LIST_ENTRY
  66. {
  67. DWORD_PTR dwContext; // Registered context associated with pFilter
  68. BaseFilter *pFilter; // Data Filter used to encode/decode dwContext
  69. FILTER_LIST_ENTRY *pNext;
  70. }
  71. FILTER_LIST_ENTRY, * LPFILTER_LIST_ENTRY;
  72. class FILTER_LIST
  73. {
  74. /*++
  75. Class Description:
  76. The FILTER_LIST class defines the data filter list used to encode/decode
  77. data when sending/receiving data.
  78. Post v5, this will need some extensions:
  79. - Make this a priority list to accommodate mroe flexible encoding order.
  80. - Implement Encode method to process upload filters once support is added.
  81. - Add smartness to Encode/Decode methods to buffer data.
  82. --*/
  83. public:
  84. FILTER_LIST()
  85. {
  86. _pFilterEntry = NULL;
  87. _uFilterCount = 0;
  88. }
  89. ~FILTER_LIST()
  90. {
  91. ClearList();
  92. }
  93. // Always inserts as the beginning of the list
  94. BOOL
  95. Insert(IN BaseFilter *pFilter, IN DWORD_PTR dwContext);
  96. VOID
  97. ClearList();
  98. DWORD
  99. Decode(
  100. IN OUT LPBYTE pInBuffer,
  101. IN DWORD dwInBufSize,
  102. IN OUT LPBYTE *ppOutBuffer,
  103. IN OUT LPDWORD pdwOutBufSize,
  104. OUT LPDWORD pdwBytesRead,
  105. OUT LPDWORD pdwBytesWritten
  106. );
  107. // Right now, there should never be more than just the chunk filter.
  108. BOOL IsFinished()
  109. {
  110. if (_pFilterEntry)
  111. return _pFilterEntry->pFilter->IsFinished(_pFilterEntry->dwContext);
  112. else
  113. return FALSE;
  114. }
  115. private:
  116. LPFILTER_LIST_ENTRY _pFilterEntry;
  117. UINT _uFilterCount;
  118. };
  119. // Chunk filter state table, data and object prototypes.
  120. // Various token flags to describe the current byte being parsed.
  121. //
  122. // NOTE: Make sure you update the global table in chunkflt.cxx
  123. // if this list is modified.
  124. typedef enum
  125. {
  126. CHUNK_TOKEN_DIGIT = 0,
  127. CHUNK_TOKEN_CR,
  128. CHUNK_TOKEN_LF,
  129. CHUNK_TOKEN_COLON,
  130. CHUNK_TOKEN_DATA,
  131. CHUNK_TOKEN_LAST = CHUNK_TOKEN_DATA
  132. } CHUNK_TOKEN_VALUE;
  133. // NOTE: Do NOT update this without updating the table in chunkflt.cxx
  134. // which maps tokens for the current state to the next state.
  135. typedef enum
  136. {
  137. CHUNK_DECODE_STATE_START = 0,
  138. CHUNK_DECODE_STATE_SIZE,
  139. CHUNK_DECODE_STATE_SIZE_CRLF,
  140. CHUNK_DECODE_STATE_EXT,
  141. CHUNK_DECODE_STATE_DATA,
  142. CHUNK_DECODE_STATE_DATA_CRLF,
  143. CHUNK_DECODE_STATE_FOOTER_NAME,
  144. CHUNK_DECODE_STATE_FOOTER_VALUE,
  145. CHUNK_DECODE_STATE_FINAL_CRLF,
  146. CHUNK_DECODE_STATE_ERROR,
  147. CHUNK_DECODE_STATE_FINISHED,
  148. CHUNK_DECODE_STATE_LAST = CHUNK_DECODE_STATE_FINISHED
  149. } CHUNK_DECODE_STATE, *LPCHUNK_DECODE_STATE;
  150. class ChunkDecodeContext
  151. {
  152. private:
  153. CHUNK_DECODE_STATE m_eDecodeState;
  154. DWORD m_dwParsedSize;
  155. friend class ChunkFilter;
  156. public:
  157. ChunkDecodeContext() { Reset(); }
  158. // TODO: Consider subclassing contexts because they share common
  159. // properties/methods that could be virtual (e.g. Get/SetState).
  160. CHUNK_DECODE_STATE
  161. GetState()
  162. {
  163. return m_eDecodeState;
  164. }
  165. VOID
  166. SetState(CHUNK_DECODE_STATE eNewState)
  167. {
  168. m_eDecodeState = eNewState;
  169. }
  170. VOID Reset()
  171. {
  172. m_eDecodeState = CHUNK_DECODE_STATE_START;
  173. m_dwParsedSize = 0;
  174. }
  175. };
  176. class ChunkFilter : public BaseFilter
  177. {
  178. public:
  179. // TODO: Provide an init method that is chunked-specific
  180. // (e.g. set size for chunked uploads)
  181. HRESULT Reset(DWORD_PTR dwContext);
  182. HRESULT
  183. Decode(
  184. IN DWORD_PTR dwContext,
  185. IN OUT LPBYTE pInBuffer,
  186. IN DWORD dwInBufSize,
  187. IN OUT LPBYTE *ppOutBuffer,
  188. IN OUT LPDWORD pdwOutBufSize,
  189. OUT LPDWORD pdwBytesRead,
  190. OUT LPDWORD pdwBytesWritten
  191. );
  192. HRESULT
  193. Encode(
  194. IN DWORD_PTR dwContext,
  195. IN OUT LPBYTE pInBuffer,
  196. IN DWORD dwInBufSize,
  197. OUT LPBYTE *ppOutBuffer,
  198. OUT LPDWORD pdwOutBufSize,
  199. OUT LPDWORD pdwBytesRead,
  200. OUT LPDWORD pdwBytesWritten
  201. );
  202. HRESULT RegisterContext(OUT DWORD_PTR *pdwContext);
  203. HRESULT UnregisterContext(IN DWORD_PTR dwContext);
  204. BOOL
  205. IsFinished(IN DWORD_PTR dwContext)
  206. {
  207. if (dwContext)
  208. return ((reinterpret_cast<ChunkDecodeContext *>(dwContext))->GetState() ==
  209. CHUNK_DECODE_STATE_FINISHED ? TRUE : FALSE);
  210. else
  211. return FALSE;
  212. }
  213. };