Skip to content

Commit 4b03baa

Browse files
committed
added FileStreamBuffered to reduce the amount of fgetc() calls
1 parent 316d4ee commit 4b03baa

1 file changed

Lines changed: 69 additions & 1 deletion

File tree

simplecpp.cpp

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,74 @@ namespace {
468468
};
469469
}
470470

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

473541
simplecpp::TokenList::TokenList(std::istream &istr, std::vector<std::string> &filenames, const std::string &filename, OutputList *outputList)
@@ -488,7 +556,7 @@ simplecpp::TokenList::TokenList(const std::string &filename, std::vector<std::st
488556
: frontToken(nullptr), backToken(nullptr), files(filenames)
489557
{
490558
try {
491-
FileStream stream(filename, filenames);
559+
FileStreamBuffered stream(filename, filenames);
492560
readfile(stream,filename,outputList);
493561
} catch (const simplecpp::Output & e) {
494562
outputList->emplace_back(e);

0 commit comments

Comments
 (0)