4
// $Id: //poco/1.2/Foundation/include/Poco/String.h#2 $
10
// String utility functions.
12
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
15
// Permission is hereby granted, free of charge, to any person or organization
16
// obtaining a copy of the software and accompanying documentation covered by
17
// this license (the "Software") to use, reproduce, display, distribute,
18
// execute, and transmit the Software, and to prepare derivative works of the
19
// Software, and to permit third-parties to whom the Software is furnished to
20
// do so, all subject to the following:
22
// The copyright notices in the Software and this entire statement, including
23
// the above license grant, this restriction and the following disclaimer,
24
// must be included in all copies of the Software, in whole or in part, and
25
// all derivative works of the Software, unless such copies or derivative
26
// works are solely in the form of machine-executable object code generated by
27
// a source language processor.
29
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
30
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
31
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
32
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
33
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
34
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
35
// DEALINGS IN THE SOFTWARE.
39
#ifndef Foundation_String_INCLUDED
40
#define Foundation_String_INCLUDED
43
#include "Poco/Foundation.h"
52
S trimLeft(const S& str)
53
/// Returns a copy of str with all leading
54
/// whitespace removed.
57
typename S::const_iterator it = str.begin();
58
typename S::const_iterator end = str.end();
60
while (it != end && isspace(*it, loc)) ++it;
66
S& trimLeftInPlace(S& str)
67
/// Removes all leading whitespace in str.
70
typename S::iterator it = str.begin();
71
typename S::iterator end = str.end();
73
while (it != end && isspace(*it, loc)) ++it;
74
str.erase(str.begin(), it);
80
S trimRight(const S& str)
81
/// Returns a copy of str with all trailing
82
/// whitespace removed.
85
int pos = int(str.size()) - 1;
87
while (pos >= 0 && isspace(str[pos], loc)) --pos;
88
return S(str, 0, pos + 1);
93
S& trimRightInPlace(S& str)
94
/// Removes all trailing whitespace in str.
97
int pos = int(str.size()) - 1;
99
while (pos >= 0 && isspace(str[pos], loc)) --pos;
108
/// Returns a copy of str with all leading and
109
/// trailing whitespace removed.
113
int last = int(str.size()) - 1;
115
while (first <= last && isspace(str[first], loc)) ++first;
116
while (last >= first && isspace(str[last], loc)) --last;
118
return S(str, first, last - first + 1);
123
S& trimInPlace(S& str)
124
/// Removes all leading and trailing whitespace in str.
128
int last = int(str.size()) - 1;
130
while (first <= last && isspace(str[first], loc)) ++first;
131
while (last >= first && isspace(str[last], loc)) --last;
133
str.resize(last + 1);
141
S toUpper(const S& str)
142
/// Returns a copy of str containing all upper-case characters.
145
typename S::const_iterator it = str.begin();
146
typename S::const_iterator end = str.end();
149
result.reserve(str.size());
150
while (it != end) result += toupper(*it++, loc);
156
S& toUpperInPlace(S& str)
157
/// Replaces all characters in str with their upper-case counterparts.
160
typename S::iterator it = str.begin();
161
typename S::iterator end = str.end();
163
while (it != end) { *it = toupper(*it, loc); ++it; }
169
S toLower(const S& str)
170
/// Returns a copy of str containing all lower-case characters.
173
typename S::const_iterator it = str.begin();
174
typename S::const_iterator end = str.end();
177
result.reserve(str.size());
178
while (it != end) result += tolower(*it++, loc);
184
S& toLowerInPlace(S& str)
185
/// Replaces all characters in str with their lower-case counterparts.
188
typename S::iterator it = str.begin();
189
typename S::iterator end = str.end();
191
while (it != end) { *it = tolower(*it, loc); ++it; }
196
#if !defined(POCO_NO_TEMPLATE_ICOMPARE)
199
template <class S, class It>
202
typename S::size_type pos,
203
typename S::size_type n,
206
/// Case-insensitive string comparison
208
typename S::size_type sz = str.size();
209
if (pos > sz) pos = sz;
210
if (pos + n > sz) n = sz - pos;
211
It it1 = str.begin() + pos;
212
It end1 = str.begin() + pos + n;
214
while (it1 != end1 && it2 != end2)
216
typename S::value_type c1 = tolower(*it1, loc);
217
typename S::value_type c2 = tolower(*it2, loc);
226
return it2 == end2 ? 0 : -1;
233
int icompare(const S& str1, const S& str2)
235
return icompare(str1, 0, str1.size(), str2.begin(), str2.end());
240
int icompare(const S& str1, typename S::size_type n1, const S& str2, typename S::size_type n2)
242
if (n2 > str2.size()) n2 = str2.size();
243
return icompare(str1, 0, n1, str2.begin(), str2.begin() + n2);
248
int icompare(const S& str1, typename S::size_type n, const S& str2)
250
if (n > str2.size()) n = str2.size();
251
return icompare(str1, 0, n, str2.begin(), str2.begin() + n);
256
int icompare(const S& str1, typename S::size_type pos, typename S::size_type n, const S& str2)
258
return icompare(str1, pos, n, str2.begin(), str2.end());
265
typename S::size_type pos1,
266
typename S::size_type n1,
268
typename S::size_type pos2,
269
typename S::size_type n2)
271
typename S::size_type sz2 = str2.size();
272
if (pos2 > sz2) pos2 = sz2;
273
if (pos2 + n2 > sz2) n2 = sz2 - pos2;
274
return icompare(str1, pos1, n1, str2.begin() + pos2, str2.begin() + pos2 + n2);
281
typename S::size_type pos1,
282
typename S::size_type n,
284
typename S::size_type pos2)
286
typename S::size_type sz2 = str2.size();
287
if (pos2 > sz2) pos2 = sz2;
288
if (pos2 + n > sz2) n = sz2 - pos2;
289
return icompare(str1, pos1, n, str2.begin() + pos2, str2.begin() + pos2 + n);
296
typename S::size_type pos,
297
typename S::size_type n,
298
const typename S::value_type* ptr)
300
poco_check_ptr (ptr);
301
typename S::size_type sz = str.size();
302
if (pos > sz) pos = sz;
303
if (pos + n > sz) n = sz - pos;
304
typename S::const_iterator it = str.begin() + pos;
305
typename S::const_iterator end = str.begin() + pos + n;
307
while (it != end && *ptr)
309
typename S::value_type c1 = tolower(*it, loc);
310
typename S::value_type c2 = tolower(*ptr, loc);
319
return *ptr == 0 ? 0 : -1;
328
typename S::size_type pos,
329
const typename S::value_type* ptr)
331
return icompare(str, pos, str.size() - pos, ptr);
338
const typename S::value_type* ptr)
340
return icompare(str, 0, str.size(), ptr);
347
int Foundation_API icompare(const std::string& str, std::string::size_type pos, std::string::size_type n, std::string::const_iterator it2, std::string::const_iterator end2);
348
int Foundation_API icompare(const std::string& str1, const std::string& str2);
349
int Foundation_API icompare(const std::string& str1, std::string::size_type n1, const std::string& str2, std::string::size_type n2);
350
int Foundation_API icompare(const std::string& str1, std::string::size_type n, const std::string& str2);
351
int Foundation_API icompare(const std::string& str1, std::string::size_type pos, std::string::size_type n, const std::string& str2);
352
int Foundation_API icompare(const std::string& str1, std::string::size_type pos1, std::string::size_type n1, const std::string& str2, std::string::size_type pos2, std::string::size_type n2);
353
int Foundation_API icompare(const std::string& str1, std::string::size_type pos1, std::string::size_type n, const std::string& str2, std::string::size_type pos2);
354
int Foundation_API icompare(const std::string& str, std::string::size_type pos, std::string::size_type n, const std::string::value_type* ptr);
355
int Foundation_API icompare(const std::string& str, std::string::size_type pos, const std::string::value_type* ptr);
356
int Foundation_API icompare(const std::string& str, const std::string::value_type* ptr);
363
S translate(const S& str, const S& from, const S& to)
364
/// Returns a copy of str with all characters in
365
/// from replaced by the corresponding (by position)
366
/// characters in to. If there is no corresponding
367
/// character in to, the character is removed from
371
result.reserve(str.size());
372
typename S::const_iterator it = str.begin();
373
typename S::const_iterator end = str.end();
374
typename S::size_type toSize = to.size();
377
typename S::size_type pos = from.find(*it);
384
if (pos < toSize) result += to[pos];
393
S translate(const S& str, const typename S::value_type* from, const typename S::value_type* to)
395
poco_check_ptr (from);
397
return translate(str, S(from), S(to));
402
S& translateInPlace(S& str, const S& from, const S& to)
403
/// Replaces in str all occurences of characters in from
404
/// with the corresponding (by position) characters in to.
405
/// If there is no corresponding character, the character
408
str = translate(str, from, to);
414
S translateInPlace(S& str, const typename S::value_type* from, const typename S::value_type* to)
416
poco_check_ptr (from);
418
str = translate(str, S(from), S(to));
423
#if !defined(POCO_NO_TEMPLATE_ICOMPARE)
427
S replace(const S& str, const S& from, const S& to, typename S::size_type start = 0)
428
/// Replace all occurences of from (which must not be the empty string)
429
/// in str with to, starting at position start.
432
replaceInPlace(result, from, to, start);
438
S replace(const S& str, const typename S::value_type* from, const typename S::value_type* to, typename S::size_type start = 0)
441
replaceInPlace(result, from, to, start);
447
S& replaceInPlace(S& str, const S& from, const S& to, typename S::size_type start = 0)
449
poco_assert (from.size() > 0);
452
typename S::size_type pos = 0;
453
result.append(str, 0, start);
456
pos = str.find(from, start);
459
result.append(str, start, pos - start);
461
start = pos + from.length();
463
else result.append(str, start, str.size() - start);
465
while (pos != S::npos);
472
S& replaceInPlace(S& str, const typename S::value_type* from, const typename S::value_type* to, typename S::size_type start = 0)
477
typename S::size_type pos = 0;
478
typename S::size_type fromLen = strlen(from);
479
result.append(str, 0, start);
482
pos = str.find(from, start);
485
result.append(str, start, pos - start);
487
start = pos + fromLen;
489
else result.append(str, start, str.size() - start);
491
while (pos != S::npos);
500
std::string Foundation_API replace(const std::string& str, const std::string& from, const std::string& to, std::string::size_type start = 0);
501
std::string Foundation_API replace(const std::string& str, const std::string::value_type* from, const std::string::value_type* to, std::string::size_type start = 0);
502
std::string& Foundation_API replaceInPlace(std::string& str, const std::string& from, const std::string& to, std::string::size_type start = 0);
503
std::string& Foundation_API replaceInPlace(std::string& str, const std::string::value_type* from, const std::string::value_type* to, std::string::size_type start = 0);
510
S cat(const S& s1, const S& s2)
511
/// Concatenates two strings.
514
result.reserve(s1.size() + s2.size());
521
S cat(const S& s1, const S& s2, const S& s3)
522
/// Concatenates three strings.
525
result.reserve(s1.size() + s2.size() + s3.size());
533
S cat(const S& s1, const S& s2, const S& s3, const S& s4)
534
/// Concatenates four strings.
537
result.reserve(s1.size() + s2.size() + s3.size() + s4.size());
546
S cat(const S& s1, const S& s2, const S& s3, const S& s4, const S& s5)
547
/// Concatenates five strings.
550
result.reserve(s1.size() + s2.size() + s3.size() + s4.size() + s5.size());
560
S cat(const S& s1, const S& s2, const S& s3, const S& s4, const S& s5, const S& s6)
561
/// Concatenates six strings.
564
result.reserve(s1.size() + s2.size() + s3.size() + s4.size() + s5.size() + s6.size());
574
template <class S, class It>
575
S cat(const S& delim, const It& begin, const It& end)
576
/// Concatenates a sequence of strings, delimited
577
/// by the string given in delim.
580
for (It it = begin; it != end; ++it)
582
if (!result.empty()) result.append(delim);
592
#endif // Foundation_String_INCLUDED