/////////////////////////////////////////////////////////////////////////////// // // ParseStm.cpp // /////////////////////////////////////////////////////////////////////////////// #include #include "parsestm.h" // Constructor CParseStream::CParseStream() { m_pStm = NULL; m_rgchBuff[0] = '\0'; m_cchBuff = 0; m_idxBuff = 0; } // Desctructor CParseStream::~CParseStream() { if (NULL != m_pStm) { m_pStm->Release(); } } /////////////////////////////////////////////////////////////////////////////// // // HrSetFile // // This sets which stream we should be parsing. // // dwFlags - modifiers on how to load the stream // pszFilename - the file to parse // // Returns: S_OK, on success // /////////////////////////////////////////////////////////////////////////////// HRESULT CParseStream::HrSetFile(DWORD dwFlags, LPCTSTR pszFilename) { HRESULT hr = S_OK; IStream * pIStm = NULL; // Check incoming params if ((0 != dwFlags) || (NULL == pszFilename)) { hr = E_INVALIDARG; goto exit; } // Create a stream on the file hr = CreateStreamOnHFile((LPTSTR) pszFilename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL, &pIStm); if (FAILED(hr)) { goto exit; } // Reset the read buffer m_cchBuff = 0; m_idxBuff = 0; // Free up any old stream if (NULL != m_pStm) { m_pStm->Release(); } m_pStm = pIStm; pIStm = NULL; // Set the proper return value hr = S_OK; exit: SafeRelease(pIStm); return hr; } /////////////////////////////////////////////////////////////////////////////// // // HrSetStream // // This sets which stream we should be parsing. // // dwFlags - modifiers on how to load the stream // pStm - the stream to parse // // Returns: S_OK, on success // /////////////////////////////////////////////////////////////////////////////// HRESULT CParseStream::HrSetStream(DWORD dwFlags, IStream * pStm) { HRESULT hr = S_OK; // Check incoming params if ((0 != dwFlags) || (NULL == pStm)) { hr = E_INVALIDARG; goto exit; } // Reset the read buffer m_cchBuff = 0; m_idxBuff = 0; // Free up any old stream if (NULL != m_pStm) { m_pStm->Release(); } m_pStm = pStm; m_pStm->AddRef(); // Set the proper return value hr = S_OK; exit: return hr; } /////////////////////////////////////////////////////////////////////////////// // // HrReset // // This resets the stream to parse from the beginning. // // Returns: S_OK, on success // /////////////////////////////////////////////////////////////////////////////// HRESULT CParseStream::HrReset(VOID) { HRESULT hr = S_OK; LARGE_INTEGER liZero = {0}; // Reset the read buffer m_cchBuff = 0; m_idxBuff = 0; // Free up any old stream if (NULL != m_pStm) { m_pStm->Seek(liZero, STREAM_SEEK_SET, NULL); } // Set the proper return value hr = S_OK; return hr; } /////////////////////////////////////////////////////////////////////////////// // // HrGetLine // // This gets a line from the stream. // // dwFlags - modifiers on how to get the line from the stream // ppszLine - an allocated buffer holding the line parsed from the stream // pcchLine - the number of characters in the line buffer // // Returns: S_OK, on success // /////////////////////////////////////////////////////////////////////////////// HRESULT CParseStream::HrGetLine(DWORD dwFlags, LPTSTR * ppszLine, ULONG * pcchLine) { HRESULT hr = S_OK; BOOL fFoundCRLF = FALSE; ULONG cchAlloc = 0; ULONG cchLine = 0; LPTSTR pszLine = NULL; ULONG idxStart = 0; TCHAR chPrev = '\0'; // Check incoming params if ((0 != dwFlags) || (NULL == ppszLine) || (NULL == pcchLine)) { hr = E_INVALIDARG; goto exit; } // Initialize the outgoing params *ppszLine = NULL; *pcchLine = 0; // while we have found the end of the line while (FALSE == fFoundCRLF) { // Fill the buffer if (m_idxBuff == m_cchBuff) { hr = _HrFillBuffer(0); if (S_OK != hr) { break; } } // While we have room in the buffer for (idxStart = m_idxBuff; m_idxBuff < m_cchBuff; m_idxBuff++) { // Search for the end of line marker if ((chCR == chPrev) && (chLF == m_rgchBuff[m_idxBuff])) { m_idxBuff++; fFoundCRLF = TRUE; break; } chPrev = m_rgchBuff[m_idxBuff]; } // Make enough space to hold the new characters cchAlloc += m_idxBuff - idxStart; if (NULL == pszLine) { hr = HrAlloc((void **) &pszLine, (cchAlloc + 1) * sizeof(*pszLine)); if (FAILED(hr)) { goto exit; } } else { hr = HrRealloc((void **) &pszLine, (cchAlloc + 1) * sizeof(*pszLine)); if (FAILED(hr)) { goto exit; } } // Copy the data into the buffer CopyMemory(pszLine + cchLine, m_rgchBuff + idxStart, m_idxBuff - idxStart); cchLine += m_idxBuff - idxStart; } // Remove the CRLF cchLine -= 2; // Terminate the line pszLine[cchLine] = '\0'; // Set the return values *ppszLine = pszLine; pszLine = NULL; *pcchLine = cchLine; // Set the proper return value hr = S_OK; exit: SafeMemFree(pszLine); return hr; } /////////////////////////////////////////////////////////////////////////////// // // _HrFillBuffer // // This fills the buffer from the stream if necessary. // // dwFlags - modifiers on how to fill the buffer from the stream // // Returns: S_OK, on success // /////////////////////////////////////////////////////////////////////////////// HRESULT CParseStream::_HrFillBuffer(DWORD dwFlags) { HRESULT hr = S_OK; ULONG cchRead = 0; // Check incoming params if (0 != dwFlags) { hr = E_INVALIDARG; goto exit; } hr = m_pStm->Read((void *) m_rgchBuff, CCH_BUFF_MAX, &cchRead); if (FAILED(hr)) { goto exit; } m_cchBuff = cchRead; m_idxBuff = 0; // Set the proper return value hr = S_OK; exit: return hr; }