/*
+ string.cc - implement String
- string.cc - implement String
-
- (c) 1997 Han-Wen Nienhuys & Jan Nieuwenhuizen
+ (c) 1997--2006 Han-Wen Nienhuys & Jan Nieuwenhuizen
+*/
+#if !STD_STRING
+
+#ifndef _GNU_SOURCE // we want memmem
+#define _GNU_SOURCE
+#endif
- */
+#include "std-string.hh"
-#include <stdlib.h>
-#include <stdio.h>
+#include <cstdlib>
+#include <cstdio>
+#include <cassert>
+#include <cstring>
-#include <assert.h>
-#include <string.h>
+using namespace std;
-#include "string.hh"
#include "libc-extension.hh"
#include "string-convert.hh"
-#ifdef STRING_DEBUG
-void* mymemmove( void* dest, void const* src, size_t n );
-#define memmove mymemmove
-#endif
+/* std::string interface */
-// return array, alloced with new.
-Byte*
-String::copy_byte_p() const
+namespace std {
+
+String::String (char const *s, int n)
{
- Byte const* src = strh_.byte_c_l();
- Byte* dest = new Byte[strh_.length_i() + 1];
- memcpy( dest, src, strh_.length_i() + 1 );
- return dest;
+ strh_.set ((Byte const *)s, n);
}
-void
-String::print_on(ostream& os) const
+
+String::String (String const &s, int pos, ssize n)
{
- if (strh_.null_terminated_b())
- os << ch_c_l();
- else
- for ( int i = 0; i < length_i(); i++ )
- os << (Byte)(*this)[ i ];
+ *this = s.substr (pos, n);
}
-\f
-/*
- copying, constructing.
- */
-String&
-String::operator = (String const&source )
+
+String::String (int n, char c)
{
- strh_ = source.strh_;
- return *this;
+ *this = String_convert::char_string (c, n);
}
-
-String::String(Rational r)
+String &
+String::operator = (String const &source)
{
- *this = String_convert::rational_str(r);
+ strh_ = source.strh_;
+ return *this;
}
-String::String (double f, char const* fmt)
-{
- *this= String_convert::double_str(f,fmt);
+String
+String::substr (int pos, ssize n) const
+{
+#if 1
+ if (n == (ssize)-1 || n == (ssize)INT_MAX || n == NPOS)
+ n = length () - pos;
+ return cut_string (pos, n);
+#else
+ if (n == (ssize)-1 || n == (ssize)INT_MAX || n == NPOS)
+ n = length () - pos;
+ if (pos == 0)
+ return left_string (n);
+ else
+ return right_string (length () - pos).left_string (n);
+#endif
}
-String::String( char c, int n )
+String
+String::insert (ssize pos, String s)
{
- *this = String_convert::char_str (c,n);
+ *this = substr (0, pos) + s + substr (pos + 1);
+ return *this;
}
-/**
- @see
- String_convert::int_str
- */
-String::String(int i, const char * format )
+ssize
+String::copy (char *buf, ssize n, ssize pos) const
{
- *this = String_convert::int_str(i,format);
+ assert (pos == 0);
+ memcpy (buf, strh_.to_bytes (), strh_.length () + 1);
+ return n; // ?
}
-String::String (bool b)
+int
+String::compare (String const &s) const
{
- *this = (char const* ) (b ? "true" : "false");
+ char const *p1 = c_str ();
+ char const *p2 = s.c_str ();
+ if (p1 == p2)
+ return 0;
+
+ /*
+ don't forget the terminating '\0'
+ */
+ int f = min (length (), s.length ());
+ int cmp_length = 1+ f;
+ int i = memcmp (p1, p2, cmp_length);
+ return i;
}
-String::String( char const* source )
-{
- assert(source);
- strh_ = source;
+char const *
+String::data () const
+{
+ return (char const*) to_bytes ();
}
-String::String( Byte const* byte_l, int length_i )
-{
- strh_.set( byte_l, length_i );
+bool
+String::empty () const
+{
+ return !length ();
}
-\f
-void
-String::append(String s)
+
+int
+String::find (char c, int pos) const
{
- strh_.append( s.byte_c_l(), s.length_i() );
+ String f = right_string (length () - pos);
+ ssize n = f.index (c);
+ if (n != NPOS)
+ return pos + n;
+ return NPOS;
}
-void
-String::operator +=(String s)
+
+int
+String::find (char const *c, int pos) const
{
- append(s);
+ return find (String (c), pos);
}
-void
-String::prepend(String s)
+int
+String::find (String s, int pos) const
{
- s += *this;
- *this = s;
+ if (!pos)
+ return index (s);
+ String f = right_string (length () - pos);
+ ssize n = f.index (s);
+ if (n != NPOS)
+ return pos + n;
+ return NPOS;
}
int
-String::length_i() const
+String::rfind (char c) const
{
- return strh_.length_i();
+ return index_last (c);
}
-Byte const*
-String::byte_c_l() const
+String
+String::replace (int pos, int n, String str)
{
- return strh_.byte_c_l();
+ return this->substr (0, pos) + str + this->substr (pos + n);
}
-char const*
-String::ch_c_l() const
+void
+String::append (String s)
{
- return strh_.ch_c_l();
+ strh_.append (s.to_bytes (), s.length ());
}
-Byte*
-String::byte_l()
+void
+String::operator += (String s)
{
- return strh_.byte_l();
+ append (s);
}
-char*
-String::ch_l()
+int
+String::length () const
{
- return strh_.ch_l();
+ return strh_.length ();
}
-/**
- Do a signed comparison, analogous to memcmp;
- */
+
+
+
+/* String */
+
int
-String::compare_i(String const& s1, String const& s2 )
+String::compare (String const &s1, String const &s2)
{
- Byte const* p1 = s1.byte_c_l();
- Byte const* p2 = s2.byte_c_l();
- if ( p1 == p2 )
- return 0;
+ return s1.compare (s2);
+}
- int i1 = s1.length_i();
- int i2 = s2.length_i();
+#ifdef STRING_DEBUG
+void *mymemmove (void *dest, void const *src, size_t n);
+#define memmove mymemmove
+#endif
+
+// return array, alloced with new.
+Byte *
+String::get_copy_byte () const
+{
+ Byte const *src = strh_.to_bytes ();
+ Byte *dest = new Byte[strh_.length () + 1];
+ memcpy (dest, src, strh_.length () + 1);
+ return dest;
+}
- int result= memcmp( p1, p2, i1 <? i2 );
- return result ? result : i1-i2;
+char *
+String::get_copy_str0 () const
+{
+ return (char *)get_copy_byte ();
}
\f
-int
-String::index_last_i( char const c ) const
+
+#if 0
+void
+String::prepend (String s)
{
- if ( !length_i() )
- return -1;
+ s += *this;
+ *this = s;
+}
+
+#endif
+
- char const* me = strh_.ch_c_l();
- char const* p = memrchr(me, length_i(), c );
- if ( p )
- return p - me;
- return -1;
+Byte const *
+String::to_bytes () const
+{
+ return strh_.to_bytes ();
+}
+
+Byte *
+String::get_bytes ()
+{
+ return strh_.get_bytes ();
}
+\f
int
-String::index_last_i( char const* string ) const // UGK!
-{
- assert(false); // broken
- int length = strlen( string ); // ugrh
- if ( !length_i() || !length )
- return -1;
-
- int next_i = index_i( string );
- if ( next_i == -1 )
- return -1;
-
- int index_i = 0;
- while( next_i >= 0 ) {
- index_i += next_i;
- next_i = right_str( length_i() - index_i - length ).index_i( string );
- }
- return index_i;
+String::index_last (char const c) const
+{
+ if (!length ())
+ return NPOS;
+
+ char const *me = strh_.c_str ();
+ char const *p = (char const *)memrchr ((Byte *)me, length (), c);
+ if (p)
+ return p - me;
+ return NPOS;
}
/** find a character.
- @return
- the index of the leftmost character #c# (0 <= return < length_i()),
- or -1 if not found.
+@return
+the index of the leftmost character #c# (0 <= return < length ()),
+or NPOS if not found.
- ? should return length_i()?, as in string.left_str(index_i(delimiter))
+? should return length ()?, as in string.left_string (index (delimiter))
*/
int
-String::index_i(char c ) const
+String::index (char c) const
{
- char const* me = strh_.ch_c_l();
- char const* p = (char const *) memchr( me,c, length_i());
- if ( p )
- return p - me;
- return -1;
+ char const *me = strh_.c_str ();
+ char const *p = (char const *) memchr (me, c, length ());
+ if (p)
+ return p - me;
+ return NPOS;
}
/**
- find the substring.
+ find a substring.
- @return
- index of leftmost occurrence of #searchfor#
- */
+ @return
+ index of leftmost occurrence of #searchfor#
+*/
int
-String::index_i( String searchfor ) const
+String::index (String searchfor) const
{
- char const* me = strh_.ch_c_l();
- char const* p = (char const *) memmem(
- me, length_i(), searchfor.ch_c_l(), searchfor.length_i());
-
- if ( p )
- return p - me;
- else
- return -1;
+ char const *me = strh_.c_str ();
+
+ char const *p
+ = (char const *) memmem (me, length (),
+ searchfor.c_str (), searchfor.length ());
+
+ if (p)
+ return p - me;
+
+ return NPOS;
}
/** find chars of a set.
- @return
- the index of the leftmost occurance of an element of #set#
- */
+@return
+
+the index of the leftmost occurance of an element of #set#. NPOS if
+nothing is found.
+*/
int
-String::index_any_i( String set ) const
-{
- int n = length_i();
- if ( !n )
- return -1;
-
- const void * me_l = (const void*) strh_.ch_c_l();
- for (int i=0; i < set.length_i(); i++) {
- char * found=(char*) memchr(me_l, set[i], n );
- if (found) {
- return found - me_l;
- }
+String::index_any (String set) const
+{
+ int n = length ();
+ if (!n)
+ return NPOS;
+
+ void const *me = (void const *) strh_.c_str ();
+ for (int i = 0; i < set.length (); i++)
+ {
+ char *found = (char *) memchr (me, set[i], n);
+ if (found)
+ return found - (char const *)me;
}
- return -1;
+ return NPOS;
}
\f
String
-String::left_str( int n ) const
+String::left_string (int n) const
{
- if (n >= length_i())
- return *this;
+ if (n >= length ())
+ return *this;
- String retval;
- if (n < 1)
- return retval;
-
- retval = *this;
- retval.strh_.trunc(n);
+ String retval;
+ if (n < 1)
return retval;
+
+ retval = *this;
+ retval.strh_.trunc (n);
+ return retval;
}
String
-String::right_str( int n ) const
+String::right_string (int n) const
{
- if (n > length_i())
- return *this;
-
- if ( n < 1)
- return "";
-
- return String( strh_.byte_c_l() + length_i() - n, n );
-}
+ if (n > length ())
+ return *this;
+ if (n < 1)
+ return "";
+
+ return String (strh_.c_str () + length () - n, n);
+}
String
-String::nomid_str( int index_i, int n ) const
+String::nomid_string (int index_i, int n) const
{
- if ( index_i < 0 ) {
- n += index_i;
- index_i = 0;
+ if (index_i < 0)
+ {
+ n += index_i;
+ index_i = 0;
}
- if ( n <= 0)
- return *this;
-
- return
- left_str( index_i ) +
- right_str( length_i() - index_i - n ) ;
+ if (n <= 0)
+ return *this;
+
+ return left_string (index_i) + right_string (length () - index_i - n);
}
-/*
- proposal: change to "cut()"
- */
String
-String::mid_str( int index_i, int n ) const
+String::cut_string (int index_i, int n) const
{
- if (index_i <0) {
- n += index_i;
- index_i=0;
+ if (index_i < 0)
+ {
+ n += index_i;
+ index_i = 0;
}
-
- if ( !length_i() || ( index_i < 0 ) || ( index_i >= length_i() ) || ( n < 1 ) )
- return String();
- if ( ( n > length_i() ) || ( index_i + n > length_i() ) )
- n = length_i() - index_i;
+ if (!length () || (index_i < 0) || (index_i >= length ()) || (n < 1))
+ return String ();
+
+ if ((n > length ()) || (index_i + n > length ()))
+ n = length () - index_i;
- return String( byte_c_l() + index_i, n );
+ return String (c_str () + index_i, n);
}
\f
-String
-String::upper_str() const
-{
- String str = *this;
- str.to_upper();
- return str;
-}
-void
-String::to_upper()
+
+int
+String::to_int () const
{
- char *s = (char*)strh_.byte_l();
- strnupr( s ,length_i());
+ return String_convert::dec2int (*this);
}
-void
-String::to_lower()
+double
+String::to_double () const
{
- char* s = strh_.ch_l();
- strnlwr(s,length_i());
+ return String_convert::dec2double (*this);
}
+#ifdef STREAM_SUPPORT
+#include <iostream>
-String
-String::lower_str() const
+ostream &
+operator << (ostream &os, String d)
{
- String str = *this;
- str.to_lower();
- return str;
+ d.print_on (os);
+ return os;
}
-String
-String::reversed_str() const
+
+void
+String::print_on (ostream &os) const
{
- String str = *this;
- strrev( str.byte_l(), str.length_i() );
- return str;
+ if (!strh_.is_binary_bo ())
+ os << c_str ();
+ else
+ for (int i = 0; i < length (); i++)
+ os << (Byte) (*this)[ i ];
}
+#endif
-int
-String::value_i() const
-{
- return String_convert::dec2_i( *this );
+String
+String::substitute (String find, String replace)
+{
+ int n = find.length ();
+ int m = replace.length ();
+ for (ssize i = index (find), j = 0; i != NPOS;
+ i = right_string (length () - j).index (find))
+ {
+ *this = left_string (i + j)
+ + replace
+ + right_string (length () - j - i - n);
+ j += i + m;
+ }
+ return *this;
}
-double
-String::value_f() const
+String
+String::substitute (char find, char replace)
{
- return String_convert::dec2_f( *this );
+ for (ssize i = index (find); i != NPOS; i = index (find))
+ (*this)[i] = replace;
+ return *this;
+}
+
}
+#endif /* !STD_STRING */