让HGE支持中文(3) - HGE字符串处理

前面都已经讲了怎么请HGE支持并显示中文..

另外呢.我们还需要的一个处理字符串的类..

当然也可以不用.所以放到最后拿出来.

不过当对于UNICODE与非UNICODE之间切来切去的时候.

你不可能一直在那里改代码..

这个时候CString就可以用到了.

虽然CString可以放到HGE里使用.不过还是自己找一份比较好/

CString属于ATL的东西.自然会引入ATL的东西.编译时候会填加几十K上百K.

所有还是自己找一份或者自己定一份好..

为此我将Nebula2的nString给放到HGE里去了.

这样也便玩我们使用.

代码如下:仅一个H文件,所有代码都在里面:


// Add by ShowLong. 20070629
//  Add from nebula2

#include 
" hge.h "
#include 
< ctype.h >
#include 
< stdarg.h >
#include 
< cstdarg >
#include 
< string .h >
#include 
< assert.h >
#include 
< malloc.h >
#include 
< stdio.h >
#include 
< stdlib.h >

#define  t_max(a,b)      (((a) > (b)) ? (a) : (b))
#define  t_min(a,b)      (((a) < (b)) ? (a) : (b))

// ------------------------------------------------------------------------------
class  hgeString
{
public :
    
///  constructor
    hgeString();
    
///  constructor 1
    hgeString( const   char *  str);
    
///  copy constructor
    hgeString( const  hgeString &  rhs);
    
///  destructor
     ~ hgeString();
    
///  = operator
    hgeString &   operator = ( const  hgeString &  rhs);
    
///  = operator with string
    hgeString &   operator = ( const   char *  rhs);
    
///  += operator with char*
    hgeString &   operator += ( const   char *  rhs);
    
///  += operator with string
    hgeString &   operator += ( const  hgeString &  rhs);
    
///  Is `a' equal to `b'?
    friend  bool   operator   ==  ( const  hgeString &  a,  const  hgeString &  b);
    
///  Is `a' unequal to `b'?
    friend  bool   operator   !=  ( const  hgeString &  a,  const  hgeString &  b);
    
///  Is `a' smaller than `b'?
    friend  bool   operator   <  ( const  hgeString &  a,  const  hgeString &  b);
    
///  Is `a' greater than `b'?
    friend  bool   operator   >  ( const  hgeString &  a,  const  hgeString &  b);
    
///  Is `a' smaller than or equal to `b'?
    friend  bool   operator   <=  ( const  hgeString &  a,  const  hgeString &  b);
    
///  Is `a' greater than or equal to `b'?
    friend  bool   operator   >=  ( const  hgeString &  a,  const  hgeString &  b);
    
///  Subscript operator (read only).
     char   operator []( int  i)  const ;
    
///  Subscript operator (writable).
     char &   operator []( int  i);
    
///  set as char ptr, with explicit length
     void  Set( const   char *  ptr,  int  length);
    
///  set as char ptr
     void  Set( const   char *  str);
    
///  set as int value
     void  SetInt( int  val);
    
///  set as float value
     void  SetFloat( float  val);
    
///  set as bool value
     void  SetBool( bool  val);
    
///  get string as char ptr
     const   char *  Get()  const ;
    
///  return contents as integer
     int  AsInt()  const ;
    
///  return contents as float
     float  AsFloat()  const ;
    
///  return contents as bool
     bool  AsBool()  const ;
    
///  return true if the content is a valid integer
     bool  IsValidInt()  const ;
    
///  return true if the content is a valid float
     bool  IsValidFloat()  const ;
    
///  return true if the content is a valid bool
     bool  IsValidBool()  const ;
    
///  return length of string
     int  Length()  const ;
    
///  clear the string
     void  Clear();
    
///  return true if string object is empty
     bool  IsEmpty()  const ;
    
///  return true if string object is not empty
     bool  IsValid()  const ;
    
///  append character pointer
     void  Append( const   char *  str);
    
///  append string
     void  Append( const  hgeString &  str);
    
///  append a range of characters
     void  AppendRange( const   char *  str, unsigned  int  numChars);
    
///  append int value
     void  AppendInt( int  val);
    
///  append float value
     void  AppendFloat( float  val);
    
///  convert string to lower case
     void  ToLower();
    
///  convert string to upper case
     void  ToUpper();
    
///  *** OBSOLETE *** get first token (this will destroy the string)
     const   char *  GetFirstToken( const   char *  whiteSpace);
    
///  *** OBSOLETE *** get next token (this will destroy the string)
     const   char *  GetNextToken( const   char *  whiteSpace);
    
///  extract substring
    hgeString ExtractRange( int  from,  int  numChars)  const ;
    
///  terminate string at first occurrence of character in set
     void  Strip( const   char *  charSet);
    
///  Index of first appearance of `v' starting from index `startIndex'.
     int  FindStringIndex( const  hgeString &  v,  int  startIndex)  const ;
    
///  return index of character in string
     int  FindCharIndex(unsigned  char  c,  int  startIndex)  const ;
    
///  terminate string at given index
     void  TerminateAtIndex( int  index);
    
///  returns true if string contains character from set
     bool  ContainsCharFromSet( const   char *  charSet)  const ;
    
///  strip slash at end of path, if exists
     void  StripTrailingSlash();
    
///  delete characters from charset at left side of string
    hgeString TrimLeft( const   char *  charSet)  const ;
    
///  delete characters from charset at right side of string
    hgeString TrimRight( const   char *  charSet)  const ;
    
///  trim characters from charset at both sides of string
    hgeString Trim( const   char *  charSet)  const ;
    
///  substitute every occurrence of a string with another string
    hgeString Substitute( const   char *  str,  const   char *  substStr)  const ;
    
///  substitute every occurrence of a character with another character
     void  SubstituteCharacter( char  c,  char  subst);
    
///  convert string in place from UTF-8 to 8-bit ANSI
     void  UTF8toANSI();
    
///  convert ANSI to UTF-8 in place
     void  ANSItoUTF8();
    
///  get pointer to extension (without the dot)
     const   char *  GetExtension()  const ;
    
///  check if extension matches (no dot in the extension!)
     bool  CheckExtension( const   char *  ext)  const ;
    
///  convert backslashes to slashes
     void  ConvertBackslashes();
    
///  remove extension
     void  StripExtension();
    
///  extract the part after the last directory separator
    hgeString ExtractFileName()  const ;
    
///  extract the last directory of the path
    hgeString ExtractLastDirName()  const ;
    
///  extract the part before the last directory separator
    hgeString ExtractDirName()  const ;
    
///  extract path until last slash
    hgeString ExtractToLastSlash()  const ;
    
///  format string printf-style
     void  __cdecl Format( const   char *  fmtString, ...);
            
// __attribute__((format(printf,2,3)));
     ///  format string printf-style, taking a va_list
     void  FormatWithArgs( const   char *  fmtString, va_list args);
    
///  replace illegal filename characters
     void  ReplaceIllegalFilenameChars( char  replacement);
    
///  return true if string only contains characters from charSet argument
     bool  CheckValidCharSet( const  hgeString &  charSet)  const ;
    
///  replace characters within a string
     void  ReplaceChars( const   char *  charSet,  char  replacement);
    
///  construct a string from an int
     static  hgeString FromInt( int  i);
    
///  construct a string from a float
     static  hgeString FromFloat( float  f);
    
///  construct a string from a bool
     static  hgeString FromBool( bool  b);

protected :
    
///  copy contents
     void  Copy( const  hgeString &  src);
    
///  delete contents
     void  Delete();
    
///  get pointer to last directory separator
     char *  GetLastSlash()  const ;
    
///  Set the length, accounting for the union.
     void  SetLength(size_t);

    
enum
    {
        LOCALSTRINGSIZE 
=   14 ,
    };
    
char *   string ;
    union
    {
        
struct
        {
            
char  localString[LOCALSTRINGSIZE];
            unsigned 
short  localStrLen;
        };
        unsigned 
int  strLen;
    };
};

