@@ -48,6 +48,12 @@ using mode_t = unsigned short;
48
48
# include < sys/types.h>
49
49
#endif
50
50
51
+ #ifdef __GNUC__
52
+ # define unlikely (x ) __builtin_expect(!!(x), 0 )
53
+ #else
54
+ # define unlikely (x ) (x)
55
+ #endif
56
+
51
57
static bool isHex (const std::string &s)
52
58
{
53
59
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 {
459
465
int lastStatus;
460
466
};
461
467
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
+
462
539
simplecpp::TokenList::TokenList (std::vector<std::string> &filenames) : frontToken(nullptr ), backToken(nullptr ), files(filenames) {}
463
540
464
541
simplecpp::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
479
556
: frontToken(nullptr ), backToken(nullptr ), files(filenames)
480
557
{
481
558
try {
482
- FileStream stream (filename, filenames);
559
+ FileStreamBuffered stream (filename, filenames);
483
560
readfile (stream,filename,outputList);
484
561
} catch (const simplecpp::Output & e) { // TODO handle extra type of errors
485
562
outputList->push_back (e);
0 commit comments