dcdd144598 2011-02-23 kinaba: #ifndef _KILIB_STRING_H_ dcdd144598 2011-02-23 kinaba: #define _KILIB_STRING_H_ dcdd144598 2011-02-23 kinaba: #include "types.h" dcdd144598 2011-02-23 kinaba: #include "memory.h" dcdd144598 2011-02-23 kinaba: #include "ktlaptr.h" dcdd144598 2011-02-23 kinaba: #ifndef __ccdoc__ dcdd144598 2011-02-23 kinaba: namespace ki { dcdd144598 2011-02-23 kinaba: #endif dcdd144598 2011-02-23 kinaba: #ifdef _UNICODE dcdd144598 2011-02-23 kinaba: #define XTCHAR char dcdd144598 2011-02-23 kinaba: #else dcdd144598 2011-02-23 kinaba: #define XTCHAR wchar_t 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: //@{ @pkg ki.StdLib //@} dcdd144598 2011-02-23 kinaba: //@{ dcdd144598 2011-02-23 kinaba: // 文字列処理 dcdd144598 2011-02-23 kinaba: // dcdd144598 2011-02-23 kinaba: // かなりMFCのCStringをパクってます。とりあえず operator= による dcdd144598 2011-02-23 kinaba: // 単純代入にはほとんどコストがかからないようにしました。SubStr()の 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: class String : public Object dcdd144598 2011-02-23 kinaba: { dcdd144598 2011-02-23 kinaba: public: dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: //@{ 空文字列作成 //@} dcdd144598 2011-02-23 kinaba: String(); dcdd144598 2011-02-23 kinaba: ~String(); dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: //@{ 別のStringのコピー //@} dcdd144598 2011-02-23 kinaba: String( const String& obj ); dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: //@{ 別の文字配列のコピー //@} dcdd144598 2011-02-23 kinaba: String( const TCHAR* str, long siz=-1 ); dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: //@{ リソースから作成 //@} dcdd144598 2011-02-23 kinaba: explicit String( UINT rsrcID ); dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: //@{ 大文字小文字を区別する比較 //@} dcdd144598 2011-02-23 kinaba: bool operator==( LPCTSTR s ) const; dcdd144598 2011-02-23 kinaba: bool operator==( const String& obj ) const; dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: //@{ 大文字小文字を区別しない比較 //@} dcdd144598 2011-02-23 kinaba: bool isSame( LPCTSTR s ) const; dcdd144598 2011-02-23 kinaba: bool isSame( const String& obj ) const; dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: //@{ 単純代入 //@} dcdd144598 2011-02-23 kinaba: String& operator=( const String& obj ); dcdd144598 2011-02-23 kinaba: String& operator=( const TCHAR* s ); dcdd144598 2011-02-23 kinaba: String& operator=( const XTCHAR* s ); dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: //@{ 加算代入 //@} dcdd144598 2011-02-23 kinaba: String& operator+=( const String& obj ); dcdd144598 2011-02-23 kinaba: String& operator+=( const TCHAR* s ); dcdd144598 2011-02-23 kinaba: String& operator+=( TCHAR c ); dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: //@{ リソースロード //@} dcdd144598 2011-02-23 kinaba: String& Load( UINT rsrcID ); dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: //@{ 右を削る //@} dcdd144598 2011-02-23 kinaba: void TrimRight( ulong siz ); dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: //@{ intから文字列へ変換 //@} dcdd144598 2011-02-23 kinaba: String& SetInt( int n ); dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: //@{ 文字列からintへ変換 //@} dcdd144598 2011-02-23 kinaba: int GetInt(); dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: public: dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: //@{ 文字列バッファを返す //@} dcdd144598 2011-02-23 kinaba: const TCHAR* c_str() const; dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: //@{ 長さ //@} dcdd144598 2011-02-23 kinaba: ulong len() const; dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: //@{ 要素 //@} dcdd144598 2011-02-23 kinaba: const TCHAR operator[](int n) const; dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: //@{ ワイド文字列に変換して返す //@} dcdd144598 2011-02-23 kinaba: const wchar_t* ConvToWChar() const; dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: //@{ ConvToWCharの返値バッファの解放 //@} dcdd144598 2011-02-23 kinaba: void FreeWCMem( const wchar_t* wc ) const; dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: public: dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: //@{ 次の一文字 //@} dcdd144598 2011-02-23 kinaba: static TCHAR* next( TCHAR* p ); dcdd144598 2011-02-23 kinaba: static const TCHAR* next( const TCHAR* p ); dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: //@{ 2バイト文字の先頭かどうか? //@} dcdd144598 2011-02-23 kinaba: static bool isLB( TCHAR c ); dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: //@{ 文字列からintへ変換 //@} dcdd144598 2011-02-23 kinaba: static int GetInt( const TCHAR* p ); dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: protected: dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: // 書き込み可能なバッファを、終端含めて最低でもminimum文字分用意する dcdd144598 2011-02-23 kinaba: TCHAR* AllocMem( ulong minimum ); dcdd144598 2011-02-23 kinaba: TCHAR* ReallocMem( ulong minimum ); dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: // 書き込み終了後、長さを再設定 dcdd144598 2011-02-23 kinaba: void UnlockMem( long siz=-1 ); dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: private: dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: struct StringData dcdd144598 2011-02-23 kinaba: { dcdd144598 2011-02-23 kinaba: long ref; // 参照カウンタ dcdd144598 2011-02-23 kinaba: ulong len; // 終端'\0'を含める長さ dcdd144598 2011-02-23 kinaba: ulong alen; // 割り当てられているメモリのサイズ dcdd144598 2011-02-23 kinaba: TCHAR* buf() const // TCHAR buf[alen] dcdd144598 2011-02-23 kinaba: { return reinterpret_cast<TCHAR*>( dcdd144598 2011-02-23 kinaba: const_cast<StringData*>(this+1) dcdd144598 2011-02-23 kinaba: ); } dcdd144598 2011-02-23 kinaba: }; dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: private: dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: TCHAR* AllocMemHelper( ulong minimum, const TCHAR* str, ulong siz ); dcdd144598 2011-02-23 kinaba: String& CatString( const TCHAR* str, ulong siz ); dcdd144598 2011-02-23 kinaba: String& SetString( const TCHAR* str, ulong siz ); dcdd144598 2011-02-23 kinaba: void SetData( StringData* d ); dcdd144598 2011-02-23 kinaba: void ReleaseData(); dcdd144598 2011-02-23 kinaba: static StringData* null(); dcdd144598 2011-02-23 kinaba: StringData* data() const; dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: private: dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: StringData* data_; dcdd144598 2011-02-23 kinaba: static StringData* nullData_; dcdd144598 2011-02-23 kinaba: static char lb_[256]; dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: private: dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: static void LibInit(); dcdd144598 2011-02-23 kinaba: friend void APIENTRY Startup(); 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: #ifndef __ccdoc__ dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: // 初期化 dcdd144598 2011-02-23 kinaba: inline String::String() dcdd144598 2011-02-23 kinaba: { SetData( null() ); } dcdd144598 2011-02-23 kinaba: // 初期化 dcdd144598 2011-02-23 kinaba: inline String::String( UINT rsrcID ) dcdd144598 2011-02-23 kinaba: { SetData( null() ), Load( rsrcID ); } dcdd144598 2011-02-23 kinaba: // 初期化 dcdd144598 2011-02-23 kinaba: inline String::String( const String& obj ) dcdd144598 2011-02-23 kinaba: { SetData( obj.data() ); } dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: // ポインタ計算サポート dcdd144598 2011-02-23 kinaba: #if !defined(_UNICODE) && defined(_MBCS) dcdd144598 2011-02-23 kinaba: inline TCHAR* String::next( TCHAR* p ) dcdd144598 2011-02-23 kinaba: { return p + lb_[*(uchar*)p]; } dcdd144598 2011-02-23 kinaba: inline const TCHAR* String::next( const TCHAR* p ) dcdd144598 2011-02-23 kinaba: { return p + lb_[*(const uchar*)p]; } dcdd144598 2011-02-23 kinaba: inline bool String::isLB( TCHAR c ) dcdd144598 2011-02-23 kinaba: { return lb_[(uchar)c]==2; } dcdd144598 2011-02-23 kinaba: #else // _UNICODE or _SBCS dcdd144598 2011-02-23 kinaba: inline TCHAR* String::next( TCHAR* p ) dcdd144598 2011-02-23 kinaba: { return p + 1; } dcdd144598 2011-02-23 kinaba: inline const TCHAR* String::next( const TCHAR* p ) dcdd144598 2011-02-23 kinaba: { return p + 1; } dcdd144598 2011-02-23 kinaba: inline bool String::isLB( TCHAR c ) dcdd144598 2011-02-23 kinaba: { return false; } dcdd144598 2011-02-23 kinaba: #endif dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: // 内部メモリ確保 dcdd144598 2011-02-23 kinaba: inline TCHAR* String::AllocMem( ulong minimum ) dcdd144598 2011-02-23 kinaba: { return AllocMemHelper( minimum, TEXT(""), 1 ); } dcdd144598 2011-02-23 kinaba: // 内部メモリ固定 dcdd144598 2011-02-23 kinaba: inline void String::UnlockMem( long siz ) dcdd144598 2011-02-23 kinaba: { data_->len = 1 + (siz==-1 ? ::lstrlen(c_str()) : siz); } dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: // 0文字データ dcdd144598 2011-02-23 kinaba: inline String::StringData* String::null() dcdd144598 2011-02-23 kinaba: { return nullData_; } dcdd144598 2011-02-23 kinaba: // 内部データ構造 dcdd144598 2011-02-23 kinaba: inline String::StringData* String::data() const dcdd144598 2011-02-23 kinaba: { return data_; } dcdd144598 2011-02-23 kinaba: // 初期化 dcdd144598 2011-02-23 kinaba: inline void String::SetData( String::StringData* d ) dcdd144598 2011-02-23 kinaba: { data_=d, data_->ref++; } dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: // 属性 dcdd144598 2011-02-23 kinaba: inline const TCHAR* String::c_str() const dcdd144598 2011-02-23 kinaba: { return data_->buf(); } dcdd144598 2011-02-23 kinaba: // 属性 dcdd144598 2011-02-23 kinaba: inline ulong String::len() const dcdd144598 2011-02-23 kinaba: { return data_->len-1; } dcdd144598 2011-02-23 kinaba: // 要素 dcdd144598 2011-02-23 kinaba: inline const TCHAR String::operator[](int n) const dcdd144598 2011-02-23 kinaba: { return data_->buf()[n]; } dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: // 比較 dcdd144598 2011-02-23 kinaba: inline bool String::operator==( LPCTSTR s ) const dcdd144598 2011-02-23 kinaba: { return 0==::lstrcmp( c_str(), s ); } dcdd144598 2011-02-23 kinaba: // 比較 dcdd144598 2011-02-23 kinaba: inline bool String::operator==( const String& obj ) const dcdd144598 2011-02-23 kinaba: { return (data_==obj.data_ ? true : operator==( obj.c_str() )); } dcdd144598 2011-02-23 kinaba: // 比較 dcdd144598 2011-02-23 kinaba: inline bool String::isSame( LPCTSTR s ) const dcdd144598 2011-02-23 kinaba: { return 0==::lstrcmpi( c_str(), s ); } dcdd144598 2011-02-23 kinaba: // 比較 dcdd144598 2011-02-23 kinaba: inline bool String::isSame( const String& obj ) const dcdd144598 2011-02-23 kinaba: { return (data_==obj.data_ ? true : operator==( obj.c_str() )); } dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: // 要コピー代入 dcdd144598 2011-02-23 kinaba: inline String& String::operator = ( const TCHAR* s ) dcdd144598 2011-02-23 kinaba: { return SetString( s, ::lstrlen(s) ); } dcdd144598 2011-02-23 kinaba: // 合成 dcdd144598 2011-02-23 kinaba: inline String& String::operator += ( const String& obj ) dcdd144598 2011-02-23 kinaba: { return CatString( obj.c_str(), obj.len() ); } dcdd144598 2011-02-23 kinaba: // 合成 dcdd144598 2011-02-23 kinaba: inline String& String::operator += ( const TCHAR* s ) dcdd144598 2011-02-23 kinaba: { return CatString( s, ::lstrlen(s) ); } dcdd144598 2011-02-23 kinaba: // 合成 dcdd144598 2011-02-23 kinaba: inline String& String::operator += ( TCHAR c ) dcdd144598 2011-02-23 kinaba: { return CatString( &c, 1 ); } dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: // 変換 dcdd144598 2011-02-23 kinaba: inline int String::GetInt() dcdd144598 2011-02-23 kinaba: { return GetInt( data_->buf() ); } dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: //@{ String + String //@} dcdd144598 2011-02-23 kinaba: inline const String operator+( const String& a, const String& b ) dcdd144598 2011-02-23 kinaba: { return String(a) += b; } dcdd144598 2011-02-23 kinaba: //@{ String + TCHAR* //@} dcdd144598 2011-02-23 kinaba: inline const String operator+( const String& a, const TCHAR* b ) dcdd144598 2011-02-23 kinaba: { return String(a) += b; } dcdd144598 2011-02-23 kinaba: //@{ TCHAR* + String //@} dcdd144598 2011-02-23 kinaba: inline const String operator+( const TCHAR* a, const String& b ) dcdd144598 2011-02-23 kinaba: { return String(a) += b; } dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: // ConvToWCharの返値バッファの解放 dcdd144598 2011-02-23 kinaba: inline void String::FreeWCMem( const wchar_t* wc ) const dcdd144598 2011-02-23 kinaba: #ifdef _UNICODE dcdd144598 2011-02-23 kinaba: {} dcdd144598 2011-02-23 kinaba: #else // _MBCS or _SBCS dcdd144598 2011-02-23 kinaba: { delete [] const_cast<wchar_t*>(wc); } 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: #endif // __ccdoc__ dcdd144598 2011-02-23 kinaba: #undef XTCHAR 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です。 dcdd144598 2011-02-23 kinaba: //@} dcdd144598 2011-02-23 kinaba: //========================================================================= dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: struct RawString : public String dcdd144598 2011-02-23 kinaba: { dcdd144598 2011-02-23 kinaba: TCHAR* AllocMem( ulong m ) { return String::AllocMem(m); } dcdd144598 2011-02-23 kinaba: void UnlockMem() { String::UnlockMem(); } dcdd144598 2011-02-23 kinaba: }; dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: } // 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: // 文字列処理+α2 dcdd144598 2011-02-23 kinaba: // dcdd144598 2011-02-23 kinaba: // Wide文字版関数を自前で dcdd144598 2011-02-23 kinaba: //@} dcdd144598 2011-02-23 kinaba: //========================================================================= dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: #ifdef _UNICODE dcdd144598 2011-02-23 kinaba: #define my_lstrlenW ::lstrlenW dcdd144598 2011-02-23 kinaba: #define my_lstrcpyW ::lstrcpyW dcdd144598 2011-02-23 kinaba: #else dcdd144598 2011-02-23 kinaba: inline static dcdd144598 2011-02-23 kinaba: unicode* my_lstrcpyW( unicode* const d, const unicode* s ) dcdd144598 2011-02-23 kinaba: { dcdd144598 2011-02-23 kinaba: for(unicode* n=d; *n++=*s++;); dcdd144598 2011-02-23 kinaba: return d; dcdd144598 2011-02-23 kinaba: } dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: inline static dcdd144598 2011-02-23 kinaba: int my_lstrlenW( const unicode* const d ) dcdd144598 2011-02-23 kinaba: { dcdd144598 2011-02-23 kinaba: const unicode* n; dcdd144598 2011-02-23 kinaba: for(n=d; *n; ++n); dcdd144598 2011-02-23 kinaba: return static_cast<int>(n-d); dcdd144598 2011-02-23 kinaba: } 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: #endif // _KILIB_STRING_H_