3DCoat Core API
The 3DCoat API documentation.
Loading...
Searching...
No Matches
cStr.h
1#pragma once
2
3//*****************************************************************************
4// cStr
5//*****************************************************************************
6class APICALL cStr {
7public:
8 //-------------------------------------------------------------------------
9 // .ctor
10 //-------------------------------------------------------------------------
11 cStr();
12 cStr(const cStr& Src);
13 cStr(const cStr& Src, const int StartIndex, const int Count);
14 cStr(const char* Src);
15 cStr(const char* Src, const int StartIndex, const int Count);
16 cStr(const wchar_t* Src);
17 cStr(const int Length, const char Fill = ' '); // ... + cStr(20, '-') + ...
18
19 // .dtor
20 ~cStr();
21
22 //-------------------------------------------------------------------------
23 // Copy
24 //-------------------------------------------------------------------------
25 void Copy(const cStr&);
26 void Copy(const cStr&, const int StartIndex, const int Count);
27 void Copy(const char*);
28 void Copy(const char*, const int StartIndex, const int Count);
29 void Copy(const wchar_t*);
30 void operator = (const cStr&);
31 void operator = (const char*);
32 void operator = (int);
33
34
35 //-------------------------------------------------------------------------
36 // ToCharPtr
37 //-------------------------------------------------------------------------
38 const char* ToCharPtr() const;
39 char* ToNonConstCharPtr();
40 operator const char* () const;
41 //operator char * ();
42
43 //---------------------------------------------------------------
44 // operator []
45 //---------------------------------------------------------------
46 char operator [] (const int CharIndex) const;
47 char& operator [] (const int CharIndex);
48
49 //-------------------------------------------------------------------------
50 // Length
51 //-------------------------------------------------------------------------
52 int Length() const;
53 static int Length(const char* Str);
54
55 //-------------------------------------------------------------------------
56 // SetLength / CalcLength, Fill
57 //-------------------------------------------------------------------------
58 // Ensures needed capacity and sets a specified length. Fill char can be specified.
59 void SetLength(const int Length, const char Fill = ' ');
60 void CalcLength(); // Updates length based on actual '\0' character position.
61
62 // cStr Path;
63 // ...
64 // Path.SetLength(MAX_PATH);
65 // GetModuleFileName(nullptr, Path.ToCharPtr(), Path.Length());
66 // Path.CalcLength();
67
68 void Fill(const char c); // Fills the whole string with the specified character.
69
70 //-------------------------------------------------------------------------
71 // IsEmpty, Clear
72 //-------------------------------------------------------------------------
73 bool IsEmpty() const;
74 bool empty() const;
75 void Clear();
76 static const cStr Empty;
77
78 //-------------------------------------------------------------------------
79 // Equals(NoCase) (==, !=)
80 //-------------------------------------------------------------------------
81 static bool Equals(const char*, const char*);
82 static bool Equals(const char*, const cStr&);
83 static bool Equals(const cStr&, const char*);
84 static bool Equals(const cStr&, const cStr&);
85 static bool Equals(const cStr*, const cStr*);
86 bool Equals(const char*) const;
87
88 friend bool operator == (const char*, const cStr&);
89 friend bool operator == (const cStr&, const char*);
90 friend bool operator == (const cStr&, const cStr&);
91
92 friend bool operator != (const char*, const cStr&);
93 friend bool operator != (const cStr&, const char*);
94 friend bool operator != (const cStr&, const cStr&);
95
96 static bool Equals(const char*, const char*, const int MaxLength);
97 static bool Equals(const char*, const cStr&, const int MaxLength);
98 static bool Equals(const cStr&, const char*, const int MaxLength);
99 static bool Equals(const cStr&, const cStr&, const int MaxLength);
100
101 static bool EqualsNoCase(const char*, const char*);
102 static bool EqualsNoCase(const char*, const cStr&);
103 static bool EqualsNoCase(const cStr&, const char*);
104 static bool EqualsNoCase(const cStr&, const cStr&);
105 static bool EqualsNoCase(const cStr*, const cStr*);
106
107 static bool EqualsNoCase(const char*, const char*, const int MaxLength);
108 static bool EqualsNoCase(const char*, const cStr&, const int MaxLength);
109 static bool EqualsNoCase(const cStr&, const char*, const int MaxLength);
110 static bool EqualsNoCase(const cStr&, const cStr&, const int MaxLength);
111
112 //-------------------------------------------------------------------------
113 // Compare(NoCase) (>, >=, <, <=)
114 //-------------------------------------------------------------------------
115 static int Compare(const char*, const char*);
116 static int Compare(const char*, const cStr&);
117 static int Compare(const cStr&, const char*);
118 static int Compare(const cStr&, const cStr&);
119 static int Compare(const cStr*, const cStr*);
120
121 friend bool operator > (const char*, const cStr&);
122 friend bool operator > (const cStr&, const char*);
123 friend bool operator > (const cStr&, const cStr&);
124
125 friend bool operator >= (const char*, const cStr&);
126 friend bool operator >= (const cStr&, const char*);
127 friend bool operator >= (const cStr&, const cStr&);
128
129 friend bool operator < (const char*, const cStr&);
130 friend bool operator < (const cStr&, const char*);
131 friend bool operator < (const cStr&, const cStr&);
132
133 friend bool operator <= (const char*, const cStr&);
134 friend bool operator <= (const cStr&, const char*);
135 friend bool operator <= (const cStr&, const cStr&);
136
137 static int Compare(const char*, const char*, const int MaxLength);
138 static int Compare(const char*, const cStr&, const int MaxLength);
139 static int Compare(const cStr&, const char*, const int MaxLength);
140 static int Compare(const cStr&, const cStr&, const int MaxLength);
141
142 static int CompareNoCase(const char*, const char*);
143 static int CompareNoCase(const char*, const cStr&);
144 static int CompareNoCase(const cStr&, const char*);
145 static int CompareNoCase(const cStr&, const cStr&);
146 static int CompareNoCase(const cStr*, const cStr*);
147
148 static int CompareNoCase(const char*, const char*, const int MaxLength);
149 static int CompareNoCase(const char*, const cStr&, const int MaxLength);
150 static int CompareNoCase(const cStr&, const char*, const int MaxLength);
151 static int CompareNoCase(const cStr&, const cStr&, const int MaxLength);
152
153 //-------------------------------------------------------------------------
154 // EqualsPath
155 //-------------------------------------------------------------------------
156 static bool EqualsPath(const char*, const char*);
157 static bool EqualsPath(const char*, const cStr&);
158 static bool EqualsPath(const cStr&, const char*);
159 static bool EqualsPath(const cStr&, const cStr&);
160 static bool EqualsPath(const cStr*, const cStr*);
161
162 static bool EqualsPath(const char*, const char*, const int MaxLength);
163 static bool EqualsPath(const char*, const cStr&, const int MaxLength);
164 static bool EqualsPath(const cStr&, const char*, const int MaxLength);
165 static bool EqualsPath(const cStr&, const cStr&, const int MaxLength);
166
167 //-------------------------------------------------------------------------
168 // ComparePath
169 //-------------------------------------------------------------------------
170 static int ComparePath(const char*, const char*);
171 static int ComparePath(const char*, const cStr&);
172 static int ComparePath(const cStr&, const char*);
173 static int ComparePath(const cStr&, const cStr&);
174 static int ComparePath(const cStr*, const cStr*);
175
176 static int ComparePath(const char*, const char*, const int MaxLength);
177 static int ComparePath(const char*, const cStr&, const int MaxLength);
178 static int ComparePath(const cStr&, const char*, const int MaxLength);
179 static int ComparePath(const cStr&, const cStr&, const int MaxLength);
180
181 // Path comparers consider '\\' and '/' as equivalents. They use no case compare.
182 // Also they compare according to folder depth.
183
184 //-------------------------------------------------------------------------
185 // StartsWith / EndsWith
186 //-------------------------------------------------------------------------
187 // Determines whether the beginning of this instance matches the specified string.
188 // If the specified string is empty (not nullptr is asserted), the return value is "true".
189 // Case insesitive compare can be specified.
190 bool StartsWith(const char* Str, const bool NoCase = false) const;
191 // Determines whether the end of this instance matches the specified string.
192 // If the specified string is empty (not nullptr is asserted), the return value is "true";
193 // Case insesitive compare can be specified.
194 bool EndsWith(const char* Str, const bool NoCase = false) const;
195
196 //-------------------------------------------------------------------------
197 // ToString
198 //-------------------------------------------------------------------------
199 // Returns a string that represents a specified value.
200 // These functions are heavily used in "Append" and "Insert" functions,
201 // as well as in "+=", "+" and "<<" operators.
202 static const cStr ToString(const bool);
203 static const cStr ToString(const int);
204 static const cStr ToString(const int, const int Prec);
205 static const cStr ToString(const int* IntArray, const int Count, const char* Separator = " ");
206 static const cStr ToString(const float, const int Prec = 2);
207 static const cStr ToString(const float* FloatArray, const int Count, const int Prec = 2, const char* Separator = " ");
208 static const cStr ToString(const double, const int Prec = 6);
209 static const cStr ToString(const double* DoubleArray, const int Count, const int Prec = 6, const char* Separator = " ");
210 static const cStr ToHex(const dword dw);
211 static const cStr ToHex(const qword qw);
212 static const cStr ToHex(const void* Ptr);
213
228 static const cStr ToSize(const qword, const bool Pow2 = false);
229
230 //-------------------------------------------------------------------------
231 // Append (+=, <<, +)
232 //-------------------------------------------------------------------------
233 void Append(const cStr&);
234 void Append(const cStr&, const int StartIndex, const int Count);
235 void Append(const char*);
236 void Append(const wchar_t*);
237 void Append(const char*, const int StartIndex, const int Count);
238 void Append(const char);
239 void Append(const char, const int Count);
240 void Append(const bool);
241 void Append(const int);
242 void Append(const float, const int Prec = 2);
243 void Append(const double, const int Prec = 6);
244
245 void AppendWithEndLn(const cStr&);
246 static const cStr EndLn;
247
248 void operator += (const cStr&);
249 void operator += (const char*);
250 void operator += (const wchar_t*);
251 void operator += (const char);
252 void operator += (const bool);
253 void operator += (const int);
254 void operator += (const float);
255 void operator += (const double);
256
257 cStr& operator << (const cStr&);
258 cStr& operator << (const char*);
259 cStr& operator << (const wchar_t*);
260 cStr& operator << (const char);
261 cStr& operator << (const bool);
262 cStr& operator << (const int);
263 cStr& operator << (const float);
264 cStr& operator << (const double);
265
266 friend const cStr operator + (const cStr&, const cStr&);
267 friend const cStr operator + (const cStr&, const char*);
268 friend const cStr operator + (const char*, const cStr&);
269 friend const cStr operator + (const cStr&, const char);
270 friend const cStr operator + (const char, const cStr&);
271 friend const cStr operator + (const cStr&, const bool);
272 friend const cStr operator + (const bool, const cStr&);
273 friend const cStr operator + (const cStr&, const int);
274 friend const cStr operator + (const int, const cStr&);
275 friend const cStr operator + (const cStr&, const float);
276 friend const cStr operator + (const float, const cStr&);
277 friend const cStr operator + (const cStr&, const double);
278 friend const cStr operator + (const double, const cStr&);
279
280 friend const cStr operator + (const cStr&, const wchar_t*);
281 friend const cStr operator + (const wchar_t*, const cStr&);
282
283 //-------------------------------------------------------------------------
284 // Append... (Path, Format)
285 //-------------------------------------------------------------------------
286 void AppendPath(const char* Path); // Appends '\\' under Windows, '/' under Linux and macOS
287 void AppendFormat(const char* Format, ...);
288
289 //-------------------------------------------------------------------------
290 // Insert
291 //-------------------------------------------------------------------------
292 void Insert(const int Index, const cStr&);
293 void Insert(const int Index, const cStr&, const int StartIndex, const int Count);
294 void Insert(const int Index, const char*);
295 void Insert(const int Index, const char*, const int StartIndex, const int Count);
296 void Insert(const int Index, const char);
297 void Insert(const int Index, const char, const int Count);
298 void Insert(const int Index, const bool);
299 void Insert(const int Index, const int);
300 void Insert(const int Index, const float, const int Prec = 2);
301 void Insert(const int Index, const double, const int Prec = 6);
302
303 //-------------------------------------------------------------------------
304 // Remove
305 //-------------------------------------------------------------------------
306 // Deletes all the characters from this string beginning at a specified position
307 // and continuing through the last position.
308 void Remove(const int StartIndex);
309 // Deletes a specified number of characters from this instance
310 // beginning at a specified position.
311 void Remove(const int StartIndex, const int Count);
312
313 //-------------------------------------------------------------------------
314 // Replace : (const char, const char, ...)
315 //-------------------------------------------------------------------------
316 // Replaces all occurrences of a specified character in this instance// with another specified character.
317 void Replace(const char Char, const char WithChar);
318 void ReplaceCommaWithDot() {
319 Replace(',', '.');
320 }
321 // Replaces only within a substring of this instance.
322 void Replace(const char Char, const char WithChar, const int StartIndex, const int Count);
323
324 //-------------------------------------------------------------------------
325 // Replace : (const char *, const char *, ...)
326 //-------------------------------------------------------------------------
327 // Replaces all occurrences of a specified string in this instance
328 // with another specified string.
329 // Returns number of replaces.
330 // Case insensitive compare can be specified.
331 int Replace(const char* String, const char* WithString, const bool NoCase = false);
332 // Replaces in a substring beginning from a specified position to the end.
333 int Replace(const char* String, const char* WithString, const int StartIndex, const bool NoCase = false);
334 // Replaces only within a substring of this instance.
335 int Replace(const char* String, const char* WithString, const int StartIndex, const int Count, const bool NoCase = false);
336 // Replaces first occurrence of a specified string in this instance with another specified string.
337 int ReplaceFirst(const char* String, const char* WithString, const bool NoCase = false);
338 // Replaces only within a substring of this instance.
339 int ReplaceFirst(const char* String, const char* WithString, const int StartIndex, const int Count, const bool NoCase = false);
340
341 //-------------------------------------------------------------------------
342 // ReplaceAny : (const char *, const char, ...)
343 //-------------------------------------------------------------------------
344 // Replaces all occurrences in this instance of every character in the
345 // specified list of characters with another specified character.
346 void ReplaceAny(const char* Chars, const char WithChar); // S.ReplaceAny(",;\t", ' ');
347 // Replaces only within a substring of this instance.
348 void ReplaceAny(const char* Chars, const char WithChar, const int StartIndex, const int Count);
349
350 //-------------------------------------------------------------------------
351 // Substring
352 //-------------------------------------------------------------------------
353 // Retrieves a substring from this instance.
354 // The substring starts at a specified character position.
355 const cStr Substring(const int StartIndex) const;
356 // The substring starts at a specified character position and has a specified length.
357 const cStr Substring(const int StartIndex, const int Count) const;
358
359 //-------------------------------------------------------------------------
360 // Trim...
361 //-------------------------------------------------------------------------
362 // Removes all occurrences of a set of characters specified in a string
363 // from the beginning of this instance.
364 void TrimStart(const char* TrimChars);
365 // Removes all occurrences of a set of characters specified in a string
366 // from the end of this instance.
367 void TrimEnd(const char* TrimChars);
368 // Removes all occurrences of a set of characters specified in a string
369 // from the beginning and end of this instance.
370 void Trim(const char* TrimChars);
371
372 //-------------------------------------------------------------------------
373 // PadLeft / PadRight
374 //-------------------------------------------------------------------------
375 // Right - aligns the characters of this instance, padding on the left with
376 // spaces or a specified character for a specified total length.
377 void PadLeft(const int TotalWidth, const char PaddingChar = ' ');
378 // Left - align the characters of this instance, padding on the right with
379 // spaces or a specified character for a specified total length.
380 void PadRight(const int TotalWidth, const char PaddingChar = ' ');
381
382 //-------------------------------------------------------------------------
383 // Contains
384 //-------------------------------------------------------------------------
385 // Returns a value indicating whether the specified character occurs within this string.
386 bool Contains(const char c) const;
387 // Returns "true" if the specified string occurs within this string, or if the
388 // specified string is empty string or nullptr; otherwise, "false".
389 // Case insesitive compare can be specified.
390 bool Contains(const char* Str, const bool NoCase = false) const;
391
392 //-------------------------------------------------------------------------
393 // IndexOf : (const char, ...)
394 //-------------------------------------------------------------------------
395 // Returns the index position of the first occurrence within this instance
396 // where the specified character is found, or -1 if it is not.
397 int IndexOf(const char c) const;
398 static int IndexOf(const char* Src, const char c);
399 // The search starts at a specified character position.
400 int IndexOf(const char c, const int StartIndex) const;
401 // The search starts at a specified character position and examines a specified number of character positions.
402 int IndexOf(const char c, const int StartIndex, const int Count) const;
403
404 //-------------------------------------------------------------------------
405 // IndexOf : (const char *, ...)
406 //-------------------------------------------------------------------------
407 // Returns the index position of the first occurrence in this instance
408 // where the specified string is found, or -1 if it is not.
409 // If the specified string is empty or nullptr, the return value is "StartIndex".
410 // Case insesitive compare can be specified.
411 int IndexOf(const char* Str, const bool NoCase = false) const;
412 // The search starts at a specified character position.
413 int IndexOf(const char* Str, const int StartIndex, const bool NoCase = false) const;
414 // The search starts at a specified character position and examines a specified number of character positions.
415 int IndexOf(const char* Str, const int StartIndex, const int Count, const bool NoCase = false) const;
416
417 //-------------------------------------------------------------------------
418 // IndexOfAny
419 //-------------------------------------------------------------------------
420 // Returns the index position of the first occurrence in this instance
421 // where any character from the specified list of characters is found, or -1 if it is not.
422 int IndexOfAny(const char* Chars) const;
423 // The search starts at a specified character position.
424 int IndexOfAny(const char* Chars, const int StartIndex) const;
425 // The search starts at a specified character position and examines a specified number of character positions.
426 int IndexOfAny(const char* Chars, const int StartIndex, const int Count) const;
427
428 //-------------------------------------------------------------------------
429 // LastIndexOf : (const char, ...)
430 //-------------------------------------------------------------------------
431 // Returns the index position of the last occurrence within this instance
432 // where the specified character is found, or -1 if it is not.
433 int LastIndexOf(const char c) const;
434 // The search starts at a specified character position and
435 // proceeds backwards towards the beginning.
436 int LastIndexOf(const char c, const int StartIndex) const;
437 // The search starts at a specified character position and
438 // proceeds backwards towards the beginning until either character is found
439 // or a specified number of character positions have been examined.
440 int LastIndexOf(const char c, const int StartIndex, const int Count) const;
441
442 //-------------------------------------------------------------------------
443 // LastIndexOf : (const char *, ...)
444 //-------------------------------------------------------------------------
445 // Returns the index position of the last occurrence within this instance
446 // where the specified string is found, or -1 if it is not.
447 // If the specified string is empty or nullptr, the return value is "StartIndex".
448 // Case insesitive compare can be specified.
449 int LastIndexOf(const char* Str, const bool NoCase = false) const;
450 // The search starts at a specified character position and proceeds backwards towards the beginning.
451 int LastIndexOf(const char* Str, const int StartIndex, const bool NoCase = false) const;
452 // The search starts at a specified character position and proceeds backwards towards the beginning
453 // until either the string is found or a specified character positions have been examined.
454 int LastIndexOf(const char* Str, const int StartIndex, const int Count, const bool NoCase = false) const;
455
456 //-------------------------------------------------------------------------
457 // LastIndexOfAny
458 //-------------------------------------------------------------------------
459 // Returns the index position of the last occurrence in this instance
460 // where any character from the specified list of characters is found, or -1 if it is not.
461 int LastIndexOfAny(const char* Chars) const;
462 // The search starts at a specified character position and
463 // proceeds backwards towards the beginning.
464 int LastIndexOfAny(const char* Chars, const int StartIndex) const;
465 // The search starts at a specified character position and proceeds
466 // backwards towards the beginning until either character in a specified string
467 // is found or a specified number of character positions have been examined.
468 int LastIndexOfAny(const char* Chars, const int StartIndex, const int Count) const;
469
470 //-------------------------------------------------------------------------
471 // ToLower / ToUpper, MakeLower / MakeUpper
472 //-------------------------------------------------------------------------
473 static char ToLower(const char c);
474 static char ToUpper(const char c);
475 void MakeLower(int start = 0); // Converts this string instance to lowercase.
476 void MakeUpper(int start = 0); // Converts this string instance to uppercase.
477 const cStr ToLower() const; // Returns a copy of this string converted to lowercase.
478 const cStr ToUpper() const; // Returns a copy of this string converted to uppercase.
479
480 //-------------------------------------------------------------------------
481 // Join
482 //-------------------------------------------------------------------------
483 // Concatenates a specified separator between each element of a specified
484 // string list, yielding a single concatenated string.
485 static const cStr Join(const char* Separator, const cList<cStr>& Strings);
486 // Parameters specify the first array element and number of elements to use.
487 static const cStr Join(const char* Separator, const cList<cStr>& Strings, const int StartIndex, const int Count);
488
489 //-------------------------------------------------------------------------
490 // Split
491 //-------------------------------------------------------------------------
492 // Fills a list with the substrings from a specified string or this instance
493 // that are delimited by a specified characters.
494 static void Split(const char* Src, cList<cStr>* List, const char* Delimiters = " ,;\t");
495 void Split(cList<cStr>* List, const char* Delimiters = " ,;\t") const;
496
497 //-------------------------------------------------------------------------
498 // Format
499 //-------------------------------------------------------------------------
500 // Returns a copy of the specified format string in which each format item is replaced
501 // with the text equivalent of a corresponding value from arguments.
502 static const cStr Format(const char* Format, ...);
503 static const cStr Formatv(const char* Format, va_list Args); // Uses list of arguments.
504
505 //-------------------------------------------------------------------------
506 // CharIs...
507 //-------------------------------------------------------------------------
508 static bool CharIsLower(const int c);
509 static bool CharIsUpper(const int c);
510 static bool CharIsAlpha(const int c);
511 static bool CharIsNumeric(const int c);
512 static bool CharIsHexadecimal(const int c);
513 static bool CharIsNewLine(const int c);
514 static bool CharIsTab(const int c);
515 static bool CharIsWhitespace(const int c);
516 static bool CharIsDecimalPoint(const int c);
517 static bool CharIsSign(const int c);
518 static bool CharIsExponent(const int c);
519
520 //-------------------------------------------------------------------------
521 // ToInt(Array) / ToFloat(Array)
522 //-------------------------------------------------------------------------
523 static bool ToInt(const char* Str, int* Value);
524 // [Whitespace] Consists of space or tab characters, which are ignored.
525 // [Sign] Is either plus (+) or minus (-).
526 // Digits Are one or more decimal digits.
527
528 static bool ToFloat(const char* Str, float* Value);
529 // [Whitespace] Consists of space or tab characters, which are ignored.
530 // [Sign] Is either plus (+) or minus (-).
531 // [Digits] Are one or more decimal digits.
532 // [.Digits] If no digits appear before the decimal point,
533 // at least one must appear after the decimal point.
534 // [ {d | D | e | E }[Sign]Digits] The decimal point may be followed by an exponent,
535 // which consists of an introductory letter (d, D, e, or E) and
536 // an optionally signed decimal integer.
537
538 static bool ToIntArray(const char* Str, cList<int>* IntArray);
539 static bool ToFloatArray(const char* Str, cList<float>* FloatArray);
540
541 //-------------------------------------------------------------------------
542 // GetHashCode
543 //-------------------------------------------------------------------------
544 int GetHashCode(const bool NoCase = false) const {
545 return GetHashCode(m_Str, NoCase);
546 }
547 static int GetHashCode(const char* Str, const bool NoCase = false);
548
549 //-------------------------------------------------------------------------
550 // GetFile... Extension / Name / Base / Path
551 //-------------------------------------------------------------------------
552 const cStr GetFileExtension() const;
553 const cStr GetFileName() const;
554 const cStr GetFileBase() const;
555 const cStr GetFilePath() const;
556
557 //-------------------------------------------------------------------------
558 // RemoveFile... Extension / Name / Path
559 //-------------------------------------------------------------------------
560 void RemoveFileExtension();
561 void RemoveFileName();
562 void RemoveFilePath();
563 // If string contains absolute path to file below specified "AbsPath", it will be removed
564 void RemoveFileAbsPath(const char* AbsPath);
565
566 //-------------------------------------------------------------------------
567 // SetFile... (Default)Extension / (Default)Path
568 //-------------------------------------------------------------------------
569 void SetFileExtension(const char* Extension);
570 void SetFileDefaultExtension(const char* DefaultExtension); // If there's no extension set the default.
571 void SetFilePath(const char* Path);
572 void SetFileDefaultPath(const char* DefaultPath); // If there's no path set the default.
573
574 void EnsureTrailingBackslash();
575 void EnsureTrailingSlash();
576 void EnsureTrailingPlatformSlash() {
577#if defined COMMS_WINDOWS
578 EnsureTrailingBackslash();
579#endif // Windows
580#if defined COMMS_MACOS || defined COMMS_LINUX
581 EnsureTrailingSlash();
582#endif // macOS, Linux
583 }
584 static const cStr EnsureTrailingPlatformSlash(const cStr &S) {
585 cStr T(S);
586 T.EnsureTrailingPlatformSlash();
587 return T;
588 }
589
590 void SlashesToBackSlashes(); // Replaces '/' with '\\'
591 void BackSlashesToSlashes(); // Replaces '\\' with '/'
592 void MakePlatformSlashes() {
593#if defined COMMS_WINDOWS
594 SlashesToBackSlashes(); // '/' -> '\\'
595#endif // Windows
596#if defined COMMS_MACOS || defined COMMS_LINUX
597 BackSlashesToSlashes(); // '\\' -> '/'
598#endif // macOS, Linux
599 }
600
601 //-------------------------------------------------------------------------
602 // Unicode
603 //-------------------------------------------------------------------------
604 struct CodePage {
605 enum Enum {
606 _1251 = 0,
607 Count = 1
608 };
609 };
610 void Decode(const CodePage::Enum _CodePage, cList<word>* UniChars) const;
611 bool DecodeUTF8(cList<word>* UniChars) const;
612 int CalcUTF8Length(const int StartIndex) const;
613 void Init();
614 void Free();
615#ifndef DLL_API
616 // if the DLL interface used the std containers may not be used because sizeof(std::...) is different
617 cStr(const ::std::wstring& Src);
618 cStr(const std::string& Src);
619 void Copy(const ::std::wstring&);
620 void Copy(const ::std::string&);
621 void operator = (const ::std::wstring&);
622 void operator = (const ::std::string&);
623 void toWstring(::std::wstring& ws);
624 std::wstring toWstring();
625 void Append(const std::string&);
626 void Append(const std::wstring&);
627 void operator += (const std::string&);
628 void operator += (const std::wstring&);
629 cStr& operator << (const std::string&);
630 cStr& operator << (const std::wstring&);
631 friend const cStr operator + (const cStr&, const std::wstring&);
632 friend const cStr operator + (const std::wstring&, const cStr&);
633 friend const cStr operator + (const cStr&, const std::string&);
634 friend const cStr operator + (const std::string&, const cStr&);
635#endif
636private:
637 char* m_Str;
638 int m_Length, m_Capacity;
639 static char def_str;
640
641 struct Param {
642 enum Values {
643 BaseBufferLength = 32,
644 GrowBy = 32
645 };
646 };
647
648 //char m_BaseBuffer[Param::BaseBufferLength];
649 bool IsValid() const;
650 friend class cXml;
651 void EnsureCapacity(const int MinCapacity, const bool KeepOld = true);
652 void Resize(const int MinCapacity, const bool KeepOld);
653 static char* getstr();
654 static void freestr(char* s);
655};
656
657// cStr::IsValid
658inline bool cStr::IsValid() const {
659 //cAssert(m_Str != nullptr);
660 // Seriously slows down Debug build of 3D-Coat
661 //cAssert(m_Length == Length(m_Str)); // Cached length should be the same as actual
662 //cAssert(m_Capacity >= m_Length); // Capacity should be at least length + 1 (terminating zero)
663 return true;
664}
665
666// cStr::Init
667inline void cStr::Init() {
668 m_Length = 0;
669 m_Capacity = 0;// Param::BaseBufferLength;
670 m_Str = nullptr;// m_BaseBuffer;
671 //m_Str[0] = '\0';
672 // No need in "cAssert(IsValid())", since after "Init" this string is valid for sure
673}
674
675// cStr::Free
676inline void cStr::Free() {
677 // In "Free" we don't care was string valid or not, cause usage of
678 // string buffer may be not only for storing one string with terminating zero.
679 //cAssert(m_Str != nullptr);
680 if (m_Capacity > Param::BaseBufferLength) {
681 cPool::Free((byte*)m_Str, m_Capacity);
682 }
683 else if (m_Str)freestr(m_Str);
684 Init();
685}
686
687// cStr::EnsureCapacity
688inline void cStr::EnsureCapacity(const int MinCapacity, const bool KeepOld) {
689 if (MinCapacity > m_Capacity) {
690 Resize(MinCapacity, KeepOld);
691 }
692}
693
694//-----------------------------------------------------------------------------
695// cStr.ctor
696//-----------------------------------------------------------------------------
697
698// cStr.ctor : ()
699inline cStr::cStr() {
700 Init();
701}
702
703// cStr.ctor : (const cStr &)
704inline cStr::cStr(const cStr& Src) {
705 Init();
706 Copy(Src);
707}
708
709// cStr.ctor : (const cStr &, const int, const int)
710inline cStr::cStr(const cStr& Src, const int StartIndex, const int Count) {
711 Init();
712 Copy(Src, StartIndex, Count);
713}
714
715// cStr.ctor : (const char *)
716inline cStr::cStr(const char* Src) {
717 Init();
718 Copy(Src);
719}
720
721inline cStr::cStr(const wchar_t* Src) {
722 Init();
723 Copy(Src);
724}
725
726// cStr.ctor : (const char *, const int, const int)
727inline cStr::cStr(const char* Src, const int StartIndex, const int Count) {
728 Init();
729 Copy(Src, StartIndex, Count);
730}
731
732// cStr.ctor : (const int, const char)
733inline cStr::cStr(const int Length, const char Fill) {
734 Init();
735 SetLength(Length, Fill);
736}
737
738//-----------------------------------------------------------------------------
739// cStr.dtor
740//-----------------------------------------------------------------------------
741
742// cStr.dtor
743inline cStr::~cStr() {
744 Free();
745}
746
747//-----------------------------------------------------------------------------
748// cStr::Copy
749//-----------------------------------------------------------------------------
750
751// cStr::Copy : (const cStr &)
752inline void cStr::Copy(const cStr& Src) {
753 cAssert(Src.IsValid());
754 Copy(Src.m_Str, 0, Src.m_Length);
755}
756
757// cStr::Copy : (const cStr &, const int, const int)
758inline void cStr::Copy(const cStr& Src, const int StartIndex, const int Count) {
759 cAssert(Src.IsValid());
760 Copy(Src.m_Str, StartIndex, Count);
761}
762
763// cStr::Copy : (const char *)
764inline void cStr::Copy(const char* Src) {
765 Copy(Src, 0, Length(Src));
766}
767
768// cStr::operator = : (const cStr &)
769inline void cStr::operator = (const cStr& Src) {
770 Copy(Src);
771}
772
773// cStr::operator = : (const char *)
774inline void cStr::operator = (const char* Src) {
775 Copy(Src);
776}
777
778inline void cStr::operator=(int x) {
779 *this = ToString(x);
780}
781
782//-----------------------------------------------------------------------------
783// cStr::ToCharPtr
784//-----------------------------------------------------------------------------
785
786// None of these casters has cAssert on validity, cause during work with
787// string buffer as with temp storage, its state most probably is not valid.
788
789// cStr::ToCharPtr : const char * () const
790inline const char* cStr::ToCharPtr() const {
791 //cAssert(m_Str != nullptr);
792 return m_Str ? m_Str : &def_str;
793}
794
795// cStr::ToNonConstCharPtr() : char * ()
796inline char* cStr::ToNonConstCharPtr() {
797 return (this && m_Str) ? m_Str : &def_str;
798}
799
800// cStr::operator const char * () const
801inline cStr::operator const char* () const {
802 return (this && m_Str) ? m_Str : &def_str;
803}
804
805// cStr::operator char * ()
806//inline cStr::operator char * () {
807// return (this && m_Str) ? m_Str : &def_str;
808//}
809
810//-----------------------------------------------------------------------------
811// cStr::operator []
812//-----------------------------------------------------------------------------
813
814// cStr::operator [] const
815inline char cStr::operator [] (const int CharIndex) const {
816 cAssert(IsValid());
817 cAssert(CharIndex >= 0);
818 cAssert(CharIndex <= m_Length);
819 return m_Str ? m_Str[CharIndex] : 0;
820}
821
822// cStr::operator []
823inline char& cStr::operator [] (const int CharIndex) {
824 cAssert(IsValid());
825 cAssert(CharIndex >= 0);
826 cAssert(CharIndex <= m_Length);
827 return m_Str ? m_Str[CharIndex] : def_str;
828}
829
830//-----------------------------------------------------------------------------
831// cStr::Length
832//-----------------------------------------------------------------------------
833
834// cStr::Length : ()
835inline int cStr::Length() const {
836 cAssert(IsValid());
837 return m_Length;
838}
839
840// cStr::Length : (const char *)
841inline int cStr::Length(const char* Str) {
842 if (Str == nullptr) {
843 return 0;
844 }
845
846 int l;
847
848 for (l = 0; Str[l] != '\0'; l++) {
849 }
850 return l;
851}
852
853//-----------------------------------------------------------------------------
854// cStr::SetLength / cStr::CalcLength
855//-----------------------------------------------------------------------------
856
857// cStr::SetLength : (const int, const char)
858inline void cStr::SetLength(const int Length, const char Fill) {
859 cAssert(IsValid());
860 cAssert(Length >= 0);
861
862 int i;
863
864 if (Length <= 0) {
865 Free();
866 }
867 else {
868 EnsureCapacity(Length + 1);
869 for (i = 0; i < Length; i++) {
870 m_Str[i] = Fill;
871 }
872 m_Length = Length;
873 m_Str[Length] = '\0';
874
875 }
876}
877
878// cStr::CalcLength
879inline void cStr::CalcLength() {
880 m_Length = Length(m_Str);
881 cAssert(IsValid());
882}
883
884// cStr::Fill : (const char)
885inline void cStr::Fill(const char c) {
886 cAssert(IsValid());
887
888 int i;
889
890 for (i = 0; i < m_Length; i++) {
891 m_Str[i] = c;
892 }
893}
894
895//-----------------------------------------------------------------------------
896// cStr::IsEmpty, cStr::Clear
897//-----------------------------------------------------------------------------
898
899// cStr::IsEmpty
900inline bool cStr::IsEmpty() const {
901 return Equals(m_Str, "");
902}
903
904inline bool cStr::empty() const {
905 return Length() == 0;
906}
907
908// cStr::Clear
909inline void cStr::Clear() {
910 if (m_Str) {
911 EnsureCapacity(1, false);
912 m_Str[0] = '\0';
913 m_Length = 0;
914 }
915 else m_Length = 0;
916}
917
918//-----------------------------------------------------------------------------
919// cStr::Equals(NoCase) (==, !=)
920//-----------------------------------------------------------------------------
921
922// cStr::Equals : bool (const char *, const char *)
923inline bool cStr::Equals(const char* l, const char* r) {
924 return Compare(l, r) == 0;
925}
926
927// cStr::Equals : bool (const char *, const cStr &)
928inline bool cStr::Equals(const char* l, const cStr& r) {
929 cAssert(r.IsValid());
930 return Compare(l, r.ToCharPtr()) == 0;
931}
932
933// cStr::Equals : bool (const cStr &, const char *)
934inline bool cStr::Equals(const cStr& l, const char* r) {
935 cAssert(l.IsValid());
936 return Compare(l.ToCharPtr(), r) == 0;
937}
938
939// cStr::Equals : bool (const cStr &, const cStr &)
940inline bool cStr::Equals(const cStr& l, const cStr& r) {
941 cAssert(l.IsValid());
942 cAssert(r.IsValid());
943 return Compare(l.ToCharPtr(), r.ToCharPtr()) == 0;
944}
945
946// cStr::Equals : bool (const cStr *, const cStr *)
947inline bool cStr::Equals(const cStr* l, const cStr* r) {
948 cAssert(l != nullptr);
949 cAssert(r != nullptr);
950 cAssert(l->IsValid());
951 cAssert(r->IsValid());
952 return Compare(l->ToCharPtr(), r->ToCharPtr()) == 0;
953}
954
955inline bool cStr::Equals(const char* r) const {
956 return cStr::Compare(ToCharPtr(), r) == 0;
957}
958
959// cStr.friend operator == : bool (const char *, const cStr &)
960inline bool operator == (const char* l, const cStr& r) {
961 cAssert(r.IsValid());
962 return cStr::Compare(l, r.ToCharPtr()) == 0;
963}
964
965// cStr.friend operator == : bool (const cStr &, const char *)
966inline bool operator == (const cStr& l, const char* r) {
967 cAssert(l.IsValid());
968 return cStr::Compare(l.ToCharPtr(), r) == 0;
969}
970
971// cStr.friend operator == : bool (const cStr &, const cStr &)
972inline bool operator == (const cStr& l, const cStr& r) {
973 cAssert(l.IsValid());
974 cAssert(r.IsValid());
975 return cStr::Compare(l.ToCharPtr(), r.ToCharPtr()) == 0;
976}
977
978// cStr.friend operator != : bool (const char *, const cStr &)
979inline bool operator != (const char* l, const cStr& r) {
980 cAssert(r.IsValid());
981 return cStr::Compare(l, r.ToCharPtr()) != 0;
982}
983
984// cStr.friend operator != : bool (const cStr &, const char *)
985inline bool operator != (const cStr& l, const char* r) {
986 cAssert(l.IsValid());
987 return cStr::Compare(l.ToCharPtr(), r) != 0;
988}
989
990// cStr.friend operator != : bool (const cStr &, const cStr &)
991inline bool operator != (const cStr& l, const cStr& r) {
992 cAssert(l.IsValid());
993 cAssert(r.IsValid());
994 return cStr::Compare(l.ToCharPtr(), r.ToCharPtr()) != 0;
995}
996
997// cStr::Equals : bool (const char *, const char *, const int)
998inline bool cStr::Equals(const char* l, const char* r, const int MaxLength) {
999 return Compare(l, r, MaxLength) == 0;
1000}
1001
1002// cStr::Equals : bool (const char *, const cStr &, const int)
1003inline bool cStr::Equals(const char* l, const cStr& r, const int MaxLength) {
1004 cAssert(r.IsValid());
1005 return Compare(l, r.ToCharPtr(), MaxLength) == 0;
1006}
1007
1008// cStr::Equals : bool (const cStr &, const char *, const int)
1009inline bool cStr::Equals(const cStr& l, const char* r, const int MaxLength) {
1010 cAssert(l.IsValid());
1011 return Compare(l.ToCharPtr(), r, MaxLength) == 0;
1012}
1013
1014// cStr::Equals : bool (const cStr &, const cStr &, const int)
1015inline bool cStr::Equals(const cStr& l, const cStr& r, const int MaxLength) {
1016 cAssert(l.IsValid());
1017 cAssert(r.IsValid());
1018 return Compare(l.ToCharPtr(), r.ToCharPtr(), MaxLength) == 0;
1019}
1020
1021// cStr::EqualsNoCase : bool (const char *, const char *)
1022inline bool cStr::EqualsNoCase(const char* l, const char* r) {
1023 return CompareNoCase(l, r) == 0;
1024}
1025
1026// cStr::EqualsNoCase : bool (const char *, const cStr &)
1027inline bool cStr::EqualsNoCase(const char* l, const cStr& r) {
1028 cAssert(r.IsValid());
1029 return CompareNoCase(l, r.ToCharPtr()) == 0;
1030}
1031
1032// cStr::EqualsNoCase : bool (const cStr &, const char *)
1033inline bool cStr::EqualsNoCase(const cStr& l, const char* r) {
1034 cAssert(l.IsValid());
1035 return CompareNoCase(l.ToCharPtr(), r) == 0;
1036}
1037
1038// cStr::EqualsNoCase : bool (const cStr &, const cStr &)
1039inline bool cStr::EqualsNoCase(const cStr& l, const cStr& r) {
1040 cAssert(l.IsValid());
1041 cAssert(r.IsValid());
1042 return CompareNoCase(l.ToCharPtr(), r.ToCharPtr()) == 0;
1043}
1044
1045// cStr::EqualsNoCase : bool (const cStr *, const cStr *)
1046inline bool cStr::EqualsNoCase(const cStr* l, const cStr* r) {
1047 cAssert(l != nullptr);
1048 cAssert(r != nullptr);
1049 cAssert(l->IsValid());
1050 cAssert(r->IsValid());
1051 return CompareNoCase(l->ToCharPtr(), r->ToCharPtr()) == 0;
1052}
1053
1054// cStr::EqualsNoCase : bool (const char *, const char *, const int)
1055inline bool cStr::EqualsNoCase(const char* l, const char* r, const int MaxLength) {
1056 return CompareNoCase(l, r, MaxLength) == 0;
1057}
1058
1059// cStr::EqualsNoCase : bool (const char *, const cStr &, const int)
1060inline bool cStr::EqualsNoCase(const char* l, const cStr& r, const int MaxLength) {
1061 cAssert(r.IsValid());
1062 return CompareNoCase(l, r.ToCharPtr(), MaxLength) == 0;
1063}
1064
1065// cStr::EqualsNoCase : bool (const cStr &, const char *, const int)
1066inline bool cStr::EqualsNoCase(const cStr& l, const char* r, const int MaxLength) {
1067 cAssert(l.IsValid());
1068 return CompareNoCase(l.ToCharPtr(), r, MaxLength) == 0;
1069}
1070
1071// cStr::EqualsNoCase : bool (const cStr &, const cStr &, const int)
1072inline bool cStr::EqualsNoCase(const cStr& l, const cStr& r, const int MaxLength) {
1073 cAssert(l.IsValid());
1074 cAssert(r.IsValid());
1075 return CompareNoCase(l.ToCharPtr(), r.ToCharPtr(), MaxLength) == 0;
1076}
1077
1078//-----------------------------------------------------------------------------
1079// cStr::Compare(NoCase) (>, >=, <, <=)
1080//-----------------------------------------------------------------------------
1081
1082// cStr::Compare : int (const char *, const char *)
1083inline int cStr::Compare(const char* l, const char* r) {
1084 return Compare(l, r, -1);
1085}
1086
1087// cStr::Compare : int (const char *, const cStr &)
1088inline int cStr::Compare(const char* l, const cStr& r) {
1089 cAssert(r.IsValid());
1090 return Compare(l, r.ToCharPtr());
1091}
1092
1093// cStr::Compare : int (const cStr &, const char *)
1094inline int cStr::Compare(const cStr& l, const char* r) {
1095 cAssert(l.IsValid());
1096 return Compare(l.ToCharPtr(), r);
1097}
1098
1099// cStr::Compare : int (const cStr &, const cStr &)
1100inline int cStr::Compare(const cStr& l, const cStr& r) {
1101 cAssert(l.IsValid());
1102 cAssert(r.IsValid());
1103 return Compare(l.ToCharPtr(), r.ToCharPtr());
1104}
1105
1106// cStr::Compare : int (const cStr *, const cStr *)
1107inline int cStr::Compare(const cStr* l, const cStr* r) {
1108 cAssert(l != nullptr);
1109 cAssert(r != nullptr);
1110 cAssert(l->IsValid());
1111 cAssert(r->IsValid());
1112 return Compare(l->ToCharPtr(), r->ToCharPtr());
1113}
1114
1115// cStr.friend operator > : bool (const char *, const cStr &)
1116inline bool operator > (const char* l, const cStr& r) {
1117 cAssert(r.IsValid());
1118 return cStr::Compare(l, r.ToCharPtr()) > 0;
1119}
1120
1121// cStr.friend operator > : bool (const cStr &, const char *)
1122inline bool operator > (const cStr& l, const char* r) {
1123 cAssert(l.IsValid());
1124 return cStr::Compare(l.ToCharPtr(), r) > 0;
1125}
1126
1127// cStr.friend operator > : bool (const cStr &, const cStr &)
1128inline bool operator > (const cStr& l, const cStr& r) {
1129 cAssert(l.IsValid());
1130 cAssert(r.IsValid());
1131 return cStr::Compare(l.ToCharPtr(), r.ToCharPtr()) > 0;
1132}
1133
1134// cStr.friend operator >= : bool (const char *, const cStr &)
1135inline bool operator >= (const char* l, const cStr& r) {
1136 cAssert(r.IsValid());
1137 return cStr::Compare(l, r.ToCharPtr()) >= 0;
1138}
1139
1140// cStr.friend operator >= : bool (const cStr &, const char *)
1141inline bool operator >= (const cStr& l, const char* r) {
1142 cAssert(l.IsValid());
1143 return cStr::Compare(l.ToCharPtr(), r) >= 0;
1144}
1145
1146// cStr.friend operator >= : bool (const cStr &, const cStr &)
1147inline bool operator >= (const cStr& l, const cStr& r) {
1148 cAssert(l.IsValid());
1149 cAssert(r.IsValid());
1150 return cStr::Compare(l.ToCharPtr(), r.ToCharPtr()) >= 0;
1151}
1152
1153// cStr.friend operator < : bool (const char *, const cStr &)
1154inline bool operator < (const char* l, const cStr& r) {
1155 cAssert(r.IsValid());
1156 return cStr::Compare(l, r.ToCharPtr()) < 0;
1157}
1158
1159// cStr.friend operator < : bool (const cStr &, const char *)
1160inline bool operator < (const cStr& l, const char* r) {
1161 cAssert(l.IsValid());
1162 return cStr::Compare(l.ToCharPtr(), r) < 0;
1163}
1164
1165// cStr.friend operator < : bool (const cStr &, const cStr &)
1166inline bool operator < (const cStr& l, const cStr& r) {
1167 cAssert(l.IsValid());
1168 cAssert(r.IsValid());
1169 return cStr::Compare(l.ToCharPtr(), r.ToCharPtr()) < 0;
1170}
1171
1172// cStr.friend operator <= : bool (const char *, const cStr &)
1173inline bool operator <= (const char* l, const cStr& r) {
1174 cAssert(r.IsValid());
1175 return cStr::Compare(l, r.ToCharPtr()) <= 0;
1176}
1177
1178// cStr.friend operator <= : bool (const cStr &, const char *)
1179inline bool operator <= (const cStr& l, const char* r) {
1180 cAssert(l.IsValid());
1181 return cStr::Compare(l.ToCharPtr(), r) <= 0;
1182}
1183
1184// cStr.friend operator <= : bool (const cStr &, const cStr &)
1185inline bool operator <= (const cStr& l, const cStr& r) {
1186 cAssert(l.IsValid());
1187 cAssert(r.IsValid());
1188 return cStr::Compare(l.ToCharPtr(), r.ToCharPtr()) <= 0;
1189}
1190
1191// cStr::Compare : int (const char *, const cStr &, const int)
1192inline int cStr::Compare(const char* l, const cStr& r, const int MaxLength) {
1193 cAssert(r.IsValid());
1194 return Compare(l, r.ToCharPtr(), MaxLength);
1195}
1196
1197// cStr::Compare : int (const cStr &, const char *, const int)
1198inline int cStr::Compare(const cStr& l, const char* r, const int MaxLength) {
1199 cAssert(l.IsValid());
1200 return Compare(l.ToCharPtr(), r, MaxLength);
1201}
1202
1203// cStr::Compare : int (const cStr &, const cStr &, const int)
1204inline int cStr::Compare(const cStr& l, const cStr& r, const int MaxLength) {
1205 cAssert(l.IsValid());
1206 cAssert(r.IsValid());
1207 return Compare(l.ToCharPtr(), r.ToCharPtr(), MaxLength);
1208}
1209
1210// cStr::CompareNoCase : int (const char *, const char *)
1211inline int cStr::CompareNoCase(const char* l, const char* r) {
1212 return CompareNoCase(l, r, -1);
1213}
1214
1215// cStr::CompareNoCase : int (const char *, const cStr &)
1216inline int cStr::CompareNoCase(const char* l, const cStr& r) {
1217 cAssert(r.IsValid());
1218 return CompareNoCase(l, r.ToCharPtr());
1219}
1220
1221// cStr::CompareNoCase : int (const cStr &, const char *)
1222inline int cStr::CompareNoCase(const cStr& l, const char* r) {
1223 cAssert(l.IsValid());
1224 return CompareNoCase(l.ToCharPtr(), r);
1225}
1226
1227// cStr::CompareNoCase : int (const cStr &, const cStr &)
1228inline int cStr::CompareNoCase(const cStr& l, const cStr& r) {
1229 cAssert(l.IsValid());
1230 cAssert(r.IsValid());
1231 return CompareNoCase(l.ToCharPtr(), r.ToCharPtr());
1232}
1233
1234// cStr::CompareNoCase : int (const cStr *, const cStr *)
1235inline int cStr::CompareNoCase(const cStr* l, const cStr* r) {
1236 cAssert(l != nullptr);
1237 cAssert(r != nullptr);
1238 cAssert(l->IsValid());
1239 cAssert(r->IsValid());
1240 return CompareNoCase(l->ToCharPtr(), r->ToCharPtr());
1241}
1242
1243// cStr::CompareNoCase : int (const char *, const cStr &, const int)
1244inline int cStr::CompareNoCase(const char* l, const cStr& r, const int MaxLength) {
1245 cAssert(r.IsValid());
1246 return CompareNoCase(l, r.ToCharPtr(), MaxLength);
1247}
1248
1249// cStr::CompareNoCase : int (const cStr &, const char *, const int)
1250inline int cStr::CompareNoCase(const cStr& l, const char* r, const int MaxLength) {
1251 cAssert(l.IsValid());
1252 return CompareNoCase(l.ToCharPtr(), r, MaxLength);
1253}
1254
1255// cStr::CompareNoCase : int (const cStr &, const cStr &, const int)
1256inline int cStr::CompareNoCase(const cStr& l, const cStr& r, const int MaxLength) {
1257 cAssert(l.IsValid());
1258 cAssert(r.IsValid());
1259 return CompareNoCase(l.ToCharPtr(), r.ToCharPtr(), MaxLength);
1260}
1261
1262//-----------------------------------------------------------------------------
1263// cStr::EqualsPath
1264//-----------------------------------------------------------------------------
1265
1266// cStr::EqualsPath : bool (const char *, const char *)
1267inline bool cStr::EqualsPath(const char* l, const char* r) {
1268 return ComparePath(l, r) == 0;
1269}
1270
1271// cStr::EqualsPath : bool (const char *, const cStr &)
1272inline bool cStr::EqualsPath(const char* l, const cStr& r) {
1273 cAssert(r.IsValid());
1274 return ComparePath(l, r.ToCharPtr()) == 0;
1275}
1276
1277// cStr::EqualsPath : bool (const cStr &, const char *)
1278inline bool cStr::EqualsPath(const cStr& l, const char* r) {
1279 cAssert(l.IsValid());
1280 return ComparePath(l.ToCharPtr(), r) == 0;
1281}
1282
1283// cStr::EqualsPath : bool (const cStr &, const cStr &)
1284inline bool cStr::EqualsPath(const cStr& l, const cStr& r) {
1285 cAssert(l.IsValid());
1286 cAssert(r.IsValid());
1287 return ComparePath(l.ToCharPtr(), r.ToCharPtr()) == 0;
1288}
1289
1290// cStr::EqualsPath : bool (const cStr *, const cStr *)
1291inline bool cStr::EqualsPath(const cStr* l, const cStr* r) {
1292 cAssert(l != nullptr);
1293 cAssert(r != nullptr);
1294 cAssert(l->IsValid());
1295 cAssert(r->IsValid());
1296 return ComparePath(l->ToCharPtr(), r->ToCharPtr()) == 0;
1297}
1298
1299// cStr::EqualsPath : bool (const char *, const char *, const int)
1300inline bool cStr::EqualsPath(const char* l, const char* r, const int MaxLength) {
1301 return ComparePath(l, r, MaxLength) == 0;
1302}
1303
1304// cStr::EqualsPath : bool (const char *, const cStr &, const int)
1305inline bool cStr::EqualsPath(const char* l, const cStr& r, const int MaxLength) {
1306 cAssert(r.IsValid());
1307 return ComparePath(l, r.ToCharPtr(), MaxLength) == 0;
1308}
1309
1310// cStr::EqualsPath : bool (const cStr &, const char *, const int)
1311inline bool cStr::EqualsPath(const cStr& l, const char* r, const int MaxLength) {
1312 cAssert(l.IsValid());
1313 return ComparePath(l.ToCharPtr(), r, MaxLength) == 0;
1314}
1315
1316// cStr::EqualsPath : bool (const cStr &, const cStr &, const int)
1317inline bool cStr::EqualsPath(const cStr& l, const cStr& r, const int MaxLength) {
1318 cAssert(l.IsValid());
1319 cAssert(r.IsValid());
1320 return ComparePath(l.ToCharPtr(), r.ToCharPtr(), MaxLength) == 0;
1321}
1322
1323//-----------------------------------------------------------------------------
1324// cStr::ComparePath
1325//-----------------------------------------------------------------------------
1326
1327// cStr::ComparePath : int (const char *, const char *)
1328inline int cStr::ComparePath(const char* l, const char* r) {
1329 return ComparePath(l, r, -1);
1330}
1331
1332// cStr::ComparePath : int (const char *, const cStr &)
1333inline int cStr::ComparePath(const char* l, const cStr& r) {
1334 cAssert(r.IsValid());
1335 return ComparePath(l, r.ToCharPtr());
1336}
1337
1338// cStr::ComparePath : int (const cStr &, const char *)
1339inline int cStr::ComparePath(const cStr& l, const char* r) {
1340 cAssert(l.IsValid());
1341 return ComparePath(l.ToCharPtr(), r);
1342}
1343
1344// cStr::ComparePath : int (const cStr &, const cStr &)
1345inline int cStr::ComparePath(const cStr& l, const cStr& r) {
1346 cAssert(l.IsValid());
1347 cAssert(r.IsValid());
1348 return ComparePath(l.ToCharPtr(), r.ToCharPtr());
1349}
1350
1351// cStr::ComparePath : int (const cStr *, const cStr *)
1352inline int cStr::ComparePath(const cStr* l, const cStr* r) {
1353 cAssert(l != nullptr);
1354 cAssert(r != nullptr);
1355 cAssert(l->IsValid());
1356 cAssert(r->IsValid());
1357 return ComparePath(l->ToCharPtr(), r->ToCharPtr());
1358}
1359
1360// cStr::ComparePath : int (const char *, const cStr &, const int)
1361inline int cStr::ComparePath(const char* l, const cStr& r, const int MaxLength) {
1362 cAssert(r.IsValid());
1363 return ComparePath(l, r.ToCharPtr(), MaxLength);
1364}
1365
1366// cStr::ComparePath : int (const cStr &, const char *, const int)
1367inline int cStr::ComparePath(const cStr& l, const char* r, const int MaxLength) {
1368 cAssert(l.IsValid());
1369 return ComparePath(l.ToCharPtr(), r, MaxLength);
1370}
1371
1372// cStr::ComparePath : int (const cStr &, const cStr &, const int)
1373inline int cStr::ComparePath(const cStr& l, const cStr& r, const int MaxLength) {
1374 cAssert(l.IsValid());
1375 cAssert(r.IsValid());
1376 return ComparePath(l.ToCharPtr(), r.ToCharPtr(), MaxLength);
1377}
1378
1379//-----------------------------------------------------------------------------
1380// cStr::StartsWith / cStr::EndsWith
1381//-----------------------------------------------------------------------------
1382
1383// cStr::StartsWith
1384inline bool cStr::StartsWith(const char* Str, const bool NoCase) const {
1385 cAssert(IsValid());
1386 cAssert(Str != nullptr);
1387
1388 int L;
1389
1390 L = Length(Str);
1391 return NoCase ? EqualsNoCase(m_Str, Str, L) : Equals(m_Str, Str, L);
1392}
1393
1394// cStr::EndsWith
1395inline bool cStr::EndsWith(const char* Str, const bool NoCase) const {
1396 cAssert(IsValid());
1397 cAssert(Str != nullptr);
1398
1399 int L;
1400
1401 L = Length(Str);
1402 if (L > m_Length) {
1403 return false;
1404 }
1405
1406 return NoCase ? EqualsNoCase(&m_Str[m_Length - L], Str) : Equals(&m_Str[m_Length - L], Str);
1407} // cStr::EndsWith
1408
1409//-----------------------------------------------------------------------------
1410// cStr::ToString
1411//-----------------------------------------------------------------------------
1412
1413// cStr::ToString : (const bool)
1414inline const cStr cStr::ToString(const bool b) {
1415 return b ? "True" : "False";
1416}
1417
1418// cStr::ToString : (const int)
1419inline const cStr cStr::ToString(const int i) {
1420 return Format("%d", i);
1421}
1422
1423// cStr::ToString : (const int, const int)
1424inline const cStr cStr::ToString(const int i, const int Prec) {
1425 return Format(Format("%%0%dd", Prec), i);
1426}
1427
1428// cStr::ToString : (const float, ...)
1429inline const cStr cStr::ToString(const float f, const int Prec) {
1430 cStr S = Format(Format("%%.%df", Prec), f);
1431 S.Replace(',', '.');
1432 return S;
1433}
1434
1435// cStr::ToString : (const double, ...)
1436inline const cStr cStr::ToString(const double d, const int Prec) {
1437 cStr S = Format(Format("%%.%df", Prec), d);
1438 S.Replace(',', '.');
1439 return S;
1440}
1441
1442// cStr::ToHex : (dword)
1443inline const cStr cStr::ToHex(const dword dw) {
1444 return cStr::Format("0x%08x", dw);
1445}
1446
1447// cStr::ToHex : (qword)
1448inline const cStr cStr::ToHex(const qword qw) {
1449 return cStr::Format("0x%016llx", qw);
1450}
1451
1452// cStr::ToHex : (void *)
1453inline const cStr cStr::ToHex(const void* Ptr) {
1454 return cStr::Format("%p", Ptr);
1455}
1456
1457//-----------------------------------------------------------------------------
1458// cStr::Append
1459//-----------------------------------------------------------------------------
1460
1461// cStr::Append : (const cStr &)
1462inline void cStr::Append(const cStr& Src) {
1463 Append(Src, 0, Src.m_Length);
1464}
1465
1466// cStr::Append : (const char *)
1467inline void cStr::Append(const char* Src) {
1468 Append(Src, 0, Length(Src));
1469}
1470
1471inline void cStr::Append(const wchar_t* Src) {
1472 cStr r(Src);
1473 Append(r);
1474}
1475
1476// cStr::Append : (const char)
1477inline void cStr::Append(const char c) {
1478 Append(c, 1);
1479}
1480
1481// cStr::Append : (const bool)
1482inline void cStr::Append(const bool b) {
1483 Append(ToString(b));
1484}
1485
1486// cStr::Append : (const int)
1487inline void cStr::Append(const int i) {
1488 Append(ToString(i));
1489}
1490
1491// cStr::Append : (const float, const int)
1492inline void cStr::Append(const float f, const int Prec) {
1493 Append(ToString(f, Prec));
1494}
1495
1496// cStr::Append : (const double, const int)
1497inline void cStr::Append(const double d, const int Prec) {
1498 Append(ToString(d, Prec));
1499}
1500
1501//*****************************************************************************
1502// cStr::operator +=
1503//*****************************************************************************
1504
1505// cStr::operator += : (const cStr &)
1506inline void cStr::operator += (const cStr& Src) {
1507 Append(Src);
1508}
1509
1510// cStr::operator += : (const char *)
1511inline void cStr::operator += (const char* Src) {
1512 Append(Src);
1513}
1514
1515inline void cStr::operator += (const wchar_t* Src) {
1516 Append(Src);
1517}
1518
1519// cStr::operator += : (const char)
1520inline void cStr::operator += (const char c) {
1521 Append(c);
1522}
1523
1524// cStr::operator += (const bool)
1525inline void cStr::operator += (const bool b) {
1526 Append(b);
1527}
1528
1529// cStr::operator += : (const int)
1530inline void cStr::operator += (const int i) {
1531 Append(i);
1532}
1533
1534// cStr::operator += : (const float)
1535inline void cStr::operator += (const float f) {
1536 Append(f);
1537}
1538
1539// cStr::operator += : (const double)
1540inline void cStr::operator += (const double d) {
1541 Append(d);
1542}
1543
1544//*****************************************************************************
1545// cStr::operator <<
1546//*****************************************************************************
1547
1548// cStr::operator << : (const cStr &)
1549inline cStr& cStr::operator << (const cStr& Src) {
1550 Append(Src);
1551 return *this;
1552}
1553
1554// cStr::operator << : (const char *)
1555inline cStr& cStr::operator << (const char* Src) {
1556 Append(Src);
1557 return *this;
1558}
1559
1560inline cStr& cStr::operator << (const wchar_t* Src) {
1561 Append(Src);
1562 return *this;
1563}
1564
1565// cStr::operator << : (const char)
1566inline cStr& cStr::operator << (const char c) {
1567 Append(c);
1568 return *this;
1569}
1570
1571// cStr::operator << : (const bool)
1572inline cStr& cStr::operator << (const bool b) {
1573 Append(b);
1574 return *this;
1575}
1576
1577// cStr::operator << : (const int)
1578inline cStr& cStr::operator << (const int i) {
1579 Append(i);
1580 return *this;
1581}
1582
1583// cStr::operator << : (const float)
1584inline cStr& cStr::operator << (const float f) {
1585 Append(f);
1586 return *this;
1587}
1588
1589// cStr::operator << : (const double)
1590inline cStr& cStr::operator << (const double d) {
1591 Append(d);
1592 return *this;
1593}
1594
1595//*****************************************************************************
1596// cStr::friend operator +
1597//*****************************************************************************
1598
1599// cStr::friend operator + : (const cStr &, const cStr &)
1600inline const cStr operator + (const cStr& l, const cStr& r) {
1601 cStr t(l);
1602 t.Append(r);
1603 return t;
1604}
1605
1606// cStr::friend operator + : (const cStr &, const char *)
1607inline const cStr operator + (const cStr& l, const char* r) {
1608 cStr t(l);
1609 t.Append(r);
1610 return t;
1611}
1612
1613// cStr::friend operator + : (const char *, const cStr &)
1614inline const cStr operator + (const char* l, const cStr& r) {
1615 cStr t(l);
1616 t.Append(r);
1617 return t;
1618}
1619
1620// cStr::friend operator + : (const cStr &, const char)
1621inline const cStr operator + (const cStr& l, const char c) {
1622 cStr t(l);
1623 t.Append(c);
1624 return t;
1625}
1626
1627// cStr::friend operator + : (const char, const cStr &)
1628inline const cStr operator + (const char c, const cStr& r) {
1629 cStr t;
1630 t.Append(c);
1631 t.Append(r);
1632 return t;
1633}
1634
1635// cStr::friend operator + : (const cStr &, const bool)
1636inline const cStr operator + (const cStr& l, const bool b) {
1637 cStr t(l);
1638 t.Append(b);
1639 return t;
1640}
1641
1642// cStr::friend operator + : (const bool, const cStr &)
1643inline const cStr operator + (const bool b, const cStr& r) {
1644 cStr t;
1645 t.Append(b);
1646 t.Append(r);
1647 return t;
1648}
1649
1650// cStr::friend operator + : (const cStr &, const int)
1651inline const cStr operator + (const cStr& l, const int i) {
1652 cStr t(l);
1653 t.Append(i);
1654 return t;
1655}
1656
1657// cStr::friend operator + : (const int, const cStr &)
1658inline const cStr operator + (const int i, const cStr& r) {
1659 cStr t;
1660 t.Append(i);
1661 t.Append(r);
1662 return t;
1663}
1664
1665// cStr::friend operator + : (const cStr &, const float)
1666inline const cStr operator + (const cStr& l, const float f) {
1667 cStr t(l);
1668 t.Append(f);
1669 return t;
1670}
1671
1672// cStr::friend operator + : (const float, const cStr &)
1673inline const cStr operator + (const float f, const cStr& r) {
1674 cStr t;
1675 t.Append(f);
1676 t.Append(r);
1677 return t;
1678}
1679
1680// cStr::friend operator + : (const cStr &, const double)
1681inline const cStr operator + (const cStr& l, const double d) {
1682 cStr t(l);
1683 t.Append(d);
1684 return t;
1685}
1686
1687// cStr::friend operator + : (const double, const cStr &)
1688inline const cStr operator + (const double d, const cStr& r) {
1689 cStr t;
1690 t.Append(d);
1691 t.Append(r);
1692 return t;
1693}
1694
1695inline const cStr operator + (const cStr& l, const wchar_t* r) {
1696 cStr s(l);
1697 s.Append(r);
1698 return s;
1699}
1700inline const cStr operator + (const wchar_t* l, const cStr& r) {
1701 cStr s(l);
1702 s.Append(r);
1703 return s;
1704}
1705
1706//-----------------------------------------------------------------------------
1707// cStr::Insert
1708//-----------------------------------------------------------------------------
1709
1710// cStr::Insert : (..., const cStr &)
1711inline void cStr::Insert(const int Index, const cStr& Src) {
1712 Insert(Index, Src, 0, Src.m_Length);
1713}
1714
1715// cStr::Insert : (..., const char *)
1716inline void cStr::Insert(const int Index, const char* Src) {
1717 Insert(Index, Src, 0, Length(Src));
1718}
1719
1720// cStr::Insert : (..., const char)
1721inline void cStr::Insert(const int Index, const char c) {
1722 Insert(Index, c, 1);
1723}
1724
1725// cStr::Insert : (..., const bool)
1726inline void cStr::Insert(const int Index, const bool b) {
1727 Insert(Index, ToString(b));
1728}
1729
1730// cStr::Insert : (..., const int)
1731inline void cStr::Insert(const int Index, const int i) {
1732 Insert(Index, ToString(i));
1733}
1734
1735// cStr::Insert : (..., const float, ...)
1736inline void cStr::Insert(const int Index, const float f, const int Prec) {
1737 Insert(Index, ToString(f, Prec));
1738}
1739
1740// cStr::Insert : (..., const double, ...)
1741inline void cStr::Insert(const int Index, const double d, const int Prec) {
1742 Insert(Index, ToString(d, Prec));
1743}
1744
1745//-----------------------------------------------------------------------------
1746// cStr::Remove
1747//-----------------------------------------------------------------------------
1748
1749// cStr::Remove : (const int)
1750inline void cStr::Remove(const int StartIndex) {
1751 Remove(StartIndex, m_Length - StartIndex);
1752}
1753
1754// cStr::Remove : (const int, const int)
1755inline void cStr::Remove(const int StartIndex, const int Count) {
1756 cAssert(IsValid());
1757 cAssert(StartIndex >= 0);
1758 cAssert(Count >= 0);
1759 cAssert(StartIndex + Count <= m_Length);
1760
1761 if (Count > 0) {
1762 memmove(&m_Str[StartIndex], &m_Str[StartIndex + Count], m_Length - (StartIndex + Count) + 1);
1763 m_Length -= Count;
1764 }
1765}
1766
1767//-----------------------------------------------------------------------------
1768// cStr::Replace : (const char, const char, ...)
1769//-----------------------------------------------------------------------------
1770
1771// cStr::Replace : (const char, const char)
1772inline void cStr::Replace(const char Char, const char WithChar) {
1773 Replace(Char, WithChar, 0, m_Length);
1774}
1775
1776//-----------------------------------------------------------------------------
1777// cStr::Replace : (const char *, const char *, ...)
1778//-----------------------------------------------------------------------------
1779
1780// cStr::Replace : (const char *, const char *)
1781inline int cStr::Replace(const char* String, const char* WithString, const bool NoCase) {
1782 return Replace(String, WithString, 0, m_Length, NoCase);
1783}
1784
1785// cStr::Replace : (const char *, const char *, const int)
1786inline int cStr::Replace(const char* String, const char* WithString, const int StartIndex, const bool NoCase) {
1787 return Replace(String, WithString, StartIndex, m_Length - StartIndex, NoCase);
1788}
1789
1790//-----------------------------------------------------------------------------
1791// cStr::ReplaceFirst : (const char *, const char *, ...)
1792//-----------------------------------------------------------------------------
1793
1794// cStr::ReplaceFirst : (const char *, const char *)
1795inline int cStr::ReplaceFirst(const char* String, const char* WithString, const bool NoCase) {
1796 return ReplaceFirst(String, WithString, 0, m_Length, NoCase);
1797}
1798
1799//-----------------------------------------------------------------------------
1800// cStr::ReplaceAny : (const char *, const char, ...)
1801//-----------------------------------------------------------------------------
1802
1803// cStr::ReplaceAny : (const char *, const char)
1804inline void cStr::ReplaceAny(const char* Chars, const char WithChar) {
1805 ReplaceAny(Chars, WithChar, 0, m_Length);
1806}
1807
1808//-----------------------------------------------------------------------------
1809// cStr::Substring
1810//-----------------------------------------------------------------------------
1811
1812// cStr::Substring : (const int)
1813inline const cStr cStr::Substring(const int StartIndex) const {
1814 cAssert(IsValid());
1815 cAssert(StartIndex >= 0);
1816 cAssert(StartIndex <= m_Length); // For empty string returns empty string
1817 return cStr(m_Str, StartIndex, m_Length - StartIndex);
1818}
1819
1820// cStr::Substring : (const int, const int)
1821inline const cStr cStr::Substring(const int StartIndex, const int Count) const {
1822 cAssert(IsValid());
1823 cAssert(StartIndex >= 0);
1824 cAssert(Count >= 0);
1825 cAssert(StartIndex + Count <= m_Length);
1826 return cStr(m_Str, StartIndex, Count);
1827}
1828
1829//-----------------------------------------------------------------------------
1830// cStr::Trim...
1831//-----------------------------------------------------------------------------
1832
1833// cStr::TrimStart
1834inline void cStr::TrimStart(const char* TrimChars) {
1835 cAssert(IsValid());
1836 if (m_Str) {
1837 cStr t(TrimChars);
1838 while (t.Contains(m_Str[0])) {
1839 memmove(&m_Str[0], &m_Str[1], m_Length);
1840 m_Length--;
1841 }
1842 }
1843}
1844
1845// cStr::TrimEnd
1846inline void cStr::TrimEnd(const char* TrimChars) {
1847 cAssert(IsValid());
1848 if (m_Str) {
1849 int i;
1850 cStr t(TrimChars);
1851 for (i = m_Length; i > 0 && t.Contains(m_Str[i - 1]); i--) {
1852 m_Str[i - 1] = '\0';
1853 m_Length--;
1854 }
1855 }
1856}
1857
1858// cStr::Trim
1859inline void cStr::Trim(const char* TrimChars) {
1860 TrimStart(TrimChars);
1861 TrimEnd(TrimChars);
1862}
1863
1864//-----------------------------------------------------------------------------
1865// cStr::PadLeft / PadRight
1866//-----------------------------------------------------------------------------
1867
1868// cStr::PadLeft
1869inline void cStr::PadLeft(const int TotalWidth, const char PaddingChar) {
1870 cAssert(IsValid());
1871 cAssert(TotalWidth >= 0);
1872
1873 const char TrimChars[2] = {
1874 PaddingChar, '\0'
1875 };
1876
1877 TrimStart(TrimChars);
1878 if (TotalWidth > m_Length) {
1879 Insert(0, PaddingChar, TotalWidth - m_Length);
1880 }
1881}
1882
1883// cStr::PadRight
1884inline void cStr::PadRight(const int TotalWidth, const char PaddingChar) {
1885 cAssert(IsValid());
1886 cAssert(TotalWidth >= 0);
1887
1888 const char TrimChars[2] = {
1889 PaddingChar, '\0'
1890 };
1891
1892 TrimEnd(TrimChars);
1893 if (TotalWidth > m_Length) {
1894 Append(PaddingChar, TotalWidth - m_Length);
1895 }
1896}
1897
1898//-----------------------------------------------------------------------------
1899// cStr::Contains
1900//-----------------------------------------------------------------------------
1901
1902// cStr::Contains : (const char)
1903inline bool cStr::Contains(const char c) const {
1904 return IndexOf(c, 0, m_Length) != -1;
1905}
1906
1907// cStr::Contains : (const char *, const bool)
1908inline bool cStr::Contains(const char* Str, const bool NoCase) const {
1909 return IndexOf(Str, 0, m_Length, NoCase) != -1;
1910}
1911
1912//-----------------------------------------------------------------------------
1913// cStr::IndexOf : (const char, ...)
1914//-----------------------------------------------------------------------------
1915
1916// cStr::IndexOf : (const char)
1917inline int cStr::IndexOf(const char c) const {
1918 return IndexOf(c, 0, m_Length);
1919}
1920
1921// cStr::IndexOf : (const char *, const char)
1922inline int cStr::IndexOf(const char* Src, const char c) {
1923 cAssert(Src != nullptr);
1924 int i = -1, j;
1925 if (Src != nullptr) {
1926 j = 0;
1927 while (*Src != '\0') {
1928 if (*Src == c) {
1929 i = j;
1930 break;
1931 }
1932 Src++;
1933 j++;
1934 }
1935 }
1936 return i;
1937}
1938
1939// cStr::IndexOf : (const char, const int)
1940inline int cStr::IndexOf(const char c, const int StartIndex) const {
1941 return IndexOf(c, StartIndex, m_Length - StartIndex);
1942}
1943
1944// cStr::IndexOf : (const char, const int, const int)
1945inline int cStr::IndexOf(const char c, const int StartIndex, const int Count) const {
1946 cAssert(IsValid());
1947 cAssert(StartIndex >= 0);
1948 cAssert(Count >= 0);
1949 cAssert(StartIndex + Count <= m_Length);
1950 if (m_Str) {
1951 int i1, i;
1952
1953 i1 = StartIndex + Count - 1;
1954 for (i = StartIndex; i <= i1; i++) {
1955 if (m_Str[i] == c) {
1956 return i;
1957 }
1958 }
1959 }
1960
1961 return -1;
1962} // cStr::IndexOf : (const char, ...)
1963
1964//-----------------------------------------------------------------------------
1965// cStr::IndexOf : (const char *, ...)
1966//-----------------------------------------------------------------------------
1967
1968// cStr::IndexOf : (const char *, const bool)
1969inline int cStr::IndexOf(const char* Str, const bool NoCase) const {
1970 return IndexOf(Str, 0, m_Length, NoCase);
1971}
1972
1973// cStr::IndexOf : (const char *, const int, const bool)
1974inline int cStr::IndexOf(const char* Str, const int StartIndex, const bool NoCase) const {
1975 return IndexOf(Str, StartIndex, m_Length - StartIndex, NoCase);
1976}
1977
1978// cStr::IndexOf : (const char *, const int, const int, const bool)
1979inline int cStr::IndexOf(const char* Str, const int StartIndex, const int Count, const bool NoCase) const {
1980 cAssert(IsValid());
1981 cAssert(StartIndex >= 0);
1982 cAssert(Count >= 0);
1983 cAssert(StartIndex + Count <= m_Length);
1984 if (m_Str) {
1985 int L, i1, i;
1986
1987 L = Length(Str);
1988 i1 = StartIndex + Count - 1;
1989
1990 for (i = StartIndex; i <= i1; i++) {
1991 if (NoCase ? EqualsNoCase(&m_Str[i], Str, L) : Equals(&m_Str[i], Str, L)) {
1992 return i;
1993 }
1994 }
1995 }
1996
1997 return -1;
1998} // cStr::IndexOf : (const char *, ...)
1999
2000//-----------------------------------------------------------------------------
2001// cStr::IndexOfAny
2002//-----------------------------------------------------------------------------
2003
2004// cStr::IndexOfAny : (const char *)
2005inline int cStr::IndexOfAny(const char* Chars) const {
2006 return IndexOfAny(Chars, 0, m_Length);
2007}
2008
2009// cStr::IndexOfAny : (const char *, const int)
2010inline int cStr::IndexOfAny(const char* Chars, const int StartIndex) const {
2011 return IndexOfAny(Chars, StartIndex, m_Length - StartIndex);
2012}
2013
2014// cStr::IndexOfAny : (const char *, const int, const int)
2015inline int cStr::IndexOfAny(const char* Chars, const int StartIndex, const int Count) const {
2016 cAssert(IsValid());
2017 cAssert(StartIndex >= 0);
2018 cAssert(Count >= 0);
2019 cAssert(StartIndex + Count <= m_Length);
2020 if (m_Str) {
2021 int i1, i;
2022 char c;
2023 cStr t(Chars);
2024
2025 i1 = StartIndex + Count - 1;
2026 for (i = StartIndex; i <= i1; i++) {
2027 c = m_Str[i];
2028 if (t.Contains(c)) {
2029 return i;
2030 }
2031 }
2032 }
2033
2034 return -1;
2035} // cStr::IndexOfAny : (const char *, ...)
2036
2037//-----------------------------------------------------------------------------
2038// cStr::LastIndexOf : (const char, ...)
2039//-----------------------------------------------------------------------------
2040
2041// cStr::LastIndexOf : (const char)
2042inline int cStr::LastIndexOf(const char c) const {
2043 return LastIndexOf(c, m_Length - 1, m_Length);
2044}
2045
2046// cStr::LastIndexOf : (const char, const int)
2047inline int cStr::LastIndexOf(const char c, const int StartIndex) const {
2048 return LastIndexOf(c, StartIndex, StartIndex + 1);
2049}
2050
2051// cStr::LastIndexOf : (const char, const int, const int)
2052inline int cStr::LastIndexOf(const char c, const int StartIndex, const int Count) const {
2053 cAssert(IsValid());
2054 cAssert(Count >= 0);
2055
2056 if (m_Length == 0 || m_Str == nullptr) {
2057 cAssert(StartIndex >= -1);
2058 cAssert(StartIndex <= 0);
2059
2060 return -1;
2061 }
2062
2063 cAssert(StartIndex >= 0);
2064 cAssert(StartIndex < m_Length);
2065 cAssert(Count <= StartIndex + 1);
2066
2067 int i0, i;
2068
2069 i0 = StartIndex - Count + 1;
2070 for (i = StartIndex; i >= i0; i--) {
2071 if (c == m_Str[i]) {
2072 return i;
2073 }
2074 }
2075
2076 return -1;
2077} // cStr::LastIndexOf : (const char, ...)
2078
2079//-----------------------------------------------------------------------------
2080// cStr::LastIndexOf : (const char *, ...)
2081//-----------------------------------------------------------------------------
2082
2083// cStr::LastIndexOf : (const char *, const bool)
2084inline int cStr::LastIndexOf(const char* Str, const bool NoCase) const {
2085 return LastIndexOf(Str, m_Length - 1, m_Length, NoCase);
2086}
2087
2088// cStr::LastIndexOf : (const char *, const int, const bool)
2089inline int cStr::LastIndexOf(const char* Str, const int StartIndex, const bool NoCase) const {
2090 return LastIndexOf(Str, StartIndex, StartIndex + 1, NoCase);
2091}
2092
2093// cStr::LastIndexOf : (const char *, const int, const int, const bool)
2094inline int cStr::LastIndexOf(const char* Str, const int StartIndex, const int Count, const bool NoCase) const {
2095 cAssert(IsValid());
2096 cAssert(Count >= 0);
2097 if (m_Str == nullptr)return -1;
2098
2099 int L, i0, i;
2100
2101 L = Length(Str);
2102
2103 if (m_Length == 0) {
2104 cAssert(StartIndex >= -1);
2105 cAssert(StartIndex <= 0);
2106
2107 if (L > 0) {
2108 return -1;
2109 }
2110 return 0;
2111 }
2112
2113 cAssert(StartIndex >= 0);
2114 cAssert(StartIndex < m_Length);
2115 cAssert(Count <= StartIndex + 1);
2116
2117 i0 = StartIndex - Count + 1;
2118 for (i = StartIndex; i >= i0; i--) {
2119 if (NoCase ? EqualsNoCase(&m_Str[i], Str, L) : Equals(&m_Str[i], Str, L)) {
2120 return i;
2121 }
2122 }
2123
2124 return -1;
2125} // cStr::LastIndexOf : (const char *, ...)
2126
2127//-----------------------------------------------------------------------------
2128// cStr::LastIndexOfAny
2129//-----------------------------------------------------------------------------
2130
2131// cStr::LastIndexOfAny : (const char *)
2132inline int cStr::LastIndexOfAny(const char* Chars) const {
2133 return LastIndexOfAny(Chars, m_Length - 1, m_Length);
2134}
2135
2136// cStr::LastIndexOfAny : (const char *, const int)
2137inline int cStr::LastIndexOfAny(const char* Chars, const int StartIndex) const {
2138 return LastIndexOfAny(Chars, StartIndex, StartIndex + 1);
2139}
2140
2141// cStr::LastIndexOfAny : (const char *, const int, const int)
2142inline int cStr::LastIndexOfAny(const char* Chars, const int StartIndex, const int Count) const {
2143 cAssert(IsValid());
2144 cAssert(Count >= 0);
2145 if (m_Str == nullptr)return -1;
2146 if (m_Length == 0) {
2147 cAssert(StartIndex >= -1);
2148 cAssert(StartIndex <= 0);
2149
2150 return -1;
2151 }
2152
2153 cAssert(StartIndex >= 0);
2154 cAssert(StartIndex < m_Length);
2155 cAssert(Count <= StartIndex + 1);
2156
2157 int i0, i;
2158 char c;
2159 cStr t(Chars);
2160
2161 i0 = StartIndex - Count + 1;
2162 for (i = StartIndex; i >= i0; i--) {
2163 c = m_Str[i];
2164 if (t.Contains(c)) {
2165 return i;
2166 }
2167 }
2168
2169 return -1;
2170} // cStr::LastIndexOfAny
2171
2172
2173//-----------------------------------------------------------------------------
2174// ToLower / ToUpper, MakeLower / MakeUpper
2175//-----------------------------------------------------------------------------
2176
2177// cStr::ToLower : (const char)
2178inline char cStr::ToLower(const char c) {
2179 if (c >= 'A' && c <= 'Z') {
2180 return c + ('a' - 'A');
2181 }
2182 return c;
2183}
2184
2185// cStr::ToUpper : (const char)
2186inline char cStr::ToUpper(const char c) {
2187 if (c >= 'a' && c <= 'z') {
2188 return c - ('a' - 'A');
2189 }
2190 return c;
2191}
2192
2193// cStr::MakeLower
2194inline void cStr::MakeLower(int start) {
2195 cAssert(IsValid());
2196 if (m_Str == nullptr)return;
2197 int i;
2198 for (i = start; i < m_Length; i++) {
2199 m_Str[i] = ToLower(m_Str[i]);
2200 }
2201}
2202
2203// cStr::MakeUpper
2204inline void cStr::MakeUpper(int start) {
2205 cAssert(IsValid());
2206 if (m_Str == nullptr)return;
2207 int i;
2208 for (i = start; i < m_Length; i++) {
2209 m_Str[i] = ToUpper(m_Str[i]);
2210 }
2211}
2212
2213// cStr::ToLower : const cStr () const
2214inline const cStr cStr::ToLower() const {
2215 cStr S = *this;
2216 S.MakeLower();
2217 return S;
2218}
2219
2220// cStr::ToUpper : const cStr () const
2221inline const cStr cStr::ToUpper() const {
2222 cStr S = *this;
2223 S.MakeUpper();
2224 return S;
2225}
2226
2227//-----------------------------------------------------------------------------
2228// cStr::Join
2229//-----------------------------------------------------------------------------
2230
2231// cStr::Join : (const char *, const cList<cStr> &)
2232inline const cStr cStr::Join(const char* Separator, const cList<cStr>& Strings) {
2233 return Join(Separator, Strings, 0, Strings.Count());
2234}
2235
2236//-----------------------------------------------------------------------------
2237// cStr::Split
2238//-----------------------------------------------------------------------------
2239
2240// cStr::Split
2241inline void cStr::Split(cList<cStr>* List, const char* Delimiters) const {
2242 cAssert(IsValid());
2243 cStr::Split(m_Str, List, Delimiters);
2244}
2245
2246//-----------------------------------------------------------------------------
2247// cStr::CharIs...
2248//-----------------------------------------------------------------------------
2249
2250// cStr::CharIsLower
2251inline bool cStr::CharIsLower(const int c) {
2252 return c >= 'a' && c <= 'z';
2253}
2254
2255// cStr::CharIsUpper
2256inline bool cStr::CharIsUpper(const int c) {
2257 return c >= 'A' && c <= 'Z';
2258}
2259
2260// cStr::CharIsAlpha
2261inline bool cStr::CharIsAlpha(const int c) {
2262 return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
2263}
2264
2265// cStr::CharIsNumeric
2266inline bool cStr::CharIsNumeric(const int c) {
2267 return c >= '0' && c <= '9';
2268}
2269
2270// cStr::CharIsHexadecimal
2271inline bool cStr::CharIsHexadecimal(const int c) {
2272 return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
2273}
2274
2275// cStr::CharIsNewLine
2276inline bool cStr::CharIsNewLine(const int c) {
2277 return c == '\n' || c == '\r' || c == '\v';
2278}
2279
2280// cStr::CharIsTab
2281inline bool cStr::CharIsTab(const int c) {
2282 return c == '\t';
2283}
2284
2285// cStr::CharIsWhitespace
2286inline bool cStr::CharIsWhitespace(const int c) {
2287 return ' ' == c || '\t' == c;
2288}
2289
2290// cStr::CharIsDecimalPoint
2291inline bool cStr::CharIsDecimalPoint(const int c) {
2292 return '.' == c || ',' == c;
2293}
2294
2295// cStr::CharIsSign
2296inline bool cStr::CharIsSign(const int c) {
2297 return '+' == c || '-' == c;
2298}
2299
2300// cStr::CharIsExponent
2301inline bool cStr::CharIsExponent(const int c) {
2302 return 'd' == c || 'D' == c || 'e' == c || 'E' == c;
2303}
2304
2305//-----------------------------------------------------------------------------
2306// cStr::GetHashCode
2307//-----------------------------------------------------------------------------
2308inline int cStr::GetHashCode(const char* Str, const bool NoCase) {
2309 cAssert(Str != nullptr);
2310
2311 int H = 0, i;
2312
2313 for (i = 0; *Str != '\0'; i++) {
2314 H += (NoCase ? ToLower(*Str++) : (*Str++)) * (i + 119);
2315 }
2316 return H;
2317} // cStr::GetHashCode
The array template, refer it as coat::list <...> if you are using the Core API.
Definition cList.h:133
Definition cStr.h:6
static const cStr ToSize(const qword, const bool Pow2=false)
"cStr::ToSize" converts "qword" into short rounded size using Greek prefix
Definition cStr.h:604