File: BufferedFileReader.h

package info (click to toggle)
arb 6.0.6-8
  • links: PTS, VCS
  • area: non-free
  • in suites: sid, trixie
  • size: 66,204 kB
  • sloc: ansic: 394,911; cpp: 250,290; makefile: 19,644; sh: 15,879; perl: 10,473; fortran: 6,019; ruby: 683; xml: 503; python: 53; awk: 32
file content (136 lines) | stat: -rw-r--r-- 3,464 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
// --------------------------------------------------------------------------------
// Copyright (C) 2000
// Ralf Westram
//
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation.  Ralf Westram makes no
// representations about the suitability of this software for any
// purpose.  It is provided "as is" without express or implied warranty.
// --------------------------------------------------------------------------------

#ifndef BUFFEREDFILEREADER_H
#define BUFFEREDFILEREADER_H

#ifndef _GLIBCXX_CSTDIO
#include <cstdio>
#endif
#ifndef _GLIBCXX_STRING
#include <string>
#endif
#ifndef ARBTOOLS_H
#include <arbtools.h>
#endif
#ifndef ARB_ASSERT_H
#include <arb_assert.h>
#endif

#define fb_assert(cond) arb_assert(cond)

using std::string;

class LineReader : virtual Noncopyable {
    /*! may represent any source that can be read line by line
     */

    size_t  lineNumber; // current line number
    string *next_line;
    bool   showFilename; // @@@ rename (not necessarily a file)

    virtual bool getLine_intern(string& line) = 0;

protected:
    void reset() {
        if (next_line) {
            delete next_line;
            next_line = NULL;
        }
        lineNumber = 0;
    }

public:
    LineReader()
        : lineNumber(0),
          next_line(NULL),
          showFilename(true)
    {}
    virtual ~LineReader() {
        delete next_line;
    }

    string lineError(const string& msg) const;
    string lineError(const char *msg) const { return lineError(string(msg)); }

    void showFilenameInLineError(bool show) { showFilename = show; } // @@@ rename (not necessarily a file)

    virtual bool getLine(string& line) {
        lineNumber++;
        if (next_line) {
            line = *next_line;
            delete next_line;
            next_line = NULL;
            return true;
        }
        return getLine_intern(line);
    }

    void backLine(const string& line) { // push line back
        fb_assert(next_line==0);
        next_line = new string(line);
        lineNumber--;
    }

    size_t getLineNumber() const { return lineNumber; }
    void setLineNumber(size_t line) { lineNumber = line; }

    virtual const string& getFilename() const = 0; // @@@ rename (not necessarily a file)

    void copyTo(FILE *out) {
        string line;
        while (getLine(line)) {
            fputs(line.c_str(), out);
            fputc('\n', out);
        }
    }
};

const size_t BUFFERSIZE = 64*1024;

class BufferedFileReader : public LineReader { // derived from Noncopyable
    char buf[BUFFERSIZE];
    size_t read; // chars in buf
    size_t offset; // offset to next line

    FILE *fp;

    string filename;

    void fillBuffer();

    bool getLine_intern(string& line) OVERRIDE;

public:
    BufferedFileReader(const string& filename_, FILE *in) {
        filename = filename_;
        fp       = in;

        fb_assert(fp);
        read = BUFFERSIZE;
        fillBuffer();
    }
    virtual ~BufferedFileReader() {
        if (fp) fclose(fp);
    }

    bool good() { return fp!=0; }
    void rewind();

    const string& getFilename() const OVERRIDE { return filename; }

};

#else
#error BufferedFileReader.h included twice
#endif // BUFFEREDFILEREADER_H