]> de.git.xonotic.org Git - xonotic/netradiant.git/blobdiff - libs/splines/util_str.h
set eol-style
[xonotic/netradiant.git] / libs / splines / util_str.h
index 26dfa42debb91773250dee5779af4b1bb25e1ca0..0ce1ecb41cd9cb3f555bfa61ed3bf4c5d4041fe6 100644 (file)
-/*\r
-Copyright (C) 1999-2007 id Software, Inc. and contributors.\r
-For a list of contributors, see the accompanying CONTRIBUTORS file.\r
-\r
-This file is part of GtkRadiant.\r
-\r
-GtkRadiant is free software; you can redistribute it and/or modify\r
-it under the terms of the GNU General Public License as published by\r
-the Free Software Foundation; either version 2 of the License, or\r
-(at your option) any later version.\r
-\r
-GtkRadiant is distributed in the hope that it will be useful,\r
-but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-GNU General Public License for more details.\r
-\r
-You should have received a copy of the GNU General Public License\r
-along with GtkRadiant; if not, write to the Free Software\r
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA\r
-*/\r
-\r
-//need to rewrite this\r
-\r
-#ifndef __UTIL_STR_H__\r
-#define __UTIL_STR_H__\r
-\r
-#include <assert.h>\r
-#include <string.h>\r
-#include <stdio.h>\r
-\r
-#ifdef _WIN32\r
-#pragma warning(disable : 4710)     // function 'blah' not inlined\r
-#endif\r
-\r
-void TestStringClass ();\r
-\r
-class strdata\r
-   {\r
-   public:\r
-      strdata () : len( 0 ), refcount ( 0 ), data ( NULL ), alloced ( 0 ) {}\r
-      ~strdata () \r
-         {\r
-         if ( data )\r
-            delete [] data;\r
-         }\r
-\r
-      void AddRef () { refcount++; }\r
-      bool DelRef () // True if killed\r
-         {\r
-         refcount--;\r
-         if ( refcount < 0 )\r
-            {\r
-            delete this;\r
-            return true;\r
-            }\r
-         \r
-         return false;\r
-         }\r
-\r
-      int len;\r
-      int refcount;\r
-      char *data;\r
-      int alloced;\r
-   };\r
-\r
-class idStr {\r
-protected:\r
-       strdata *m_data;\r
-       void EnsureAlloced ( int, bool keepold = true );\r
-       void EnsureDataWritable ();\r
-\r
-public:\r
-       ~idStr();\r
-       idStr();\r
-       idStr( const char *text );\r
-       idStr( const idStr& string );\r
-       idStr( const idStr string, int start, int end );\r
-       idStr( const char ch );\r
-       idStr( const int num );\r
-       idStr( const float num );\r
-       idStr( const unsigned num );\r
-       int     length( void ) const;\r
-       int     allocated( void ) const;\r
-       const char * c_str( void ) const;\r
-\r
-       void            append( const char *text );\r
-       void            append( const idStr& text );\r
-       char            operator[]( int index ) const;\r
-       char&           operator[]( int index );\r
-\r
-       void            operator=( const idStr& text );\r
-       void            operator=( const char *text );\r
-\r
-       friend  idStr           operator+( const idStr& a, const idStr& b );\r
-       friend  idStr           operator+( const idStr& a, const char *b );\r
-       friend  idStr           operator+( const char *a, const idStr& b );\r
-\r
-    friend     idStr           operator+( const idStr& a, const float b );\r
-    friend     idStr           operator+( const idStr& a, const int b );\r
-    friend     idStr           operator+( const idStr& a, const unsigned b );\r
-    friend     idStr           operator+( const idStr& a, const bool b );\r
-    friend     idStr           operator+( const idStr& a, const char b );\r
-\r
-       idStr&          operator+=( const idStr& a );\r
-       idStr&          operator+=( const char *a );\r
-       idStr&          operator+=( const float a );\r
-       idStr&          operator+=( const char a );\r
-       idStr&          operator+=( const int a );\r
-       idStr&          operator+=( const unsigned a );\r
-       idStr&          operator+=( const bool a );\r
-\r
-       friend  bool            operator==(     const idStr& a, const idStr& b );\r
-       friend  bool            operator==(     const idStr& a, const char *b );\r
-       friend  bool            operator==(     const char *a, const idStr& b );\r
-\r
-       friend  bool            operator!=(     const idStr& a, const idStr& b );\r
-       friend  bool            operator!=(     const idStr& a, const char *b );\r
-       friend  bool            operator!=(     const char *a, const idStr& b );\r
-\r
-       operator const char * () const;\r
-       operator const char * ();\r
-\r
-    int      icmpn( const char *text, int n ) const;\r
-       int      icmpn( const idStr& text, int n ) const;\r
-       int      icmp( const char *text ) const;\r
-       int      icmp( const idStr& text ) const;\r
-       int      cmpn( const char *text, int n ) const;\r
-       int      cmpn( const idStr& text, int n ) const;\r
-       int      cmp( const char *text ) const;\r
-       int      cmp( const idStr& text ) const;\r
-\r
-       void     tolower( void );\r
-       void     toupper( void );\r
-\r
-       static   char     *tolower( char *s1 );\r
-       static   char     *toupper( char *s1 );\r
-\r
-       static   int      icmpn( const char *s1, const char *s2, int n );\r
-       static   int      icmp( const char *s1, const char *s2 );\r
-       static   int      cmpn( const char *s1, const char *s2, int n );\r
-       static   int      cmp( const char *s1, const char *s2 );\r
-\r
-       static   void     snprintf ( char *dst, int size, const char *fmt, ... );\r
-\r
-       static   bool      isNumeric( const char *str );\r
-    bool    isNumeric( void ) const;\r
-\r
-       void     CapLength ( int );\r
-\r
-       void     BackSlashesToSlashes ();\r
-\r
-};\r
-\r
-inline idStr::~idStr()\r
-       {\r
-   if ( m_data )\r
-      {\r
-      m_data->DelRef ();\r
-      m_data = NULL;\r
-      }\r
-       }\r
-\r
-inline idStr::idStr() : m_data ( NULL )\r
-       {\r
-   EnsureAlloced ( 1 );\r
-       m_data->data[ 0 ] = 0;\r
-       }\r
-\r
-inline idStr::idStr\r
-       (\r
-       const char *text\r
-   ) : m_data ( NULL )\r
-\r
-       {\r
-   int len;\r
-\r
-       assert( text );\r
-\r
-       if ( text )\r
-               {\r
-      len = strlen( text );\r
-               EnsureAlloced ( len + 1 );\r
-               strcpy( m_data->data, text );\r
-      m_data->len = len;\r
-               }\r
-       else\r
-               {\r
-      EnsureAlloced ( 1 );\r
-               m_data->data[ 0 ] = 0;\r
-               m_data->len = 0;\r
-               }\r
-       }\r
-\r
-inline idStr::idStr\r
-       (\r
-       const idStr& text\r
-   ) : m_data ( NULL )\r
-\r
-       {\r
-   m_data = text.m_data;\r
-   m_data->AddRef ();\r
-   }\r
-\r
-inline idStr::idStr\r
-       (\r
-       const idStr text, \r
-       int start,\r
-       int end\r
-   ) : m_data ( NULL )\r
-\r
-       {\r
-       int i;\r
-   int len;\r
-\r
-       if ( end > text.length() )\r
-               {\r
-               end = text.length();\r
-               }\r
-\r
-       if ( start > text.length() )\r
-               {\r
-               start = text.length();\r
-               }\r
-\r
-       len = end - start;\r
-       if ( len < 0 )\r
-               {\r
-               len = 0;\r
-               }\r
-\r
-   EnsureAlloced ( len + 1 );\r
-\r
-       for( i = 0; i < len; i++ )\r
-               {\r
-               m_data->data[ i ] = text[ start + i ];\r
-               }\r
-\r
-       m_data->data[ len ] = 0;\r
-   m_data->len = len;\r
-       }\r
-\r
-inline idStr::idStr\r
-   (\r
-   const char ch\r
-   ) : m_data ( NULL )\r
-\r
-   {\r
-   EnsureAlloced ( 2 );\r
-\r
-   m_data->data[ 0 ] = ch;\r
-   m_data->data[ 1 ] = 0;\r
-   m_data->len = 1;\r
-   }\r
-\r
-inline idStr::idStr\r
-   (\r
-   const float num\r
-   ) : m_data ( NULL )\r
-\r
-   {\r
-   char text[ 32 ];\r
-   int len;\r
-\r
-   sprintf( text, "%.3f", num );\r
-   len = strlen( text );\r
-   EnsureAlloced( len + 1 );\r
-   strcpy( m_data->data, text );\r
-   m_data->len = len;\r
-   }\r
-\r
-inline idStr::idStr\r
-   (\r
-   const int num\r
-   ) : m_data ( NULL )\r
-\r
-   {\r
-   char text[ 32 ];\r
-   int len;\r
-\r
-   sprintf( text, "%d", num );\r
-   len = strlen( text );\r
-   EnsureAlloced( len + 1 );\r
-   strcpy( m_data->data, text );\r
-   m_data->len = len;\r
-   }\r
-\r
-inline idStr::idStr\r
-   (\r
-   const unsigned num\r
-   ) : m_data ( NULL )\r
-\r
-   {\r
-   char text[ 32 ];\r
-   int len;\r
-\r
-   sprintf( text, "%u", num );\r
-   len = strlen( text );\r
-   EnsureAlloced( len + 1 );\r
-   strcpy( m_data->data, text );\r
-   m_data->len = len;\r
-   }\r
-\r
-inline int idStr::length( void ) const\r
-       {\r
-   return ( m_data != NULL ) ? m_data->len : 0;\r
-       }\r
-\r
-inline int idStr::allocated( void ) const\r
-       {\r
-   return ( m_data != NULL ) ? m_data->alloced + sizeof( *m_data ) : 0;\r
-       }\r
-\r
-inline const char *idStr::c_str( void ) const\r
-       {\r
-       assert( m_data );\r
-\r
-       return m_data->data;\r
-       }\r
-\r
-inline void idStr::append\r
-       (\r
-       const char *text\r
-       )\r
-\r
-       {\r
-   int len;\r
-\r
-       assert( text );\r
-\r
-       if ( text )\r
-               {\r
-               len = length() + strlen( text );\r
-               EnsureAlloced( len + 1 );\r
-\r
-      strcat( m_data->data, text );\r
-      m_data->len = len;\r
-               }\r
-       }\r
-\r
-inline void idStr::append\r
-       (\r
-       const idStr& text\r
-       )\r
-\r
-       {\r
-   int len;\r
-\r
-   len = length() + text.length();\r
-   EnsureAlloced ( len + 1 );\r
-\r
-   strcat ( m_data->data, text.c_str () );\r
-   m_data->len = len;\r
-       }\r
-\r
-inline char idStr::operator[]( int index ) const\r
-       {\r
-   assert ( m_data );\r
-   \r
-   if ( !m_data )\r
-      return 0;\r
-\r
-       // don't include the '/0' in the test, because technically, it's out of bounds\r
-       assert( ( index >= 0 ) && ( index < m_data->len ) );\r
-\r
-       // In release mode, give them a null character\r
-       // don't include the '/0' in the test, because technically, it's out of bounds\r
-       if ( ( index < 0 ) || ( index >= m_data->len ) )\r
-               {\r
-               return 0;\r
-               }\r
-\r
-       return m_data->data[ index ];\r
-       }\r
-\r
-inline char& idStr::operator[]\r
-       (\r
-       int index\r
-       )\r
-\r
-       {\r
-       // Used for result for invalid indices\r
-       static char dummy = 0;\r
-   assert ( m_data );\r
-\r
-   // We don't know if they'll write to it or not\r
-   // if it's not a const object\r
-   EnsureDataWritable ();\r
-\r
-   if ( !m_data )\r
-      return dummy;\r
-\r
-       // don't include the '/0' in the test, because technically, it's out of bounds\r
-       assert( ( index >= 0 ) && ( index < m_data->len ) );\r
-\r
-       // In release mode, let them change a safe variable\r
-       // don't include the '/0' in the test, because technically, it's out of bounds\r
-       if ( ( index < 0 ) || ( index >= m_data->len ) )\r
-               {\r
-               return dummy;\r
-               }\r
-\r
-       return m_data->data[ index ];\r
-       }\r
-\r
-inline void idStr::operator=\r
-       (\r
-       const idStr& text\r
-       )\r
-\r
-       {\r
-   // adding the reference before deleting our current reference prevents\r
-   // us from deleting our string if we are copying from ourself\r
-   text.m_data->AddRef();\r
-   m_data->DelRef();\r
-   m_data = text.m_data;\r
-   }\r
-\r
-inline void idStr::operator=\r
-       (\r
-       const char *text\r
-       )\r
-\r
-       {\r
-   int len;\r
-\r
-       assert( text );\r
-\r
-       if ( !text )\r
-               {\r
-               // safe behaviour if NULL\r
-               EnsureAlloced ( 1, false );\r
-      m_data->data[0] = 0;\r
-      m_data->len = 0;\r
-      return;\r
-               }\r
-\r
-   if ( !m_data )\r
-      {\r
-      len = strlen ( text );\r
-      EnsureAlloced( len + 1, false );\r
-      strcpy ( m_data->data, text );\r
-      m_data->len = len;\r
-      return;\r
-      }\r
-\r
-   if ( text == m_data->data )\r
-      return; // Copying same thing.  Punt.\r
-\r
-   // If we alias and I don't do this, I could corrupt other strings...  This \r
-   // will get called with EnsureAlloced anyway\r
-   EnsureDataWritable ();\r
-\r
-   // Now we need to check if we're aliasing..\r
-   if ( text >= m_data->data && text <= m_data->data + m_data->len )\r
-      {\r
-      // Great, we're aliasing.  We're copying from inside ourselves.\r
-      // This means that I don't have to ensure that anything is alloced,\r
-      // though I'll assert just in case.\r
-      int diff = text - m_data->data;\r
-      int i;\r
-\r
-      assert ( strlen ( text ) < (unsigned) m_data->len );\r
-      \r
-      for ( i = 0; text[i]; i++ )\r
-         {\r
-         m_data->data[i] = text[i];\r
-         }\r
-\r
-      m_data->data[i] = 0;\r
-\r
-      m_data->len -= diff;\r
-\r
-      return;\r
-      }\r
-\r
-       len = strlen( text );\r
-   EnsureAlloced ( len + 1, false );\r
-       strcpy( m_data->data, text );\r
-   m_data->len = len;\r
-       }\r
-\r
-inline idStr operator+\r
-       (\r
-       const idStr& a,\r
-       const idStr& b\r
-       )\r
-\r
-       {\r
-       idStr result( a );\r
-\r
-       result.append( b );\r
-\r
-       return result;\r
-       }\r
-\r
-inline idStr operator+\r
-       (\r
-       const idStr& a,\r
-       const char *b\r
-       )\r
-\r
-       {\r
-       idStr result( a );\r
-\r
-       result.append( b );\r
-\r
-       return result;\r
-       }\r
-\r
-inline idStr operator+\r
-       (\r
-       const char *a,\r
-       const idStr& b\r
-       )\r
-\r
-       {\r
-       idStr result( a );\r
-\r
-       result.append( b );\r
-\r
-       return result;\r
-       }\r
-\r
-inline idStr operator+\r
-   (\r
-   const idStr& a,\r
-   const bool b\r
-   )\r
-\r
-   {\r
-       idStr result( a );\r
-\r
-   result.append( b ? "true" : "false" );\r
-\r
-       return result;\r
-   }\r
-\r
-inline idStr operator+\r
-       (\r
-   const idStr& a,\r
-       const char b\r
-       )\r
-\r
-       {\r
-   char text[ 2 ];\r
-\r
-   text[ 0 ] = b;\r
-   text[ 1 ] = 0;\r
-\r
-       return a + text;\r
-       }\r
-\r
-inline idStr& idStr::operator+=\r
-       (\r
-       const idStr& a\r
-       )\r
-\r
-       {\r
-       append( a );\r
-       return *this;\r
-       }\r
-\r
-inline idStr& idStr::operator+=\r
-       (\r
-       const char *a\r
-       )\r
-\r
-       {\r
-       append( a );\r
-       return *this;\r
-       }\r
-\r
-inline idStr& idStr::operator+=\r
-       (\r
-       const char a\r
-       )\r
-\r
-       {\r
-   char text[ 2 ];\r
-\r
-   text[ 0 ] = a;\r
-   text[ 1 ] = 0;\r
-       append( text );\r
-\r
-   return *this;\r
-       }\r
-\r
-inline idStr& idStr::operator+=\r
-       (\r
-       const bool a\r
-       )\r
-\r
-       {\r
-   append( a ? "true" : "false" );\r
-       return *this;\r
-       }\r
-\r
-inline bool operator==\r
-       (\r
-       const idStr& a,\r
-       const idStr& b\r
-       )\r
-\r
-       {\r
-       return ( !strcmp( a.c_str(), b.c_str() ) );\r
-       }\r
-\r
-inline bool operator==\r
-       (\r
-       const idStr& a,\r
-       const char *b\r
-       )\r
-\r
-       {\r
-       assert( b );\r
-       if ( !b )\r
-               {\r
-               return false;\r
-               }\r
-       return ( !strcmp( a.c_str(), b ) );\r
-       }\r
-\r
-inline bool operator==\r
-       (\r
-       const char *a,\r
-       const idStr& b\r
-       )\r
-\r
-       {\r
-       assert( a );\r
-       if ( !a )\r
-               {\r
-               return false;\r
-               }\r
-       return ( !strcmp( a, b.c_str() ) );\r
-       }\r
-\r
-inline bool operator!=\r
-       (\r
-       const idStr& a,\r
-       const idStr& b\r
-       )\r
-\r
-       {\r
-       return !( a == b );\r
-       }\r
-\r
-inline bool operator!=\r
-       (\r
-       const idStr& a,\r
-       const char *b\r
-       )\r
-\r
-       {\r
-       return !( a == b );\r
-       }\r
-\r
-inline bool operator!=\r
-       (\r
-       const char *a,\r
-       const idStr& b\r
-       )\r
-\r
-       {\r
-       return !( a == b );\r
-       }\r
-\r
-inline int idStr::icmpn\r
-   (\r
-   const char *text, \r
-   int n\r
-   ) const\r
-\r
-   {\r
-       assert( m_data );\r
-       assert( text );\r
-\r
-   return idStr::icmpn( m_data->data, text, n );\r
-   }\r
-\r
-inline int idStr::icmpn\r
-   (\r
-   const idStr& text, \r
-   int n\r
-   ) const\r
-\r
-   {\r
-       assert( m_data );\r
-       assert( text.m_data );\r
-\r
-   return idStr::icmpn( m_data->data, text.m_data->data, n );\r
-   }\r
-\r
-inline int idStr::icmp\r
-   (\r
-   const char *text\r
-   ) const\r
-\r
-   {\r
-       assert( m_data );\r
-       assert( text );\r
-\r
-   return idStr::icmp( m_data->data, text );\r
-   }\r
-\r
-inline int idStr::icmp\r
-   (\r
-   const idStr& text\r
-   ) const\r
-\r
-   {\r
-       assert( c_str () );\r
-       assert( text.c_str () );\r
-\r
-   return idStr::icmp( c_str () , text.c_str () );\r
-   }\r
-\r
-inline int idStr::cmp\r
-   (\r
-   const char *text\r
-   ) const\r
-\r
-   {\r
-       assert( m_data );\r
-       assert( text );\r
-\r
-   return idStr::cmp( m_data->data, text );\r
-   }\r
-\r
-inline int idStr::cmp\r
-   (\r
-   const idStr& text\r
-   ) const\r
-\r
-   {\r
-       assert( c_str () );\r
-       assert( text.c_str () );\r
-\r
-   return idStr::cmp( c_str () , text.c_str () );\r
-   }\r
-\r
-inline int idStr::cmpn\r
-   (\r
-   const char *text, \r
-   int n\r
-   ) const\r
-\r
-   {\r
-       assert( c_str () );\r
-       assert( text );\r
-\r
-   return idStr::cmpn( c_str () , text, n );\r
-   }\r
-\r
-inline int idStr::cmpn\r
-   (\r
-   const idStr& text, \r
-   int n\r
-   ) const\r
-\r
-   {\r
-       assert( c_str () );\r
-       assert( text.c_str ()  );\r
-\r
-   return idStr::cmpn( c_str () , text.c_str () , n );\r
-   }\r
-\r
-inline void idStr::tolower\r
-   (\r
-   void\r
-   )\r
-\r
-   {\r
-   assert( m_data );\r
-\r
-   EnsureDataWritable ();\r
-\r
-   idStr::tolower( m_data->data );\r
-   }\r
-\r
-inline void idStr::toupper\r
-   (\r
-   void\r
-   )\r
-\r
-   {\r
-   assert( m_data );\r
-\r
-   EnsureDataWritable ();\r
-\r
-   idStr::toupper( m_data->data );\r
-   }\r
-\r
-inline bool idStr::isNumeric\r
-   (\r
-   void\r
-   ) const\r
-\r
-   {\r
-   assert( m_data );\r
-   return idStr::isNumeric( m_data->data );\r
-   }\r
-\r
-inline idStr::operator const char *() {\r
-       return c_str();\r
-}\r
-\r
-inline idStr::operator const char *\r
-   (\r
-   void\r
-   ) const\r
-\r
-   {\r
-   return c_str ();\r
-   }\r
-\r
-#endif\r
+/*
+Copyright (C) 1999-2007 id Software, Inc. and contributors.
+For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+This file is part of GtkRadiant.
+
+GtkRadiant is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+GtkRadiant is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GtkRadiant; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+//need to rewrite this
+
+#ifndef __UTIL_STR_H__
+#define __UTIL_STR_H__
+
+#include <assert.h>
+#include <string.h>
+#include <stdio.h>
+
+#ifdef _WIN32
+#pragma warning(disable : 4710)     // function 'blah' not inlined
+#endif
+
+void TestStringClass ();
+
+class strdata
+   {
+   public:
+      strdata () : len( 0 ), refcount ( 0 ), data ( NULL ), alloced ( 0 ) {}
+      ~strdata () 
+         {
+         if ( data )
+            delete [] data;
+         }
+
+      void AddRef () { refcount++; }
+      bool DelRef () // True if killed
+         {
+         refcount--;
+         if ( refcount < 0 )
+            {
+            delete this;
+            return true;
+            }
+         
+         return false;
+         }
+
+      int len;
+      int refcount;
+      char *data;
+      int alloced;
+   };
+
+class idStr {
+protected:
+       strdata *m_data;
+       void EnsureAlloced ( int, bool keepold = true );
+       void EnsureDataWritable ();
+
+public:
+       ~idStr();
+       idStr();
+       idStr( const char *text );
+       idStr( const idStr& string );
+       idStr( const idStr string, int start, int end );
+       idStr( const char ch );
+       idStr( const int num );
+       idStr( const float num );
+       idStr( const unsigned num );
+       int     length( void ) const;
+       int     allocated( void ) const;
+       const char * c_str( void ) const;
+
+       void            append( const char *text );
+       void            append( const idStr& text );
+       char            operator[]( int index ) const;
+       char&           operator[]( int index );
+
+       void            operator=( const idStr& text );
+       void            operator=( const char *text );
+
+       friend  idStr           operator+( const idStr& a, const idStr& b );
+       friend  idStr           operator+( const idStr& a, const char *b );
+       friend  idStr           operator+( const char *a, const idStr& b );
+
+    friend     idStr           operator+( const idStr& a, const float b );
+    friend     idStr           operator+( const idStr& a, const int b );
+    friend     idStr           operator+( const idStr& a, const unsigned b );
+    friend     idStr           operator+( const idStr& a, const bool b );
+    friend     idStr           operator+( const idStr& a, const char b );
+
+       idStr&          operator+=( const idStr& a );
+       idStr&          operator+=( const char *a );
+       idStr&          operator+=( const float a );
+       idStr&          operator+=( const char a );
+       idStr&          operator+=( const int a );
+       idStr&          operator+=( const unsigned a );
+       idStr&          operator+=( const bool a );
+
+       friend  bool            operator==(     const idStr& a, const idStr& b );
+       friend  bool            operator==(     const idStr& a, const char *b );
+       friend  bool            operator==(     const char *a, const idStr& b );
+
+       friend  bool            operator!=(     const idStr& a, const idStr& b );
+       friend  bool            operator!=(     const idStr& a, const char *b );
+       friend  bool            operator!=(     const char *a, const idStr& b );
+
+       operator const char * () const;
+       operator const char * ();
+
+    int      icmpn( const char *text, int n ) const;
+       int      icmpn( const idStr& text, int n ) const;
+       int      icmp( const char *text ) const;
+       int      icmp( const idStr& text ) const;
+       int      cmpn( const char *text, int n ) const;
+       int      cmpn( const idStr& text, int n ) const;
+       int      cmp( const char *text ) const;
+       int      cmp( const idStr& text ) const;
+
+       void     tolower( void );
+       void     toupper( void );
+
+       static   char     *tolower( char *s1 );
+       static   char     *toupper( char *s1 );
+
+       static   int      icmpn( const char *s1, const char *s2, int n );
+       static   int      icmp( const char *s1, const char *s2 );
+       static   int      cmpn( const char *s1, const char *s2, int n );
+       static   int      cmp( const char *s1, const char *s2 );
+
+       static   void     snprintf ( char *dst, int size, const char *fmt, ... );
+
+       static   bool      isNumeric( const char *str );
+    bool    isNumeric( void ) const;
+
+       void     CapLength ( int );
+
+       void     BackSlashesToSlashes ();
+
+};
+
+inline idStr::~idStr()
+       {
+   if ( m_data )
+      {
+      m_data->DelRef ();
+      m_data = NULL;
+      }
+       }
+
+inline idStr::idStr() : m_data ( NULL )
+       {
+   EnsureAlloced ( 1 );
+       m_data->data[ 0 ] = 0;
+       }
+
+inline idStr::idStr
+       (
+       const char *text
+   ) : m_data ( NULL )
+
+       {
+   int len;
+
+       assert( text );
+
+       if ( text )
+               {
+      len = strlen( text );
+               EnsureAlloced ( len + 1 );
+               strcpy( m_data->data, text );
+      m_data->len = len;
+               }
+       else
+               {
+      EnsureAlloced ( 1 );
+               m_data->data[ 0 ] = 0;
+               m_data->len = 0;
+               }
+       }
+
+inline idStr::idStr
+       (
+       const idStr& text
+   ) : m_data ( NULL )
+
+       {
+   m_data = text.m_data;
+   m_data->AddRef ();
+   }
+
+inline idStr::idStr
+       (
+       const idStr text, 
+       int start,
+       int end
+   ) : m_data ( NULL )
+
+       {
+       int i;
+   int len;
+
+       if ( end > text.length() )
+               {
+               end = text.length();
+               }
+
+       if ( start > text.length() )
+               {
+               start = text.length();
+               }
+
+       len = end - start;
+       if ( len < 0 )
+               {
+               len = 0;
+               }
+
+   EnsureAlloced ( len + 1 );
+
+       for( i = 0; i < len; i++ )
+               {
+               m_data->data[ i ] = text[ start + i ];
+               }
+
+       m_data->data[ len ] = 0;
+   m_data->len = len;
+       }
+
+inline idStr::idStr
+   (
+   const char ch
+   ) : m_data ( NULL )
+
+   {
+   EnsureAlloced ( 2 );
+
+   m_data->data[ 0 ] = ch;
+   m_data->data[ 1 ] = 0;
+   m_data->len = 1;
+   }
+
+inline idStr::idStr
+   (
+   const float num
+   ) : m_data ( NULL )
+
+   {
+   char text[ 32 ];
+   int len;
+
+   sprintf( text, "%.3f", num );
+   len = strlen( text );
+   EnsureAlloced( len + 1 );
+   strcpy( m_data->data, text );
+   m_data->len = len;
+   }
+
+inline idStr::idStr
+   (
+   const int num
+   ) : m_data ( NULL )
+
+   {
+   char text[ 32 ];
+   int len;
+
+   sprintf( text, "%d", num );
+   len = strlen( text );
+   EnsureAlloced( len + 1 );
+   strcpy( m_data->data, text );
+   m_data->len = len;
+   }
+
+inline idStr::idStr
+   (
+   const unsigned num
+   ) : m_data ( NULL )
+
+   {
+   char text[ 32 ];
+   int len;
+
+   sprintf( text, "%u", num );
+   len = strlen( text );
+   EnsureAlloced( len + 1 );
+   strcpy( m_data->data, text );
+   m_data->len = len;
+   }
+
+inline int idStr::length( void ) const
+       {
+   return ( m_data != NULL ) ? m_data->len : 0;
+       }
+
+inline int idStr::allocated( void ) const
+       {
+   return ( m_data != NULL ) ? m_data->alloced + sizeof( *m_data ) : 0;
+       }
+
+inline const char *idStr::c_str( void ) const
+       {
+       assert( m_data );
+
+       return m_data->data;
+       }
+
+inline void idStr::append
+       (
+       const char *text
+       )
+
+       {
+   int len;
+
+       assert( text );
+
+       if ( text )
+               {
+               len = length() + strlen( text );
+               EnsureAlloced( len + 1 );
+
+      strcat( m_data->data, text );
+      m_data->len = len;
+               }
+       }
+
+inline void idStr::append
+       (
+       const idStr& text
+       )
+
+       {
+   int len;
+
+   len = length() + text.length();
+   EnsureAlloced ( len + 1 );
+
+   strcat ( m_data->data, text.c_str () );
+   m_data->len = len;
+       }
+
+inline char idStr::operator[]( int index ) const
+       {
+   assert ( m_data );
+   
+   if ( !m_data )
+      return 0;
+
+       // don't include the '/0' in the test, because technically, it's out of bounds
+       assert( ( index >= 0 ) && ( index < m_data->len ) );
+
+       // In release mode, give them a null character
+       // don't include the '/0' in the test, because technically, it's out of bounds
+       if ( ( index < 0 ) || ( index >= m_data->len ) )
+               {
+               return 0;
+               }
+
+       return m_data->data[ index ];
+       }
+
+inline char& idStr::operator[]
+       (
+       int index
+       )
+
+       {
+       // Used for result for invalid indices
+       static char dummy = 0;
+   assert ( m_data );
+
+   // We don't know if they'll write to it or not
+   // if it's not a const object
+   EnsureDataWritable ();
+
+   if ( !m_data )
+      return dummy;
+
+       // don't include the '/0' in the test, because technically, it's out of bounds
+       assert( ( index >= 0 ) && ( index < m_data->len ) );
+
+       // In release mode, let them change a safe variable
+       // don't include the '/0' in the test, because technically, it's out of bounds
+       if ( ( index < 0 ) || ( index >= m_data->len ) )
+               {
+               return dummy;
+               }
+
+       return m_data->data[ index ];
+       }
+
+inline void idStr::operator=
+       (
+       const idStr& text
+       )
+
+       {
+   // adding the reference before deleting our current reference prevents
+   // us from deleting our string if we are copying from ourself
+   text.m_data->AddRef();
+   m_data->DelRef();
+   m_data = text.m_data;
+   }
+
+inline void idStr::operator=
+       (
+       const char *text
+       )
+
+       {
+   int len;
+
+       assert( text );
+
+       if ( !text )
+               {
+               // safe behaviour if NULL
+               EnsureAlloced ( 1, false );
+      m_data->data[0] = 0;
+      m_data->len = 0;
+      return;
+               }
+
+   if ( !m_data )
+      {
+      len = strlen ( text );
+      EnsureAlloced( len + 1, false );
+      strcpy ( m_data->data, text );
+      m_data->len = len;
+      return;
+      }
+
+   if ( text == m_data->data )
+      return; // Copying same thing.  Punt.
+
+   // If we alias and I don't do this, I could corrupt other strings...  This 
+   // will get called with EnsureAlloced anyway
+   EnsureDataWritable ();
+
+   // Now we need to check if we're aliasing..
+   if ( text >= m_data->data && text <= m_data->data + m_data->len )
+      {
+      // Great, we're aliasing.  We're copying from inside ourselves.
+      // This means that I don't have to ensure that anything is alloced,
+      // though I'll assert just in case.
+      int diff = text - m_data->data;
+      int i;
+
+      assert ( strlen ( text ) < (unsigned) m_data->len );
+      
+      for ( i = 0; text[i]; i++ )
+         {
+         m_data->data[i] = text[i];
+         }
+
+      m_data->data[i] = 0;
+
+      m_data->len -= diff;
+
+      return;
+      }
+
+       len = strlen( text );
+   EnsureAlloced ( len + 1, false );
+       strcpy( m_data->data, text );
+   m_data->len = len;
+       }
+
+inline idStr operator+
+       (
+       const idStr& a,
+       const idStr& b
+       )
+
+       {
+       idStr result( a );
+
+       result.append( b );
+
+       return result;
+       }
+
+inline idStr operator+
+       (
+       const idStr& a,
+       const char *b
+       )
+
+       {
+       idStr result( a );
+
+       result.append( b );
+
+       return result;
+       }
+
+inline idStr operator+
+       (
+       const char *a,
+       const idStr& b
+       )
+
+       {
+       idStr result( a );
+
+       result.append( b );
+
+       return result;
+       }
+
+inline idStr operator+
+   (
+   const idStr& a,
+   const bool b
+   )
+
+   {
+       idStr result( a );
+
+   result.append( b ? "true" : "false" );
+
+       return result;
+   }
+
+inline idStr operator+
+       (
+   const idStr& a,
+       const char b
+       )
+
+       {
+   char text[ 2 ];
+
+   text[ 0 ] = b;
+   text[ 1 ] = 0;
+
+       return a + text;
+       }
+
+inline idStr& idStr::operator+=
+       (
+       const idStr& a
+       )
+
+       {
+       append( a );
+       return *this;
+       }
+
+inline idStr& idStr::operator+=
+       (
+       const char *a
+       )
+
+       {
+       append( a );
+       return *this;
+       }
+
+inline idStr& idStr::operator+=
+       (
+       const char a
+       )
+
+       {
+   char text[ 2 ];
+
+   text[ 0 ] = a;
+   text[ 1 ] = 0;
+       append( text );
+
+   return *this;
+       }
+
+inline idStr& idStr::operator+=
+       (
+       const bool a
+       )
+
+       {
+   append( a ? "true" : "false" );
+       return *this;
+       }
+
+inline bool operator==
+       (
+       const idStr& a,
+       const idStr& b
+       )
+
+       {
+       return ( !strcmp( a.c_str(), b.c_str() ) );
+       }
+
+inline bool operator==
+       (
+       const idStr& a,
+       const char *b
+       )
+
+       {
+       assert( b );
+       if ( !b )
+               {
+               return false;
+               }
+       return ( !strcmp( a.c_str(), b ) );
+       }
+
+inline bool operator==
+       (
+       const char *a,
+       const idStr& b
+       )
+
+       {
+       assert( a );
+       if ( !a )
+               {
+               return false;
+               }
+       return ( !strcmp( a, b.c_str() ) );
+       }
+
+inline bool operator!=
+       (
+       const idStr& a,
+       const idStr& b
+       )
+
+       {
+       return !( a == b );
+       }
+
+inline bool operator!=
+       (
+       const idStr& a,
+       const char *b
+       )
+
+       {
+       return !( a == b );
+       }
+
+inline bool operator!=
+       (
+       const char *a,
+       const idStr& b
+       )
+
+       {
+       return !( a == b );
+       }
+
+inline int idStr::icmpn
+   (
+   const char *text, 
+   int n
+   ) const
+
+   {
+       assert( m_data );
+       assert( text );
+
+   return idStr::icmpn( m_data->data, text, n );
+   }
+
+inline int idStr::icmpn
+   (
+   const idStr& text, 
+   int n
+   ) const
+
+   {
+       assert( m_data );
+       assert( text.m_data );
+
+   return idStr::icmpn( m_data->data, text.m_data->data, n );
+   }
+
+inline int idStr::icmp
+   (
+   const char *text
+   ) const
+
+   {
+       assert( m_data );
+       assert( text );
+
+   return idStr::icmp( m_data->data, text );
+   }
+
+inline int idStr::icmp
+   (
+   const idStr& text
+   ) const
+
+   {
+       assert( c_str () );
+       assert( text.c_str () );
+
+   return idStr::icmp( c_str () , text.c_str () );
+   }
+
+inline int idStr::cmp
+   (
+   const char *text
+   ) const
+
+   {
+       assert( m_data );
+       assert( text );
+
+   return idStr::cmp( m_data->data, text );
+   }
+
+inline int idStr::cmp
+   (
+   const idStr& text
+   ) const
+
+   {
+       assert( c_str () );
+       assert( text.c_str () );
+
+   return idStr::cmp( c_str () , text.c_str () );
+   }
+
+inline int idStr::cmpn
+   (
+   const char *text, 
+   int n
+   ) const
+
+   {
+       assert( c_str () );
+       assert( text );
+
+   return idStr::cmpn( c_str () , text, n );
+   }
+
+inline int idStr::cmpn
+   (
+   const idStr& text, 
+   int n
+   ) const
+
+   {
+       assert( c_str () );
+       assert( text.c_str ()  );
+
+   return idStr::cmpn( c_str () , text.c_str () , n );
+   }
+
+inline void idStr::tolower
+   (
+   void
+   )
+
+   {
+   assert( m_data );
+
+   EnsureDataWritable ();
+
+   idStr::tolower( m_data->data );
+   }
+
+inline void idStr::toupper
+   (
+   void
+   )
+
+   {
+   assert( m_data );
+
+   EnsureDataWritable ();
+
+   idStr::toupper( m_data->data );
+   }
+
+inline bool idStr::isNumeric
+   (
+   void
+   ) const
+
+   {
+   assert( m_data );
+   return idStr::isNumeric( m_data->data );
+   }
+
+inline idStr::operator const char *() {
+       return c_str();
+}
+
+inline idStr::operator const char *
+   (
+   void
+   ) const
+
+   {
+   return c_str ();
+   }
+
+#endif