str.h

Engine/source/core/util/str.h

More...

Classes:

class

The String class represents a 0-terminated array of characters.

class

An internal support class for ToString().

Public Typedefs

StringChar 

Detailed Description

Public Typedefs

typedef UTF8 StringChar 

Public Functions

operator+(const String & a, const String & b)

operator+(const String & a, const StringChar * b)

operator+(const String & a, StringChar c)

operator+(const StringChar * a, const String & b)

operator+(StringChar c, const String & a)

  1
  2//-----------------------------------------------------------------------------
  3// Copyright (c) 2012 GarageGames, LLC
  4//
  5// Permission is hereby granted, free of charge, to any person obtaining a copy
  6// of this software and associated documentation files (the "Software"), to
  7// deal in the Software without restriction, including without limitation the
  8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  9// sell copies of the Software, and to permit persons to whom the Software is
 10// furnished to do so, subject to the following conditions:
 11//
 12// The above copyright notice and this permission notice shall be included in
 13// all copies or substantial portions of the Software.
 14//
 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 21// IN THE SOFTWARE.
 22//-----------------------------------------------------------------------------
 23
 24#ifndef _TORQUE_STRING_H_
 25#define _TORQUE_STRING_H_
 26
 27#include <cstdarg>
 28
 29#ifndef _TORQUE_TYPES_H_
 30#include "platform/types.h"
 31#endif
 32
 33
 34template< class T > class Vector;
 35
 36
 37typedef UTF8 StringChar;
 38
 39
 40/// The String class represents a 0-terminated array of characters.
 41class String
 42{
 43public:
 44   class StringData;
 45
 46   /// Default mode is case sensitive starting from the left
 47   enum Mode
 48   {
 49      Case = 0,         ///< Case sensitive
 50      NoCase = 1,       ///< Case insensitive
 51      Left = 0,         ///< Start at left end of string
 52      Right = 2,        ///< Start at right end of string
 53   };
 54
 55   typedef U32 SizeType;
 56   typedef StringChar ValueType;
 57
 58   static const SizeType NPos;   ///< Indicates 'not found' when using find() functions
 59
 60   /// A predefined empty string.
 61   static const String EmptyString;
 62
 63   String();
 64   String(const String &str);
 65   String(const StringChar *str);
 66   String(const StringChar *str, SizeType size); ///< Copy from raw data
 67   String(const UTF16 *str);
 68   ~String();
 69
 70   const UTF8  *c_str() const;   ///< Return the string as a native type
 71   const UTF16 *utf16() const;
 72   const UTF8* utf8() const { return c_str(); }
 73
 74   SizeType length() const;   ///< Returns the length of the string in bytes.
 75   SizeType size() const;     ///< Returns the length of the string in bytes including the NULL terminator.
 76   SizeType numChars() const; ///< Returns the length of the string in characters.
 77   bool     isEmpty() const;  ///< Is this an empty string [""]?
 78   static bool isEmpty(const char*); // is the input empty?
 79   bool     isNotEmpty() const { return !isEmpty(); }  ///< Is this not an empty string [""]?
 80
 81   /// Erases all characters in a string.
 82   void clear() { *this = EmptyString; }
 83
 84   bool     isShared() const; ///< Is this string's reference count greater than 1?
 85   bool     isSame( const String& str ) const; ///< Return true if both strings refer to the same shared data.
 86
 87   U32   getHashCaseSensitive() const;    ///< Get the case-sensitive hash of the string [only calculates the hash as necessary]
 88   U32   getHashCaseInsensitive() const;  ///< Get the case-insensitive hash of the string  [only calculates the hash as necessary]
 89
 90   String& operator=(StringChar);
 91   String& operator+=(StringChar);
 92   String& operator=(const StringChar*);
 93   String& operator+=(const StringChar*);
 94   String& operator=(const String&);
 95   String& operator+=(const String&);
 96   
 97   /**
 98      Compare this string with another.
 99      @param str  The string to compare against.
100      @param len  If len is non-zero, then at most len characters are compared.
101      @param mode Comparison mode.
102      @return Difference between the first two characters that don't match.
103   */
104   S32 compare(const StringChar *str, SizeType len = 0, U32 mode = Case</a>|<a href="/coding/class/classstring/#classstring_1ad23530ba3c445d964722346a3c80771da84aa4530ee3fa8bfa8e0c2305744bff8">Left) const;
105   S32 compare(const String &str, SizeType len = 0, U32 mode = Case</a>|<a href="/coding/class/classstring/#classstring_1ad23530ba3c445d964722346a3c80771da84aa4530ee3fa8bfa8e0c2305744bff8">Left) const; ///< @see compare(const StringChar *, SizeType, U32) const
106
107   /**
108      Compare two strings for equality.
109      It will use the string hashes to determine inequality.
110      @param str  The string to compare against.
111      @param mode Comparison mode - case sensitive or not.
112   */
113   bool equal(const String &str, U32 mode = Case) const;
114
115   SizeType find(StringChar c, SizeType pos = 0, U32 mode = Case</a>|<a href="/coding/class/classstring/#classstring_1ad23530ba3c445d964722346a3c80771da84aa4530ee3fa8bfa8e0c2305744bff8">Left) const;
116   SizeType find(const StringChar *str, SizeType pos = 0, U32 mode = Case</a>|<a href="/coding/class/classstring/#classstring_1ad23530ba3c445d964722346a3c80771da84aa4530ee3fa8bfa8e0c2305744bff8">Left) const;
117   SizeType find(const String &str, SizeType pos = 0, U32 mode = Case</a>|<a href="/coding/class/classstring/#classstring_1ad23530ba3c445d964722346a3c80771da84aa4530ee3fa8bfa8e0c2305744bff8">Left) const;
118   
119   String   &insert(SizeType pos, const StringChar c) { return insert(pos,&c,1); }
120   String   &insert(SizeType pos, const StringChar *str);
121   String   &insert(SizeType pos, const String &str);
122   String   &insert(SizeType pos, const StringChar *str, SizeType len);
123
124   String   &erase(SizeType pos, SizeType len);
125
126   String   &replace(SizeType pos, SizeType len, const StringChar *str);
127   String   &replace(SizeType pos, SizeType len, const String &str);
128   
129   /// Replace all occurrences of character 'c1' with 'c2'
130   String &replace( StringChar c1, StringChar c2 );
131
132   /// Replace all occurrences of StringData 's1' with StringData 's2'
133   String &replace(const String &s1, const String &s2);
134
135   String substr( SizeType pos, SizeType len = -1 ) const;
136   
137   /// Remove leading and trailing whitespace.
138   String trim() const;
139   
140   /// Replace all characters that need to be escaped for the string to be a valid string literal with their
141   /// respective escape sequences.
142   String expandEscapes() const;
143   
144   /// Replace all escape sequences in with their respective character codes.
145   String collapseEscapes() const;
146   
147   /// Split the string into its components separated by the given delimiter.
148   void split( const char* delimiter, Vector< String>& outElements ) const;
149   
150   /// Return true if the string starts with the given text.
151   bool startsWith( const char* text ) const;
152   
153   /// Return true if the string ends with the given text.
154   bool endsWith( const char* text ) const;
155
156   operator const StringChar*() const { return c_str(); }
157
158   StringChar operator []( U32 i ) const { return c_str()[i]; }
159   StringChar operator []( S32 i ) const { return c_str()[i]; }
160
161   bool operator==(const String &str) const;
162   bool operator!=(const String &str) const { return !(*this == str); }
163   bool operator==( StringChar c ) const;
164   bool operator!=( StringChar c ) const { return !(*this == c); }
165   bool operator<(const String &str) const;
166   bool operator>(const String &str) const;
167   bool operator<=(const String &str) const;
168   bool operator>=(const String &str) const;
169
170   friend String operator+(const String &a, StringChar c);
171   friend String operator+(StringChar c, const String &a);
172   friend String operator+(const String &a, const StringChar *b);
173   friend String operator+(const String &a, const String &b);
174   friend String operator+(const StringChar *a, const String &b);
175
176public:
177   /// @name String Utility routines
178   /// @{
179
180   static String ToString(const char *format, ...);
181   static String VToString(const char* format, va_list args);
182
183   static String ToString( bool v );
184   static inline String ToString( U32 v ) { return ToString( "%u", v ); }
185   static inline String ToString( S32 v ) { return ToString( "%d", v ); }
186   static inline String ToString( F32 v ) { return ToString( "%g", v ); }
187   static inline String ToString( F64 v ) { return ToString( "%Lg", v ); }
188
189   static String SpanToString(const char* start, const char* end);
190
191   static String ToLower(const String &string);
192   static String ToUpper(const String &string);
193
194   static String GetTrailingNumber(const char* str, S32& number);
195   static String GetFirstNumber(const char* str, U32& startPos, U32& endPos);
196
197   /// @}
198
199   /// @name Interning
200   ///
201   /// Interning maps identical strings to unique instances so that equality
202   /// amounts to simple pointer comparisons.
203   ///
204   /// Note that using interned strings within global destructors is not safe
205   /// as table destruction runs within this phase as well.  Uses o interned
206   /// strings in global destructors is thus dependent on object file ordering.
207   ///
208   /// Also, interned strings are not reference-counted.  Once interned, a
209   /// string will persist until shutdown.  This is to avoid costly concurrent
210   /// reference counting that would otherwise be necessary.
211   ///
212   /// @{
213   
214   /// Return the interned version of the string.
215   /// @note Interning is case-sensitive.
216   String intern() const;
217   
218   /// Return true if this string is interned.
219   bool isInterned() const;
220      
221   /// @}
222
223   /** An internal support class for ToString().
224      StrFormat manages the formatting of arbitrary length strings.
225      The class starts with a default internal fixed size buffer and
226      moves to dynamic allocation from the heap when that is exceeded.
227      Constructing the class on the stack will result in its most
228      efficient use. This class is meant to be used as a helper class,
229      and not for the permanent storage of string data.
230      @code
231         char* indexString(U32 index)
232         {
233            StrFormat format("Index: %d",index);
234            char* str = new char[format.size()];
235            format.copy(str);
236            return str;
237         }
238      @endcode
239   */
240   class StrFormat
241   {
242   public:
243      StrFormat()
244         :  _dynamicBuffer( NULL ),
245            _dynamicSize( 0 ),
246            _len( 0 )
247      {
248         _fixedBuffer[0] = '\0';
249      }
250
251      StrFormat(const char *formatStr, va_list args)
252         :  _dynamicBuffer( NULL ),
253            _dynamicSize( 0 ),
254            _len( 0 )
255      {
256         format(formatStr, args);
257      }
258
259      ~StrFormat();
260
261      S32 format( const char *format, va_list args );
262      S32 formatAppend( const char *format, va_list args );
263      S32 append(const char * str, S32 len);
264      S32 append(const char * str);
265
266      String getString() { return String(c_str(),_len); }
267
268      const char * c_str() const { return _dynamicBuffer ? _dynamicBuffer : _fixedBuffer; }
269
270      void reset()
271      {
272         _len = 0;
273         _fixedBuffer[0] = '\0';
274      }
275
276      /// Copy the formatted string into the output buffer which must be at least size() characters.
277      char  *copy(char* buffer) const;
278
279      /// Return the length of the formated string (does not include the terminating 0)
280      U32 length() const { return _len; };
281
282   public:
283      char  _fixedBuffer[2048];  //< Fixed size buffer
284      char  *_dynamicBuffer;     //< Temporary format buffer
285      U32   _dynamicSize;        //< Dynamic buffer size
286      U32   _len;                //< Len of the formatted string
287   };
288
289private:
290   String(StringData *str)
291      : _string( str ) {}
292
293   // Generate compile error if operator bool is used.  Without this we use
294   // operator const char *, which is always true...including operator bool
295   // causes an ambiguous cast compile error.  Making it private is simply
296   // more insurance that it isn't used on different compilers.
297   // NOTE: disable on GCC since it causes hyper casting to U32 on gcc.
298#if !defined(TORQUE_COMPILER_GCC) && !defined(__clang__)
299   operator const bool() const { return false; }
300#endif
301
302   static void copy(StringChar *dst, const StringChar *src, U32 size);
303
304   StringData   *_string;
305};
306
307// Utility class for formatting strings.
308class StringBuilder
309{
310   protected:
311
312      ///
313      String::StrFormat mFormat;
314
315   public:
316
317      StringBuilder() {}
318      
319      U32 length() const
320      {
321         return mFormat.length();
322      }
323      
324      void copy( char* buffer ) const
325      {
326         mFormat.copy( buffer );
327      }
328
329      const char* data() const
330      {
331         return mFormat.c_str();
332      }
333
334      String end()
335      {
336         return mFormat.getString();
337      }
338
339      S32 append( char ch )
340      {
341         char str[2];
342         str[0]=ch;
343         str[1]='\0';
344         return mFormat.append(str);
345      }
346      S32 append( const char* str )
347      {
348         return mFormat.append(str);
349      }
350      S32 append( const String& str )
351      {
352         return mFormat.append( str.c_str(), str.length() );
353      }
354      S32 append( const char* str, U32 length )
355      {
356         return mFormat.append(str,length);
357      }
358      S32 format( const char* fmt, ... )
359      {
360         va_list args;
361         va_start(args, fmt);
362         return mFormat.formatAppend(fmt, args);
363      }
364};
365
366// For use in hash tables and the like for explicitly requesting case sensitive hashing.
367// Meant to only appear in hash table definition (casting will take care of the rest).
368class StringCase : public String
369{
370public:
371   StringCase() : String() {}
372   StringCase(const String & s) : String(s) {}
373};
374
375// For use in hash tables and the like for explicitly requesting case insensitive hashing.
376// Meant to only appear in hash table definition (casting will take care of the rest).
377class StringNoCase : public String
378{
379public:
380   StringNoCase() : String() {}
381   StringNoCase(const String & s) : String(s) {}
382};
383
384class FileName : public String
385{
386public:
387   FileName() : String() {}
388   FileName(const String & s) : String(s) {}
389   FileName & operator=(const String & s) { String::operator=(s); return *this; }
390};
391
392//-----------------------------------------------------------------------------
393
394extern String operator+(const String &a, StringChar c);
395extern String operator+(StringChar c, const String &a);
396extern String operator+(const String &a, const StringChar *b);
397extern String operator+(const String &a, const String &b);
398extern String operator+(const StringChar *a, const String &b);
399
400#endif
401
402