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
|