/* ====================================================================
* Copyright (c) 2003-2006, Martin Hauner
* http://subcommander.tigris.org
*
* Subcommander is licensed as described in the file doc/COPYING, which
* you should have received as part of this distribution.
* ====================================================================
*/
// sc
#include "String.h"
#include "utf8.h"
// sys
#include <string.h>
#include <stdlib.h>
#define max(a, b) (((a) > (b)) ? (a) : (b))
#define min(a, b) (((a) < (b)) ? (a) : (b))
namespace sc
{
String::String()
: _str(0), _chars(0), _bytes(0)
{
}
String::String( const String& src )
: _str(0), _chars(0), _bytes(0)
{
*this = src;
}
String::String( const char* str )
: _str(0), _chars(0), _bytes(0)
{
_copy(str);
_bytes = _strbytes(str);
_chars = utf8::strlen8(str,_bytes);
}
String::String( const char* str, Size bytes )
: _str(0), _chars(0), _bytes(0)
{
_ncopy(str,bytes);
_bytes = bytes;
_chars = utf8::strlen8(str,bytes);
}
String::~String()
{
_free(_str);
}
String::operator const char*() const
{
return _str;
}
void String::operator=( const String& in )
{
_ncopy( in._str, in._bytes );
_chars = in._chars;
_bytes = in._bytes;
}
void String::operator=( const char* in )
{
_copy(in);
_bytes = _strbytes(in);
_chars = utf8::strlen8(in,_bytes);
}
const char* String::getStr() const
{
return _str;
}
size_t String::getCharCnt() const
{
return _chars;
}
size_t String::getByteCnt() const
{
return _bytes;
}
bool String::isEmpty() const
{
return getCharCnt() == 0;
}
String& String::operator+=( const String& in )
{
_append( in._str );
_chars += in._chars;
_bytes += in._bytes;
return *this;
}
String& String::operator+=( const char* in )
{
return *this += String(in);
}
bool String::operator<( const String &src ) const
{
return _cmp(src._str) < 0;
}
bool String::operator==( const String &src ) const
{
return _cmp(src._str) == 0;
}
bool String::operator!=( const String &src ) const
{
return _cmp(src._str) != 0;
}
String String::left( Size chars ) const
{
char* cur = utf8::next8( _str, min(chars,_chars) );
Size bytes = cur - _str;
char* buf = _malloc( bytes+1 );
_strncpy( buf, _str, bytes );
String left( buf, bytes ); // bytes without 0
_free(buf);
return left;
}
String String::right( Size chars ) const
{
char* cur = utf8::prev8( _str+_bytes, _str, min(chars,_chars) );
Size bytes = _str + _bytes - cur;
Size start = _bytes - bytes;
return String( _str+start, _bytes-start ); // bytes without 0
}
String String::mid( Size first, Size chars ) const
{
return right( _chars-first ).left(chars);
}
int String::_cmp( const char* src ) const
{
if( _bytes == 0 )
{
if( _strbytes(src) == 0 )
return 0;
else
return -1;
}
else
{
if( _strbytes(src) == 0 )
return 1;
else
return strcmp(_str, src);
}
}
void String::_copy( const char *szSrc )
{
Size length = _strbytes(szSrc);
char* szDest = _malloc( length + 1 /* 0 byte */ );
_strcpy( szDest, szSrc );
_replace( szDest );
}
void String::_ncopy( const char *szSrc, Size length )
{
char *szDest = _malloc( length + 1 /* 0 byte */ );
_strncpy( szDest, szSrc, length );
_replace( szDest );
}
char* String::_strcpy( char *szDest, const char *szSrc ) const
{
if( szDest == 0 || szSrc == 0 )
{
return szDest;
}
return ::strcpy(szDest,szSrc);
}
char* String::_strncpy( char *szDest, const char *szSrc, Size length ) const
{
if( szDest == 0 || szSrc == 0 )
{
return szDest;
}
::strncpy( szDest, szSrc, length );
szDest[length] = 0;
return szDest;
}
void String::_append( const char *src )
{
char* tmp = _malloc( _bytes + _strbytes(src) + 1 );
_strcat( tmp, _str );
_strcat( tmp, src );
_replace( tmp );
}
char* String::_strcat( char *dest, const char* src ) const
{
if( dest == 0 || src == 0 )
{
return const_cast<char*>(src);
}
return ::strcat(dest,src);
}
void String::_replace( const char *szSrc )
{
_free( _str );
_str = const_cast<char*>(szSrc);
}
Size String::_strbytes( const char *szIn ) const
{
if( ! szIn )
{
return 0;
}
return ::strlen(szIn);
}
char* String::_malloc( Size nbytes ) const
{
// don't allocate memory for a negative size or
// one of 0 or 1 byte, 1 is a "" string
if( nbytes <= 1 )
{
return 0;
}
char *ptr = (char*)::malloc( nbytes );
*ptr = 0;
return ptr;
}
void String::_free( char *ptr ) const
{
if( ptr )
{
::free( ptr );
}
}
} // namespace
#if 0
void CCharString::_init()
{
_str = 0;
if( ! _mem )
{
SetDefaultMalloc();
}
}
void CCharString::_owner( char *szSrc )
{
char *buf = 0;
if( szSrc && _strlen(szSrc) == 0 )
{
_free(szSrc);
}
else
{
buf = szSrc;
}
_replace(buf);
}
void CCharString::_append( const char *szSrc )
{
_str = _realloc( _str, _strlen() + _strlen(szSrc) + 1 );
_strcat( _str, szSrc );
}
int CCharString::_cmp( const char* szSrc ) const
{
if(_strlen() == 0)
{
if(_strlen(szSrc) == 0)
return 0;
else
return -1;
}
else
{
if(_strlen(szSrc) == 0)
return 1;
else
return strcmp(_str, szSrc);
}
}
size_t CCharString::_strlen() const
{
return _strlen(_str);
}
size_t CCharString::_strlen( const char *szIn ) const
{
if( ! szIn )
{
return 0;
}
return ::strlen(szIn);
}
char *CCharString::_strcpy( char *szDest, const char *szSrc ) const
{
if( szDest == 0 || szSrc == 0 )
{
return szDest;
}
return ::strcpy(szDest,szSrc);
}
char *CCharString::_strncpy( char *szDest, const char *szSrc, size_t length ) const
{
if( szDest == 0 || szSrc == 0 )
{
return szDest;
}
::strncpy( szDest, szSrc, length );
szDest[length] = 0;
return szDest;
}
char *CCharString::_strcat( char *szDest, const char *szSrc ) const
{
if( szDest == 0 || szSrc == 0 )
{
return szDest;
}
return ::strcat(szDest,szSrc);
}
bool CCharString::_iswhite( const char cIn ) const
{
if( cIn == 0x20 || (cIn >= 0x09 && cIn <= 0x0d) )
{
return true;
}
return false;
}
#endif
/*
String dupString( apr_pool_t* pool, const String& src )
{
char* dup = apr_pstrmemdup( pool, src.getStr(), src.getBytes() );
return String( dup, src.getBytes() );
}
*/
syntax highlighted by Code2HTML, v. 0.9.1