source: tags/ms_r16q3/CONVERTALN/reader.cxx

Last change on this file was 15176, checked in by westram, 8 years ago
File size: 3.5 KB
Line 
1#include "reader.h"
2#include <unistd.h>
3
4Reader::Reader(const char *inf)
5    : fp(fopen(inf, "rt")),
6      file(NULL), 
7      curr(NULL),
8      failure(false)
9{
10    reset();
11    try {
12        if (!fp) {
13            throw_errorf(1, "can't read input file '%s' (Reason: %s)", inf, strerror(errno));
14        }
15        file = new BufferedFileReader(inf, fp);
16        file->showFilenameInLineError(true);
17        read();
18    }
19    catch (Convaln_exception& exc) {
20        failure = true;
21        curr    = NULL;
22        throw;
23    }
24}
25
26Reader::~Reader() {
27    // if kicked by exception, decorate error-msg with current reader position
28    if (const Convaln_exception *exc = Convaln_exception::exception_thrown()) {
29        exc->replace_msg(file->lineError(exc->get_msg()).c_str());
30    }
31    else {
32        ca_assert(!curr); // reader did NOT read till EOF, why ?
33    }
34    delete file;
35}
36
37void Reader::read() {
38    if (!curr) {
39        failure = true; // read _beyond_ EOF
40    }
41    else {
42        ca_assert(!failure); // attempt to read after failure
43
44        string next_line;
45        if (!file->getLine(next_line)) {
46            curr = NULL;
47        }
48        else {
49            size_t len = next_line.length();
50
51            if (len >= (LINESIZE-1)) {
52                char lbuf[200];
53                memcpy(lbuf, next_line.c_str(), 200-4);
54                strcpy(lbuf+200-4, "...");
55                throw_errorf(148, "Line too long: '%s'", lbuf);
56            }
57            memcpy(linebuf, next_line.c_str(), len);
58            linebuf[len]     = '\n';
59            linebuf[len + 1] = 0;
60
61            curr = linebuf;
62        }
63    }
64}
65
66
67// --------------------------------------------------------------------------------
68
69FileWriter::FileWriter(const char *outname)
70    : ofp(NULL),
71      filename(NULL),
72      written(0)
73#if defined(ENFORCE_CHECKED_WRITTEN)
74    , checked_written(false)
75#endif
76{
77    ofp = fopen(outname, "wt");
78    if (!ofp) {
79        throw_errorf(2, "can't write output file '%s' (Reason: %s)", outname, strerror(errno));
80    }
81    filename = ARB_strdup(outname);
82}
83FileWriter::~FileWriter() {
84    bool fine = is_fine();
85
86#if defined(ENFORCE_CHECKED_WRITTEN)
87    ca_assert(implicated(fine, checked_written)); // you have to call expect_written() on FileWriter before destruction
88#endif
89
90    if (ofp) fclose(ofp);
91    if (!fine) unlink(filename);
92    free(filename);
93
94    log_processed(written);
95}
96
97void FileWriter::expect_written() {
98#if defined(ENFORCE_CHECKED_WRITTEN)
99    ca_assert(!checked_written); // checking twice is nonsense
100    checked_written = true;
101#endif
102    if (is_fine() && !written) {
103        throw_errorf(42, "No sequence has been written");
104    }
105}
106
107void Writer::throw_write_error() const {
108    throw_errorf(41, "Write error: %s(=%i) while writing %s",
109                 strerror(errno), errno, name());
110}
111void FileWriter::out(char ch) {
112    if (fputc(ch, ofp) == EOF) throw_write_error();
113}
114
115int FileWriter::outf(const char *format, ...) {
116    va_list parg;
117    va_start(parg, format);
118    int     printed = vfprintf(ofp, format, parg);
119    va_end(parg);
120    if (printed<0) throw_write_error();
121    return printed;
122}
123
124int Writer::outf(const char *format, ...) {
125    va_list parg;
126    va_start(parg, format);
127    char    buffer[LINESIZE];
128    int     printed = vsprintf(buffer, format, parg);
129    ca_assert(printed <= LINESIZE);
130    va_end(parg);
131
132    out(buffer);
133    return printed;
134}
135
136int Writer::out(const char *text) {
137    int i = 0;
138    while (text[i]) {
139        out(text[i++]);
140    }
141    return i;
142}
143
Note: See TracBrowser for help on using the repository browser.