// ------------------------------- //
// -------- Start of File -------- //
// ------------------------------- //
// ----------------------------------------------------------- // 
// C++ Source Code File Name: string.cpp 
// Compiler Used: MSVC40, DJGPP 2.7.2.1, GCC 2.7.2.1, HP CPP 10.24
// Produced By: Doug Gaer 
// File Creation Date: 04/05/1996 
// Date Last Modified: 03/17/1999
// ----------------------------------------------------------- // 
// ------------- Program Description and Details ------------- // 
// ----------------------------------------------------------- // 
/*
THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND.
THE ENTIRE RISK OF THE QUALITY AND PERFORMANCE OF THIS SOFTWARE
IS WITH YOU. SHOULD ANY ELEMENT OF THIS SOFTWARE PROVE DEFECTIVE,
YOU WILL ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR, OR
CORRECTION.

A simple fixed length (static) string class.
*/
// ----------------------------------------------------------- // 
#include <string.h>
#include <iostream.h>
#include <iomanip.h>

const unsigned Len = 25; // String length of the fixed string

// (F)ixed (S)tring class
class FString 
{ 
public:
  FString() { Clear(); }
  FString(char *s) { Clear(); Store(s); }
  ~FString() { }    

  FString(const FString &s) { Copy(s); }

  FString &operator=(const FString &s) {
    if(this != &s) Copy(s);
    return *this;
  }

public:
  void Store(char *s);
  void Clear();
  void Copy(const FString &s);
  char *c_str();
  
public:
  friend int operator==(const FString &a, const FString &b) {
    return strcmp(a.str, b.str) == 0;
  }

  friend int operator<(const FString &a, const FString &b) {
    return strcmp(a.str, b.str) < 0;
  }

  friend int operator>(const FString &a, const FString &b) {
    return strcmp(a.str, b.str) > 0;
  }

  friend int operator!=(const FString &a, const FString &b) {
    return strcmp(a.str, b.str) != 0;
  }
  
  friend ostream &operator<<(ostream &os, const FString &s) {
    return os.write(s.str, strlen(s.str));
  }

  friend istream &operator>>(istream &os, FString &s) {
    os >> setw(strlen(s.str)) >> s.str;
    return os;
  }
	       
private:
  char str[Len];
};

void FString::Clear()
{
  for(unsigned i = 0; i < Len; i++)
    str[i] = 0;
}

void FString::Store(char *s)
{
  char *buf = new char[Len];
  buf[Len] = '\0';
  memcpy(buf, s, Len);
  for(unsigned i = 0; i < Len; i++)
    str[i] = buf[i];
}

void FString::Copy(const FString &s)
{
  Clear();

  for(unsigned i = 0; i < Len; i++)
    str[i] = s.str[i];
}

char *FString::c_str()
{
  char *buf = new char[Len];
  buf[Len] = '\0';
  memcpy(buf, str, Len);
  return buf;
}

// Test program code starts here
// *********************************************************** //
int main()
{
  cout << "Constructing FString class objects..." << endl;
  FString a("DOG");
  FString b("CAT");
  FString c("MOUSE");
  FString d("BIRD");

  cout << "Testing copy constructor..." << endl;
  FString e(a);  

  cout << "Testing assignment operator..." << endl;
  a = b;

  cout << endl;
  cout << "Testing overloaded << operator..."  << endl;
  cout << a << ' ' << b  << ' ' << c  << ' ' << d << ' ' << e << endl;

  cout << endl;
  cout << "Testing c_str() function..." << endl;
  cout << a.c_str() << endl;
  cout << b.c_str() << endl;
  cout << c.c_str() << endl;
  cout << d.c_str() << endl;
  cout << e.c_str() << endl;

  cout << endl;
  cout << "Testing overloaded >> operator..." << endl;
  FString buf;
  cout << "Enter a string up to " << Len << " characters long: ";
  cin >> buf;

  cout << endl;
  cout << "Data entered = " << buf << endl;

  cout << endl;
  cout << "Testing FString boundaries..." << endl;
  char *s = "ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789";
  FString x(s);
  cout << "Alphabet string = " << x.c_str() << endl;
  return 0;
}  
// ----------------------------------------------------------- // 
// ------------------------------- //
// --------- End of File --------- //
// ------------------------------- //
