dcdd144598 2011-02-23 kinaba: #include "stdafx.h" dcdd144598 2011-02-23 kinaba: #include "app.h" dcdd144598 2011-02-23 kinaba: #include "memory.h" dcdd144598 2011-02-23 kinaba: #include "string.h" dcdd144598 2011-02-23 kinaba: using namespace ki; dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: //========================================================================= dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: String::StringData* String::nullData_; dcdd144598 2011-02-23 kinaba: char String::lb_[256]; dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: void String::LibInit() dcdd144598 2011-02-23 kinaba: { dcdd144598 2011-02-23 kinaba: static int nullstr_image[4]; dcdd144598 2011-02-23 kinaba: nullstr_image[0] = 1; dcdd144598 2011-02-23 kinaba: nullstr_image[1] = 1; dcdd144598 2011-02-23 kinaba: nullstr_image[2] = 4; dcdd144598 2011-02-23 kinaba: nullData_ = reinterpret_cast<StringData*>(nullstr_image); dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: #if !defined(_UNICODE) && defined(_MBCS) dcdd144598 2011-02-23 kinaba: for( int c=0; c<256; ++c ) dcdd144598 2011-02-23 kinaba: lb_[c] = (::IsDBCSLeadByte(c) ? 2 : 1); dcdd144598 2011-02-23 kinaba: #endif dcdd144598 2011-02-23 kinaba: } dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: //------------------------------------------------------------------------- dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: String::String( const TCHAR* s, long len ) dcdd144598 2011-02-23 kinaba: { dcdd144598 2011-02-23 kinaba: // 長さ指定が無い場合は計算 dcdd144598 2011-02-23 kinaba: if( len==-1 ) dcdd144598 2011-02-23 kinaba: len = ::lstrlen(s); dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: if( len==0 ) dcdd144598 2011-02-23 kinaba: { dcdd144598 2011-02-23 kinaba: // 0文字用の特殊バッファ dcdd144598 2011-02-23 kinaba: SetData( null() ); dcdd144598 2011-02-23 kinaba: } dcdd144598 2011-02-23 kinaba: else dcdd144598 2011-02-23 kinaba: { dcdd144598 2011-02-23 kinaba: // 新規バッファ作成 dcdd144598 2011-02-23 kinaba: data_ = static_cast<StringData*> dcdd144598 2011-02-23 kinaba: (mem().Alloc( sizeof(StringData)+(len+1)*sizeof(TCHAR) )); dcdd144598 2011-02-23 kinaba: data_->ref = 1; dcdd144598 2011-02-23 kinaba: data_->len = len+1; dcdd144598 2011-02-23 kinaba: data_->alen = len+1; dcdd144598 2011-02-23 kinaba: memmove( data_+1, s, (len+1)*sizeof(TCHAR) ); dcdd144598 2011-02-23 kinaba: } dcdd144598 2011-02-23 kinaba: } dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: inline void String::ReleaseData() dcdd144598 2011-02-23 kinaba: { dcdd144598 2011-02-23 kinaba: if( --data_->ref <= 0 ) dcdd144598 2011-02-23 kinaba: mem().DeAlloc( dcdd144598 2011-02-23 kinaba: data_, sizeof(StringData)+sizeof(TCHAR)*data_->alen ); dcdd144598 2011-02-23 kinaba: } dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: String::~String() dcdd144598 2011-02-23 kinaba: { dcdd144598 2011-02-23 kinaba: ReleaseData(); dcdd144598 2011-02-23 kinaba: } dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: TCHAR* String::ReallocMem( ulong minimum=0 ) dcdd144598 2011-02-23 kinaba: { dcdd144598 2011-02-23 kinaba: return AllocMemHelper( minimum, c_str(), len()+1 ); dcdd144598 2011-02-23 kinaba: } dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: String& String::SetString( const TCHAR* str, ulong siz ) dcdd144598 2011-02-23 kinaba: { dcdd144598 2011-02-23 kinaba: TCHAR* buf = AllocMem( siz+1 ); dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: memmove( buf, str, siz*sizeof(TCHAR) ); dcdd144598 2011-02-23 kinaba: buf[siz] = TEXT('\0'); dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: UnlockMem( siz ); dcdd144598 2011-02-23 kinaba: return *this; dcdd144598 2011-02-23 kinaba: } dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: String& String::CatString( const TCHAR* str, ulong siz ) dcdd144598 2011-02-23 kinaba: { dcdd144598 2011-02-23 kinaba: const int plen = len(); dcdd144598 2011-02-23 kinaba: TCHAR* buf = ReallocMem( plen + siz + 1 ); dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: memmove( buf+plen, str, siz*sizeof(TCHAR) ); dcdd144598 2011-02-23 kinaba: buf[plen+siz] = TEXT('\0'); dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: UnlockMem( plen+siz ); dcdd144598 2011-02-23 kinaba: return *this; dcdd144598 2011-02-23 kinaba: } dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: TCHAR* String::AllocMemHelper( ulong minimum, const TCHAR* str, ulong siz ) dcdd144598 2011-02-23 kinaba: { dcdd144598 2011-02-23 kinaba: if( data_->ref > 1 || data_->alen < minimum ) dcdd144598 2011-02-23 kinaba: { dcdd144598 2011-02-23 kinaba: minimum = Max( minimum, data_->alen ); dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: StringData* pNew = static_cast<StringData*> dcdd144598 2011-02-23 kinaba: (mem().Alloc( sizeof(StringData)+minimum*sizeof(TCHAR) )); dcdd144598 2011-02-23 kinaba: pNew->ref = 1; dcdd144598 2011-02-23 kinaba: pNew->alen = minimum; dcdd144598 2011-02-23 kinaba: pNew->len = siz; dcdd144598 2011-02-23 kinaba: memmove( pNew->buf(), str, siz*sizeof(TCHAR) ); dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: ReleaseData(); dcdd144598 2011-02-23 kinaba: data_ = pNew; dcdd144598 2011-02-23 kinaba: } dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: return data_->buf(); dcdd144598 2011-02-23 kinaba: } dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: String& String::operator = ( const String& obj ) dcdd144598 2011-02-23 kinaba: { dcdd144598 2011-02-23 kinaba: if( data() != obj.data() ) dcdd144598 2011-02-23 kinaba: { dcdd144598 2011-02-23 kinaba: ReleaseData(); dcdd144598 2011-02-23 kinaba: SetData( obj.data() ); dcdd144598 2011-02-23 kinaba: } dcdd144598 2011-02-23 kinaba: return *this; dcdd144598 2011-02-23 kinaba: } dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: #ifdef _UNICODE dcdd144598 2011-02-23 kinaba: String& String::operator = ( const char* s ) dcdd144598 2011-02-23 kinaba: { dcdd144598 2011-02-23 kinaba: long len = ::MultiByteToWideChar( CP_ACP, 0, s, -1, NULL, 0 ); dcdd144598 2011-02-23 kinaba: ::MultiByteToWideChar( CP_ACP, 0, s, -1, AllocMem(len+1), len+1 ); dcdd144598 2011-02-23 kinaba: #else dcdd144598 2011-02-23 kinaba: String& String::operator = ( const wchar_t* s ) dcdd144598 2011-02-23 kinaba: { dcdd144598 2011-02-23 kinaba: long len = ::WideCharToMultiByte(CP_ACP,0,s,-1,NULL,0,NULL,NULL); dcdd144598 2011-02-23 kinaba: ::WideCharToMultiByte(CP_ACP,0,s,-1,AllocMem(len+1),len+1,NULL,NULL); dcdd144598 2011-02-23 kinaba: #endif dcdd144598 2011-02-23 kinaba: UnlockMem( len ); dcdd144598 2011-02-23 kinaba: return *this; dcdd144598 2011-02-23 kinaba: } dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: String& String::Load( UINT rsrcID ) dcdd144598 2011-02-23 kinaba: { dcdd144598 2011-02-23 kinaba: const int step=256; dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: // 256バイトの固定長バッファへまず読んでみる dcdd144598 2011-02-23 kinaba: TCHAR tmp[step], *buf; dcdd144598 2011-02-23 kinaba: int red = app().LoadString( rsrcID, tmp, countof(tmp) ); dcdd144598 2011-02-23 kinaba: if( countof(tmp) - red > 2 ) dcdd144598 2011-02-23 kinaba: return (*this = tmp); dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: // 少しずつ増やして対応してみる dcdd144598 2011-02-23 kinaba: int siz = step; dcdd144598 2011-02-23 kinaba: do dcdd144598 2011-02-23 kinaba: { dcdd144598 2011-02-23 kinaba: siz+= step; dcdd144598 2011-02-23 kinaba: buf = AllocMem( siz ); dcdd144598 2011-02-23 kinaba: red = app().LoadString( rsrcID, buf, siz ); dcdd144598 2011-02-23 kinaba: } while( siz - red <= 2 ); dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: buf[red] = TEXT('\0'); dcdd144598 2011-02-23 kinaba: UnlockMem( red ); dcdd144598 2011-02-23 kinaba: return *this; dcdd144598 2011-02-23 kinaba: } dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: void String::TrimRight( ulong siz ) dcdd144598 2011-02-23 kinaba: { dcdd144598 2011-02-23 kinaba: if( siz >= len() ) dcdd144598 2011-02-23 kinaba: { dcdd144598 2011-02-23 kinaba: ReleaseData(); dcdd144598 2011-02-23 kinaba: SetData( null() ); dcdd144598 2011-02-23 kinaba: } dcdd144598 2011-02-23 kinaba: else dcdd144598 2011-02-23 kinaba: { dcdd144598 2011-02-23 kinaba: // 文字列バッファの参照カウントを確実に1にする dcdd144598 2011-02-23 kinaba: ReallocMem(); dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: // 指定文字数分削る dcdd144598 2011-02-23 kinaba: data_->len -= siz; dcdd144598 2011-02-23 kinaba: data_->buf()[data_->len-1] = TEXT('\0'); dcdd144598 2011-02-23 kinaba: } dcdd144598 2011-02-23 kinaba: } dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: int String::GetInt( const TCHAR* x ) dcdd144598 2011-02-23 kinaba: { dcdd144598 2011-02-23 kinaba: int n=0; dcdd144598 2011-02-23 kinaba: bool minus = (*x==TEXT('-')); dcdd144598 2011-02-23 kinaba: for( const TCHAR* p=(minus?x+1:x); *p!=TEXT('\0'); p=next(p) ) dcdd144598 2011-02-23 kinaba: { dcdd144598 2011-02-23 kinaba: if( *p<TEXT('0') || TEXT('9')<*p ) dcdd144598 2011-02-23 kinaba: return 0; dcdd144598 2011-02-23 kinaba: n = (10*n) + (*p-TEXT('0')); dcdd144598 2011-02-23 kinaba: } dcdd144598 2011-02-23 kinaba: return minus ? -n : n; dcdd144598 2011-02-23 kinaba: } dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: String& String::SetInt( int n ) dcdd144598 2011-02-23 kinaba: { dcdd144598 2011-02-23 kinaba: if( n==0 ) dcdd144598 2011-02-23 kinaba: { dcdd144598 2011-02-23 kinaba: *this = TEXT("0"); dcdd144598 2011-02-23 kinaba: } dcdd144598 2011-02-23 kinaba: else dcdd144598 2011-02-23 kinaba: { dcdd144598 2011-02-23 kinaba: bool minus = (n<0); dcdd144598 2011-02-23 kinaba: if( minus ) dcdd144598 2011-02-23 kinaba: n= -n; dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: TCHAR tmp[20]; dcdd144598 2011-02-23 kinaba: tmp[19] = TEXT('\0'); dcdd144598 2011-02-23 kinaba: int i; dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: for( i=18; i>=0; --i ) dcdd144598 2011-02-23 kinaba: { dcdd144598 2011-02-23 kinaba: tmp[i] = TEXT('0') + n%10; dcdd144598 2011-02-23 kinaba: n /= 10; dcdd144598 2011-02-23 kinaba: if( n==0 ) dcdd144598 2011-02-23 kinaba: break; dcdd144598 2011-02-23 kinaba: } dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: if( minus ) dcdd144598 2011-02-23 kinaba: tmp[--i] = TEXT('-'); dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: *this = tmp+i; dcdd144598 2011-02-23 kinaba: } dcdd144598 2011-02-23 kinaba: return *this; dcdd144598 2011-02-23 kinaba: } dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: const wchar_t* String::ConvToWChar() const dcdd144598 2011-02-23 kinaba: { dcdd144598 2011-02-23 kinaba: #ifdef _UNICODE dcdd144598 2011-02-23 kinaba: return c_str(); dcdd144598 2011-02-23 kinaba: #else dcdd144598 2011-02-23 kinaba: int ln = ::MultiByteToWideChar( CP_ACP, 0, c_str(), -1 , 0, 0 ); dcdd144598 2011-02-23 kinaba: wchar_t* p = new wchar_t[ln+1]; dcdd144598 2011-02-23 kinaba: ::MultiByteToWideChar( CP_ACP, 0, c_str(), -1 , p, ln+1 ); dcdd144598 2011-02-23 kinaba: return p; dcdd144598 2011-02-23 kinaba: #endif dcdd144598 2011-02-23 kinaba: } dcdd144598 2011-02-23 kinaba: