⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cs_string.cpp

📁 c-smile 一个语法类似与JS 又有点像C++的 编译器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*
*
* 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 + -