@@ -48,6 +48,12 @@ using mode_t = unsigned short;
4848# include < sys/types.h>
4949#endif
5050
51+ #ifdef __GNUC__
52+ # define unlikely (x ) __builtin_expect(!!(x), 0 )
53+ #else
54+ # define unlikely (x ) (x)
55+ #endif
56+
5157static bool isHex (const std::string &s)
5258{
5359 return s.size ()>2 && (s.compare (0 ,2 ," 0x" )==0 || s.compare (0 ,2 ," 0X" )==0 );
@@ -459,6 +465,77 @@ class FileStream : public simplecpp::TokenList::Stream {
459465 int lastStatus;
460466};
461467
468+ class FileStreamBuffered : public simplecpp ::TokenList::Stream {
469+ public:
470+ FileStreamBuffered (const std::string &filename, std::vector<std::string> &files)
471+ : file(fopen(filename.c_str(), " rb" ))
472+ , lastStatus(0 )
473+ , buf_len(0 )
474+ , buf_idx(-1 )
475+ {
476+ if (!file) {
477+ files.push_back (filename);
478+ throw simplecpp::Output (files, simplecpp::Output::FILE_NOT_FOUND, " File is missing: " + filename);
479+ }
480+ init ();
481+ }
482+
483+ ~FileStreamBuffered () {
484+ fclose (file);
485+ file = nullptr ;
486+ }
487+
488+ virtual int get () {
489+ read_internal ();
490+ return buf[buf_idx++];
491+ }
492+ virtual int peek () {
493+ read_internal ();
494+ return buf[buf_idx];
495+ }
496+ virtual void unget () {
497+ --buf_idx;
498+ }
499+ virtual bool good () {
500+ return lastStatus != EOF;
501+ }
502+
503+ private:
504+ void read_internal () {
505+ // check if we are in the last chunk
506+ if (unlikely (buf_idx >= buf_len)) {
507+ if (buf_len != sizeof (buf)) {
508+ lastStatus = EOF;
509+ return ;
510+ }
511+ }
512+
513+ if (unlikely (buf_idx == -1 || buf_idx == buf_len))
514+ {
515+ buf_idx = 0 ;
516+ buf_len = fread (buf, 1 , sizeof (buf), file);
517+ if (buf_len == 0 ) {
518+ lastStatus = EOF;
519+ }
520+ else if (buf_len != sizeof (buf)) {
521+ if (ferror (file)) {
522+ // TODO: is this correct?
523+ lastStatus = EOF;
524+ }
525+ }
526+ }
527+ }
528+
529+ FileStreamBuffered (const FileStreamBuffered&);
530+ FileStreamBuffered &operator =(const FileStreamBuffered&);
531+
532+ FILE *file;
533+ int lastStatus;
534+ unsigned char buf[8192 ];
535+ int buf_len;
536+ int buf_idx;
537+ };
538+
462539simplecpp::TokenList::TokenList (std::vector<std::string> &filenames) : frontToken(nullptr ), backToken(nullptr ), files(filenames) {}
463540
464541simplecpp::TokenList::TokenList (std::istream &istr, std::vector<std::string> &filenames, const std::string &filename, OutputList *outputList)
@@ -479,7 +556,7 @@ simplecpp::TokenList::TokenList(const std::string &filename, std::vector<std::st
479556 : frontToken(nullptr ), backToken(nullptr ), files(filenames)
480557{
481558 try {
482- FileStream stream (filename, filenames);
559+ FileStreamBuffered stream (filename, filenames);
483560 readfile (stream,filename,outputList);
484561 } catch (const simplecpp::Output & e) { // TODO handle extra type of errors
485562 outputList->push_back (e);
0 commit comments