Skip to content

Commit 71b7dfc

Browse files
committed
added FileStreamBuffered to reduce the amount of fgetc() calls
1 parent d381ec2 commit 71b7dfc

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

472540
simplecpp::TokenList::TokenList(std::istream &istr, std::vector<std::string> &filenames, const std::string &filename, OutputList *outputList)
@@ -487,7 +555,7 @@ simplecpp::TokenList::TokenList(const std::string &filename, std::vector<std::st
487555
: frontToken(nullptr), backToken(nullptr), files(filenames)
488556
{
489557
try {
490-
FileStream stream(filename, filenames);
558+
FileStreamBuffered stream(filename, filenames);
491559
readfile(stream,filename,outputList);
492560
} catch (const simplecpp::Output & e) { // TODO handle extra type of errors
493561
outputList->push_back(e);

0 commit comments

Comments
 (0)