source: nscp/include/strEx.h @ 96c1461

0.4.00.4.10.4.2
Last change on this file since 96c1461 was 96c1461, checked in by Michael Medin <michael@…>, 19 months ago
  • Major refactoring in the command line interface
  • Added support for alias to many common module (command line) so: nscp eventlog (is the same as nscp client --module CheckEventLog)
  • Fixed issue with CheckEventLog message rendering and eventid
  • Refactored all Client modules to all support command line, commands and submissions.
  • Added uniform handling of "everything" to all Client plugins
  • Fixed SyslogClient to work "as advertised" (ie. all hardcoded stuff is removed)
  • Fixed utf8 issue with text strings (now have a working concept which needs to be implementd "all over the place")
  • Many issues and fixes related to clients.
  • Fixed so CheckEvent? log (insert) works much better (added new options)
  • Property mode set to 100644
File size: 32.7 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#include <unicode_char.hpp>
23#include <types.hpp>
24
25#include <string>
26#include <sstream>
27#include <iomanip>
28#include <utility>
29#include <list>
30#include <functional>
31#include <time.h>
32#include <algorithm>
33#include <locale>
34#include <iostream>
35
36#include <cctype>
37
38#ifdef __GNUC__
39#include <iconv.h>
40#include <errno.h>
41#endif
42
43#include <boost/lexical_cast.hpp>
44#include <boost/date_time.hpp>
45#include <boost/algorithm/string.hpp>
46#include <boost/foreach.hpp>
47//#include <boost/date_time/local_time/local_date_time.hpp>
48//#include <boost/date_time/gregorian/conversion.hpp>
49//boost::local_time::local_date_time
50
51
52#ifdef _DEBUG
53#include <iostream>
54#endif
55
56
57
58
59#include <string>
60#include <locale>
61
62
63namespace utf8 {
64        /** Converts a std::wstring into a std::string with UTF-8 encoding. */
65        template<typename StringT>
66        StringT cvt(std::wstring const & string);
67
68        /** Converts a std::String with UTF-8 encoding into a std::wstring.     */
69        template<typename StringT>
70        StringT cvt(std::string const & string );
71
72        /** Nop specialization for std::string. */
73        template <>
74        inline std::string cvt(std::string const & string) {
75                return string;
76        }
77
78        /** Nop specialization for std::wstring. */
79        template<>
80        inline std::wstring cvt(std::wstring const & rc_string) {
81                return rc_string;
82        }
83
84        inline std::wstring to_unicode(std::string const & str) {
85#ifdef WIN32
86                int len = static_cast<int>(str.length());
87                int nChars = MultiByteToWideChar(CP_ACP, 0, str.c_str(), len, NULL, 0);
88                if (nChars == 0)
89                        return L"";
90                wchar_t *buffer = new wchar_t[nChars+1];
91                if (buffer == NULL)
92                        return L"";
93                MultiByteToWideChar(CP_ACP, 0, str.c_str(), len, buffer, nChars);
94                buffer[nChars] = 0;
95                std::wstring buf(buffer, nChars);
96                delete [] buffer;
97                return buf;
98#else
99                size_t utf8Length = str.length();
100                size_t outbytesLeft = utf8Length*sizeof(wchar_t);
101
102                //Copy the instring
103                char *inString = new char[str.length()+1];
104                strcpy(inString, str.c_str());
105
106                //Create buffer for output
107                char *outString = (char*)new wchar_t[utf8Length+1];
108                memset(outString, 0, sizeof(wchar_t)*(utf8Length+1));
109
110                char *inPointer = inString;
111                char *outPointer = outString;
112
113                iconv_t convDesc = iconv_open("WCHAR_T", "");
114                iconv(convDesc, &inPointer, &utf8Length, &outPointer, &outbytesLeft);
115                iconv_close(convDesc);
116
117                std::wstring retval( (wchar_t *)outString );
118
119                //Cleanup
120                delete[] inString;
121                delete[] outString;
122
123                return retval;
124#endif 
125        }
126        /*
127        inline std::wstring to_unicode(std::wstring const & str) {
128#ifdef WIN32
129                // figure out how many narrow characters we are going to get
130                int nChars = WideCharToMultiByte(CP_OEMCP, 0, str.c_str(), static_cast<int>(str.length()), NULL, 0, NULL, NULL);
131                if (nChars == 0)
132                        return "";
133
134                // convert the wide string to a narrow string
135                // nb: slightly naughty to write directly into the string like this
136                std::string buf;
137                buf.resize(nChars);
138                WideCharToMultiByte(CP_OEMCP, 0, str.c_str(), static_cast<int>(str.length()), const_cast<char*>(buf.c_str()), nChars, NULL, NULL);
139                return buf;
140#else
141                return str;
142#endif
143        }
144*/
145
146        template<>
147        inline std::string cvt(std::wstring const & str) {
148#ifdef WIN32
149                // figure out how many narrow characters we are going to get
150                int nChars = WideCharToMultiByte(CP_UTF8, 0, str.c_str(), static_cast<int>(str.length()), NULL, 0, NULL, NULL);
151                if (nChars == 0)
152                        return "";
153
154                // convert the wide string to a narrow string
155                // nb: slightly naughty to write directly into the string like this
156                std::string buf;
157                buf.resize(nChars);
158                WideCharToMultiByte(CP_UTF8, 0, str.c_str(), static_cast<int>(str.length()), const_cast<char*>(buf.c_str()), nChars, NULL, NULL);
159                return buf;
160#else
161                size_t wideSize = sizeof(wchar_t)*str.length();
162                size_t outbytesLeft = wideSize+sizeof(char); //We cannot know how many wide character there is yet
163
164                //Copy the instring
165                char *inString = (char*)new wchar_t[str.length()+1];
166                memcpy(inString, str.c_str(), wideSize+sizeof(wchar_t));
167
168                //Create buffer for output
169                char *outString = new char[outbytesLeft];
170                memset(outString, 0, sizeof(char)*(outbytesLeft));
171
172                char *inPointer = inString;
173                char *outPointer = outString;
174
175                iconv_t convDesc = iconv_open("UTF-8", "WCHAR_T");
176                iconv(convDesc, &inPointer, &wideSize, &outPointer, &outbytesLeft);
177                iconv_close(convDesc);
178
179                std::string retval(outString);
180
181                //Cleanup
182                delete[] inString;
183                delete[] outString;
184
185                return retval;
186#endif
187        }
188
189        template<>
190        inline std::wstring cvt(std::string const & str) {
191#ifdef WIN32
192                int len = static_cast<int>(str.length());
193                int nChars = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), len, NULL, 0);
194                if (nChars == 0)
195                        return L"";
196                wchar_t *buffer = new wchar_t[nChars+1];
197                if (buffer == NULL)
198                        return L"";
199                MultiByteToWideChar(CP_UTF8, 0, str.c_str(), len, buffer, nChars);
200                buffer[nChars] = 0;
201                std::wstring buf(buffer, nChars);
202                delete [] buffer;
203                return buf;
204#else
205                size_t utf8Length = str.length();
206                size_t outbytesLeft = utf8Length*sizeof(wchar_t);
207
208                //Copy the instring
209                char *inString = new char[str.length()+1];
210                strcpy(inString, str.c_str());
211
212                //Create buffer for output
213                char *outString = (char*)new wchar_t[utf8Length+1];
214                memset(outString, 0, sizeof(wchar_t)*(utf8Length+1));
215
216                char *inPointer = inString;
217                char *outPointer = outString;
218
219                iconv_t convDesc = iconv_open("WCHAR_T", "UTF-8");
220                iconv(convDesc, &inPointer, &utf8Length, &outPointer, &outbytesLeft);
221                iconv_close(convDesc);
222
223                std::wstring retval( (wchar_t *)outString );
224
225                //Cleanup
226                delete[] inString;
227                delete[] outString;
228
229                return retval;
230#endif
231        }
232}
233
234namespace boost
235{
236        template<>
237        inline std::wstring lexical_cast<std::wstring, std::string>(const std::string& arg) {
238                return utf8::cvt<std::wstring>(arg);
239        }
240
241        template<>
242        inline std::string lexical_cast<std::string, std::wstring>(const std::wstring& arg) {
243                return utf8::cvt<std::string>(arg);
244        }
245}
246
247namespace strEx {
248        class string_exception : public std::exception {
249                std::wstring _what;
250        public:
251                string_exception(std::wstring what) : _what(what) {}
252                std::wstring what() {
253                        return _what;
254                }
255                virtual ~string_exception() throw();
256        };
257        namespace s {
258                inline std::string itos(float i) {
259                        std::stringstream ss;
260                        ss << i;
261                        return ss.str();
262                }
263                inline std::string itos(int i) {
264                        std::stringstream ss;
265                        ss << i;
266                        return ss.str();
267                }
268                inline std::string itos(unsigned int i) {
269                        std::stringstream ss;
270                        ss << i;
271                        return ss.str();
272                }
273        }
274
275        inline std::wstring strip_hex(std::wstring str) {
276                std::wstring ret; ret.reserve(str.size());
277                BOOST_FOREACH(wchar_t c, str)
278                {
279                        if (c==0||c==7||c==10||c==11||c==12||c==13||c==127)
280                                ret.push_back(L'?');
281                        else
282                                ret.push_back(c);
283                }
284                return ret;
285        }
286        inline std::string strip_hex(std::string str) {
287                std::string ret; ret.reserve(str.size());
288                BOOST_FOREACH(char c, str)
289                {
290                        if (c==0||c==7||c==10||c==11||c==12||c==13||c==127)
291                                ret.push_back('?');
292                        else
293                                ret.push_back(c);
294                }
295                return ret;
296        }
297
298        inline std::string strip_hex(std::vector<char> str) {
299                std::string ret; ret.reserve(str.size());
300                BOOST_FOREACH(char c, str)
301                {
302                        if (c==0||c==7||c==10||c==11||c==12||c==13||c==127)
303                                ret.push_back('?');
304                        else
305                                ret.push_back(c);
306                }
307                return ret;
308        }
309
310        inline void append_list(std::wstring &lst, std::wstring &append, std::wstring sep = _T(", ")) {
311                if (append.empty())
312                        return;
313                if (!lst.empty())
314                        lst += sep;
315                lst += append;
316        }
317        inline void append_list_ex(std::wstring &lst, std::wstring append, std::wstring sep = _T(", ")) {
318                if (append.empty())
319                        return;
320                if (!lst.empty())
321                        lst += sep;
322                lst += append;
323        }
324        inline std::string wstring_to_string( const std::wstring& str ) {
325                return utf8::cvt<std::string>(str);
326        }
327        inline std::wstring string_to_wstring( const std::string& str ) {
328                return utf8::cvt<std::wstring>(str);
329        }
330
331        inline std::wstring format_buffer(const wchar_t* buf, unsigned int len) {
332                std::wstringstream ss;
333                std::wstring chars;
334                for (unsigned int i=0;i<len;i++) {
335                        ss << std::hex << buf[i];
336                        ss << _T(", ");
337                        if (buf[i] >= ' ' && buf[i] <= 'z')
338                                chars += buf[i];
339                        else
340                                chars += '?';
341                        if (i%32==0) {
342                                ss << chars;
343                                ss << _T("\n");
344                                chars = _T("");
345                        }
346                }
347                ss << chars;
348                return ss.str();
349        }
350        inline std::string format_buffer(const char* buf, std::string::size_type len) {
351                std::stringstream ss;
352                std::string chars;
353                for (std::string::size_type i=0;i<len;i++) {
354                        if (i%32==0) {
355                                if (i > 0) {
356                                        ss << chars;
357                                        ss << "\n";
358                                }
359                                chars = "";
360                                ss << std::hex << std::setw(8) << std::setfill('0') << i;
361                                ss << ": ";
362                        }
363                        ss << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(static_cast<unsigned char>(buf[i]));
364                        ss << ", ";
365                        if (buf[i] < 30 || buf[i] == 127)
366                                chars += '?';
367                        else
368                                chars += buf[i];
369                }
370                ss << chars;
371                return ss.str();
372        }
373        inline std::string format_buffer(const std::string &buf) {
374                return format_buffer(buf.c_str(), buf.size());
375        }
376        inline std::string format_buffer(const std::vector<char> &buf) {
377                std::stringstream ss;
378                std::string chars;
379                for (unsigned int i=0;i<buf.size();i++) {
380                        if (i%32==0) {
381                                if (i > 0) {
382                                        ss << chars;
383                                        ss << "\n";
384                                }
385                                chars = "";
386                                ss << std::hex << std::setw(8) << std::setfill('0') << i;
387                                ss << ": ";
388                        }
389                        ss << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(static_cast<unsigned char>(buf[i]));
390                        ss << ", ";
391                        if (buf[i] < 30 || buf[i] == 127)
392                                chars += '?';
393                        else
394                                chars += buf[i];
395                }
396                ss << chars;
397                return ss.str();
398        }
399        inline std::wstring format_date(boost::posix_time::ptime date, std::wstring format = _T("%Y-%m-%d %H:%M:%S")) {
400                std::locale locale_local ("");
401
402                boost::gregorian::wdate_facet *date_output = new boost::gregorian::wdate_facet();
403                std::locale locale_adjusted (locale_local, date_output);
404
405                std::wstringstream date_ss;
406                date_ss.imbue(locale_adjusted);
407
408                date_output->format(format.c_str());
409                date_ss << date;
410
411                std::wstring ss = date_ss.str();
412                return ss;
413        }
414#ifdef WIN32
415        inline std::wstring format_date(const SYSTEMTIME &time, std::wstring format = _T("%Y-%m-%d %H:%M:%S")) {
416                TCHAR buf[51];
417
418                struct tm tmTime;
419                memset(&tmTime, 0, sizeof(tmTime));
420
421                tmTime.tm_sec = time.wSecond; // seconds after the minute - [0,59]
422                tmTime.tm_min = time.wMinute; // minutes after the hour - [0,59]
423                tmTime.tm_hour = time.wHour;  // hours since midnight - [0,23]
424                tmTime.tm_mday = time.wDay;  // day of the month - [1,31]
425                tmTime.tm_mon = time.wMonth-1; // months since January - [0,11]
426                tmTime.tm_year = time.wYear-1900; // years since 1900
427                tmTime.tm_wday = time.wDayOfWeek; // days since Sunday - [0,6]
428
429                size_t l = wcsftime(buf, 50, format.c_str(), &tmTime);
430                if (l <= 0 || l >= 50)
431                        return _T("");
432                buf[l] = 0;
433                return buf;
434        }
435#endif
436
437
438        inline std::wstring format_date(std::time_t time, std::wstring format = _T("%Y-%m-%d %H:%M:%S")) {
439                return format_date(boost::posix_time::from_time_t(time), format);
440        }
441
442       
443        static const long long SECS_BETWEEN_EPOCHS = 11644473600;
444        static const long long SECS_TO_100NS = 10000000;
445        inline unsigned long long filetime_to_time(unsigned long long filetime) {
446                return (filetime - (SECS_BETWEEN_EPOCHS * SECS_TO_100NS)) / SECS_TO_100NS;
447        }
448        inline std::wstring format_filetime(unsigned long long filetime, std::wstring format = _T("%Y-%m-%d %H:%M:%S")) {
449                if (filetime == 0)
450                        return _T("ZERO");
451                return format_date(static_cast<time_t>(filetime_to_time(filetime)), format);
452        }
453
454        inline void replace(std::wstring &string, const std::wstring replace, const std::wstring with) {
455                std::wstring::size_type pos = string.find(replace);
456                std::wstring::size_type len = replace.length();
457                while (pos != std::wstring::npos) {
458                        string = string.substr(0,pos)+with+string.substr(pos+len);
459                        if (with.find(replace) != std::wstring::npos) // If the replace containes the key look after the replace!
460                                pos = string.find(replace, pos+with.length());
461                        else
462                                pos = string.find(replace, pos+1);
463                }
464        }
465        inline void replace(std::string &string, const std::string replace, const std::string with) {
466                std::string::size_type pos = string.find(replace);
467                std::string::size_type len = replace.length();
468                while (pos != std::string::npos) {
469                        string = string.substr(0,pos)+with+string.substr(pos+len);
470                        if (with.find(replace) != std::string::npos) // If the replace containes the key look after the replace!
471                                pos = string.find(replace, pos+with.length());
472                        else
473                                pos = string.find(replace, pos+1);
474                }
475        }
476        inline std::wstring ctos(wchar_t c) {
477                return std::wstring(1, c);
478        }
479        inline wchar_t stoc(std::wstring str) {
480                if (str.length() == 0)
481                        return L' ';
482                return str[0];
483        }
484        inline std::wstring itos(unsigned int i) {
485                std::wstringstream ss;
486                ss << i;
487                return ss.str();
488        }
489        inline std::wstring itos(int i) {
490                std::wstringstream ss;
491                ss << i;
492                return ss.str();
493        }
494        inline std::wstring itos(unsigned long long i) {
495                std::wstringstream ss;
496                ss << i;
497                return ss.str();
498        }
499        inline std::wstring itos(long long i) {
500                std::wstringstream ss;
501                ss << i;
502                return ss.str();
503        }
504        /*
505        inline std::wstring itos(__int64 i) {
506                std::wstringstream ss;
507                ss << i;
508                return ss.str();
509        }
510        */
511        inline std::wstring itos(unsigned long i) {
512                std::wstringstream ss;
513                ss << i;
514                return ss.str();
515        }
516        inline std::wstring itos(double i) {
517                std::wstringstream ss;
518                ss << i;
519                return ss.str();
520        }
521        inline std::wstring itos_non_sci(double i) {
522                std::wstringstream ss;
523                if (i < 10)
524                        ss.precision(20);
525                ss << std::noshowpoint << std::fixed << i;
526                std::wstring s = ss.str();
527                std::wstring::size_type pos = s.find_last_not_of('0');
528                if (pos == std::wstring::npos)
529                        return s;
530                if (s[pos] != '.')
531                        pos++;
532                return s.substr(0, pos);
533        }
534        inline std::wstring itos(float i) {
535                std::wstringstream ss;
536                ss << i;
537                return ss.str();
538        }
539        inline std::wstring ihextos(unsigned int i) {
540                std::wstringstream ss;
541                ss << std::hex << i;
542                return ss.str();
543        }
544        inline int stoi(std::wstring s) {
545                return boost::lexical_cast<int>(s.c_str());
546        }
547        inline int stoi(std::string s) {
548                return boost::lexical_cast<int>(s.c_str());
549        }
550        inline double stod(std::wstring s) {
551                return boost::lexical_cast<double>(s.c_str());
552        }
553        inline long long stoi64(std::wstring s) {
554                return boost::lexical_cast<long long>(s.c_str());
555        }
556        inline unsigned stoui_as_time(std::wstring time, unsigned int smallest_unit = 1000) {
557                std::wstring::size_type p = time.find_first_of(_T("sSmMhHdDwW"));
558                std::wstring::size_type pend = time.find_first_not_of(_T("0123456789"));
559                unsigned int value = boost::lexical_cast<unsigned int>(pend==std::wstring::npos?time:time.substr(0,pend).c_str());
560                if (p == std::wstring::npos)
561                        return value * smallest_unit;
562                else if ( (time[p] == 's') || (time[p] == 'S') )
563                        return value * 1000;
564                else if ( (time[p] == 'm') || (time[p] == 'M') )
565                        return value * 60 * 1000;
566                else if ( (time[p] == 'h') || (time[p] == 'H') )
567                        return value * 60 * 60 * 1000;
568                else if ( (time[p] == 'd') || (time[p] == 'D') )
569                        return value * 24 * 60 * 60 * 1000;
570                else if ( (time[p] == 'w') || (time[p] == 'W') )
571                        return value * 7 * 24 * 60 * 60 * 1000;
572                return value * smallest_unit;
573        }
574        inline unsigned stoui_as_time_sec(std::wstring time, unsigned int smallest_unit = 1) {
575                std::wstring::size_type p = time.find_first_of(_T("sSmMhHdDwW"));
576                std::wstring::size_type pend = time.find_first_not_of(_T("0123456789"));
577                unsigned int value = boost::lexical_cast<unsigned int>(pend==std::wstring::npos?time:time.substr(0,pend).c_str());
578                if (p == std::wstring::npos)
579                        return value * smallest_unit;
580                else if ( (time[p] == L's') || (time[p] == L'S') )
581                        return value;
582                else if ( (time[p] == L'm') || (time[p] == L'M') )
583                        return value * 60;
584                else if ( (time[p] == L'h') || (time[p] == L'H') )
585                        return value * 60 * 60;
586                else if ( (time[p] == L'd') || (time[p] == L'D') )
587                        return value * 24 * 60 * 60;
588                else if ( (time[p] == L'w') || (time[p] == L'W') )
589                        return value * 7 * 24 * 60 * 60;
590                return value * smallest_unit;
591        }
592        inline unsigned stoui_as_time_sec(std::string time, unsigned int smallest_unit = 1) {
593                std::string::size_type p = time.find_first_of("sSmMhHdDwW");
594                std::string::size_type pend = time.find_first_not_of("0123456789");
595                unsigned int value = boost::lexical_cast<unsigned int>(pend==std::string::npos?time:time.substr(0,pend).c_str());
596                if (p == std::string::npos)
597                        return value * smallest_unit;
598                else if ( (time[p] == 's') || (time[p] == 'S') )
599                        return value;
600                else if ( (time[p] == 'm') || (time[p] == 'M') )
601                        return value * 60;
602                else if ( (time[p] == 'h') || (time[p] == 'H') )
603                        return value * 60 * 60;
604                else if ( (time[p] == 'd') || (time[p] == 'D') )
605                        return value * 24 * 60 * 60;
606                else if ( (time[p] == 'w') || (time[p] == 'W') )
607                        return value * 7 * 24 * 60 * 60;
608                return value * smallest_unit;
609        }
610        inline long stol_as_time_sec(std::wstring time, unsigned int smallest_unit = 1) {
611                long neg = 1;
612                if (time.length() > 1 && time[0] == L'-')
613                        return -(long)stoui_as_time_sec(time.substr(1), smallest_unit);
614                return stoui_as_time_sec(time, smallest_unit);
615        }
616        inline long stol_as_time_sec(std::string time, unsigned int smallest_unit = 1) {
617                long neg = 1;
618                if (time.length() > 1 && time[0] == '-')
619                        return -(long)stoui_as_time_sec(time.substr(1), smallest_unit);
620                return stoui_as_time_sec(time, smallest_unit);
621        }
622
623        inline unsigned long long stoi64_as_time(std::wstring time, unsigned int smallest_unit = 1000) {
624                std::wstring::size_type p = time.find_first_of(_T("sSmMhHdDwW"));
625                if (p == std::wstring::npos)
626                        return boost::lexical_cast<long long>(time) * smallest_unit;
627                unsigned long long value = boost::lexical_cast<long long>(time.substr(0, p));
628                if ( (time[p] == 's') || (time[p] == 'S') )
629                        return value * 1000;
630                else if ( (time[p] == 'm') || (time[p] == 'M') )
631                        return value * 60 * 1000;
632                else if ( (time[p] == 'h') || (time[p] == 'H') )
633                        return value * 60 * 60 * 1000;
634                else if ( (time[p] == 'd') || (time[p] == 'D') )
635                        return value * 24 * 60 * 60 * 1000;
636                else if ( (time[p] == 'w') || (time[p] == 'W') )
637                        return value * 7 * 24 * 60 * 60 * 1000;
638                return value * smallest_unit;
639        }
640
641
642#define WEEK    (7 * 24 * 60 * 60 * 1000)
643#define DAY             (24 * 60 * 60 * 1000)
644#define HOUR    (60 * 60 * 1000)
645#define MIN             (60 * 1000)
646#define SEC             (1000)
647        inline std::wstring itos_as_time(unsigned long long time) {
648                if (time > WEEK) {
649                        unsigned int w = static_cast<unsigned int>(time/WEEK);
650                        unsigned int d = static_cast<unsigned int>((time-(w*WEEK))/DAY);
651                        unsigned int h = static_cast<unsigned int>((time-(w*WEEK)-(d*DAY))/HOUR);
652                        unsigned int m = static_cast<unsigned int>((time-(w*WEEK)-(d*DAY)-(h*HOUR))/MIN);
653                        return itos(w) + _T("w ") + itos(d) + _T("d ") + itos(h) + _T(":") + itos(m);
654                }
655                else if (time > DAY) {
656                        unsigned int d = static_cast<unsigned int>((time)/DAY);
657                        unsigned int h = static_cast<unsigned int>((time-(d*DAY))/HOUR);
658                        unsigned int m = static_cast<unsigned int>((time-(d*DAY)-(h*HOUR))/MIN);
659                        return itos(d) + _T("d ") + itos(h) + _T(":") + itos(m);
660                }
661                else if (time > HOUR) {
662                        unsigned int h = static_cast<unsigned int>((time)/HOUR);
663                        unsigned int m = static_cast<unsigned int>((time-(h*HOUR))/MIN);
664                        return itos(h) + _T(":") + itos(m);
665                } else if (time > MIN) {
666                        return _T("0:") + itos(static_cast<unsigned int>(time/(60 * 1000)));
667                } else if (time > SEC)
668                        return itos(static_cast<unsigned int>(time/(1000))) + _T("s");
669                return itos(static_cast<unsigned int>(time));
670        }
671
672        inline long long stoi64_as_BKMG(std::wstring s) {
673                std::wstring::size_type p = s.find_first_of(_T("BMKGT"));
674                if (p == std::wstring::npos)
675                        return boost::lexical_cast<long long>(s.c_str());
676                else if (s[p] == 'B')
677                        return boost::lexical_cast<long long>(s.c_str());
678                else if (s[p] == 'K')
679                        return boost::lexical_cast<long long>(s.c_str())*1024;
680                else if (s[p] == 'M')
681                        return boost::lexical_cast<long long>(s.c_str())*1024*1024;
682                else if (s[p] == 'G')
683                        return boost::lexical_cast<long long>(s.c_str())*1024*1024*1024;
684                else if (s[p] == 'T')
685                        return boost::lexical_cast<long long>(s.c_str())*1024*1024*1024*1024;
686                else
687                        return boost::lexical_cast<long long>(s.c_str());
688        }
689#define BKMG_RANGE _T("BKMGTP")
690#define BKMG_SIZE 5
691
692        inline std::wstring itos_as_BKMG(unsigned long long i) {
693                double cpy = static_cast<double>(i);
694                wchar_t postfix[] = BKMG_RANGE;
695                int idx = 0;
696                while ((cpy > 999)&&(idx<BKMG_SIZE)) {
697                        cpy/=1024;
698                        idx++;
699                }
700                std::wstringstream ss;
701                ss << std::setprecision(3);
702                ss << cpy;
703                std::wstring ret = ss.str(); // itos(cpy);
704                ret += postfix[idx];
705                return ret;
706        }
707        inline std::wstring format_BKMG(unsigned long long i, std::wstring unit) {
708                double cpy = static_cast<double>(i);
709                wchar_t postfix[] = BKMG_RANGE;
710                if (unit.length() != 1)
711                        return itos(cpy);
712                for (int i=0;i<BKMG_SIZE;i++) {
713                        if (unit[0] == postfix[i]) {
714                                std::wstringstream ss;
715                                ss << std::setiosflags(std::ios::fixed) << std::setprecision(3) << cpy;
716                                std::wstring s = ss.str();
717                                std::wstring::size_type pos = s.find_last_not_of(_T("0"));
718                                if (pos != std::string::npos) {
719                                        s = s.substr(0,pos);
720                                }
721                                return s;
722                        }
723                        cpy/=1024;
724                }
725                return itos(cpy);
726        }
727        inline std::wstring find_proper_unit_BKMG(unsigned long long i) {
728                double cpy = static_cast<double>(i);
729                wchar_t postfix[] = BKMG_RANGE;
730                int idx = 0;
731                while ((cpy > 999)&&(idx<BKMG_SIZE)) {
732                        cpy/=1024;
733                        idx++;
734                }
735                return std::wstring(1, postfix[idx]);
736        }
737
738        typedef std::list<std::wstring> splitList;
739        inline splitList splitEx(const std::wstring str, const std::wstring key) {
740                splitList ret;
741                std::wstring::size_type pos = 0, lpos = 0;
742                while ((pos = str.find(key, pos)) !=  std::wstring::npos) {
743                        ret.push_back(str.substr(lpos, pos-lpos));
744                        lpos = ++pos;
745                }
746                if (lpos < str.size())
747                        ret.push_back(str.substr(lpos));
748                return ret;
749        }
750        typedef std::vector<std::wstring> splitVector;
751        inline splitVector splitV(const std::wstring str, const std::wstring key) {
752                splitVector ret;
753                std::wstring::size_type pos = 0, lpos = 0;
754                while ((pos = str.find(key, pos)) !=  std::wstring::npos) {
755                        ret.push_back(str.substr(lpos, pos-lpos));
756                        lpos = ++pos;
757                }
758                if (lpos < str.size())
759                        ret.push_back(str.substr(lpos));
760                return ret;
761        }
762        inline std::wstring joinEx(splitList lst, std::wstring key) {
763                std::wstring ret;
764                for (splitList::const_iterator it = lst.begin(); it != lst.end(); ++it) {
765                        if (!ret.empty())
766                                ret += key;
767                        ret += *it;
768                }
769                return ret;
770        }
771
772
773
774        inline std::wstring trim_right(const std::wstring &source , const std::wstring& t = _T(" "))
775        {
776                std::wstring str = source;
777                return str.erase( str.find_last_not_of(t) + 1);
778        }
779
780        inline std::wstring trim_left( const std::wstring& source, const std::wstring& t = _T(" "))
781        {
782                std::wstring str = source;
783                return str.erase(0 , source.find_first_not_of(t) );
784        }
785
786        inline std::wstring trim(const std::wstring& source, const std::wstring& t = _T(" "))
787        {
788                std::wstring str = source;
789                return trim_left( trim_right( str , t) , t );
790        }
791        inline std::pair<std::wstring,std::wstring> split(std::wstring str, std::wstring key) {
792                std::wstring::size_type pos = str.find(key);
793                if (pos == std::wstring::npos)
794                        return std::pair<std::wstring,std::wstring>(str, _T(""));
795                return std::pair<std::wstring,std::wstring>(str.substr(0, pos), str.substr(pos+key.length()));
796        }
797        typedef std::pair<std::wstring,std::wstring> token;
798        // foo bar "foo \" bar" foo -> foo, bar "foo \" bar" foo -> bar, "foo \" bar" foo ->
799        //
800        inline token getToken(std::wstring buffer, char split, bool escape = false) {
801                std::wstring::size_type pos = std::wstring::npos;
802                if ((escape) && (buffer[0] == '\"')) {
803                        do {
804                                pos = buffer.find('\"');
805                        }
806                        while (((pos != std::wstring::npos)&&(pos > 1))&&(buffer[pos-1] == '\\'));
807                } else
808                        pos = buffer.find(split);
809                if (pos == std::wstring::npos)
810                        return token(buffer, _T(""));
811                if (pos == buffer.length()-1)
812                        return token(buffer.substr(0, pos), _T(""));
813                return token(buffer.substr(0, pos-1), buffer.substr(++pos));
814        }
815
816
817
818        template<class char_type>
819        struct ci_char_traits : public std::char_traits<char_type> {
820                static bool eq( char_type c1, char_type c2 ) {
821                        return toupper(c1) == toupper(c2);
822                }
823
824                static bool ne( char_type c1, char_type c2 ) {
825                        return toupper(c1) != toupper(c2);
826                }
827
828                static bool lt( char_type c1, char_type c2 ) {
829                        return toupper(c1) <  toupper(c2);
830                }
831
832                static int compare( const char_type* s1, const char_type* s2, size_t n ) {
833#ifdef WIN32
834                        return memicmp( s1, s2, n );
835#else
836                        while (n-- && eq(*s1, *s2))
837                                ++s1, ++s2;
838                        return lt(*s2, *s1) - lt(*s1, *s2);
839#endif
840                }
841
842                static const char* find( const char_type* s, int n, char_type a ) {
843                        while( n-- > 0 && toupper(*s) != toupper(a) ) {
844                                ++s;
845                        }
846                        return s;
847                }
848        };
849        typedef std::basic_string<wchar_t, ci_char_traits<wchar_t> > wci_string;
850
851        template<class _E>
852        struct blind_traits : public std::char_traits<_E>
853        {
854               
855                static bool eq(const _E& x, const _E& y) {
856                        return boost::algorithm::iequals(x,y);
857                }
858                static bool lt(const _E& x, const _E& y) {
859                        return ilexicographical_compare(x, y);
860                }
861/*
862                static int compare(const _E *x, const _E *y, size_t n) {
863                        return ilexicographical_compare(x, y);
864                        return _wcsnicmp( x, y, n );
865                }
866
867                //  There's no memichr(), so we roll our own.  It ain't rocket science.
868                static const _E * / *__cdecl* / find(const _E *buf, size_t len, const _E& ch) {
869                        //  Jerry says that x86s have special mojo for memchr(), so the
870                        //  memchr() calls end up being reasonably efficient in practice.
871                        const _E *pu = (const _E *)memchr(buf, ch, len);
872                        const _E *pl = (const _E *)memchr(buf, tolower( ch ), len);
873                        if ( ! pu )
874                                return pl;  //  Might be NULL; if so, NULL's the word.
875                        else if ( ! pl )
876                                return pu;
877                        else
878                                //  If either one was NULL, we return the other; if neither is
879                                //  NULL, we return the lesser of the two.
880                                return ( pu < pl ) ? pu : pl;
881                }
882
883                //  I'm reasonably sure that this is eq() for wide characters.  Maybe.
884                static bool eq_int_type(const long& ch1, const long& ch2) {
885                        return std::char_traits<_E>::eq_int_type( tolower( ch1 ), tolower( ch2 ) );
886                }
887                */
888        };
889
890        //  And here's our case-blind string class.
891        //typedef std::basic_string<char, blind_traits<char>, std::allocator<char> >  blindstr;
892        typedef std::basic_string<wchar_t, blind_traits<wchar_t>, std::allocator<wchar_t> >  blindstr;
893
894
895
896
897        class StrICmp
898        {
899        public:
900                StrICmp(const std::string &Lang = "english") : m_locE(Lang.c_str())
901                {
902                }
903                class CharLessI
904                {
905                public:
906                        CharLessI(std::locale &locE) : m_locE(locE)
907                        {
908                        }
909                        template<typename T>
910                        bool operator()(T c1, T c2)
911                        {
912                                return std::tolower(c1, m_locE) < std::tolower(c2, m_locE);
913                        }
914                private:
915                        std::locale &m_locE;
916                };
917                template<typename T>
918                int operator()(const T &s1, const T &s2) const
919                {
920                        if (std::lexicographical_compare(s1.begin(), s1.end(), s2.begin(), s2.end(), CharLessI(m_locE)))
921                                return -1;
922                        if (std::lexicographical_compare(s2.begin(), s2.end(), s1.begin(), s1.end(), CharLessI(m_locE)))
923                                return 1;
924                        return 0;
925                }
926        private:
927                std::locale m_locE;
928        };
929
930        template<typename T>
931        int StrCmpI(const T &s1, const T &s2, const std::string &Lang = "english")
932        {
933                return StrICmp(Lang)(s1, s2);
934        }
935
936#define MK_FORMAT_FTD(min, key, val) \
937        if (mtm->tm_year > min) \
938        strEx::replace(format, key, strEx::itos(val));  \
939        else  \
940        strEx::replace(format, key, _T("0"));
941#ifdef WIN32
942        inline std::wstring format_time_delta(struct tm *mtm, std::wstring format = _T("%Y years %m months %d days %H hours %M minutes")) {
943                // "Date: %Y-%m-%d %H:%M:%S"
944                MK_FORMAT_FTD(70, _T("%Y"), mtm->tm_year);
945                MK_FORMAT_FTD(0, _T("%m"), mtm->tm_mon);
946                MK_FORMAT_FTD(0, _T("%d"), mtm->tm_mday-1);
947                MK_FORMAT_FTD(0, _T("%H"), mtm->tm_hour);
948                MK_FORMAT_FTD(0, _T("%M"), mtm->tm_min);
949                MK_FORMAT_FTD(0, _T("%S"), mtm->tm_sec);
950                return format;
951        }
952        inline std::wstring format_time_delta(time_t time, std::wstring format = _T("%Y years %m months %d days %H hours %M minutes")) {
953                struct tm nt; // = new struct tm;
954#if (_MSC_VER > 1300)  // 1300 == VC++ 7.0
955                if (gmtime_s(&nt, &time) != 0)
956                        return _T("");
957#else
958                nt = gmtime(&time);
959                if (nt == NULL)
960                        return "";
961#endif
962                return format_time_delta(&nt, format);
963        }
964        inline std::wstring format_filetime_delta(unsigned long long filetime, std::wstring format = _T("%Y-%m-%d %H:%M:%S")) {
965                if (filetime == 0)
966                        return _T("ZERO");
967                //filetime -= (SECS_BETWEEN_EPOCHS * SECS_TO_100NS);
968                filetime /= SECS_TO_100NS;
969                return format_time_delta(static_cast<time_t>(filetime), format);
970        }
971#endif
972
973#ifdef _DEBUG
974        inline void test_getToken(std::wstring in1, char in2, std::wstring out1, std::wstring out2) {
975                token t = getToken(in1, in2);
976                std::wcout << _T("strEx::test_getToken(") << in1 << _T(", ") << in2 << _T(") : ");
977                if ((t.first == out1) && (t.second == out2))
978                        std::wcout << _T("Succeeded") << std::endl;
979                else
980                        std::wcout << _T("Failed [") << out1 << _T("=") << t.first << _T(", ") << out2 << _T("=") << t.second << _T("]") << std::endl;
981        }
982        inline void run_test_getToken() {
983                test_getToken(_T(""), '&', _T(""), _T(""));
984                test_getToken(_T("&"), '&', _T(""), _T(""));
985                test_getToken(_T("&&"), '&', _T(""), _T("&"));
986                test_getToken(_T("foo"), '&', _T("foo"), _T(""));
987                test_getToken(_T("foo&"), '&', _T("foo"), _T(""));
988                test_getToken(_T("foo&bar"), '&', _T("foo"), _T("bar"));
989                test_getToken(_T("foo&bar&test"), '&', _T("foo"), _T("bar&test"));
990        }
991
992        inline void test_replace(std::wstring source, std::wstring replace, std::wstring with, std::wstring out) {
993                std::wcout << _T("strEx::test_replace(") << source << _T(", ") << replace << _T(", ") << with << _T(") : ");
994                std::wstring s = source;
995                strEx::replace(s, replace, with);
996                if (s == out)
997                        std::wcout << _T("Succeeded") << std::endl;
998                else
999                        std::wcout << _T("Failed [") << s << _T("=") << out << _T("]") << std::endl;
1000        }
1001        inline void run_test_replace() {
1002                test_replace(_T(""), _T(""), _T(""), _T(""));
1003                test_replace(_T("foo"), _T(""), _T(""), _T("foo"));
1004                test_replace(_T("foobar"), _T("foo"), _T(""), _T("bar"));
1005                test_replace(_T("foobar"), _T("foo"), _T("bar"), _T("barbar"));
1006        }
1007
1008#endif
1009
1010        template<typename T>
1011        inline void parse_command(T &cmd_line, std::list<T> &args) {
1012                boost::tokenizer<boost::escaped_list_separator<wchar_t>, typename T::const_iterator, T > tok(cmd_line, boost::escaped_list_separator<wchar_t>(L'\\', L' ', L'\"'));
1013                BOOST_FOREACH(T s, tok)
1014                        args.push_back(s);
1015        }
1016        template<typename T>
1017        inline void parse_command(T cmd_line, T &cmd, std::list<T> &args) {
1018                boost::tokenizer<boost::escaped_list_separator<wchar_t>, typename T::const_iterator, T > tok(cmd_line, boost::escaped_list_separator<wchar_t>(L'\\', L' ', L'\"'));
1019                bool first = true;
1020                BOOST_FOREACH(T s, tok)
1021                {
1022                        if (first) {
1023                                cmd = s;
1024                                first = false;
1025                        } else {
1026                                args.push_back(s);
1027                        }
1028
1029                }
1030        }
1031        /*
1032        template<typename T = std::string>
1033        inline void parse_command(T &string, std::list<T> &list) {
1034                boost::tokenizer<boost::escaped_list_separator<char>, T::const_iterator, T > tok(string, boost::escaped_list_separator<char>('\\', ' ', '\"'));
1035                BOOST_FOREACH(T s, tok)
1036                        list.push_back(s);
1037        }
1038        */
1039
1040}
1041
1042namespace nscp {
1043        namespace helpers {
1044                template <typename T> std::string to_string(const T& arg) {
1045                        try {
1046                                return boost::lexical_cast<std::string>(arg) ;
1047                        }
1048                        catch(...) {
1049                                return "";
1050                        }
1051                }
1052                template <typename T> std::string to_string(const std::string& arg) {
1053                        return arg;
1054                }
1055                template <typename T> std::string to_string(const std::wstring& arg) {
1056                        return utf8::cvt<std::string>(arg);
1057                }
1058                template <typename T> std::wstring to_wstring(const T& arg) {
1059                        try {
1060                                return boost::lexical_cast<std::wstring>(arg) ;
1061                        }
1062                        catch(...) {
1063                                return _T("");
1064                        }
1065                }
1066                template <typename T> std::wstring to_wstring(const std::wstring& arg) {
1067                        return arg;
1068                }
1069                template <typename T> std::wstring to_wstring(const std::string& arg) {
1070                        return utf8::cvt<std::wstring>(arg);
1071                }
1072        }
1073}
1074
Note: See TracBrowser for help on using the repository browser.