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