From: <cn...@us...> - 2008-12-30 21:25:12
|
Revision: 107 http://hgengine.svn.sourceforge.net/hgengine/?rev=107&view=rev Author: cnlohr Date: 2008-12-30 21:25:06 +0000 (Tue, 30 Dec 2008) Log Message: ----------- add MercuryString Added Paths: ----------- Mercury2/src/MercuryString.cpp Mercury2/src/MercuryString.h Added: Mercury2/src/MercuryString.cpp =================================================================== --- Mercury2/src/MercuryString.cpp (rev 0) +++ Mercury2/src/MercuryString.cpp 2008-12-30 21:25:06 UTC (rev 107) @@ -0,0 +1,453 @@ +#include "MercuryString.h" +#include <stdlib.h> +#include <string.h> + +//For ssprintf. +#include <stdarg.h> +#include <stdio.h> + +#define BASE_ALLOC 16 + +#define NEXT_ALLOC( x, y ) ( x + y + BASE_ALLOC ) + +#define MANAGE_ALLOC( y ) \ + if ( m_iLen + y + 1 > m_iAlloc ) \ + { \ + m_iAlloc = NEXT_ALLOC( m_iLen, y ); \ + m_sCur = (char*)realloc( m_sCur, m_iAlloc ); \ + } + +MString::MString() +{ + m_sCur = (char*)malloc( BASE_ALLOC ); + m_sCur[0] = '\0'; + m_iLen = 0; + m_iAlloc = BASE_ALLOC; +} + +MString::MString( int iPreAlloc ) +{ + m_sCur = (char*)malloc( iPreAlloc ); + m_sCur[0] = '\0'; + m_iLen = 0; + m_iAlloc = iPreAlloc; +} + +MString::MString( const char sIn ) +{ + m_iLen = 1; + m_iAlloc = 2; + m_sCur = (char*)malloc( m_iAlloc ); + m_sCur[0] = sIn; + m_sCur[1] = '\0'; +} + +MString::MString( const char * sIn ) +{ + m_iLen = strlen( sIn ); + m_iAlloc = m_iLen + 1; + m_sCur = (char*)malloc( m_iAlloc ); + memcpy( m_sCur, sIn, m_iAlloc ); +} + +MString::MString( const char * sIn, int iSize ) +{ + m_iLen = iSize; + m_iAlloc = m_iLen + 1; + m_sCur = (char*)malloc( m_iAlloc ); + memcpy( m_sCur, sIn, m_iLen ); + m_sCur[m_iLen] = '\0'; +} + +MString::MString( const MString & rhs ) +{ + m_iLen = rhs.m_iLen; + m_iAlloc = rhs.m_iAlloc; + m_sCur = (char*)malloc( m_iAlloc ); + memcpy( m_sCur, rhs.m_sCur, m_iLen ); + m_sCur[m_iLen] = '\0'; +} + +MString::~MString() +{ + free(m_sCur); +} + +const MString & MString::operator = ( const MString & rhs ) +{ + if (&rhs != this) + { + free (m_sCur); + m_iLen = rhs.m_iLen; + m_iAlloc = rhs.m_iAlloc; + m_sCur = (char*)malloc( m_iAlloc ); + memcpy( m_sCur, rhs.m_sCur, m_iLen ); + m_sCur[m_iLen] = '\0'; + } + return (*this); +} + +const MString & MString::operator = ( const char * rhs ) +{ + if (rhs != m_sCur) + { + free (m_sCur); + m_iLen = strlen( rhs ); + m_iAlloc = m_iLen + 1; + m_sCur = (char*)malloc( m_iAlloc ); + memcpy( m_sCur, rhs, m_iAlloc ); + } + return (*this); +} + +const MString MString::operator + ( const MString & rhs ) const +{ + int iNextMalloc = NEXT_ALLOC( m_iLen, rhs.m_iLen ); + MString ret( iNextMalloc ); + ret.m_iLen = m_iLen + rhs.m_iLen; + memcpy( ret.m_sCur, m_sCur, m_iLen ); + memcpy( ret.m_sCur + m_iLen, rhs.m_sCur, rhs.m_iLen ); + ret.m_sCur[ret.m_iLen] = '\0'; + return ret; +} + +const MString MString::operator + ( const char * rhs ) const +{ + if ( !rhs ) + return (*this); + int iRhsLen = strlen( rhs ); + int iNextMalloc = NEXT_ALLOC( m_iLen, iRhsLen ); + MString ret( iNextMalloc ); + ret.m_iLen = m_iLen + iRhsLen; + memcpy( ret.m_sCur, m_sCur, m_iLen ); + memcpy( ret.m_sCur + m_iLen, rhs, iRhsLen ); + ret.m_sCur[ret.m_iLen] = '\0'; + return ret; +} + +const MString MString::operator + ( const char rhs ) const +{ + int iNextMalloc = NEXT_ALLOC( m_iLen, 1 ); + MString ret( iNextMalloc ); + ret.m_iLen = m_iLen + 1; + memcpy( ret.m_sCur, m_sCur, m_iLen ); + ret.m_sCur[ret.m_iLen - 1] = rhs; + ret.m_sCur[ret.m_iLen] = '\0'; + return ret; +} + +const MString & MString::operator += ( const char * rhs ) +{ + int iRhsLen = strlen( rhs ); + MANAGE_ALLOC( iRhsLen ) + memcpy( m_sCur + m_iLen, rhs, iRhsLen ); + m_iLen += iRhsLen; + m_sCur[m_iLen] = '\0'; + return (*this); +} + +const MString & MString::operator += ( const MString & rhs ) +{ + MANAGE_ALLOC( rhs.m_iLen ) + memcpy( m_sCur + m_iLen, rhs.m_sCur, rhs.m_iLen ); + m_iLen += rhs.m_iLen; + m_sCur[m_iLen] = '\0'; + return (*this); +} + +const MString & MString::operator += ( const char rhs ) +{ + MANAGE_ALLOC( 1 ) + m_sCur[m_iLen] = rhs; + m_iLen++; + m_sCur[m_iLen] = '\0'; + return (*this); +} + +bool MString::operator == ( const MString & rhs ) +{ + return strcmp( m_sCur, rhs.m_sCur ) == 0; +} + +bool MString::operator == ( const char * rhs ) +{ + return strcmp( m_sCur, rhs ) == 0; +} + +bool MString::operator < ( const MString & rhs ) +{ + return strcmp( m_sCur, rhs.m_sCur ) < 0; +} + +bool MString::operator > ( const MString & rhs ) +{ + return strcmp( m_sCur, rhs.m_sCur ) > 0; +} + +void MString::append( const MString & app ) +{ + MANAGE_ALLOC( app.m_iLen ) + memcpy( m_sCur + m_iLen, app.m_sCur, app.m_iLen ); + m_iLen += app.m_iLen; + m_sCur[m_iLen] = '\0'; +} + +void MString::append( const char app ) +{ + MANAGE_ALLOC( 1 ) + m_sCur[m_iLen] = app; + m_iLen++; + m_sCur[m_iLen] = '\0'; +} + +void MString::append( const char * app ) +{ + int iRhsLen = strlen( app ); + MANAGE_ALLOC( iRhsLen ) + memcpy( m_sCur + m_iLen, app, iRhsLen ); + m_iLen += iRhsLen; + m_sCur[m_iLen] = '\0'; +} + +void MString::append( const char * app, int len ) +{ + MANAGE_ALLOC( len ) + memcpy( m_sCur + m_iLen, app, len ); + m_iLen += len; + m_sCur[m_iLen] = '\0'; +} + +void MString::append( const char app, int len ) +{ + MANAGE_ALLOC( len ) + memset( m_sCur + m_iLen, app, len ); + m_iLen += len; + m_sCur[m_iLen] = '\0'; +} + +void MString::assign( const MString & app ) +{ + free( m_sCur ); + m_iLen = app.m_iLen; + m_iAlloc = app.m_iAlloc; + m_sCur = (char*)malloc( m_iAlloc ); + memcpy( m_sCur, app.m_sCur, m_iLen ); + m_sCur[m_iLen] = '\0'; +} + +void MString::assign( const char * app ) +{ + free( m_sCur ); + m_iLen = strlen( app ); + m_iAlloc = m_iLen + 1; + m_sCur = (char*)malloc( m_iAlloc ); + memcpy( m_sCur, app, m_iAlloc ); +} + +void MString::assign( const char * app, int len ) +{ + free( m_sCur ); + m_iLen = len; + m_iAlloc = m_iLen + 1; + m_sCur = (char*)malloc( m_iAlloc ); + memcpy( m_sCur, app, m_iLen ); + m_sCur[m_iLen] = '\0'; +} + +int MString::find( const MString & tofind, int start ) const +{ + const char * ret = strstr( m_sCur + start, tofind.m_sCur ); + return (ret)?(ret-m_sCur):npos; +} + +int MString::rfind( const MString & tofind ) const +{ + int iLen = tofind.length(); + int iTarg = m_iLen - iLen; + + while ( iTarg >= 0 ) + { + if ( strncmp( tofind.m_sCur+iTarg, tofind, iLen ) == 0 ) + return iTarg; + iTarg--; + } + return npos; +} + +int MString::find( const char * tofind, int start ) const +{ + const char * ret = strstr( m_sCur + start, tofind ); + return (ret)?(ret-m_sCur):npos; +} + +int MString::rfind( const char * tofind ) const +{ + int iLen = strlen( tofind ); + int iTarg = m_iLen - iLen; + + while ( iTarg >= 0 ) + { + if ( strncmp( m_sCur+iTarg, tofind, iLen ) == 0 ) + return iTarg; + iTarg--; + } + return npos; +} + +int MString::find( const char tofind, int start ) const +{ + const char * ret = strchr( m_sCur + start, tofind ); + return (ret)?(ret-m_sCur):npos; +} + +int MString::rfind( const char tofind ) const +{ + const char * ret = strrchr( m_sCur, tofind ); + return (ret)?(ret-m_sCur):npos; +} + +const MString MString::substr( int iStart ) const +{ + return MString( m_sCur + iStart, m_iLen - iStart ); +} + +const MString MString::substr( int iStart, int iLength ) const +{ + return MString( m_sCur + iStart, iLength ); +} + +int MString::compare( const MString & cmp ) const +{ + return strcmp( m_sCur, cmp.m_sCur ); +} + +int MString::compare( const char * cmp ) const +{ + return strcmp( m_sCur, cmp ); +} + +int MString::compare( int start, int len, const MString & cmp ) const +{ + return strncmp( m_sCur + start, cmp.m_sCur, len ); +} + +int MString::compare( int start, int len, const char * cmp ) const +{ + return strncmp( m_sCur + start, cmp, len ); +} + +unsigned int MString::hash() const +{ + unsigned int ret = 0; + unsigned int i; + unsigned int j = size()>>2; + for( i = 0; i < j; i++ ) + ret += ((unsigned int *)m_sCur)[i]; + + for( i = j<<2; i < size(); i++ ) + ret += (unsigned int)(unsigned char)m_sCur[i]; + + return ret; +} + +void MString::resize( unsigned int size ) +{ + if( size <= m_iLen ) + { + m_iLen = size; + m_sCur[size] = '\0'; + } else + { + MANAGE_ALLOC( size ) + } +} + +bool operator < ( const MString & lhs, const MString & rhs ) +{ + return strcmp( lhs.m_sCur, rhs.m_sCur ) < 0; +} + +bool operator > ( const MString & lhs, const MString & rhs ) +{ + return strcmp( lhs.m_sCur, rhs.m_sCur ) > 0; +} + +//YUCK! This cannot be a friend function becuse of VC6 internal compiler error! +MString operator + ( const char * lhs, const MString & rhs ) +{ + return MString( lhs ) + rhs; +} + +MString operator + ( const char lhs, const MString & rhs ) +{ + return MString( lhs ) + rhs; +} + +#define FMT_BLOCK_SIZE 127 + +MString ssprintf( const char *fmt, ...) +{ + if ( strlen(fmt)==0 ) + return MString(""); + + + int CurMal = FMT_BLOCK_SIZE; + MString ret; + + while ( true ) + { + va_list va; + va_start(va, fmt); + char * base = (char*)malloc( CurMal + 1 ); + #if defined(WIN32) + int len = _vsnprintf( base, CurMal, fmt, va ); + #else + int len = vsnprintf( base, CurMal, fmt, va ); + #endif + + va_end( va ); + + if (len > CurMal) + while (CurMal < len) + CurMal*=2; + else + if ( len > 0 ) + { + ret.assign( base, len ); + free( base ); + break; + } else + CurMal*=2; + + free(base); + } + return ret; +} + +/* + * Copyright (c) 2006,2008, Charles Lohr + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * - Neither the name of the Mercury Engine nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ Added: Mercury2/src/MercuryString.h =================================================================== --- Mercury2/src/MercuryString.h (rev 0) +++ Mercury2/src/MercuryString.h 2008-12-30 21:25:06 UTC (rev 107) @@ -0,0 +1,133 @@ +#ifndef _MERCURY_STRING_H +#define _MERCURY_STRING_H + +///Very fast String class +class MString +{ +public: + MString(); + MString( int iPreAlloc ); + MString( const char sIn ); + MString( const char * sIn ); + MString( const char * sIn, int iSize ); + MString( const MString & rhs ); + ~MString(); + + const MString & operator = ( const MString & rhs ); + const MString & operator = ( const char * rhs ); + const MString operator + ( const MString & rhs ) const; + const MString operator + ( const char * rhs ) const; + const MString operator + ( const char rhs ) const; + const MString & operator += ( const char * rhs ); + const MString & operator += ( const MString & rhs ); + const MString & operator += ( const char rhs ); + + bool operator == ( const MString & rhs ); + bool operator == ( const char * rhs ); + bool operator < ( const MString & rhs ); + bool operator > ( const MString & rhs ); + + operator const char * () const { return m_sCur; } + + inline const char * c_str() const { return m_sCur; } + inline unsigned long length() const { return m_iLen; } + inline unsigned long size() const { return m_iLen; } + inline bool empty() const { return m_iLen == 0; } + + void append( const MString & app ); + void append( const char app ); + void append( const char * app ); + void append( const char * app, int len ); + + ///Special: Append app len times + void append( const char app, int len ); + + void assign( const MString & app ); + void assign( const char * app ); + void assign( const char * app, int len ); + + int find( const MString & tofind, int start = 0 ) const; + int rfind( const MString & tofind ) const; + inline int find_last_of( const MString & tofind ) const { return rfind( tofind ); } + + int find( const char * tofind,int start = 0 ) const; + int find( const char tofind, int start = 0 ) const; + int rfind( const char * tofind ) const; + int rfind( const char tofind ) const; + inline int find_last_of( const char * tofind ) const { return rfind( tofind ); } + + const MString substr( int iStart ) const; + const MString substr( int iStart, int iLength ) const; + + int compare( const MString & cmp ) const; + int compare( const char * cmp ) const; + + int compare( int start, int len, const MString & cmp ) const; + int compare( int start, int len, const char * cmp ) const; + + unsigned int hash() const; + + enum + { + npos = -1 + }; + + void resize( unsigned int size ); +private: + char * m_sCur; + unsigned int m_iLen; + unsigned int m_iAlloc; + friend bool operator < ( const MString & lhs, const MString & rhs ); + friend bool operator > ( const MString & lhs, const MString & rhs ); +}; + +/* //Keep around incase we need to debug a little and use our old string +#include "StdString.h" +typedef StdString::CStdString MString; +*/ + +bool operator < ( const MString & lhs, const MString & rhs ); +bool operator > ( const MString & lhs, const MString & rhs ); +inline bool operator == ( const MString & lhs, const char * rhs ) { return lhs.compare( rhs ) == 0; } +inline bool operator != ( const MString & lhs, const char * rhs ) { return lhs.compare( rhs ) != 0; } + +MString operator + ( const char lhs, const MString & rhs ); +MString operator + ( const char * lhs, const MString & rhs ); + +#if defined(__GNUC__) +#define PRINTF(a,b) __attribute__((format(__printf__,a,b))) +#else +#define PRINTF(a,b) +#endif + +MString ssprintf( const char *fmt, ...) PRINTF(1,2); + +#endif + +/* + * Copyright (c) 2006,2008, Charles Lohr + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * - Neither the name of the Mercury Engine nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |