@@ -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+
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