source: branches/help/CORE/MultiFileReader.cxx

Last change on this file was 16763, checked in by westram, 7 years ago
File size: 4.1 KB
Line 
1// ============================================================= //
2//                                                               //
3//   File      : MultiFileReader.cxx                             //
4//   Purpose   : Read multiple files like one concatenated file  //
5//                                                               //
6//   Coded by Ralf Westram (coder@reallysoft.de) in March 2014   //
7//   http://www.arb-home.de/                                     //
8//                                                               //
9// ============================================================= //
10
11#include "MultiFileReader.h"
12#include "arb_msg.h"
13
14const string& MultiFileReader::getFilename() const {
15    if (!reader) {
16        if (last_reader) return last_reader->getFilename();
17        arb_assert(0);
18        static string nf = "unknown-source";
19        return nf;
20    }
21    return reader->getFilename();
22}
23bool MultiFileReader::getLine_intern(string& line) {
24    bool gotLine = false;
25    if (reader) {
26        gotLine = reader->getLine(line);
27        if (!gotLine) {
28            nextReader();
29            gotLine = getLine_intern(line);
30            if (gotLine) setLineNumber(reader->getLineNumber());
31        }
32    }
33    return gotLine;
34}
35
36FILE *MultiFileReader::open(int i) {
37    FILE *in       = fopen(files[i], "rt");
38    if (!in) error = new string(GB_IO_error("reading", files[i]));
39    return in;
40}
41
42void MultiFileReader::nextReader() {
43    if (reader) {
44        if (last_reader) {
45            delete last_reader;
46            last_reader = NULp;
47        }
48        last_reader = reader;
49        reader      = NULp;
50    }
51    ++at;
52    if (at<files.size()) {
53        FILE *in = open(at);
54        if (in) {
55            reader = new BufferedFileReader(files[at], in);
56        }
57    }
58}
59
60MultiFileReader::MultiFileReader(const CharPtrArray& files_) :
61    files(files_),
62    reader(NULp),
63    last_reader(NULp),
64    error(NULp),
65    at(-1)
66{
67    for (size_t i = 0; i<files.size() && !error; ++i) {
68        // test open all files
69        FILE *in = open(i);
70        if (in) fclose(in);
71    }
72    if (!error) nextReader();
73}
74
75MultiFileReader::~MultiFileReader() {
76    delete reader;
77    delete last_reader;
78    delete error;
79}
80
81// --------------------------------------------------------------------------------
82
83#ifdef UNIT_TESTS
84#ifndef TEST_UNIT_H
85#include <test_unit.h>
86#endif
87
88void TEST_MultiFileReader() {
89    ConstStrArray files;
90    files.put("general/broken_LF.input"); // 6 lines
91    files.put("general/dos.input");       // 6 lines
92    files.put("general/mac.input");       // 6 lines
93    files.put("general/empty.input");     // 1 line
94    files.put("general/text.input");      // 6 lines
95
96    {
97        MultiFileReader reader(files);
98
99        TEST_EXPECT_NO_ERROR(reader.get_error());
100
101        string line;
102        string emptyLineError;
103        string db_found_msgs;
104        int    lineCount      = 0;
105        int    emptyLineCount = 0;
106
107        while (reader.getLine(line)) {
108            lineCount++;
109            if (line.empty()) {
110                emptyLineCount++;
111                emptyLineError = reader.lineError("seen empty line");
112            }
113            else if (strstr(line.c_str(), "database")) {
114                db_found_msgs += reader.lineError("DB") + "\n";
115            }
116        }
117
118        TEST_EXPECT_NO_ERROR(reader.get_error());
119        TEST_EXPECT_EQUAL(lineCount, 25);
120        TEST_EXPECT_EQUAL(emptyLineCount, 1);
121        TEST_EXPECT_EQUAL(emptyLineError, "general/empty.input:1: seen empty line");
122        TEST_EXPECT_EQUAL(db_found_msgs,
123                          "general/broken_LF.input:2: DB\n"
124                          "general/dos.input:2: DB\n"
125                          "general/mac.input:2: DB\n"
126                          "general/text.input:2: DB\n");
127    }
128
129    files.put("general/nosuch.input");
130    {
131        MultiFileReader reader(files);
132        TEST_EXPECT_EQUAL(reader.get_error(), "While reading 'general/nosuch.input': No such file or directory");
133    }
134}
135TEST_PUBLISH(TEST_MultiFileReader);
136
137#endif // UNIT_TESTS
138
139// --------------------------------------------------------------------------------
140
Note: See TracBrowser for help on using the repository browser.