@@ -55,6 +55,12 @@ using mode_t = unsigned short;
55
55
# include < sys/types.h>
56
56
#endif
57
57
58
+ #ifdef __GNUC__
59
+ # define unlikely (x ) __builtin_expect(!!(x), 0 )
60
+ #else
61
+ # define unlikely (x ) (x)
62
+ #endif
63
+
58
64
static bool isHex (const std::string &s)
59
65
{
60
66
return s.size ()>2 && (s.compare (0 ,2 ," 0x" )==0 || s.compare (0 ,2 ," 0X" )==0 );
@@ -466,6 +472,77 @@ class FileStream : public simplecpp::TokenList::Stream {
466
472
int lastStatus;
467
473
};
468
474
475
+ class FileStreamBuffered : public simplecpp ::TokenList::Stream {
476
+ public:
477
+ FileStreamBuffered (const std::string &filename, std::vector<std::string> &files)
478
+ : file(fopen(filename.c_str(), " rb" ))
479
+ , lastStatus(0 )
480
+ , buf_len(0 )
481
+ , buf_idx(-1 )
482
+ {
483
+ if (!file) {
484
+ files.push_back (filename);
485
+ throw simplecpp::Output (files, simplecpp::Output::FILE_NOT_FOUND, " File is missing: " + filename);
486
+ }
487
+ init ();
488
+ }
489
+
490
+ ~FileStreamBuffered () {
491
+ fclose (file);
492
+ file = nullptr ;
493
+ }
494
+
495
+ virtual int get () {
496
+ read_internal ();
497
+ return buf[buf_idx++];
498
+ }
499
+ virtual int peek () {
500
+ read_internal ();
501
+ return buf[buf_idx];
502
+ }
503
+ virtual void unget () {
504
+ --buf_idx;
505
+ }
506
+ virtual bool good () {
507
+ return lastStatus != EOF;
508
+ }
509
+
510
+ private:
511
+ void read_internal () {
512
+ // check if we are in the last chunk
513
+ if (unlikely (buf_idx >= buf_len)) {
514
+ if (buf_len != sizeof (buf)) {
515
+ lastStatus = EOF;
516
+ return ;
517
+ }
518
+ }
519
+
520
+ if (unlikely (buf_idx == -1 || buf_idx == buf_len))
521
+ {
522
+ buf_idx = 0 ;
523
+ buf_len = fread (buf, 1 , sizeof (buf), file);
524
+ if (buf_len == 0 ) {
525
+ lastStatus = EOF;
526
+ }
527
+ else if (buf_len != sizeof (buf)) {
528
+ if (ferror (file)) {
529
+ // TODO: is this correct?
530
+ lastStatus = EOF;
531
+ }
532
+ }
533
+ }
534
+ }
535
+
536
+ FileStreamBuffered (const FileStreamBuffered&);
537
+ FileStreamBuffered &operator =(const FileStreamBuffered&);
538
+
539
+ FILE *file;
540
+ int lastStatus;
541
+ unsigned char buf[8192 ];
542
+ int buf_len;
543
+ int buf_idx;
544
+ };
545
+
469
546
simplecpp::TokenList::TokenList (std::vector<std::string> &filenames) : frontToken(nullptr ), backToken(nullptr ), files(filenames) {}
470
547
471
548
simplecpp::TokenList::TokenList (std::istream &istr, std::vector<std::string> &filenames, const std::string &filename, OutputList *outputList)
@@ -486,7 +563,7 @@ simplecpp::TokenList::TokenList(const std::string &filename, std::vector<std::st
486
563
: frontToken(nullptr ), backToken(nullptr ), files(filenames)
487
564
{
488
565
try {
489
- FileStream stream (filename, filenames);
566
+ FileStreamBuffered stream (filename, filenames);
490
567
readfile (stream,filename,outputList);
491
568
} catch (const simplecpp::Output & e) { // TODO handle extra type of errors
492
569
outputList->push_back (e);
0 commit comments