让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).
     charoperator[]( 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,
    };
     charstring;
    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.

代码有点长.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值