#include #include // included for open and read #include #include #include #include #include "buffer.h" using namespace std; void loadBuffer(char * buffer, int fd, int size) { int loaded; loaded = read(fd, buffer, size); if (loaded != size) { // put a marker where we finished. buffer[loaded] = EOF; } // put an eof at the end anyway buffer[size] = EOF; return; } BufferT::BufferT(string filename, int size) { buffer1 = NULL; buffer2 = NULL; bufferSize = size; fd = open(filename.c_str(),'r'); if(0== fd) { cerr << "Failed to open " << filename; return; } buffer1 = new char[bufferSize+1]; buffer2 = new char[bufferSize+1]; loadBuffer(buffer1, fd, bufferSize); currentBuffer = buffer1; lexemeBegin = buffer1; forward = buffer1; doReload = true; return; } BufferT::~BufferT() { delete[] buffer1; delete[] buffer2; close(fd); return; } char * BufferT::OtherBuffer() { if (currentBuffer == buffer1) { return buffer2; } else { return buffer1; } } void BufferT::ReloadBuffer() { char * target= OtherBuffer(); loadBuffer(target, fd, bufferSize); forward = target; return; } bool BufferT::IsInCurrent(char * p) { if (p >= currentBuffer and p <= currentBuffer+bufferSize) { return true; } else { return false; } } string BufferT::GetLexeme() { string rv; char * next; // bad case, you didn't ask for anything. if (forward == lexemeBegin) { return ""; } // go through and build up the next lexeme. next=lexemeBegin; while (next != forward) { rv += *next; next++; // mostly good, EOF means switch buffers, but not at real EOF if (*next == EOF and next == currentBuffer+bufferSize ) { next = OtherBuffer(); } else if (*next == EOF) { next = forward; } } // ok, so now do we need to move to the next buffer? // This will happen if lexemeBegin is in one buffer and forwad // is in the other. if (IsInCurrent(lexemeBegin) and !IsInCurrent(forward) ) { currentBuffer = OtherBuffer(); doReload = true; } // now forward and lexeme begin point to the same thing. lexemeBegin = forward; return rv; } char BufferT::NextLetter() { // catch all for absolute end of file. if (*forward == EOF) { return *forward; } // forward is not at EOF so save the return character char rv = *forward; // advance forward forward++; //cout << "fetching " << rv << endl; // if we just pointed to the EOF marker. if(*forward== EOF) { // check to see if we are the end of buffer, if (forward == currentBuffer+bufferSize) { // reload, but only if this is the first time in the new buffer. if (doReload) { ReloadBuffer(); doReload = false; } else { // otherwise just switch back. forward = OtherBuffer(); } } } return rv; } void BufferT::ResetForward() { forward = lexemeBegin; return; } void BufferT::RetractForward() { // don't back up if we are at the end of file. // this is REALLY a special case, and we should only encounter it // if we are at the ABSOLUTE end of the file, otherwise, we should // have advanced to the next buffer. if (*forward == EOF) { return; } if (forward == OtherBuffer() ) { forward=currentBuffer+bufferSize-1; } else { forward--; } return; }