Merge pull request #4875 from koying/fixdroidremotekeyboard
[vuplus_xbmc] / xbmc / utils / StringUtils.cpp
1 /*
2  *      Copyright (C) 2005-2013 Team XBMC
3  *      http://xbmc.org
4  *
5  *  This Program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This Program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with XBMC; see the file COPYING.  If not, see
17  *  <http://www.gnu.org/licenses/>.
18  *
19  */
20 //-----------------------------------------------------------------------
21 //
22 //  File:      StringUtils.cpp
23 //
24 //  Purpose:   ATL split string utility
25 //  Author:    Paul J. Weiss
26 //
27 //  Modified to use J O'Leary's CStdString class by kraqh3d
28 //
29 //------------------------------------------------------------------------
30
31
32 #include "StringUtils.h"
33 #include "utils/RegExp.h"
34 #include "utils/fstrcmp.h"
35 #include <locale>
36
37 #include <math.h>
38 #include <sstream>
39 #include <time.h>
40 #include <stdlib.h>
41
42 #define FORMAT_BLOCK_SIZE 2048 // # of bytes to increment per try
43
44 using namespace std;
45
46 const char* ADDON_GUID_RE = "^(\\{){0,1}[0-9a-fA-F]{8}\\-[0-9a-fA-F]{4}\\-[0-9a-fA-F]{4}\\-[0-9a-fA-F]{4}\\-[0-9a-fA-F]{12}(\\}){0,1}$";
47
48 /* empty string for use in returns by ref */
49 const CStdString StringUtils::EmptyString = "";
50 const std::string StringUtils::Empty = "";
51 CStdString StringUtils::m_lastUUID = "";
52
53 //      Copyright (c) Leigh Brasington 2012.  All rights reserved.
54 //  This code may be used and reproduced without written permission.
55 //  http://www.leighb.com/tounicupper.htm
56 //
57 //      The tables were constructed from
58 //      http://publib.boulder.ibm.com/infocenter/iseries/v7r1m0/index.jsp?topic=%2Fnls%2Frbagslowtoupmaptable.htm
59
60 static wchar_t unicode_lowers[] = {
61   (wchar_t)0x0061, (wchar_t)0x0062, (wchar_t)0x0063, (wchar_t)0x0064, (wchar_t)0x0065, (wchar_t)0x0066, (wchar_t)0x0067, (wchar_t)0x0068, (wchar_t)0x0069,
62   (wchar_t)0x006A, (wchar_t)0x006B, (wchar_t)0x006C, (wchar_t)0x006D, (wchar_t)0x006E, (wchar_t)0x006F, (wchar_t)0x0070, (wchar_t)0x0071, (wchar_t)0x0072,
63   (wchar_t)0x0073, (wchar_t)0x0074, (wchar_t)0x0075, (wchar_t)0x0076, (wchar_t)0x0077, (wchar_t)0x0078, (wchar_t)0x0079, (wchar_t)0x007A, (wchar_t)0x00E0,
64   (wchar_t)0x00E1, (wchar_t)0x00E2, (wchar_t)0x00E3, (wchar_t)0x00E4, (wchar_t)0x00E5, (wchar_t)0x00E6, (wchar_t)0x00E7, (wchar_t)0x00E8, (wchar_t)0x00E9,
65   (wchar_t)0x00EA, (wchar_t)0x00EB, (wchar_t)0x00EC, (wchar_t)0x00ED, (wchar_t)0x00EE, (wchar_t)0x00EF, (wchar_t)0x00F0, (wchar_t)0x00F1, (wchar_t)0x00F2,
66   (wchar_t)0x00F3, (wchar_t)0x00F4, (wchar_t)0x00F5, (wchar_t)0x00F6, (wchar_t)0x00F8, (wchar_t)0x00F9, (wchar_t)0x00FA, (wchar_t)0x00FB, (wchar_t)0x00FC,
67   (wchar_t)0x00FD, (wchar_t)0x00FE, (wchar_t)0x00FF, (wchar_t)0x0101, (wchar_t)0x0103, (wchar_t)0x0105, (wchar_t)0x0107, (wchar_t)0x0109, (wchar_t)0x010B,
68   (wchar_t)0x010D, (wchar_t)0x010F, (wchar_t)0x0111, (wchar_t)0x0113, (wchar_t)0x0115, (wchar_t)0x0117, (wchar_t)0x0119, (wchar_t)0x011B, (wchar_t)0x011D,
69   (wchar_t)0x011F, (wchar_t)0x0121, (wchar_t)0x0123, (wchar_t)0x0125, (wchar_t)0x0127, (wchar_t)0x0129, (wchar_t)0x012B, (wchar_t)0x012D, (wchar_t)0x012F,
70   (wchar_t)0x0131, (wchar_t)0x0133, (wchar_t)0x0135, (wchar_t)0x0137, (wchar_t)0x013A, (wchar_t)0x013C, (wchar_t)0x013E, (wchar_t)0x0140, (wchar_t)0x0142,
71   (wchar_t)0x0144, (wchar_t)0x0146, (wchar_t)0x0148, (wchar_t)0x014B, (wchar_t)0x014D, (wchar_t)0x014F, (wchar_t)0x0151, (wchar_t)0x0153, (wchar_t)0x0155,
72   (wchar_t)0x0157, (wchar_t)0x0159, (wchar_t)0x015B, (wchar_t)0x015D, (wchar_t)0x015F, (wchar_t)0x0161, (wchar_t)0x0163, (wchar_t)0x0165, (wchar_t)0x0167,
73   (wchar_t)0x0169, (wchar_t)0x016B, (wchar_t)0x016D, (wchar_t)0x016F, (wchar_t)0x0171, (wchar_t)0x0173, (wchar_t)0x0175, (wchar_t)0x0177, (wchar_t)0x017A,
74   (wchar_t)0x017C, (wchar_t)0x017E, (wchar_t)0x0183, (wchar_t)0x0185, (wchar_t)0x0188, (wchar_t)0x018C, (wchar_t)0x0192, (wchar_t)0x0199, (wchar_t)0x01A1,
75   (wchar_t)0x01A3, (wchar_t)0x01A5, (wchar_t)0x01A8, (wchar_t)0x01AD, (wchar_t)0x01B0, (wchar_t)0x01B4, (wchar_t)0x01B6, (wchar_t)0x01B9, (wchar_t)0x01BD,
76   (wchar_t)0x01C6, (wchar_t)0x01C9, (wchar_t)0x01CC, (wchar_t)0x01CE, (wchar_t)0x01D0, (wchar_t)0x01D2, (wchar_t)0x01D4, (wchar_t)0x01D6, (wchar_t)0x01D8,
77   (wchar_t)0x01DA, (wchar_t)0x01DC, (wchar_t)0x01DF, (wchar_t)0x01E1, (wchar_t)0x01E3, (wchar_t)0x01E5, (wchar_t)0x01E7, (wchar_t)0x01E9, (wchar_t)0x01EB,
78   (wchar_t)0x01ED, (wchar_t)0x01EF, (wchar_t)0x01F3, (wchar_t)0x01F5, (wchar_t)0x01FB, (wchar_t)0x01FD, (wchar_t)0x01FF, (wchar_t)0x0201, (wchar_t)0x0203,
79   (wchar_t)0x0205, (wchar_t)0x0207, (wchar_t)0x0209, (wchar_t)0x020B, (wchar_t)0x020D, (wchar_t)0x020F, (wchar_t)0x0211, (wchar_t)0x0213, (wchar_t)0x0215,
80   (wchar_t)0x0217, (wchar_t)0x0253, (wchar_t)0x0254, (wchar_t)0x0257, (wchar_t)0x0258, (wchar_t)0x0259, (wchar_t)0x025B, (wchar_t)0x0260, (wchar_t)0x0263,
81   (wchar_t)0x0268, (wchar_t)0x0269, (wchar_t)0x026F, (wchar_t)0x0272, (wchar_t)0x0275, (wchar_t)0x0283, (wchar_t)0x0288, (wchar_t)0x028A, (wchar_t)0x028B,
82   (wchar_t)0x0292, (wchar_t)0x03AC, (wchar_t)0x03AD, (wchar_t)0x03AE, (wchar_t)0x03AF, (wchar_t)0x03B1, (wchar_t)0x03B2, (wchar_t)0x03B3, (wchar_t)0x03B4,
83   (wchar_t)0x03B5, (wchar_t)0x03B6, (wchar_t)0x03B7, (wchar_t)0x03B8, (wchar_t)0x03B9, (wchar_t)0x03BA, (wchar_t)0x03BB, (wchar_t)0x03BC, (wchar_t)0x03BD,
84   (wchar_t)0x03BE, (wchar_t)0x03BF, (wchar_t)0x03C0, (wchar_t)0x03C1, (wchar_t)0x03C3, (wchar_t)0x03C4, (wchar_t)0x03C5, (wchar_t)0x03C6, (wchar_t)0x03C7,
85   (wchar_t)0x03C8, (wchar_t)0x03C9, (wchar_t)0x03CA, (wchar_t)0x03CB, (wchar_t)0x03CC, (wchar_t)0x03CD, (wchar_t)0x03CE, (wchar_t)0x03E3, (wchar_t)0x03E5,
86   (wchar_t)0x03E7, (wchar_t)0x03E9, (wchar_t)0x03EB, (wchar_t)0x03ED, (wchar_t)0x03EF, (wchar_t)0x0430, (wchar_t)0x0431, (wchar_t)0x0432, (wchar_t)0x0433,
87   (wchar_t)0x0434, (wchar_t)0x0435, (wchar_t)0x0436, (wchar_t)0x0437, (wchar_t)0x0438, (wchar_t)0x0439, (wchar_t)0x043A, (wchar_t)0x043B, (wchar_t)0x043C,
88   (wchar_t)0x043D, (wchar_t)0x043E, (wchar_t)0x043F, (wchar_t)0x0440, (wchar_t)0x0441, (wchar_t)0x0442, (wchar_t)0x0443, (wchar_t)0x0444, (wchar_t)0x0445,
89   (wchar_t)0x0446, (wchar_t)0x0447, (wchar_t)0x0448, (wchar_t)0x0449, (wchar_t)0x044A, (wchar_t)0x044B, (wchar_t)0x044C, (wchar_t)0x044D, (wchar_t)0x044E,
90   (wchar_t)0x044F, (wchar_t)0x0451, (wchar_t)0x0452, (wchar_t)0x0453, (wchar_t)0x0454, (wchar_t)0x0455, (wchar_t)0x0456, (wchar_t)0x0457, (wchar_t)0x0458,
91   (wchar_t)0x0459, (wchar_t)0x045A, (wchar_t)0x045B, (wchar_t)0x045C, (wchar_t)0x045E, (wchar_t)0x045F, (wchar_t)0x0461, (wchar_t)0x0463, (wchar_t)0x0465,
92   (wchar_t)0x0467, (wchar_t)0x0469, (wchar_t)0x046B, (wchar_t)0x046D, (wchar_t)0x046F, (wchar_t)0x0471, (wchar_t)0x0473, (wchar_t)0x0475, (wchar_t)0x0477,
93   (wchar_t)0x0479, (wchar_t)0x047B, (wchar_t)0x047D, (wchar_t)0x047F, (wchar_t)0x0481, (wchar_t)0x0491, (wchar_t)0x0493, (wchar_t)0x0495, (wchar_t)0x0497,
94   (wchar_t)0x0499, (wchar_t)0x049B, (wchar_t)0x049D, (wchar_t)0x049F, (wchar_t)0x04A1, (wchar_t)0x04A3, (wchar_t)0x04A5, (wchar_t)0x04A7, (wchar_t)0x04A9,
95   (wchar_t)0x04AB, (wchar_t)0x04AD, (wchar_t)0x04AF, (wchar_t)0x04B1, (wchar_t)0x04B3, (wchar_t)0x04B5, (wchar_t)0x04B7, (wchar_t)0x04B9, (wchar_t)0x04BB,
96   (wchar_t)0x04BD, (wchar_t)0x04BF, (wchar_t)0x04C2, (wchar_t)0x04C4, (wchar_t)0x04C8, (wchar_t)0x04CC, (wchar_t)0x04D1, (wchar_t)0x04D3, (wchar_t)0x04D5,
97   (wchar_t)0x04D7, (wchar_t)0x04D9, (wchar_t)0x04DB, (wchar_t)0x04DD, (wchar_t)0x04DF, (wchar_t)0x04E1, (wchar_t)0x04E3, (wchar_t)0x04E5, (wchar_t)0x04E7,
98   (wchar_t)0x04E9, (wchar_t)0x04EB, (wchar_t)0x04EF, (wchar_t)0x04F1, (wchar_t)0x04F3, (wchar_t)0x04F5, (wchar_t)0x04F9, (wchar_t)0x0561, (wchar_t)0x0562,
99   (wchar_t)0x0563, (wchar_t)0x0564, (wchar_t)0x0565, (wchar_t)0x0566, (wchar_t)0x0567, (wchar_t)0x0568, (wchar_t)0x0569, (wchar_t)0x056A, (wchar_t)0x056B,
100   (wchar_t)0x056C, (wchar_t)0x056D, (wchar_t)0x056E, (wchar_t)0x056F, (wchar_t)0x0570, (wchar_t)0x0571, (wchar_t)0x0572, (wchar_t)0x0573, (wchar_t)0x0574,
101   (wchar_t)0x0575, (wchar_t)0x0576, (wchar_t)0x0577, (wchar_t)0x0578, (wchar_t)0x0579, (wchar_t)0x057A, (wchar_t)0x057B, (wchar_t)0x057C, (wchar_t)0x057D,
102   (wchar_t)0x057E, (wchar_t)0x057F, (wchar_t)0x0580, (wchar_t)0x0581, (wchar_t)0x0582, (wchar_t)0x0583, (wchar_t)0x0584, (wchar_t)0x0585, (wchar_t)0x0586,
103   (wchar_t)0x10D0, (wchar_t)0x10D1, (wchar_t)0x10D2, (wchar_t)0x10D3, (wchar_t)0x10D4, (wchar_t)0x10D5, (wchar_t)0x10D6, (wchar_t)0x10D7, (wchar_t)0x10D8,
104   (wchar_t)0x10D9, (wchar_t)0x10DA, (wchar_t)0x10DB, (wchar_t)0x10DC, (wchar_t)0x10DD, (wchar_t)0x10DE, (wchar_t)0x10DF, (wchar_t)0x10E0, (wchar_t)0x10E1,
105   (wchar_t)0x10E2, (wchar_t)0x10E3, (wchar_t)0x10E4, (wchar_t)0x10E5, (wchar_t)0x10E6, (wchar_t)0x10E7, (wchar_t)0x10E8, (wchar_t)0x10E9, (wchar_t)0x10EA,
106   (wchar_t)0x10EB, (wchar_t)0x10EC, (wchar_t)0x10ED, (wchar_t)0x10EE, (wchar_t)0x10EF, (wchar_t)0x10F0, (wchar_t)0x10F1, (wchar_t)0x10F2, (wchar_t)0x10F3,
107   (wchar_t)0x10F4, (wchar_t)0x10F5, (wchar_t)0x1E01, (wchar_t)0x1E03, (wchar_t)0x1E05, (wchar_t)0x1E07, (wchar_t)0x1E09, (wchar_t)0x1E0B, (wchar_t)0x1E0D,
108   (wchar_t)0x1E0F, (wchar_t)0x1E11, (wchar_t)0x1E13, (wchar_t)0x1E15, (wchar_t)0x1E17, (wchar_t)0x1E19, (wchar_t)0x1E1B, (wchar_t)0x1E1D, (wchar_t)0x1E1F,
109   (wchar_t)0x1E21, (wchar_t)0x1E23, (wchar_t)0x1E25, (wchar_t)0x1E27, (wchar_t)0x1E29, (wchar_t)0x1E2B, (wchar_t)0x1E2D, (wchar_t)0x1E2F, (wchar_t)0x1E31,
110   (wchar_t)0x1E33, (wchar_t)0x1E35, (wchar_t)0x1E37, (wchar_t)0x1E39, (wchar_t)0x1E3B, (wchar_t)0x1E3D, (wchar_t)0x1E3F, (wchar_t)0x1E41, (wchar_t)0x1E43,
111   (wchar_t)0x1E45, (wchar_t)0x1E47, (wchar_t)0x1E49, (wchar_t)0x1E4B, (wchar_t)0x1E4D, (wchar_t)0x1E4F, (wchar_t)0x1E51, (wchar_t)0x1E53, (wchar_t)0x1E55,
112   (wchar_t)0x1E57, (wchar_t)0x1E59, (wchar_t)0x1E5B, (wchar_t)0x1E5D, (wchar_t)0x1E5F, (wchar_t)0x1E61, (wchar_t)0x1E63, (wchar_t)0x1E65, (wchar_t)0x1E67,
113   (wchar_t)0x1E69, (wchar_t)0x1E6B, (wchar_t)0x1E6D, (wchar_t)0x1E6F, (wchar_t)0x1E71, (wchar_t)0x1E73, (wchar_t)0x1E75, (wchar_t)0x1E77, (wchar_t)0x1E79,
114   (wchar_t)0x1E7B, (wchar_t)0x1E7D, (wchar_t)0x1E7F, (wchar_t)0x1E81, (wchar_t)0x1E83, (wchar_t)0x1E85, (wchar_t)0x1E87, (wchar_t)0x1E89, (wchar_t)0x1E8B,
115   (wchar_t)0x1E8D, (wchar_t)0x1E8F, (wchar_t)0x1E91, (wchar_t)0x1E93, (wchar_t)0x1E95, (wchar_t)0x1EA1, (wchar_t)0x1EA3, (wchar_t)0x1EA5, (wchar_t)0x1EA7,
116   (wchar_t)0x1EA9, (wchar_t)0x1EAB, (wchar_t)0x1EAD, (wchar_t)0x1EAF, (wchar_t)0x1EB1, (wchar_t)0x1EB3, (wchar_t)0x1EB5, (wchar_t)0x1EB7, (wchar_t)0x1EB9,
117   (wchar_t)0x1EBB, (wchar_t)0x1EBD, (wchar_t)0x1EBF, (wchar_t)0x1EC1, (wchar_t)0x1EC3, (wchar_t)0x1EC5, (wchar_t)0x1EC7, (wchar_t)0x1EC9, (wchar_t)0x1ECB,
118   (wchar_t)0x1ECD, (wchar_t)0x1ECF, (wchar_t)0x1ED1, (wchar_t)0x1ED3, (wchar_t)0x1ED5, (wchar_t)0x1ED7, (wchar_t)0x1ED9, (wchar_t)0x1EDB, (wchar_t)0x1EDD,
119   (wchar_t)0x1EDF, (wchar_t)0x1EE1, (wchar_t)0x1EE3, (wchar_t)0x1EE5, (wchar_t)0x1EE7, (wchar_t)0x1EE9, (wchar_t)0x1EEB, (wchar_t)0x1EED, (wchar_t)0x1EEF,
120   (wchar_t)0x1EF1, (wchar_t)0x1EF3, (wchar_t)0x1EF5, (wchar_t)0x1EF7, (wchar_t)0x1EF9, (wchar_t)0x1F00, (wchar_t)0x1F01, (wchar_t)0x1F02, (wchar_t)0x1F03,
121   (wchar_t)0x1F04, (wchar_t)0x1F05, (wchar_t)0x1F06, (wchar_t)0x1F07, (wchar_t)0x1F10, (wchar_t)0x1F11, (wchar_t)0x1F12, (wchar_t)0x1F13, (wchar_t)0x1F14,
122   (wchar_t)0x1F15, (wchar_t)0x1F20, (wchar_t)0x1F21, (wchar_t)0x1F22, (wchar_t)0x1F23, (wchar_t)0x1F24, (wchar_t)0x1F25, (wchar_t)0x1F26, (wchar_t)0x1F27,
123   (wchar_t)0x1F30, (wchar_t)0x1F31, (wchar_t)0x1F32, (wchar_t)0x1F33, (wchar_t)0x1F34, (wchar_t)0x1F35, (wchar_t)0x1F36, (wchar_t)0x1F37, (wchar_t)0x1F40,
124   (wchar_t)0x1F41, (wchar_t)0x1F42, (wchar_t)0x1F43, (wchar_t)0x1F44, (wchar_t)0x1F45, (wchar_t)0x1F51, (wchar_t)0x1F53, (wchar_t)0x1F55, (wchar_t)0x1F57,
125   (wchar_t)0x1F60, (wchar_t)0x1F61, (wchar_t)0x1F62, (wchar_t)0x1F63, (wchar_t)0x1F64, (wchar_t)0x1F65, (wchar_t)0x1F66, (wchar_t)0x1F67, (wchar_t)0x1F80,
126   (wchar_t)0x1F81, (wchar_t)0x1F82, (wchar_t)0x1F83, (wchar_t)0x1F84, (wchar_t)0x1F85, (wchar_t)0x1F86, (wchar_t)0x1F87, (wchar_t)0x1F90, (wchar_t)0x1F91,
127   (wchar_t)0x1F92, (wchar_t)0x1F93, (wchar_t)0x1F94, (wchar_t)0x1F95, (wchar_t)0x1F96, (wchar_t)0x1F97, (wchar_t)0x1FA0, (wchar_t)0x1FA1, (wchar_t)0x1FA2,
128   (wchar_t)0x1FA3, (wchar_t)0x1FA4, (wchar_t)0x1FA5, (wchar_t)0x1FA6, (wchar_t)0x1FA7, (wchar_t)0x1FB0, (wchar_t)0x1FB1, (wchar_t)0x1FD0, (wchar_t)0x1FD1,
129   (wchar_t)0x1FE0, (wchar_t)0x1FE1, (wchar_t)0x24D0, (wchar_t)0x24D1, (wchar_t)0x24D2, (wchar_t)0x24D3, (wchar_t)0x24D4, (wchar_t)0x24D5, (wchar_t)0x24D6,
130   (wchar_t)0x24D7, (wchar_t)0x24D8, (wchar_t)0x24D9, (wchar_t)0x24DA, (wchar_t)0x24DB, (wchar_t)0x24DC, (wchar_t)0x24DD, (wchar_t)0x24DE, (wchar_t)0x24DF,
131   (wchar_t)0x24E0, (wchar_t)0x24E1, (wchar_t)0x24E2, (wchar_t)0x24E3, (wchar_t)0x24E4, (wchar_t)0x24E5, (wchar_t)0x24E6, (wchar_t)0x24E7, (wchar_t)0x24E8,
132   (wchar_t)0x24E9, (wchar_t)0xFF41, (wchar_t)0xFF42, (wchar_t)0xFF43, (wchar_t)0xFF44, (wchar_t)0xFF45, (wchar_t)0xFF46, (wchar_t)0xFF47, (wchar_t)0xFF48,
133   (wchar_t)0xFF49, (wchar_t)0xFF4A, (wchar_t)0xFF4B, (wchar_t)0xFF4C, (wchar_t)0xFF4D, (wchar_t)0xFF4E, (wchar_t)0xFF4F, (wchar_t)0xFF50, (wchar_t)0xFF51,
134   (wchar_t)0xFF52, (wchar_t)0xFF53, (wchar_t)0xFF54, (wchar_t)0xFF55, (wchar_t)0xFF56, (wchar_t)0xFF57, (wchar_t)0xFF58, (wchar_t)0xFF59, (wchar_t)0xFF5A
135 };
136
137 static const wchar_t unicode_uppers[] = {
138   (wchar_t)0x0041, (wchar_t)0x0042, (wchar_t)0x0043, (wchar_t)0x0044, (wchar_t)0x0045, (wchar_t)0x0046, (wchar_t)0x0047, (wchar_t)0x0048, (wchar_t)0x0049,
139   (wchar_t)0x004A, (wchar_t)0x004B, (wchar_t)0x004C, (wchar_t)0x004D, (wchar_t)0x004E, (wchar_t)0x004F, (wchar_t)0x0050, (wchar_t)0x0051, (wchar_t)0x0052,
140   (wchar_t)0x0053, (wchar_t)0x0054, (wchar_t)0x0055, (wchar_t)0x0056, (wchar_t)0x0057, (wchar_t)0x0058, (wchar_t)0x0059, (wchar_t)0x005A, (wchar_t)0x00C0,
141   (wchar_t)0x00C1, (wchar_t)0x00C2, (wchar_t)0x00C3, (wchar_t)0x00C4, (wchar_t)0x00C5, (wchar_t)0x00C6, (wchar_t)0x00C7, (wchar_t)0x00C8, (wchar_t)0x00C9,
142   (wchar_t)0x00CA, (wchar_t)0x00CB, (wchar_t)0x00CC, (wchar_t)0x00CD, (wchar_t)0x00CE, (wchar_t)0x00CF, (wchar_t)0x00D0, (wchar_t)0x00D1, (wchar_t)0x00D2,
143   (wchar_t)0x00D3, (wchar_t)0x00D4, (wchar_t)0x00D5, (wchar_t)0x00D6, (wchar_t)0x00D8, (wchar_t)0x00D9, (wchar_t)0x00DA, (wchar_t)0x00DB, (wchar_t)0x00DC,
144   (wchar_t)0x00DD, (wchar_t)0x00DE, (wchar_t)0x0178, (wchar_t)0x0100, (wchar_t)0x0102, (wchar_t)0x0104, (wchar_t)0x0106, (wchar_t)0x0108, (wchar_t)0x010A,
145   (wchar_t)0x010C, (wchar_t)0x010E, (wchar_t)0x0110, (wchar_t)0x0112, (wchar_t)0x0114, (wchar_t)0x0116, (wchar_t)0x0118, (wchar_t)0x011A, (wchar_t)0x011C,
146   (wchar_t)0x011E, (wchar_t)0x0120, (wchar_t)0x0122, (wchar_t)0x0124, (wchar_t)0x0126, (wchar_t)0x0128, (wchar_t)0x012A, (wchar_t)0x012C, (wchar_t)0x012E,
147   (wchar_t)0x0049, (wchar_t)0x0132, (wchar_t)0x0134, (wchar_t)0x0136, (wchar_t)0x0139, (wchar_t)0x013B, (wchar_t)0x013D, (wchar_t)0x013F, (wchar_t)0x0141,
148   (wchar_t)0x0143, (wchar_t)0x0145, (wchar_t)0x0147, (wchar_t)0x014A, (wchar_t)0x014C, (wchar_t)0x014E, (wchar_t)0x0150, (wchar_t)0x0152, (wchar_t)0x0154,
149   (wchar_t)0x0156, (wchar_t)0x0158, (wchar_t)0x015A, (wchar_t)0x015C, (wchar_t)0x015E, (wchar_t)0x0160, (wchar_t)0x0162, (wchar_t)0x0164, (wchar_t)0x0166,
150   (wchar_t)0x0168, (wchar_t)0x016A, (wchar_t)0x016C, (wchar_t)0x016E, (wchar_t)0x0170, (wchar_t)0x0172, (wchar_t)0x0174, (wchar_t)0x0176, (wchar_t)0x0179,
151   (wchar_t)0x017B, (wchar_t)0x017D, (wchar_t)0x0182, (wchar_t)0x0184, (wchar_t)0x0187, (wchar_t)0x018B, (wchar_t)0x0191, (wchar_t)0x0198, (wchar_t)0x01A0,
152   (wchar_t)0x01A2, (wchar_t)0x01A4, (wchar_t)0x01A7, (wchar_t)0x01AC, (wchar_t)0x01AF, (wchar_t)0x01B3, (wchar_t)0x01B5, (wchar_t)0x01B8, (wchar_t)0x01BC,
153   (wchar_t)0x01C4, (wchar_t)0x01C7, (wchar_t)0x01CA, (wchar_t)0x01CD, (wchar_t)0x01CF, (wchar_t)0x01D1, (wchar_t)0x01D3, (wchar_t)0x01D5, (wchar_t)0x01D7,
154   (wchar_t)0x01D9, (wchar_t)0x01DB, (wchar_t)0x01DE, (wchar_t)0x01E0, (wchar_t)0x01E2, (wchar_t)0x01E4, (wchar_t)0x01E6, (wchar_t)0x01E8, (wchar_t)0x01EA,
155   (wchar_t)0x01EC, (wchar_t)0x01EE, (wchar_t)0x01F1, (wchar_t)0x01F4, (wchar_t)0x01FA, (wchar_t)0x01FC, (wchar_t)0x01FE, (wchar_t)0x0200, (wchar_t)0x0202,
156   (wchar_t)0x0204, (wchar_t)0x0206, (wchar_t)0x0208, (wchar_t)0x020A, (wchar_t)0x020C, (wchar_t)0x020E, (wchar_t)0x0210, (wchar_t)0x0212, (wchar_t)0x0214,
157   (wchar_t)0x0216, (wchar_t)0x0181, (wchar_t)0x0186, (wchar_t)0x018A, (wchar_t)0x018E, (wchar_t)0x018F, (wchar_t)0x0190, (wchar_t)0x0193, (wchar_t)0x0194,
158   (wchar_t)0x0197, (wchar_t)0x0196, (wchar_t)0x019C, (wchar_t)0x019D, (wchar_t)0x019F, (wchar_t)0x01A9, (wchar_t)0x01AE, (wchar_t)0x01B1, (wchar_t)0x01B2,
159   (wchar_t)0x01B7, (wchar_t)0x0386, (wchar_t)0x0388, (wchar_t)0x0389, (wchar_t)0x038A, (wchar_t)0x0391, (wchar_t)0x0392, (wchar_t)0x0393, (wchar_t)0x0394,
160   (wchar_t)0x0395, (wchar_t)0x0396, (wchar_t)0x0397, (wchar_t)0x0398, (wchar_t)0x0399, (wchar_t)0x039A, (wchar_t)0x039B, (wchar_t)0x039C, (wchar_t)0x039D,
161   (wchar_t)0x039E, (wchar_t)0x039F, (wchar_t)0x03A0, (wchar_t)0x03A1, (wchar_t)0x03A3, (wchar_t)0x03A4, (wchar_t)0x03A5, (wchar_t)0x03A6, (wchar_t)0x03A7,
162   (wchar_t)0x03A8, (wchar_t)0x03A9, (wchar_t)0x03AA, (wchar_t)0x03AB, (wchar_t)0x038C, (wchar_t)0x038E, (wchar_t)0x038F, (wchar_t)0x03E2, (wchar_t)0x03E4,
163   (wchar_t)0x03E6, (wchar_t)0x03E8, (wchar_t)0x03EA, (wchar_t)0x03EC, (wchar_t)0x03EE, (wchar_t)0x0410, (wchar_t)0x0411, (wchar_t)0x0412, (wchar_t)0x0413,
164   (wchar_t)0x0414, (wchar_t)0x0415, (wchar_t)0x0416, (wchar_t)0x0417, (wchar_t)0x0418, (wchar_t)0x0419, (wchar_t)0x041A, (wchar_t)0x041B, (wchar_t)0x041C,
165   (wchar_t)0x041D, (wchar_t)0x041E, (wchar_t)0x041F, (wchar_t)0x0420, (wchar_t)0x0421, (wchar_t)0x0422, (wchar_t)0x0423, (wchar_t)0x0424, (wchar_t)0x0425,
166   (wchar_t)0x0426, (wchar_t)0x0427, (wchar_t)0x0428, (wchar_t)0x0429, (wchar_t)0x042A, (wchar_t)0x042B, (wchar_t)0x042C, (wchar_t)0x042D, (wchar_t)0x042E,
167   (wchar_t)0x042F, (wchar_t)0x0401, (wchar_t)0x0402, (wchar_t)0x0403, (wchar_t)0x0404, (wchar_t)0x0405, (wchar_t)0x0406, (wchar_t)0x0407, (wchar_t)0x0408,
168   (wchar_t)0x0409, (wchar_t)0x040A, (wchar_t)0x040B, (wchar_t)0x040C, (wchar_t)0x040E, (wchar_t)0x040F, (wchar_t)0x0460, (wchar_t)0x0462, (wchar_t)0x0464,
169   (wchar_t)0x0466, (wchar_t)0x0468, (wchar_t)0x046A, (wchar_t)0x046C, (wchar_t)0x046E, (wchar_t)0x0470, (wchar_t)0x0472, (wchar_t)0x0474, (wchar_t)0x0476,
170   (wchar_t)0x0478, (wchar_t)0x047A, (wchar_t)0x047C, (wchar_t)0x047E, (wchar_t)0x0480, (wchar_t)0x0490, (wchar_t)0x0492, (wchar_t)0x0494, (wchar_t)0x0496,
171   (wchar_t)0x0498, (wchar_t)0x049A, (wchar_t)0x049C, (wchar_t)0x049E, (wchar_t)0x04A0, (wchar_t)0x04A2, (wchar_t)0x04A4, (wchar_t)0x04A6, (wchar_t)0x04A8,
172   (wchar_t)0x04AA, (wchar_t)0x04AC, (wchar_t)0x04AE, (wchar_t)0x04B0, (wchar_t)0x04B2, (wchar_t)0x04B4, (wchar_t)0x04B6, (wchar_t)0x04B8, (wchar_t)0x04BA,
173   (wchar_t)0x04BC, (wchar_t)0x04BE, (wchar_t)0x04C1, (wchar_t)0x04C3, (wchar_t)0x04C7, (wchar_t)0x04CB, (wchar_t)0x04D0, (wchar_t)0x04D2, (wchar_t)0x04D4,
174   (wchar_t)0x04D6, (wchar_t)0x04D8, (wchar_t)0x04DA, (wchar_t)0x04DC, (wchar_t)0x04DE, (wchar_t)0x04E0, (wchar_t)0x04E2, (wchar_t)0x04E4, (wchar_t)0x04E6,
175   (wchar_t)0x04E8, (wchar_t)0x04EA, (wchar_t)0x04EE, (wchar_t)0x04F0, (wchar_t)0x04F2, (wchar_t)0x04F4, (wchar_t)0x04F8, (wchar_t)0x0531, (wchar_t)0x0532,
176   (wchar_t)0x0533, (wchar_t)0x0534, (wchar_t)0x0535, (wchar_t)0x0536, (wchar_t)0x0537, (wchar_t)0x0538, (wchar_t)0x0539, (wchar_t)0x053A, (wchar_t)0x053B,
177   (wchar_t)0x053C, (wchar_t)0x053D, (wchar_t)0x053E, (wchar_t)0x053F, (wchar_t)0x0540, (wchar_t)0x0541, (wchar_t)0x0542, (wchar_t)0x0543, (wchar_t)0x0544,
178   (wchar_t)0x0545, (wchar_t)0x0546, (wchar_t)0x0547, (wchar_t)0x0548, (wchar_t)0x0549, (wchar_t)0x054A, (wchar_t)0x054B, (wchar_t)0x054C, (wchar_t)0x054D,
179   (wchar_t)0x054E, (wchar_t)0x054F, (wchar_t)0x0550, (wchar_t)0x0551, (wchar_t)0x0552, (wchar_t)0x0553, (wchar_t)0x0554, (wchar_t)0x0555, (wchar_t)0x0556,
180   (wchar_t)0x10A0, (wchar_t)0x10A1, (wchar_t)0x10A2, (wchar_t)0x10A3, (wchar_t)0x10A4, (wchar_t)0x10A5, (wchar_t)0x10A6, (wchar_t)0x10A7, (wchar_t)0x10A8,
181   (wchar_t)0x10A9, (wchar_t)0x10AA, (wchar_t)0x10AB, (wchar_t)0x10AC, (wchar_t)0x10AD, (wchar_t)0x10AE, (wchar_t)0x10AF, (wchar_t)0x10B0, (wchar_t)0x10B1,
182   (wchar_t)0x10B2, (wchar_t)0x10B3, (wchar_t)0x10B4, (wchar_t)0x10B5, (wchar_t)0x10B6, (wchar_t)0x10B7, (wchar_t)0x10B8, (wchar_t)0x10B9, (wchar_t)0x10BA,
183   (wchar_t)0x10BB, (wchar_t)0x10BC, (wchar_t)0x10BD, (wchar_t)0x10BE, (wchar_t)0x10BF, (wchar_t)0x10C0, (wchar_t)0x10C1, (wchar_t)0x10C2, (wchar_t)0x10C3,
184   (wchar_t)0x10C4, (wchar_t)0x10C5, (wchar_t)0x1E00, (wchar_t)0x1E02, (wchar_t)0x1E04, (wchar_t)0x1E06, (wchar_t)0x1E08, (wchar_t)0x1E0A, (wchar_t)0x1E0C,
185   (wchar_t)0x1E0E, (wchar_t)0x1E10, (wchar_t)0x1E12, (wchar_t)0x1E14, (wchar_t)0x1E16, (wchar_t)0x1E18, (wchar_t)0x1E1A, (wchar_t)0x1E1C, (wchar_t)0x1E1E,
186   (wchar_t)0x1E20, (wchar_t)0x1E22, (wchar_t)0x1E24, (wchar_t)0x1E26, (wchar_t)0x1E28, (wchar_t)0x1E2A, (wchar_t)0x1E2C, (wchar_t)0x1E2E, (wchar_t)0x1E30,
187   (wchar_t)0x1E32, (wchar_t)0x1E34, (wchar_t)0x1E36, (wchar_t)0x1E38, (wchar_t)0x1E3A, (wchar_t)0x1E3C, (wchar_t)0x1E3E, (wchar_t)0x1E40, (wchar_t)0x1E42,
188   (wchar_t)0x1E44, (wchar_t)0x1E46, (wchar_t)0x1E48, (wchar_t)0x1E4A, (wchar_t)0x1E4C, (wchar_t)0x1E4E, (wchar_t)0x1E50, (wchar_t)0x1E52, (wchar_t)0x1E54,
189   (wchar_t)0x1E56, (wchar_t)0x1E58, (wchar_t)0x1E5A, (wchar_t)0x1E5C, (wchar_t)0x1E5E, (wchar_t)0x1E60, (wchar_t)0x1E62, (wchar_t)0x1E64, (wchar_t)0x1E66,
190   (wchar_t)0x1E68, (wchar_t)0x1E6A, (wchar_t)0x1E6C, (wchar_t)0x1E6E, (wchar_t)0x1E70, (wchar_t)0x1E72, (wchar_t)0x1E74, (wchar_t)0x1E76, (wchar_t)0x1E78,
191   (wchar_t)0x1E7A, (wchar_t)0x1E7C, (wchar_t)0x1E7E, (wchar_t)0x1E80, (wchar_t)0x1E82, (wchar_t)0x1E84, (wchar_t)0x1E86, (wchar_t)0x1E88, (wchar_t)0x1E8A,
192   (wchar_t)0x1E8C, (wchar_t)0x1E8E, (wchar_t)0x1E90, (wchar_t)0x1E92, (wchar_t)0x1E94, (wchar_t)0x1EA0, (wchar_t)0x1EA2, (wchar_t)0x1EA4, (wchar_t)0x1EA6,
193   (wchar_t)0x1EA8, (wchar_t)0x1EAA, (wchar_t)0x1EAC, (wchar_t)0x1EAE, (wchar_t)0x1EB0, (wchar_t)0x1EB2, (wchar_t)0x1EB4, (wchar_t)0x1EB6, (wchar_t)0x1EB8,
194   (wchar_t)0x1EBA, (wchar_t)0x1EBC, (wchar_t)0x1EBE, (wchar_t)0x1EC0, (wchar_t)0x1EC2, (wchar_t)0x1EC4, (wchar_t)0x1EC6, (wchar_t)0x1EC8, (wchar_t)0x1ECA,
195   (wchar_t)0x1ECC, (wchar_t)0x1ECE, (wchar_t)0x1ED0, (wchar_t)0x1ED2, (wchar_t)0x1ED4, (wchar_t)0x1ED6, (wchar_t)0x1ED8, (wchar_t)0x1EDA, (wchar_t)0x1EDC,
196   (wchar_t)0x1EDE, (wchar_t)0x1EE0, (wchar_t)0x1EE2, (wchar_t)0x1EE4, (wchar_t)0x1EE6, (wchar_t)0x1EE8, (wchar_t)0x1EEA, (wchar_t)0x1EEC, (wchar_t)0x1EEE,
197   (wchar_t)0x1EF0, (wchar_t)0x1EF2, (wchar_t)0x1EF4, (wchar_t)0x1EF6, (wchar_t)0x1EF8, (wchar_t)0x1F08, (wchar_t)0x1F09, (wchar_t)0x1F0A, (wchar_t)0x1F0B,
198   (wchar_t)0x1F0C, (wchar_t)0x1F0D, (wchar_t)0x1F0E, (wchar_t)0x1F0F, (wchar_t)0x1F18, (wchar_t)0x1F19, (wchar_t)0x1F1A, (wchar_t)0x1F1B, (wchar_t)0x1F1C,
199   (wchar_t)0x1F1D, (wchar_t)0x1F28, (wchar_t)0x1F29, (wchar_t)0x1F2A, (wchar_t)0x1F2B, (wchar_t)0x1F2C, (wchar_t)0x1F2D, (wchar_t)0x1F2E, (wchar_t)0x1F2F,
200   (wchar_t)0x1F38, (wchar_t)0x1F39, (wchar_t)0x1F3A, (wchar_t)0x1F3B, (wchar_t)0x1F3C, (wchar_t)0x1F3D, (wchar_t)0x1F3E, (wchar_t)0x1F3F, (wchar_t)0x1F48,
201   (wchar_t)0x1F49, (wchar_t)0x1F4A, (wchar_t)0x1F4B, (wchar_t)0x1F4C, (wchar_t)0x1F4D, (wchar_t)0x1F59, (wchar_t)0x1F5B, (wchar_t)0x1F5D, (wchar_t)0x1F5F,
202   (wchar_t)0x1F68, (wchar_t)0x1F69, (wchar_t)0x1F6A, (wchar_t)0x1F6B, (wchar_t)0x1F6C, (wchar_t)0x1F6D, (wchar_t)0x1F6E, (wchar_t)0x1F6F, (wchar_t)0x1F88,
203   (wchar_t)0x1F89, (wchar_t)0x1F8A, (wchar_t)0x1F8B, (wchar_t)0x1F8C, (wchar_t)0x1F8D, (wchar_t)0x1F8E, (wchar_t)0x1F8F, (wchar_t)0x1F98, (wchar_t)0x1F99,
204   (wchar_t)0x1F9A, (wchar_t)0x1F9B, (wchar_t)0x1F9C, (wchar_t)0x1F9D, (wchar_t)0x1F9E, (wchar_t)0x1F9F, (wchar_t)0x1FA8, (wchar_t)0x1FA9, (wchar_t)0x1FAA,
205   (wchar_t)0x1FAB, (wchar_t)0x1FAC, (wchar_t)0x1FAD, (wchar_t)0x1FAE, (wchar_t)0x1FAF, (wchar_t)0x1FB8, (wchar_t)0x1FB9, (wchar_t)0x1FD8, (wchar_t)0x1FD9,
206   (wchar_t)0x1FE8, (wchar_t)0x1FE9, (wchar_t)0x24B6, (wchar_t)0x24B7, (wchar_t)0x24B8, (wchar_t)0x24B9, (wchar_t)0x24BA, (wchar_t)0x24BB, (wchar_t)0x24BC,
207   (wchar_t)0x24BD, (wchar_t)0x24BE, (wchar_t)0x24BF, (wchar_t)0x24C0, (wchar_t)0x24C1, (wchar_t)0x24C2, (wchar_t)0x24C3, (wchar_t)0x24C4, (wchar_t)0x24C5,
208   (wchar_t)0x24C6, (wchar_t)0x24C7, (wchar_t)0x24C8, (wchar_t)0x24C9, (wchar_t)0x24CA, (wchar_t)0x24CB, (wchar_t)0x24CC, (wchar_t)0x24CD, (wchar_t)0x24CE,
209   (wchar_t)0x24CF, (wchar_t)0xFF21, (wchar_t)0xFF22, (wchar_t)0xFF23, (wchar_t)0xFF24, (wchar_t)0xFF25, (wchar_t)0xFF26, (wchar_t)0xFF27, (wchar_t)0xFF28,
210   (wchar_t)0xFF29, (wchar_t)0xFF2A, (wchar_t)0xFF2B, (wchar_t)0xFF2C, (wchar_t)0xFF2D, (wchar_t)0xFF2E, (wchar_t)0xFF2F, (wchar_t)0xFF30, (wchar_t)0xFF31,
211   (wchar_t)0xFF32, (wchar_t)0xFF33, (wchar_t)0xFF34, (wchar_t)0xFF35, (wchar_t)0xFF36, (wchar_t)0xFF37, (wchar_t)0xFF38, (wchar_t)0xFF39, (wchar_t)0xFF3A
212 };
213
214 string StringUtils::Format(const char *fmt, ...)
215 {
216   va_list args;
217   va_start(args, fmt);
218   string str = FormatV(fmt, args);
219   va_end(args);
220
221   return str;
222 }
223
224 string StringUtils::FormatV(const char *fmt, va_list args)
225 {
226   if (fmt == NULL)
227     return "";
228
229   int size = FORMAT_BLOCK_SIZE;
230   va_list argCopy;
231
232   char *cstr = reinterpret_cast<char*>(malloc(sizeof(char) * size));
233   if (cstr == NULL)
234     return "";
235
236   while (1) 
237   {
238     va_copy(argCopy, args);
239
240     int nActual = vsnprintf(cstr, size, fmt, argCopy);
241     va_end(argCopy);
242
243     if (nActual > -1 && nActual < size) // We got a valid result
244     {
245       string str(cstr, nActual);
246       free(cstr);
247       return str;
248     }
249     if (nActual > -1)                   // Exactly what we will need (glibc 2.1)
250       size = nActual + 1;
251     else                                // Let's try to double the size (glibc 2.0)
252       size *= 2;
253
254     char *new_cstr = reinterpret_cast<char*>(realloc(cstr, sizeof(char) * size));
255     if (new_cstr == NULL)
256     {
257       free(cstr);
258       return "";
259     }
260
261     cstr = new_cstr;
262   }
263
264   free(cstr);
265   return "";
266 }
267
268 wstring StringUtils::Format(const wchar_t *fmt, ...)
269 {
270   va_list args;
271   va_start(args, fmt);
272   wstring str = FormatV(fmt, args);
273   va_end(args);
274   
275   return str;
276 }
277
278 wstring StringUtils::FormatV(const wchar_t *fmt, va_list args)
279 {
280   if (fmt == NULL)
281     return L"";
282   
283   int size = FORMAT_BLOCK_SIZE;
284   va_list argCopy;
285   
286   wchar_t *cstr = reinterpret_cast<wchar_t*>(malloc(sizeof(wchar_t) * size));
287   if (cstr == NULL)
288     return L"";
289   
290   while (1)
291   {
292     va_copy(argCopy, args);
293     
294     int nActual = vswprintf(cstr, size, fmt, argCopy);
295     va_end(argCopy);
296     
297     if (nActual > -1 && nActual < size) // We got a valid result
298     {
299       wstring str(cstr, nActual);
300       free(cstr);
301       return str;
302     }
303     if (nActual > -1)                   // Exactly what we will need (glibc 2.1)
304       size = nActual + 1;
305     else                                // Let's try to double the size (glibc 2.0)
306       size *= 2;
307     
308     wchar_t *new_cstr = reinterpret_cast<wchar_t*>(realloc(cstr, sizeof(wchar_t) * size));
309     if (new_cstr == NULL)
310     {
311       free(cstr);
312       return L"";
313     }
314     
315     cstr = new_cstr;
316   }
317   
318   return L"";
319 }
320
321 int compareWchar (const void* a, const void* b)
322 {
323   if (*(wchar_t*)a <  *(wchar_t*)b)
324     return -1;
325   else if (*(wchar_t*)a >  *(wchar_t*)b)
326     return 1;
327   return 0;
328 }
329
330 wchar_t tolowerUnicode(const wchar_t& c)
331 {
332   wchar_t* p = (wchar_t*) bsearch (&c, unicode_uppers, sizeof(unicode_uppers) / sizeof(wchar_t), sizeof(wchar_t), compareWchar);
333   if (p)
334     return *(unicode_lowers + (p - unicode_uppers));
335
336   return c;
337 }
338
339 wchar_t toupperUnicode(const wchar_t& c)
340 {
341   wchar_t* p = (wchar_t*) bsearch (&c, unicode_lowers, sizeof(unicode_lowers) / sizeof(wchar_t), sizeof(wchar_t), compareWchar);
342   if (p)
343     return *(unicode_uppers + (p - unicode_lowers));
344
345   return c;
346 }
347
348 void StringUtils::ToUpper(string &str)
349 {
350   transform(str.begin(), str.end(), str.begin(), ::toupper);
351 }
352
353 void StringUtils::ToUpper(wstring &str)
354 {
355   transform(str.begin(), str.end(), str.begin(), toupperUnicode);
356 }
357
358 void StringUtils::ToLower(string &str)
359 {
360   transform(str.begin(), str.end(), str.begin(), ::tolower);
361 }
362
363 void StringUtils::ToLower(wstring &str)
364 {
365   transform(str.begin(), str.end(), str.begin(), tolowerUnicode);
366 }
367
368 bool StringUtils::EqualsNoCase(const std::string &str1, const std::string &str2)
369 {
370   return EqualsNoCase(str1.c_str(), str2.c_str());
371 }
372
373 bool StringUtils::EqualsNoCase(const std::string &str1, const char *s2)
374 {
375   return EqualsNoCase(str1.c_str(), s2);
376 }
377
378 bool StringUtils::EqualsNoCase(const char *s1, const char *s2)
379 {
380   char c2; // we need only one char outside the loop
381   do
382   {
383     const char c1 = *s1++; // const local variable should help compiler to optimize
384     c2 = *s2++;
385     if (c1 != c2 && ::tolower(c1) != ::tolower(c2)) // This includes the possibility that one of the characters is the null-terminator, which implies a string mismatch.
386       return false;
387   } while (c2 != '\0'); // At this point, we know c1 == c2, so there's no need to test them both.
388   return true;
389 }
390
391 int StringUtils::CompareNoCase(const std::string &str1, const std::string &str2)
392 {
393   return CompareNoCase(str1.c_str(), str2.c_str());
394 }
395
396 int StringUtils::CompareNoCase(const char *s1, const char *s2)
397 {
398   char c2; // we need only one char outside the loop
399   do
400   {
401     const char c1 = *s1++; // const local variable should help compiler to optimize
402     c2 = *s2++;
403     if (c1 != c2 && ::tolower(c1) != ::tolower(c2)) // This includes the possibility that one of the characters is the null-terminator, which implies a string mismatch.
404       return ::tolower(c1) - ::tolower(c2);
405   } while (c2 != '\0'); // At this point, we know c1 == c2, so there's no need to test them both.
406   return 0;
407 }
408
409 string StringUtils::Left(const string &str, size_t count)
410 {
411   count = max((size_t)0, min(count, str.size()));
412   return str.substr(0, count);
413 }
414
415 string StringUtils::Mid(const string &str, size_t first, size_t count /* = string::npos */)
416 {
417   if (first + count > str.size())
418     count = str.size() - first;
419   
420   if (first > str.size())
421     return string();
422   
423   ASSERT(first + count <= str.size());
424   
425   return str.substr(first, count);
426 }
427
428 string StringUtils::Right(const string &str, size_t count)
429 {
430   count = max((size_t)0, min(count, str.size()));
431   return str.substr(str.size() - count);
432 }
433
434 std::string& StringUtils::Trim(std::string &str)
435 {
436   TrimLeft(str);
437   return TrimRight(str);
438 }
439
440 std::string& StringUtils::Trim(std::string &str, const char* const chars)
441 {
442   TrimLeft(str, chars);
443   return TrimRight(str, chars);
444 }
445
446 // hack to ensure that std::string::iterator will be dereferenced as _unsigned_ char
447 // without this hack "TrimX" functions failed on Win32 with UTF-8 strings
448 static int isspace_c(char c)
449 {
450   return ::isspace((unsigned char)c);
451 }
452
453 std::string& StringUtils::TrimLeft(std::string &str)
454 {
455   str.erase(str.begin(), ::find_if(str.begin(), str.end(), ::not1(::ptr_fun(isspace_c))));
456   return str;
457 }
458
459 std::string& StringUtils::TrimLeft(std::string &str, const char* const chars)
460 {
461   size_t nidx = str.find_first_not_of(chars);
462   str.erase(0, nidx);
463   return str;
464 }
465
466 std::string& StringUtils::TrimRight(std::string &str)
467 {
468   str.erase(::find_if(str.rbegin(), str.rend(), ::not1(::ptr_fun(isspace_c))).base(), str.end());
469   return str;
470 }
471
472 std::string& StringUtils::TrimRight(std::string &str, const char* const chars)
473 {
474   size_t nidx = str.find_last_not_of(chars);
475   str.erase(str.npos == nidx ? 0 : ++nidx);
476   return str;
477 }
478
479 std::string& StringUtils::RemoveDuplicatedSpacesAndTabs(std::string& str)
480 {
481   std::string::iterator it = str.begin();
482   bool onSpace = false;
483   while(it != str.end())
484   {
485     if (*it == '\t')
486       *it = ' ';
487
488     if (*it == ' ')
489     {
490       if (onSpace)
491       {
492         it = str.erase(it);
493         continue;
494       }
495       else
496         onSpace = true;
497     }
498     else
499       onSpace = false;
500
501     ++it;
502   }
503   return str;
504 }
505
506 int StringUtils::Replace(string &str, char oldChar, char newChar)
507 {
508   int replacedChars = 0;
509   for (string::iterator it = str.begin(); it != str.end(); it++)
510   {
511     if (*it == oldChar)
512     {
513       *it = newChar;
514       replacedChars++;
515     }
516   }
517   
518   return replacedChars;
519 }
520
521 int StringUtils::Replace(std::string &str, const std::string &oldStr, const std::string &newStr)
522 {
523   if (oldStr.empty())
524     return 0;
525
526   int replacedChars = 0;
527   size_t index = 0;
528   
529   while (index < str.size() && (index = str.find(oldStr, index)) != string::npos)
530   {
531     str.replace(index, oldStr.size(), newStr);
532     index += newStr.size();
533     replacedChars++;
534   }
535   
536   return replacedChars;
537 }
538
539 int StringUtils::Replace(std::wstring &str, const std::wstring &oldStr, const std::wstring &newStr)
540 {
541   if (oldStr.empty())
542     return 0;
543
544   int replacedChars = 0;
545   size_t index = 0;
546
547   while (index < str.size() && (index = str.find(oldStr, index)) != string::npos)
548   {
549     str.replace(index, oldStr.size(), newStr);
550     index += newStr.size();
551     replacedChars++;
552   }
553
554   return replacedChars;
555 }
556
557 bool StringUtils::StartsWith(const std::string &str1, const std::string &str2)
558 {
559   return str1.compare(0, str2.size(), str2) == 0;
560 }
561
562 bool StringUtils::StartsWith(const std::string &str1, const char *s2)
563 {
564   return StartsWith(str1.c_str(), s2);
565 }
566
567 bool StringUtils::StartsWith(const char *s1, const char *s2)
568 {
569   while (*s2 != '\0')
570   {
571     if (*s1 != *s2)
572       return false;
573     s1++;
574     s2++;
575   }
576   return true;
577 }
578
579 bool StringUtils::StartsWithNoCase(const std::string &str1, const std::string &str2)
580 {
581   return StartsWithNoCase(str1.c_str(), str2.c_str());
582 }
583
584 bool StringUtils::StartsWithNoCase(const std::string &str1, const char *s2)
585 {
586   return StartsWithNoCase(str1.c_str(), s2);
587 }
588
589 bool StringUtils::StartsWithNoCase(const char *s1, const char *s2)
590 {
591   while (*s2 != '\0')
592   {
593     if (::tolower(*s1) != ::tolower(*s2))
594       return false;
595     s1++;
596     s2++;
597   }
598   return true;
599 }
600
601 bool StringUtils::EndsWith(const std::string &str1, const std::string &str2)
602 {
603   if (str1.size() < str2.size())
604     return false;
605   return str1.compare(str1.size() - str2.size(), str2.size(), str2) == 0;
606 }
607
608 bool StringUtils::EndsWith(const std::string &str1, const char *s2)
609 {
610   size_t len2 = strlen(s2);
611   if (str1.size() < len2)
612     return false;
613   return str1.compare(str1.size() - len2, len2, s2) == 0;
614 }
615
616 bool StringUtils::EndsWithNoCase(const std::string &str1, const std::string &str2)
617 {
618   if (str1.size() < str2.size())
619     return false;
620   const char *s1 = str1.c_str() + str1.size() - str2.size();
621   const char *s2 = str2.c_str();
622   while (*s2 != '\0')
623   {
624     if (::tolower(*s1) != ::tolower(*s2))
625       return false;
626     s1++;
627     s2++;
628   }
629   return true;
630 }
631
632 bool StringUtils::EndsWithNoCase(const std::string &str1, const char *s2)
633 {
634   size_t len2 = strlen(s2);
635   if (str1.size() < len2)
636     return false;
637   const char *s1 = str1.c_str() + str1.size() - len2;
638   while (*s2 != '\0')
639   {
640     if (::tolower(*s1) != ::tolower(*s2))
641       return false;
642     s1++;
643     s2++;
644   }
645   return true;
646 }
647
648 void StringUtils::JoinString(const CStdStringArray &strings, const CStdString& delimiter, CStdString& result)
649 {
650   result = "";
651   for(CStdStringArray::const_iterator it = strings.begin(); it != strings.end(); it++ )
652     result += (*it) + delimiter;
653
654   if(result != "")
655     result.erase(result.size()-delimiter.size(), delimiter.size());
656 }
657
658 CStdString StringUtils::JoinString(const CStdStringArray &strings, const CStdString& delimiter)
659 {
660   CStdString result;
661   JoinString(strings, delimiter, result);
662   return result;
663 }
664
665 CStdString StringUtils::Join(const vector<string> &strings, const CStdString& delimiter)
666 {
667   CStdStringArray strArray;
668   for (unsigned int index = 0; index < strings.size(); index++)
669     strArray.push_back(strings.at(index));
670
671   return JoinString(strArray, delimiter);
672 }
673
674 // Splits the string input into pieces delimited by delimiter.
675 // if 2 delimiters are in a row, it will include the empty string between them.
676 // added MaxStrings parameter to restrict the number of returned substrings (like perl and python)
677 int StringUtils::SplitString(const CStdString& input, const CStdString& delimiter, CStdStringArray &results, unsigned int iMaxStrings /* = 0 */)
678 {
679   size_t iPos = std::string::npos;
680   size_t newPos = std::string::npos;
681   size_t sizeS2 = delimiter.size();
682   size_t isize = input.size();
683
684   results.clear();
685
686   vector<unsigned int> positions;
687
688   newPos = input.find(delimiter, 0);
689
690   if (newPos == std::string::npos)
691   {
692     results.push_back(input);
693     return 1;
694   }
695
696   while (newPos != std::string::npos)
697   {
698     positions.push_back(newPos);
699     iPos = newPos;
700     newPos = input.find(delimiter, iPos + sizeS2);
701   }
702
703   // numFound is the number of delimiters which is one less
704   // than the number of substrings
705   unsigned int numFound = positions.size();
706   if (iMaxStrings > 0 && numFound >= iMaxStrings)
707     numFound = iMaxStrings - 1;
708
709   for ( unsigned int i = 0; i <= numFound; i++ )
710   {
711     CStdString s;
712     if ( i == 0 )
713     {
714       if ( i == numFound )
715         s = input;
716       else
717         s = input.substr(i, positions[i]);
718     }
719     else
720     {
721       size_t offset = positions[i - 1] + sizeS2;
722       if ( offset < isize )
723       {
724         if ( i == numFound )
725           s = input.substr(offset);
726         else if ( i > 0 )
727           s = input.substr( positions[i - 1] + sizeS2,
728                          positions[i] - positions[i - 1] - sizeS2 );
729       }
730     }
731     results.push_back(s);
732   }
733   // return the number of substrings
734   return results.size();
735 }
736
737 CStdStringArray StringUtils::SplitString(const CStdString& input, const CStdString& delimiter, unsigned int iMaxStrings /* = 0 */)
738 {
739   CStdStringArray result;
740   SplitString(input, delimiter, result, iMaxStrings);
741   return result;
742 }
743
744 vector<string> StringUtils::Split(const std::string& input, const std::string& delimiter, unsigned int iMaxStrings /* = 0 */)
745 {
746   CStdStringArray result;
747   SplitString(input, delimiter, result, iMaxStrings);
748
749   vector<string> strArray;
750   for (unsigned int index = 0; index < result.size(); index++)
751     strArray.push_back(result.at(index));
752
753   return strArray;
754 }
755
756 // returns the number of occurrences of strFind in strInput.
757 int StringUtils::FindNumber(const CStdString& strInput, const CStdString &strFind)
758 {
759   size_t pos = strInput.find(strFind, 0);
760   int numfound = 0;
761   while (pos != std::string::npos)
762   {
763     numfound++;
764     pos = strInput.find(strFind, pos + 1);
765   }
766   return numfound;
767 }
768
769 // Compares separately the numeric and alphabetic parts of a string.
770 // returns negative if left < right, positive if left > right
771 // and 0 if they are identical (essentially calculates left - right)
772 int64_t StringUtils::AlphaNumericCompare(const wchar_t *left, const wchar_t *right)
773 {
774   wchar_t *l = (wchar_t *)left;
775   wchar_t *r = (wchar_t *)right;
776   wchar_t *ld, *rd;
777   wchar_t lc, rc;
778   int64_t lnum, rnum;
779   const collate<wchar_t>& coll = use_facet< collate<wchar_t> >( locale() );
780   int cmp_res = 0;
781   while (*l != 0 && *r != 0)
782   {
783     // check if we have a numerical value
784     if (*l >= L'0' && *l <= L'9' && *r >= L'0' && *r <= L'9')
785     {
786       ld = l;
787       lnum = 0;
788       while (*ld >= L'0' && *ld <= L'9' && ld < l + 15)
789       { // compare only up to 15 digits
790         lnum *= 10;
791         lnum += *ld++ - '0';
792       }
793       rd = r;
794       rnum = 0;
795       while (*rd >= L'0' && *rd <= L'9' && rd < r + 15)
796       { // compare only up to 15 digits
797         rnum *= 10;
798         rnum += *rd++ - L'0';
799       }
800       // do we have numbers?
801       if (lnum != rnum)
802       { // yes - and they're different!
803         return lnum - rnum;
804       }
805       l = ld;
806       r = rd;
807       continue;
808     }
809     // do case less comparison
810     lc = *l;
811     if (lc >= L'A' && lc <= L'Z')
812       lc += L'a'-L'A';
813     rc = *r;
814     if (rc >= L'A' && rc <= L'Z')
815       rc += L'a'- L'A';
816
817     // ok, do a normal comparison, taking current locale into account. Add special case stuff (eg '(' characters)) in here later
818     if ((cmp_res = coll.compare(&lc, &lc + 1, &rc, &rc + 1)) != 0)
819     {
820       return cmp_res;
821     }
822     l++; r++;
823   }
824   if (*r)
825   { // r is longer
826     return -1;
827   }
828   else if (*l)
829   { // l is longer
830     return 1;
831   }
832   return 0; // files are the same
833 }
834
835 int StringUtils::DateStringToYYYYMMDD(const CStdString &dateString)
836 {
837   CStdStringArray days;
838   int splitCount = StringUtils::SplitString(dateString, "-", days);
839   if (splitCount == 1)
840     return atoi(days[0].c_str());
841   else if (splitCount == 2)
842     return atoi(days[0].c_str())*100+atoi(days[1].c_str());
843   else if (splitCount == 3)
844     return atoi(days[0].c_str())*10000+atoi(days[1].c_str())*100+atoi(days[2].c_str());
845   else
846     return -1;
847 }
848
849 long StringUtils::TimeStringToSeconds(const CStdString &timeString)
850 {
851   CStdString strCopy(timeString);
852   StringUtils::Trim(strCopy);
853   if(StringUtils::EndsWithNoCase(strCopy, " min"))
854   {
855     // this is imdb format of "XXX min"
856     return 60 * atoi(strCopy.c_str());
857   }
858   else
859   {
860     CStdStringArray secs;
861     StringUtils::SplitString(strCopy, ":", secs);
862     int timeInSecs = 0;
863     for (unsigned int i = 0; i < 3 && i < secs.size(); i++)
864     {
865       timeInSecs *= 60;
866       timeInSecs += atoi(secs[i]);
867     }
868     return timeInSecs;
869   }
870 }
871
872 CStdString StringUtils::SecondsToTimeString(long lSeconds, TIME_FORMAT format)
873 {
874   int hh = lSeconds / 3600;
875   lSeconds = lSeconds % 3600;
876   int mm = lSeconds / 60;
877   int ss = lSeconds % 60;
878
879   if (format == TIME_FORMAT_GUESS)
880     format = (hh >= 1) ? TIME_FORMAT_HH_MM_SS : TIME_FORMAT_MM_SS;
881   CStdString strHMS;
882   if (format & TIME_FORMAT_HH)
883     strHMS += StringUtils::Format("%02.2i", hh);
884   else if (format & TIME_FORMAT_H)
885     strHMS += StringUtils::Format("%i", hh);
886   if (format & TIME_FORMAT_MM)
887     strHMS += StringUtils::Format(strHMS.empty() ? "%02.2i" : ":%02.2i", mm);
888   if (format & TIME_FORMAT_SS)
889     strHMS += StringUtils::Format(strHMS.empty() ? "%02.2i" : ":%02.2i", ss);
890   return strHMS;
891 }
892
893 bool StringUtils::IsNaturalNumber(const CStdString& str)
894 {
895   size_t i = 0, n = 0;
896   // allow whitespace,digits,whitespace
897   while (i < str.size() && isspace((unsigned char) str[i]))
898     i++;
899   while (i < str.size() && isdigit((unsigned char) str[i]))
900   {
901     i++; n++;
902   }
903   while (i < str.size() && isspace((unsigned char) str[i]))
904     i++;
905   return i == str.size() && n > 0;
906 }
907
908 bool StringUtils::IsInteger(const CStdString& str)
909 {
910   size_t i = 0, n = 0;
911   // allow whitespace,-,digits,whitespace
912   while (i < str.size() && isspace((unsigned char) str[i]))
913     i++;
914   if (i < str.size() && str[i] == '-')
915     i++;
916   while (i < str.size() && isdigit((unsigned char) str[i]))
917   {
918     i++; n++;
919   }
920   while (i < str.size() && isspace((unsigned char) str[i]))
921     i++;
922   return i == str.size() && n > 0;
923 }
924
925 int StringUtils::asciidigitvalue(char chr)
926 {
927   if (!isasciidigit(chr))
928     return -1;
929
930   return chr - '0';
931 }
932
933 int StringUtils::asciixdigitvalue(char chr)
934 {
935   int v = asciidigitvalue(chr);
936   if (v >= 0)
937     return v;
938   if (chr >= 'a' && chr <= 'f')
939     return chr - 'a' + 10;
940   if (chr >= 'A' && chr <= 'F')
941     return chr - 'A' + 10;
942
943   return -1;
944 }
945
946
947 void StringUtils::RemoveCRLF(CStdString& strLine)
948 {
949   StringUtils::TrimRight(strLine, "\n\r");
950 }
951
952 CStdString StringUtils::SizeToString(int64_t size)
953 {
954   CStdString strLabel;
955   const char prefixes[] = {' ','k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'};
956   unsigned int i = 0;
957   double s = (double)size;
958   while (i < sizeof(prefixes)/sizeof(prefixes[0]) && s >= 1000.0)
959   {
960     s /= 1024.0;
961     i++;
962   }
963
964   if (!i)
965     strLabel = StringUtils::Format("%.0lf %cB ", s, prefixes[i]);
966   else if (s >= 100.0)
967     strLabel = StringUtils::Format("%.1lf %cB", s, prefixes[i]);
968   else
969     strLabel = StringUtils::Format("%.2lf %cB", s, prefixes[i]);
970
971   return strLabel;
972 }
973
974 // return -1 if not, else return the utf8 char length.
975 int IsUTF8Letter(const unsigned char *str)
976 {
977   // reference:
978   // unicode -> utf8 table: http://www.utf8-chartable.de/
979   // latin characters in unicode: http://en.wikipedia.org/wiki/Latin_characters_in_Unicode
980   unsigned char ch = str[0];
981   if (!ch)
982     return -1;
983   if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))
984     return 1;
985   if (!(ch & 0x80))
986     return -1;
987   unsigned char ch2 = str[1];
988   if (!ch2)
989     return -1;
990   // check latin 1 letter table: http://en.wikipedia.org/wiki/C1_Controls_and_Latin-1_Supplement
991   if (ch == 0xC3 && ch2 >= 0x80 && ch2 <= 0xBF && ch2 != 0x97 && ch2 != 0xB7)
992     return 2;
993   // check latin extended A table: http://en.wikipedia.org/wiki/Latin_Extended-A
994   if (ch >= 0xC4 && ch <= 0xC7 && ch2 >= 0x80 && ch2 <= 0xBF)
995     return 2;
996   // check latin extended B table: http://en.wikipedia.org/wiki/Latin_Extended-B
997   // and International Phonetic Alphabet: http://en.wikipedia.org/wiki/IPA_Extensions_(Unicode_block)
998   if (((ch == 0xC8 || ch == 0xC9) && ch2 >= 0x80 && ch2 <= 0xBF)
999       || (ch == 0xCA && ch2 >= 0x80 && ch2 <= 0xAF))
1000     return 2;
1001   return -1;
1002 }
1003
1004 size_t StringUtils::FindWords(const char *str, const char *wordLowerCase)
1005 {
1006   // NOTE: This assumes word is lowercase!
1007   unsigned char *s = (unsigned char *)str;
1008   do
1009   {
1010     // start with a compare
1011     unsigned char *c = s;
1012     unsigned char *w = (unsigned char *)wordLowerCase;
1013     bool same = true;
1014     while (same && *c && *w)
1015     {
1016       unsigned char lc = *c++;
1017       if (lc >= 'A' && lc <= 'Z')
1018         lc += 'a'-'A';
1019
1020       if (lc != *w++) // different
1021         same = false;
1022     }
1023     if (same && *w == 0)  // only the same if word has been exhausted
1024       return (const char *)s - str;
1025
1026     // otherwise, skip current word (composed by latin letters) or number
1027     int l;
1028     if (*s >= '0' && *s <= '9')
1029     {
1030       ++s;
1031       while (*s >= '0' && *s <= '9') ++s;
1032     }
1033     else if ((l = IsUTF8Letter(s)) > 0)
1034     {
1035       s += l;
1036       while ((l = IsUTF8Letter(s)) > 0) s += l;
1037     }
1038     else
1039       ++s;
1040     while (*s && *s == ' ') s++;
1041
1042     // and repeat until we're done
1043   } while (*s);
1044
1045   return CStdString::npos;
1046 }
1047
1048 // assumes it is called from after the first open bracket is found
1049 int StringUtils::FindEndBracket(const CStdString &str, char opener, char closer, int startPos)
1050 {
1051   int blocks = 1;
1052   for (unsigned int i = startPos; i < str.size(); i++)
1053   {
1054     if (str[i] == opener)
1055       blocks++;
1056     else if (str[i] == closer)
1057     {
1058       blocks--;
1059       if (!blocks)
1060         return i;
1061     }
1062   }
1063
1064   return (int)CStdString::npos;
1065 }
1066
1067 void StringUtils::WordToDigits(CStdString &word)
1068 {
1069   static const char word_to_letter[] = "22233344455566677778889999";
1070   StringUtils::ToLower(word);
1071   for (unsigned int i = 0; i < word.size(); ++i)
1072   { // NB: This assumes ascii, which probably needs extending at some  point.
1073     char letter = word[i];
1074     if ((letter >= 'a' && letter <= 'z')) // assume contiguous letter range
1075     {
1076       word[i] = word_to_letter[letter-'a'];
1077     }
1078     else if (letter < '0' || letter > '9') // We want to keep 0-9!
1079     {
1080       word[i] = ' ';  // replace everything else with a space
1081     }
1082   }
1083 }
1084
1085 CStdString StringUtils::CreateUUID()
1086 {
1087   /* This function generate a DCE 1.1, ISO/IEC 11578:1996 and IETF RFC-4122
1088   * Version 4 conform local unique UUID based upon random number generation.
1089   */
1090   char UuidStrTmp[40];
1091   char *pUuidStr = UuidStrTmp;
1092   int i;
1093
1094   static bool m_uuidInitialized = false;
1095   if (!m_uuidInitialized)
1096   {
1097     /* use current time as the seed for rand()*/
1098     srand(time(NULL));
1099     m_uuidInitialized = true;
1100   }
1101
1102   /*Data1 - 8 characters.*/
1103   for(i = 0; i < 8; i++, pUuidStr++)
1104     ((*pUuidStr = (rand() % 16)) < 10) ? *pUuidStr += 48 : *pUuidStr += 55;
1105
1106   /*Data2 - 4 characters.*/
1107   *pUuidStr++ = '-';
1108   for(i = 0; i < 4; i++, pUuidStr++)
1109     ((*pUuidStr = (rand() % 16)) < 10) ? *pUuidStr += 48 : *pUuidStr += 55;
1110
1111   /*Data3 - 4 characters.*/
1112   *pUuidStr++ = '-';
1113   for(i = 0; i < 4; i++, pUuidStr++)
1114     ((*pUuidStr = (rand() % 16)) < 10) ? *pUuidStr += 48 : *pUuidStr += 55;
1115
1116   /*Data4 - 4 characters.*/
1117   *pUuidStr++ = '-';
1118   for(i = 0; i < 4; i++, pUuidStr++)
1119     ((*pUuidStr = (rand() % 16)) < 10) ? *pUuidStr += 48 : *pUuidStr += 55;
1120
1121   /*Data5 - 12 characters.*/
1122   *pUuidStr++ = '-';
1123   for(i = 0; i < 12; i++, pUuidStr++)
1124     ((*pUuidStr = (rand() % 16)) < 10) ? *pUuidStr += 48 : *pUuidStr += 55;
1125
1126   *pUuidStr = '\0';
1127
1128   m_lastUUID = UuidStrTmp;
1129   return UuidStrTmp;
1130 }
1131
1132 bool StringUtils::ValidateUUID(const CStdString &uuid)
1133 {
1134   CRegExp guidRE;
1135   guidRE.RegComp(ADDON_GUID_RE);
1136   return (guidRE.RegFind(uuid.c_str()) == 0);
1137 }
1138
1139 double StringUtils::CompareFuzzy(const CStdString &left, const CStdString &right)
1140 {
1141   return (0.5 + fstrcmp(left.c_str(), right.c_str(), 0.0) * (left.length() + right.length())) / 2.0;
1142 }
1143
1144 int StringUtils::FindBestMatch(const CStdString &str, const CStdStringArray &strings, double &matchscore)
1145 {
1146   int best = -1;
1147   matchscore = 0;
1148
1149   int i = 0;
1150   for (CStdStringArray::const_iterator it = strings.begin(); it != strings.end(); it++, i++)
1151   {
1152     int maxlength = max(str.length(), it->length());
1153     double score = StringUtils::CompareFuzzy(str, *it) / maxlength;
1154     if (score > matchscore)
1155     {
1156       matchscore = score;
1157       best = i;
1158     }
1159   }
1160   return best;
1161 }
1162
1163 bool StringUtils::ContainsKeyword(const CStdString &str, const CStdStringArray &keywords)
1164 {
1165   for (CStdStringArray::const_iterator it = keywords.begin(); it != keywords.end(); it++)
1166   {
1167     if (str.find(*it) != str.npos)
1168       return true;
1169   }
1170   return false;
1171 }
1172
1173 size_t StringUtils::utf8_strlen(const char *s)
1174 {
1175   size_t length = 0;
1176   while (*s)
1177   {
1178     if ((*s++ & 0xC0) != 0x80)
1179       length++;
1180   }
1181   return length;
1182 }
1183
1184 std::string StringUtils::Paramify(const std::string &param)
1185 {
1186   std::string result = param;
1187   // escape backspaces
1188   StringUtils::Replace(result, "\\", "\\\\");
1189   // escape double quotes
1190   StringUtils::Replace(result, "\"", "\\\"");
1191
1192   // add double quotes around the whole string
1193   return "\"" + result + "\"";
1194 }
1195
1196 void StringUtils::Tokenize(const std::string& input, std::vector<std::string>& tokens, const std::string& delimiters)
1197 {
1198   // Tokenize ripped from http://www.linuxselfhelp.com/HOWTO/C++Programming-HOWTO-7.html
1199   // Skip delimiters at beginning.
1200   string::size_type lastPos = input.find_first_not_of(delimiters, 0);
1201   // Find first "non-delimiter".
1202   string::size_type pos = input.find_first_of(delimiters, lastPos);
1203
1204   while (string::npos != pos || string::npos != lastPos)
1205   {
1206     // Found a token, add it to the vector.
1207     tokens.push_back(input.substr(lastPos, pos - lastPos));
1208     // Skip delimiters.  Note the "not_of"
1209     lastPos = input.find_first_not_of(delimiters, pos);
1210     // Find next "non-delimiter"
1211     pos = input.find_first_of(delimiters, lastPos);
1212   }
1213 }