Artifact Content

Not logged in

Artifact 39bddacbff2819d9435fe379befdc119e116ff34


     1  //--- K.I.LIB ---
     2  // kl_str.cpp : string classes for K.I.LIB
     3  
     4  #include "stdafx.h"
     5  #include "kilib.h"
     6  
     7  
     8  //------------------------ 2byte文字処理用 ----------------------//
     9  
    10  
    11  char kiStr::st_lb[256];
    12  
    13  void kiStr::init()
    14  {
    15  	st_lb[0] = 0;
    16  	for( int c=1; c!=256; c++ )
    17  		st_lb[c] = (::IsDBCSLeadByte(c) ? 2 : 1);
    18  }
    19  
    20  
    21  //-------------------------- コピー系色々 ------------------------//
    22  
    23  
    24  kiStr::kiStr( int start_size )
    25  {
    26  	(m_pBuf = new char[ m_ALen = start_size ])[0] = '\0';
    27  }
    28  
    29  kiStr::kiStr( const char* s, int min_size )
    30  {
    31  	int slen = ki_strlen(s) + 1;
    32  	m_ALen = ( slen < min_size ) ? min_size : slen;
    33  	ki_memcpy( m_pBuf=new char[m_ALen], s, slen );
    34  }
    35  
    36  kiStr::kiStr( const kiStr& s )
    37  {
    38  	ki_memcpy( m_pBuf=new char[m_ALen=s.m_ALen], s.m_pBuf, m_ALen=s.m_ALen );
    39  }
    40  
    41  kiStr& kiStr::operator = ( const kiStr& s )
    42  {
    43  	if( this != &s )
    44  		*this = (const char*)s;
    45  	return *this;
    46  }
    47  
    48  kiStr& kiStr::operator = ( const char* s )
    49  {
    50  	int slen = ki_strlen( s ) + 1;
    51  	int  len = this->len();
    52  
    53  	if( m_ALen < slen || s <= m_pBuf+len || m_pBuf <= s+slen )
    54  	{
    55  		char* tmp = new char[ m_ALen = ( m_ALen>slen ? m_ALen : slen) ];
    56  		ki_memcpy( tmp, s, slen );
    57  		delete [] m_pBuf;
    58  		m_pBuf = tmp;
    59  	}
    60  	else
    61  		ki_memcpy( m_pBuf, s, slen );
    62  	return *this;
    63  }
    64  
    65  kiStr& kiStr::operator += ( const char* s )
    66  {
    67  	int slen = ki_strlen( s ) + 1;
    68  	int  len = this->len();
    69  
    70  	if( m_ALen < len+slen+1
    71  	 || ( s <= m_pBuf && m_pBuf <= s+len )
    72  	 || ( m_pBuf <= s && s <= m_pBuf+slen ) )
    73  	{
    74  		char* tmp = new char[ m_ALen = ( m_ALen>slen+len+1 ? m_ALen : slen+len+1) ];
    75  		ki_memcpy( tmp, m_pBuf, len );
    76  		delete [] m_pBuf;
    77  		m_pBuf = tmp;
    78  	}
    79  
    80  	ki_memcpy( m_pBuf+len, s, slen );
    81  	return *this;
    82  }
    83  
    84  kiStr& kiStr::operator += ( char c )
    85  {
    86  	int  len = this->len();
    87  
    88  	if( m_ALen < len+2 )
    89  	{
    90  		char* tmp = new char[ m_ALen=len+20 ];
    91  		ki_memcpy( tmp, m_pBuf, len );
    92  		delete [] m_pBuf;
    93  		m_pBuf = tmp;
    94  	}
    95  
    96  	m_pBuf[len]=c, m_pBuf[len+1]='\0';
    97  	return *this;
    98  }
    99  
   100  kiStr& kiStr::setInt( int n, bool cm )
   101  {
   102  	if( n==0 )
   103  		m_pBuf[0] = '0', m_pBuf[1] = '\0';
   104  	else
   105  	{
   106  		bool minus = (n<0);
   107  		if( minus )
   108  			n= -n;
   109  
   110  		char tmp[30];
   111  		tmp[29]='\0';
   112  		int i;
   113  
   114  		for( i=28; i>=0; i-- )
   115  		{
   116  			if( cm && (29-i)%4==0 )
   117  				tmp[i--] = ',';
   118  			tmp[i] = '0' + n%10;
   119  			n /= 10;
   120  			if( n==0 )
   121  				break;
   122  		}
   123  
   124  		if( minus )
   125  			tmp[--i] = '-';
   126  
   127  		(*this) = tmp+i;
   128  	}
   129  	return (*this);
   130  }
   131  
   132  //-------------------------- 文字列処理全般 ------------------------//
   133  
   134  
   135  kiStr::~kiStr()
   136  {
   137  	delete [] m_pBuf;
   138  }
   139  
   140  kiStr::operator const char*() const
   141  {
   142  	return m_pBuf;
   143  }
   144  
   145  bool kiStr::operator == ( const char* s ) const
   146  {
   147  	return 0==ki_strcmp( m_pBuf, s );
   148  }
   149  
   150  bool kiStr::isSame( const char* s ) const
   151  {
   152  	return 0==ki_strcmpi( m_pBuf, s );
   153  }
   154  
   155  int kiStr::len() const
   156  {
   157  	return ki_strlen( m_pBuf );
   158  }
   159  
   160  
   161  //-------------------------- ユーティリティー ------------------------//
   162  
   163  
   164  kiStr& kiStr::removeTrailWS()
   165  {
   166  	char* m=m_pBuf-1;
   167  	for( char *p=m_pBuf; *p!='\0'; p=next(p) )
   168  		if( *p!=' ' && *p!='\t' && *p!='\n' )
   169  			m = p;
   170  	*next(m) = '\0';
   171  	return *this;
   172  }
   173  
   174  kiStr& kiStr::loadRsrc( UINT id )
   175  {
   176  	::LoadString( GetModuleHandle(NULL), id, m_pBuf, m_ALen );
   177  	return *this;
   178  }
   179  
   180  void kiPath::beSpecialPath( int nPATH )
   181  {
   182  	switch( nPATH )
   183  	{
   184  	case Win:	::GetWindowsDirectory( m_pBuf, m_ALen );	break;
   185  	case Sys:	::GetSystemDirectory( m_pBuf, m_ALen );		break;
   186  	case Tmp:	::GetTempPath( m_ALen, m_pBuf );			break;
   187  	case Cur:	::GetCurrentDirectory( m_ALen, m_pBuf );	break;
   188  	case Exe_name:
   189  				::GetModuleFileName( NULL, m_pBuf, m_ALen );break;
   190  	case Exe:
   191  		{
   192  			::GetModuleFileName( NULL, m_pBuf, m_ALen );
   193  
   194  			char* m=NULL;
   195  			for( char *p=m_pBuf; *p!='\0'; p=next(p) )
   196  				if( *p=='\\' )
   197  					m = p;
   198  			if( m )
   199  				*m='\0';
   200  			break;
   201  		}
   202  	default:
   203  		{
   204  			*m_pBuf = '\0';
   205  
   206  			LPITEMIDLIST il;
   207  			if( NOERROR!=::SHGetSpecialFolderLocation( NULL, nPATH, &il ) )
   208  				return;
   209  			::SHGetPathFromIDList( il, m_pBuf );
   210  			app()->shellFree( il );
   211  		}
   212  	}
   213  }
   214  
   215  void kiPath::beBackSlash( bool add )
   216  {
   217  	char* last = m_pBuf;
   218  	for( char* p=m_pBuf; *p!='\0'; p=next(p) )
   219  		last=p;
   220  	if( *last=='\\' || *last=='/' )
   221  	{
   222  		if( !add )
   223  			*last = '\0';
   224  	}
   225  	else if( add && last!=m_pBuf )
   226  		*this += '\\';
   227  }
   228  
   229  bool kiPath::beDirOnly()
   230  {
   231  	char* lastslash = m_pBuf-1;
   232  	for( char* p=m_pBuf; *p; p=next(p) )
   233  		if( *p=='\\' || *p=='/' )
   234  			lastslash = p;
   235  
   236  	*(lastslash+1) = '\0';
   237  
   238  	return (lastslash+1 != m_pBuf);
   239  }
   240  
   241  bool kiPath::isInSameDir(const char* q) const
   242  {
   243  	bool diff=false;
   244  	for( const char *p=m_pBuf; *p && *q; p=next(p), q=next(q) )
   245  		if( *p != *q )
   246  			diff = true;
   247  		else if( diff && (*p=='\\' || *p=='/' || *q=='\\' || *q=='/') )
   248  			return false;
   249  
   250  	const char* r = (*p ? p : q);
   251  	if( *r )
   252  		for( ; *r; r=next(r) )
   253  			if( *r=='\\' || *r=='/' )
   254  				return false;
   255  	return true;
   256  }
   257  
   258  void kiPath::beShortPath()
   259  {
   260  	::GetShortPathName( m_pBuf, m_pBuf, m_ALen );
   261  }
   262  
   263  void kiPath::mkdir()
   264  {
   265  	for( char *p=m_pBuf; *p; p=kiStr::next(p) )
   266  	{
   267  		if( (*p!='\\' && *p!='/') || (p-m_pBuf<=4) )
   268  			continue;
   269  		*p = '\0';
   270  		if( !kiSUtil::exist(m_pBuf) )
   271  			if( ::CreateDirectory( m_pBuf, NULL ) )
   272  				::SHChangeNotify( SHCNE_MKDIR,SHCNF_PATH,(const void*)m_pBuf,NULL );
   273  		*p = '\\';
   274  	}
   275  }
   276  
   277  void kiPath::remove()
   278  {
   279  	if( !kiSUtil::exist(*this) )
   280  		return;
   281  	if( !kiSUtil::isdir(*this) )
   282  	{
   283  		::DeleteFile(*this);
   284  		return;
   285  	}
   286  
   287  	// buf == filename with no last '\\'
   288  	kiPath buf(*this);
   289  	buf.beBackSlash(false);
   290  
   291  	kiPath tmp(buf);
   292  	WIN32_FIND_DATA fd;
   293  	kiFindFile find;
   294  	find.begin( tmp += "\\*" );
   295  	while( find.next( &fd ) )
   296  	{
   297  		tmp = buf;
   298  		tmp += '\\';
   299  		tmp += fd.cFileName;
   300  		tmp.remove();
   301  	}
   302  	find.close();
   303  
   304  	::RemoveDirectory( buf );
   305  }
   306  
   307  void kiPath::getBody( kiStr& str ) const
   308  {
   309  	char *p=const_cast<char*>(name()),*x,c;
   310  	for( x=(*p=='.'?p+1:p); *x; x=next(x) ) // 先頭の.は拡張子と見なさない
   311  		if( *x=='.' )
   312  			break;
   313  	c=*x, *x='\0';
   314  	str=p;
   315  	*x=c;
   316  }
   317  
   318  void kiPath::getBody_all( kiStr& str ) const
   319  {
   320  // 最後の拡張子だけ削る版
   321  	char *p=const_cast<char*>(name()),*x=NULL, *n, c;
   322  	for( n=(*p=='.'?p+1:p); *n; n=next(n) ) // 先頭の.は拡張子と見なさない
   323  		if( *n=='.' )
   324  			x = n;
   325  	if( !x )x = n;
   326  
   327  	c  =*x;
   328  	*x ='\0';
   329  	str=p;
   330  	*x =c;
   331  }
   332  
   333  const char* kiPath::ext( const char* str )
   334  {
   335  	const char *ans = NULL, *p = name(str);
   336  	if( *p == '.' ) ++p; // 先頭の.は拡張子と見なさない
   337  	for( ; *p; p=next(p) )
   338  		if( *p=='.' )
   339  			ans = p;
   340  	return ans ? (ans+1) : p;
   341  }
   342  
   343  const char* kiPath::ext_all( const char* str )
   344  {
   345  	const char* p = name(str);
   346  	if( *p == '.' ) ++p; // 先頭の.は拡張子と見なさない
   347  	for( ; *p; p=next(p) )
   348  		if( *p=='.' )
   349  			return (p+1);
   350  	return p;
   351  }
   352  
   353  const char* kiPath::name( const char* str )
   354  {
   355  	const char* ans = str - 1;
   356  	for( const char* p=str; *p; p=next(p) )
   357  		if( *p=='\\' || *p=='/' )
   358  			ans = p;
   359  	return (ans+1);
   360  }
   361  
   362  UINT kiPath::getDriveType() const
   363  {
   364  	char* p;
   365  	for( p=m_pBuf; *p=='\\'; p=next(p) );
   366  	for( p=m_pBuf; *p && *p!='\\'; p=next(p) );
   367  	char c=*(++p);*p='\0';
   368  	UINT ans=::GetDriveType( m_pBuf );
   369  	*p=c; return ans;
   370  }
   371  
   372  bool kiPath::endwithyen( const char* str )
   373  {
   374  	for( const char *p=str,*last=str; *p; p=next(p) )
   375  		last=p;
   376  	return ( *last=='\\' || *last=='/' );
   377  }
   378