source: XMLIO_V2/external/include/Poco/String.h @ 80

Last change on this file since 80 was 80, checked in by ymipsl, 14 years ago

ajout lib externe

  • Property svn:eol-style set to native
File size: 14.8 KB
Line 
1//
2// String.h
3//
4// $Id: //poco/1.3/Foundation/include/Poco/String.h#5 $
5//
6// Library: Foundation
7// Package: Core
8// Module:  String
9//
10// String utility functions.
11//
12// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
13// and Contributors.
14//
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:
21//
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.
28//
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.
36//
37
38
39#ifndef Foundation_String_INCLUDED
40#define Foundation_String_INCLUDED
41
42
43#include "Poco/Foundation.h"
44#include <cstring>
45#include <cctype>
46
47
48namespace Poco {
49
50
51template <class S>
52S trimLeft(const S& str)
53        /// Returns a copy of str with all leading
54        /// whitespace removed.
55{
56        typename S::const_iterator it  = str.begin();
57        typename S::const_iterator end = str.end();
58       
59        while (it != end && std::isspace(*it)) ++it;
60        return S(it, end);
61}
62
63
64template <class S>
65S& trimLeftInPlace(S& str)
66        /// Removes all leading whitespace in str.
67{
68        typename S::iterator it  = str.begin();
69        typename S::iterator end = str.end();
70       
71        while (it != end && std::isspace(*it)) ++it;
72        str.erase(str.begin(), it);
73        return str;
74}
75
76
77template <class S>
78S trimRight(const S& str)
79        /// Returns a copy of str with all trailing
80        /// whitespace removed.
81{
82        int pos = int(str.size()) - 1;
83               
84        while (pos >= 0 && std::isspace(str[pos])) --pos;
85        return S(str, 0, pos + 1);
86}
87
88
89template <class S>
90S& trimRightInPlace(S& str)
91        /// Removes all trailing whitespace in str.
92{
93        int pos = int(str.size()) - 1;
94               
95        while (pos >= 0 && std::isspace(str[pos])) --pos;
96        str.resize(pos + 1);
97
98        return str;
99}
100
101
102template <class S>
103S trim(const S& str)
104        /// Returns a copy of str with all leading and
105        /// trailing whitespace removed.
106{
107        int first = 0;
108        int last  = int(str.size()) - 1;
109       
110        while (first <= last && std::isspace(str[first])) ++first;
111        while (last >= first && std::isspace(str[last])) --last;
112
113        return S(str, first, last - first + 1);
114}
115
116
117template <class S>
118S& trimInPlace(S& str)
119        /// Removes all leading and trailing whitespace in str.
120{
121        int first = 0;
122        int last  = int(str.size()) - 1;
123       
124        while (first <= last && std::isspace(str[first])) ++first;
125        while (last >= first && std::isspace(str[last])) --last;
126
127        str.resize(last + 1);
128        str.erase(0, first);
129
130        return str;
131}
132
133
134template <class S>
135S toUpper(const S& str)
136        /// Returns a copy of str containing all upper-case characters.
137{
138        typename S::const_iterator it  = str.begin();
139        typename S::const_iterator end = str.end();
140
141        S result;
142        result.reserve(str.size());
143        while (it != end) result += std::toupper(*it++);
144        return result;
145}
146
147
148template <class S>
149S& toUpperInPlace(S& str)
150        /// Replaces all characters in str with their upper-case counterparts.
151{
152        typename S::iterator it  = str.begin();
153        typename S::iterator end = str.end();
154
155        while (it != end) { *it = std::toupper(*it); ++it; }
156        return str;
157}
158
159
160template <class S>
161S toLower(const S& str)
162        /// Returns a copy of str containing all lower-case characters.
163{
164        typename S::const_iterator it  = str.begin();
165        typename S::const_iterator end = str.end();
166
167        S result;
168        result.reserve(str.size());
169        while (it != end) result += std::tolower(*it++);
170        return result;
171}
172
173
174template <class S>
175S& toLowerInPlace(S& str)
176        /// Replaces all characters in str with their lower-case counterparts.
177{
178        typename S::iterator it  = str.begin();
179        typename S::iterator end = str.end();
180
181        while (it != end) { *it = std::tolower(*it); ++it; }
182        return str;
183}
184
185
186#if !defined(POCO_NO_TEMPLATE_ICOMPARE)
187
188
189template <class S, class It>
190int icompare(
191        const S& str,
192        typename S::size_type pos, 
193        typename S::size_type n,
194        It it2, 
195        It end2)
196        /// Case-insensitive string comparison
197{
198        typename S::size_type sz = str.size();
199        if (pos > sz) pos = sz;
200        if (pos + n > sz) n = sz - pos;
201        It it1  = str.begin() + pos; 
202        It end1 = str.begin() + pos + n;
203        while (it1 != end1 && it2 != end2)
204        {
205        typename S::value_type c1(std::tolower(*it1));
206        typename S::value_type c2(std::tolower(*it2));
207        if (c1 < c2)
208            return -1;
209        else if (c1 > c2)
210            return 1;
211        ++it1; ++it2;
212        }
213   
214    if (it1 == end1)
215                return it2 == end2 ? 0 : -1;
216    else
217        return 1;
218}
219
220
221template <class S>
222int icompare(const S& str1, const S& str2)
223        // A special optimization for an often used case.
224{
225        typename S::const_iterator it1(str1.begin());
226        typename S::const_iterator end1(str1.end());
227        typename S::const_iterator it2(str2.begin());
228        typename S::const_iterator end2(str2.end());
229        while (it1 != end1 && it2 != end2)
230        {
231        typename S::value_type c1(std::tolower(*it1));
232        typename S::value_type c2(std::tolower(*it2));
233        if (c1 < c2)
234            return -1;
235        else if (c1 > c2)
236            return 1;
237        ++it1; ++it2;
238        }
239   
240    if (it1 == end1)
241                return it2 == end2 ? 0 : -1;
242    else
243        return 1;
244}
245
246
247template <class S>
248int icompare(const S& str1, typename S::size_type n1, const S& str2, typename S::size_type n2)
249{
250        if (n2 > str2.size()) n2 = str2.size();
251        return icompare(str1, 0, n1, str2.begin(), str2.begin() + n2);
252}
253
254
255template <class S>
256int icompare(const S& str1, typename S::size_type n, const S& str2)
257{
258        if (n > str2.size()) n = str2.size();
259        return icompare(str1, 0, n, str2.begin(), str2.begin() + n);
260}
261
262
263template <class S>
264int icompare(const S& str1, typename S::size_type pos, typename S::size_type n, const S& str2)
265{
266        return icompare(str1, pos, n, str2.begin(), str2.end());
267}
268
269
270template <class S>
271int icompare(
272        const S& str1, 
273        typename S::size_type pos1, 
274        typename S::size_type n1, 
275        const S& str2,
276        typename S::size_type pos2,
277        typename S::size_type n2)
278{
279        typename S::size_type sz2 = str2.size();
280        if (pos2 > sz2) pos2 = sz2;
281        if (pos2 + n2 > sz2) n2 = sz2 - pos2;
282        return icompare(str1, pos1, n1, str2.begin() + pos2, str2.begin() + pos2 + n2);
283}
284
285
286template <class S>
287int icompare(
288        const S& str1, 
289        typename S::size_type pos1, 
290        typename S::size_type n, 
291        const S& str2,
292        typename S::size_type pos2)
293{
294        typename S::size_type sz2 = str2.size();
295        if (pos2 > sz2) pos2 = sz2;
296        if (pos2 + n > sz2) n = sz2 - pos2;
297        return icompare(str1, pos1, n, str2.begin() + pos2, str2.begin() + pos2 + n);
298}
299
300
301template <class S>
302int icompare(
303        const S& str,
304        typename S::size_type pos,
305        typename S::size_type n,
306        const typename S::value_type* ptr)
307{
308        poco_check_ptr (ptr);
309        typename S::size_type sz = str.size();
310        if (pos > sz) pos = sz;
311        if (pos + n > sz) n = sz - pos;
312        typename S::const_iterator it  = str.begin() + pos; 
313        typename S::const_iterator end = str.begin() + pos + n;
314        while (it != end && *ptr)
315        {
316        typename S::value_type c1(std::tolower(*it));
317        typename S::value_type c2(std::tolower(*ptr));
318        if (c1 < c2)
319            return -1;
320        else if (c1 > c2)
321            return 1;
322        ++it; ++ptr;
323        }
324   
325    if (it == end)
326                return *ptr == 0 ? 0 : -1;
327    else
328        return 1;
329}
330
331
332template <class S>
333int icompare(
334        const S& str,
335        typename S::size_type pos,
336        const typename S::value_type* ptr)
337{
338        return icompare(str, pos, str.size() - pos, ptr);
339}
340
341
342template <class S>
343int icompare(
344        const S& str,
345        const typename S::value_type* ptr)
346{
347        return icompare(str, 0, str.size(), ptr);
348}
349
350
351#else
352
353
354int 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);
355int Foundation_API icompare(const std::string& str1, const std::string& str2);
356int Foundation_API icompare(const std::string& str1, std::string::size_type n1, const std::string& str2, std::string::size_type n2);
357int Foundation_API icompare(const std::string& str1, std::string::size_type n, const std::string& str2);
358int Foundation_API icompare(const std::string& str1, std::string::size_type pos, std::string::size_type n, const std::string& str2);
359int 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);
360int 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);
361int Foundation_API icompare(const std::string& str, std::string::size_type pos, std::string::size_type n, const std::string::value_type* ptr);
362int Foundation_API icompare(const std::string& str, std::string::size_type pos, const std::string::value_type* ptr);
363int Foundation_API icompare(const std::string& str, const std::string::value_type* ptr);
364
365
366#endif
367
368
369template <class S>
370S translate(const S& str, const S& from, const S& to)
371        /// Returns a copy of str with all characters in
372        /// from replaced by the corresponding (by position)
373        /// characters in to. If there is no corresponding
374        /// character in to, the character is removed from
375        /// the copy.
376{
377        S result;
378        result.reserve(str.size());
379        typename S::const_iterator it  = str.begin();
380        typename S::const_iterator end = str.end();
381        typename S::size_type toSize = to.size();
382        while (it != end)
383        {
384                typename S::size_type pos = from.find(*it);
385                if (pos == S::npos)
386                {
387                        result += *it;
388                }
389                else
390                {
391                        if (pos < toSize) result += to[pos];
392                }
393                ++it;
394        }
395        return result;
396}
397
398
399template <class S>
400S translate(const S& str, const typename S::value_type* from, const typename S::value_type* to)
401{
402        poco_check_ptr (from);
403        poco_check_ptr (to);
404        return translate(str, S(from), S(to));
405}
406
407
408template <class S>
409S& translateInPlace(S& str, const S& from, const S& to)
410        /// Replaces in str all occurences of characters in from
411        /// with the corresponding (by position) characters in to.
412        /// If there is no corresponding character, the character
413        /// is removed.
414{
415        str = translate(str, from, to);
416        return str;
417}
418
419
420template <class S>
421S translateInPlace(S& str, const typename S::value_type* from, const typename S::value_type* to)
422{
423        poco_check_ptr (from);
424        poco_check_ptr (to);
425        str = translate(str, S(from), S(to));
426        return str;
427}
428
429
430#if !defined(POCO_NO_TEMPLATE_ICOMPARE)
431
432
433template <class S>
434S replace(const S& str, const S& from, const S& to, typename S::size_type start = 0)
435        /// Replace all occurences of from (which must not be the empty string)
436        /// in str with to, starting at position start.
437{
438        S result(str);
439        replaceInPlace(result, from, to, start);
440        return result;
441}
442
443
444template <class S>
445S replace(const S& str, const typename S::value_type* from, const typename S::value_type* to, typename S::size_type start = 0)
446{
447        S result(str);
448        replaceInPlace(result, from, to, start);
449        return result;
450}
451
452
453template <class S>
454S& replaceInPlace(S& str, const S& from, const S& to, typename S::size_type start = 0)
455{
456        poco_assert (from.size() > 0);
457       
458        S result;
459        typename S::size_type pos = 0;
460        result.append(str, 0, start);
461        do
462        {
463                pos = str.find(from, start);
464                if (pos != S::npos)
465                {
466                        result.append(str, start, pos - start);
467                        result.append(to);
468                        start = pos + from.length();
469                }
470                else result.append(str, start, str.size() - start);
471        }
472        while (pos != S::npos);
473        str.swap(result);
474        return str;
475}
476
477
478template <class S>
479S& replaceInPlace(S& str, const typename S::value_type* from, const typename S::value_type* to, typename S::size_type start = 0)
480{
481        poco_assert (*from);
482
483        S result;
484        typename S::size_type pos = 0;
485        typename S::size_type fromLen = std::strlen(from);
486        result.append(str, 0, start);
487        do
488        {
489                pos = str.find(from, start);
490                if (pos != S::npos)
491                {
492                        result.append(str, start, pos - start);
493                        result.append(to);
494                        start = pos + fromLen;
495                }
496                else result.append(str, start, str.size() - start);
497        }
498        while (pos != S::npos);
499        str.swap(result);
500        return str;
501}
502
503
504#else
505
506
507std::string Foundation_API replace(const std::string& str, const std::string& from, const std::string& to, std::string::size_type start = 0);
508std::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);
509std::string& Foundation_API replaceInPlace(std::string& str, const std::string& from, const std::string& to, std::string::size_type start = 0);
510std::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);
511       
512
513#endif 
514
515
516template <class S>
517S cat(const S& s1, const S& s2)
518        /// Concatenates two strings.
519{
520        S result = s1;
521        result.reserve(s1.size() + s2.size());
522        result.append(s2);
523        return result;
524}
525
526
527template <class S>
528S cat(const S& s1, const S& s2, const S& s3)
529        /// Concatenates three strings.
530{
531        S result = s1;
532        result.reserve(s1.size() + s2.size() + s3.size());
533        result.append(s2);
534        result.append(s3);
535        return result;
536}
537
538
539template <class S>
540S cat(const S& s1, const S& s2, const S& s3, const S& s4)
541        /// Concatenates four strings.
542{
543        S result = s1;
544        result.reserve(s1.size() + s2.size() + s3.size() + s4.size());
545        result.append(s2);
546        result.append(s3);
547        result.append(s4);
548        return result;
549}
550
551
552template <class S>
553S cat(const S& s1, const S& s2, const S& s3, const S& s4, const S& s5)
554        /// Concatenates five strings.
555{
556        S result = s1;
557        result.reserve(s1.size() + s2.size() + s3.size() + s4.size() + s5.size());
558        result.append(s2);
559        result.append(s3);
560        result.append(s4);
561        result.append(s5);
562        return result;
563}
564
565
566template <class S>
567S cat(const S& s1, const S& s2, const S& s3, const S& s4, const S& s5, const S& s6)
568        /// Concatenates six strings.
569{
570        S result = s1;
571        result.reserve(s1.size() + s2.size() + s3.size() + s4.size() + s5.size() + s6.size());
572        result.append(s2);
573        result.append(s3);
574        result.append(s4);
575        result.append(s5);
576        result.append(s6);
577        return result;
578}
579
580
581template <class S, class It>
582S cat(const S& delim, const It& begin, const It& end)
583        /// Concatenates a sequence of strings, delimited
584        /// by the string given in delim.
585{
586        S result;
587        for (It it = begin; it != end; ++it)
588        {
589                if (!result.empty()) result.append(delim);
590                result += *it;
591        }
592        return result;
593}
594
595
596} // namespace Poco
597
598
599#endif // Foundation_String_INCLUDED
Note: See TracBrowser for help on using the repository browser.