1 /*
2  * This source file is part of MyGUI. For the latest info, see http://mygui.info/
3  * Distributed under the MIT License
4  * (See accompanying file COPYING.MIT or copy at http://opensource.org/licenses/MIT)
5  */
6 
7 #ifndef MYGUI_STRING_UTILITY_H_
8 #define MYGUI_STRING_UTILITY_H_
9 
10 #include "MyGUI_Prerequest.h"
11 #include <vector>
12 #include <sstream>
13 
14 namespace MyGUI
15 {
16 	namespace utility
17 	{
18 
19 		inline void trim(std::string& _str, bool _left = true, bool _right = true)
20 		{
21 			if (_right) _str.erase(_str.find_last_not_of(" \t\r") + 1);
22 			if (_left) _str.erase(0, _str.find_first_not_of(" \t\r"));
23 		}
24 
25 		// конвертирование в строку
26 		template<typename T>
toString(T p)27 		inline std::string toString (T p)
28 		{
29 			std::ostringstream stream;
30 			stream << p;
31 			return stream.str();
32 		}
33 
toString(const std::string & _value)34 		inline const std::string& toString (const std::string& _value)
35 		{
36 			return _value;
37 		}
38 
39 		template<typename T1,  typename T2>
toString(T1 p1,T2 p2)40 		inline std::string toString (T1 p1, T2 p2)
41 		{
42 			std::ostringstream stream;
43 			stream << p1 << p2;
44 			return stream.str();
45 		}
46 
47 		template<typename T1,  typename T2,  typename T3>
toString(T1 p1,T2 p2,T3 p3)48 		inline std::string toString (T1 p1, T2 p2, T3 p3)
49 		{
50 			std::ostringstream stream;
51 			stream << p1 << p2 << p3;
52 			return stream.str();
53 		}
54 
55 		template<typename T1,  typename T2,  typename T3, typename T4>
toString(T1 p1,T2 p2,T3 p3,T4 p4)56 		inline std::string toString (T1 p1, T2 p2, T3 p3, T4 p4)
57 		{
58 			std::ostringstream stream;
59 			stream << p1 << p2 << p3 << p4;
60 			return stream.str();
61 		}
62 
63 		template<typename T1,  typename T2,  typename T3, typename T4, typename T5>
toString(T1 p1,T2 p2,T3 p3,T4 p4,T5 p5)64 		inline std::string toString (T1 p1, T2 p2, T3 p3, T4 p4, T5 p5)
65 		{
66 			std::ostringstream stream;
67 			stream << p1 << p2 << p3 << p4 << p5;
68 			return stream.str();
69 		}
70 
71 		template<typename T1,  typename T2,  typename T3, typename T4, typename T5, typename T6>
toString(T1 p1,T2 p2,T3 p3,T4 p4,T5 p5,T6 p6)72 		inline std::string toString (T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6)
73 		{
74 			std::ostringstream stream;
75 			stream << p1 << p2 << p3 << p4 << p5 << p6;
76 			return stream.str();
77 		}
78 
79 		template<typename T1,  typename T2,  typename T3, typename T4, typename T5, typename T6, typename T7>
toString(T1 p1,T2 p2,T3 p3,T4 p4,T5 p5,T6 p6,T7 p7)80 		inline std::string toString (T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7)
81 		{
82 			std::ostringstream stream;
83 			stream << p1 << p2 << p3 << p4 << p5 << p6 << p7;
84 			return stream.str();
85 		}
86 
87 		template<typename T1,  typename T2,  typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
toString(T1 p1,T2 p2,T3 p3,T4 p4,T5 p5,T6 p6,T7 p7,T8 p8)88 		inline std::string toString (T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, T8 p8)
89 		{
90 			std::ostringstream stream;
91 			stream << p1 << p2 << p3 << p4 << p5 << p6 << p7 << p8;
92 			return stream.str();
93 		}
94 
95 		template<typename T1,  typename T2,  typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
toString(T1 p1,T2 p2,T3 p3,T4 p4,T5 p5,T6 p6,T7 p7,T8 p8,T9 p9)96 		inline std::string toString (T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, T8 p8, T9 p9)
97 		{
98 			std::ostringstream stream;
99 			stream << p1 << p2 << p3 << p4 << p5 << p6 << p7 << p8 << p9;
100 			return stream.str();
101 		}
102 
103 		template<>
104 		inline std::string toString<bool> (bool _value)
105 		{
106 			return _value ? "true" : "false";
107 		}
108 
109 
110 		// утилиты для парсинга
111 		template<typename T>
parseValue(const std::string & _value)112 		inline T parseValue( const std::string& _value )
113 		{
114 			std::istringstream stream(_value);
115 			T result;
116 			stream >> result;
117 			if (stream.fail())
118 				return T();
119 			else
120 			{
121 				int item = stream.get();
122 				while (item != -1)
123 				{
124 					if (item != ' ' && item != '\t')
125 						return T();
126 					item = stream.get();
127 				}
128 			}
129 			return result;
130 		}
131 
132 		// отдельная имплементация под bool
133 		template<>
parseValue(const std::string & _value)134 		inline bool parseValue(const std::string& _value)
135 		{
136 			return _value == "True" || _value == "true" || _value == "1";
137 		}
138 
139 		// отдельная имплементация под char
140 		template<>
parseValue(const std::string & _value)141 		inline char parseValue(const std::string& _value)
142 		{
143 			return (char)parseValue<short>(_value);
144 		}
145 
146 		// отдельная имплементация под unsigned char
147 		template<>
parseValue(const std::string & _value)148 		inline unsigned char parseValue(const std::string& _value)
149 		{
150 			return (unsigned char)parseValue<unsigned short>(_value);
151 		}
152 
153 
parseShort(const std::string & _value)154 		inline short parseShort(const std::string& _value)
155 		{
156 			return parseValue<short>(_value);
157 		}
158 
parseUShort(const std::string & _value)159 		inline unsigned short parseUShort(const std::string& _value)
160 		{
161 			return parseValue<unsigned short>(_value);
162 		}
163 
parseInt(const std::string & _value)164 		inline int parseInt(const std::string& _value)
165 		{
166 			return parseValue<int>(_value);
167 		}
168 
parseUInt(const std::string & _value)169 		inline unsigned int parseUInt(const std::string& _value)
170 		{
171 			return parseValue<unsigned int>(_value);
172 		}
173 
parseSizeT(const std::string & _value)174 		inline size_t parseSizeT(const std::string& _value)
175 		{
176 			return parseValue<size_t>(_value);
177 		}
178 
parseFloat(const std::string & _value)179 		inline float parseFloat(const std::string& _value)
180 		{
181 			return parseValue<float>(_value);
182 		}
183 
parseDouble(const std::string & _value)184 		inline double parseDouble(const std::string& _value)
185 		{
186 			return parseValue<double>(_value);
187 		}
188 
parseBool(const std::string & _value)189 		inline bool parseBool(const std::string& _value)
190 		{
191 			return parseValue<bool>(_value);
192 		}
193 
parseChar(const std::string & _value)194 		inline char parseChar(const std::string& _value)
195 		{
196 			return parseValue<char>(_value);
197 		}
198 
parseUChar(const std::string & _value)199 		inline unsigned char parseUChar(const std::string& _value)
200 		{
201 			return parseValue<unsigned char>(_value);
202 		}
203 
204 		// для парсинга сложных типов, состоящих из простых
205 		template<typename T1, typename T2>
parseValueEx2(const std::string & _value)206 		inline T1 parseValueEx2(const std::string& _value)
207 		{
208 			T2 p1, p2;
209 			std::istringstream stream(_value);
210 			stream >> p1 >> p2;
211 			if (stream.fail())
212 				return T1();
213 			else
214 			{
215 				int item = stream.get();
216 				while (item != -1)
217 				{
218 					if (item != ' ' && item != '\t')
219 						return T1();
220 					item = stream.get();
221 				}
222 			}
223 			return T1(p1, p2);
224 		}
225 
226 		template<typename T1, typename T2>
parseValueEx3(const std::string & _value)227 		inline T1 parseValueEx3(const std::string& _value)
228 		{
229 			T2 p1, p2, p3;
230 			std::istringstream stream(_value);
231 			stream >> p1 >> p2 >> p3;
232 			if (stream.fail())
233 				return T1();
234 			else
235 			{
236 				int item = stream.get();
237 				while (item != -1)
238 				{
239 					if (item != ' ' && item != '\t')
240 						return T1();
241 					item = stream.get();
242 				}
243 			}
244 			return T1(p1, p2, p3);
245 		}
246 
247 		template<typename T1, typename T2>
parseValueEx4(const std::string & _value)248 		inline T1 parseValueEx4(const std::string& _value)
249 		{
250 			T2 p1, p2, p3, p4;
251 			std::istringstream stream(_value);
252 			stream >> p1 >> p2 >> p3 >> p4;
253 			if (stream.fail())
254 				return T1();
255 			else
256 			{
257 				int item = stream.get();
258 				while (item != -1)
259 				{
260 					if (item != ' ' && item != '\t')
261 						return T1();
262 					item = stream.get();
263 				}
264 			}
265 			return T1(p1, p2, p3, p4);
266 		}
267 
268 		namespace templates
269 		{
270 			template<typename Type>
split(std::vector<Type> & _ret,const Type & _source,const Type & _delims)271 			inline void split(std::vector<Type>& _ret, const Type& _source, const Type& _delims)
272 			{
273 				size_t start = _source.find_first_not_of(_delims);
274 				while (start != _source.npos)
275 				{
276 					size_t end = _source.find_first_of(_delims, start);
277 					if (end != _source.npos)
278 						_ret.push_back(_source.substr(start, end - start));
279 					else
280 					{
281 						_ret.push_back(_source.substr(start));
282 						break;
283 					}
284 					start = _source.find_first_not_of(_delims, end + 1);
285 				}
286 			}
287 		} // namespace templates
288 
289 		inline std::vector<std::string> split(const std::string& _source, const std::string& _delims = "\t\n ")
290 		{
291 			std::vector<std::string> result;
292 			templates::split<std::string>(result, _source, _delims);
293 			return result;
294 		}
295 
296 		template<typename T1, typename T2, typename T3, typename T4>
parseComplex(const std::string & _value,T1 & _p1,T2 & _p2,T3 & _p3,T4 & _p4)297 		inline bool parseComplex(const std::string& _value, T1& _p1, T2& _p2, T3& _p3, T4& _p4)
298 		{
299 			std::istringstream stream(_value);
300 
301 			stream >> _p1 >> _p2 >> _p3 >> _p4;
302 
303 			if (stream.fail())
304 				return false;
305 			int item = stream.get();
306 			while (item != -1)
307 			{
308 				if (item != ' ' && item != '\t')
309 					return false;
310 				item = stream.get();
311 			}
312 
313 			return true;
314 		}
315 
316 		template<typename T1, typename T2, typename T3>
parseComplex(const std::string & _value,T1 & _p1,T2 & _p2,T3 & _p3)317 		inline bool parseComplex(const std::string& _value, T1& _p1, T2& _p2, T3& _p3)
318 		{
319 			std::istringstream stream(_value);
320 
321 			stream >> _p1 >> _p2 >> _p3;
322 
323 			if (stream.fail())
324 				return false;
325 			int item = stream.get();
326 			while (item != -1)
327 			{
328 				if (item != ' ' && item != '\t')
329 					return false;
330 				item = stream.get();
331 			}
332 
333 			return true;
334 		}
335 
336 		template<typename T1, typename T2>
parseComplex(const std::string & _value,T1 & _p1,T2 & _p2)337 		inline bool parseComplex(const std::string& _value, T1& _p1, T2& _p2)
338 		{
339 			std::istringstream stream(_value);
340 
341 			stream >> _p1 >> _p2;
342 
343 			if (stream.fail())
344 				return false;
345 			int item = stream.get();
346 			while (item != -1)
347 			{
348 				if (item != ' ' && item != '\t')
349 					return false;
350 				item = stream.get();
351 			}
352 
353 			return true;
354 		}
355 
356 		template<typename T1>
parseComplex(const std::string & _value,T1 & _p1)357 		inline bool parseComplex(const std::string& _value, T1& _p1)
358 		{
359 			std::istringstream stream(_value);
360 
361 			stream >> _p1;
362 
363 			if (stream.fail())
364 				return false;
365 			int item = stream.get();
366 			while (item != -1)
367 			{
368 				if (item != ' ' && item != '\t')
369 					return false;
370 				item = stream.get();
371 			}
372 
373 			return true;
374 		}
375 
376 		template<>
377 		inline bool parseComplex<bool>(const std::string& _value, bool& _p1)
378 		{
379 			std::string value(_value);
380 			trim(value);
381 			if ((value == "True") || (value == "true") || (value == "1"))
382 			{
383 				_p1 = true;
384 				return true;
385 			}
386 			else if ((value == "False") || (value == "false") || (value == "0"))
387 			{
388 				_p1 = false;
389 				return true;
390 			}
391 
392 			return false;
393 		}
394 
startWith(const std::string & _source,const std::string & _value)395 		inline bool startWith(const std::string& _source, const std::string& _value)
396 		{
397 			size_t count = _value.size();
398 			if (_source.size() < count)
399 				return false;
400 			for (size_t index = 0; index < count; ++ index)
401 			{
402 				if (_source[index] != _value[index])
403 					return false;
404 			}
405 			return true;
406 		}
407 
endWith(const std::string & _source,const std::string & _value)408 		inline bool endWith(const std::string& _source, const std::string& _value)
409 		{
410 			size_t count = _value.size();
411 			if (_source.size() < count)
412 				return false;
413 			size_t offset = _source.size() - count;
414 			for (size_t index = 0; index < count; ++ index)
415 			{
416 				if (_source[index + offset] != _value[index])
417 					return false;
418 			}
419 			return true;
420 		}
421 
422 	} // namespace utility
423 
424 } // namespace MyGUI
425 
426 #endif // MYGUI_STRING_UTILITY_H_
427