Skip to content

Commit b9c89fe

Browse files
committed
added FileStreamBuffered to reduce the amount of fgetc() calls
1 parent a74ed72 commit b9c89fe

File tree

1 file changed

+72
-1
lines changed

1 file changed

+72
-1
lines changed

simplecpp.cpp

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,77 @@ class FileStream : public simplecpp::TokenList::Stream {
467467
int lastStatus{};
468468
};
469469

470+
class FileStreamBuffered : public simplecpp::TokenList::Stream {
471+
public:
472+
FileStreamBuffered(const std::string &filename, std::vector<std::string> &files)
473+
: file(fopen(filename.c_str(), "rb"))
474+
, lastStatus(0)
475+
, buf_len(0)
476+
, buf_idx(-1)
477+
{
478+
if (!file) {
479+
files.push_back(filename);
480+
throw simplecpp::Output(files, simplecpp::Output::FILE_NOT_FOUND, "File is missing: " + filename);
481+
}
482+
init();
483+
}
484+
485+
~FileStreamBuffered() {
486+
fclose(file);
487+
file = nullptr;
488+
}
489+
490+
virtual int get() {
491+
read_internal();
492+
return buf[buf_idx++];
493+
}
494+
virtual int peek() {
495+
read_internal();
496+
return buf[buf_idx];
497+
}
498+
virtual void unget() {
499+
--buf_idx;
500+
}
501+
virtual bool good() {
502+
return lastStatus != EOF;
503+
}
504+
505+
private:
506+
void read_internal() {
507+
// check if we are in the last chunk
508+
if (buf_idx >= buf_len) {
509+
if (buf_len != sizeof(buf)) {
510+
lastStatus = EOF;
511+
return;
512+
}
513+
}
514+
515+
if (buf_idx == -1 || buf_idx == buf_len)
516+
{
517+
buf_idx = 0;
518+
buf_len = fread(buf, 1, sizeof(buf), file);
519+
if (buf_len == 0) {
520+
lastStatus = EOF;
521+
}
522+
else if (buf_len != sizeof(buf)) {
523+
if (ferror(file)) {
524+
// TODO: is this correct?
525+
lastStatus = EOF;
526+
}
527+
}
528+
}
529+
}
530+
531+
FileStreamBuffered(const FileStreamBuffered&);
532+
FileStreamBuffered &operator=(const FileStreamBuffered&);
533+
534+
FILE *file;
535+
int lastStatus;
536+
unsigned char buf[8192];
537+
int buf_len;
538+
int buf_idx;
539+
};
540+
470541
simplecpp::TokenList::TokenList(std::vector<std::string> &filenames) : frontToken(nullptr), backToken(nullptr), files(filenames) {}
471542

472543
simplecpp::TokenList::TokenList(std::istream &istr, std::vector<std::string> &filenames, const std::string &filename, OutputList *outputList)
@@ -487,7 +558,7 @@ simplecpp::TokenList::TokenList(const std::string &filename, std::vector<std::st
487558
: frontToken(nullptr), backToken(nullptr), files(filenames)
488559
{
489560
try {
490-
FileStream stream(filename, filenames);
561+
FileStreamBuffered stream(filename, filenames);
491562
readfile(stream,filename,outputList);
492563
} catch (const simplecpp::Output & e) { // TODO handle extra type of errors
493564
outputList->push_back(e);

0 commit comments

Comments
 (0)