OSDN Git Service

q,bat: QueryCSV and QueryTSV plugins are only supported on x64 systems
[winmerge-jp/winmerge-jp.git] / ShellExtension / UnicodeString.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 //    License (GPLv2+):
3 //    This program is free software; you can redistribute it and/or modify
4 //    it under the terms of the GNU General Public License as published by
5 //    the Free Software Foundation; either version 2 of the License, or
6 //    (at your option) any later version.
7 //
8 //    This program is distributed in the hope that it will be useful, but
9 //    WITHOUT ANY WARRANTY; without even the implied warranty of
10 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 //    General Public License for more details.
12 //
13 //    You should have received a copy of the GNU General Public License
14 //    along with this program; if not, write to the Free Software
15 //    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
16 /////////////////////////////////////////////////////////////////////////////
17
18 /** 
19  * @file  UnicodeString.cpp
20  *
21  * @brief String utilities.
22  */
23
24 // String formatting code originally from Paul Senzee:
25 // http://www.senzee5.com/2006/05/c-formatting-stdstring.html
26
27 #include "UnicodeString.h"
28 #include <cstdarg>
29 #include <cstdio>
30 #include <cstdlib>
31 #include <cstring>
32 #include <cerrno>
33 #include <vector>
34
35 namespace strutils
36 {
37
38 /**
39  * @brief Convert a string to lower case string.
40  * @param [in] str String to convert to lower case.
41  * @return Lower case string.
42  */
43 String makelower(const String &str)
44 {
45         String ret(str);
46         String::size_type i = 0;
47         for (i = 0; i < ret.length(); i++)
48                 ret[i] = _totlower(ret[i]);
49         return ret;
50 }
51
52 /**
53  * @brief Convert a string to upper case string.
54  * @param [in] str String to convert to upper case.
55  * @return upper case string.
56  */
57 String makeupper(const String &str)
58 {
59         String ret(str);
60         String::size_type i = 0;
61         for (i = 0; i < ret.length(); i++)
62                 ret[i] = _totupper(ret[i]);
63         return ret;
64 }
65
66 /**
67  * @brief Replace a string inside a string with another string.
68  * This function searches for a string inside another string an if found,
69  * replaces it with another string. Function can replace several instances
70  * of the string inside one string.
71  * @param [in] target A string containing another string to replace.
72  * @param [in] find A string to search and replace with another (@p replace).
73  * @param [in] replace A string used to replace original (@p find).
74  */
75 void replace(String &target, const String &find, const String &replace)
76 {
77         const String::size_type find_len = find.length();
78         const String::size_type replace_len = replace.length();
79         String::size_type pos = 0;
80         while ((pos = target.find(find, pos)) != String::npos)
81         {
82                 target.replace(pos, find_len, replace);
83                 pos += replace_len;
84         }
85 }
86
87 /**
88  * @brief Compare two strings ignoring the character casing.
89  * @param [in] str1 First string to compare.
90  * @param [in] str2 Second string to compare.
91  * @return As strcmp(), 0 if strings match.
92  */
93 int compare_nocase(const String &str1, const String &str2)
94 {
95         return _tcsicoll(str1.c_str(), str2.c_str());
96 }
97
98 /**
99  * @brief Trims whitespace chars from begin and end of the string.
100  * @param [in] str the original string.
101  * @return Trimmed string.
102  */
103 String trim_ws(const String & str)
104 {
105         if (str.empty())
106                 return str;
107
108         String result(str);
109         String::iterator it = result.begin();
110         while (it != result.end() && _istspace(*it))
111                 ++it;
112         
113         if (it != result.begin())
114                 result.erase(result.begin(), it);
115
116         if (result.empty())
117                 return result;
118
119         it = result.end() - 1;
120         while (it != result.begin() && _istspace(*it))
121                 --it;
122
123         if (it != result.end() - 1)
124                 result.erase(it + 1, result.end());
125         return result;
126 }
127
128 /**
129  * @brief Trims whitespace chars from begin of the string.
130  * @param [in] str the original string.
131  * @return Trimmed string.
132  */
133 String trim_ws_begin(const String & str)
134 {
135         if (str.empty())
136                 return str;
137
138         String result(str);
139         String::iterator it = result.begin();
140         while (it != result.end() && _istspace(*it))
141                 ++it;
142         
143         if (it != result.begin())
144                 result.erase(result.begin(), it);
145         return result;
146 }
147
148 /**
149  * @brief Trims whitespace chars from end of the string.
150  * @param [in] str the original string.
151  * @return Trimmed string.
152  */
153 String trim_ws_end(const String & str)
154 {
155         if (str.empty())
156                 return str;
157
158         String result(str);
159         String::reverse_iterator it = result.rbegin();
160         while (it != result.rend() && _istspace(*it))
161                 ++it;
162
163         if (it != result.rbegin())
164                 result.erase(it.base(), result.end());
165         return result;
166 }
167
168 String format_arg_list(const TCHAR *fmt, va_list args)
169 {
170         if (!fmt)
171                 return _T("");
172         int result = -1;
173         int length = 256;
174         std::vector<TCHAR> buffer(length, 0);
175         while (result == -1)
176         {
177                 result = _vsntprintf_s(&buffer[0], length, _TRUNCATE, fmt, args);
178                 length *= 2;
179                 buffer.resize(length, 0);
180         }
181         String s(&buffer[0]);
182         return s;
183 }
184
185 /**
186  * @brief printf()-style formatting for STL string.
187  * Use this function to format String:s in printf() style.
188  */
189 String format(const TCHAR *fmt, ...)
190 {
191         va_list args;
192         va_start(args, fmt);
193         String s = format_arg_list(fmt, args);
194         va_end(args);
195         return s;
196 }
197
198 String format_strings(const String& fmt, const String *args[], size_t nargs)
199 {
200         String str;
201         str.reserve(fmt.length() * 2);
202         String::const_iterator it;
203         for (it = fmt.begin(); it != fmt.end(); ++it)
204         {
205                 if (*it == '%')
206                 {
207                         ++it;
208                         if (it == fmt.end())
209                                 break;
210                         int n = *it - '0';
211                         if (n > 0 && static_cast<unsigned int>(n) <= nargs)
212                                 str += *args[n - 1];
213                         else
214                                 str += *it;
215                 }
216                 else
217                 {
218                         str += *it;
219                 }
220         }
221         return str;
222 }
223
224 String format_string1(const String& fmt, const String& arg1)
225 {
226         const String* args[] = {&arg1};
227         return format_strings(fmt, args, 1);
228 }
229
230 String format_string2(const String& fmt, const String& arg1, const String& arg2)
231 {
232         const String* args[] = {&arg1, &arg2};
233         return format_strings(fmt, args, 2);
234 }
235
236 }