mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
116 lines
2.7 KiB
116 lines
2.7 KiB
#include "precomp.h"
|
|
#pragma hdrstop
|
|
EnableAssert
|
|
|
|
// REVERSE BUFFER Module
|
|
//
|
|
// Supports the reverse buffer (RB) type.
|
|
//
|
|
// Operations:
|
|
// void InitRb(RB *, POS);
|
|
// F FReadLineMfRb(MF *, RB *, char [], int);
|
|
// POS PosRb(RB *);
|
|
//
|
|
|
|
// Initialize RB for use with FReadLineMfRb.
|
|
|
|
void
|
|
InitRb(
|
|
RB *prb,
|
|
POS pos
|
|
)
|
|
{
|
|
// Fake that we have just successfully read a line, and the buffer
|
|
// is now empty.
|
|
|
|
prb->pos = pos;
|
|
prb->ich = 0;
|
|
prb->rgch[0] = '\n';
|
|
AssertF(FRbOk(*prb));
|
|
}
|
|
|
|
// Get previous line from file into buffer 'rgchLine'.
|
|
// Return fTrue if successful, fFalse if there are no more lines to read.
|
|
|
|
F
|
|
FReadLineMfRb(
|
|
MF *pmf,
|
|
RB *prb,
|
|
char szLine[],
|
|
int cchMax
|
|
)
|
|
{
|
|
int cPass;
|
|
int ich;
|
|
int cch;
|
|
|
|
AssertF(FRbOk(*prb));
|
|
|
|
if (prb->ich == -1)
|
|
return fFalse;
|
|
|
|
// Search backwards for the beginning of a line.
|
|
// We may need a second pass if the line buffer doesn't contain
|
|
// the entire line (and therefore we have to reload the buffer).
|
|
|
|
for (cPass = 1; cPass <= 2; cPass++) {
|
|
// search backwards for beginning of line
|
|
for (ich = prb->ich - 1; // skip the '\n'
|
|
ich >= 0 && prb->rgch[ich] != '\n';
|
|
ich--)
|
|
;
|
|
if (ich >= 0 || prb->pos == 0) // found!
|
|
break;
|
|
|
|
if (cPass == 2) {
|
|
// We still haven't found a line separator. The
|
|
// line does not fit in our buffer!
|
|
|
|
AssertF(fFalse);
|
|
}
|
|
|
|
// Refill the buffer, moving the first prb->ich+1 characters to the
|
|
// end of the buffer and reading the rest from the file.
|
|
|
|
cch = sizeof(prb->rgch) - (prb->ich + 1); // count to read
|
|
if ((long)cch > prb->pos) // near front of file?
|
|
cch = (int)prb->pos; // if so, read what's left
|
|
|
|
// move unprocessed chars to end of buffer
|
|
memmove(prb->rgch + cch, prb->rgch, prb->ich + 1);
|
|
|
|
SeekMf(pmf, prb->pos -= cch, 0);
|
|
ReadMf(pmf, (char far *)prb->rgch, cch);
|
|
prb->ich += cch;
|
|
}
|
|
|
|
AssertF(ich >= 0 && prb->rgch[ich] == '\n' ||
|
|
prb->pos == 0 && ich == -1);
|
|
|
|
// copy the buffer to the line, throw away \r\n, and null terminate
|
|
cch = prb->ich - (ich + 1);
|
|
if (cch > cchMax-1)
|
|
cch = cchMax-1;
|
|
if (cch > 0) {
|
|
memmove(szLine, prb->rgch + (ich + 1), cch);
|
|
if (szLine[cch-1] == '\r')
|
|
szLine[cch-1] = 0;
|
|
else
|
|
szLine[cch] = 0;
|
|
} else
|
|
szLine[0] = 0;
|
|
|
|
prb->ich = ich;
|
|
AssertF(FRbOk(*prb));
|
|
return fTrue;
|
|
}
|
|
|
|
|
|
// Return current offset within file.
|
|
POS
|
|
PosRb(
|
|
RB *prb
|
|
)
|
|
{
|
|
return prb->pos + prb->ich;
|
|
}
|