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.

242 lines
7.1 KiB

  1. // stream i/o functions
  2. #include "stdafx.h"
  3. #include <memory>
  4. /*+-------------------------------------------------------------------------*
  5. * ReadScalar
  6. *
  7. * Reads a scalar value from a stream.
  8. *--------------------------------------------------------------------------*/
  9. template<class T>
  10. static IStream& ReadScalar (IStream& stm, T& t)
  11. {
  12. ULONG cbActuallyRead;
  13. HRESULT hr = stm.Read (&t, sizeof (t), &cbActuallyRead);
  14. THROW_ON_FAILURE(hr);
  15. if (cbActuallyRead != sizeof (t))
  16. _com_issue_error (E_FAIL);
  17. return (stm);
  18. }
  19. /*+-------------------------------------------------------------------------*
  20. * WriteScalar
  21. *
  22. * Writes a scalar value to a stream.
  23. *--------------------------------------------------------------------------*/
  24. template<class T>
  25. static IStream& WriteScalar (IStream& stm, const T& t)
  26. {
  27. ULONG cbActuallyWritten;
  28. HRESULT hr = stm.Write (&t, sizeof (t), &cbActuallyWritten);
  29. THROW_ON_FAILURE(hr);
  30. if (cbActuallyWritten != sizeof (t))
  31. THROW_ERROR(E_FAIL);
  32. return (stm);
  33. }
  34. //----------------------------------------------------------------
  35. // Define by-value stream operators
  36. //----------------------------------------------------------------
  37. #define DefineScalarStreamOperators(scalar_type) \
  38. IStream& operator>> (IStream& stm, scalar_type& t) \
  39. { return (ReadScalar (stm, t)); } \
  40. IStream& operator<< (IStream& stm, scalar_type t) \
  41. { return (WriteScalar (stm, t)); }
  42. DefineScalarStreamOperators ( bool);
  43. DefineScalarStreamOperators ( char);
  44. DefineScalarStreamOperators (unsigned char);
  45. DefineScalarStreamOperators ( short);
  46. DefineScalarStreamOperators (unsigned short);
  47. DefineScalarStreamOperators ( int);
  48. DefineScalarStreamOperators (unsigned int);
  49. DefineScalarStreamOperators ( long);
  50. DefineScalarStreamOperators (unsigned long);
  51. //----------------------------------------------------------------
  52. // Define by-value stream operators
  53. //----------------------------------------------------------------
  54. #define DefineScalarStreamOperatorsByRef(scalar_type) \
  55. IStream& operator>> (IStream& stm, scalar_type& t) \
  56. { return (ReadScalar (stm, t)); } \
  57. IStream& operator<< (IStream& stm, const scalar_type& t) \
  58. { return (WriteScalar (stm, t)); }
  59. DefineScalarStreamOperatorsByRef(CLSID);
  60. DefineScalarStreamOperatorsByRef(FILETIME);
  61. /*+-------------------------------------------------------------------------*
  62. * ReadString
  63. *
  64. * Reads a std::basic_string of char type CH from a stream. The string should
  65. * have been written with a DWORD character count preceding an array of
  66. * characters that is not NULL-terminated.
  67. *--------------------------------------------------------------------------*/
  68. template<class CH>
  69. static IStream& ReadString (IStream& stm, std::basic_string<CH>& str)
  70. {
  71. /*
  72. * read the length
  73. */
  74. DWORD cch;
  75. stm >> cch;
  76. /* Loading more than 1 million characters just isn't going to be supported. */
  77. if( cch > 1000000 )
  78. THROW_ERROR(E_OUTOFMEMORY);
  79. /*
  80. * allocate a buffer for the characters
  81. */
  82. std::auto_ptr<CH> spBuffer (new (std::nothrow) CH[cch + 1]);
  83. CH* pBuffer = spBuffer.get();
  84. if (pBuffer == NULL)
  85. THROW_ERROR(E_OUTOFMEMORY);
  86. /*
  87. * read the characters
  88. */
  89. ULONG cbActuallyRead;
  90. const ULONG cbToRead = cch * sizeof (CH);
  91. HRESULT hr = stm.Read (pBuffer, cbToRead, &cbActuallyRead);
  92. THROW_ON_FAILURE(hr);
  93. if (cbToRead != cbActuallyRead)
  94. THROW_ERROR(E_FAIL);
  95. /*
  96. * terminate the character array and assign it to the string
  97. */
  98. pBuffer[cch] = 0;
  99. /*
  100. * assign it to the string (clear the string first to work around
  101. * the bug described in KB Q172398)
  102. */
  103. str.erase();
  104. str = pBuffer;
  105. return (stm);
  106. }
  107. /*+-------------------------------------------------------------------------*
  108. * ReadString for byte_string
  109. *
  110. * Specialization of ReadString for a string of bytes which may contain NULLs.
  111. * he string should have been written with a DWORD character count preceding
  112. * an array of characters that is not NULL-terminated.
  113. *--------------------------------------------------------------------------*/
  114. static IStream& ReadString (IStream& stm, std::basic_string<BYTE>& str)
  115. {
  116. /*
  117. * read the length
  118. */
  119. DWORD cch;
  120. stm >> cch;
  121. /* Loading more than 1 million characters just isn't going to be supported. */
  122. if( cch > 1000000 )
  123. THROW_ERROR(E_OUTOFMEMORY);
  124. if (cch == 0)
  125. {
  126. str.erase();
  127. }
  128. else
  129. {
  130. /*
  131. * allocate a buffer for the characters
  132. */
  133. std::auto_ptr<BYTE> spBuffer (new (std::nothrow) BYTE[cch]);
  134. BYTE* pBuffer = spBuffer.get();
  135. if (pBuffer == NULL)
  136. THROW_ERROR(E_OUTOFMEMORY);
  137. /*
  138. * read the characters
  139. */
  140. ULONG cbActuallyRead;
  141. const ULONG cbToRead = cch;
  142. HRESULT hr = stm.Read (pBuffer, cbToRead, &cbActuallyRead);
  143. THROW_ON_FAILURE(hr);
  144. if (cbToRead != cbActuallyRead)
  145. THROW_ERROR(E_FAIL);
  146. /*
  147. * assign it to the string (clear the string first to work around
  148. * the bug described in KB Q172398)
  149. */
  150. str.erase();
  151. str.assign(pBuffer, cch);
  152. }
  153. return (stm);
  154. }
  155. /*+-------------------------------------------------------------------------*
  156. * WriteString
  157. *
  158. * Writes a std::basic_string of char type CH to a stream. The string is
  159. * written with a DWORD character count preceding an array of characters that
  160. * is not NULL-terminated.
  161. *--------------------------------------------------------------------------*/
  162. template<class CH>
  163. static IStream& WriteString (IStream& stm, const std::basic_string<CH>& str)
  164. {
  165. /*
  166. * write the length
  167. */
  168. DWORD cch = str.length();
  169. stm << cch;
  170. if (cch > 0)
  171. {
  172. /*
  173. * write the characters
  174. */
  175. ULONG cbActuallyWritten;
  176. const ULONG cbToWrite = cch * sizeof (CH);
  177. HRESULT hr = stm.Write (str.data(), cbToWrite, &cbActuallyWritten);
  178. THROW_ON_FAILURE(hr);
  179. if (cbToWrite != cbActuallyWritten)
  180. THROW_ERROR(E_FAIL);
  181. }
  182. return (stm);
  183. }
  184. //-----------------------------------------------------------------
  185. // Define basic string stream operators
  186. //-----------------------------------------------------------------
  187. #define DefineStringStreamOperators(string_type) \
  188. IStream& operator>> (IStream& stm, string_type& str) \
  189. { return (ReadString (stm, str)); } \
  190. IStream& operator<< (IStream& stm, const string_type& str) \
  191. { return (WriteString (stm, str)); }
  192. DefineStringStreamOperators(tstring);
  193. DefineStringStreamOperators(byte_string);