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.

297 lines
6.8 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // ParseStm.cpp
  4. //
  5. ///////////////////////////////////////////////////////////////////////////////
  6. #include <pch.hxx>
  7. #include "parsestm.h"
  8. // Constructor
  9. CParseStream::CParseStream()
  10. {
  11. m_pStm = NULL;
  12. m_rgchBuff[0] = '\0';
  13. m_cchBuff = 0;
  14. m_idxBuff = 0;
  15. }
  16. // Desctructor
  17. CParseStream::~CParseStream()
  18. {
  19. if (NULL != m_pStm)
  20. {
  21. m_pStm->Release();
  22. }
  23. }
  24. ///////////////////////////////////////////////////////////////////////////////
  25. //
  26. // HrSetFile
  27. //
  28. // This sets which stream we should be parsing.
  29. //
  30. // dwFlags - modifiers on how to load the stream
  31. // pszFilename - the file to parse
  32. //
  33. // Returns: S_OK, on success
  34. //
  35. ///////////////////////////////////////////////////////////////////////////////
  36. HRESULT CParseStream::HrSetFile(DWORD dwFlags, LPCTSTR pszFilename)
  37. {
  38. HRESULT hr = S_OK;
  39. IStream * pIStm = NULL;
  40. // Check incoming params
  41. if ((0 != dwFlags) || (NULL == pszFilename))
  42. {
  43. hr = E_INVALIDARG;
  44. goto exit;
  45. }
  46. // Create a stream on the file
  47. hr = CreateStreamOnHFile((LPTSTR) pszFilename, GENERIC_READ, FILE_SHARE_READ, NULL,
  48. OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL, &pIStm);
  49. if (FAILED(hr))
  50. {
  51. goto exit;
  52. }
  53. // Reset the read buffer
  54. m_cchBuff = 0;
  55. m_idxBuff = 0;
  56. // Free up any old stream
  57. if (NULL != m_pStm)
  58. {
  59. m_pStm->Release();
  60. }
  61. m_pStm = pIStm;
  62. pIStm = NULL;
  63. // Set the proper return value
  64. hr = S_OK;
  65. exit:
  66. SafeRelease(pIStm);
  67. return hr;
  68. }
  69. ///////////////////////////////////////////////////////////////////////////////
  70. //
  71. // HrSetStream
  72. //
  73. // This sets which stream we should be parsing.
  74. //
  75. // dwFlags - modifiers on how to load the stream
  76. // pStm - the stream to parse
  77. //
  78. // Returns: S_OK, on success
  79. //
  80. ///////////////////////////////////////////////////////////////////////////////
  81. HRESULT CParseStream::HrSetStream(DWORD dwFlags, IStream * pStm)
  82. {
  83. HRESULT hr = S_OK;
  84. // Check incoming params
  85. if ((0 != dwFlags) || (NULL == pStm))
  86. {
  87. hr = E_INVALIDARG;
  88. goto exit;
  89. }
  90. // Reset the read buffer
  91. m_cchBuff = 0;
  92. m_idxBuff = 0;
  93. // Free up any old stream
  94. if (NULL != m_pStm)
  95. {
  96. m_pStm->Release();
  97. }
  98. m_pStm = pStm;
  99. m_pStm->AddRef();
  100. // Set the proper return value
  101. hr = S_OK;
  102. exit:
  103. return hr;
  104. }
  105. ///////////////////////////////////////////////////////////////////////////////
  106. //
  107. // HrReset
  108. //
  109. // This resets the stream to parse from the beginning.
  110. //
  111. // Returns: S_OK, on success
  112. //
  113. ///////////////////////////////////////////////////////////////////////////////
  114. HRESULT CParseStream::HrReset(VOID)
  115. {
  116. HRESULT hr = S_OK;
  117. LARGE_INTEGER liZero = {0};
  118. // Reset the read buffer
  119. m_cchBuff = 0;
  120. m_idxBuff = 0;
  121. // Free up any old stream
  122. if (NULL != m_pStm)
  123. {
  124. m_pStm->Seek(liZero, STREAM_SEEK_SET, NULL);
  125. }
  126. // Set the proper return value
  127. hr = S_OK;
  128. return hr;
  129. }
  130. ///////////////////////////////////////////////////////////////////////////////
  131. //
  132. // HrGetLine
  133. //
  134. // This gets a line from the stream.
  135. //
  136. // dwFlags - modifiers on how to get the line from the stream
  137. // ppszLine - an allocated buffer holding the line parsed from the stream
  138. // pcchLine - the number of characters in the line buffer
  139. //
  140. // Returns: S_OK, on success
  141. //
  142. ///////////////////////////////////////////////////////////////////////////////
  143. HRESULT CParseStream::HrGetLine(DWORD dwFlags, LPTSTR * ppszLine, ULONG * pcchLine)
  144. {
  145. HRESULT hr = S_OK;
  146. BOOL fFoundCRLF = FALSE;
  147. ULONG cchAlloc = 0;
  148. ULONG cchLine = 0;
  149. LPTSTR pszLine = NULL;
  150. ULONG idxStart = 0;
  151. TCHAR chPrev = '\0';
  152. // Check incoming params
  153. if ((0 != dwFlags) || (NULL == ppszLine) || (NULL == pcchLine))
  154. {
  155. hr = E_INVALIDARG;
  156. goto exit;
  157. }
  158. // Initialize the outgoing params
  159. *ppszLine = NULL;
  160. *pcchLine = 0;
  161. // while we have found the end of the line
  162. while (FALSE == fFoundCRLF)
  163. {
  164. // Fill the buffer
  165. if (m_idxBuff == m_cchBuff)
  166. {
  167. hr = _HrFillBuffer(0);
  168. if (S_OK != hr)
  169. {
  170. break;
  171. }
  172. }
  173. // While we have room in the buffer
  174. for (idxStart = m_idxBuff; m_idxBuff < m_cchBuff; m_idxBuff++)
  175. {
  176. // Search for the end of line marker
  177. if ((chCR == chPrev) && (chLF == m_rgchBuff[m_idxBuff]))
  178. {
  179. m_idxBuff++;
  180. fFoundCRLF = TRUE;
  181. break;
  182. }
  183. chPrev = m_rgchBuff[m_idxBuff];
  184. }
  185. // Make enough space to hold the new characters
  186. cchAlloc += m_idxBuff - idxStart;
  187. if (NULL == pszLine)
  188. {
  189. hr = HrAlloc((void **) &pszLine, (cchAlloc + 1) * sizeof(*pszLine));
  190. if (FAILED(hr))
  191. {
  192. goto exit;
  193. }
  194. }
  195. else
  196. {
  197. hr = HrRealloc((void **) &pszLine, (cchAlloc + 1) * sizeof(*pszLine));
  198. if (FAILED(hr))
  199. {
  200. goto exit;
  201. }
  202. }
  203. // Copy the data into the buffer
  204. CopyMemory(pszLine + cchLine, m_rgchBuff + idxStart, m_idxBuff - idxStart);
  205. cchLine += m_idxBuff - idxStart;
  206. }
  207. // Remove the CRLF
  208. cchLine -= 2;
  209. // Terminate the line
  210. pszLine[cchLine] = '\0';
  211. // Set the return values
  212. *ppszLine = pszLine;
  213. pszLine = NULL;
  214. *pcchLine = cchLine;
  215. // Set the proper return value
  216. hr = S_OK;
  217. exit:
  218. SafeMemFree(pszLine);
  219. return hr;
  220. }
  221. ///////////////////////////////////////////////////////////////////////////////
  222. //
  223. // _HrFillBuffer
  224. //
  225. // This fills the buffer from the stream if necessary.
  226. //
  227. // dwFlags - modifiers on how to fill the buffer from the stream
  228. //
  229. // Returns: S_OK, on success
  230. //
  231. ///////////////////////////////////////////////////////////////////////////////
  232. HRESULT CParseStream::_HrFillBuffer(DWORD dwFlags)
  233. {
  234. HRESULT hr = S_OK;
  235. ULONG cchRead = 0;
  236. // Check incoming params
  237. if (0 != dwFlags)
  238. {
  239. hr = E_INVALIDARG;
  240. goto exit;
  241. }
  242. hr = m_pStm->Read((void *) m_rgchBuff, CCH_BUFF_MAX, &cchRead);
  243. if (FAILED(hr))
  244. {
  245. goto exit;
  246. }
  247. m_cchBuff = cchRead;
  248. m_idxBuff = 0;
  249. // Set the proper return value
  250. hr = S_OK;
  251. exit:
  252. return hr;
  253. }