Eclipse SUMO - Simulation of Urban MObility
LineReader.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3// Copyright (C) 2001-2022 German Aerospace Center (DLR) and others.
4// This program and the accompanying materials are made available under the
5// terms of the Eclipse Public License 2.0 which is available at
6// https://www.eclipse.org/legal/epl-2.0/
7// This Source Code may also be made available under the following Secondary
8// Licenses when the conditions for such availability set forth in the Eclipse
9// Public License 2.0 are satisfied: GNU General Public License, version 2
10// or later which is available at
11// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13/****************************************************************************/
20// Retrieves a file linewise and reports the lines to a handler.
21/****************************************************************************/
22#include <config.h>
23
24#include <string>
25#include <fstream>
26#include <iostream>
27#include <algorithm>
28#include <sstream>
30#include "LineHandler.h"
31#include "LineReader.h"
32
33
34// ===========================================================================
35// method definitions
36// ===========================================================================
38
39
40LineReader::LineReader(const std::string& file)
41 : myFileName(file),
42 myRead(0) {
43 reinit();
44}
45
46
48
49
50bool
52 return myRread < myAvailable;
53}
54
55
56void
58 while (myRread < myAvailable) {
59 if (!readLine(lh)) {
60 return;
61 }
62 }
63}
64
65
66bool
68 std::string toReport;
69 bool moreAvailable = true;
70 while (toReport.length() == 0) {
71 const std::string::size_type idx = myStrBuffer.find('\n');
72 if (idx == 0) {
73 myStrBuffer = myStrBuffer.substr(1);
74 myRread++;
75 return lh.report("");
76 }
77 if (idx != std::string::npos) {
78 toReport = myStrBuffer.substr(0, idx);
79 myStrBuffer = myStrBuffer.substr(idx + 1);
80 myRread += (int)idx + 1;
81 } else {
82 if (myRead < myAvailable) {
83 myStrm.read(myBuffer,
84 myAvailable - myRead < 1024
86 : 1024);
87 int noBytes = myAvailable - myRead;
88 noBytes = noBytes > 1024 ? 1024 : noBytes;
89 myStrBuffer += std::string(myBuffer, noBytes);
90 myRead += 1024;
91 } else {
92 toReport = myStrBuffer;
93 moreAvailable = false;
94 if (toReport == "") {
95 return lh.report(toReport);
96 }
97 }
98 }
99 }
100 // remove trailing blanks
101 int idx = (int)toReport.length() - 1;
102 while (idx >= 0 && toReport[idx] < 32) {
103 idx--;
104 }
105 if (idx >= 0) {
106 toReport = toReport.substr(0, idx + 1);
107 } else {
108 toReport = "";
109 }
110 // give it to the handler
111 if (!lh.report(toReport)) {
112 return false;
113 }
114 return moreAvailable;
115}
116
117
118std::string
120 std::string toReport;
121 while (toReport.length() == 0 && myStrm.good()) {
122 const std::string::size_type idx = myStrBuffer.find('\n');
123 if (idx == 0) {
124 myStrBuffer = myStrBuffer.substr(1);
125 myRread++;
126 myLinesRead++;
127 return "";
128 }
129 if (idx != std::string::npos) {
130 toReport = myStrBuffer.substr(0, idx);
131 myStrBuffer = myStrBuffer.substr(idx + 1);
132 myRread += (int) idx + 1;
133 } else {
134 if (myRead < myAvailable) {
135 myStrm.read(myBuffer,
136 myAvailable - myRead < 1024
138 : 1024);
139 int noBytes = myAvailable - myRead;
140 noBytes = noBytes > 1024 ? 1024 : noBytes;
141 myStrBuffer += std::string(myBuffer, noBytes);
142 myRead += 1024;
143 } else {
144 toReport = myStrBuffer;
145 myRread += 1024;
146 if (toReport == "") {
147 myLinesRead++;
148 return toReport;
149 }
150 }
151 }
152 }
153 if (!myStrm.good()) {
154 return "";
155 }
156 // remove trailing blanks
157 int idx = (int)toReport.length() - 1;
158 while (idx >= 0 && toReport[idx] < 32) {
159 idx--;
160 }
161 if (idx >= 0) {
162 toReport = toReport.substr(0, idx + 1);
163 } else {
164 toReport = "";
165 }
166 myLinesRead++;
167 return toReport;
168}
169
170
171
172std::string
174 return myFileName;
175}
176
177
178bool
179LineReader::setFile(const std::string& file) {
180 myFileName = file;
181 reinit();
182 return myStrm.good();
183}
184
185
186unsigned long
188 return myRread;
189}
190
191
192void
194 if (myStrm.is_open()) {
195 myStrm.close();
196 }
197 myStrm.clear();
198 myStrm.open(myFileName.c_str(), std::ios::binary);
199 myStrm.unsetf(std::ios::skipws);
200 myStrm.seekg(0, std::ios::end);
201 myAvailable = static_cast<int>(myStrm.tellg());
202 myStrm.seekg(0, std::ios::beg);
203 if (myAvailable >= 3) {
204 // check for BOM
205 myStrm.read(myBuffer, 3);
206 if (myBuffer[0] == '\xef' && myBuffer[1] == '\xbb' && myBuffer[2] == '\xbf') {
207 myAvailable -= 3;
208 } else {
209 myStrm.seekg(0, std::ios::beg);
210 }
211 }
212 myRead = 0;
213 myRread = 0;
214 myStrBuffer = "";
215 myLinesRead = 0;
216}
217
218
219void
220LineReader::setPos(unsigned long pos) {
221 myStrm.seekg(pos, std::ios::beg);
222 myRead = pos;
223 myRread = pos;
224 myStrBuffer = "";
225}
226
227
228bool
230 return myStrm.good();
231}
232
233
234/****************************************************************************/
Interface definition for a class which retrieves lines from a LineHandler.
Definition: LineHandler.h:42
virtual bool report(const std::string &result)=0
Method that obatins a line read by the LineReader.
void setPos(unsigned long pos)
Sets the current position within the file to the given value.
Definition: LineReader.cpp:220
~LineReader()
Destructor.
Definition: LineReader.cpp:47
unsigned long getPosition()
Returns the current position within the file.
Definition: LineReader.cpp:187
LineReader()
Constructor.
Definition: LineReader.cpp:37
bool good() const
Returns the information whether the stream is readable.
Definition: LineReader.cpp:229
int myRead
Information about how many characters were supplied to the LineHandler.
Definition: LineReader.h:161
int myRread
Information how many bytes were read by the reader from the file.
Definition: LineReader.h:167
int myAvailable
Information how many bytes are available within the used file.
Definition: LineReader.h:164
std::string readLine()
Reads a single (the next) line from the file and returns it.
Definition: LineReader.cpp:119
bool setFile(const std::string &file)
Reinitialises the reader for reading from the given file.
Definition: LineReader.cpp:179
void reinit()
Reinitialises the reading (of the previous file)
Definition: LineReader.cpp:193
int myLinesRead
Information how many lines were read for meaningful error messages.
Definition: LineReader.h:170
bool hasMore() const
Returns whether another line may be read (the file was not read completely)
Definition: LineReader.cpp:51
std::string getFileName() const
Returns the name of the used file.
Definition: LineReader.cpp:173
std::ifstream myStrm
the stream used
Definition: LineReader.h:152
std::string myFileName
the name of the file to read the contents from
Definition: LineReader.h:149
char myBuffer[1024]
To override MSVC++-bugs, we use an own getline which uses this buffer.
Definition: LineReader.h:155
std::string myStrBuffer
a string-buffer
Definition: LineReader.h:158
void readAll(LineHandler &lh)
Reads the whole file linewise, reporting every line to the given LineHandler.
Definition: LineReader.cpp:57