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.

416 lines
11 KiB

  1. #ifndef _BODY_H_
  2. #define _BODY_H_
  3. // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  4. //
  5. // BODY.H
  6. //
  7. // Common implementation classes from which request body and
  8. // response body are derived.
  9. //
  10. // Copyright 1986-1997 Microsoft Corporation, All Rights Reserved
  11. //
  12. #include <sgstruct.h>
  13. #include <limits.h> // definition of LONG_MIN
  14. #include <ex\refcnt.h> // IRefCounted
  15. #include <ex\astream.h> // Async stream interfaces
  16. #include <ex\refhandle.h> // auto_ref_handle, etc.
  17. // ========================================================================
  18. //
  19. // CLASS IAsyncPersistObserver
  20. //
  21. // Async I/O completion callback object interface used by
  22. // IBody::AsyncPersist(). Callers of AsyncPersist() must pass an object
  23. // conforming to this interface. That object will be notified when
  24. // the async persist operation completes via a call to its
  25. // PersistComplete() member function.
  26. //
  27. class IAsyncPersistObserver : public IRefCounted
  28. {
  29. // NOT IMPLEMENTED
  30. //
  31. IAsyncPersistObserver& operator=( const IAsyncPersistObserver& );
  32. public:
  33. // CREATORS
  34. //
  35. virtual ~IAsyncPersistObserver() = 0;
  36. // MANIPULATORS
  37. //
  38. virtual VOID PersistComplete( HRESULT hr ) = 0;
  39. };
  40. // ========================================================================
  41. //
  42. // CLASS IAcceptObserver
  43. //
  44. // Passed to the IBody::Accept() and IBodyPartAccept() methods when
  45. // accepting a body part visitor. The accept observer is called whenever
  46. // the accept operation completes (which may happen asynchronously).
  47. // Note that the body part visitor is often the accept observer itself,
  48. // but it doesn't have to be. The accept code which notifies the observer
  49. // is not aware that it is notifying a visitor.
  50. //
  51. class IAcceptObserver
  52. {
  53. // NOT IMPLEMENTED
  54. //
  55. IAcceptObserver& operator=( const IAcceptObserver& );
  56. public:
  57. // CREATORS
  58. //
  59. virtual ~IAcceptObserver() = 0;
  60. // MANIPULATORS
  61. //
  62. virtual VOID AcceptComplete( UINT64 cbAccepted64 ) = 0;
  63. };
  64. // ========================================================================
  65. //
  66. // CLASS CAsyncDriver
  67. //
  68. // Implements a mechanism to allow an object to be driven asynchronously
  69. // from any one thread at a time.
  70. //
  71. template<class X>
  72. class CAsyncDriver
  73. {
  74. //
  75. // Number of calls to Run() that will be made before
  76. // the object requires another call to Start() to
  77. // get it going again. Each call to Start() increments
  78. // this count by one. The count is decremented by
  79. // one as each Run() completes.
  80. //
  81. LONG m_lcRunCount;
  82. // NOT IMPLEMENTED
  83. //
  84. CAsyncDriver( const CAsyncDriver& );
  85. CAsyncDriver& operator=( const CAsyncDriver& );
  86. public:
  87. // CREATORS
  88. //
  89. CAsyncDriver() : m_lcRunCount(0) {}
  90. #ifdef DBG
  91. ~CAsyncDriver() { m_lcRunCount = LONG_MIN; }
  92. #endif
  93. // MANIPULATORS
  94. //
  95. VOID Start(X& x)
  96. {
  97. //
  98. // The object's Run() implementation often allows the final ref
  99. // on the object to be released. And this CAsyncDriver is often
  100. // a member of that object. Therefore, we need to AddRef() the
  101. // object to keep ourselves alive until we return from this
  102. // function. It's kinda strange, but the alternative is to
  103. // require callers to AddRef() the object themselves, but that
  104. // approach would be more prone to error.
  105. //
  106. auto_ref_ptr<X> px(&x);
  107. AssertSz( m_lcRunCount >= 0, "CAsyncDriver::Start() called on destroyed/bad CAsyncDriver!" );
  108. //
  109. // Start/Restart/Continue the driver
  110. //
  111. if ( InterlockedIncrement( &m_lcRunCount ) == 1 )
  112. {
  113. do
  114. {
  115. x.Run();
  116. }
  117. while ( InterlockedDecrement( &m_lcRunCount ) > 0 );
  118. }
  119. }
  120. };
  121. // ========================================================================
  122. //
  123. // CLASS IBodyPart
  124. //
  125. // Defines the interface to a body part. An IBodyPart object is assumed
  126. // to consist of the body part data and an internal iterator over that
  127. // data.
  128. //
  129. // An IBodyPart must implement the following methods:
  130. //
  131. // CbSize()
  132. // Returns the size (in bytes) of the body part. Necessary for
  133. // computation of a part's contribution to the content length.
  134. //
  135. // Rewind()
  136. // Prepares the body part to be traversed again by new visitor.
  137. //
  138. // Accept()
  139. // Accepts a body part visitor object to iterate over the body part.
  140. // The accept operation may be asynchronous either because the
  141. // body part chooses to implement it that way, or because the accepted
  142. // visitor requires it. For this reason, an accept observer is
  143. // also used. This observer should be called whenever the
  144. // accept operation completes.
  145. //
  146. class IBodyPart
  147. {
  148. // NOT IMPLEMENTED
  149. //
  150. IBodyPart& operator=( const IBodyPart& );
  151. public:
  152. // CREATORS
  153. //
  154. virtual ~IBodyPart() = 0;
  155. // ACCESSORS
  156. //
  157. virtual UINT64 CbSize64() const = 0;
  158. // MANIPULATORS
  159. //
  160. virtual VOID Accept( IBodyPartVisitor& v,
  161. UINT64 ibPos64,
  162. IAcceptObserver& obsAccept ) = 0;
  163. virtual VOID Rewind() = 0;
  164. };
  165. // ========================================================================
  166. //
  167. // CLASS IBodyPartVisitor
  168. //
  169. // Defines an interface for an object used to access body part data.
  170. // A body part visitor handles three types of data: in-memory bytes (text),
  171. // files, and streams (via IAsyncStream). What the visitor does with that
  172. // data and how it does it is not specified; the behavior is provided by
  173. // the visitor itself. The IBodyPartVisitor interface just standardizes
  174. // things to provide for asynchronous iteration over the entire body
  175. // without the need for custom asynchronous iteration code everywhere.
  176. //
  177. // A body part visitor may implement any of its VisitXXX() methods
  178. // as asynchronous operations. Regardless, the visitor must call
  179. // VisitComplete() on the visitor observer passed to it whenever
  180. // the visit operation completes.
  181. //
  182. // When visiting body part data in one of the VisitXXX() methods,
  183. // a visitor does not have to visit (i.e. buffer) ALL of the data
  184. // before calling IAcceptObserver::AcceptComplete(). It can just
  185. // call AcceptComplete() with the number of bytes that can actually
  186. // be accepted.
  187. //
  188. class IAsyncStream;
  189. class IBodyPartVisitor
  190. {
  191. // NOT IMPLEMENTED
  192. //
  193. IBodyPartVisitor& operator=( const IBodyPartVisitor& );
  194. public:
  195. // CREATORS
  196. //
  197. virtual ~IBodyPartVisitor() = 0;
  198. // MANIPULATORS
  199. //
  200. virtual VOID VisitBytes( const BYTE * pbData,
  201. UINT cbToVisit,
  202. IAcceptObserver& obsAccept ) = 0;
  203. virtual VOID VisitFile( const auto_ref_handle& hf,
  204. UINT64 ibOffset64,
  205. UINT64 cbToVisit64,
  206. IAcceptObserver& obsAccept ) = 0;
  207. virtual VOID VisitStream( IAsyncStream& stm,
  208. UINT cbToVisit,
  209. IAcceptObserver& obsAccept ) = 0;
  210. virtual VOID VisitComplete() = 0;
  211. };
  212. // ========================================================================
  213. //
  214. // CLASS IBody
  215. //
  216. // Common request/response body interface
  217. //
  218. class IAsyncStream;
  219. class IBody
  220. {
  221. // NOT IMPLEMENTED
  222. //
  223. IBody& operator=( const IBody& );
  224. public:
  225. // ========================================================================
  226. //
  227. // CLASS iterator
  228. //
  229. class iterator
  230. {
  231. // NOT IMPLEMENTED
  232. //
  233. iterator& operator=( const iterator& );
  234. public:
  235. // CREATORS
  236. //
  237. virtual ~iterator() = 0;
  238. // MANIPULATORS
  239. //
  240. virtual VOID Accept( IBodyPartVisitor& v,
  241. IAcceptObserver& obs ) = 0;
  242. virtual VOID Prune() = 0;
  243. };
  244. // CREATORS
  245. //
  246. virtual ~IBody() = 0;
  247. // ACCESSORS
  248. //
  249. virtual BOOL FIsEmpty() const = 0;
  250. virtual UINT64 CbSize64() const = 0;
  251. // MANIPULATORS
  252. //
  253. virtual VOID Clear() = 0;
  254. virtual VOID AddText( LPCSTR lpszText, UINT cbText ) = 0;
  255. VOID AddText( LPCSTR lpszText ) { AddText(lpszText, static_cast<UINT>(strlen(lpszText))); }
  256. virtual VOID AddFile( const auto_ref_handle& hf,
  257. UINT64 ibFile64,
  258. UINT64 cbFile64 ) = 0;
  259. virtual VOID AddStream( IStream& stm ) = 0;
  260. virtual VOID AddStream( IStream& stm, UINT ibOffset, UINT cbSize ) = 0;
  261. virtual VOID AddBodyPart( IBodyPart * pBodyPart ) = 0;
  262. virtual VOID AsyncPersist( IAsyncStream& stm,
  263. IAsyncPersistObserver& obs ) = 0;
  264. virtual IStream * GetIStream( IAsyncIStreamObserver& obs ) = 0;
  265. virtual iterator * GetIter() = 0;
  266. };
  267. IBody * NewBody();
  268. // ========================================================================
  269. //
  270. // CLASS CFileBodyPart
  271. //
  272. // Represents a file body part. A file body part is a part whose content
  273. // can be accessed with the standard Win32 APIs ReadFile() and TransmitFile().
  274. //
  275. // Note: File body parts using this implementation must be no longer
  276. // than ULONG_MAX bytes!
  277. //
  278. class CFileBodyPart : public IBodyPart
  279. {
  280. // The file handle
  281. //
  282. auto_ref_handle m_hf;
  283. // Starting offset into the file
  284. //
  285. UINT64 m_ibFile64;
  286. // Size of the content
  287. //
  288. UINT64 m_cbFile64;
  289. // NOT IMPLEMENTED
  290. //
  291. CFileBodyPart( const CFileBodyPart& );
  292. CFileBodyPart& operator=( const CFileBodyPart& );
  293. public:
  294. // CREATORS
  295. //
  296. CFileBodyPart( const auto_ref_handle& hf,
  297. UINT64 ibFile64,
  298. UINT64 cbFile64 );
  299. // ACCESSORS
  300. //
  301. UINT64 CbSize64() const { return m_cbFile64; }
  302. // MANIPULATORS
  303. //
  304. VOID Rewind();
  305. VOID Accept( IBodyPartVisitor& v,
  306. UINT64 ibPos64,
  307. IAcceptObserver& obsAccept );
  308. };
  309. // ========================================================================
  310. //
  311. // CLASS CTextBodyPart
  312. //
  313. class CTextBodyPart : public IBodyPart
  314. {
  315. // String buffer to hold the text
  316. //
  317. StringBuffer<char> m_bufText;
  318. // NOT IMPLEMENTED
  319. //
  320. CTextBodyPart( const CTextBodyPart& );
  321. CTextBodyPart& operator=( const CTextBodyPart& );
  322. public:
  323. // AddTextBytes()
  324. //
  325. // NOTE: this method was added for XML emitting.
  326. // In that scenaro, an XML response is composed of
  327. // many -- potentially thousands -- of calls to add
  328. // response bytes. If we strictly went and used the
  329. // CMethUtil methods to ::AddResponseText(), we would
  330. // end up with many -- potentially thousands -- of body
  331. // parts. So, the upshot here is that performance of
  332. // such a mechanism would suck.
  333. //
  334. // By adding the method -- and moving the declaration of
  335. // this class to a publicly available header, we can now
  336. // create a text body part as a component of the emitting
  337. // process, and pour our data into body part directly.
  338. // Once the content is complete, we can then simply add
  339. // the body part.
  340. //
  341. VOID AddTextBytes ( UINT cbText, LPCSTR lpszText );
  342. // CREATORS
  343. //
  344. CTextBodyPart( UINT cbText, LPCSTR lpszText );
  345. // ACCESSORS
  346. //
  347. UINT64 CbSize64() const { return m_bufText.CbSize(); }
  348. // MANIPULATORS
  349. //
  350. VOID Rewind();
  351. VOID Accept( IBodyPartVisitor& v,
  352. UINT64 ibPos64,
  353. IAcceptObserver& obsAccept );
  354. };
  355. #endif // !defined(_BODY_H_)