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.

305 lines
9.6 KiB

  1. /*--------------------------------------------------------------------------*
  2. *
  3. * Microsoft Windows
  4. * Copyright (C) Microsoft Corporation, 1992 - 1999
  5. *
  6. * File: stgio.h
  7. *
  8. * Contents: Interface file structured storage I/O utilities
  9. *
  10. * History: 25-Jun-98 jeffro Created
  11. *
  12. *--------------------------------------------------------------------------*/
  13. #include "stgio.h"
  14. #include "stddbg.h"
  15. #include "macros.h"
  16. #include <comdef.h>
  17. #include <tchar.h>
  18. /*+-------------------------------------------------------------------------*
  19. * ReadScalar
  20. *
  21. * Reads a scalar value from a stream.
  22. *--------------------------------------------------------------------------*/
  23. template<class T>
  24. static IStream& ReadScalar (IStream& stm, T& t)
  25. {
  26. ULONG cbActuallyRead;
  27. HRESULT hr = stm.Read (&t, sizeof (t), &cbActuallyRead);
  28. THROW_ON_FAIL (hr);
  29. if (cbActuallyRead != sizeof (t))
  30. _com_issue_error (E_FAIL);
  31. return (stm);
  32. }
  33. /*+-------------------------------------------------------------------------*
  34. * WriteScalar
  35. *
  36. * Writes a scalar value to a stream.
  37. *--------------------------------------------------------------------------*/
  38. template<class T>
  39. static IStream& WriteScalar (IStream& stm, const T& t)
  40. {
  41. ULONG cbActuallyWritten;
  42. HRESULT hr = stm.Write (&t, sizeof (t), &cbActuallyWritten);
  43. THROW_ON_FAIL (hr);
  44. if (cbActuallyWritten != sizeof (t))
  45. _com_issue_error (E_FAIL);
  46. return (stm);
  47. }
  48. /*+-------------------------------------------------------------------------*
  49. * ReadString
  50. *
  51. * Reads a std::basic_string from a stream. The string should have been
  52. * written with a DWORD character count preceding an array of characters
  53. * that is not NULL-terminated.
  54. *--------------------------------------------------------------------------*/
  55. template<class E, class Tr, class A>
  56. static IStream& ReadString (IStream& stm, std::basic_string<E,Tr,A>& str)
  57. {
  58. /*
  59. * read the length
  60. */
  61. DWORD cch;
  62. stm >> cch;
  63. /*
  64. * allocate a buffer for the characters
  65. */
  66. std::auto_ptr<E> spBuffer (new (std::nothrow) E[cch + 1]);
  67. E* pBuffer = spBuffer.get();
  68. if (pBuffer == NULL)
  69. _com_issue_error (E_OUTOFMEMORY);
  70. /*
  71. * read the characters
  72. */
  73. ULONG cbActuallyRead;
  74. const ULONG cbToRead = cch * sizeof (E);
  75. HRESULT hr = stm.Read (pBuffer, cbToRead, &cbActuallyRead);
  76. THROW_ON_FAIL (hr);
  77. if (cbToRead != cbActuallyRead)
  78. _com_issue_error (E_FAIL);
  79. /*
  80. * terminate the character array and assign it to the string
  81. */
  82. pBuffer[cch] = 0;
  83. /*
  84. * assign it to the string (clear the string first to work around
  85. * the bug described in KB Q172398)
  86. */
  87. str.erase();
  88. str = pBuffer;
  89. return (stm);
  90. }
  91. /*+-------------------------------------------------------------------------*
  92. * WriteString
  93. *
  94. * Writes a std::basic_string to a stream. The string is written with a
  95. * DWORD character count preceding an array of characters that is not
  96. * NULL-terminated.
  97. *--------------------------------------------------------------------------*/
  98. template<class E, class Tr, class A>
  99. static IStream& WriteString (IStream& stm, const std::basic_string<E,Tr,A>& str)
  100. {
  101. /*
  102. * write the length
  103. */
  104. DWORD cch = str.length();
  105. stm << cch;
  106. if (cch > 0)
  107. {
  108. /*
  109. * write the characters
  110. */
  111. ULONG cbActuallyWritten;
  112. const ULONG cbToWrite = cch * sizeof (E);
  113. HRESULT hr = stm.Write (str.data(), cbToWrite, &cbActuallyWritten);
  114. THROW_ON_FAIL (hr);
  115. if (cbToWrite != cbActuallyWritten)
  116. _com_issue_error (E_FAIL);
  117. }
  118. return (stm);
  119. }
  120. /*+-------------------------------------------------------------------------*
  121. * operator<<, operator>>
  122. *
  123. * Stream insertion and extraction operators for various types
  124. *--------------------------------------------------------------------------*/
  125. #define DefineScalarStreamOperators(scalar_type) \
  126. IStream& operator>> (IStream& stm, scalar_type& t) \
  127. { return (ReadScalar (stm, t)); } \
  128. IStream& operator<< (IStream& stm, scalar_type t) \
  129. { return (WriteScalar (stm, t)); }
  130. #define DefineScalarStreamOperatorsByRef(scalar_type) \
  131. IStream& operator>> (IStream& stm, scalar_type& t) \
  132. { return (ReadScalar (stm, t)); } \
  133. IStream& operator<< (IStream& stm, const scalar_type& t) \
  134. { return (WriteScalar (stm, t)); }
  135. DefineScalarStreamOperators (bool);
  136. DefineScalarStreamOperators ( char);
  137. DefineScalarStreamOperators (unsigned char);
  138. DefineScalarStreamOperators ( short);
  139. DefineScalarStreamOperators (unsigned short);
  140. DefineScalarStreamOperators ( int);
  141. DefineScalarStreamOperators (unsigned int);
  142. DefineScalarStreamOperators ( long);
  143. DefineScalarStreamOperators (unsigned long);
  144. DefineScalarStreamOperators ( __int64);
  145. DefineScalarStreamOperators (unsigned __int64);
  146. DefineScalarStreamOperators (float);
  147. DefineScalarStreamOperators (double);
  148. DefineScalarStreamOperators (long double);
  149. DefineScalarStreamOperatorsByRef (CLSID);
  150. IStream& operator>> (IStream& stm, std::string& str)
  151. { return (ReadString (stm, str)); }
  152. IStream& operator<< (IStream& stm, const std::string& str)
  153. { return (WriteString (stm, str)); }
  154. IStream& operator>> (IStream& stm, std::wstring& str)
  155. { return (ReadString (stm, str)); }
  156. IStream& operator<< (IStream& stm, const std::wstring& str)
  157. { return (WriteString (stm, str)); }
  158. /*+-------------------------------------------------------------------------*
  159. * ReadScalarVector
  160. *
  161. * Reads an entire vector collection of scalar types (written by
  162. * insert_collection) from an IStream.
  163. *--------------------------------------------------------------------------*/
  164. template<class T>
  165. static void ReadScalarVector (IStream* pstm, std::vector<T>& v)
  166. {
  167. /*
  168. * clear out the current container
  169. */
  170. v.clear();
  171. /*
  172. * read the number of items
  173. */
  174. DWORD cItems;
  175. *pstm >> cItems;
  176. if (cItems > 0)
  177. {
  178. /*
  179. * allocate a buffer for the elements
  180. */
  181. std::auto_ptr<T> spBuffer (new (std::nothrow) T[cItems]);
  182. T* pBuffer = spBuffer.get();
  183. if (pBuffer == NULL)
  184. _com_issue_error (E_OUTOFMEMORY);
  185. /*
  186. * read the elements
  187. */
  188. ULONG cbActuallyRead;
  189. const ULONG cbToRead = cItems * sizeof (T);
  190. HRESULT hr = pstm->Read (pBuffer, cbToRead, &cbActuallyRead);
  191. THROW_ON_FAIL (hr);
  192. if (cbToRead != cbActuallyRead)
  193. _com_issue_error (E_FAIL);
  194. /*
  195. * assign the elements to the vector
  196. */
  197. v.assign (pBuffer, pBuffer + cItems);
  198. }
  199. }
  200. /*+-------------------------------------------------------------------------*
  201. * WriteScalarVector
  202. *
  203. * Writes an entire vector of scalar types to an IStream. Note that this
  204. * code assumes that vectors store their elements sequentially.
  205. *--------------------------------------------------------------------------*/
  206. template<class T>
  207. static void WriteScalarVector (IStream* pstm, const std::vector<T>& v)
  208. {
  209. /*
  210. * write the size
  211. */
  212. DWORD cItems = v.size();
  213. *pstm << cItems;
  214. if (cItems > 0)
  215. {
  216. /*
  217. * write the elements
  218. */
  219. ULONG cbActuallyWritten;
  220. const ULONG cbToWrite = cItems * sizeof (T);
  221. HRESULT hr = pstm->Write (v.begin(), cbToWrite, &cbActuallyWritten);
  222. THROW_ON_FAIL (hr);
  223. if (cbToWrite != cbActuallyWritten)
  224. _com_issue_error (E_FAIL);
  225. }
  226. }
  227. /*+-------------------------------------------------------------------------*
  228. * extract_vector (specialization for std::vector<scalar>)
  229. * Efficiently extracts an entire vector collection of scalar types
  230. * (written by insert_collection) from an IStream.
  231. *
  232. * insert_collection (specializations for std::vector<scalar>)
  233. * Efficiently inserts an entire vector of scalar types into an IStream.
  234. *--------------------------------------------------------------------------*/
  235. #define DefineScalarVectorStreamFunctions(scalar_type) \
  236. void extract_vector (IStream* pstm, std::vector<scalar_type>& v) \
  237. { ReadScalarVector (pstm, v); } \
  238. void insert_collection (IStream* pstm, const std::vector<scalar_type>& v)\
  239. { WriteScalarVector (pstm, v); }
  240. DefineScalarVectorStreamFunctions (bool);
  241. DefineScalarVectorStreamFunctions ( char);
  242. DefineScalarVectorStreamFunctions (unsigned char);
  243. DefineScalarVectorStreamFunctions ( short);
  244. DefineScalarVectorStreamFunctions (unsigned short);
  245. DefineScalarVectorStreamFunctions ( int);
  246. DefineScalarVectorStreamFunctions (unsigned int);
  247. DefineScalarVectorStreamFunctions ( long);
  248. DefineScalarVectorStreamFunctions (unsigned long);
  249. DefineScalarVectorStreamFunctions ( __int64);
  250. DefineScalarVectorStreamFunctions (unsigned __int64);
  251. DefineScalarVectorStreamFunctions (float);
  252. DefineScalarVectorStreamFunctions (double);
  253. DefineScalarVectorStreamFunctions (long double);