Deleted Added
sdiff udiff text old ( 10447:a465576671d4 ) new ( 10448:bc1a3b7ab5ef )
full compact
1/* Copyright (c) 2012 Massachusetts Institute of Technology
2 *
3 * Permission is hereby granted, free of charge, to any person obtaining a copy
4 * of this software and associated documentation files (the "Software"), to deal
5 * in the Software without restriction, including without limitation the rights
6 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 * copies of the Software, and to permit persons to whom the Software is
8 * furnished to do so, subject to the following conditions:
9 *
10 * The above copyright notice and this permission notice shall be included in
11 * all copies or substantial portions of the Software.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 * THE SOFTWARE.
20 */
21
22#include "String.h"
23
24#include <cstdarg>
25#include <cstdio>
26#include <iostream>
27#include <ios>
28
29namespace LibUtil
30{
31 const unsigned int String::msBufferSize = 4096;
32
33 String String::format(const String& format_, ...)
34 {
35 char buffer[msBufferSize];
36
37 va_list args;
38 va_start(args, format_);
39 vsnprintf(buffer, msBufferSize, format_.c_str(), args);
40 va_end(args);
41
42 return (String)(buffer);
43 }
44
45 String String::format(const String& format_, va_list args_)
46 {
47 char buffer[msBufferSize];
48
49 vsnprintf(buffer, msBufferSize, format_.c_str(), args_);
50
51 return (String)(buffer);
52 }
53
54 String::String()
55 {}
56
57 String::String(const string& str_)
58 : string(str_)
59 {}
60
61 String::String(const char* str_, size_t n_)
62 : string(str_, n_)
63 {}
64
65 String::String(const char* str_)
66 : string(str_)
67 {}
68
69 String::String(size_t n_, char c_)
70 : string(n_, c_)
71 {}
72
73 String::String(int value_)
74 : string(toString<int>(value_))
75 {}
76
77 String::String(unsigned int value_)
78 : string(toString<unsigned int>(value_))
79 {}
80
81 String::String(long value_)
82 : string(toString<long>(value_))
83 {}
84
85 String::String(unsigned long value_)
86 : string(toString<unsigned long>(value_))
87 {}
88
89 String::String(float value_)
90 : string(toString<float>(value_))
91 {}
92
93 String::String(double value_)
94 : string(toString<double>(value_))
95 {}
96
97 String::String(bool value_)
98 : string(toString<bool>(value_))
99 {}
100
101 String::~String()
102 {}
103
104 String& String::trim()
105 {
106 // Remove leading and trailing whitespace
107 static const char whitespace[] = " \n\t\v\r\f";
108 erase(0, find_first_not_of(whitespace));
109 erase(find_last_not_of(whitespace) + 1U);
110 return (*this);
111 }
112
113 String& String::substitute(const String& str1_, const String& str2_)
114 {
115 size_t str1Size = str1_.size();
116 size_t str2Size = str2_.size();
117
118 size_t pos;
119 pos = find(str1_);
120 while(pos != string::npos)
121 {
122 replace(pos, str1Size, str2_);
123 pos += str2Size;
124 pos = find(str1_, pos);
125 }
126 return (*this);
127 }
128
129 vector<String> String::split(const char* delimiters_) const
130 {
131 vector<String> result;
132
133 if(size() == 0)
134 {
135 return result;
136 }
137
138 size_t currPos, nextPos;
139 currPos = 0;
140 nextPos = find_first_of(delimiters_);
141 while(1)
142 {
143 if(nextPos == string::npos)
144 {
145 if(currPos != size())
146 {
147 result.push_back(substr(currPos));
148 }
149 break;
150 }
151
152 if(nextPos != currPos)
153 {
154 result.push_back(substr(currPos, nextPos - currPos));
155 }
156 currPos = nextPos + 1;
157 nextPos = find_first_of(delimiters_, currPos);
158 }
159
160 return result;
161 }
162
163 vector<String> String::split(const String* delimiters_, unsigned int num_delimiters_) const
164 {
165 vector<String> result;
166
167 if(size() == 0)
168 {
169 return result;
170 }
171
172 if(num_delimiters_ == 1)
173 {
174 size_t currPos, nextPos;
175 currPos = 0;
176 nextPos = find(delimiters_[0]);
177 while(1)
178 {
179 if(nextPos == String::npos)
180 {
181 result.push_back(substr(currPos));
182 break;
183 }
184
185 if(nextPos != currPos)
186 {
187 result.push_back(substr(currPos, nextPos - currPos));
188 }
189 currPos = nextPos + delimiters_[0].size();
190 nextPos = find(delimiters_[0], currPos);
191 }
192 }
193 else
194 {
195 // Currently the length of the delimiters are not checked
196 unsigned int delimiterLength = 0;
197 size_t currPos, nextPos;
198 currPos = 0;
199 nextPos = size();
200 for(unsigned int i = 0; i < num_delimiters_; ++i)
201 {
202 size_t tempPos = find(delimiters_[i], currPos);
203 if((tempPos != String::npos) && (tempPos < nextPos))
204 {
205 nextPos = tempPos;
206 delimiterLength = delimiters_[i].size();
207 }
208 }
209 while(1)
210 {
211 if((nextPos == String::npos) || (nextPos == size()))
212 {
213 result.push_back(substr(currPos));
214 break;
215 }
216
217 if(nextPos != currPos)
218 {
219 result.push_back(substr(currPos, nextPos - currPos));
220 }
221 currPos = nextPos + delimiterLength;
222 nextPos = size();
223 delimiterLength = 0;
224 for(unsigned int i = 0; i < num_delimiters_; ++i)
225 {
226 size_t tempPos = find(delimiters_[i], currPos);
227 if((tempPos != String::npos) && (tempPos < nextPos))
228 {
229 nextPos = tempPos;
230 delimiterLength = delimiters_[i].size();
231 }
232 }
233 }
234 }
235 return result;
236 }
237
238 vector<String> String::splitByString(const String& delimiter_) const
239 {
240 return split(&delimiter_, 1);
241 }
242
243 bool String::contain(const String& str_) const
244 {
245 return (find(str_) != String::npos);
246 }
247
248 const char* String::toCString() const
249 {
250 return this->c_str();
251 }
252
253 int String::toInt() const
254 {
255 return fromString<int>(*this);
256 }
257
258 unsigned int String::toUInt() const
259 {
260 return fromString<unsigned int>(*this);
261 }
262
263 long String::toLong() const
264 {
265 return fromString<long>(*this);
266 }
267
268 unsigned long String::toULong() const
269 {
270 return fromString<unsigned long>(*this);
271 }
272
273 float String::toFloat() const
274 {
275 return fromString<float>(*this);
276 }
277
278 double String::toDouble() const
279 {
280 return fromString<double>(*this);
281 }
282
283 bool String::toBool() const
284 {
285 return fromString<bool>(*this);
286 }
287
288 String::operator const char*() const
289 {
290 return this->c_str();
291 }
292
293 String::operator int() const
294 {
295 return fromString<int>(*this);
296 }
297
298 String::operator unsigned int() const
299 {
300 return fromString<unsigned int>(*this);
301 }
302
303 String::operator long() const
304 {
305 return fromString<long>(*this);
306 }
307
308 String::operator unsigned long() const
309 {
310 return fromString<unsigned long>(*this);
311 }
312
313 String::operator float() const
314 {
315 return fromString<float>(*this);
316 }
317
318 String::operator double() const
319 {
320 return fromString<double>(*this);
321 }
322
323 String::operator bool() const
324 {
325 return fromString<bool>(*this);
326 }
327
328 String& String::operator=(char c_)
329 {
330 this->assign(1, c_);
331 return *this;
332 }
333
334 std::istream& safeGetline(std::istream& is_, String& str_)
335 {
336 str_.clear();
337
338 // The characters in the stream are read one-by-one using a std::streambuf.
339 // That is faster than reading them one-by-one using the std::istream.
340 // Code that uses streambuf this way must be guarded by a sentry object.
341 // The sentry object performs various tasks,
342 // such as thread synchronization and updating the stream state.
343
344 std::istream::sentry se(is_, true);
345 std::streambuf* sb = is_.rdbuf();
346
347 while(1)
348 {
349 int c = sb->sbumpc();
350 switch(c)
351 {
352 case '\r':
353 c = sb->sgetc();
354 if(c == '\n')
355 sb->sbumpc();
356 return is_;
357 case '\n':
358 return is_;
359 case EOF:
360 is_.setstate(std::ios_base::failbit|std::ios_base::eofbit);
361 return is_;
362 default:
363 str_ += String(1, (char)c);
364 }
365 }
366 }
367} // namespace LibUtil
368