| 1 | #ifndef READER_H | 
|---|
| 2 | #define READER_H | 
|---|
| 3 |  | 
|---|
| 4 | #ifndef BUFFEREDFILEREADER_H | 
|---|
| 5 | #include <BufferedFileReader.h> | 
|---|
| 6 | #endif | 
|---|
| 7 | #ifndef DEFS_H | 
|---|
| 8 | #include "defs.h" | 
|---|
| 9 | #endif | 
|---|
| 10 | #ifndef FUN_H | 
|---|
| 11 | #include "fun.h" | 
|---|
| 12 | #endif | 
|---|
| 13 | #ifndef SEQ_H | 
|---|
| 14 | #include "seq.h" | 
|---|
| 15 | #endif | 
|---|
| 16 | #ifndef INPUT_FORMAT_H | 
|---|
| 17 | #include "input_format.h" | 
|---|
| 18 | #endif | 
|---|
| 19 |  | 
|---|
| 20 |  | 
|---|
| 21 | class Reader : virtual Noncopyable { | 
|---|
| 22 | FILE               *fp; | 
|---|
| 23 | BufferedFileReader *file; | 
|---|
| 24 | char                linebuf[LINESIZE]; | 
|---|
| 25 | const char         *curr; // NULp means "EOF reached" | 
|---|
| 26 | bool                failure; | 
|---|
| 27 |  | 
|---|
| 28 | void reset() { | 
|---|
| 29 | curr    = linebuf; | 
|---|
| 30 | failure = false; | 
|---|
| 31 | } | 
|---|
| 32 |  | 
|---|
| 33 | void read(); | 
|---|
| 34 |  | 
|---|
| 35 | public: | 
|---|
| 36 | Reader(const char *inf); | 
|---|
| 37 | virtual ~Reader(); | 
|---|
| 38 |  | 
|---|
| 39 | void rewind() { file->rewind(); reset(); read(); } | 
|---|
| 40 |  | 
|---|
| 41 | Reader& operator++() { read(); return *this; } | 
|---|
| 42 |  | 
|---|
| 43 | const char *line() const { return curr; } | 
|---|
| 44 |  | 
|---|
| 45 | void set_line(const char *new_line)  { | 
|---|
| 46 | ca_assert(new_line); | 
|---|
| 47 | ca_assert(strlen(new_line)<LINESIZE); | 
|---|
| 48 | strcpy(linebuf, new_line); | 
|---|
| 49 | } | 
|---|
| 50 |  | 
|---|
| 51 | bool failed() const { return failure; } | 
|---|
| 52 | bool ok() const { return !failure; } | 
|---|
| 53 |  | 
|---|
| 54 | void abort() { failure = true; curr = NULp; } | 
|---|
| 55 | void ignore_rest_of_file() { curr = NULp; } | 
|---|
| 56 |  | 
|---|
| 57 | template<class PRED> | 
|---|
| 58 | void skipOverLinesThat(const PRED& match_condition) { | 
|---|
| 59 | while (line() && match_condition(line())) | 
|---|
| 60 | ++(*this); | 
|---|
| 61 | } | 
|---|
| 62 | PREPARE_MARK_NONFINAL_CLASS(Reader); | 
|---|
| 63 | }; | 
|---|
| 64 | MARK_NONFINAL_DTOR(Reader); // silence weird suggestion to make Reader-dtor final | 
|---|
| 65 |  | 
|---|
| 66 | inline const char *shorttimekeep(char *heapcopy) { RETURN_LOCAL_ALLOC(heapcopy); } | 
|---|
| 67 | inline const char *shorttimecopy(const char *nocopy) { return shorttimekeep(nulldup(nocopy)); } | 
|---|
| 68 |  | 
|---|
| 69 | struct FormatReader { | 
|---|
| 70 | virtual ~FormatReader() {} | 
|---|
| 71 | virtual bool read_one_entry(Seq& seq) __ATTR__USERESULT = 0; | 
|---|
| 72 | virtual bool failed() const = 0; | 
|---|
| 73 | virtual void ignore_rest_of_file() = 0; | 
|---|
| 74 | virtual void rewind() = 0; | 
|---|
| 75 | virtual InputFormat& get_data() = 0; | 
|---|
| 76 |  | 
|---|
| 77 | static SmartPtr<FormatReader> create(const FormattedFile& in); | 
|---|
| 78 | }; | 
|---|
| 79 |  | 
|---|
| 80 | typedef SmartPtr<FormatReader> FormatReaderPtr; | 
|---|
| 81 |  | 
|---|
| 82 | struct SimpleFormatReader : public Reader, public FormatReader { | 
|---|
| 83 | SimpleFormatReader(const char *inf) : Reader(inf) {} | 
|---|
| 84 | bool failed() const OVERRIDE { return Reader::failed(); } | 
|---|
| 85 | void ignore_rest_of_file() OVERRIDE { Reader::ignore_rest_of_file(); } | 
|---|
| 86 | void rewind() OVERRIDE { Reader::rewind(); } | 
|---|
| 87 | }; | 
|---|
| 88 |  | 
|---|
| 89 | // -------------------------------------------------------------------------------- | 
|---|
| 90 |  | 
|---|
| 91 | #if defined(ASSERTION_USED) | 
|---|
| 92 | #define ENFORCE_CHECKED_WRITTEN | 
|---|
| 93 | #endif | 
|---|
| 94 |  | 
|---|
| 95 | struct Writer { | 
|---|
| 96 | Writer() {} | 
|---|
| 97 | virtual ~Writer() {} | 
|---|
| 98 |  | 
|---|
| 99 | virtual bool ok() const          = 0; | 
|---|
| 100 | virtual void out(char ch)        = 0; | 
|---|
| 101 | virtual const char *name() const = 0; | 
|---|
| 102 |  | 
|---|
| 103 | virtual void throw_write_error() const __ATTR__NORETURN; | 
|---|
| 104 | virtual int out(const char *text) { | 
|---|
| 105 | int i = 0; | 
|---|
| 106 | while (text[i]) { | 
|---|
| 107 | out(text[i++]); | 
|---|
| 108 | } | 
|---|
| 109 | return i; | 
|---|
| 110 | } | 
|---|
| 111 | virtual int outf(const char *format, ...) __ATTR__FORMAT_MEMBER(1); | 
|---|
| 112 |  | 
|---|
| 113 | void repeated(char ch, int repeat) { while (repeat--) out(ch); } | 
|---|
| 114 | }; | 
|---|
| 115 |  | 
|---|
| 116 | #ifdef GCC_TOO_SMART_FOR_USEFUL_FINAL_TYPE_SUGGESTION | 
|---|
| 117 | # pragma GCC diagnostic push | 
|---|
| 118 | # pragma GCC diagnostic ignored "-Wsuggest-final-types" | 
|---|
| 119 | #endif | 
|---|
| 120 |  | 
|---|
| 121 | class FileWriter : public Writer, virtual Noncopyable { | 
|---|
| 122 | FILE *ofp; | 
|---|
| 123 | char *filename; | 
|---|
| 124 | int   written; // count written sequences | 
|---|
| 125 |  | 
|---|
| 126 | #if defined(ENFORCE_CHECKED_WRITTEN) | 
|---|
| 127 | bool checked_written; | 
|---|
| 128 | #endif | 
|---|
| 129 |  | 
|---|
| 130 | bool is_fine() const { return ofp && !Convaln_exception::exception_thrown(); } | 
|---|
| 131 |  | 
|---|
| 132 | public: | 
|---|
| 133 | FileWriter(const char *outf); | 
|---|
| 134 | ~FileWriter() OVERRIDE; | 
|---|
| 135 |  | 
|---|
| 136 | FILE *get_FILE() { return ofp; } | 
|---|
| 137 |  | 
|---|
| 138 | bool ok() const OVERRIDE { return ofp; } | 
|---|
| 139 | void out(char ch) FINAL_OVERRIDE { | 
|---|
| 140 | if (fputc(ch, ofp) == EOF) throw_write_error(); | 
|---|
| 141 | } | 
|---|
| 142 |  | 
|---|
| 143 | const char *name() const OVERRIDE { return filename; } | 
|---|
| 144 |  | 
|---|
| 145 | int out(const char *text) OVERRIDE { return Writer::out(text); } | 
|---|
| 146 | int outf(const char *format, ...) OVERRIDE __ATTR__FORMAT_MEMBER(1); | 
|---|
| 147 |  | 
|---|
| 148 | void seq_done() { ++written; } | 
|---|
| 149 | void seq_done(int count) { ca_assert(count >= 0); written += count; } | 
|---|
| 150 |  | 
|---|
| 151 | void expect_written(); | 
|---|
| 152 |  | 
|---|
| 153 | PREPARE_MARK_NONFINAL_CLASS(FileWriter); | 
|---|
| 154 | }; | 
|---|
| 155 | MARK_NONFINAL_CLASS(FileWriter); // does not work for too smart gcc|s | 
|---|
| 156 | #ifdef GCC_TOO_SMART_FOR_USEFUL_FINAL_TYPE_SUGGESTION | 
|---|
| 157 | # pragma GCC diagnostic pop | 
|---|
| 158 | #endif | 
|---|
| 159 |  | 
|---|
| 160 | #else | 
|---|
| 161 | #error reader.h included twice | 
|---|
| 162 | #endif // READER_H | 
|---|
| 163 |  | 
|---|