Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2001-2024 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 : /****************************************************************************/
14 : /// @file LineReader.cpp
15 : /// @author Daniel Krajzewicz
16 : /// @author Laura Bieker
17 : /// @author Michael Behrisch
18 : /// @author Mirko Barthauer
19 : /// @date Fri, 19 Jul 2002
20 : ///
21 : // Retrieves a file linewise and reports the lines to a handler.
22 : /****************************************************************************/
23 : #include <config.h>
24 :
25 : #include <string>
26 : #include <fstream>
27 : #include <iostream>
28 : #include <algorithm>
29 : #include <sstream>
30 : #include <utils/common/UtilExceptions.h>
31 : #include "LineHandler.h"
32 : #include "LineReader.h"
33 :
34 :
35 : // ===========================================================================
36 : // method definitions
37 : // ===========================================================================
38 57 : LineReader::LineReader() {}
39 :
40 :
41 1290 : LineReader::LineReader(const std::string& file)
42 1290 : : myFileName(file),
43 1290 : myRead(0) {
44 1290 : reinit();
45 1290 : }
46 :
47 :
48 1347 : LineReader::~LineReader() {}
49 :
50 :
51 : bool
52 1205161 : LineReader::hasMore() const {
53 1205161 : return myRread < myAvailable;
54 : }
55 :
56 :
57 : void
58 114 : LineReader::readAll(LineHandler& lh) {
59 3112 : while (myRread < myAvailable) {
60 2998 : if (!readLine(lh)) {
61 : return;
62 : }
63 : }
64 : }
65 :
66 :
67 : bool
68 2998 : LineReader::readLine(LineHandler& lh) {
69 : std::string toReport;
70 : bool moreAvailable = true;
71 6246 : while (toReport.length() == 0) {
72 3248 : const std::string::size_type idx = myStrBuffer.find('\n');
73 3248 : if (idx == 0) {
74 0 : myStrBuffer = myStrBuffer.substr(1);
75 0 : myRread++;
76 0 : return lh.report("");
77 : }
78 3248 : if (idx != std::string::npos) {
79 2998 : toReport = myStrBuffer.substr(0, idx);
80 2998 : myStrBuffer = myStrBuffer.substr(idx + 1);
81 2998 : myRread += (int)idx + 1;
82 : } else {
83 250 : if (myRead < myAvailable) {
84 250 : myStrm.read(myBuffer,
85 250 : myAvailable - myRead < 1024
86 250 : ? myAvailable - myRead
87 : : 1024);
88 250 : int noBytes = myAvailable - myRead;
89 250 : noBytes = noBytes > 1024 ? 1024 : noBytes;
90 250 : myStrBuffer += std::string(myBuffer, noBytes);
91 250 : myRead += 1024;
92 : } else {
93 : toReport = myStrBuffer;
94 : moreAvailable = false;
95 0 : if (toReport == "") {
96 0 : return lh.report(toReport);
97 : }
98 : }
99 : }
100 : }
101 : // remove trailing blanks
102 2998 : int idx = (int)toReport.length() - 1;
103 3819 : while (idx >= 0 && toReport[idx] < 32) {
104 821 : idx--;
105 : }
106 2998 : if (idx >= 0) {
107 5996 : toReport = toReport.substr(0, idx + 1);
108 : } else {
109 : toReport = "";
110 : }
111 : // give it to the handler
112 2998 : if (!lh.report(toReport)) {
113 0 : return false;
114 : }
115 : return moreAvailable;
116 : }
117 :
118 :
119 : std::string
120 1203546 : LineReader::readLine() {
121 : std::string toReport;
122 2425564 : while (toReport.length() == 0 && myStrm.good()) {
123 1223149 : const std::string::size_type idx = myStrBuffer.find('\n');
124 1223149 : if (idx == 0) {
125 1131 : myStrBuffer = myStrBuffer.substr(1);
126 1131 : myRread++;
127 1131 : myLinesRead++;
128 1131 : return "";
129 : }
130 1222018 : if (idx != std::string::npos) {
131 1202407 : toReport = myStrBuffer.substr(0, idx);
132 1202407 : myStrBuffer = myStrBuffer.substr(idx + 1);
133 1202407 : myRread += (int) idx + 1;
134 : } else {
135 19611 : if (myRead < myAvailable) {
136 19603 : myStrm.read(myBuffer,
137 19603 : myAvailable - myRead < 1024
138 19603 : ? myAvailable - myRead
139 : : 1024);
140 19603 : int noBytes = myAvailable - myRead;
141 19603 : noBytes = noBytes > 1024 ? 1024 : noBytes;
142 19603 : myStrBuffer += std::string(myBuffer, noBytes);
143 19603 : myRead += 1024;
144 : } else {
145 : toReport = myStrBuffer;
146 8 : myRread += (int)myStrBuffer.size();
147 8 : if (toReport == "") {
148 0 : myLinesRead++;
149 0 : return toReport;
150 : }
151 : }
152 : }
153 : }
154 1202415 : if (!myStrm.good()) {
155 0 : return "";
156 : }
157 : // remove trailing blanks
158 1202415 : int idx = (int)toReport.length() - 1;
159 1202614 : while (idx >= 0 && toReport[idx] < 32) {
160 199 : idx--;
161 : }
162 1202415 : if (idx >= 0) {
163 2404816 : toReport = toReport.substr(0, idx + 1);
164 : } else {
165 : toReport = "";
166 : }
167 1202415 : myLinesRead++;
168 1202415 : return toReport;
169 : }
170 :
171 :
172 :
173 : std::string
174 184 : LineReader::getFileName() const {
175 184 : return myFileName;
176 : }
177 :
178 :
179 : bool
180 305 : LineReader::setFile(const std::string& file) {
181 305 : myFileName = file;
182 305 : reinit();
183 305 : return myStrm.good();
184 : }
185 :
186 :
187 : unsigned long
188 159 : LineReader::getPosition() {
189 159 : return myRread;
190 : }
191 :
192 :
193 : void
194 1754 : LineReader::reinit() {
195 1754 : if (myStrm.is_open()) {
196 272 : myStrm.close();
197 : }
198 1754 : myStrm.clear();
199 1754 : myStrm.open(myFileName.c_str(), std::ios::binary);
200 : myStrm.unsetf(std::ios::skipws);
201 1754 : myStrm.seekg(0, std::ios::end);
202 1754 : myAvailable = static_cast<int>(myStrm.tellg());
203 1754 : myStrm.seekg(0, std::ios::beg);
204 1754 : if (myAvailable >= 3) {
205 : // check for BOM
206 1568 : myStrm.read(myBuffer, 3);
207 1568 : if (myBuffer[0] == '\xef' && myBuffer[1] == '\xbb' && myBuffer[2] == '\xbf') {
208 2 : mySkipBOM = 3;
209 2 : myAvailable -= mySkipBOM;
210 : } else {
211 1566 : mySkipBOM = 0;
212 1566 : myStrm.seekg(0, std::ios::beg);
213 : }
214 : }
215 1754 : myRead = 0;
216 1754 : myRread = 0;
217 1754 : myStrBuffer = "";
218 1754 : myLinesRead = 0;
219 1754 : }
220 :
221 :
222 : void
223 159 : LineReader::setPos(unsigned long pos) {
224 159 : myStrm.seekg(pos + mySkipBOM, std::ios::beg);
225 159 : myRead = pos;
226 159 : myRread = pos;
227 159 : myStrBuffer = "";
228 159 : }
229 :
230 :
231 : bool
232 3359 : LineReader::good() const {
233 3359 : return myStrm.good();
234 : }
235 :
236 :
237 : /****************************************************************************/
|