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 58 : LineReader::LineReader() {} 39 : 40 : 41 2284 : LineReader::LineReader(const std::string& file) 42 2284 : : myFileName(file), 43 2284 : myRead(0) { 44 2284 : reinit(); 45 2284 : } 46 : 47 : 48 4680 : LineReader::~LineReader() {} 49 : 50 : 51 : bool 52 2377894 : LineReader::hasMore() const { 53 2377894 : return myRread < myAvailable; 54 : } 55 : 56 : 57 : void 58 119 : LineReader::readAll(LineHandler& lh) { 59 4238 : while (myRread < myAvailable) { 60 4119 : if (!readLine(lh)) { 61 : return; 62 : } 63 : } 64 : } 65 : 66 : 67 : bool 68 4119 : LineReader::readLine(LineHandler& lh) { 69 : std::string toReport; 70 : bool moreAvailable = true; 71 8551 : while (toReport.length() == 0) { 72 4432 : const std::string::size_type idx = myStrBuffer.find('\n'); 73 4432 : if (idx == 0) { 74 0 : myStrBuffer = myStrBuffer.substr(1); 75 0 : myRread++; 76 0 : return lh.report(""); 77 : } 78 4432 : if (idx != std::string::npos) { 79 4119 : toReport = myStrBuffer.substr(0, idx); 80 4119 : myStrBuffer = myStrBuffer.substr(idx + 1); 81 4119 : myRread += (int)idx + 1; 82 : } else { 83 313 : if (myRead < myAvailable) { 84 313 : myStrm.read(myBuffer, 85 313 : myAvailable - myRead < 1024 86 313 : ? myAvailable - myRead 87 : : 1024); 88 313 : int noBytes = myAvailable - myRead; 89 313 : noBytes = noBytes > 1024 ? 1024 : noBytes; 90 313 : myStrBuffer += std::string(myBuffer, noBytes); 91 313 : 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 4119 : int idx = (int)toReport.length() - 1; 103 5517 : while (idx >= 0 && toReport[idx] < 32) { 104 1398 : idx--; 105 : } 106 4119 : if (idx >= 0) { 107 8238 : toReport = toReport.substr(0, idx + 1); 108 : } else { 109 : toReport = ""; 110 : } 111 : // give it to the handler 112 4119 : if (!lh.report(toReport)) { 113 0 : return false; 114 : } 115 : return moreAvailable; 116 : } 117 : 118 : 119 : std::string 120 2375286 : LineReader::readLine() { 121 : std::string toReport; 122 4786904 : while (toReport.length() == 0 && myStrm.good()) { 123 2412749 : const std::string::size_type idx = myStrBuffer.find('\n'); 124 2412749 : if (idx == 0) { 125 1131 : myStrBuffer = myStrBuffer.substr(1); 126 1131 : myRread++; 127 1131 : myLinesRead++; 128 1131 : return ""; 129 : } 130 2411618 : if (idx != std::string::npos) { 131 2374147 : toReport = myStrBuffer.substr(0, idx); 132 2374147 : myStrBuffer = myStrBuffer.substr(idx + 1); 133 2374147 : myRread += (int) idx + 1; 134 : } else { 135 37471 : if (myRead < myAvailable) { 136 37463 : myStrm.read(myBuffer, 137 37463 : myAvailable - myRead < 1024 138 37463 : ? myAvailable - myRead 139 : : 1024); 140 37463 : int noBytes = myAvailable - myRead; 141 37463 : noBytes = noBytes > 1024 ? 1024 : noBytes; 142 37463 : myStrBuffer += std::string(myBuffer, noBytes); 143 37463 : myRead += 1024; 144 : } else { 145 : toReport = myStrBuffer; 146 8 : myRread += (int)myStrBuffer.size(); 147 8 : if (toReport == "") { 148 0 : myLinesRead++; 149 : return toReport; 150 : } 151 : } 152 : } 153 : } 154 2374155 : if (!myStrm.good()) { 155 0 : return ""; 156 : } 157 : // remove trailing blanks 158 2374155 : int idx = (int)toReport.length() - 1; 159 2374354 : while (idx >= 0 && toReport[idx] < 32) { 160 199 : idx--; 161 : } 162 2374155 : if (idx >= 0) { 163 4748296 : toReport = toReport.substr(0, idx + 1); 164 : } else { 165 : toReport = ""; 166 : } 167 2374155 : myLinesRead++; 168 : return toReport; 169 : } 170 : 171 : 172 : 173 : std::string 174 185 : LineReader::getFileName() const { 175 185 : return myFileName; 176 : } 177 : 178 : 179 : bool 180 311 : LineReader::setFile(const std::string& file) { 181 311 : myFileName = file; 182 311 : reinit(); 183 311 : return myStrm.good(); 184 : } 185 : 186 : 187 : unsigned long 188 159 : LineReader::getPosition() { 189 159 : return myRread; 190 : } 191 : 192 : 193 : void 194 2754 : LineReader::reinit() { 195 2754 : if (myStrm.is_open()) { 196 277 : myStrm.close(); 197 : } 198 2754 : myStrm.clear(); 199 2754 : myStrm.open(myFileName.c_str(), std::ios::binary); 200 : myStrm.unsetf(std::ios::skipws); 201 2754 : myStrm.seekg(0, std::ios::end); 202 2754 : myAvailable = static_cast<int>(myStrm.tellg()); 203 2754 : myStrm.seekg(0, std::ios::beg); 204 2754 : if (myAvailable >= 3) { 205 : // check for BOM 206 2566 : myStrm.read(myBuffer, 3); 207 2566 : if (myBuffer[0] == '\xef' && myBuffer[1] == '\xbb' && myBuffer[2] == '\xbf') { 208 2 : mySkipBOM = 3; 209 2 : myAvailable -= mySkipBOM; 210 : } else { 211 2564 : mySkipBOM = 0; 212 2564 : myStrm.seekg(0, std::ios::beg); 213 : } 214 : } 215 2754 : myRead = 0; 216 2754 : myRread = 0; 217 2754 : myStrBuffer = ""; 218 2754 : myLinesRead = 0; 219 2754 : } 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 4353 : LineReader::good() const { 233 4353 : return myStrm.good(); 234 : } 235 : 236 : 237 : /****************************************************************************/