📄 cs_string.cpp
字号:
/*
*
* cs_string.cpp
*
* Copyright (c) 2001, 2002
* Andrew Fedoniouk - andrew@terra-informatica.org
* Portions: Serge Kuznetsov - kuznetsov@deeptown.org
*
* See the file "COPYING" for information on usage
* and redistribution of this file
*
*/
#include <iostream.h>
#include <stdlib.h>
#include <iomanip.h>
#include <string.h>
#include <ctype.h>
#include <stdarg.h>
#include "cs_basic.h"
#include "cs_string.h"
#include "cs_list.h"
#include <stdio.h>
#if !defined(_WIN32)
#define _vsnprintf vsnprintf
#endif
namespace tool
{
string::data string::null_data;
/****************************************************************************/
string::data *
string::new_data ( int length, int refcount )
{
if ( length > 0 )
{
int to_allocate = ( length + 0x10 ) & ~0xF;
//assert ( to_allocate >= length );
data *dt = (data *) new byte [ sizeof ( data ) + to_allocate ];
dt->ref_count = refcount;
dt->length = length;
dt->allocated = to_allocate;
dt->chars [ length ] = '\0';
//memset ( dt->chars, 0, to_allocate + 1 );
return dt;
}
else
return &null_data;
}
void
string::set_length ( int length, bool preserve_content )
{
if ( ( length <= my_data->allocated ) && ( my_data->ref_count <= 1 ) )
{
my_data->length = length;
my_data->chars [ length ] = '\0';
return;
}
data *dt = new_data ( length, 1 );
if ( preserve_content )
::memcpy ( dt->chars, my_data->chars, my_data->length );
release_data();
my_data = dt;
}
void
string::release_data ( void )
{
if ( ( my_data != &null_data ) && ( --my_data->ref_count == 0 ) )
delete (byte *) my_data;
}
void
string::set_data ( data *data )
{
release_data();
my_data = data;
my_data->ref_count++;
}
void
string::make_unique ()
{
if ( my_data->ref_count > 1 )
{
data *data = new_data ( length(), 1 );
::memcpy ( data->chars, chars(), length() );
my_data->ref_count--;
my_data = data;
}
}
/****************************************************************************/
string
operator+ ( const char *s1, const string &s2 )
{
const int s1_length = ::strlen ( s1 );
if ( s1_length == 0 )
return s2;
else
{
string newstring;
newstring.set_length ( s1_length + s2.length() );
::memcpy ( newstring.chars(), s1, s1_length );
::memcpy ( &( newstring.chars() ) [ s1_length ], s2.chars(), s2.length() );
return newstring;
}
}
/****************************************************************************/
string
string::operator+ ( const string &s ) const
{
if ( length() == 0 )
return s;
else if (s.length() == 0)
return *this;
else
{
string newstring;
newstring.set_length ( length() + s.length() );
if ( length() )
::memcpy ( newstring.chars(), chars(), length() );
if ( s.length() )
::memcpy ( &( newstring.chars() ) [ length() ], s.chars(), s.length() );
return newstring;
}
}
/****************************************************************************/
string
string::operator+ ( const char *s ) const
{
const int s_length = ::strlen ( s );
if ( s_length == 0 )
return *this;
else
{
string newstring;
newstring.set_length ( length() + s_length );
::memcpy ( newstring.chars(), chars(), length() );
::memcpy ( &( newstring.chars() ) [ length() ], s, s_length );
return newstring;
}
}
/****************************************************************************/
bool
string::is_whitespace () const
{
if ( my_data == &null_data )
return false;
for ( register const char *p = chars(); *p; p++ )
if ( !isspace ( *p ) )
return false;
return true;
}
/****************************************************************************/
string
string::substr ( int index, int len ) const
{
// a negative index specifies an index from the right of the string.
if ( index < 0 )
index += length();
// a length of -1 specifies the rest of the string.
if ( len == -1 )
len = length() - index;
string newstring;
if ( index < 0 || index >= length() || len < 0 || len > length() - index )
return newstring; // error in parameters;
newstring.set_length ( len );
::memcpy ( newstring.chars(), &chars() [ index ], len );
return newstring;
}
/****************************************************************************/
string &
string::cut ( int index, int len )
{
if ( len == 0 )
return *this;
// a negative index specifies an index from the right of the string.
if ( index < 0 )
index += length();
// a length of -1 specifies the rest of the string.
if ( len == -1 )
len = length() - index;
make_unique();
assert ( ( index >= 0 ) && ( index < length() ) &&
( len > 0 ) && ( len <= ( length() - index ) ) );
assert ( index + my_data->length - index - len <= my_data->allocated );
::memmove ( my_data->chars + index, my_data->chars + index + len,
my_data->length - index - len );
set_length ( my_data->length - len );
return *this;
}
/****************************************************************************/
string&
string::replace_substr ( const char *s, int index, int len )
{
assert ( s );
return replace_substr ( s, strlen ( s ), index, len );
}
/****************************************************************************/
string &
string::replace_substr ( const char *s, int s_len, int index, int len )
{
// a negative index specifies an index from the right of the string.
if ( index < 0 )
index += length();
// a length of -1 specifies the rest of the string.
if ( len == -1 )
len = length() - index;
assert ( index >= 0 && index < length() && len >= 0 || len < ( length() - index ) );
make_unique();
if ( len == s_len && my_data->ref_count == 1 )
::memcpy ( &chars() [ index ], s, len );
else
{
int prev_len = length();
set_length ( prev_len - len + s_len, true );
::memmove ( &chars() [ index + s_len ], &chars() [ index + len ], prev_len - len - index );
if ( s_len > 0 )
{
::memcpy ( &chars() [ index ], s, s_len );
}
}
return *this;
}
/****************************************************************************/
string &
string::insert ( const char *s, int s_length, int index )
{
// a negative index specifies an index from the right of the string.
if ( index < 0 )
index += length();
assert ( index >= 0 && index < length() );
if ( s_length > 0 )
{
make_unique();
int prev_len = length();
set_length ( prev_len + s_length, true );
::memmove ( &chars() [ index + s_length ], &chars() [ index ],
prev_len - index );
::memcpy ( &chars() [ index ], s, s_length );
}
return *this;
}
/****************************************************************************/
string&
string::trim()
{
int start = 0;
int end = length() - 1;
const unsigned char *p;
for ( p = (unsigned char *) chars(); *p; p++ )
if ( isspace ( *p ) )
start++;
else
break;
for ( p = (unsigned char *) chars() + length() - 1;
p >= ( (unsigned char *) chars() + start ); p-- )
if ( isspace ( *p ) )
end--;
else
break;
make_unique();
if ( start > end )
{
set_length ( 0 );
return *this;
}
int newlen = end - start + 1;
if ( start )
::memmove ( chars(), chars() + start, newlen );
set_length ( newlen, true );
return *this;
}
/****************************************************************************/
string &
string::printf ( const char *fmt, ... )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -