source: nscp/include/strEx.h @ d5356c1

0.4.00.4.10.4.2
Last change on this file since d5356c1 was d5356c1, checked in by Michael Medin <michael@…>, 4 years ago

tried boost::asio in the NRPECLient and split settings to a new file (reduces build time)

  • Property mode set to 100644
File size: 20.6 KB
Line 
1/**************************************************************************
2*   Copyright (C) 2004-2007 by Michael Medin <michael@medin.name>         *
3*                                                                         *
4*   This code is part of NSClient++ - http://trac.nakednuns.org/nscp      *
5*                                                                         *
6*   This program is free software; you can redistribute it and/or modify  *
7*   it under the terms of the GNU General Public License as published by  *
8*   the Free Software Foundation; either version 2 of the License, or     *
9*   (at your option) any later version.                                   *
10*                                                                         *
11*   This program is distributed in the hope that it will be useful,       *
12*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
13*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
14*   GNU General Public License for more details.                          *
15*                                                                         *
16*   You should have received a copy of the GNU General Public License     *
17*   along with this program; if not, write to the                         *
18*   Free Software Foundation, Inc.,                                       *
19*   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
20***************************************************************************/
21#pragma once
22
23#include <tchar.h>
24#include <windows.h>
25#include <sstream>
26#include <iomanip>
27#include <string>
28#include <utility>
29#include <list>
30#include <functional>
31#include <time.h>
32#include <algorithm>
33#include <locale>
34
35
36#ifdef _DEBUG
37#include <iostream>
38#endif
39
40namespace strEx {
41        class string_exception : public std::exception {
42                std::wstring _what;
43        public:
44                string_exception(std::wstring what) : _what(what) {}
45                std::wstring what() {
46                        return _what;
47                }
48        };
49        namespace s {
50                inline std::string itos(float i) {
51                        std::stringstream ss;
52                        ss << i;
53                        return ss.str();
54                }
55                inline std::string itos(int i) {
56                        std::stringstream ss;
57                        ss << i;
58                        return ss.str();
59                }
60                inline std::string itos(unsigned int i) {
61                        std::stringstream ss;
62                        ss << i;
63                        return ss.str();
64                }
65        }
66
67        inline void append_list(std::wstring &lst, std::wstring &append, std::wstring sep = _T(", ")) {
68                if (append.empty())
69                        return;
70                if (!lst.empty())
71                        lst += sep;
72                lst += append;
73        }
74
75        inline std::string wstring_to_string( const wchar_t* pStr, int len) {
76                if (pStr == NULL)
77                        throw string_exception(_T("Invalid pointer in wstring_to_string"));
78                if (len < 0 && len != -1)
79                        throw string_exception(_T("Invalid string length in wstring_to_string"));
80
81                // figure out how many narrow characters we are going to get
82                int nChars = WideCharToMultiByte( CP_ACP , 0 , pStr , len , NULL , 0 , NULL , NULL ) ;
83                if ( len == -1 )
84                        -- nChars ;
85                if ( nChars == 0 )
86                        return "" ;
87
88                // convert the wide string to a narrow string
89                // nb: slightly naughty to write directly into the string like this
90                std::string buf ;
91                buf.resize( nChars ) ;
92                WideCharToMultiByte( CP_ACP , 0 , pStr , len ,
93                        const_cast<char*>(buf.c_str()) , nChars , NULL , NULL ) ;
94
95                return buf ;
96        }
97        inline std::string wstring_to_string( const std::wstring& str ) {
98                return wstring_to_string(str.c_str(), static_cast<int>(str.length()));
99        }
100
101        inline std::wstring string_to_wstring( const char* pStr , int len ) {
102                if (pStr == NULL)
103                        throw string_exception(_T("Invalid pointer in wstring_to_string"));
104                if (len < 0 && len != -1)
105                        throw string_exception(_T("Invalid string length in wstring_to_string"));
106
107                // figure out how many wide characters we are going to get
108                int nChars = MultiByteToWideChar( CP_ACP , 0 , pStr , len , NULL , 0 ) ;
109                if ( len == -1 )
110                        -- nChars ;
111                if ( nChars == 0 )
112                        return L"" ;
113
114                // convert the narrow string to a wide string
115                // nb: slightly naughty to write directly into the string like this
116                std::wstring buf ;
117                buf.resize( nChars ) ;
118                MultiByteToWideChar( CP_ACP , 0 , pStr , len , const_cast<wchar_t*>(buf.c_str()) , nChars ) ;
119
120                return buf ;
121        }
122        inline std::wstring string_to_wstring( const std::string& str ) {
123                return string_to_wstring(str.c_str(), static_cast<int>(str.length())) ;
124        }
125
126        inline std::wstring format_buffer(const wchar_t* buf, unsigned int len) {
127                std::wstringstream ss;
128                std::wstring chars;
129                for (unsigned int i=0;i<len;i++) {
130                        ss << std::hex << buf[i];
131                        ss << _T(", ");
132                        if (buf[i] >= ' ' && buf[i] <= 'z')
133                                chars += buf[i];
134                        else
135                                chars += '?';
136                        if (i%32==0) {
137                                ss << chars;
138                                ss << _T("\n");
139                                chars = _T("");
140                        }
141                }
142                return ss.str();
143        }
144        inline std::string format_buffer(const char* buf, unsigned int len) {
145                std::stringstream ss;
146                std::string chars;
147                for (unsigned int i=0;i<len;i++) {
148                        if (i%32==0) {
149                                if (i > 0) {
150                                        ss << chars;
151                                        ss << "\n";
152                                }
153                                chars = "";
154                                ss << std::hex << std::setw(8) << std::setfill('0') << i;
155                                ss << ": ";
156                        }
157                        ss << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(static_cast<unsigned char>(buf[i]));
158                        ss << ", ";
159                        if (buf[i] < 30 || buf[i] == 127)
160                                chars += '?';
161                        else
162                                chars += buf[i];
163                }
164                return ss.str();
165        }
166
167        inline std::wstring format_date(time_t time, std::wstring format = _T("%Y-%m-%d %H:%M:%S")) {
168                TCHAR buf[51];
169                struct tm nt; // = new struct tm;
170#if (_MSC_VER > 1300)  // 1300 == VC++ 7.0
171                if (gmtime_s(&nt, &time) != 0)
172                        return _T("");
173#else
174                nt = gmtime(&time);
175                if (nt == NULL)
176                        return "";
177#endif
178                size_t l = wcsftime(buf, 50, format.c_str(), &nt);
179                if (l <= 0 || l >= 50)
180                        return _T("");
181                buf[l] = 0;
182                return buf;
183        }
184        inline std::wstring format_date(const SYSTEMTIME &time, std::wstring format = _T("%Y-%m-%d %H:%M:%S")) {
185                TCHAR buf[51];
186
187                struct tm tmTime;
188                memset(&tmTime, 0, sizeof(tmTime));
189
190                tmTime.tm_sec = time.wSecond; // seconds after the minute - [0,59]
191                tmTime.tm_min = time.wMinute; // minutes after the hour - [0,59]
192                tmTime.tm_hour = time.wHour;  // hours since midnight - [0,23]
193                tmTime.tm_mday = time.wDay;  // day of the month - [1,31]
194                tmTime.tm_mon = time.wMonth-1; // months since January - [0,11]
195                tmTime.tm_year = time.wYear-1900; // years since 1900
196                tmTime.tm_wday = time.wDayOfWeek; // days since Sunday - [0,6]
197
198                size_t l = wcsftime(buf, 50, format.c_str(), &tmTime);
199                if (l <= 0 || l >= 50)
200                        return _T("");
201                buf[l] = 0;
202                return buf;
203        }
204
205        static const __int64 SECS_BETWEEN_EPOCHS = 11644473600;
206        static const __int64 SECS_TO_100NS = 10000000;
207        inline std::wstring format_filetime(unsigned long long filetime, std::wstring format = _T("%Y-%m-%d %H:%M:%S")) {
208                filetime -= (SECS_BETWEEN_EPOCHS * SECS_TO_100NS);
209                filetime /= SECS_TO_100NS;
210                return format_date(static_cast<time_t>(filetime), format);
211        }
212
213        inline void replace(std::wstring &string, std::wstring replace, std::wstring with) {
214                std::wstring::size_type pos = string.find(replace);
215                std::wstring::size_type len = replace.length();
216                while (pos != std::wstring::npos) {
217                        string = string.substr(0,pos)+with+string.substr(pos+len);
218                        if (with.find(replace) != std::wstring::npos) // If the replace containes the key look after the replace!
219                                pos = string.find(replace, pos+with.length());
220                        else
221                                pos = string.find(replace, pos+1);
222                }
223        }
224        inline std::wstring ctos(TCHAR c) {
225                return std::wstring(1, c);
226        }
227        inline TCHAR stoc(std::wstring str) {
228                if (str.length() == 0)
229                        return L' ';
230                return str[0];
231        }
232        inline std::wstring itos(unsigned int i) {
233                std::wstringstream ss;
234                ss << i;
235                return ss.str();
236        }
237        inline std::wstring itos(int i) {
238                std::wstringstream ss;
239                ss << i;
240                return ss.str();
241        }
242        inline std::wstring itos(unsigned long long i) {
243                std::wstringstream ss;
244                ss << i;
245                return ss.str();
246        }
247        inline std::wstring itos(__int64 i) {
248                std::wstringstream ss;
249                ss << i;
250                return ss.str();
251        }
252        inline std::wstring itos(unsigned long i) {
253                std::wstringstream ss;
254                ss << i;
255                return ss.str();
256        }
257        inline std::wstring itos(double i) {
258                std::wstringstream ss;
259                ss << i;
260                return ss.str();
261        }
262        inline std::wstring itos_non_sci(double i) {
263                std::wstringstream ss;
264                if (i < 10)
265                        ss.precision(20);
266                ss << std::noshowpoint << std::fixed << i;
267                std::wstring s = ss.str();
268                std::wstring::size_type pos = s.find_last_not_of('0');
269                if (pos == std::wstring::npos)
270                        return s;
271                if (s[pos] != '.')
272                        pos++;
273                return s.substr(0, pos);
274        }
275        inline std::wstring itos(float i) {
276                std::wstringstream ss;
277                ss << i;
278                return ss.str();
279        }
280        inline std::wstring ihextos(unsigned int i) {
281                std::wstringstream ss;
282                ss << std::hex << i;
283                return ss.str();
284        }
285        inline int stoi(std::wstring s) {
286                return _wtoi(s.c_str());
287        }
288        inline double stod(std::wstring s) {
289                return _wtof(s.c_str());
290        }
291        inline long long stoi64(std::wstring s) {
292                return _wtoi64(s.c_str());
293        }
294        inline unsigned stoui_as_time(std::wstring time, unsigned int smallest_unit = 1000) {
295                std::wstring::size_type p = time.find_first_of(_T("sSmMhHdDwW"));
296                unsigned int value = _wtoi(time.c_str());
297                if (p == std::wstring::npos)
298                        return value * smallest_unit;
299                else if ( (time[p] == 's') || (time[p] == 'S') )
300                        return value * 1000;
301                else if ( (time[p] == 'm') || (time[p] == 'M') )
302                        return value * 60 * 1000;
303                else if ( (time[p] == 'h') || (time[p] == 'H') )
304                        return value * 60 * 60 * 1000;
305                else if ( (time[p] == 'd') || (time[p] == 'D') )
306                        return value * 24 * 60 * 60 * 1000;
307                else if ( (time[p] == 'w') || (time[p] == 'W') )
308                        return value * 7 * 24 * 60 * 60 * 1000;
309                return value * smallest_unit;
310        }
311
312        inline unsigned long long stoi64_as_time(std::wstring time, unsigned int smallest_unit = 1000) {
313                std::wstring::size_type p = time.find_first_of(_T("sSmMhHdDwW"));
314                unsigned long long value = _wtoi64(time.c_str());
315                if (p == std::wstring::npos)
316                        return value * smallest_unit;
317                else if ( (time[p] == 's') || (time[p] == 'S') )
318                        return value * 1000;
319                else if ( (time[p] == 'm') || (time[p] == 'M') )
320                        return value * 60 * 1000;
321                else if ( (time[p] == 'h') || (time[p] == 'H') )
322                        return value * 60 * 60 * 1000;
323                else if ( (time[p] == 'd') || (time[p] == 'D') )
324                        return value * 24 * 60 * 60 * 1000;
325                else if ( (time[p] == 'w') || (time[p] == 'W') )
326                        return value * 7 * 24 * 60 * 60 * 1000;
327                return value * smallest_unit;
328        }
329
330#define MK_FORMAT_FTD(min, key, val) \
331        if (mtm->tm_year > min) \
332                strEx::replace(format, key, strEx::itos(val));  \
333        else  \
334                strEx::replace(format, key, _T("0"));
335
336        inline std::wstring format_time_delta(struct tm *mtm, std::wstring format = _T("%Y years %m months %d days %H hours %M minutes")) {
337                // "Date: %Y-%m-%d %H:%M:%S"
338                MK_FORMAT_FTD(70, _T("%Y"), mtm->tm_year);
339                MK_FORMAT_FTD(0, _T("%m"), mtm->tm_mon);
340                MK_FORMAT_FTD(0, _T("%d"), mtm->tm_mday-1);
341                MK_FORMAT_FTD(0, _T("%H"), mtm->tm_hour);
342                MK_FORMAT_FTD(0, _T("%M"), mtm->tm_min);
343                MK_FORMAT_FTD(0, _T("%S"), mtm->tm_sec);
344                return format;
345        }
346
347#define WEEK    (7 * 24 * 60 * 60 * 1000)
348#define DAY             (24 * 60 * 60 * 1000)
349#define HOUR    (60 * 60 * 1000)
350#define MIN             (60 * 1000)
351#define SEC             (1000)
352        inline std::wstring itos_as_time(unsigned long long time) {
353                if (time > WEEK) {
354                        unsigned int w = static_cast<unsigned int>(time/WEEK);
355                        unsigned int d = static_cast<unsigned int>((time-(w*WEEK))/DAY);
356                        unsigned int h = static_cast<unsigned int>((time-(w*WEEK)-(d*DAY))/HOUR);
357                        unsigned int m = static_cast<unsigned int>((time-(w*WEEK)-(d*DAY)-(h*HOUR))/MIN);
358                        return itos(w) + _T("w ") + itos(d) + _T("d ") + itos(h) + _T(":") + itos(m);
359                }
360                else if (time > DAY) {
361                        unsigned int d = static_cast<unsigned int>((time)/DAY);
362                        unsigned int h = static_cast<unsigned int>((time-(d*DAY))/HOUR);
363                        unsigned int m = static_cast<unsigned int>((time-(d*DAY)-(h*HOUR))/MIN);
364                        return itos(d) + _T("d ") + itos(h) + _T(":") + itos(m);
365                }
366                else if (time > HOUR) {
367                        unsigned int h = static_cast<unsigned int>((time)/HOUR);
368                        unsigned int m = static_cast<unsigned int>((time-(h*HOUR))/MIN);
369                        return itos(h) + _T(":") + itos(m);
370                } else if (time > MIN) {
371                        return _T("0:") + itos(static_cast<unsigned int>(time/(60 * 1000)));
372                } else if (time > SEC)
373                        return itos(static_cast<unsigned int>(time/(1000))) + _T("s");
374                return itos(static_cast<unsigned int>(time));
375        }
376
377        inline long long stoi64_as_BKMG(std::wstring s) {
378                std::wstring::size_type p = s.find_first_of(_T("BMKGT"));
379                if (p == std::wstring::npos)
380                        return _wtoi64(s.c_str());
381                else if (s[p] == 'B')
382                        return _wtoi64(s.c_str());
383                else if (s[p] == 'K')
384                        return _wtoi64(s.c_str())*1024;
385                else if (s[p] == 'M')
386                        return _wtoi64(s.c_str())*1024*1024;
387                else if (s[p] == 'G')
388                        return _wtoi64(s.c_str())*1024*1024*1024;
389                else if (s[p] == 'T')
390                        return _wtoi64(s.c_str())*1024*1024*1024*1024;
391                else
392                        return _wtoi64(s.c_str());
393        }
394#define BKMG_RANGE "BKMGTP"
395#define BKMG_SIZE 5
396
397        inline std::wstring itos_as_BKMG(unsigned __int64 i) {
398                double cpy = static_cast<double>(i);
399                TCHAR postfix[] = _T(BKMG_RANGE);
400                int idx = 0;
401                while ((cpy > 999)&&(idx<BKMG_SIZE)) {
402                        cpy/=1024;
403                        idx++;
404                }
405                std::wstringstream ss;
406                ss << std::setprecision(3);
407                ss << cpy;
408                std::wstring ret = ss.str(); // itos(cpy);
409                ret += postfix[idx];
410                return ret;
411        }
412        inline std::wstring format_BKMG(unsigned __int64 i, std::wstring unit) {
413                double cpy = static_cast<double>(i);
414                TCHAR postfix[] = _T(BKMG_RANGE);
415                if (unit.length() != 1)
416                        return itos(cpy);
417                for (int i=0;i<BKMG_SIZE;i++) {
418                        if (unit[0] == postfix[i]) {
419                                std::wstringstream ss;
420                                ss << std::setiosflags(std::ios::fixed) << std::setprecision(3) << cpy;
421                                std::wstring s = ss.str();
422                                std::wstring::size_type pos = s.find_last_not_of(_T("0"));
423                                if (pos != std::string::npos) {
424                                        s = s.substr(0,pos);
425                                }
426                                return s;
427                        }
428                        cpy/=1024;
429                }
430                return itos(cpy);
431        }
432        inline std::wstring find_proper_unit_BKMG(unsigned __int64 i) {
433                double cpy = static_cast<double>(i);
434                TCHAR postfix[] = _T(BKMG_RANGE);
435                int idx = 0;
436                while ((cpy > 999)&&(idx<BKMG_SIZE)) {
437                        cpy/=1024;
438                        idx++;
439                }
440                return std::wstring(1, postfix[idx]);
441        }
442
443        typedef std::list<std::wstring> splitList;
444        inline splitList splitEx(std::wstring str, std::wstring key) {
445                splitList ret;
446                std::wstring::size_type pos = 0, lpos = 0;
447                while ((pos = str.find(key, pos)) !=  std::wstring::npos) {
448                        ret.push_back(str.substr(lpos, pos-lpos));
449                        lpos = ++pos;
450                }
451                if (lpos < str.size())
452                        ret.push_back(str.substr(lpos));
453                return ret;
454        }
455        inline std::wstring joinEx(splitList lst, std::wstring key) {
456                std::wstring ret;
457                for (splitList::const_iterator it = lst.begin(); it != lst.end(); ++it) {
458                        if (!ret.empty())
459                                ret += key;
460                        ret += *it;
461                }
462                return ret;
463        }
464
465
466
467        inline std::wstring trim_right(const std::wstring &source , const std::wstring& t = _T(" "))
468        {
469                std::wstring str = source;
470                return str.erase( str.find_last_not_of(t) + 1);
471        }
472
473        inline std::wstring trim_left( const std::wstring& source, const std::wstring& t = _T(" "))
474        {
475                std::wstring str = source;
476                return str.erase(0 , source.find_first_not_of(t) );
477        }
478
479        inline std::wstring trim(const std::wstring& source, const std::wstring& t = _T(" "))
480        {
481                std::wstring str = source;
482                return trim_left( trim_right( str , t) , t );
483        }
484        inline std::pair<std::wstring,std::wstring> split(std::wstring str, std::wstring key) {
485                std::wstring::size_type pos = str.find(key);
486                if (pos == std::wstring::npos)
487                        return std::pair<std::wstring,std::wstring>(str, _T(""));
488                return std::pair<std::wstring,std::wstring>(str.substr(0, pos), str.substr(pos+key.length()));
489        }
490        typedef std::pair<std::wstring,std::wstring> token;
491        // foo bar "foo \" bar" foo -> foo, bar "foo \" bar" foo -> bar, "foo \" bar" foo ->
492        //
493        inline token getToken(std::wstring buffer, char split, bool escape = false) {
494                std::wstring::size_type pos = std::wstring::npos;
495                if ((escape) && (buffer[0] == '\"')) {
496                        do {
497                                pos = buffer.find('\"');
498                        }
499                        while (((pos != std::wstring::npos)&&(pos > 1))&&(buffer[pos-1] == '\\'));
500                } else
501                        pos = buffer.find(split);
502                if (pos == std::wstring::npos)
503                        return token(buffer, _T(""));
504                if (pos == buffer.length()-1)
505                        return token(buffer.substr(0, pos), _T(""));
506                return token(buffer.substr(0, pos-1), buffer.substr(++pos));
507        }
508
509
510        template<class _E>
511        struct blind_traits : public std::char_traits<_E>
512        {
513                static bool eq(const _E& x, const _E& y) {
514                        return tolower( x ) == tolower( y );
515                }
516                static bool lt(const _E& x, const _E& y) {
517                        return tolower( x ) < tolower( y );
518                }
519
520                static int compare(const _E *x, const _E *y, size_t n) {
521                        return _wcsnicmp( x, y, n );
522                }
523
524                //  There's no memichr(), so we roll our own.  It ain't rocket science.
525                static const _E * __cdecl find(const _E *buf, size_t len, const _E& ch) {
526                        //  Jerry says that x86s have special mojo for memchr(), so the
527                        //  memchr() calls end up being reasonably efficient in practice.
528                        const _E *pu = (const _E *)memchr(buf, ch, len);
529                        const _E *pl = (const _E *)memchr(buf, tolower( ch ), len);
530                        if ( ! pu )
531                                return pl;  //  Might be NULL; if so, NULL's the word.
532                        else if ( ! pl )
533                                return pu;
534                        else
535                                //  If either one was NULL, we return the other; if neither is
536                                //  NULL, we return the lesser of the two.
537                                return ( pu < pl ) ? pu : pl;
538                }
539
540                //  I'm reasonably sure that this is eq() for wide characters.  Maybe.
541                static bool eq_int_type(const int_type& ch1, const int_type& ch2) {
542                        return char_traits<_E>::eq_int_type( tolower( ch1 ), tolower( ch2 ) );
543                }
544        };
545
546        //  And here's our case-blind string class.
547        //typedef std::basic_string<char, blind_traits<char>, std::allocator<char> >  blindstr;
548        typedef std::basic_string<wchar_t, blind_traits<wchar_t>, std::allocator<wchar_t> >  blindstr;
549
550        struct case_blind_string_compare : public std::binary_function<std::wstring, std::wstring, bool>
551        {
552                bool operator() (const std::wstring& x, const std::wstring& y) const {
553                        return _wcsicmp( x.c_str(), y.c_str() ) < 0;
554                }
555        };
556
557
558
559        class StrICmp
560        {
561        public:
562                StrICmp(const std::string &Lang = "english") : m_locE(Lang.c_str())
563                {
564                }
565                class CharLessI
566                {
567                public:
568                        CharLessI(std::locale &locE) : m_locE(locE)
569                        {
570                        }
571                        template<typename T>
572                        bool operator()(T c1, T c2)
573                        {
574                                return std::tolower(c1, m_locE) < std::tolower(c2, m_locE);
575                        }
576                private:
577                        std::locale &m_locE;
578                };
579                template<typename T>
580                int operator()(const T &s1, const T &s2)
581                {
582                        if (std::lexicographical_compare(s1.begin(), s1.end(), s2.begin(), s2.end(), CharLessI(m_locE)))
583                                return -1;
584                        if (std::lexicographical_compare(s2.begin(), s2.end(), s1.begin(), s1.end(), CharLessI(m_locE)))
585                                return 1;
586                        return 0;
587                }
588        private:
589                std::locale m_locE;
590        };
591
592        template<typename T>
593        int StrCmpI(const T &s1, const T &s2, const std::string &Lang = "english")
594        {
595                return StrICmp(Lang)(s1, s2);
596        }
597
598
599#ifdef _DEBUG
600        inline void test_getToken(std::wstring in1, char in2, std::wstring out1, std::wstring out2) {
601                token t = getToken(in1, in2);
602                std::wcout << _T("strEx::test_getToken(") << in1 << _T(", ") << in2 << _T(") : ");
603                if ((t.first == out1) && (t.second == out2))
604                        std::wcout << _T("Succeeded") << std::endl;
605                else
606                        std::wcout << _T("Failed [") << out1 << _T("=") << t.first << _T(", ") << out2 << _T("=") << t.second << _T("]") << std::endl;
607        }
608        inline void run_test_getToken() {
609                test_getToken(_T(""), '&', _T(""), _T(""));
610                test_getToken(_T("&"), '&', _T(""), _T(""));
611                test_getToken(_T("&&"), '&', _T(""), _T("&"));
612                test_getToken(_T("foo"), '&', _T("foo"), _T(""));
613                test_getToken(_T("foo&"), '&', _T("foo"), _T(""));
614                test_getToken(_T("foo&bar"), '&', _T("foo"), _T("bar"));
615                test_getToken(_T("foo&bar&test"), '&', _T("foo"), _T("bar&test"));
616        }
617
618        inline void test_replace(std::wstring source, std::wstring replace, std::wstring with, std::wstring out) {
619                std::wcout << _T("strEx::test_replace(") << source << _T(", ") << replace << _T(", ") << with << _T(") : ");
620                std::wstring s = source;
621                strEx::replace(s, replace, with);
622                if (s == out)
623                        std::wcout << _T("Succeeded") << std::endl;
624                else
625                        std::wcout << _T("Failed [") << s << _T("=") << out << _T("]") << std::endl;
626        }
627        inline void run_test_replace() {
628                test_replace(_T(""), _T(""), _T(""), _T(""));
629                test_replace(_T("foo"), _T(""), _T(""), _T("foo"));
630                test_replace(_T("foobar"), _T("foo"), _T(""), _T("bar"));
631                test_replace(_T("foobar"), _T("foo"), _T("bar"), _T("barbar"));
632        }
633
634#endif
635}
636
637
638#include <string>
639#include <locale>
640
641#include <boost/lexical_cast.hpp>
642
643namespace boost
644{
645        template<>
646        inline std::wstring lexical_cast<std::wstring, std::string>(const std::string& arg)
647        {
648                std::wstring result;
649                std::locale loc;
650                for(unsigned int i= 0; i < arg.size(); ++i)
651                {
652                        result += std::use_facet<std::ctype<wchar_t> >(loc).widen(arg[i]);
653                }
654                return result;
655        }
656
657        template<>
658        inline std::string lexical_cast<std::string, std::wstring>(const std::wstring& arg)
659        {
660                std::string result;
661                std::locale loc;
662                for(unsigned int i= 0; i < arg.size(); ++i)
663                {
664                        result += std::use_facet<std::ctype<wchar_t> >(loc).narrow(arg[i]);
665                }
666                return result;
667        }
668}
669
Note: See TracBrowser for help on using the repository browser.