// ------------------------------------------------------------------------------
/*
*
*/
inline
hgeString::hgeString() :
    
string ( 0 ),
    strLen(
0 ),
    localStrLen(
0 )
{
}

// ------------------------------------------------------------------------------
/*
*
*/
inline
void
hgeString::Delete()
{
    
if  ( this -> string )
    {
        delete []
this -> string ;
        
this -> string   =   0 ;
    }
    
this -> localString[ 0 =   0 ;
    
this -> localStrLen  =   0 ;
}

// ------------------------------------------------------------------------------
/*
*
*/
inline
hgeString::
~ hgeString()
{
    
this -> Delete();
}

// ------------------------------------------------------------------------------
/*
*
*/
inline
void
hgeString::Set(
const   char *  str,  int  length)
{
    
this -> Delete();
    
if  (str)
    {
        
if  (length  >=  LOCALSTRINGSIZE)
        {
            
this -> string   =   new   char [length  +   1 ];
            memcpy(
this -> string , str, length);
            
this -> string [length]  =   0 ;
            
this -> strLen  =  length;
        }
        
else
        {
            memcpy(
this -> localString, str, length);
            
this -> localString[length]  =   0 ;
            
this -> localStrLen  =  (unsigned  short )length;
        }
    }
}

// ------------------------------------------------------------------------------
/*
*
*/
inline
void
hgeString::Set(
const   char *  str)
{
    
int  len  =   0 ;
    
if  (str)
    {
        len 
=  ( int ) strlen(str);
    }
    
this -> Set(str, len);
}

// ------------------------------------------------------------------------------
/*
*
*/
inline
void
hgeString::SetInt(
int  val)
{
    
this -> Format( " %d " , val);
}

// ------------------------------------------------------------------------------
/*
*
*/
inline
void
hgeString::SetFloat(
float  val)
{
    
this -> Format( " %.6f " , val);
}

// ------------------------------------------------------------------------------
/*
*
*/
inline
void
hgeString::SetBool(
bool  val)
{
    
if  (val)
    {
        
* this   =   " true " ;
    }
    
else
    {
        
* this   =   " false " ;
    }
}

// ------------------------------------------------------------------------------
/*
*
*/
inline
void
hgeString::Copy(
const  hgeString &  src)
{
    assert(
0   ==   this -> string );
    
const   char *  str  =  src.Get();
    
if  (str)
    {
        
this -> Set(str);
    }
}

// ------------------------------------------------------------------------------
/*
*
*/
inline
hgeString::hgeString(
const   char *  str) :
    
string ( 0 ),
    strLen(
0 ),
    localStrLen(
0 )
{
    
this -> Set(str);
}

// ------------------------------------------------------------------------------
/*
*
*/
inline
hgeString::hgeString(
const  hgeString &  rhs) :
    
string ( 0 ),
    strLen(
0 )
{
    
this -> localString[ 0 =   0 ;
    
this -> Copy(rhs);
}

// ------------------------------------------------------------------------------
/*
*
*/
inline
const   char *
hgeString::Get() 
const
{
    
if  ( this -> string )
    {
        
return   this -> string ;
    }
    
if  ( this -> localString[ 0 ])
    {
        
return   this -> localString;
    }
    
return   "" ;
}

// ------------------------------------------------------------------------------
/*
*
*/
inline
hgeString
&
hgeString::
operator = ( const  hgeString &  rhs)
{
    
if  ( & rhs  !=   this )
    {
        
this -> Delete();
        
this -> Copy(rhs);
    }
    
return   * this ;
}

// ------------------------------------------------------------------------------
/*
*
*/
inline
hgeString
&
hgeString::
operator = ( const   char *  rhs)
{
    
if  (rhs  !=   this -> Get())
    {
        
this -> Set(rhs);
    }
    
return   * this ;
}

// ------------------------------------------------------------------------------
/*
*
*/
inline
void
hgeString::AppendRange(
const   char *  str, unsigned  int  numChars)
{
    assert(str);
    
if  (numChars  >   0 )
    {
        unsigned 
int  rlen  =  numChars;
        unsigned 
int  tlen  =   this -> Length()  +  rlen;
        
if  ( this -> string )
        {
            
char *  ptr  =   new   char [tlen  +   1 ];
            strcpy(ptr, 
this -> string );
            strncat(ptr, str, numChars);
            delete []
this -> string ;
            
this -> string   =  ptr;
            
this -> strLen  =  tlen;
        }
        
else   if  ( this -> localString[ 0 ])
        {
            
if  (tlen  >=  LOCALSTRINGSIZE)
            {
                
char *  ptr  =   new   char [tlen  +   1 ];
                strcpy(ptr, 
this -> localString);
                strncat(ptr, str, numChars);
                
this -> localString[ 0 =   0 ;
                
this -> string   =  ptr;
                
this -> strLen  =  tlen;
            }
            
else
            {
                strncat(
this -> localString, str, numChars);
                
this -> localStrLen  =  (unsigned  short )tlen;
            }
        }
        
else
        {
            
this -> Set(str, numChars);
        }
    }
}

// ------------------------------------------------------------------------------
/*
*
*/
inline
void
hgeString::Append(
const   char *  str)
{
    assert(str);
    unsigned 
int  rlen  =  (unsigned  int )strlen(str);
    
this -> AppendRange(str, rlen);
}

// ------------------------------------------------------------------------------
/*
*
*/
inline
void
hgeString::Append(
const  hgeString &  str)
{
    
this -> Append(str.Get());
}

// ------------------------------------------------------------------------------
/*
*
*/
inline
void
hgeString::AppendInt(
int  val)
{
    hgeString str;
    str.SetInt(val);
    
this -> Append(str);
}

// ------------------------------------------------------------------------------
/*
*
*/
inline
void
hgeString::AppendFloat(
float  val)
{
    hgeString str;
    str.SetFloat(val);
    
this -> Append(str);
}

// ------------------------------------------------------------------------------
/*
*
*/
inline
hgeString
&
hgeString::
operator += ( const   char *  rhs)
{
    
this -> Append(rhs);
    
return   * this ;
}

// ------------------------------------------------------------------------------
/*
*
*/
inline
hgeString
&
hgeString::
operator += ( const  hgeString &  rhs)
{
    
this -> Append(rhs.Get());
    
return   * this ;
}

// ------------------------------------------------------------------------------
/*
*
*/
inline
bool
operator   ==  ( const  hgeString &  a,  const  hgeString &  b)
{
    
return  strcmp(a.Get(), b.Get())  ==   0 ;
}

// ------------------------------------------------------------------------------
/*
*
*/
inline
bool
operator   !=  ( const  hgeString &  a,  const  hgeString &  b)
{
    
return  strcmp(a.Get(), b.Get())  !=   0 ;
}

// ------------------------------------------------------------------------------
/*
*
*/
inline
bool
operator   <  ( const  hgeString &  a,  const  hgeString &  b)
{
    
return  strcmp(a.Get(), b.Get())  <   0 ;
}

// ------------------------------------------------------------------------------
/*
*
*/
inline
bool
operator   >  ( const  hgeString &  a,  const  hgeString &  b)
{
    
return  strcmp(a.Get(), b.Get())  >   0 ;
}

// ------------------------------------------------------------------------------
/*
*
*/
inline
bool
operator   <=  ( const  hgeString &  a,  const  hgeString &  b)
{
    
return  strcmp(a.Get(), b.Get())  <=   0 ;
}

// ------------------------------------------------------------------------------
/*
*
*/
inline
bool
operator   >=  ( const  hgeString &  a,  const  hgeString &  b)
{
    
return  strcmp(a.Get(), b.Get())  >=   0 ;
}

// ------------------------------------------------------------------------------
/*
*
     - 21-Sep-04    Johannes        the '/0' is a valid part of the string
*/
inline
char
hgeString::
operator []( int  i)  const
{
    assert(
0   <=  i  &&  i  <=   this -> Length());
    
if  ( this -> string   !=   0 )
    {
        
return   this -> string [i];
    }
    
return   this -> localString[i];
}

// ------------------------------------------------------------------------------
/*
*
     - 21-Sep-04    Johannes        the '/0' is a valid part of the string
*/
inline
char &
hgeString::
operator []( int  i)
{
    assert(
0   <=  i  &&  i  <=   this -> Length());
    
if  ( this -> string   !=   0 )
    {
        
return   this -> string [i];
    }
    
else
    {
        
return   this -> localString[i];
    }
}

// ------------------------------------------------------------------------------
/*
*
*/
inline
int
hgeString::Length() 
const
{
    
if  ( this -> string   !=   0 )
    {
        
return   this -> strLen;
    }
    
return   this -> localStrLen;
}

// ------------------------------------------------------------------------------
/*
*
*/
inline
void
hgeString::Clear()
{
    
this -> Delete();
}

// ------------------------------------------------------------------------------
/*
*
*/
inline
bool
hgeString::IsEmpty() 
const
{
    
if  ( this -> string   &&  ( this -> string [ 0 !=   0 ))
    {
        
return   false ;
    }
    
if  ( this -> localString[ 0 !=   0 )
    {
        
return   false ;
    }
    
return   true ;
}

// ------------------------------------------------------------------------------
/*
*
*/
inline
bool
hgeString::IsValid() 
const
{
    
return   ! this -> IsEmpty();
}

// ------------------------------------------------------------------------------
/*
*
*/
inline
void
hgeString::ToLower()
{
    
char *  str  =  ( char * )( this -> string   ?   this -> string  :  this -> localString);
    
if  (str)
    {
        
char  c;
        
char *  ptr  =  ( char * )str;
        
while  ((c  =   * ptr))
        {
            
* ptr ++   =  tolower(c);
        }
    }
}

// ------------------------------------------------------------------------------
/*
*
*/
inline
void
hgeString::ToUpper()
{
    
char *  str  =  ( char * )( this -> string   ?   this -> string  :  this -> localString);
    
if  (str)
    {
        
char  c;
        
char *  ptr  =  ( char * )str;
        
while  ((c  =   * ptr))
        {
            
* ptr ++   =  toupper(c);
        }
    }
}

// ------------------------------------------------------------------------------
/*
*
*/
static
inline
hgeString
operator + ( const  hgeString &  s0,  const  hgeString &  s1)
{
    hgeString newString 
=  s0;
    newString.Append(s1.Get());
    
return  newString;
}

// ------------------------------------------------------------------------------
/*
*
    Get the first token in the string, delimited by one or more of the
    character in 'whiteSpace'. This simply invokes the strtok() function
    internally, and will destroy the contained string. After calling
    GetFirstToken(), invoke GetNextToken() until 0 returns.

    ATTENTION: if somebody else calls strtok() while GetFirstToken()/
    GetNextToken() is underway, everything will break apart!
    Check out the Tokenize() method for a better alternative.

    @param  whiteSpace  string containing white space characters
*/
inline
const   char *
hgeString::GetFirstToken(
const   char *  whiteSpace)
{
    assert(whiteSpace);
    
return  strtok(( char * ) this -> Get(), whiteSpace);
}

// ------------------------------------------------------------------------------
/*
*
    Get the next token in the string. Call this after a GetFirstToken()
    or GetNextToken(). Returns 0 if no more tokens in string. This method
    will destroy the original string.

    ATTENTION: if somebody else calls strtok() while GetFirstToken()/
    GetNextToken() is underway, everything will break apart!
    Check out the Tokenize() method for a better alternative.

    @param  whiteSpace  string containing whitespace characters
*/
inline
const   char *
hgeString::GetNextToken(
const   char *  whiteSpace)
{
    assert(whiteSpace);
    
return  strtok( 0 , whiteSpace);
}

// ------------------------------------------------------------------------------
/*
*
    Extract sub string.
*/
inline
hgeString
hgeString::ExtractRange(
int  from,  int  numChars)  const
{
    assert(from 
<=   this -> Length());
    assert(from 
+  numChars  <=   this -> Length());
    
const   char *  str  =   this -> Get();
    hgeString newString;
    newString.Set(
& (str[from]), numChars);
    
return  newString;
}

// ------------------------------------------------------------------------------
/*
*
    Terminates the string at the first occurrence of one of the characters
    in charSet.
*/
inline
void
hgeString::Strip(
const   char *  charSet)
{
    assert(charSet);
    
char *  str  =  ( char * ) this -> Get();
    
char *  ptr  =  strpbrk(str, charSet);
    
if  (ptr)
    {
        
* ptr  =   0 ;
    }
    
this -> SetLength(strlen(str));

}

// ------------------------------------------------------------------------------
/*
*
    Returns true if string contains one of the characters from charset.
*/
inline
bool
hgeString::ContainsCharFromSet(
const   char *  charSet)  const
{
    assert(charSet);
    
char *  str  =  ( char * ) this -> Get();
    
char *  ptr  =  strpbrk(str, charSet);
    
return  ( 0   !=  ptr);
}

// ------------------------------------------------------------------------------
/*
*
    @result Index or -1 if not found.
*/
inline
int
hgeString::FindStringIndex(
const  hgeString &  v,  int  startIndex)  const
{
    assert(
0   <=  startIndex  &&  startIndex  <=  Length()  -   1 );
    assert(
! v.IsEmpty());

    
for  ( int  i  =  startIndex; i  <  Length(); i ++ )
    {
        
if  (Length()  -  i  <  v.Length())
        {
            
break ;
        }

        
if  (strncmp( & (Get()[i]), v.Get(), v.Length())  ==   0 )
        {
            
return  i;
        }
    }

    
return   - 1 ;
}

// ------------------------------------------------------------------------------
/*
*
    Return index of character in string, or -1 if not found.
*/
inline
int
hgeString::FindCharIndex(unsigned 
char  c,  int  startIndex)  const
{
    
if  ( this -> Length()  >   0 )
    {
        assert(startIndex 
<   this -> Length());
        
const   char *  ptr  =  strchr( this -> Get()  +  startIndex, c);
        
if  (ptr)
        {
            
return  ( int )(ptr  -   this -> Get());
        }
    }
    
return   - 1 ;
}

// ------------------------------------------------------------------------------
/*
*
    Terminates the string at the given index.
*/
inline
void
hgeString::TerminateAtIndex(
int  index)
{
    assert(index 
<   this -> Length());
    
char *  ptr  =  ( char * ) this -> Get();
    ptr[index] 
=   0 ;
    
this -> SetLength(strlen( this -> Get()));
}

// ------------------------------------------------------------------------------
/*
*
    Strips last slash, if the path name ends on a slash.
*/
inline
void
hgeString::StripTrailingSlash()
{
    
if  ( this -> Length()  >   0 )
    {
        
int  pos  =  Length()  -   1 ;
        
char *  str  =  ( char * ) this -> Get();
        
if  (str[pos]  ==   ' / '   ||  str[pos]  ==   ' / ' )
        {
            str[pos] 
=   0 ;
            
if  ( this -> string   !=   0 )
            {
                
this -> strLen -- ;
            }
            
else
            {
                
this -> localStrLen -- ;
            }
        }
        
this -> SetLength(strlen( this -> Get()));
    }
}

// ------------------------------------------------------------------------------
/*
*
    Returns a new string which is this string, stripped on the left side
    by all characters in the char set.
*/
inline
hgeString
hgeString::TrimLeft(
const   char *  charSet)  const
{
    assert(charSet);
    
if  ( this -> IsEmpty())
    {
        
return   * this ;
    }

    
int  charSetLen  =  ( int )strlen(charSet);
    
int  thisIndex  =   0 ;
    
bool  stopped  =   false ;
    
while  ( ! stopped  &&  (thisIndex  <   this -> Length()))
    {
        
int  charSetIndex;
        
bool  match  =   false ;
        
for  (charSetIndex  =   0 ; charSetIndex  <  charSetLen; charSetIndex ++ )
        {
            
if  (( * this )[thisIndex]  ==  charSet[charSetIndex])
            {
                
//  a match
                match  =   true ;
                
break ;
            }
        }
        
if  ( ! match)
        {
            
//  stop if no match
            stopped  =   true ;
        }
        
else
        {
            
//  a match, advance to next character
             ++ thisIndex;
        }
    }
    hgeString trimmedString(
& ( this -> Get()[thisIndex]));
    
return  trimmedString;
}

// ------------------------------------------------------------------------------
/*
*
    Returns a new string, which is this string, stripped on the right side
    by all characters in the char set.
*/
inline
hgeString
hgeString::TrimRight(
const   char *  charSet)  const
{
    assert(charSet);
    
if  ( this -> IsEmpty())
    {
        
return   * this ;
    }

    
int  charSetLen  =  ( int )strlen(charSet);
    
int  thisIndex  =   this -> Length()  -   1 ;
    
bool  stopped  =   false ;
    
while  ( ! stopped  &&  (thisIndex  <   this -> Length()))
    {
        
int  charSetIndex;
        
bool  match  =   false ;
        
for  (charSetIndex  =   0 ; charSetIndex  <  charSetLen; charSetIndex ++ )
        {
            
if  (( * this )[thisIndex]  ==  charSet[charSetIndex])
            {
                
//  a match
                match  =   true ;
                
break ;
            }
        }
        
if  ( ! match)
        {
            
//  stop if no match
            stopped  =   true ;
        }
        
else
        {
            
//  a match, advance to next character
             -- thisIndex;
        }
    }
    hgeString trimmedString;
    trimmedString.Set(
this -> Get(), thisIndex  +   1 );
    
return  trimmedString;
}

// ------------------------------------------------------------------------------
/*
*
    Trim both sides of a string.
*/
inline
hgeString
hgeString::Trim(
const   char *  charSet)  const
{
    
return   this -> TrimLeft(charSet).TrimRight(charSet);
}

// ------------------------------------------------------------------------------
/*
*
    Substitute every occurrence of origStr with substStr.
*/
inline
hgeString
hgeString::Substitute(
const   char *  matchStr,  const   char *  substStr)  const
{
    assert(matchStr 
&&  substStr);

    
const   char *  ptr  =   this -> Get();
    
int  matchStrLen  =  ( int )strlen(matchStr);
    hgeString dest;

    
//  walk original string for occurrences of str
     const   char *  occur;
    
while  ((occur  =  strstr(ptr, matchStr)))
    {
        
//  append string fragment until match
        dest.AppendRange(ptr, (unsigned  int )(occur  -  ptr));

        
//  append replacement string
        dest.Append(substStr);

        
//  adjust source pointer
        ptr  =  occur  +  matchStrLen;
    }
    dest.Append(ptr);
    
return  dest;
}

// ------------------------------------------------------------------------------
/*
*
    This converts an UTF-8 string to 8-bit-ANSI. Note that only characters
    in the range 0 .. 255 are converted, all other characters will be converted
    to a question mark.

    For conversion rules see 
http://www.cl.cam.ac.uk/ ~mgk25/unicode.html#utf-8
*/
inline
void
hgeString::UTF8toANSI()
{
    unsigned 
char *  src  =  (unsigned  char * ) this -> Get();
    unsigned 
char *  dst  =  src;
    unsigned 
char  c;
    
while  ((c  =   * src ++ ))
    {
        
if  (c  >=   0x80 )
        {
            
if  ((c  &   0xE0 ==   0xC0 )
            {
                
//  a 2 byte sequence with 11 bits of information
                unsigned  short  wide  =  ((c  &   0x1F <<   6 |  ( * src ++   &   0x3F );
                
if  (wide  >   0xff )
                {
                    c 
=   ' ? ' ;
                }
                
else
                {
                    c 
=  (unsigned  char ) wide;
                }
            }
            
else   if  ((c  &   0xF0 ==   0xE0 )
            {
                
//  a 3 byte sequence with 16 bits of information
                c  =   ' ? ' ;
                src 
+=   2 ;
            }
            
else   if  ((c  &   0xF8 ==   0xF0 )
            {
                
//  a 4 byte sequence with 21 bits of information
                c  =   ' ? ' ;
                src 
+=   3 ;
            }
            
else   if  ((c  &   0xFC ==   0xF8 )
            {
                
//  a 5 byte sequence with 26 bits of information
                c  =   ' ? ' ;
                src 
+=   4 ;
            }
            
else   if  ((c  &   0xFE ==   0xFC )
            {
                
//  a 6 byte sequence with 31 bits of information
                c  =   ' ? ' ;
                src 
+=   5 ;
            }
        }
        
* dst ++   =  c;
    }
    
* dst  =   0 ;
}

// ------------------------------------------------------------------------------
/*
*
    Convert contained ANSI string to UTF-8 in place.
*/
inline
void
hgeString::ANSItoUTF8()
{
    assert(
! this -> IsEmpty());
    
int  bufSize  =   this -> Length()  *   2   +   1 ;
    
char *  buffer  =   new   char [bufSize];
    
char *  dstPtr  =  buffer;
    
const   char *  srcPtr  =   this -> Get();
    unsigned 
char  c;
    
while  ((c  =   * srcPtr ++ ))
    {
        
//  note: this only covers the 2 cases that the character
        
//  is between 0 and 127 and between 128 and 255
         if  (c  <   128 )
        {
            
* dstPtr ++   =  c;
        }
        
else
        {
            
* dstPtr ++   =   192   +  (c  /   64 );
            
* dstPtr ++   =   128   +  (c  %   64 );
        }
    }
    
* dstPtr  =   0 ;
    
this -> Set(buffer);
    delete []buffer;
}

// ------------------------------------------------------------------------------
/*
*
    Replace character with another.
*/
inline
void
hgeString::SubstituteCharacter(
char  c,  char  subst)
{
    
char *  ptr  =  ( char * ) this -> Get();
    
int  i;
    
for  (i  =   0 ; i  <=   this -> Length(); i ++ )
    {
        
if  (ptr[i]  ==  c)
        {
            ptr[i] 
=  subst;
        }
    }
}

// ------------------------------------------------------------------------------
/*
*
    Converts backslashes to slashes.
*/
inline
void
hgeString::ConvertBackslashes()
{
    
this -> SubstituteCharacter( ' / ' ' / ' );
}

// ------------------------------------------------------------------------------
/*
*
    @return     pointer to extension (without the dot), or 0
*/
inline
const   char *
hgeString::GetExtension() 
const
{
    
const   char *  str  =   this -> Get();
    
const   char *  ext  =  strrchr(str,  ' . ' );
    
if  (ext)
    {
        ext
++ ;
        
if  (ext[ 0 !=   0 )
        {
            
return  ext;
        }
    }
    
return   0 ;
}

// ------------------------------------------------------------------------------
/*
*
    Returns true if file extension matches.

    @param  ext     extension string (without the dot)
    @return         true if extension matches
*/
inline
bool
hgeString::CheckExtension(
const   char *  ext)  const
{
    assert(ext);
    
const   char *  extStr  =   this -> GetExtension();
    
if  ( 0   ==  extStr)
    {
        
return   false ;
    }
    
return  ( 0   ==  (strcmp(ext, extStr)));
}

// ------------------------------------------------------------------------------
/*
*
    Remove the file extension.
*/
inline
void
hgeString::StripExtension()
{
    
char *  ext  =  ( char * ) this -> GetExtension();
    
if  (ext)
    {
        ext[
- 1 =   0 ;
    }
    
this -> SetLength(strlen( this -> Get()));
}

// ------------------------------------------------------------------------------
/*
*
    Get a pointer to the last directory separator.
*/
inline
char *
hgeString::GetLastSlash() 
const
{
    
char *  s  =  ( char * ) this -> Get();
    
char *  lastSlash  =  strrchr(s,  ' / ' );
    
if  ( 0   ==  lastSlash) lastSlash  =  strrchr(s,  ' / ' );
    
if  ( 0   ==  lastSlash) lastSlash  =  strrchr(s,  ' : ' );
    
return  lastSlash;
}

// ------------------------------------------------------------------------------
/*
*
    Return a hgeString object containing the part after the last
    path separator.
*/
inline
hgeString
hgeString::ExtractFileName() 
const
{
    hgeString pathString;
    
char *  lastSlash  =   this -> GetLastSlash();
    
if  (lastSlash)
    {
        pathString 
=   & (lastSlash[ 1 ]);
    }
    
else
    {
        pathString 
=   this -> Get();
    }
    
return  pathString;
}

// ------------------------------------------------------------------------------
/*
*
    Return a hgeString object containing the last directory of the path, i.e.
    a category.

    - 17-Feb-04     floh    fixed a bug when the path ended with a slash
*/
inline
hgeString
hgeString::ExtractLastDirName() 
const
{
    hgeString pathString(
* this );
    
char *  lastSlash  =  pathString.GetLastSlash();

    
//  special case if path ends with a slash
     if  (lastSlash)
    {
        
if  ( 0   ==  lastSlash[ 1 ])
        {
            
* lastSlash  =   0 ;
            lastSlash 
=  pathString.GetLastSlash();
        }

        
char *  secLastSlash  =   0 ;
        
if  ( 0   !=  lastSlash)
        {
            
* lastSlash  =   0 //  cut filename
            secLastSlash  =  pathString.GetLastSlash();
            
if  (secLastSlash)
            {
                
* secLastSlash  =   0 ;
                
return  hgeString(secLastSlash + 1 );
            }
        }
    }
    
return   "" ;
}

// ------------------------------------------------------------------------------
/*
*
    Return a hgeString object containing the part before the last
    directory separator.

    NOTE: I left my fix in that returns the last slash (or colon), this was
    necessary to tell if a dirname is a normal directory or an assign.

    - 17-Feb-04     floh    fixed a bug when the path ended with a slash
*/
inline
hgeString
hgeString::ExtractDirName() 
const
{
    hgeString pathString(
* this );
    
char *  lastSlash  =  pathString.GetLastSlash();

    
//  special case if path ends with a slash
     if  (lastSlash)
    {
        
if  ( 0   ==  lastSlash[ 1 ])
        {
            
* lastSlash  =   0 ;
            lastSlash 
=  pathString.GetLastSlash();
        }
        
if  (lastSlash)
        {
            
*++ lastSlash  =   0 ;
        }
    }
    pathString.SetLength(strlen(pathString.Get()));
    
return  pathString;
}

// ------------------------------------------------------------------------------
/*
*
    Return a path string object which contains of the complete path
    up to the last slash. Returns an empty string if there is no
    slash in the path.
*/
inline
hgeString
hgeString::ExtractToLastSlash() 
const
{
    hgeString pathString(
* this );
    
char *  lastSlash  =  pathString.GetLastSlash();
    
if  (lastSlash)
    {
        lastSlash[
1 =   0 ;
    }
    
else
    {
        pathString 
=   "" ;
    }
    
return  pathString;
}

// ------------------------------------------------------------------------------
/*
*
*/
inline
void
hgeString::ReplaceChars(
const   char *  charSet,  char  replacement)
{
    assert(charSet);
    
char *  ptr  =  ( char * ) this -> Get();
    
char  c;
    
while  ( 0   !=  (c  =   * ptr))
    {
        
if  (strchr(charSet, c))
        {
            
* ptr  =  replacement;
        }
        ptr
++ ;
    }
}

// ------------------------------------------------------------------------------
/*
*
    Return true if the string only contains characters which are in the defined
    character set.
*/
inline
bool
hgeString::CheckValidCharSet(
const  hgeString &  charSet)  const
{
    
int  i;
    
int  len  =   this -> Length();
    
for  (i  =   0 ; i  <  len; i ++ )
    {
        
if  ( - 1   ==  charSet.FindCharIndex(( * this )[i],  0 ))
        {
            
return   false ;
        }
    }
    
return   true ;
}

// ------------------------------------------------------------------------------
/*
*
*/
inline
bool
hgeString::IsValidInt() 
const
{
    
return   this -> CheckValidCharSet( "   -+01234567890 " );
}

// ------------------------------------------------------------------------------
/*
*
    Note: this method is not 100% correct, it just checks for invalid characters.
*/
inline
bool
hgeString::IsValidFloat() 
const
{
    
return   this -> CheckValidCharSet( "   -+.e1234567890 " );
}

// ------------------------------------------------------------------------------
/*
*
*/
inline
bool
hgeString::IsValidBool() 
const
{
    
static   const   char *  bools[]  =  {
        
" no " " yes " " off " " on " " false " " true " 0
    };
    
int  i  =   0 ;
    
while  (bools[i]  !=   0 )
    {
        
if  ( 0   ==  stricmp(bools[i],  this -> Get()))
        {
            
return   true ;
        }
        i
++ ;
    }
    
return   false ;
}

// ------------------------------------------------------------------------------
/*
*
    Returns content as integer. Note: this method doesn't check whether the
    contents is actually a valid integer. Use the IsValidInteger() method
    for this!
*/
inline
int
hgeString::AsInt() 
const
{
    
return  atoi( this -> Get());
}

// ------------------------------------------------------------------------------
/*
*
    Returns content as float. Note: this method doesn't check whether the
    contents is actually a valid float. Use the IsValidInt() method
    for this!
*/
inline
float
hgeString::AsFloat() 
const
{
    
return   float (atof( this -> Get()));
}

// ------------------------------------------------------------------------------
/*
*
*/
inline
bool
hgeString::AsBool() 
const
{
    
static   const   char *  bools[]  =  {
        
" no " " yes " " off " " on " " false " " true " 0
    };
    
int  i  =   0 ;
    
while  (bools[i]  !=   0 )
    {
        
if  ( 0   ==  stricmp(bools[i],  this -> Get()))
        {
            
return   1   ==  (i  &   1 );
        }
        i
++ ;
    }
    
return   false ;
}

// ------------------------------------------------------------------------------
/*
*
*/
inline
void  __cdecl
hgeString::Format(
const   char *  fmtString, ...)
{
    va_list argList;
    va_start(argList, fmtString);
    
this -> FormatWithArgs(fmtString, argList);
    va_end(argList);
}

// ------------------------------------------------------------------------------
/*
*
*/
inline
void
hgeString::FormatWithArgs(
const   char *  fmtString, va_list args)
{
    va_list argList;

    
//  First calculate the required length
    argList  =  args;
    size_t requiredLength;

    requiredLength 
=  _vscprintf(fmtString, argList);

    requiredLength
++ //  Account for NULL termination
    va_end(argList);

    
//  Now we can allocate a buffer of the right length
     char *  buf  =  ( char * )alloca(requiredLength);

    
//  Now do the formatting
    _vsnprintf(buf, requiredLength, fmtString, args);
    
this -> Set(buf);
}

// ------------------------------------------------------------------------------
/*
*
*/
inline
void
hgeString::SetLength(size_t length)
{
    
if  ( this -> string   !=   0 )
    {
        
this -> strLen  =  (unsigned  int )length;
    }
    
else
    {
        
this -> localStrLen  =  (unsigned  short )length;
    }
}

// ------------------------------------------------------------------------------
/*
*
*/
inline
void
hgeString::ReplaceIllegalFilenameChars(
char  replacement)
{
    
this -> ReplaceChars( " //:*?"<>| " , replacement);
}

// ------------------------------------------------------------------------------
/*
*
*/
inline
hgeString
hgeString::FromInt(
int  i)
{
    hgeString str;
    str.SetInt(i);
    
return  str;
}

// ------------------------------------------------------------------------------
/*
*
*/
inline
hgeString
hgeString::FromFloat(
float  f)
{
    hgeString str;
    str.SetFloat(f);
    
return  str;
}

// ------------------------------------------------------------------------------
/*
*
*/
inline
hgeString
hgeString::FromBool(
bool  b)
{
    hgeString str;
    str.SetBool(b);
    
return  str;
}
#pragma  once

//  修改来自于nebula2引擎,代码原作属于nebula2.

代码有点长.

你可能感兴趣的:(HGE)