Skip to content

Commit a6a1239

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

File tree

1 file changed

+69
-1
lines changed

1 file changed

+69
-1
lines changed

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+
FileStreamBuffered(const FileStreamBuffered&) = delete;
488+
FileStreamBuffered &operator=(const FileStreamBuffered&) = delete;
489+
490+
int get() override {
491+
read_internal();
492+
return buf[buf_idx++];
493+
}
494+
int peek() override {
495+
read_internal();
496+
return buf[buf_idx];
497+
}
498+
void unget() override {
499+
--buf_idx;
500+
}
501+
bool good() override {
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+
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)