windows-nt/Source/XPSP1/NT/sdktools/asn1/asn1cpp/getsym.cpp
2020-09-26 16:20:57 +08:00

444 lines
9 KiB
C++

/* Copyright (C) Microsoft Corporation, 1998. All rights reserved. */
#include "precomp.h"
#include "getsym.h"
#include "utils.h"
CInput::
CInput
(
BOOL *pfRetCode,
LPSTR pszPathName,
UINT cbBufSize
)
:
m_cbBufSize(cbBufSize),
m_cbValidData(0),
m_nCurrOffset(0),
m_chCurr(INVALID_CHAR),
m_fEndOfFile(TRUE)
{
m_pszPathName = ::My_strdup(pszPathName);
m_pbDataBuf = new BYTE[m_cbBufSize];
m_hFile = ::CreateFile(pszPathName,
GENERIC_READ,
FILE_SHARE_READ,
NULL, // default security
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_READONLY,
NULL); // no template
m_cbFileSize = (NULL != m_hFile) ? ::GetFileSize(m_hFile, NULL) : 0;
*pfRetCode = (NULL != m_pszPathName) &&
(NULL != m_pbDataBuf) &&
(NULL != m_hFile);
if (*pfRetCode)
{
if (CheckBuffer(1))
{
m_chCurr = m_pbDataBuf[0];
m_fEndOfFile = FALSE;
}
}
}
CInput::
~CInput ( void )
{
delete m_pszPathName;
delete m_pbDataBuf;
if (NULL != m_hFile)
{
::CloseHandle(m_hFile);
}
}
void CInput::
NextChar ( void )
{
if (INVALID_CHAR != m_chCurr)
{
// set up the next new char
if (CheckBuffer(1))
{
m_chCurr = m_pbDataBuf[++m_nCurrOffset];
}
else
{
m_chCurr = INVALID_CHAR;
m_fEndOfFile = TRUE;
}
}
}
void CInput::
PeekChars ( UINT cChars, LPSTR pszChars )
{
if (CheckBuffer(cChars - 1))
{
::CopyMemory(pszChars, &m_pbDataBuf[m_nCurrOffset], cChars);
}
else
{
::ZeroMemory(pszChars, cChars);
}
}
void CInput::
SkipChars ( UINT cChars )
{
for (UINT i = 0; i < cChars; i++)
{
NextChar();
}
}
BOOL CInput::
CheckBuffer ( UINT cChars )
{
if (m_nCurrOffset + cChars >= m_cbValidData)
{
ASSERT(m_cbValidData >= m_nCurrOffset);
UINT cbCurrValid = m_cbValidData - m_nCurrOffset;
UINT cbToRead = m_cbBufSize - cbCurrValid;
if (cbCurrValid > 0)
{
// Move the data to the front of the buffer.
::CopyMemory(&m_pbDataBuf[0], &m_pbDataBuf[m_nCurrOffset], cbCurrValid);
m_nCurrOffset = 0;
}
ULONG cbRead = 0;
if (::ReadFile(m_hFile, &m_pbDataBuf[cbCurrValid], cbToRead, &cbRead, NULL))
{
ASSERT(cbRead <= cbToRead);
m_cbValidData = cbCurrValid + cbRead;
m_nCurrOffset = 0;
if (cbRead < cbToRead)
{
m_fEndOfFile = TRUE;
}
}
else
{
m_fEndOfFile = TRUE;
}
return (m_nCurrOffset + cChars < m_cbValidData);
}
return TRUE;
}
BOOL CInput::
Rewind ( void )
{
if ((DWORD) -1 != ::SetFilePointer(m_hFile, 0, NULL, FILE_BEGIN))
{
// clean up members
m_cbValidData = 0;
m_nCurrOffset = 0;
m_chCurr = INVALID_CHAR;
// set up the buffer
if (CheckBuffer(1))
{
m_chCurr = m_pbDataBuf[0];
m_fEndOfFile = FALSE;
}
else
{
m_fEndOfFile = TRUE;
}
return TRUE;
}
return FALSE;
}
CSymbol::
CSymbol ( CInput *pInput )
:
m_pInput(pInput),
m_eSymbolID(SYMBOL_UNKNOWN),
m_cchSymbolStr(0)
{
m_szSymbolStr[0] = '\0';
}
BOOL CSymbol::
NextSymbol ( void )
{
if (SYMBOL_EOF == m_eSymbolID)
{
return FALSE;
}
char ch = m_pInput->GetChar();
m_szSymbolStr[0] = ch;
m_cchSymbolStr = 1;
m_pInput->NextChar();
if (::isdigit(ch))
{
// numbers
while (INVALID_CHAR != (ch = m_pInput->GetChar()))
{
if (::isdigit(ch))
{
m_szSymbolStr[m_cchSymbolStr++] = ch;
m_pInput->NextChar();
}
else
{
break;
}
}
m_eSymbolID = SYMBOL_NUMBER;
}
else
if (::isalpha(ch))
{
// alphanumeric
while (INVALID_CHAR != (ch = m_pInput->GetChar()))
{
if (::isalnum(ch) || '_' == ch || '-' == ch)
{
m_szSymbolStr[m_cchSymbolStr++] = ch;
m_pInput->NextChar();
}
else
{
m_szSymbolStr[m_cchSymbolStr] = '\0';
break;
}
}
m_eSymbolID = ::IsKeyword(&m_szSymbolStr[0]) ? SYMBOL_KEYWORD : SYMBOL_IDENTIFIER;
}
else
if ('\n' == ch)
{
m_szSymbolStr[m_cchSymbolStr++] = '\n';
m_eSymbolID = SYMBOL_SPACE_EOL;
}
else
if (::isspace(ch))
{
// space
m_eSymbolID = SYMBOL_SPACE;
while (INVALID_CHAR != (ch = m_pInput->GetChar()))
{
if (::isspace(ch))
{
m_szSymbolStr[m_cchSymbolStr++] = ch;
m_pInput->NextChar();
if ('\n' == ch)
{
m_eSymbolID = SYMBOL_SPACE_EOL;
}
}
else
{
break;
}
}
}
else
if ('&' == ch)
{
m_eSymbolID = SYMBOL_FIELD;
// alphanumeric
while (INVALID_CHAR != (ch = m_pInput->GetChar()))
{
if (::isalnum(ch) || '_' == ch)
{
m_szSymbolStr[m_cchSymbolStr++] = ch;
m_pInput->NextChar();
}
else
{
m_szSymbolStr[m_cchSymbolStr] = '\0';
break;
}
}
}
else
{
char szTemp[4];
m_eSymbolID = SYMBOL_SPECIAL;
if (':' == ch)
{
m_pInput->PeekChars(2, &szTemp[0]);
if (':' == szTemp[0] && '=' == szTemp[1])
{
m_pInput->SkipChars(2);
m_szSymbolStr[m_cchSymbolStr++] = ':';
m_szSymbolStr[m_cchSymbolStr++] = '=';
m_eSymbolID = SYMBOL_DEFINITION;
}
}
else
if ('-' == ch)
{
m_pInput->PeekChars(1, &szTemp[0]);
if ('-' == szTemp[0])
{
m_pInput->SkipChars(1);
m_szSymbolStr[m_cchSymbolStr++] = '-';
m_eSymbolID = SYMBOL_COMMENT;
}
}
else
if ('.' == ch)
{
m_pInput->PeekChars(2, &szTemp[0]);
if ('.' == szTemp[0] && '.' == szTemp[1])
{
m_pInput->SkipChars(2);
m_szSymbolStr[m_cchSymbolStr++] = '.';
m_szSymbolStr[m_cchSymbolStr++] = '.';
m_eSymbolID = SYMBOL_DOTDOTDOT;
}
}
}
// null terminate the string
m_szSymbolStr[m_cchSymbolStr] = '\0';
if (INVALID_CHAR != m_szSymbolStr[0])
{
return TRUE;
}
m_eSymbolID = SYMBOL_EOF;
return FALSE;
}
BOOL CSymbol::
NextUsefulSymbol ( void )
{
BOOL fInsideComment = FALSE;
while (NextSymbol())
{
if (SYMBOL_SPACE_EOL == m_eSymbolID)
{
fInsideComment = FALSE;
}
else
if (SYMBOL_COMMENT == m_eSymbolID)
{
fInsideComment = ! fInsideComment;
}
else
if (! fInsideComment)
{
if (SYMBOL_SPACE != m_eSymbolID)
{
return TRUE;
}
}
}
return FALSE;
}
COutput::
COutput
(
BOOL *pfRetCode,
LPSTR pszPathName,
UINT cbBufSize
)
:
m_cbBufSize(cbBufSize),
m_cbValidData(0)
{
m_pszPathName = ::My_strdup(pszPathName);
m_pbDataBuf = new BYTE[m_cbBufSize];
m_hFile = ::CreateFile(pszPathName,
GENERIC_WRITE,
FILE_SHARE_READ,
NULL, // default security
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL); // no template
*pfRetCode = (NULL != m_pszPathName) &&
(NULL != m_pbDataBuf) &&
(NULL != m_hFile);
}
COutput::
~COutput ( void )
{
delete m_pszPathName;
delete m_pbDataBuf;
if (NULL != m_hFile)
{
Flush();
::CloseHandle(m_hFile);
}
}
BOOL COutput::
Write
(
LPBYTE pbDataBuf,
UINT cbToWrite
)
{
ULONG cbWritten;
while (0 != cbToWrite)
{
if (::WriteFile(m_hFile, pbDataBuf, cbToWrite, &cbWritten, NULL))
{
pbDataBuf += cbWritten;
cbToWrite -= cbWritten;
}
else
{
return FALSE;
}
}
return TRUE;
}
BOOL COutput::
Writeln
(
LPBYTE pbDataBuf,
UINT cbToWrite
)
{
return Write(pbDataBuf, cbToWrite) && Write("\n", 1);
}