1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2019 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
10 /// @file StringTokenizer.cpp
11 /// @author Daniel Krajzewicz
12 /// @author Jakob Erdmann
13 /// @author Michael Behrisch
14 /// @date ?
15 /// @version $Id$
16 ///
17 // A java-style StringTokenizer for c++ (stl)
18 /****************************************************************************/
19
20
21 // ===========================================================================
22 // included modules
23 // ===========================================================================
24 #include <config.h>
25
26 #include <string>
27 #include <vector>
28 #include <iostream> // !!! debug only
29 #include "UtilExceptions.h"
30 #include "StringTokenizer.h"
31
32
33 // ===========================================================================
34 // variable definitions
35 // ===========================================================================
36 const int StringTokenizer::NEWLINE = -256;
37 const int StringTokenizer::WHITECHARS = -257;
38 const int StringTokenizer::SPACE = 32;
39 const int StringTokenizer::TAB = 9;
40
41
42 // ===========================================================================
43 // method definitions
44 // ===========================================================================
StringTokenizer(std::string tosplit)45 StringTokenizer::StringTokenizer(std::string tosplit)
46 : myTosplit(tosplit), myPos(0) {
47 prepareWhitechar(tosplit);
48 }
49
50
StringTokenizer(std::string tosplit,std::string token,bool splitAtAllChars)51 StringTokenizer::StringTokenizer(std::string tosplit, std::string token, bool splitAtAllChars)
52 : myTosplit(tosplit), myPos(0) {
53 prepare(tosplit, token, splitAtAllChars);
54 }
55
56
StringTokenizer(std::string tosplit,int special)57 StringTokenizer::StringTokenizer(std::string tosplit, int special)
58 : myTosplit(tosplit), myPos(0) {
59 switch (special) {
60 case NEWLINE:
61 prepare(tosplit, "\r\n", true);
62 break;
63 case TAB:
64 prepare(tosplit, "\t", true);
65 break;
66 case WHITECHARS:
67 prepareWhitechar(tosplit);
68 break;
69 default:
70 char* buf = new char[2];
71 buf[0] = (char) special;
72 buf[1] = 0;
73 prepare(tosplit, buf, false);
74 delete[] buf;
75 break;
76 }
77 }
78
79
~StringTokenizer()80 StringTokenizer::~StringTokenizer() {}
81
reinit()82 void StringTokenizer::reinit() {
83 myPos = 0;
84 }
85
hasNext()86 bool StringTokenizer::hasNext() {
87 return myPos != (int)myStarts.size();
88 }
89
next()90 std::string StringTokenizer::next() {
91 if (myPos >= (int)myStarts.size()) {
92 throw OutOfBoundsException();
93 }
94 if (myLengths[myPos] == 0) {
95 myPos++;
96 return "";
97 }
98 int start = myStarts[myPos];
99 int length = myLengths[myPos++];
100 return myTosplit.substr(start, length);
101 }
102
front()103 std::string StringTokenizer::front() {
104 if (myStarts.size() == 0) {
105 throw OutOfBoundsException();
106 }
107 if (myLengths[0] == 0) {
108 return "";
109 }
110 return myTosplit.substr(myStarts[0], myLengths[0]);
111 }
112
get(int pos) const113 std::string StringTokenizer::get(int pos) const {
114 if (pos >= (int)myStarts.size()) {
115 throw OutOfBoundsException();
116 }
117 if (myLengths[pos] == 0) {
118 return "";
119 }
120 int start = myStarts[pos];
121 int length = myLengths[pos];
122 return myTosplit.substr(start, length);
123 }
124
125
size() const126 int StringTokenizer::size() const {
127 return (int)myStarts.size();
128 }
129
prepare(const std::string & tosplit,const std::string & token,bool splitAtAllChars)130 void StringTokenizer::prepare(const std::string& tosplit, const std::string& token, bool splitAtAllChars) {
131 int beg = 0;
132 int len = (int)token.length();
133 if (splitAtAllChars) {
134 len = 1;
135 }
136 while (beg < (int)tosplit.length()) {
137 std::string::size_type end;
138 if (splitAtAllChars) {
139 end = tosplit.find_first_of(token, beg);
140 } else {
141 end = tosplit.find(token, beg);
142 }
143 if (end == std::string::npos) {
144 end = tosplit.length();
145 }
146 myStarts.push_back(beg);
147 myLengths.push_back((int)end - beg);
148 beg = (int)end + len;
149 if (beg == (int)tosplit.length()) {
150 myStarts.push_back(beg - 1);
151 myLengths.push_back(0);
152 }
153 }
154 }
155
prepareWhitechar(const std::string & tosplit)156 void StringTokenizer::prepareWhitechar(const std::string& tosplit) {
157 std::string::size_type len = tosplit.length();
158 std::string::size_type beg = 0;
159 while (beg < len && tosplit[beg] <= SPACE) {
160 beg++;
161 }
162 while (beg != std::string::npos && beg < len) {
163 std::string::size_type end = beg;
164 while (end < len && tosplit[end] > SPACE) {
165 end++;
166 }
167 myStarts.push_back((int)beg);
168 myLengths.push_back((int)end - (int)beg);
169 beg = end;
170 while (beg < len && tosplit[beg] <= SPACE) {
171 beg++;
172 }
173 }
174 }
175
176
177 std::vector<std::string>
getVector()178 StringTokenizer::getVector() {
179 std::vector<std::string> ret;
180 ret.reserve(size());
181 while (hasNext()) {
182 ret.push_back(next());
183 }
184 reinit();
185 return ret;
186 }
187
188
189 /****************************************************************************/
190