/*  
**  cxstring.h		C++ Runtime 
**
**  Copyright (C)	Microway, Inc. 1987 - 1994.
**			P.O. BOX 79
**			Kingston, MA. 02364
**			(508) 746 - 7341 Voice
**			(508) 746 - 4678 FAX
**			e-mail tech@microway.com
**
**  This program is the property of Microway, Inc, its contents are
**  proprietary information and no part of it is to be disclosed to anyone
**  except employees of Microway, Inc., or as agreed in writing by the
**  President of Microway, Inc.
*/

#include <string.h>
#include <iostream.h>

class String {
   char *str;
   static int compare( const String &, const String &);
  public:
   // constructors for String
String()
  { str = new char[1]; *str = 0; }
String(const char c)
   { str = new char[2]; str[0] = c; str[1] = NULL; }
String(const char *s){
  str = new char [strlen(s)+1];
  strcpy(str,s);
  }
String(const String &s){
  str = new char [strlen(s.str) + 1];
  strcpy(str,s.str);
  }
   // destructor for String
~String()
      { delete str; }
   // operators for String
   friend int operator <  ( const String&, const String& );
   friend int operator >  ( const String&, const String& );
   friend int operator == ( const String&, const String& );
   friend int operator != ( const String&, const String& );
   friend int operator >= ( const String&, const String& );
   friend int operator <= ( const String&, const String& );
   String &operator += ( const String& );
   friend char operator ++ ( String& );
   friend String operator + ( const String&, const String& );
   friend String operator - ( const String&, const String& );
   friend char operator * ( const String& );
   String &operator = ( const String& );

   friend int operator ! ( const String & );
   char get_c(void);
   char *get_s(void);
   char operator()( unsigned );
   String operator()( unsigned, unsigned );

   friend ostream& operator << ( ostream& , const String& );
   friend istream& operator >> ( istream&, String& );
   // interface to "C" library through member functions
   size_t  _strlen( void );
   int     _memcmp( const String&, const String&, size_t );
   void *  _memchr( const String&, int, size_t );
   void *  _memset( String&, int, size_t );
   char *  _strchr( String&, int );
   int     _strcoll( const String&, const String& );
   size_t  _strcspn( const String&, const String& );
   char *  _strncat( String&, const String&, size_t );
   int     _strncmp( const String&, const String&, size_t );
   char *  _strncpy( String &, const String&, size_t );
   char *  _strpbrk( const String&, const String& );
   char *  _strrchr( const String&, int c );
   size_t  _strspn( const String&, const String& );
   char *  _strstr( const String&, const String& );
   char *  _strtok( const String&, const String& );
   size_t  _strxfrm( String&, const String&, size_t );
      };   // end of String class
int String::compare(const String& s, const String& t){
   if (!t.str) return (s.str != 0);
   if (!s.str) return (-1);
   return (strcmp(s.str, t.str));
   }
char String::get_c(void){
   return *str;
   }
char * String::get_s(void){
   return str;
   }
String& String::operator=(const String& s){
   char *new_str;
   if (s.str){
      new_str = new char[strlen(s.str)+1];
      strcpy(new_str,s.str);
      }
   else
     new_str = 0;
   delete str;
   str = new_str;
   return *this;
   }
String& String::operator+=(const String& s){
   if (s._strlen()){
      char *new_str = new char[s._strlen() + _strlen() + 1];
      if (_strlen())
         strcpy(new_str,str);
      else
         *str = ' ';
      strcat(new_str, s.str);
      delete str;
      str = new_str;
      }
   return *this;
   }
String operator + (const String& s, const String& t){
   String r = s;
   r += t;
   return r;
   }
char operator * (const String &s){
   return s.str[0];
   }
int operator ! (const String &s){
   return (s.str[0] != NULL);
   }
char operator ++ (String &s){
   char c = s.str[0];
   if (c) s.str++;
   return c;
   }
char String::operator()(unsigned int cnt) {
   if (cnt  _strlen())
      return str[cnt];
      return NULL;
   }
int operator == (const String& s, const String& t){
   return String::compare(s,t) == 0;
   }
int operator != (const String& s, const String& t){
   return String::compare(s,t) != 0;
   }
int operator >= (const String& s, const String& t){
   return String::compare(s,t) >= 0;
   }
int operator <= (const String& s, const String& t){
   return String::compare(s,t) <= 0;
   }
int operator > (const String& s, const String& t){
   return String::compare(s,t) > 0;
   }
int operator < (const String& s, const String& t){
   return String::compare(s,t) < 0;
   }
ostream& operator << (ostream& my_cout, const String& s){
   my_cout << s.str;
   return my_cout;
   }
istream& operator >> (istream& i, String& s){
   char c;
   s = "";
   while (i.get(c) && isspace(c));
   if (i){
      do
         s += c;
         while (i.get(c) && !isspace(c));
      if (i)
         i.putback(c);
      }
   return i;
   }
