// str.cpp - implementation of simple string class
//
// CSE374 example, 5/08-11/15 hp

#include <cstring>
#include <iostream>
#include "str.h"

#define TRACE(what)  cout << "str: " << what << " called" << endl

using namespace std;

// constructors
// create empty string
str::str() {
  TRACE("null constructor");
  // allocate empty string
  st = new char[1];
  st[0] = '\0';
}

// create str from c-string
str::str(const char *s) {
  TRACE("c-string constructor");
  int len = strlen(s);
  st = new char[len+1];
  strcpy(st, s);
}

// copy constructor
str::str(const str &s) {
  TRACE("copy constructor");
  int len = strlen(s.st);
  st = new char[len+1];
  strcpy(st, s.st);
}

// destructor
str::~str() {
  TRACE("destructor");
  delete [] st;
}

// return length of this string
int str::length() {
  return strlen(st);
}

// return a c-string with a copy of the contents of this string
char * str::c_str() {
  char * result = new char[strlen(st)+1];
  strcpy(result, st);
  return result;
}


// append contents of s to the end of this string
void str::append(const str &s) {
  char *newst = new char[strlen(st) + strlen(s.st) + 1];
  strcpy(newst, st);
  strcat(newst, s.st);
  delete [] st;
  st = newst;
}

// string assignment - assign s to this str and return this str
// (way beyond CSE303/374, but pretty cool nevertheless)
str & str::operator=(const str &s) {
  TRACE("str assignment");
  // do nothing if trying to assign a string to itself
  if (this == &s) {
    return *this;
  }

  // Allocate space for data if source length is different
  if (strlen(st) != strlen(s.st)) {
    delete [] st;
    st = new char[strlen(s.st)+1];
  }

  // copy characters and return
  strcpy(st, s.st);
  return *this;
}