|
|
@@ -4,18 +4,16 @@
|
|
|
#include <iostream>
|
|
|
#include <cstdlib>
|
|
|
#include <string.h>
|
|
|
+#include <climits>
|
|
|
+#include <cmath>
|
|
|
+#include "common.h"
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
-
|
|
|
+/// class string_t
|
|
|
class string_t
|
|
|
{
|
|
|
private:
|
|
|
- char* data;
|
|
|
- bool const_data;
|
|
|
- uint length;
|
|
|
-
|
|
|
- public:
|
|
|
// friends
|
|
|
friend ostream& operator <<( ostream& output, const string_t& str );
|
|
|
friend string_t operator +( const string_t& a, const string_t& b );
|
|
|
@@ -23,7 +21,29 @@ class string_t
|
|
|
friend string_t operator +( char a, const string_t& b );
|
|
|
friend string_t operator +( const string_t& a, const char* b );
|
|
|
friend string_t operator +( const string_t& a, char b );
|
|
|
-
|
|
|
+ friend bool operator ==( const string_t& a, const string_t& b );
|
|
|
+ friend bool operator ==( const string_t& a, const char* b );
|
|
|
+ friend bool operator ==( const char* a, const string_t& b );
|
|
|
+
|
|
|
+ // data
|
|
|
+ char* data;
|
|
|
+ bool const_data; ///< false means that we have allocated memory
|
|
|
+ uint length;
|
|
|
+
|
|
|
+ // private stuff
|
|
|
+ void Init( float d )
|
|
|
+ {
|
|
|
+ char pc [256];
|
|
|
+ sprintf( pc, "%f", d );
|
|
|
+ length = strlen( pc );
|
|
|
+ const_data = false;
|
|
|
+ data = (char*) malloc( (length+1)*sizeof(char) );
|
|
|
+ memcpy( data, pc, length+1 );
|
|
|
+ }
|
|
|
+
|
|
|
+ public:
|
|
|
+ static const uint npos = UINT_MAX; // ToDo: change it when C++0x becomes standard
|
|
|
+
|
|
|
// constructor []
|
|
|
string_t(): data(NULL), const_data(true), length(0) {}
|
|
|
|
|
|
@@ -33,7 +53,6 @@ class string_t
|
|
|
data = const_cast<char*>(pchar);
|
|
|
const_data = true;
|
|
|
length = strlen(pchar);
|
|
|
- DEBUG_ERR( Length()<1 );
|
|
|
}
|
|
|
|
|
|
// constructor [char*]
|
|
|
@@ -41,33 +60,34 @@ class string_t
|
|
|
{
|
|
|
length = strlen( pchar );
|
|
|
const_data = false;
|
|
|
- DEBUG_ERR( Length()<1 );
|
|
|
- data = (char*) malloc( (Length()+1)*sizeof(char) );
|
|
|
- memcpy( data, pchar, Length()+1 );
|
|
|
+ data = (char*) malloc( (length+1)*sizeof(char) );
|
|
|
+ memcpy( data, pchar, length+1 );
|
|
|
}
|
|
|
|
|
|
// constructor [string_t]
|
|
|
string_t( const string_t& b )
|
|
|
{
|
|
|
const_data = b.const_data;
|
|
|
- length = b.Length();
|
|
|
+ length = b.length;
|
|
|
if( b.const_data )
|
|
|
data = b.data;
|
|
|
else
|
|
|
{
|
|
|
- data = (char*) malloc( (Length()+1)*sizeof(char) );
|
|
|
- memcpy( data, b.data, Length()+1 );
|
|
|
+ data = (char*) malloc( (length+1)*sizeof(char) );
|
|
|
+ memcpy( data, b.data, length+1 );
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// constructor [char]
|
|
|
- string_t( char char_ )
|
|
|
+ string_t( char c )
|
|
|
{
|
|
|
- DEBUG_ERR( char_ == '\0' );
|
|
|
+ DEBUG_ERR( c == '\0' );
|
|
|
+ length = 1;
|
|
|
data = (char*) malloc( 2*sizeof(char) );
|
|
|
- data[0] = char_;
|
|
|
+ const_data = false;
|
|
|
+ data[0] = c;
|
|
|
data[1] = '\0';
|
|
|
- }
|
|
|
+ }
|
|
|
|
|
|
// destructor
|
|
|
virtual ~string_t()
|
|
|
@@ -80,13 +100,17 @@ class string_t
|
|
|
const char& operator []( uint i ) const { DEBUG_ERR(i>=length); return data[i]; }
|
|
|
char& operator []( uint i ) { DEBUG_ERR(i>=length); return data[i]; }
|
|
|
|
|
|
+
|
|
|
+ //================================================================================================================================
|
|
|
+ // operator = =
|
|
|
+ //================================================================================================================================
|
|
|
+
|
|
|
// = [string_t]
|
|
|
string_t& operator =( const string_t& b )
|
|
|
{
|
|
|
- if( data!=NULL && !const_data )
|
|
|
- free( data );
|
|
|
+ if( !const_data ) free( data );
|
|
|
const_data = b.const_data;
|
|
|
- length = b.Length();
|
|
|
+ length = b.length;
|
|
|
if( b.const_data )
|
|
|
data = b.data;
|
|
|
else
|
|
|
@@ -100,40 +124,40 @@ class string_t
|
|
|
// = [char*]
|
|
|
string_t& operator =( char* pchar )
|
|
|
{
|
|
|
- if( data!=NULL && !const_data )
|
|
|
- free( data );
|
|
|
+ if( !const_data ) free( data );
|
|
|
length = strlen( pchar );
|
|
|
const_data = false;
|
|
|
- DEBUG_ERR( Length()<1 );
|
|
|
- data = (char*) malloc( (Length()+1)*sizeof(char) );
|
|
|
- memcpy( data, pchar, Length()+1 );
|
|
|
+ data = (char*) malloc( (length+1)*sizeof(char) );
|
|
|
+ memcpy( data, pchar, length+1 );
|
|
|
return (*this);
|
|
|
}
|
|
|
|
|
|
// = [const char*]
|
|
|
string_t& operator =( const char* pchar )
|
|
|
{
|
|
|
- if( data!=NULL && !const_data )
|
|
|
- free( data );
|
|
|
+ if( !const_data ) free( data );
|
|
|
data = const_cast<char*>(pchar);
|
|
|
const_data = true;
|
|
|
length = strlen(pchar);
|
|
|
- DEBUG_ERR( Length()<1 );
|
|
|
return (*this);
|
|
|
}
|
|
|
|
|
|
// = [char]
|
|
|
- string_t& operator =( char char_ )
|
|
|
+ string_t& operator =( char c )
|
|
|
{
|
|
|
- if( data!=NULL && !const_data )
|
|
|
- free( data );
|
|
|
- DEBUG_ERR( char_ == '\0' );
|
|
|
+ if( !const_data ) free( data );
|
|
|
+ DEBUG_ERR( c == '\0' );
|
|
|
data = (char*) malloc( 2*sizeof(char) );
|
|
|
- data[0] = char_;
|
|
|
+ data[0] = c;
|
|
|
data[1] = '\0';
|
|
|
return (*this);
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+ //================================================================================================================================
|
|
|
+ // operator += =
|
|
|
+ //================================================================================================================================
|
|
|
+
|
|
|
// += [string_t]
|
|
|
string_t& operator +=( const string_t& str )
|
|
|
{
|
|
|
@@ -193,10 +217,72 @@ class string_t
|
|
|
return (*this);
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+ //================================================================================================================================
|
|
|
+ // misc =
|
|
|
+ //================================================================================================================================
|
|
|
+
|
|
|
+ // Convert
|
|
|
+ static string_t Convert( int i )
|
|
|
+ {
|
|
|
+ string_t out;
|
|
|
+ if( i == 0 )
|
|
|
+ {
|
|
|
+ out.data = "0";
|
|
|
+ out.const_data = true;
|
|
|
+ out.length = 1;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ char cv [256];
|
|
|
+ const size_t cv_size = sizeof(cv)/sizeof(char);
|
|
|
+ char* pc = &cv[ cv_size ];
|
|
|
+ int ii = (i<0) ? -i : i;
|
|
|
+ while( ii != 0 )
|
|
|
+ {
|
|
|
+ int mod = ii%10;
|
|
|
+ ii /= 10;
|
|
|
+ --pc;
|
|
|
+ *pc = ('0' + mod);
|
|
|
+ }
|
|
|
+ if( i < 0 )
|
|
|
+ {
|
|
|
+ --pc;
|
|
|
+ *pc = '-';
|
|
|
+ }
|
|
|
+ out.length = cv + cv_size - pc;
|
|
|
+ DEBUG_ERR( out.length >= sizeof(cv)/sizeof(char) );
|
|
|
+ out.const_data = false;
|
|
|
+ out.data = (char*) malloc( (out.length+1)*sizeof(char) );
|
|
|
+ memcpy( out.data, pc, out.length );
|
|
|
+ out.data[out.length] = '\0';
|
|
|
+ }
|
|
|
+ return out;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Convert [float]
|
|
|
+ static string_t Convert( float f )
|
|
|
+ {
|
|
|
+ string_t out;
|
|
|
+ char pc [256];
|
|
|
+ sprintf( pc, "%f", f );
|
|
|
+ out.length = strlen( pc );
|
|
|
+ out.const_data = false;
|
|
|
+ out.data = (char*) malloc( (out.length+1)*sizeof(char) );
|
|
|
+ memcpy( out.data, pc, out.length+1 );
|
|
|
+ return out;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Convert [double]
|
|
|
+ static string_t Convert( double d )
|
|
|
+ {
|
|
|
+ return Convert( (float)d );
|
|
|
+ }
|
|
|
+
|
|
|
// Clear
|
|
|
void Clear()
|
|
|
{
|
|
|
- DEBUG_ERR( (data==NULL && length!=0) || (data!=NULL && length==0) );
|
|
|
+ DEBUG_ERR( (data==NULL && length!=0) || (data!=NULL && length==0) ); // not my bug
|
|
|
if( data != NULL )
|
|
|
{
|
|
|
if( !const_data )
|
|
|
@@ -210,7 +296,7 @@ class string_t
|
|
|
// CStr
|
|
|
const char* CStr() const
|
|
|
{
|
|
|
- DEBUG_ERR( data == NULL );
|
|
|
+ DEBUG_ERR( data == NULL ); // not my bug
|
|
|
return data;
|
|
|
}
|
|
|
|
|
|
@@ -221,7 +307,7 @@ class string_t
|
|
|
return length;
|
|
|
}
|
|
|
|
|
|
- // Find
|
|
|
+ // Find [char]
|
|
|
uint Find( char c, uint pos = 0 ) const
|
|
|
{
|
|
|
DEBUG_ERR( pos >= length ); // not my bug
|
|
|
@@ -230,11 +316,45 @@ class string_t
|
|
|
{
|
|
|
++pc;
|
|
|
}
|
|
|
- return pc - data;
|
|
|
+ uint diff = pc - data;
|
|
|
+ return (diff == length) ? npos : diff;
|
|
|
+ }
|
|
|
+
|
|
|
+ // RFind [char]
|
|
|
+ uint RFind( char c, uint pos = npos ) const
|
|
|
+ {
|
|
|
+ DEBUG_ERR( pos >= length && pos!=npos ); // not my bug
|
|
|
+ if( pos==npos ) pos = length-1;
|
|
|
+ char* pc = data + pos;
|
|
|
+ while( pc!=data-1 && *pc!=c )
|
|
|
+ {
|
|
|
+ --pc;
|
|
|
+ }
|
|
|
+ return (pc == data-1) ? npos : pc - data;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Find [string_t]
|
|
|
+ uint Find( const string_t& str, uint pos = 0 ) const
|
|
|
+ {
|
|
|
+ DEBUG_ERR( pos >= length ); // not my bug
|
|
|
+ char* pc = strstr( data+pos, str.data );
|
|
|
+ return (pc == NULL) ? npos : pc-data;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Find [char*]
|
|
|
+ uint Find( const char* pc, uint pos = 0 ) const
|
|
|
+ {
|
|
|
+ DEBUG_ERR( pos >= length ); // not my bug
|
|
|
+ char* pc_ = strstr( data+pos, pc );
|
|
|
+ return (pc_ == NULL) ? npos : pc_-data;
|
|
|
}
|
|
|
};
|
|
|
|
|
|
|
|
|
+//================================================================================================================================
|
|
|
+// operator + =
|
|
|
+//================================================================================================================================
|
|
|
+
|
|
|
/// string_t + string_t
|
|
|
inline string_t operator +( const string_t& a, const string_t& b )
|
|
|
{
|
|
|
@@ -247,7 +367,6 @@ inline string_t operator +( const string_t& a, const string_t& b )
|
|
|
return out;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
/// char* + string_t
|
|
|
inline string_t operator +( const char* a, const string_t& b )
|
|
|
{
|
|
|
@@ -265,7 +384,6 @@ inline string_t operator +( const char* a, const string_t& b )
|
|
|
return out;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
/// char + string_t
|
|
|
inline string_t operator +( char a, const string_t& b )
|
|
|
{
|
|
|
@@ -278,7 +396,6 @@ inline string_t operator +( char a, const string_t& b )
|
|
|
return out;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
/// string_t + char*
|
|
|
inline string_t operator +( const string_t& a, const char* b )
|
|
|
{
|
|
|
@@ -293,7 +410,6 @@ inline string_t operator +( const string_t& a, const char* b )
|
|
|
return out;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
/// string_t + char
|
|
|
inline string_t operator +( const string_t& a, char b )
|
|
|
{
|
|
|
@@ -309,6 +425,32 @@ inline string_t operator +( const string_t& a, char b )
|
|
|
}
|
|
|
|
|
|
|
|
|
+//================================================================================================================================
|
|
|
+// operator == =
|
|
|
+//================================================================================================================================
|
|
|
+
|
|
|
+/// string_t == string_t
|
|
|
+inline bool operator ==( const string_t& a, const string_t& b )
|
|
|
+{
|
|
|
+ return strcmp( a.data, b.data ) == 0;
|
|
|
+}
|
|
|
+
|
|
|
+/// string_t == char*
|
|
|
+inline bool operator ==( const string_t& a, const char* b )
|
|
|
+{
|
|
|
+ return strcmp( a.data, b ) == 0;
|
|
|
+}
|
|
|
+
|
|
|
+/// char* == string_t
|
|
|
+inline bool operator ==( const char* a, const string_t& b )
|
|
|
+{
|
|
|
+ return strcmp( a, b.data ) == 0;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+//================================================================================================================================
|
|
|
+// misc =
|
|
|
+//================================================================================================================================
|
|
|
/// For cout support
|
|
|
inline ostream& operator <<( ostream& output, const string_t& str )
|
|
|
{
|