/*
**
**  overloaded functions which class String can use "C" string
**  functions. Notice that the following "C" string functions
**  are not defined because their functionality can be realized
**  through overloaded operators:
**
**  memcpy(), memmove(), strcat(), strcmp(), strcpy()
**
**  strerror() can be called independent of class String.
*/
extern "C" size_t strlen( const char *);
inline size_t strlen( const String& s ){
   return s._strlen();
   }
extern "C"  int memcmp( const void *, const void *, size_t n );
inline  int memcmp( const String& s1, const String& s2, size_t n){
   return s1._memcmp( s1, s2, n );
   }
extern "C" void *memchr( const void *, int, size_t );
inline void *memchr( const String& s, int c, size_t n ){
   return s._memchr( s, c, n );
   }
extern "C" void *memset( void *, int , size_t );
inline void *memset( String& s, int c, size_t n ){
   return s._memset( s, c, n );
   }
extern "C" char *strchr( const char *, int );
inline char *strchr( String& s, int n ){
   return s._strchr( s, n );
   }
extern "C" int strcoll( const char *, const char * );
inline int strcoll( const String& s1, const String& s2 ){
   return s1._strcoll( s1, s2 );
   }
extern "C" size_t strcspn( const char *, const char * );
inline size_t strcspn( const String& s1, const String& s2 ){
   return s1._strcspn( s1, s2 );
   }
extern "C" char *strncat( char *, const char *, size_t );
inline char *strncat( String& s1, const String& s2, size_t n ){
   return s1._strncat( s1, s2, n );
   }
extern "C" int strncmp( const char *, const char *, size_t );
inline int strncmp( const String& s1, const String& s2, size_t n ){
   return s1._strncmp( s1, s2, n );
   }
extern "C" char *strncpy( char *, const char *, size_t n );
inline char *strncpy( String& s1, const String& s2, size_t n ){
   return s1._strncpy( s1, s2, n );
   }
extern "C" char *strpbrk( const char *, const char * );
inline char *strpbrk( const String& s1, const String& s2 ){
   return s1._strpbrk( s1, s2 );
   }
extern "C" char *strrchr( const char *, int );
inline char *strrchr( const String& s, int c){
   return s._strrchr( s, c );
   }
extern "C" size_t strspn( const char *, const char * );
inline size_t strspn( const String& s1, const String& s2 ){
   return s1._strspn( s1, s2 );
   }
extern "C" char *strstr( const char *, const char * );
inline char *strstr( const String& s1, const String& s2 ){
   return s1._strstr( s1, s2 );
   }
extern "C" char *strtok( char *, const char * );
inline char *strtok( String& s1, const String& s2 ){
   return s1._strtok( s1, s2 );
   }
extern "C" size_t strxfrm( char *, const char *, size_t n);
inline  size_t strxfrm( String& s1, const String& s2, size_t n ){
   return s1._strxfrm( s1, s2, n );
   }
size_t String::_strlen(){
   if (str)
      return strlen( str );
   return 0;
   }
int String::_memcmp( const String& s1, const String& s2, size_t n ){
   return memcmp( s1.str, s2.str, n );
   }
void * String::_memchr( const String& s, int c, size_t n ){
   return memchr( s.str, c, n );
   }
void * String::_memset( String& s, int c, size_t n ){
   return memset( s.str, c, n );
   }
char * String::_strchr( String& s, int c ){
   return strchr( s.str, c );
   }
int String::_strcoll( const String& s1, const String& s2 ){
   return strcoll( s1.str, s2.str );
   }
size_t String::_strcspn( const String& s1, const String& s2 ){
   return strcspn( s1.str, s2.str );
   }
char * String::_strncat( String& s1, const String& s2, size_t n ){
   return strncat( s1.str, s2.str, n );
   }
int String::_strncmp( const String& s1, const String& s2, size_t n ){
   return strncmp( s1.str, s2.str, n );
   }
char * String::_strncpy( String& s1, const String& s2, size_t n ){
   return strncpy( s1.str, s2.str, n );
   }
char * String::_strpbrk( const String& s1, const String& s2 ){
   return strpbrk( s1.str, s2.str );
   }
char * String::_strrchr( const String& s1, int c ){
   return strrchr( s1.str, c );
   }
size_t String::_strspn( const String& s1, const String& s2 ){
   return strspn( s1.str, s2.str );
   }
char * String::_strstr( const String& s1, const String& s2 ){
   return strstr( s1.str, s2.str );
   }
char * String::_strtok( const String& s1, const String& s2 ){
   return strtok( s1.str, s2.str );
   }
size_t String::_strxfrm( String& s1, const String& s2, size_t n ){
   return strxfrm( s1.str, s2.str, n );
   }
