298 lines
6.8 KiB
C++
298 lines
6.8 KiB
C++
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// ParseStm.cpp
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include <pch.hxx>
|
|
#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;
|
|
}
|
|
|
|
|