📄 string.cpp
字号:
#include <lang/String.h>
#include <lang/Globals.h>
#include <lang/MemoryPool.h>
#include <lang/UTFConverter.h>
#include "dprintf.h"
#include <ctype.h>
#include <stdint.h>
#include <string.h>
#include <assert.h>
#include <stdio.h>
#include <config.h>
namespace lang
{
static int allocateString( int len )
{
int handle = -1;
if ( len > 0 )
{
handle = Globals::get().stringPool.allocate( len+1 );
char* s = Globals::get().stringPool.get(handle);
s[0] = s[len] = 0;
}
return handle;
}
static int allocateString( const void* data, int bytes, const Converter& decoder )
{
// find out UTF-8 length
const uint8_t* databytes = reinterpret_cast<const uint8_t*>(data);
int len = 0;
UTFConverter encoder( UTFConverter::ENCODING_UTF8 );
char buf[32];
for ( int i = 0 ; i < bytes ; )
{
int decodedbytes = 1;
int cp;
if ( decoder.decode(databytes+i, databytes+bytes, &decodedbytes, &cp) )
{
i += decodedbytes;
int encodedbytes = 0;
encoder.encode( buf, buf+sizeof(buf), &encodedbytes, cp );
len += encodedbytes;
}
else
{
++i;
}
}
// alloc and set UTF-8 string
int strh = allocateString( len );
if ( len > 0 )
{
char* s = Globals::get().stringPool.get(strh);
int d = 0;
for ( int i = 0 ; i < bytes ; )
{
int decodedbytes = 1;
int cp;
if ( decoder.decode(databytes+i, databytes+bytes, &decodedbytes, &cp) )
{
i += decodedbytes;
int encodedbytes = 0;
encoder.encode( s+d, s+len, &encodedbytes, cp );
d += encodedbytes;
}
else
{
++i;
}
}
}
return strh;
}
String::String() :
m_h(-1)
{
}
String::String( const char* str ) :
m_h(-1)
{
TRACEF(1);
Globals::get().stringPool.compact();
TRACEF(1);
if ( str )
{
// DEBUG: print String ctor
//printf( "String('%s')\n", str );
TRACEF(1);
int len = strlen( str );
TRACEF(1);
if ( len > 0 )
{
TRACEF(1);
m_h = allocateString( len );
memcpy( Globals::get().stringPool.get(m_h), str, len );
}
}
TRACEF(1);
}
String::String( const void* data, int size, const Converter& decoder ) :
m_h( allocateString(data, size, decoder) )
{
}
String::String( const String& other ) :
m_h( other.m_h )
{
if ( other.m_h != -1 )
Globals::get().stringPool.ref( other.m_h );
}
String::~String()
{
if ( m_h != -1 )
Globals::get().stringPool.unref( m_h );
}
String& String::operator=( const String& other )
{
if ( other.m_h != -1 )
Globals::get().stringPool.ref( other.m_h );
if ( m_h != -1 )
Globals::get().stringPool.unref( m_h );
m_h = other.m_h;
return *this;
}
int String::length() const
{
return m_h != -1 ? strlen(Globals::get().stringPool.get(m_h)) : 0;
}
char String::charAt( int index ) const
{
assert( index >= 0 && index < length() );
char* s = Globals::get().stringPool.get(m_h);
return s[index];
}
void String::getChars( int begin, int end, char* dest ) const
{
assert( begin >= 0 && begin <= length() );
assert( begin >= 0 && begin <= end );
assert( end <= length() );
if ( end > begin )
{
char* s = Globals::get().stringPool.get(m_h);
memcpy( dest, s+begin, end-begin );
}
}
void String::get( char* buf, int bufsize ) const
{
assert( buf != 0 );
assert( bufsize > length() );
int len = 0;
if ( -1 != m_h )
{
char* s = Globals::get().stringPool.get(m_h);
int len = strlen(s);
if ( len >= bufsize )
len = bufsize-1;
memcpy( buf, s, len );
}
if ( bufsize > 0 )
buf[len] = 0;
}
const char* String::c_str() const
{
Globals& g = Globals::get();
const int BUFSIZE = sizeof(g.cstrBuffer)/sizeof(g.cstrBuffer[0]);
const char* sz = (m_h != -1 ? g.stringPool.get(m_h) : "");
int len = strlen(sz);
if ( len >= BUFSIZE )
len = BUFSIZE-1;
char* buf = g.cstrBuffer;
int& bufp = Globals::get().cstrBufferIndex;
if ( bufp+len >= BUFSIZE )
bufp = 0;
assert( bufp+len < BUFSIZE );
const int bufp0 = bufp;
bufp += len+1;
assert( bufp0 >= 0 && bufp0 < BUFSIZE );
assert( bufp0+len >= 0 && bufp0+len < BUFSIZE );
if ( len > 0 )
memcpy( buf+bufp0, sz, len );
buf[bufp0+len] = 0;
return buf+bufp0;
}
int String::indexOf( char ch, int index ) const
{
assert( index >= 0 && index < length() );
int thislen = length();
char* s = Globals::get().stringPool.get(m_h);
for ( ; index < thislen ; ++index )
{
if ( s[index] == ch )
return index;
}
return -1;
}
int String::compareTo( const String& other ) const
{
return strcmp(
m_h != -1 ? Globals::get().stringPool.get(m_h) : "",
other.m_h != -1 ? Globals::get().stringPool.get(other.m_h) : "" );
}
int String::compareTo( const char* other ) const
{
return strcmp( m_h != -1 ? Globals::get().stringPool.get(m_h) : "", other );
}
String String::operator+( const char* other ) const
{
return *this + String(other);
}
String String::operator+( const String& other ) const
{
int len1 = length();
int len2 = other.length();
int len = len1 + len2;
String s;
if ( len > 0 )
{
s.m_h = allocateString( len );
char* sz = Globals::get().stringPool.get(s.m_h);
if ( m_h != -1 )
memcpy( sz, Globals::get().stringPool.get(m_h), len1 );
if ( other.m_h != -1 )
memcpy( sz+len1, Globals::get().stringPool.get(other.m_h), len2 );
}
return s;
}
bool String::cpy( char* buf, int bufsize, const char* sz )
{
assert( bufsize > 0 );
int bufp = 0;
while ( 0 != *sz && bufp+1 < bufsize )
buf[bufp++] = *sz++;
assert( bufp < bufsize );
buf[bufp] = 0;
return *sz == 0;
}
bool String::cpy( char* buf, int bufsize, const String& str )
{
assert( bufsize > 0 );
if ( str.m_h != -1 )
return String::cpy( buf, bufsize, Globals::get().stringPool.get(str.m_h) );
else
buf[0] = 0;
return true;
}
} // lang
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -