WindowsXP-SP1/inetcore/outlookexpress/oejunk/parsestm.cpp
2020-09-30 16:53:49 +02:00

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;
}