NT4/private/windows/win4help/common/cinput.cpp
2020-09-30 17:12:29 +02:00

209 lines
4.0 KiB
C++

#include "stdafx.h"
#pragma hdrstop
#ifndef _INPUT_INCLUDED
#include "cinput.h"
#endif
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
static const int INPUT_BUF_SIZE = (32 * 1024);
static const int DEFAULT_MAX_LINE = 256;
static void STDCALL ReAlloc(CStr* pcsz, PSTR* ppszCur, PSTR* ppszEnd);
CInput::CInput(PCSTR pszFileName)
{
if ((hfile = _lopen(pszFileName,
OF_READ | OF_SHARE_DENY_WRITE)) == HFILE_ERROR) {
fInitialized = FALSE;
return;
}
pbuf = (PBYTE) LocalAlloc(LMEM_FIXED, INPUT_BUF_SIZE);
fInitialized = pbuf ? TRUE : FALSE;
ASSERT(pbuf);
if (!pbuf) {
OOM();
return;
}
// Position current buffer at end to force a read
pCurBuf = pEndBuf = pbuf + INPUT_BUF_SIZE;
cbMax = DEFAULT_MAX_LINE;
}
CInput::~CInput(void)
{
_lclose(hfile);
LocalFree((HLOCAL) pbuf);
}
BOOL STDCALL CInput::getline(PSTR pszDst)
{
PSTR pszOrgBuf = pszDst;
int i = 0;
for (;;) {
if (pCurBuf >= pEndBuf) {
if (!ReadNextBuffer()) {
// End of file: return TRUE if we got any text.
if (pszDst > pszOrgBuf) {
*pszDst = '\0';
return TRUE;
}
else
return FALSE;
}
}
switch (*pszDst = *pCurBuf++) {
case '\n':
// Remove trailing spaces.
while (pszDst > pszOrgBuf && pszDst[-1] == ' ')
pszDst--;
*pszDst = '\0';
return TRUE;
case '\r':
break; // ignore it
default:
pszDst++;
if (++i >= cbMax) {
*pszDst = '\0';
return TRUE;
}
break;
}
}
}
/***************************************************************************
FUNCTION: CInput::getline
PURPOSE: Reads a line into a CStr buffer, increasing that buffer
as necessary to hold the line.
PARAMETERS:
pcsz CStr pointer
RETURNS:
COMMENTS:
This function relies HEAVILY on the implementation of the CStr
class, namely in CStr's use of lcmem functions.
MODIFICATION DATES:
05-Sep-1994 [ralphw]
***************************************************************************/
BOOL STDCALL CInput::getline(CStr* pcsz)
{
PSTR pszDst = pcsz->psz;
PSTR pszEnd = pszDst + lcSize(pszDst);
for (;;) {
if (pCurBuf >= pEndBuf) {
if (!ReadNextBuffer())
return FALSE;
}
switch (*pszDst = *pCurBuf++) {
case '\n':
if (pszDst > pcsz->psz) {
while (pszDst[-1] == ' ') { // remove trailing spaces
pszDst--;
if (pszDst == pcsz->psz)
break;
}
}
*pszDst = '\0';
return TRUE;
case '\r':
break; // ignore it
case 0: // This shouldn't happen in a text file
// Not a definitive test, buts catches a lot of them
if ((pbuf[0] == 0xdb || pbuf[0] == 0xd0) &&
(pbuf[1] == 0xa5 || pbuf[1] == 0xcf)) {
return FALSE;
}
break;
default:
pszDst++;
if (pszDst == pszEnd)
ReAlloc(pcsz, &pszDst, &pszEnd);
break;
}
}
}
/***************************************************************************
FUNCTION: ReAlloc
PURPOSE: Increase the size of the destination buffer
PARAMETERS:
ppszOrg
ppszCur
ppszEnd
RETURNS:
COMMENTS:
This is called by getline(CStr pcsz) and therefore relies heavily
on the way the CStr is implemented (namely, in the use of the
lcmem functions for memory management).
MODIFICATION DATES:
05-Sep-1994 [ralphw]
***************************************************************************/
static void STDCALL ReAlloc(CStr* pcsz, PSTR* ppszCur, PSTR* ppszEnd)
{
int offset = (*ppszCur - pcsz->psz);
pcsz->ReSize((*ppszEnd - pcsz->psz) + 128);
*ppszCur = pcsz->psz + offset;
*ppszEnd = pcsz->psz + pcsz->SizeAlloc();
}
BOOL CInput::ReadNextBuffer(void)
{
UINT cbRead;
if ((cbRead = _lread(hfile, pbuf, INPUT_BUF_SIZE)) <= 0)
return FALSE;
pCurBuf = pbuf;
pEndBuf = pbuf + cbRead;
return TRUE;
}
BOOL STDCALL CInput::IsWinWordFile(void)
{
if (pCurBuf >= pEndBuf) {
if (!ReadNextBuffer())
return FALSE;
}
// Not a definitive test, buts catches a lot of them
if ((pbuf[0] == 0xdb || pbuf[0] == 0xd0) &&
(pbuf[1] == 0xa5 || pbuf[1] == 0xcf))
return TRUE;
else
return FALSE;
}