Tiberian Technologies Scripts Reference Revision: 9000
Loading...
Searching...
No Matches
engine_string.h
1/* Renegade Scripts.dll
2 Copyright 2013 Tiberian Technologies
3
4 This file is part of the Renegade scripts.dll
5 The Renegade scripts.dll is free software; you can redistribute it and/or modify it under
6 the terms of the GNU General Public License as published by the Free
7 Software Foundation; either version 2, or (at your option) any later
8 version. See the file COPYING for more details.
9 In addition, an exemption is given to allow Run Time Dynamic Linking of this code with any closed source module that does not contain code covered by this licence.
10 Only the source code to the module(s) containing the licenced code has to be released.
11*/
12#ifndef SCRIPTS_INCLUDE__ENGINE_STRING_H
13#define SCRIPTS_INCLUDE__ENGINE_STRING_H
14
15
16
17#include "engine_common.h"
18#include "HashTemplateKeyClass.h"
19
20
21
22
23class StringClass {
24public:
25 StringClass(bool hint_temporary);
26 StringClass(int initial_len = 0, bool hint_temporary = false);
27 StringClass(const StringClass& string,bool hint_temporary = false);
28 StringClass(const char *string,bool hint_temporary = false);
29 StringClass(char ch, bool hint_temporary = false);
30 StringClass(const wchar_t *string, bool hint_temporary = false);
31 ~StringClass();
32 bool operator ==(const char* rvalue) const;
33 bool operator!= (const char* rvalue) const;
34 const StringClass& operator=(const char* string);
35 const StringClass& operator=(const StringClass& string);
36 const StringClass& operator=(char ch);
37 const StringClass& operator=(const wchar_t *string);
38
39 const StringClass& operator+=(const char* string);
40 const StringClass& operator+=(const StringClass& string);
41 const StringClass& operator+=(char ch);
42
43 friend StringClass operator+ (const StringClass &string1, const StringClass &string2);
44 friend StringClass operator+ (const StringClass &string1, const char *string2);
45 friend StringClass operator+ (const char *string1, const StringClass &string2);
46
47 bool operator < (const char *string) const;
48 bool operator <= (const char *string) const;
49 bool operator > (const char *string) const;
50 bool operator >= (const char *string) const;
51
52 const char & operator[] (int index) const;
53 char & operator[] (int index);
54 operator const char * (void) const;
55
56 int Compare (const char *string) const;
57 int Compare_No_Case (const char *string) const;
58
59 int Get_Length (void) const;
60 bool Is_Empty (void) const;
61 void Erase (int start_index, int char_count);
62 SHARED_API int __cdecl Format(const char* format,...);
63 SHARED_API int __cdecl Format_Args(const char* format,const va_list& arg_list);
64 char *Get_Buffer (int new_length);
65 char *Peek_Buffer (void);
66 const char * Peek_Buffer (void) const;
67 SHARED_API bool Copy_Wide (const wchar_t *source);
68 SHARED_API static void Release_Resources();
69
86 SHARED_API int Replace(const char* search, const char* replace, bool bCaseSensitive = true, int maxCount=-1);
87
88 void TruncateLeft(uint truncateLength)
89 {
90 uint length = Get_Length();
91 if (length <= truncateLength)
92 Free_String();
93
94 else
95 {
96 int newLength = length - truncateLength;
97 memmove(m_Buffer, m_Buffer + truncateLength, newLength + 1);
98 Store_Length(newLength);
99 }
100 }
101
102 void TruncateRight(uint truncateLength)
103 {
104 uint length = Get_Length();
105 if (length <= truncateLength)
106 Free_String();
107
108 else
109 {
110 int newLength = length - truncateLength;
111 m_Buffer[newLength] = '\0';
112 Store_Length(newLength);
113 }
114 }
115
116 void cropTo(int to)
117 {
118 const int length = Get_Length();
119 if (to <= 0)
120 Free_String();
121 else if (to < length)
122 {
123 m_Buffer[to] = '\0';
124 Store_Length(to);
125 }
126 }
127
128 void cropFrom(int from)
129 {
130 const int length = Get_Length();
131 if (from >= length)
132 Free_String();
133 else if (from > 0)
134 {
135 memmove(m_Buffer, m_Buffer + from, length - from + 1);
136 Store_Length(length - from);
137 }
138 }
139
140 void crop(int from, int to)
141 {
142 cropTo(to);
143 cropFrom(from);
144 }
145
146 void TrimLeft()
147 {
148 char* iter = m_Buffer;
149 for (; *iter != '\0' && *iter <= ' '; iter++);
150
151 TruncateLeft((int)(iter - m_Buffer));
152 }
153
154 void TrimRight()
155 {
156 char* iter = m_Buffer + Get_Length() - 1;
157 for (; *iter != '\0' && *iter <= ' '; iter--);
158
159 TruncateRight((int)(m_Buffer + Get_Length() - 1 - iter));
160 }
161
162 void Trim()
163 {
164 TrimLeft();
165 TrimRight();
166 }
167
168 bool StartsWithI(const char* string)
169 {
170 return _strnicmp(m_Buffer, string, strlen(string)) == 0;
171 }
172
173 uint GetHash() const
174 {
175 int length = Get_Length();
176 if (length >= 8)
177 return HashTemplateKeyClass<uint>::Get_Hash_Value((uint&)m_Buffer[length - 8]);
178 else
179 {
180 uint hash = 0;
181 for (int i = 0; i < length; i++)
182 hash += m_Buffer[i] + hash * 37;
183 return hash;
184 }
185 }
186
187 int IndexOf(char c)
188 {
189 int length = Get_Length();
190 for (int i = 0; i < length; ++i)
191 {
192 if (m_Buffer[i] == c) return i;
193 }
194 return -1;
195 }
196
197 int LastIndexOf(char c)
198 {
199 for (int i = Get_Length() - 1; i >= 0; --i)
200 {
201 if (m_Buffer[i] == c) return i;
202 }
203 return -1;
204 }
205
206 void ToUpper()
207 {
208 _strupr(m_Buffer);
209 }
210
211 void ToLower()
212 {
213 _strlwr(m_Buffer);
214 }
215
216 StringClass AsUpper() const
217 {
218 StringClass result = *this;
219 result.ToUpper();
220 return result;
221 }
222
223 StringClass AsLower() const
224 {
225 StringClass result = *this;
226 result.ToLower();
227 return result;
228 }
229
230 static StringClass getFormattedString(const char* format, ...)
231 {
232 va_list arguments;
233 StringClass result;
234
235 va_start(arguments, format);
236 result.Format_Args(format, arguments);
237 va_end(arguments);
238
239 return result;
240 }
241
242private:
243 typedef struct _HEADER
244 {
245 int allocated_length;
246 int length;
247 } HEADER;
248 enum
249 {
250 MAX_TEMP_STRING = 8,
251 MAX_TEMP_LEN = 256-sizeof(_HEADER),
252 MAX_TEMP_BYTES = (MAX_TEMP_LEN * sizeof (char)) + sizeof (HEADER),
253 };
254 SHARED_API void Get_String(int length,bool is_temp);
255 char* Allocate_Buffer(int len);
256 SHARED_API void Resize(int new_len);
257 SHARED_API void Uninitialised_Grow(int new_len);
258 SHARED_API void Free_String();
259 void Store_Length(int length);
260 void Store_Allocated_Length(int length);
261 HEADER *Get_Header() const;
262 int Get_Allocated_Length() const;
263 void Set_Buffer_And_Allocated_Length(char *buffer, int length);
264 char* m_Buffer;
265#if (SHARED_EXPORTS) || (EXTERNAL)
266 static char __declspec(thread) TempStrings[MAX_TEMP_STRING][MAX_TEMP_BYTES];
267 static unsigned int __declspec(thread) FreeTempStrings;
268#endif
269#ifdef EXTERNAL
270 static char *m_EmptyString;
271 static char m_NullChar;
272#else
273 SHARED_API static REF_DECL(char *, m_EmptyString);
274 SHARED_API static REF_DECL(char, m_NullChar);
275#endif
276};
277
278inline const StringClass &StringClass::operator= (const StringClass &string)
279{
280 int len = string.Get_Length();
281 Uninitialised_Grow(len+1);
282 Store_Length(len);
283 memcpy (m_Buffer, string.m_Buffer, (len+1) * sizeof (char));
284 return (*this);
285}
286
287inline const StringClass &StringClass::operator= (const char *string)
288{
289 if (string != 0)
290 {
291 int len = (int)strlen (string);
292 Uninitialised_Grow (len+1);
293 Store_Length (len);
294 memcpy (m_Buffer, string, (len + 1) * sizeof (char));
295 }
296 return (*this);
297}
298
299inline const StringClass &StringClass::operator= (const wchar_t *string)
300{
301 if (string != 0)
302 {
303 Copy_Wide (string);
304 }
305 return (*this);
306}
307
308inline const StringClass &StringClass::operator= (char ch)
309{
310 Uninitialised_Grow (2);
311 m_Buffer[0] = ch;
312 m_Buffer[1] = m_NullChar;
313 Store_Length (1);
314 return (*this);
315}
316
317inline StringClass::StringClass (bool hint_temporary) : m_Buffer (m_EmptyString)
318{
319 Get_String (MAX_TEMP_LEN, hint_temporary);
320 m_Buffer[0] = m_NullChar;
321 return ;
322}
323
324inline StringClass::StringClass (int initial_len, bool hint_temporary) : m_Buffer (m_EmptyString)
325{
326 Get_String (initial_len, hint_temporary);
327 m_Buffer[0] = m_NullChar;
328}
329
330inline StringClass::StringClass (char ch, bool hint_temporary) : m_Buffer (m_EmptyString)
331{
332 Get_String (2, hint_temporary);
333 (*this) = ch;
334}
335
336inline StringClass::StringClass (const StringClass &string, bool hint_temporary) : m_Buffer (m_EmptyString)
337{
338 if (hint_temporary || (string.Get_Length()>0))
339 {
340 Get_String (string.Get_Length()+1, hint_temporary);
341 }
342 (*this) = string;
343}
344
345inline StringClass::StringClass (const char *string, bool hint_temporary) : m_Buffer (m_EmptyString)
346{
347 int len=string ? (int)strlen(string) : 0;
348 if (hint_temporary || len>0)
349 {
350 Get_String (len+1, hint_temporary);
351 }
352 (*this) = string;
353}
354
355inline StringClass::StringClass (const wchar_t *string, bool hint_temporary) : m_Buffer (m_EmptyString)
356{
357 int len = string ? (int)wcslen (string) : 0;
358 if (hint_temporary || len > 0)
359 {
360 Get_String (len + 1, hint_temporary);
361 }
362 (*this) = string;
363}
364
365inline StringClass::~StringClass (void)
366{
367 Free_String ();
368}
369
370inline bool StringClass::Is_Empty (void) const
371{
372 return (m_Buffer[0] == m_NullChar);
373}
374
375inline int StringClass::Compare (const char *string) const
376{
377 return strcmp (m_Buffer, string);
378}
379
380inline int StringClass::Compare_No_Case (const char *string) const
381{
382 return _stricmp (m_Buffer, string);
383}
384
385inline const char &StringClass::operator[] (int index) const
386{
387 return m_Buffer[index];
388}
389
390inline char &StringClass::operator[] (int index)
391{
392 return m_Buffer[index];
393}
394
395inline StringClass::operator const char * (void) const
396{
397 return m_Buffer;
398}
399
400inline bool StringClass::operator== (const char *rvalue) const
401{
402 return (Compare (rvalue) == 0);
403}
404
405inline bool StringClass::operator!= (const char *rvalue) const
406{
407 return (Compare (rvalue) != 0);
408}
409
410inline bool StringClass::operator < (const char *string) const
411{
412 return (strcmp (m_Buffer, string) < 0);
413}
414
415inline bool StringClass::operator <= (const char *string) const
416{
417 return (strcmp (m_Buffer, string) <= 0);
418}
419
420inline bool StringClass::operator > (const char *string) const
421{
422 return (strcmp (m_Buffer, string) > 0);
423}
424
425inline bool StringClass::operator >= (const char *string) const
426{
427 return (strcmp (m_Buffer, string) >= 0);
428}
429
430inline void StringClass::Erase (int start_index, int char_count)
431{
432 int len = Get_Length ();
433 if (start_index < len)
434 {
435 if (start_index + char_count > len)
436 {
437 char_count = len - start_index;
438 }
439 memmove ( &m_Buffer[start_index], &m_Buffer[start_index + char_count], (len - (start_index + char_count) + 1) * sizeof (char));
440 Store_Length( len - char_count );
441 }
442}
443
444inline const StringClass &StringClass::operator+= (const char *string)
445{
446 int cur_len = Get_Length ();
447 int src_len = (int)strlen (string);
448 int new_len = cur_len + src_len;
449 Resize (new_len + 1);
450 Store_Length (new_len);
451 memcpy (&m_Buffer[cur_len], string, (src_len + 1) * sizeof (char));
452 return (*this);
453}
454
455inline const StringClass &StringClass::operator+= (char ch)
456{
457 int cur_len = Get_Length ();
458 Resize (cur_len + 2);
459 m_Buffer[cur_len] = ch;
460 m_Buffer[cur_len + 1] = m_NullChar;
461 if (ch != m_NullChar)
462 {
463 Store_Length (cur_len + 1);
464 }
465 return (*this);
466}
467
468inline char *StringClass::Get_Buffer (int new_length)
469{
470 Uninitialised_Grow (new_length);
471 return m_Buffer;
472}
473
474inline char *StringClass::Peek_Buffer (void)
475{
476 return m_Buffer;
477}
478
479inline const char *StringClass::Peek_Buffer (void) const
480{
481 return m_Buffer;
482}
483
484inline const StringClass &StringClass::operator+= (const StringClass &string)
485{
486 int src_len = string.Get_Length();
487 if (src_len > 0)
488 {
489 int cur_len = Get_Length ();
490 int new_len = cur_len + src_len;
491 Resize (new_len + 1);
492 Store_Length (new_len);
493 memcpy (&m_Buffer[cur_len], (const char *)string, (src_len + 1) * sizeof (char));
494 }
495 return (*this);
496}
497
498inline StringClass operator+ (const StringClass &string1, const StringClass &string2)
499{
500 StringClass new_string(string1, true);
501 new_string += string2;
502 return new_string;
503}
504
505inline StringClass operator+ (const char *string1, const StringClass &string2)
506{
507 StringClass new_string(string1, true);
508 new_string += string2;
509 return new_string;
510}
511
512inline StringClass operator+ (const StringClass &string1, const char *string2)
513{
514 StringClass new_string(string1, true);
515 StringClass new_string2(string2, true);
516 new_string += new_string2;
517 return new_string;
518}
519
520inline int StringClass::Get_Allocated_Length (void) const
521{
522 int allocated_length = 0;
523 if (m_Buffer != m_EmptyString)
524 {
525 HEADER *header = Get_Header ();
526 allocated_length = header->allocated_length;
527 }
528 return allocated_length;
529}
530
531inline int StringClass::Get_Length (void) const
532{
533 int length = 0;
534 if (m_Buffer != m_EmptyString)
535 {
536 HEADER *header = Get_Header ();
537 length = header->length;
538 if (length == 0)
539 {
540 length = (int)strlen (m_Buffer);
541 ((StringClass *)this)->Store_Length (length);
542 }
543 }
544 return length;
545}
546
547inline void StringClass::Set_Buffer_And_Allocated_Length (char *buffer, int length)
548{
549 Free_String ();
550 m_Buffer = buffer;
551 if (m_Buffer != m_EmptyString)
552 {
553 Store_Allocated_Length (length);
554 Store_Length (0);
555 }
556}
557
558inline char *StringClass::Allocate_Buffer (int length)
559{
560 char *buffer = new char[(sizeof (char) * length) + sizeof (StringClass::_HEADER)];
561 HEADER *header = reinterpret_cast<HEADER *>(buffer);
562 header->length = 0;
563 header->allocated_length = length;
564 return reinterpret_cast<char *>(buffer + sizeof (StringClass::_HEADER));
565}
566
567inline StringClass::HEADER *StringClass::Get_Header (void) const
568{
569 return reinterpret_cast<HEADER *>(((char *)m_Buffer) - sizeof (StringClass::_HEADER));
570}
571
572inline void StringClass::Store_Allocated_Length (int allocated_length)
573{
574 if (m_Buffer != m_EmptyString)
575 {
576 HEADER *header = Get_Header ();
577 header->allocated_length = allocated_length;
578 }
579}
580
581inline void StringClass::Store_Length (int length)
582{
583 if (m_Buffer != m_EmptyString)
584 {
585 HEADER *header = Get_Header();
586 header->length = length;
587 }
588}
589
590class WideStringClass {
591public:
592 WideStringClass (int initial_len = 0, bool hint_temporary = false);
593 WideStringClass (const WideStringClass &string, bool hint_temporary = false);
594 WideStringClass (const wchar_t *string, bool hint_temporary = false);
595 WideStringClass (wchar_t ch, bool hint_temporary = false);
596 WideStringClass (const char *string, bool hint_temporary = false);
597 ~WideStringClass (void);
598 bool operator== (const wchar_t *rvalue) const;
599 bool operator!= (const wchar_t *rvalue) const;
600 const WideStringClass &operator= (const WideStringClass &string);
601 const WideStringClass &operator= (const wchar_t *string);
602 const WideStringClass &operator= (wchar_t ch);
603 const WideStringClass &operator= (const char *string);
604
605 const WideStringClass &operator+= (const WideStringClass &string);
606 const WideStringClass &operator+= (const wchar_t *string);
607 const WideStringClass &operator+= (wchar_t ch);
608
609 friend WideStringClass operator+ (const WideStringClass &string1, const WideStringClass &string2);
610 friend WideStringClass operator+ (const wchar_t *string1, const WideStringClass &string2);
611 friend WideStringClass operator+ (const WideStringClass &string1, const wchar_t *string2);
612
613 bool operator < (const wchar_t *string) const;
614 bool operator <= (const wchar_t *string) const;
615 bool operator > (const wchar_t *string) const;
616 bool operator >= (const wchar_t *string) const;
617
618 wchar_t operator[] (int index) const;
619 wchar_t& operator[] (int index);
620 operator const wchar_t * (void) const;
621
622 int Compare (const wchar_t *string) const;
623 int Compare_No_Case (const wchar_t *string) const;
624 int Get_Length (void) const;
625 bool Is_Empty (void) const;
626 void Erase (int start_index, int char_count);
627 SHARED_API int _cdecl Format (const wchar_t *format, ...);
628 SHARED_API int _cdecl Format_Args (const wchar_t *format, const va_list & arg_list );
629 SHARED_API bool Convert_From (const char *text);
630 bool Convert_To (StringClass &string);
631 bool Convert_To (StringClass &string) const;
632 SHARED_API bool Is_ANSI(void);
633 wchar_t * Get_Buffer (int new_length);
634 wchar_t * Peek_Buffer (void);
635 const wchar_t* Peek_Buffer() const;
636 SHARED_API static void Release_Resources (void);
637
638 void TruncateLeft(uint truncateLength)
639 {
640 uint length = Get_Length();
641 if (length <= truncateLength)
642 Free_String();
643
644 else
645 {
646 int newLength = length - truncateLength;
647 memmove(m_Buffer, m_Buffer + truncateLength, (newLength + 1)*2);
648 Store_Length(newLength);
649 }
650 }
651 void TruncateRight(uint truncateLength)
652 {
653 uint length = Get_Length();
654 if (length <= truncateLength)
655 Free_String();
656 else
657 {
658 int newLength = length - truncateLength;
659 m_Buffer[newLength] = L'\0';
660 Store_Length(newLength);
661 }
662 }
663
664 void TrimLeft()
665 {
666 wchar_t* iter = m_Buffer;
667 for (; *iter != L'\0' && *iter <= L' '; iter++);
668 TruncateLeft((int)(iter - m_Buffer));
669 }
670
671 void TrimRight()
672 {
673 wchar_t* iter = m_Buffer + Get_Length() - 1;
674 for (; *iter != L'\0' && *iter <= L' '; iter--);
675 TruncateRight((int)(m_Buffer + Get_Length() - 1 - iter));
676 }
677
678 void Trim()
679 {
680 TrimLeft();
681 TrimRight();
682 }
683
684 static WideStringClass getFormattedString(const wchar_t* format, ...)
685 {
686 va_list arguments;
687 WideStringClass result;
688
689 va_start(arguments, format);
690 result.Format_Args(format, arguments);
691 va_end(arguments);
692
693 return result;
694 }
695
696 SHARED_API WideStringClass Substring(int start, int length) const;
697 SHARED_API void RemoveSubstring(int start, int length);
698 SHARED_API void ReplaceSubstring(int start, int length, const WideStringClass& substring);
699
700private:
701 typedef struct _HEADER
702 {
703 int allocated_length;
704 int length;
705 } HEADER;
706 enum
707 {
708 MAX_TEMP_STRING = 4,
709 MAX_TEMP_LEN = 256,
710 MAX_TEMP_BYTES = (MAX_TEMP_LEN * sizeof (wchar_t)) + sizeof (HEADER),
711 };
712 SHARED_API void Get_String(int length,bool is_temp);
713 wchar_t * Allocate_Buffer (int length);
714 SHARED_API void Resize (int size);
715 SHARED_API void Uninitialised_Grow (int length);
716 SHARED_API void Free_String();
717 void Store_Length(int length);
718 void Store_Allocated_Length(int length);
719 HEADER *Get_Header() const;
720 int Get_Allocated_Length() const;
721 void Set_Buffer_And_Allocated_Length(wchar_t *buffer, int length);
722 wchar_t* m_Buffer;
723#if (SHARED_EXPORTS || EXTERNAL)
724 static char __declspec(thread) TempStrings[MAX_TEMP_STRING][MAX_TEMP_BYTES];
725 static unsigned int __declspec(thread) FreeTempStrings;
726#endif
727#ifdef EXTERNAL
728 static wchar_t *m_EmptyString;
729 static wchar_t m_NullChar;
730#else
731 SHARED_API static REF_DECL(wchar_t *, m_EmptyString);
732 SHARED_API static REF_DECL(wchar_t, m_NullChar);
733#endif
734};
735
736inline WideStringClass::WideStringClass (int initial_len, bool hint_temporary) : m_Buffer (m_EmptyString)
737{
738 Get_String (initial_len, hint_temporary);
739 m_Buffer[0] = m_NullChar;
740}
741
742inline WideStringClass::WideStringClass (wchar_t ch, bool hint_temporary) : m_Buffer (m_EmptyString)
743{
744 Get_String (2, hint_temporary);
745 (*this) = ch;
746}
747
748inline WideStringClass::WideStringClass (const WideStringClass &string, bool hint_temporary) : m_Buffer (m_EmptyString)
749{
750 if (hint_temporary || (string.Get_Length()>1))
751 {
752 Get_String(string.Get_Length()+1, hint_temporary);
753 }
754 (*this) = string;
755}
756
757inline WideStringClass::WideStringClass (const wchar_t *string, bool hint_temporary) : m_Buffer (m_EmptyString)
758{
759 int len=string ? (int)wcslen(string) : 0;
760 if (hint_temporary || len>0)
761 {
762 Get_String (len+1, hint_temporary);
763 }
764 (*this) = string;
765}
766
767
768inline WideStringClass::WideStringClass (const char *string, bool hint_temporary) : m_Buffer (m_EmptyString)
769{
770 if (hint_temporary || (string && strlen(string)>0))
771 {
772 Get_String ((int)strlen(string) + 1, hint_temporary);
773 }
774 (*this) = string;
775}
776
777inline WideStringClass::~WideStringClass (void)
778{
779 Free_String ();
780}
781
782inline bool WideStringClass::Is_Empty (void) const
783{
784 return (m_Buffer[0] == m_NullChar);
785}
786
787inline int WideStringClass::Compare (const wchar_t *string) const
788{
789 if (string)
790 {
791 return wcscmp (m_Buffer, string);
792 }
793 return -1;
794}
795
796inline int WideStringClass::Compare_No_Case (const wchar_t *string) const
797{
798 if (string)
799 {
800 return _wcsicmp (m_Buffer, string);
801 }
802 return -1;
803}
804
805inline wchar_t WideStringClass::operator[] (int index) const
806{
807 return m_Buffer[index];
808}
809
810inline wchar_t& WideStringClass::operator[] (int index)
811{
812 return m_Buffer[index];
813}
814
815inline WideStringClass::operator const wchar_t * (void) const
816{
817 return m_Buffer;
818}
819
820inline bool WideStringClass::operator== (const wchar_t *rvalue) const
821{
822 return (Compare (rvalue) == 0);
823}
824
825inline bool WideStringClass::operator!= (const wchar_t *rvalue) const
826{
827 return (Compare (rvalue) != 0);
828}
829
830inline const WideStringClass & WideStringClass::operator= (const WideStringClass &string)
831{
832 return operator= ((const wchar_t *)string);
833}
834
835inline bool WideStringClass::operator < (const wchar_t *string) const
836{
837 if (string)
838 {
839 return (wcscmp (m_Buffer, string) < 0);
840 }
841 return false;
842}
843
844inline bool WideStringClass::operator <= (const wchar_t *string) const
845{
846 if (string)
847 {
848 return (wcscmp (m_Buffer, string) <= 0);
849 }
850 return false;
851}
852
853inline bool WideStringClass::operator > (const wchar_t *string) const
854{
855 if (string)
856 {
857 return (wcscmp (m_Buffer, string) > 0);
858 }
859 return true;
860}
861
862inline bool WideStringClass::operator >= (const wchar_t *string) const
863{
864 if (string)
865 {
866 return (wcscmp (m_Buffer, string) >= 0);
867 }
868 return true;
869}
870
871inline void WideStringClass::Erase (int start_index, int char_count)
872{
873 int len = Get_Length ();
874 if (start_index < len)
875 {
876 if (start_index + char_count > len)
877 {
878 char_count = len - start_index;
879 }
880 memmove (&m_Buffer[start_index],&m_Buffer[start_index + char_count],(len - (start_index + char_count) + 1) * sizeof (wchar_t));
881 Store_Length( (int)wcslen(m_Buffer) );
882 }
883}
884
885inline const WideStringClass & WideStringClass::operator= (const wchar_t *string)
886{
887 if (string)
888 {
889 int len = (int)wcslen (string);
890 Uninitialised_Grow (len + 1);
891 Store_Length (len);
892 memcpy (m_Buffer, string, (len + 1) * sizeof (wchar_t));
893 }
894 return (*this);
895}
896
897inline const WideStringClass &WideStringClass::operator= (const char *string)
898{
899 Convert_From(string);
900 return (*this);
901}
902
903inline const WideStringClass &WideStringClass::operator= (wchar_t ch)
904{
905 Uninitialised_Grow (2);
906 m_Buffer[0] = ch;
907 m_Buffer[1] = m_NullChar;
908 Store_Length (1);
909 return (*this);
910}
911
912inline const WideStringClass &WideStringClass::operator+= (const wchar_t *string)
913{
914 if (string)
915 {
916 int cur_len = Get_Length ();
917 int src_len = (int)wcslen (string);
918 int new_len = cur_len + src_len;
919 Resize (new_len + 1);
920 Store_Length (new_len);
921 memcpy (&m_Buffer[cur_len], string, (src_len + 1) * sizeof (wchar_t));
922 }
923 return (*this);
924}
925
926inline const WideStringClass &WideStringClass::operator+= (wchar_t ch)
927{
928 int cur_len = Get_Length ();
929 Resize (cur_len + 2);
930 m_Buffer[cur_len] = ch;
931 m_Buffer[cur_len + 1] = m_NullChar;
932 if (ch != m_NullChar)
933 {
934 Store_Length (cur_len + 1);
935 }
936 return (*this);
937}
938
939inline wchar_t *WideStringClass::Get_Buffer (int new_length)
940{
941 Uninitialised_Grow (new_length);
942 return m_Buffer;
943}
944
945inline wchar_t *WideStringClass::Peek_Buffer (void)
946{
947 return m_Buffer;
948}
949
950inline const wchar_t* WideStringClass::Peek_Buffer() const
951{
952 return m_Buffer;
953}
954
955inline const WideStringClass &WideStringClass::operator+= (const WideStringClass &string)
956{
957 int src_len = string.Get_Length();
958 if (src_len > 0)
959 {
960 int cur_len = Get_Length ();
961 int new_len = cur_len + src_len;
962 Resize (new_len + 1);
963 Store_Length (new_len);
964 memcpy (&m_Buffer[cur_len], (const wchar_t *)string, (src_len + 1) * sizeof (wchar_t));
965 }
966 return (*this);
967}
968
969inline WideStringClass operator+ (const WideStringClass &string1, const WideStringClass &string2)
970{
971 WideStringClass new_string(string1, true);
972 new_string += string2;
973 return new_string;
974}
975
976inline WideStringClass operator+ (const wchar_t *string1, const WideStringClass &string2)
977{
978 WideStringClass new_string(string1, true);
979 new_string += string2;
980 return new_string;
981}
982
983inline WideStringClass operator+ (const WideStringClass &string1, const wchar_t *string2)
984{
985 WideStringClass new_string(string1, true);
986 new_string += string2;
987 return new_string;
988}
989
990inline int WideStringClass::Get_Allocated_Length (void) const
991{
992 int allocated_length = 0;
993 if (m_Buffer != m_EmptyString)
994 {
995 HEADER *header = Get_Header ();
996 allocated_length = header->allocated_length;
997 }
998 return allocated_length;
999}
1000
1001inline int WideStringClass::Get_Length (void) const
1002{
1003 int length = 0;
1004 if (m_Buffer != m_EmptyString)
1005 {
1006 HEADER *header = Get_Header ();
1007 length = header->length;
1008 if (length == 0)
1009 {
1010 length = (int)wcslen (m_Buffer);
1011 ((WideStringClass *)this)->Store_Length (length);
1012 }
1013 }
1014 return length;
1015}
1016
1017inline void WideStringClass::Set_Buffer_And_Allocated_Length (wchar_t *buffer, int length)
1018{
1019 Free_String ();
1020 m_Buffer = buffer;
1021 if (m_Buffer != m_EmptyString)
1022 {
1023 Store_Allocated_Length (length);
1024 Store_Length (0);
1025 }
1026}
1027
1028inline wchar_t * WideStringClass::Allocate_Buffer (int length)
1029{
1030 char *buffer = new char[(sizeof (wchar_t) * length) + sizeof (WideStringClass::_HEADER)];
1031 HEADER *header = reinterpret_cast<HEADER *>(buffer);
1032 header->length = 0;
1033 header->allocated_length = length;
1034 return reinterpret_cast<wchar_t *>(buffer + sizeof (WideStringClass::_HEADER));
1035}
1036
1037inline WideStringClass::HEADER * WideStringClass::Get_Header (void) const
1038{
1039 return reinterpret_cast<HEADER *>(((char *)m_Buffer) - sizeof (WideStringClass::_HEADER));
1040}
1041
1042inline void WideStringClass::Store_Allocated_Length (int allocated_length)
1043{
1044 if (m_Buffer != m_EmptyString)
1045 {
1046 HEADER *header = Get_Header ();
1047 header->allocated_length = allocated_length;
1048 }
1049}
1050
1051inline void WideStringClass::Store_Length (int length)
1052{
1053 if (m_Buffer != m_EmptyString)
1054 {
1055 HEADER *header = Get_Header ();
1056 header->length = length;
1057 }
1058}
1059
1060inline bool WideStringClass::Convert_To (StringClass &string)
1061{
1062 return (string.Copy_Wide (m_Buffer));
1063}
1064
1065inline bool WideStringClass::Convert_To (StringClass &string) const
1066{
1067 return (string.Copy_Wide (m_Buffer));
1068}
1069
1070struct hash_istring: public std::unary_function<const char*, size_t>
1071{
1072 size_t operator()(const char* str) const
1073 {
1074 // djb2
1075 unsigned long hash = 5381;
1076 while (int c = tolower(*str++)) hash = hash * 33 + c;
1077 return hash;
1078 }
1079
1080 size_t operator()(const StringClass& str) const
1081 {
1082 return (*this)(str.Peek_Buffer());
1083 }
1084};
1085
1086struct equals_istring: public std::binary_function<const char*, const char*, bool>
1087{
1088 bool operator()(const char* a, const char* b) const
1089 {
1090 return _stricmp(a, b) == 0;
1091 }
1092
1093 size_t operator()(const StringClass& a, const StringClass& b) const
1094 {
1095 return _stricmp(a.Peek_Buffer(), b.Peek_Buffer()) == 0;
1096 }
1097
1098 size_t operator()(const StringClass& a, const char* b) const
1099 {
1100 return _stricmp(a.Peek_Buffer(), b) == 0;
1101 }
1102
1103 size_t operator()(const char* a, const StringClass& b) const
1104 {
1105 return _stricmp(a, b.Peek_Buffer()) == 0;
1106 }
1107};
1108
1109struct hash_string
1110{
1111 size_t operator()(const char* str) const
1112 {
1113 // djb2
1114 unsigned long hash = 5381;
1115 while (int c = *str++) hash = hash * 33 + c;
1116 return hash;
1117 }
1118
1119 size_t operator()(const StringClass& str) const
1120 {
1121 return (*this)(str.Peek_Buffer());
1122 }
1123};
1124
1125struct equals_string
1126{
1127 bool operator()(const char* a, const char* b) const
1128 {
1129 return strcmp(a, b) == 0;
1130 }
1131
1132 size_t operator()(const StringClass& a, const StringClass& b) const
1133 {
1134 return strcmp(a.Peek_Buffer(), b.Peek_Buffer()) == 0;
1135 }
1136
1137 size_t operator()(const StringClass& a, const char* b) const
1138 {
1139 return strcmp(a.Peek_Buffer(), b) == 0;
1140 }
1141
1142 size_t operator()(const char* a, const StringClass& b) const
1143 {
1144 return strcmp(a, b.Peek_Buffer()) == 0;
1145 }
1146};
1147
1148SCRIPTS_API const wchar_t *CharToWideChar(const char *str); //convert a char to a wide char
1149SCRIPTS_API const char *WideCharToChar(const wchar_t *wcs); //convert a wide char to a char
1150SCRIPTS_API char *newstr(const char *str); //duplicate a character string
1151SCRIPTS_API wchar_t *newwcs(const wchar_t *str); //duplicate a wide character string
1152SCRIPTS_API char *strtrim(char *); //trim a string
1153SCRIPTS_API char* strrtrim(char *); //trim trailing whitespace from a string
1154SCRIPTS_API const char *stristr(const char *str, const char *substr); //like strstr but case insenstive
1155SCRIPTS_API const wchar_t *wcsistr(const wchar_t *str, const wchar_t *substr); //like strstr but case insenstive and for wchar_t
1156#endif