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 StringTokenizer.cpp 15 : /// @author Daniel Krajzewicz 16 : /// @author Jakob Erdmann 17 : /// @author Michael Behrisch 18 : /// @date ? 19 : /// 20 : // A java-style StringTokenizer for c++ (stl) 21 : /****************************************************************************/ 22 : #include <config.h> 23 : 24 : #include <string> 25 : #include <vector> 26 : #include <iostream> // !!! debug only 27 : 28 : #include "UtilExceptions.h" 29 : #include "StringTokenizer.h" 30 : 31 : 32 : // =========================================================================== 33 : // variable definitions 34 : // =========================================================================== 35 : const int StringTokenizer::NEWLINE = -256; 36 : const int StringTokenizer::WHITECHARS = -257; 37 : const int StringTokenizer::SPACE = 32; 38 : const int StringTokenizer::TAB = 9; 39 : 40 : 41 : // =========================================================================== 42 : // method definitions 43 : // =========================================================================== 44 : 45 120 : StringTokenizer::StringTokenizer() : 46 120 : myPos(0) { 47 120 : } 48 : 49 : 50 4266950 : StringTokenizer::StringTokenizer(std::string tosplit) : 51 4266950 : myTosplit(tosplit), myPos(0) { 52 4266950 : prepareWhitechar(tosplit); 53 4266950 : } 54 : 55 : 56 14788086 : StringTokenizer::StringTokenizer(std::string tosplit, std::string token, bool splitAtAllChars) : 57 14788086 : myTosplit(tosplit), myPos(0) { 58 14788086 : prepare(tosplit, token, splitAtAllChars); 59 14788086 : } 60 : 61 : 62 3477 : StringTokenizer::StringTokenizer(std::string tosplit, int special) : 63 3477 : myTosplit(tosplit), myPos(0) { 64 3477 : switch (special) { 65 : case NEWLINE: 66 2 : prepare(tosplit, "\r\n", true); 67 2 : break; 68 : case TAB: 69 1256 : prepare(tosplit, "\t", true); 70 1256 : break; 71 1520 : case WHITECHARS: 72 1520 : prepareWhitechar(tosplit); 73 : break; 74 699 : default: 75 699 : char* buf = new char[2]; 76 699 : buf[0] = (char) special; 77 699 : buf[1] = 0; 78 699 : prepare(tosplit, buf, false); 79 699 : delete[] buf; 80 : break; 81 : } 82 3477 : } 83 : 84 : 85 19058633 : StringTokenizer::~StringTokenizer() {} 86 : 87 : 88 2652167 : void StringTokenizer::reinit() { 89 2652167 : myPos = 0; 90 2652167 : } 91 : 92 : 93 33518247 : bool StringTokenizer::hasNext() { 94 33518247 : return myPos != (int)myStarts.size(); 95 : } 96 : 97 : 98 44990424 : std::string StringTokenizer::next() { 99 44990424 : if (myPos >= (int)myStarts.size()) { 100 8 : throw OutOfBoundsException(); 101 : } 102 44990420 : if (myLengths[myPos] == 0) { 103 87 : myPos++; 104 87 : return ""; 105 : } 106 44990333 : int start = myStarts[myPos]; 107 44990333 : int length = myLengths[myPos++]; 108 44990333 : return myTosplit.substr(start, length); 109 : } 110 : 111 : 112 1501 : std::string StringTokenizer::front() { 113 1501 : if (myStarts.size() == 0) { 114 0 : throw OutOfBoundsException(); 115 : } 116 1501 : if (myLengths[0] == 0) { 117 0 : return ""; 118 : } 119 1501 : return myTosplit.substr(myStarts[0], myLengths[0]); 120 : } 121 : 122 : 123 399520 : std::string StringTokenizer::get(int pos) const { 124 399520 : if (pos >= (int)myStarts.size()) { 125 8 : throw OutOfBoundsException(); 126 : } 127 399516 : if (myLengths[pos] == 0) { 128 574 : return ""; 129 : } 130 398942 : int start = myStarts[pos]; 131 : int length = myLengths[pos]; 132 398942 : return myTosplit.substr(start, length); 133 : } 134 : 135 : 136 21393632 : int StringTokenizer::size() const { 137 21393632 : return (int)myStarts.size(); 138 : } 139 : 140 : 141 14790043 : void StringTokenizer::prepare(const std::string& tosplit, const std::string& token, bool splitAtAllChars) { 142 14790043 : int beg = 0; 143 14790043 : int len = (int)token.length(); 144 14790043 : if (splitAtAllChars) { 145 : len = 1; 146 : } 147 48403663 : while (beg < (int)tosplit.length()) { 148 : std::string::size_type end; 149 33613620 : if (splitAtAllChars) { 150 21525 : end = tosplit.find_first_of(token, beg); 151 : } else { 152 33592095 : end = tosplit.find(token, beg); 153 : } 154 33613620 : if (end == std::string::npos) { 155 : end = tosplit.length(); 156 : } 157 33613620 : myStarts.push_back(beg); 158 33613620 : myLengths.push_back((int)end - beg); 159 33613620 : beg = (int)end + len; 160 33613620 : if (beg == (int)tosplit.length()) { 161 38 : myStarts.push_back(beg - 1); 162 38 : myLengths.push_back(0); 163 : } 164 : } 165 14790043 : } 166 : 167 : 168 4268470 : void StringTokenizer::prepareWhitechar(const std::string& tosplit) { 169 : std::string::size_type len = tosplit.length(); 170 : std::string::size_type beg = 0; 171 4268565 : while (beg < len && tosplit[beg] <= SPACE) { 172 95 : beg++; 173 : } 174 18475599 : while (beg != std::string::npos && beg < len) { 175 : std::string::size_type end = beg; 176 153715105 : while (end < len && tosplit[end] > SPACE) { 177 139507976 : end++; 178 : } 179 14207129 : myStarts.push_back((int)beg); 180 14207129 : myLengths.push_back((int)end - (int)beg); 181 : beg = end; 182 24648064 : while (beg < len && tosplit[beg] <= SPACE) { 183 10440935 : beg++; 184 : } 185 : } 186 4268470 : } 187 : 188 : 189 : std::vector<std::string> 190 2652165 : StringTokenizer::getVector() { 191 : std::vector<std::string> ret; 192 2652165 : ret.reserve(size()); 193 9422975 : while (hasNext()) { 194 13541620 : ret.push_back(next()); 195 : } 196 2652165 : reinit(); 197 2652165 : return ret; 198 0 : } 199 : 200 : 201 : std::set<std::string> 202 28 : StringTokenizer::getSet() { 203 28 : std::vector<std::string> v = getVector(); 204 56 : return std::set<std::string>(v.begin(), v.end()); 205 28 : } 206 : 207 : 208 : /****************************************************************************/