@@ -467,6 +467,77 @@ 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+ , lastStatus(0 )
475+ , buf_len(0 )
476+ , buf_idx(-1 )
477+ {
478+ if (!file) {
479+ files.push_back (filename);
480+ throw simplecpp::Output (files, simplecpp::Output::FILE_NOT_FOUND, " File is missing: " + filename);
481+ }
482+ init ();
483+ }
484+
485+ ~FileStreamBuffered () {
486+ fclose (file);
487+ file = nullptr ;
488+ }
489+
490+ virtual int get () {
491+ read_internal ();
492+ return buf[buf_idx++];
493+ }
494+ virtual int peek () {
495+ read_internal ();
496+ return buf[buf_idx];
497+ }
498+ virtual void unget () {
499+ --buf_idx;
500+ }
501+ virtual bool good () {
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+ FileStreamBuffered (const FileStreamBuffered&);
532+ FileStreamBuffered &operator =(const FileStreamBuffered&);
533+
534+ FILE *file;
535+ int lastStatus;
536+ unsigned char buf[8192 ];
537+ int buf_len;
538+ int buf_idx;
539+ };
540+
470541simplecpp::TokenList::TokenList (std::vector<std::string> &filenames) : frontToken(nullptr ), backToken(nullptr ), files(filenames) {}
471542
472543simplecpp::TokenList::TokenList (std::istream &istr, std::vector<std::string> &filenames, const std::string &filename, OutputList *outputList)
@@ -487,7 +558,7 @@ simplecpp::TokenList::TokenList(const std::string &filename, std::vector<std::st
487558 : frontToken(nullptr ), backToken(nullptr ), files(filenames)
488559{
489560 try {
490- FileStream stream (filename, filenames);
561+ FileStreamBuffered stream (filename, filenames);
491562 readfile (stream,filename,outputList);
492563 } catch (const simplecpp::Output & e) { // TODO handle extra type of errors
493564 outputList->push_back (e);
0 commit comments