#include "precompiled.h" #include "0ad_warning_disable.h" # include # include # include # include # include # include "sr_string.h" # include "sr_input.h" //# define SR_USE_TRACE1 // constructors / destructors //# define SR_USE_TRACE2 // member functions //# define SR_USE_TRACE3 // set() member function # include "sr_trace.h" char *SrString::_empty = ""; //============================= SrString ========================================== SrString::SrString () : _capacity(0), _data(SrString::_empty) { SR_TRACE1 ( "Default Constructor" ); } SrString::SrString ( char c, int len ) : _capacity(0), _data(SrString::_empty) { if ( len<=0 ) return; _capacity = len+1; _data = new char[_capacity]; memset ( _data, c, len ); _data[len] = 0; SR_TRACE1 ( "Char Constructor: "<=xi && isspace(_data[xf]) ) xf--; } void SrString::substring ( int inf, int sup ) { int n=0; int max=(int)strlen(_data)-1; if ( max<0 ) return; if ( inf<0 ) inf=0; if ( sup<0 || sup>max ) sup=max; while (inf<=sup) _data[n++] = _data[inf++]; _data[n] = 0; } char SrString::last_char () const { int len = (int)strlen(_data); if ( len==0 ) return 0; return _data[len-1]; } void SrString::last_char ( char c ) { int len = (int)strlen(_data); if ( len==0 ) return; _data[len-1] = c; } void SrString::get_substring ( SrString& s, int inf, int sup ) const { int max=(int)strlen(_data)-1; if ( max<0 ) return; if ( sup<0 || sup>max ) sup=max; if ( inf<0 ) inf=0; if ( inf>sup ) return; s.len ( sup-inf+1 ); int i=0; while ( inf<=sup ) s[i++]=_data[inf++]; s[i]=0; } int SrString::get_next_string ( SrString& s, int i ) const { int i1, i2; int max=(int)strlen(_data)-1; if ( max<0 ) return -1; if ( i<0 ) i=0; while ( i<=max && isspace(_data[i]) ) i++; // cut leading spaces i1 = i; while ( i<=max && !isspace(_data[i]) ) i++; // advance untill finding other white characters i2 = i; if ( i2>i1 ) { get_substring ( s, i1, i2-1 ); return i2; } else { return -1; } } void SrString::lower () { char *pt = _data; while ( *pt ) { *pt=(char)SR_LOWER(*pt); pt++; } } void SrString::upper () { char *pt = _data; while ( *pt ) { *pt=(char)SR_UPPER(*pt); pt++; } } int SrString::search ( char c ) const { int len = (int)strlen(_data); for ( int i=0; i=0; i-- ) { if ( _data[i]=='/' || _data[i]=='\\' ) { _data[i+1]=0; break; } } return i; } int SrString::remove_path () { int i; for ( i=len()-1; i>=0; i-- ) { if ( _data[i]=='/' || _data[i]=='\\' ) { substring(i+1,-1); break; } } return i; } int SrString::get_file_name ( SrString& filename ) const { filename.set ( _data ); return filename.remove_path (); } int SrString::extract_file_name ( SrString& filename ) { int i = get_file_name ( filename ); if ( i>=0 ) _data[i+1]=0; return i; } int SrString::remove_file_extension () { int i; for ( i=len()-1; i>=0; i-- ) { if ( _data[i]=='.' ) _data[i]=0; if ( _data[i]=='/' || _data[i]=='\\' ) return -1; // no extension } return i; } int SrString::get_file_extension ( SrString& ext ) const { int i; ext.set ( _data ); for ( i=len()-1; i>=0; i-- ) { if ( _data[i]=='.' ) { ext.substring(i+1,-1); break; } if ( _data[i]=='/' || _data[i]=='\\' ) return -1; // no extension } return i; } int SrString::extract_file_extension ( SrString& ext ) { int i = get_file_extension ( ext ); if ( i>=0 ) _data[i]=0; return i; } bool SrString::has_file_extension ( const char* ext ) const { int i; for ( i=len()-1; i>=0; i-- ) { if ( _data[i]=='.' ) { if ( !ext ) return true; return sr_compare_cs ( _data+i+1, ext )==0? true:false; } if ( _data[i]=='/' || _data[i]=='\\' ) break; // early termination } return false; } bool SrString::make_valid_path () { replace_all ( "\\", "/" ); if ( _data[0]==0 ) return false; if ( last_char()!='/' ) append ( "/" ); return true; } bool SrString::make_valid_path ( const char* s ) { if ( !s ) return false; set ( s ); return make_valid_path(); } bool SrString::has_absolute_path ( const char* s ) // static function { if ( !s ) return false; if ( !s[0] ) return false; if ( s[0]=='\\' || s[0]=='/' ) return true; // /dir, \\machine\dir if ( !s[1] ) return false; // eg a 1-letter filename if ( s[1]==':' ) return true; // c:dir is considered absolute return false; } bool SrString::make_valid_string ( const char* s ) { bool need_quotes = false; bool need_slash = false; int i; int len = (int)strlen ( s ); if ( len==0 ) need_quotes = true; else { for ( i=0; i=len ) { append(st); return; } int dp = (int)strlen ( st ); if ( !dp ) return; int ns = len+dp+1; // at this point _data!=_empty, because of the i>=len test. if ( ns>_capacity ) { _capacity = ns*2; _data = sr_string_realloc ( _data, _capacity ); } // memmove deals with overlapped regions memmove ( _data+i+dp, _data+i, sizeof(char)*(len-i+1) ); // copies also the ending 0 // now we fill the created space : memcpy ( _data+i, st, sizeof(char)*dp ); } void SrString::remove ( int i, int dp ) { if ( _data==_empty || dp<=0 ) return; int len = (int)strlen(_data); if ( i>=len || i<0 ) return; if ( i+dp>=len ) { _data[i]=0; return; } // memmove deals with overlapped regions : memmove ( _data+i, _data+i+dp, sizeof(char)*(len-i-dp+1) ); // copies also the ending 0 } int SrString::replace ( const char* oldst, const char* newst, bool ci ) { int i = search ( oldst, ci ); // printf("%d\n",i); if ( i<0 ) return i; // not found int oldlen = (int)strlen(oldst); int newlen = newst? (int)strlen(newst):0; if ( oldlennewlen ) // remove space { remove ( i, oldlen-newlen ); } // void *memmove( void *dest, const void *src, size_t count ); // The memmove function copies count bytes of characters from src to dest. // If some regions of the source area and the destination overlap, // memmove ensures that the original source bytes in the overlapping // region are copied before being overwritten. if ( newlen>1 ) memmove ( _data+i, newst, sizeof(char)*newlen ); else if ( newlen==1 ) _data[i]=newst[0]; return i; } int SrString::replace_all ( const char* oldst, const char* newst, bool ci ) { int count=0; while ( replace(oldst,newst,ci)!=-1 ) count++; return count; } void SrString::take_data ( SrString &s ) { if ( _data!=_empty ) delete[] ( _data ); _data = s._data; _capacity = s._capacity; s._data = _empty; s._capacity = 0; SR_TRACE2 ( "take_data!" ); } char* SrString::leave_data ( char*& s ) { s = _data; if ( s==_empty ) { s=new char[1]; s[0]=0; } _data = _empty; _capacity = 0; SR_TRACE2 ( "leave_data!" ); return s; } SrString& SrString::operator << ( const char* st ) { append(st); return *this; } SrString& SrString::operator << ( int i ) { char buf[64]; sprintf ( buf, "%d", i ); append(buf); return *this; } SrString& SrString::operator << ( float f ) { char buf[64]; sprintf ( buf, "%f", f ); append(buf); return *this; } SrString& SrString::operator << ( double d ) { char buf[64]; sprintf ( buf, "%f", d ); append(buf); return *this; } SrString& SrString::operator << ( char c ) { char buf[2]; buf[0]=c; buf[1]=0; append(buf); return *this; } SrString& SrString::operator = ( const SrString &s ) { set(s._data); return *this; } SrString& SrString::operator = ( const char* st ) { set(st); return *this; } SrString& SrString::operator = ( int i ) { set(""); return *this<