]> git.xonotic.org Git - xonotic/netradiant.git/blobdiff - libs/splines/util_str.h
Merge commit 'bf6dd1f2d186c799adf11f1e744a1ff57aa8d335' into garux-merge
[xonotic/netradiant.git] / libs / splines / util_str.h
index 26dfa42debb91773250dee5779af4b1bb25e1ca0..02240ced728fba4ebf9f8cd589838ec11f73b0f6 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-2006 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>
+
+#if GDEF_COMPILER_MSVC
+#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