@@ -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+
471539simplecpp::TokenList::TokenList (std::vector<std::string> &filenames) : frontToken(nullptr ), backToken(nullptr ), files(filenames) {}
472540
473541simplecpp::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