Download the string cpp file.

#include "str.h"


//_______________________________________________
// constructor: set the member string with the default size

Str::Str()
{
  size   = 1;
  length = 0;
  string = new char [1];
  if (!string)
    AlError();

  *string = '\0';
}

//_______________________________________________
// constructor: set the member string with a given size

Str::Str(long sz)
{
  if (sz < 0)
    sz = 0;

  size    = sz + 1;
  length  = 0;
  string  = new char [size];
  if (!string)
    AlError();

  *string = '\0';
}

//_______________________________________________
// constructor: copy a string object

Str::Str(const Str &src)
{
  size   = src.size;
  length = src.length;
  string = new char [size];
  if (!string)
    AlError();

  strcpy(string, src.string);
}

//_______________________________________________
// constructor: copy a string object

Str::Str(const Str *src)
{
  size   = src->size;
  length = src->length;
  string = new char [size];
  if (!string)
    AlError();

  strcpy(string, src->string);
}

//_______________________________________________
// constructor: copy a character array

Str::Str(const char *src)
{
  length = strlen(src);
  size   = length + 1;
  string = new char [size];
  if (!string)
    AlError();

  strcpy(string, src);
}

//_______________________________________________
// constructor: copy a character

Str::Str(const char src)
{
  size   = 2;
  length = 1;
  string = new char [2];
  if (!string)
    AlError();

  string[0] = src;
  string[1] = '\0';
}

//_______________________________________________
// constructor: repeat a character

Str::Str(const char src, long len)
{
  size   = len + 1;
  length = len;
  string = new char [size];
  if (!string)
    AlError();

  memset(string, src, len);
  string[len] = '\0';
}

//_______________________________________________
//_______________________________________________
// Clear the member string, set it to length zero.

void Str::Clear()
{
  *string = '\0';
  length  = 0;
}

//_______________________________________________
//_______________________________________________
// Minimize the size of the string.

void Str::SetSize()
{
  long sz = length + 1;
  if (size != sz)
  {
    char *str = new char [sz];
    if (!str)
      AlError();

    size = sz;
    strcpy(str, string);
    delete [] string;
    string = str;
  }
}

//_______________________________________________
// Set the size of the member string.

void Str::SetSize(long sz)
{
  if (size != sz)
  {
    char *str = new char [sz];
    if (!str)
      AlError();

    size = sz;
    delete [] string;
    string = str;
  }

  *string = '\0';
  length  = 0;
}

//_______________________________________________
// Set the size of the member string.

void Str::SetLength(long len)
{
  len++;
  if (size != len)
  {
    char *str = new char [len];
    if (!str)
      AlError();

    size = len;
    delete [] string;
    string = str;
  }

  *string = '\0';
  length  = 0;
}

//_______________________________________________
//_______________________________________________
// Get the charactor in the member string at index.

char &Str::operator[](long index)
{
  if (index < 0 || length <= index)
    RaError();

  return string[index];
}

//_______________________________________________
// Get the charactor in the member string at index.

char Str::Get(long index)
{
  if (index < 0 || length <= index)
    RaError();

  return string[index];
}

//_______________________________________________
// Set the charactor in the member string at index.

void Str::Put(const char src, long index)
{
  if (index < 0 || length <= index)
    RaError();

  string[index] = src;
}

//_______________________________________________
//_______________________________________________

bool Str::HasContent() const
{
  char *ptr;
  for (ptr = string; *ptr; ptr++)
  {
    if (!isspace(*ptr))
      return true;
  }

  return false;
}

//_______________________________________________
//_______________________________________________

bool Str::Compare(const Str &src) const
{
  if (src.length <= length)
    return !strncmp(string, src.string, src.length);

  return false;
}

//_______________________________________________

bool Str::Compare(const char *src) const
{
  long len = strlen(src);
  if (len <= length)
    return !strncmp(string, src, len);

  return false;
}

//_______________________________________________

bool Str::Compare(const char src) const
{
  return (length && *string == src);
}

//_______________________________________________

bool Str::Compare(const Str &src, long posn)
{
  if (posn < 0 || length <= posn)
    RaError();

  long len = length - posn;
  if (src.length <= len)
    return !strncmp(string + posn, src.string, src.length);

  return false;
}

//_______________________________________________

bool Str::Compare(const char *src, long posn)
{
  if (posn < 0 || length <= posn)
    RaError();

  long len1 = strlen(src);
  long len2 = length - posn;
  if (len1 <= len2)
    return !strncmp(string + posn, src, len1);

  return false;
}

//_______________________________________________

bool Str::Compare(const char src, long posn)
{
  if (posn < 0 || length <= posn)
    RaError();

  return (string[posn] == src);
}

//_______________________________________________

bool Str::CompareRight(const Str &src) const
{
  long pos = length - src.length;
  if (pos > 0)
    return !strncmp(string + pos, src.string, src.length);

  return false;
}

//_______________________________________________

bool Str::CompareRight(const char *src) const
{
  long len = strlen(src);
  long pos = length - len;
  if (pos > 0)
    return !strncmp(string + pos, src, len);

  return false;
}

//_______________________________________________

bool Str::CompareRight(const char src) const
{
  if (length)
    return (string[length-1] == src);

  return false;
}

//_______________________________________________
//_______________________________________________

bool Str::Contains(const Str &src) const
{
  return (src.Length() && strstr(string, src.string));
}

//_______________________________________________

bool Str::Contains(const char *src) const
{
  return (*src && strstr(string, src));
}

//_______________________________________________

bool Str::Contains(const char src) const
{
  return (src && strchr(string, src));
}

//_______________________________________________
//_______________________________________________

bool Str::IsIn(const char *src) const
{
  return (strstr(src, string) != NULL);
}

//_______________________________________________
//_______________________________________________
long Str::Find(const Str &src)         const
{
  char *p = strstr(string, src.string);
  if (p)
    return p - string;

  return -1;
}

//_______________________________________________

long Str::Find(const char *src)        const
{
  char *p = strstr(string, src);
  if (p)
    return p - string;

  return -1;
}

//_______________________________________________

long Str::Find(char src)               const
{
  char *p = strchr(string, src);
  if (p)
    return p - string;

  return -1;
}

//_______________________________________________

bool Str::Find(const Str &src, long &posn) const
{
  if (posn >= 0 && posn < length)
  {
    char *p = strstr(string + posn, src.string);
    if (p)
    {
      posn = p - string;
      return true;
    }
  }

  return false;
}

//_______________________________________________

bool Str::Find(const char *src, long &posn) const
{
  if (posn >= 0 && posn < length)
  {
    char *p = strstr(string + posn, src);
    if (p)
    {
      posn = p - string;
      return true;
    }
  }

  return false;
}

//_______________________________________________

bool Str::Find(char src, long &posn) const
{
  if (posn >= 0 && posn < length)
  {
    char *p = strchr(string + posn, src);
    if (p)
    {
      posn = p - string;
      return true;
    }
  }

  return false;
}

//_______________________________________________
//_______________________________________________

long Str::FindRight(const Str &src) const
{
  if (src.length <= length)
  {
    long pos;
    for (pos = length-1; pos >= 0; pos--)
    {
      if (!strncmp(string + pos, src.string, src.length))
        return pos;
    }
  }

  return -1;
}

//_______________________________________________

long Str::FindRight(const char *src) const
{
  long len = strlen(src);
  if (len <= length)
  {
    long pos;
    for (pos = length-1; pos >= 0; pos--)
    {
      if (!strncmp(string + pos, src, len))
        return pos;
    }
  }

  return -1;
}

//_______________________________________________

long Str::FindRight(char src) const
{
  long pos;
  for (pos = length-1; pos >= 0; pos--)
  {
    if (string[pos] == src)
      return pos;
  }

  return -1;
}

//_______________________________________________

bool Str::FindRight(const Str &src, long &posn) const
{
  if (posn == -1)
    posn = length - 1;

  if (posn >= 0 && posn < length)
  {
    if (src.length <= length)
    {
      long pos;
      for (pos = posn ; pos >= 0; pos--)
      {
        if (!strncmp(string + pos, src.string, src.length))
        {
          posn = pos;
          return true;
        }
      }
    }
  }

  return false;
}

//_______________________________________________

bool Str::FindRight(const char *src, long &posn) const
{
  if (posn == -1)
    posn = length - 1;

  if (posn >= 0 && posn < length)
  {
    long len = strlen(src);
    if (len <= length)
    {
      long pos;
      for (pos = posn ; pos >= 0; pos--)
      {
        if (!strncmp(string + pos, src, len))
        {
          posn = pos;
          return true;
        }
      }
    }
  }

  return false;
}

//_______________________________________________

bool Str::FindRight(char src, long &posn) const
{
  if (posn == -1)
    posn = length - 1;

  if (posn >= 0 && posn < length)
  {
    long pos;
    for (pos = posn; pos >= 0; pos--)
    {
      if (string[pos] == src)
      {
        posn = pos;
        return true;
      }
    }
  }

  return false;
}

//_______________________________________________
//_______________________________________________
// Copy a string.

Str &Str::operator=(const Str &src)
{ 
  long sz = src.length + 1;
  if (size != sz)
  {
    char *str = new char [sz];
    if (!str)
      AlError();

    delete [] string;
    string = str;
    size   = sz;
  }

  strcpy(string, src.string);
  length = src.length;
  return *this;
}

//_______________________________________________
// Copy a character array to the member string.

Str &Str::operator=(const char *src)
{
  long sz = strlen(src) + 1;
  if (size != sz)
  {
    char *str = new char [sz];
    if (!str)
      AlError();

    delete [] string;
    string = str;
    size   = sz;
  }

  strcpy(string, src);
  length = size - 1;
  return *this;
}

//_______________________________________________
// Copy a character to the member string.

Str &Str::operator=(const char src)
{
  if (size != 2)
  {
    char *str = new char [2];
    if (!str)
      AlError();

    delete [] string;
    string = str;
    size   = 2;
  }

  string[0] = src;
  string[1] = '\0';
  length = 1;
  return *this;
}

//_______________________________________________
// Convert a long integer to a string.

Str &Str::operator=(const long number)
{
  ostrstream ostr;
  ostr << number << ends;
  char *numStr = ostr.str();

  long sz = strlen(numStr) + 1;
  if (size != sz)
  {
    char *str = new char [sz];
    if (!str)
      AlError();

    delete [] string;
    string = str;
    size   = sz;
  }

  strcpy(string, numStr);
  length = size - 1;
  delete numStr;
  return *this;
}

//_______________________________________________
// Convert a double floating-point number to a string.

Str &Str::operator=(const double number)
{
  ostrstream ostr;
  ostr << number << ends;
  char *numStr = ostr.str();

  long sz = strlen(numStr) + 1;
  if (size != sz)
  {
    char *str = new char [sz];
    if (!str)
      AlError();

    delete [] string;
    string = str;
    size   = sz;
  }

  strcpy(string, numStr);
  length = size - 1;
  delete numStr;
  return *this;
}

//_______________________________________________
//_______________________________________________
// Copy an entire string.

void Str::Copy(const Str &src)
{
  if (size <= src.length)
  {
    long sz = src.length + 1;
    char *str = new char [sz];
    if (!str)
      AlError();

    delete [] string;
    string = str;
    size = sz;
  }

  strcpy(string, src.string);
  length = src.length;
}

//_______________________________________________

void Str::Copy(const char *src)
{
  long lenS = strlen(src);
  if (size <= lenS)
  {
    long sz = lenS + 1;
    char *str = new char [sz];
    if (!str)
      AlError();

    delete [] string;
    string = str;
    size = sz;
  }

  strcpy(string, src);
  length = lenS;
}

//_______________________________________________

void Str::Copy(const char src)
{
  string[0] = src;
  string[1] = '\0';
  length    = 1;
}

//_______________________________________________
// Convert a long integer to a string.

void Str::Copy(const long number)
{
  ostrstream ostr;
  ostr << number << ends;
  char *numStr = ostr.str();

  long lenS = strlen(numStr);
  if (size <= lenS)
  {
    long sz = lenS + 1;
    char *str = new char [sz];
    if (!str)
      AlError();

    delete [] string;
    string = str;
    size = sz;
  }

  strcpy(string, numStr);
  length = lenS;
  delete numStr;
}

//_______________________________________________
// Convert a double floating-point number to a string.

void Str::Copy(const double number)
{
  ostrstream ostr;
  ostr << number << ends;
  char *numStr = ostr.str();

  long lenS = strlen(numStr);
  if (size <= lenS)
  {
    long sz = lenS + 1;
    char *str = new char [sz];
    if (!str)
      AlError();

    delete [] string;
    string = str;
    size = sz;
  }

  strcpy(string, numStr);
  length = lenS;
  delete numStr;
}

//_______________________________________________
//_______________________________________________
// Copy the left len characters of a string.

void Str::CopyLeft(const Str &src, long len)
{
  if (len < 0)
    NvError();

  if (!len || src.length < len)
    len = src.length;

  if (size <= len)
  {
    long sz = len + 1;
    char *str = new char [sz];
    if (!str)
      AlError();

    delete [] string;
    string = str;
    size = sz;
  }

  strncpy(string, src.string, len);
  string[len] = '\0';
  length = len;
}

//_______________________________________________

void Str::CopyLeft(const char *src, long len)
{
  if (len < 0)
    NvError();

  long lenS = strlen(src);
  if (!len || lenS < len)
    len = lenS;

  if (size <= len)
  {
    long sz = len + 1;
    char *str = new char [sz];
    if (!str)
      AlError();

    delete [] string;
    string = str;
    size = sz;
  }

  strncpy(string, src, len);
  string[len] = '\0';
  length = len;
}

//_______________________________________________
//_______________________________________________
// Copy an internal len characters of a string from posn.

void Str::CopyMid(const Str &src, long posn, long len)
{
  if (len < 0)
    NvError();

  if (posn < 0 || src.length <= posn)
    RaError();

  long lenS = src.length - posn;
  if (lenS < len)
    len = lenS;

  if (size <= len)
  {
    long sz = len + 1;
    char *str = new char [sz];
    if (!str)
      AlError();

    delete [] string;
    string = str;
    size = sz;
  }

  strncpy(string, src.string + posn, len);
  string[len] = '\0';
  length = len;
}

//_______________________________________________

void Str::CopyMid(const char *src, long posn, long len)
{
  if (len < 0)
    NvError();

  long lenS = strlen(src);
  if (posn < 0 || lenS <= posn)
    RaError();

  lenS -= posn;
  if (lenS < len)
    len = lenS;

  if (size <= len)
  {
    long sz = len + 1;
    char *str = new char [sz];
    if (!str)
      AlError();

    delete [] string;
    string = str;
    size = sz;
  }

  strncpy(string, src + posn, len);
  string[len] = '\0';
  length = len;
}

//_______________________________________________
//_______________________________________________
// Copy characters of a string from posn to the end.

void Str::CopyEnd(const Str &src, long posn)
{
  if (posn < 0 || src.length <= posn)
    RaError();

  long lenS = src.length - posn;
  if (size <= lenS)
  {
    long sz = lenS + 1;
    char *str = new char [sz];
    if (!str)
      AlError();

    delete [] string;
    string = str;
    size = sz;
  }

  strncpy(string, src.string + posn, lenS);
  string[lenS] = '\0';
  length = lenS;
}

//_______________________________________________

void Str::CopyEnd(const char *src, long posn)
{
  long lenS = strlen(src);
  if (posn < 0 || lenS <= posn)
    RaError();

  lenS -= posn;
  if (size <= lenS)
  {
    long sz = lenS + 1;
    char *str = new char [sz];
    if (!str)
      AlError();

    delete [] string;
    string = str;
    size = sz;
  }

  strncpy(string, src + posn, lenS);
  string[lenS] = '\0';
  length = lenS;
}

//_______________________________________________
//_______________________________________________
// Copy the right len characters of a string.

void Str::CopyRight(const Str &src, long len)
{
  if (len < 0)
    NvError();

  if (!len || src.length < len)
    len = src.length;

  if (size <= len)
  {
    long sz = len + 1;
    char *str = new char [sz];
    if (!str)
      AlError();

    delete [] string;
    string = str;
    size = sz;
  }

  strncpy(string, src.string + src.length - len, len);
  string[len] = '\0';
  length = len;
}

//_______________________________________________

void Str::CopyRight(const char *src, long len)
{
  if (len < 0)
    NvError();

  long lenS = strlen(src);
  if (!len || lenS < len)
    len = lenS;

  if (size <= len)
  {
    long sz = len + 1;
    char *str = new char [sz];
    if (!str)
      AlError();

    delete [] string;
    string = str;
    size = sz;
  }

  strncpy(string, src + lenS - len, len);
  string[len] = '\0';
  length = len;
}

//_______________________________________________
//_______________________________________________
// Copy a string and delimiter to the member string.

void Str::Copy(const Str &src, char delimiter)
{
  long len = src.length + 1;
  if (size <= len)
  {
    long sz = len << 1;
    char *str = new char [sz];
    if (!str)
      AlError();

    strcpy(str, string);
    delete [] string;
    string = str;
    size = sz;
  }


  strcpy(string, src.string);
  string[src.length] = delimiter;
  string[len] = '\0';
  length = len;
}

//_______________________________________________

void Str::Copy(const char *src, char delimiter)
{
  long len = strlen(src) + 1;
  if (size <= len)
  {
    long sz = len << 1;
    char *str = new char [sz];
    if (!str)
      AlError();

    strcpy(str, string);
    delete [] string;
    string = str;
    size = sz;
  }

  strcpy(string, src);
  string[len-1] = delimiter;
  string[len]   = '\0';
  length = len;
}

//_______________________________________________

void Str::Copy(const char src, char delimiter)
{
  if (size <= 2)
  {
    char *str = new char [4];
    if (!str)
      AlError();

    strcpy(str, string);
    delete [] string;
    string = str;
    size = 4;
  }

  string[0] = src;
  string[1] = delimiter;
  string[2] = '\0';
  length = 2;
}

//_______________________________________________

void Str::Copy(const long number, char delimiter)
{
  ostrstream ostr;
  ostr << number << delimiter << ends;
  char *numStr = ostr.str();

  long len = strlen(numStr);
  if (size <= len)
  {
    long sz = len << 1;
    char *str = new char [sz];
    if (!str)
      AlError();

    strcpy(str, string);
    delete [] string;
    string = str;
    size = sz;
  }

  strcpy(string, numStr);
  length = len;
  delete numStr;
}

//_______________________________________________

void Str::Copy(const double number, char delimiter)
{
  ostrstream ostr;
  ostr << number << delimiter << ends;
  char *numStr = ostr.str();

  long len = strlen(numStr);
  if (size <= len)
  {
    long sz = len << 1;
    char *str = new char [sz];
    if (!str)
      AlError();

    strcpy(str, string);
    delete [] string;
    string = str;
    size = sz;
  }

  strcpy(string, numStr);
  length = len;
  delete numStr;
}

//_______________________________________________
//_______________________________________________

void Str::CopyField(const Str &src, long len, bool rt)
{
  long lenB;
  char *ptr1, *ptr2;

  if (len < src.length)
    len = src.length;

  if (size <= len)
  {
    lenB = len + 1;
    ptr1 = new char [lenB];
    if (!ptr1)
      AlError();

    delete [] string;
    string = ptr1;
    size = lenB;
  }

  lenB = len - src.length;
  if (rt)
  {
    ptr1 = string + lenB;
    ptr2 = string;
  }

  else
  {
    ptr1 = string;
    ptr2 = string + src.length;
  }

  strncpy(ptr1, src.string, src.length);
  memset(ptr2, ' ', lenB);
  string[len] = '\0';
  length = len;
}

//_______________________________________________

void Str::CopyField(const char *src, long len, bool rt)
{
  long lenS, lenB;
  char *ptr1, *ptr2;

  lenS = strlen(src);
  if (len < lenS)
    len = lenS;

  if (size <= len)
  {
    long lenB = len + 1;
    ptr1 = new char [lenB];
    if (!ptr1)
      AlError();

    delete [] string;
    string = ptr1;
    size = lenB;
  }

  lenB = len - lenS;
  if (rt)
  {
    ptr1 = string + lenB;
    ptr2 = string;
  }

  else
  {
    ptr1 = string;
    ptr2 = string + lenS;
  }

  strncpy(ptr1, src, lenS);
  memset(ptr2, ' ', lenB);
  string[len] = '\0';
  length = len;
}

//_______________________________________________

void Str::CopyField(const char src, long len, bool rt)
{
  char *ptr;

  if (len < 1)
    len = 1;

  if (size <= len)
  {
    long sz = len + 1;
    ptr = new char [sz];
    if (!ptr)
      AlError();

    delete [] string;
    string = ptr;
    size = sz;
  }

  memset(string, ' ', len);
  if (rt)
    string[len - 1] = src;

  else
    *string = src;

  string[len] = '\0';
  length = len;
}

//_______________________________________________
// Convert a long integer to a string.

void Str::CopyField(const long number, long len, bool rt)
{
  ostrstream ostr;
  long lenS, lenB;
  char *numStr, *ptr1, *ptr2;

  ostr << number << ends;
  numStr = ostr.str();

  lenS = strlen(numStr);
  if (len < lenS)
    len = lenS;

  if (size <= len)
  {
    lenB = len + 1;
    ptr1 = new char [lenB];
    if (!ptr1)
      AlError();

    delete [] string;
    string = ptr1;
    size = lenB;
  }

  lenB = len - lenS;
  if (rt)
  {
    ptr1 = string + lenB;
    ptr2 = string;
  }

  else
  {
    ptr1 = string;
    ptr2 = string + lenS;
  }

  strncpy(ptr1, numStr, lenS);
  memset(ptr2, ' ', lenB);
  string[len] = '\0';
  length = len;
  delete numStr;
}

//_______________________________________________
// Convert a double floating-point number to a string.

void Str::CopyField(const double number, long len, bool rt)
{
  ostrstream ostr;
  long lenS, lenB;
  char *numStr, *ptr1, *ptr2;

  ostr << number << ends;
  numStr = ostr.str();

  lenS = strlen(numStr);
  if (len < lenS)
    len = lenS;

  if (size <= len)
  {
    lenB = len + 1;
    ptr1 = new char [lenB];
    if (!ptr1)
      AlError();

    delete [] string;
    string = ptr1;
    size = lenB;
  }

  lenB = len - lenS;
  if (rt)
  {
    ptr1 = string + lenB;
    ptr2 = string;
  }

  else
  {
    ptr1 = string;
    ptr2 = string + lenS;
  }

  strncpy(ptr1, numStr, lenS);
  memset(ptr2, ' ', lenB);
  string[len] = '\0';
  length = len;
  delete numStr;
}

//_______________________________________________
//_______________________________________________

char *Str::CopyToChar()
{
  char *dst = new char [length + 1];
  strcpy(dst, string);
  return dst;
}

//_______________________________________________

char *Str::CopyToChar(long len)
{
  if (len < 0)
    NvError();

  if (length < len)
    len = length;

  char *dst = new char [len + 1];
  strncpy(dst, string, len);
  dst[len] = '\0';
  return dst;
}

//_______________________________________________

char *Str::CopyToChar(long posn, long len)
{
  if (len < 0)
    NvError();

  if (posn < 0 || length <= posn)
    RaError();

  if (!len || length - posn < len)
    len = length - posn;

  char *dst = new char [len + 1];
  strncpy(dst, string + posn, len);
  dst[len] = '\0';
  return dst;
}

//_______________________________________________

void Str::CopyToChar(char *dst, long len)
{
  if (len < 0)
    NvError();

  if (!len || length < len)
    len = length;

  strncpy(dst, string, len);
  dst[len] = '\0';
}

//_______________________________________________

void Str::CopyToChar(char *dst, long posn, long len)
{
  if (len < 0)
    NvError();

  if (posn < 0 || length <= posn)
    RaError();

  if (!len || length - posn < len)
    len = length - posn;

  strncpy(dst, string + posn, len);
  dst[len] = '\0';
}

//_______________________________________________
//_______________________________________________

void Str::Justify(long len, bool rt)
{
  if (length < len)
  {
    long lenB;
    char *ptr;

    lenB = len - length;
    if (rt || size <= len)
    {
      long sz  = size <= len ? len + 1 : size;
      char *str = new char [sz];
      if (!str)
        AlError();

      ptr = rt ? str + lenB : str;
      strncpy(ptr, string, length);

      delete [] string;
      string = str;
      size = sz;
    }

    ptr = rt ? string : string + length;
    memset(ptr, ' ', lenB);
    string[len] = '\0';
    length = len;
  }
}

//_______________________________________________
//_______________________________________________

Str Str::operator+(const Str &src)
{
  long len = length + src.length;
  Str retStr(len);
  retStr.length = len;
  strcpy(retStr.string, string);
  strcpy(retStr.string + length, src.string);
  return retStr;
}

//_______________________________________________

Str Str::operator+(const char *src)
{
  long len = length + strlen(src);
  Str retStr(len);
  retStr.length = len;
  strcpy(retStr.string, string);
  strcpy(retStr.string + length, src);
  return retStr;
}

//_______________________________________________

Str Str::operator+(const char src)
{
  long len = length + 1;
  Str retStr(len);
  retStr.length = len;
  strcpy(retStr.string, string);
  retStr.string[length] = src;
  retStr.string[len]    = '\0';
  return retStr;
}

//_______________________________________________

Str Str::operator+(const long number)
{
  ostrstream ostr;
  ostr << number << ends;
  char *numStr = ostr.str();

  long len = length + strlen(numStr);
  Str retStr(len);
  retStr.length = len;
  strcpy(retStr.string, string);
  strcpy(retStr.string + length, numStr);
  delete numStr;
  return retStr;
}

//_______________________________________________

Str Str::operator+(const double number)
{
  ostrstream ostr;
  ostr << number << ends;
  char *numStr = ostr.str();

  long len = length + strlen(numStr);
  Str retStr(len);
  retStr.length = len;
  strcpy(retStr.string, string);
  strcpy(retStr.string + length, numStr);
  delete numStr;
  return retStr;
}

//_______________________________________________
// Friend function

Str operator+(const char *src1, const Str &src2)
{
  long lenS = strlen(src1);
  long len = lenS + src2.length;
  Str retStr(len);
  retStr.length = len;
  strcpy(retStr.string, src1);
  strcpy(retStr.string + lenS, src2.string);
  return retStr;
}

//_______________________________________________
// Friend function

Str operator+(const char src1, const Str &src2)
{
  long len = src2.length + 1;
  Str retStr(len);
  retStr.length = len;
  *retStr.string = src1;
  strcpy(retStr.string + 1, src2.string);
  return retStr;
}

//_______________________________________________
// Friend function

Str operator+(const long number, const Str &src2)
{
  ostrstream ostr;
  ostr << number << ends;
  char *numStr = ostr.str();

  long len1 = strlen(numStr);
  long len2 = len1 + src2.length;
  Str retStr(len2);
  retStr.length = len2;
  strcpy(retStr.string, numStr);
  strcpy(retStr.string + len1, src2.string);
  delete numStr;
  return retStr;
}

//_______________________________________________
// Friend function

Str operator+(const double number, const Str &src2)
{
  ostrstream ostr;
  ostr << number << ends;
  char *numStr = ostr.str();

  long len1 = strlen(numStr);
  long len2 = len1 + src2.length;
  Str retStr(len2);
  retStr.length = len2;
  strcpy(retStr.string, numStr);
  strcpy(retStr.string + len1, src2.string);
  delete numStr;
  return retStr;
}

//_______________________________________________
//_______________________________________________

void Str::operator+=(const Str &src)
{
  long sz = length + src.length + 1;
  if (size != sz)
  {
    char *str = new char [sz];
    if (!str)
      AlError();

    strcpy(str, string);
    delete [] string;
    string = str;
    size   = sz;
  }

  strcpy(string + length, src.string);
  length = size - 1;
}

//_______________________________________________

void Str::operator+=(const char *src)
{
  long sz = length + strlen(src) + 1;
  if (size != sz)
  {
    char *str = new char [sz];
    if (!str)
      AlError();

    strcpy(str, string);
    delete [] string;
    string = str;
    size   = sz;
  }

  strcpy(string + length, src);
  length = size - 1;
}

//_______________________________________________

void Str::operator+=(const char src)
{
  long sz = length + 1;
  if (size != sz)
  {
    char *str = new char [sz];
    if (!str)
      AlError();

    strcpy(str, string);
    delete [] string;
    string = str;
    size   = sz;
  }

  string[length] = src;
  length++;
  string[length] = '\0';
}

//_______________________________________________

void Str::operator+=(const long number)
{
  ostrstream ostr;
  ostr << number << ends;
  char *numStr = ostr.str();

  long sz = length + strlen(numStr) + 1;
  if (size != sz)
  {
    char *str = new char [sz];
    if (!str)
      AlError();

    strcpy(str, string);
    delete [] string;
    string = str;
    size   = sz;
  }

  strcpy(string + length, numStr);
  length = size - 1;
  delete numStr;
}

//_______________________________________________

void Str::operator+=(const double number)
{
  ostrstream ostr;
  ostr << number << ends;
  char *numStr = ostr.str();

  long sz = length + strlen(numStr);
  if (size != sz)
  {
    char *str = new char [sz];
    if (!str)
      AlError();

    strcpy(str, string);
    delete [] string;
    string = str;
    size   = sz;
  }

  strcpy(string + length, numStr);
  length = size - 1;
  delete numStr;
}

//_______________________________________________
//_______________________________________________

Str &Str::operator<<(const Str &src)
{
  long len = length + src.length;
  if (size <= len)
  {
    long sz = len << 1;
    char *str = new char [sz];
    if (!str)
      AlError();

    strcpy(str, string);
    delete [] string;
    string = str;
    size = sz;
  }

  strcpy(string + length, src.string);
  length = len;
  return *this;
}

//_______________________________________________

Str &Str::operator<<(const char *src)
{
  long len = length + strlen(src);
  if (size <= len)
  {
    long sz = len << 1;
    char *str = new char [sz];
    if (!str)
      AlError();

    strcpy(str, string);
    delete [] string;
    string = str;
    size = sz;
  }

  strcpy(string + length, src);
  length = len;
  return *this;
}

//_______________________________________________

Str &Str::operator<<(const char src)
{
  long len = length + 1;
  if (size <= len)
  {
    long sz = len << 1;
    char *str = new char [sz];
    if (!str)
      AlError();

    strcpy(str, string);
    delete [] string;
    string = str;
    size = sz;
  }

  string[length] = src;
  length++;
  string[length]   = '\0';
  return *this;
}

//_______________________________________________

Str &Str::operator<<(const long number)
{
  ostrstream ostr;
  ostr << number << ends;
  char *numStr = ostr.str();

  long len = length + strlen(numStr);
  if (size <= len)
  {
    long sz = len << 1;
    char *str = new char [sz];
    if (!str)
      AlError();

    strcpy(str, string);
    delete [] string;
    string = str;
    size = sz;
  }

  strcpy(string + length, numStr);
  length = len;
  delete numStr;
  return *this;
}

//_______________________________________________

Str &Str::operator<<(const double number)
{
  ostrstream ostr;
  ostr << number << ends;
  char *numStr = ostr.str();

  long len = length + strlen(numStr);
  if (size <= len)
  {
    long sz = len << 1;
    char *str = new char [sz];
    if (!str)
      AlError();

    strcpy(str, string);
    delete [] string;
    string = str;
    size = sz;
  }

  strcpy(string + length, numStr);
  length = len;
  delete numStr;
  return *this;
}

//_______________________________________________
//_______________________________________________
// Append a string object to the end of the member string.

void Str::Append(const Str &src)
{
  long len = length + src.length;
  if (size <= len)
  {
    long sz = len << 1;
    char *str = new char [sz];
    if (!str)
      AlError();

    strcpy(str, string);
    delete [] string;
    string = str;
    size = sz;
  }

  strcpy(string + length, src.string);
  length = len;
}

//_______________________________________________
// Append a string to the end of the member string.

void Str::Append(const char *src)
{
  long len = length + strlen(src);
  if (size <= len)
  {
    long sz = len << 1;
    char *str = new char [sz];
    if (!str)
      AlError();

    strcpy(str, string);
    delete [] string;
    string = str;
    size = sz;
  }

  strcpy(string + length, src);
  length = len;
}

//_______________________________________________
// Append a character to the end of the member string.

void Str::Append(const char src)
{
  long len = length + 1;
  if (size <= len)
  {
    long sz = len << 1;
    char *str = new char [sz];
    if (!str)
      AlError();

    strcpy(str, string);
    delete [] string;
    string = str;
    size = sz;
  }

  string[length] = src;
  length++;
  string[length] = '\0';
}

//_______________________________________________
// Append a long number to the end of the member string.

void Str::Append(const long number)
{
  ostrstream ostr;
  ostr << number << ends;
  char *numStr = ostr.str();

  long len = length + strlen(numStr);
  if (size <= len)
  {
    long sz = len << 1;
    char *str = new char [sz];
    if (!str)
      AlError();

    strcpy(str, string);
    delete [] string;
    string = str;
    size = sz;
  }

  strcpy(string + length, numStr);
  length = len;
  delete numStr;
}

//_______________________________________________
// Append a double number to the end of the member string.

void Str::Append(const double number)
{
  ostrstream ostr;
  ostr << number << ends;
  char *numStr = ostr.str();

  long len = length + strlen(numStr);
  if (size <= len)
  {
    long sz = len << 1;
    char *str = new char [sz];
    if (!str)
      AlError();

    strcpy(str, string);
    delete [] string;
    string = str;
    size = sz;
  }

  strcpy(string + length, numStr);
  length = len;
  delete numStr;
}

//_______________________________________________
//_______________________________________________
// Append a string and delimiter to the end of the member string.

void Str::Append(const Str &src, char delimiter)
{
  long len = length + src.length + 1;
  if (size <= len)
  {
    long sz = len << 1;
    char *str = new char [sz];
    if (!str)
      AlError();

    strcpy(str, string);
    delete [] string;
    string = str;
    size = sz;
  }


  strcpy(string + length, src.string);
  string[len-1] = delimiter;
  string[len]   = '\0';
  length = len;
}

//_______________________________________________
// Append a string and delimiter to the end of the member string.

void Str::Append(const char *src, char delimiter)
{
  long len = length + strlen(src) + 1;
  if (size <= len)
  {
    long sz = len << 1;
    char *str = new char [sz];
    if (!str)
      AlError();

    strcpy(str, string);
    delete [] string;
    string = str;
    size = sz;
  }

  strcpy(string + length, src);
  string[len-1] = delimiter;
  string[len]   = '\0';
  length = len;
}

//_______________________________________________
// Append a character and delimiter to the end of the member string.

void Str::Append(const char src, char delimiter)
{
  long len = length + 2;
  if (size <= len)
  {
    long sz = len << 1;
    char *str = new char [sz];
    if (!str)
      AlError();

    strcpy(str, string);
    delete [] string;
    string = str;
    size = sz;
  }

  string[length] = src;
  length++;
  string[length] = delimiter;
  length++;
  string[length] = '\0';
}

//_______________________________________________
// Append a long number and delimiter to the end of the member string.

void Str::Append(const long number, char delimiter)
{
  ostrstream ostr;
  ostr << number << delimiter << ends;
  char *numStr = ostr.str();

  long len = length + strlen(numStr);
  if (size <= len)
  {
    long sz = len << 1;
    char *str = new char [sz];
    if (!str)
      AlError();

    strcpy(str, string);
    delete [] string;
    string = str;
    size = sz;
  }

  strcpy(string + length, numStr);
  length = len;
  delete numStr;
}

//_______________________________________________
// Append a double number and delimiter to the end of the member string.

void Str::Append(const double number, char delimiter)
{
  ostrstream ostr;
  ostr << number << delimiter << ends;
  char *numStr = ostr.str();

  long len = length + strlen(numStr);
  if (size <= len)
  {
    long sz = len << 1;
    char *str = new char [sz];
    if (!str)
      AlError();

    strcpy(str, string);
    delete [] string;
    string = str;
    size = sz;
  }

  strcpy(string + length, numStr);
  length = len;
  delete numStr;
}

//_______________________________________________
//_______________________________________________
// Append a segment of a string object to the end of the member string.

void Str::Append(const Str &src, long len)
{
  if (len < 0)
    NvError();

  if (!len || src.length < len)
    len = src.length;

  long lenS = length + len;
  if (size <= lenS)
  {
    long sz = lenS << 1;
    char *str = new char [sz];
    if (!str)
      AlError();

    strcpy(str, string);
    delete [] string;
    string = str;
    size = sz;
  }

  strncpy(string + length, src.string, len);
  string[lenS] = '\0';
  length = lenS;
}

//_______________________________________________
// Append segment of a a string to the end of the member string.

void Str::Append(const char *src, long len)
{
  if (len < 0)
    NvError();

  long lenS = strlen(src);
  if (!len || lenS < len)
    len = lenS;

  lenS = length + len;
  if (size <= lenS)
  {
    long sz = lenS << 1;
    char *str = new char [sz];
    if (!str)
      AlError();

    strcpy(str, string);
    delete [] string;
    string = str;
    size = sz;
  }

  strncpy(string + length, src, len);
  string[lenS] = '\0';
  length = lenS;
}

//_______________________________________________
// Append a segment of a string object to the end of the member string.

void Str::Append(const Str &src, long posn, long len)
{
  if (len < 0)
    NvError();

  if (posn < 0 || src.length <= posn)
    RaError();

  long lenS = src.length - posn;
  if (!len || lenS < len)
    len = lenS;

  lenS = length + len;
  if (size <= lenS)
  {
    long sz = lenS << 1;
    char *str = new char [sz];
    if (!str)
      AlError();

    strcpy(str, string);
    delete [] string;
    string = str;
    size = sz;
  }

  strncpy(string + length, src.string + posn, len);
  string[lenS] = '\0';
  length = lenS;
}

//_______________________________________________
// Append segment of a string to the end of the member string.

void Str::Append(const char *src, long posn, long len)
{
  if (len < 0)
    NvError();

  long lenS = strlen(src);
  if (posn < 0 || lenS < posn)
    RaError();

  lenS -= posn;
  if (!len || lenS < len)
    len = lenS;

  lenS = length + len;
  if (size <= lenS)
  {
    long sz = lenS << 1;
    char *str = new char [sz];
    if (!str)
      AlError();

    strcpy(str, string);
    delete [] string;
    string = str;
    size = sz;
  }

  strncpy(string + length, src + posn, len);
  string[lenS] = '\0';
  length = lenS;
}

//_______________________________________________
//_______________________________________________

void Str::AppendField(const Str &src, long len, bool rt)
{
  long lenN, lenB;
  char *ptr1, *ptr2;

  if (len < src.length)
    len = src.length;

  lenN = length + len;
  if (size <= lenN)
  {
    lenB = lenN + 1;
    ptr1 = new char [lenB];
    if (!ptr1)
      AlError();

    strcpy(ptr1, string);
    delete [] string;
    string = ptr1;
    size = lenB;
  }

  lenB = len - src.length;
  ptr1 = string + length;
  ptr2 = ptr1;
  if (rt)
    ptr1 += lenB;

  else
    ptr2 += src.length;

  strncpy(ptr1, src.string, src.length);
  memset(ptr2, ' ', lenB);
  string[lenN] = '\0';
  length = lenN;
}

//_______________________________________________

void Str::AppendField(const char *src, long len, bool rt)
{
  long lenN, lenS, lenB;
  char *ptr1, *ptr2;

  lenS = strlen(src);
  if (len < lenS)
    len = lenS;

  lenN = length + len;
  if (size <= lenN)
  {
    long lenB = lenN + 1;
    ptr1 = new char [lenB];
    if (!ptr1)
      AlError();

    strcpy(ptr1, string);
    delete [] string;
    string = ptr1;
    size = lenB;
  }

  lenB = len - lenS;
  ptr1 = string + length;
  ptr2 = ptr1;
  if (rt)
    ptr1 += lenB;

  else
    ptr2 += lenS;

  strncpy(ptr1, src, lenS);
  memset(ptr2, ' ', lenB);
  string[lenN] = '\0';
  length = lenN;
}

//_______________________________________________

void Str::AppendField(const char src, long len, bool rt)
{
  long  lenN;
  char *ptr;

  if (len < 1)
    len = 1;

  lenN = length + len;
  if (size <= lenN)
  {
    long sz = lenN + 1;
    ptr = new char [sz];
    if (!ptr)
      AlError();

    strcpy(ptr, string);
    delete [] string;
    string = ptr;
    size = sz;
  }

  ptr = string + length;
  memset(ptr, ' ', len);
  if (rt)
    ptr[len - 1] = src;

  else
    *ptr = src;

  string[lenN] = '\0';
  length = lenN;
}

//_______________________________________________
// Convert a long integer to a string.

void Str::AppendField(const long number, long len, bool rt)
{
  ostrstream ostr;
  long lenN, lenS, lenB;
  char *numStr, *ptr1, *ptr2;

  ostr << number << ends;
  numStr = ostr.str();

  lenS = strlen(numStr);
  if (len < lenS)
    len = lenS;

  lenN = length + len;
  if (size <= lenN)
  {
    lenB = lenN + 1;
    ptr1 = new char [lenB];
    if (!ptr1)
      AlError();

    strcpy(ptr1, string);
    delete [] string;
    string = ptr1;
    size = lenB;
  }

  lenB = len - lenS;
  ptr1 = string + length;
  ptr2 = ptr1;
  if (rt)
    ptr1 += lenB;

  else
    ptr2 += lenS;

  strncpy(ptr1, numStr, lenS);
  memset(ptr2, ' ', lenB);
  string[lenN] = '\0';
  length = lenN;
  delete numStr;
}

//_______________________________________________
// Convert a double floating-point number to a string.

void Str::AppendField(const double number, long len, bool rt)
{
  ostrstream ostr;
  long lenN, lenS, lenB;
  char *numStr, *ptr1, *ptr2;

  ostr << number << ends;
  numStr = ostr.str();

  lenS = strlen(numStr);
  if (len < lenS)
    len = lenS;

  lenN = length + len;
  if (size <= lenN)
  {
    lenB = lenN + 1;
    ptr1 = new char [lenB];
    if (!ptr1)
      AlError();

    strcpy(ptr1, string);
    delete [] string;
    string = ptr1;
    size = lenB;
  }

  lenB = len - lenS;
  ptr1 = string + length;
  ptr2 = ptr1;
  if (rt)
    ptr1 += lenB;

  else
    ptr2 += lenS;

  strncpy(ptr1, numStr, lenS);
  memset(ptr2, ' ', lenB);
  string[lenN] = '\0';
  length = lenN;
  delete numStr;
}

//_______________________________________________
//_______________________________________________

void Str::Replace(const Str &src, long posn)
{
  if (posn < 0 || length <= posn)
    RaError();

  long len = posn + src.length;
  if (length < len)
  {
    if (size <= len)
    {
      long sz = len << 1;
      char *str = new char [sz];
      if (!str)
        AlError();

      strcpy(str, string);
      delete [] string;
      string = str;
      size = sz;
    }

    string[len] = '\0';
    length = len;
  }

  memcpy(string + posn, src.string, src.length);
}

//_______________________________________________

void Str::Replace(const char *src, long posn)
{
  if (posn < 0 || length <= posn)
    RaError();

  long lenS = strlen(src);
  long len  = posn + lenS;
  if (length < len)
  {
    if (size <= len)
    {
      long sz = len << 1;
      char *str = new char [sz];
      if (!str)
        AlError();

      strcpy(str, string);
      delete [] string;
      string = str;
      size = sz;
    }

    string[len] = '\0';
    length = len;
  }

  memcpy(string + posn, src, lenS);
}

//_______________________________________________

void Str::Replace(char src, long posn)
{
  if (posn < 0 || length <= posn)
    RaError();

  string[posn] = src;
}

//_______________________________________________
//_______________________________________________

void Str::ReplaceEnd(const Str &src, long posn)
{
  if (posn < 0 || length < posn)
    RaError();

  long len = posn + src.length;
  if (size <= len)
  {
    long sz = len << 1;
    char *str = new char [sz];
    if (!str)
      AlError();

    strcpy(str, string);
    delete [] string;
    string = str;
    size = sz;
  }

  strcpy(string + posn, src.string);
  length = len;
}

//_______________________________________________

void Str::ReplaceEnd(const char *src, long posn)
{
  if (posn < 0 || length < posn)
    RaError();

  long len = posn + strlen(src);
  if (size <= len)
  {
    long sz = len << 1;
    char *str = new char [sz];
    if (!str)
      AlError();

    strcpy(str, string);
    delete [] string;
    string = str;
    size = sz;
  }

  strcpy(string + posn, src);
  length = len;
}

//_______________________________________________

void Str::ReplaceEnd(const char src, long posn)
{
  if (posn < 0 || length < posn)
    RaError();

  long len = posn + 1;
  if (size <= len)
  {
    long sz = len << 1;
    char *str = new char [sz];
    if (!str)
      AlError();

    strcpy(str, string);
    delete [] string;
    string = str;
    size = sz;
  }

  string[posn] = src;
  string[len]  = '\0';
  length = len;
}

//_______________________________________________

void Str::ReplaceEnd(const long number, long posn)
{
  if (posn < 0 || length < posn)
    RaError();

  ostrstream ostr;
  ostr << number << ends;
  char *numStr = ostr.str();

  long len = posn + strlen(numStr);
  if (size <= len)
  {
    long sz = len << 1;
    char *str = new char [sz];
    if (!str)
      AlError();

    strcpy(str, string);
    delete [] string;
    string = str;
    size = sz;
  }

  strcpy(string + posn, numStr);
  length = len;
  delete numStr;
}

//_______________________________________________

void Str::ReplaceEnd(const double number, long posn)
{
  if (posn < 0 || length < posn)
    RaError();

  ostrstream ostr;
  ostr << number << ends;
  char *numStr = ostr.str();

  long len = posn + strlen(numStr);
  if (size <= len)
  {
    long sz = len << 1;
    char *str = new char [sz];
    if (!str)
      AlError();

    strcpy(str, string);
    delete [] string;
    string = str;
    size = sz;
  }

  strcpy(string + posn, numStr);
  length = len;
  delete numStr;
}

//_______________________________________________
//_______________________________________________

void Str::Insert(const Str &src, long posn)
{
  if (posn < 0 || length < posn)
    RaError();

  long len = length + src.length;
  if (size <= len)
  {
    long sz = len << 1;
    char *str = new char [sz];
    if (!str)
      AlError();

    strcpy(str, string);
    delete [] string;
    string = str;
    size = sz;
  }

  char *ptrP = string + posn;
  char *ptrS = string + length;
  char *ptrD = string + len;
  while (ptrP <= ptrS)
    *ptrD-- = *ptrS--;

  strncpy(ptrP, src.string, src.length);
  length = len;
}

//_______________________________________________

void Str::Insert(const char *src, long posn)
{
  if (posn < 0 || length < posn)
    RaError();

  long lenS = strlen(src);
  long len  = length + lenS;
  if (size <= len)
  {
    long sz = len << 1;
    char *str = new char [sz];
    if (!str)
      AlError();

    strcpy(str, string);
    delete [] string;
    string = str;
    size = sz;
  }

  char *ptrP = string + posn;
  char *ptrS = string + length;
  char *ptrD = string + len;
  while (ptrP <= ptrS)
    *ptrD-- = *ptrS--;

  strncpy(ptrP, src, lenS);
  length = len;
}

//_______________________________________________

void Str::Insert(const char src, long posn)
{
  if (posn < 0 || length < posn)
    RaError();

  long len = length + 1;
  if (size <= len)
  {
    long sz = len << 1;
    char *str = new char [sz];
    if (!str)
      AlError();

    strcpy(str, string);
    delete [] string;
    string = str;
    size = sz;
  }

  char *ptrP = string + posn;
  char *ptrS = string + length;
  char *ptrD = string + len;
  while (ptrP <= ptrS)
    *ptrD-- = *ptrS--;

  *ptrP = src;
  length = len;
}

//_______________________________________________
//_______________________________________________

void Str::InsertLeft(const Str &src)
{
  long len = length + src.length;
  if (size <= len)
  {
    long sz = len << 1;
    char *str = new char [sz];
    if (!str)
      AlError();

    strcpy(str, string);
    delete [] string;
    string = str;
    size = sz;
  }

  char *ptrS = string + length;
  char *ptrD = string + len;
  while (string <= ptrS)
    *ptrD-- = *ptrS--;

  strncpy(string, src.string, src.length);
  length = len;
}

//_______________________________________________

void Str::InsertLeft(const char *src)
{
  long lenS = strlen(src);
  long len  = length + lenS;
  if (size <= len)
  {
    long sz = len << 1;
    char *str = new char [sz];
    if (!str)
      AlError();

    strcpy(str, string);
    delete [] string;
    string = str;
    size = sz;
  }

  char *ptrS = string + length;
  char *ptrD = string + len;
  while (string <= ptrS)
    *ptrD-- = *ptrS--;

  strncpy(string, src, lenS);
  length = len;
}

//_______________________________________________

void Str::InsertLeft(const char src)
{
  long len = length + 1;
  if (size <= len)
  {
    long sz = len << 1;
    char *str = new char [sz];
    if (!str)
      AlError();

    strcpy(str, string);
    delete [] string;
    string = str;
    size = sz;
  }

  char *ptrS = string + length;
  char *ptrD = string + len;
  while (string <= ptrS)
    *ptrD-- = *ptrS--;

  *string = src;
  length = len;
}

//_______________________________________________
//_______________________________________________

void Str::Delete(long posn)
{
  if (posn < 0 || length <= posn)
    RaError();

  length = posn;
  string[length] = '\0';
}

//_______________________________________________

void Str::Delete(long posn, long len)
{
  if (len < 0)
    NvError();

  if (posn < 0 || length <= posn)
    RaError();

  if (length < len)
    len = length;

  char *str = string + posn;
  strcpy(str, str + len);
  length -= len;
}

//_______________________________________________

void Str::DeleteLeft(long len)
{
  if (len < 0)
    NvError();

  if (length < len)
    len = length;

  strcpy(string, string + len);
  length -= len;
}

//_______________________________________________

void Str::DeleteRight(long len)
{
  if (len < 0)
    NvError();

  if (length < len)
    len = length;

  length -= len;
  string[length] = '\0';
}

//_______________________________________________
//_______________________________________________

void Str::UpperCase()
{
  long i;
  for (i = 0; i < length; i++)
    string[i] = toupper(string[i]);
}

//_______________________________________________

void Str::LowerCase()
{
  long i;
  for (i = 0; i < length; i++)
    string[i] = tolower(string[i]);
}

//_______________________________________________
//_______________________________________________

void Str::Fill(char c)
{
  memset(string + length, c, size - length - 1);
  length = size - 1;
  string[length] = '\0';
}

//_______________________________________________

void Str::Fill(char c, long len)
{
  if (length < len)
  {
    if (size <= len)
    {
      long sz = len << 1;
      char *str = new char [sz];
      if (!str)
        AlError();

      strcpy(str, string);
      delete [] string;
      string = str;
      size = sz;
    }

    memset(string + length, c, len - length);
    length = len;
    string[length] = '\0';
  }
}

//_______________________________________________
//_______________________________________________

void Str::Reverse()
{
  int  i, j;
  char c;

  for (i = 0, j = length - 1; i < j; i++, j--)
  {
    c = string[i];
    string[i] = string[j];
    string[j] = c;
  }
}

//_______________________________________________
//_______________________________________________

void Str::RemoveLeftSpaces()
{
  long i;
  for (i = 0; i < length; i++)
  {
    if (!isspace(string[i]))
      break;
  }

  if (i)
  {
    strcpy(string, string + i);
    length -= i;
  }
}

//_______________________________________________

void Str::RemoveRightSpaces()
{
  long i;
  for (i = length-1; i >= 0; i--)
  {
    if (!isspace(string[i]))
      break;
  }

  length = i + 1;
  string[length] = '\0';
}

//_______________________________________________
//_______________________________________________

void Str::ToString(const long number)
{
  ostrstream ostr;
  ostr << number << ends;
  char *numStr = ostr.str();

  long len = strlen(numStr);
  if (size <= len)
  {
    long sz = len << 1;
    char *str = new char [sz];
    if (!str)
      AlError();

    delete [] string;
    string = str;
    size = sz;
  }

  strcpy(string, numStr);
  length = len;
  delete numStr;
}

//_______________________________________________

void Str::ToString(const double number)
{
  ostrstream ostr;
  ostr << number << ends;
  char *numStr = ostr.str();

  long len = strlen(numStr);
  if (size <= len)
  {
    long sz = len << 1;
    char *str = new char [sz];
    if (!str)
      AlError();

    delete [] string;
    string = str;
    size = sz;
  }

  strcpy(string, numStr);
  length = len;
  delete numStr;
}

//_______________________________________________

void Str::ToString(const double number, int p1, int p2, char *format)
{
  ostrstream ostr;
  double d;
  char *numStr, *ptrN, *ptrS;
  long len, lenN, n1, n2;
  char s;
  bool fill, round, sign;

  fill   = false;
  round  = false;
  sign   = false;

  if (format)
  {
    for (n1 = 0; format[n1]; n1++)
    {
      switch (format[n1])
      {
        case 'f':
        case 'F':
          fill = true;
          break;

        case 'r':
        case 'R':
          round = true;
          break;

        case 's':
        case 'S':
          sign = true;
      }
    }
  }

  if (p2 < 0)
    p2 = 0;

  d = number;
  if (round)
  {
    double r = d > 0 ? 0.5 : -0.5;
    for (n1 = 0; n1 < p2; n1++, r /= 10);

    d += r;
  }

  ostr.precision(18);
  ostr << d << ends;
  numStr = ostr.str();
  ptrN = numStr;
  if (*ptrN == '-')
  {
    s = '-';
    ptrN++;
  }

  else if (sign)
    s = '+';

  else
    s = 0;

  lenN = strlen(ptrN);
  for (n1 = 0; n1 < lenN; n1++)     // digits left of the decimal point
  {
    if (ptrN[n1] == '.')
      break;
  }

  n2 = lenN - n1;                   // digits right of the decimal point
  if (n2)
    n2--;

  if (p1 < n1)
    p1 = n1;

  if (p2 && (n2 || fill))       // true if there is a decimal point
  {
    if (n2 < p2 && !fill)
      p2 = n2;
  }

  else
    p2 = 0;

  if (p2 < n2)
    n2 = p2;

  len = p1;

  if (p2)
    len += p2 + 1;

  if (s)                            // if there is a sign
    len++;

  if (size <= len)
  {
    long sz = len << 1;
    ptrS = new char [sz];
    if (!ptrS)
      AlError();

    delete [] string;
    string = ptrS;
    size = sz;
  }

  ptrS = string;
  if (s)
  {
    *ptrS = s;
     ptrS++;
  }

  p1 -= n1;
  if (p1)  
  {
    memset(ptrS, '0', p1);
    ptrS += p1;
  }

  strncpy(ptrS, ptrN, n1);
  ptrN += n1;
  ptrS += n1;
  if (p2)
  {
    *ptrS = '.';
    ptrN++;
    ptrS++;

    strncpy(ptrS, ptrN, n2);
    ptrS += n2;

    p2 -= n2;
    if (p2)
    {
      memset(ptrS, '0', p2);
      ptrS += p2;
    }
  }

  *ptrS = '\0';

  length = len;
  delete numStr;
}

//_______________________________________________

void Str::ToString(tm *pTM, char *format)
{
  char buffer[3];
  char c;
  long i;
  int  n;

  length = 0;
  buffer[2] = 0;
  for (i = 0; format[i]; i++)
  {
    if (format[i] == '%')
    {
      i++;
      c = format[i];
      if (c == '%')
        Append(c);

      else
      {
        switch (c)
        {
          case 'Y':
          {
            n = pTM->tm_year+1900;
            buffer[0] = 48 + n / 1000;
            n %= 1000;
            buffer[1] = 48 + n / 100;
            Append(buffer);

            n %= 100;
            break;
          }

          case 'y':
            n = pTM->tm_year%100;
            break;

          case 'M':
            n = pTM->tm_mon+1;
            break;

          case 'D':
            n = pTM->tm_mday;
            break;

          case 'h':
            n = pTM->tm_hour;
            break;

          case 'm':
            n = pTM->tm_min;
            break;

          case 's':
            n = pTM->tm_sec;
            break;

          default:
            n = 0;
        }

        buffer[0] = 48 + n / 10;
        buffer[1] = 48 + n % 10;
        Append(buffer);
      }
    }

    else
      Append(format[i]);
  }
}

//_______________________________________________
//_______________________________________________

void Str::HexToString(const long number, int n)
{
  char temp[256], *ptr;
  char a;
  long len;

  if (n < 1)
    n = 1;

  for (ptr = temp + 256, len = number; len || n > 0; ptr--, n--)
  {
    a = len&15 + 48;
    len /= 16;
    if (a > 57)
      a += 7;

    *ptr = a;
  }

  len = 256 + temp - ptr;
  ptr++;

  if (size <= len)
  {
    long sz = len << 1;
    char *str = new char [sz];
    if (!str)
      AlError();

    delete [] string;
    string = str;
    size = sz;
  }

  memcpy(string, ptr, len);
  string[len] = '\0';
  length = len;
}

//_______________________________________________
//_______________________________________________

long Str::ToHex()
{
  char a;
  long number, i;

  number = 0;
  for (i = 0; i < length; i++)
  {
    a = toupper(string[i]) - 'A';
    if (a < 0 || a > 15)
      break;

    number = 16 * number + a;
  }

  return number;
}

//_______________________________________________
//_______________________________________________

bool Str::IsNumber()     const
{
  char *ptr = string;

  if (*ptr == '-' || *ptr == '+')     // Check for initial + or - sign.
    ptr++;

  if (isdigit(*ptr))                  // The fist character is a digit.
  {
    ptr++;
    while (isdigit(*ptr))
      ptr++;

    if (*ptr == '.')                   // If there is a decimal point,
    {
      ptr++;
      if (!isdigit(*ptr))              // the next character must be a digit.
        return false;

      ptr++;
      while (isdigit(*ptr))
        ptr++;
    }
  }

  else if (*ptr == '.')                // The first character is a decimal point.
  {
    ptr++;
    if (!isdigit(*ptr))                // The next character must be a digit.
      return false;

    ptr++;
    while (isdigit(*ptr))
      ptr++;
  }

  else                                 // The first character is neither.
    return false;

  if (*ptr == 'e' || *ptr == 'E')      // If exponent notation,
  {
    ptr++;
    if (*ptr == '-' || *ptr == '+')    // check for + or - sign.
      ptr++;

    if (!isdigit(*ptr))                // The next character must be a digit.
      return false;

    ptr++;
    while (isdigit(*ptr))
      ptr++;
  }

  if (!*ptr || isspace(*ptr))
    return true;

  return false;
}

//_______________________________________________
//_______________________________________________

void Str::AlError()
{
  throw "ERROR: String can not be allocated.";
}

//_______________________________________________

void Str::RaError()
{
  throw "ERROR: String position is out of range";
}

//_______________________________________________

void Str::NvError()
{
  throw "ERROR: String parameter is invalid";
}

//_______________________________________________
//_______________________________________________
// Friend function

istream &operator>>(istream &stream, Str &dst)
{
  char *ptr, *str;
  long sz, len;
  char c;

  ptr = dst.string;
  sz  = dst.size;
  len = 0;
  while (stream.get(c))
  {
    if (c == '\n')
      break;

    *ptr = c;
    ptr++;
    len++;

    if (len == sz)
    {
      sz <<= 1;
      str = new char [sz];
      if (!str)
        dst.AlError();

      memcpy(str, dst.string, len);
      delete [] dst.string;
      dst.string = str;
      ptr = str + len;
    }
  }

  *ptr = '\0';
  dst.size   = sz;
  dst.length = len;
  return stream;
}

//_______________________________________________
// Friend function

ostream &operator<<(ostream &stream, const Str &src)
{
  stream << src.string;
  return stream;
}

//________________________________________________________________
//________________________________________________________________

Parser::Parser()
{
  source = NULL;
  cursor = NULL;
}

//_______________________________________________

Parser::Parser(Str &src)
{
  source = &src;
  cursor = source->string;
}

//_______________________________________________

void Parser::SetString(Str &src)
{
  source = &src;
  cursor = source->string;
}

//_______________________________________________

bool Parser::Previous(int n)
{
  cursor -= n;
  if (cursor < source->string)
  {
    cursor = source->string;
    return false;
  }

  return true;
}

//_______________________________________________

bool Parser::Next(int n)
{
  cursor += n;
  if (cursor - source->string >= source->length)
  {
    cursor = source->string + source->length;
    return false;
  }

  return true;
}

//_______________________________________________

bool Parser::SetCursor(long n)
{
  if (n < 0 || n >= source->length)
    return false;

  cursor = source->string + n;
  return true;
}

//_______________________________________________

bool Parser::SetCursor(char ch)
{
  while (*cursor && *cursor != ch)
    cursor++;

  return (*cursor);
}

//_______________________________________________

bool Parser::SkipSpaces()
{
  while (*cursor && isspace(*cursor))
    cursor++;

  return *cursor;
}

//_______________________________________________

bool Parser::GetCharacter(char &ch)
{
  while (*cursor && isspace(*cursor))
    cursor++;

  ch = *cursor;
  if (!ch)
    return false;

  cursor++;
  return true;
}

//_______________________________________________

bool Parser::GetToken(Str &token)
{
  while (*cursor && isspace(*cursor))
    cursor++;

  if (!*cursor)
  {
    token.Clear();
    return false;
  }

  char *start = cursor;
  while (*cursor && !isspace(*cursor))
    cursor++;

  long len = cursor - start;
  if (token.size <= len)
  {
    long sz = len << 1;
    char *str = new char [sz];
    if (!str)
      token.AlError();

    delete [] token.string;
    token.string = str;
    token.size = sz;
  }

  strncpy(token.string, start, len);
  token.string[len] = '\0';
  token.length = len;
  if (*cursor)
    cursor++;

  return true;
}

//_______________________________________________

bool Parser::SkipToken(int n)
{
  while (n)
  {
    while (*cursor && isspace(*cursor))
      cursor++;

    if (!*cursor)
      return false;

    while (*cursor && !isspace(*cursor))
      cursor++;

    n--;
  }

  return true;
}

//_______________________________________________

void Parser::SkipBack()
{
  if (source->string < cursor)
    cursor--;

  while (source->string < cursor && isspace(*cursor))
    cursor--;

  while (source->string < cursor && !isspace(*cursor))
    cursor--;

  if (isspace(*cursor))
    cursor++;
}

//_______________________________________________

bool Parser::GetToken(Str &token, char delimiter)
{
  if (!*cursor)
  {
    token.Clear();
    return false;
  }

  char *start = cursor;
  while (*cursor && *cursor != delimiter)
    cursor++;

  long len = cursor - start;
  if (token.size <= len)
  {
    long sz = len << 1;
    char *str = new char [sz];
    if (!str)
      token.AlError();

    delete [] token.string;
    token.string = str;
    token.size = sz;
  }

  strncpy(token.string, start, len);
  token.string[len] = '\0';
  token.length = len;
  if (*cursor)
    cursor++;

  return true;
}

//_______________________________________________

bool Parser::SkipToken(char delimiter, int n)
{
  while (n)
  {
    while (*cursor && *cursor != delimiter)
      cursor++;

    if (!*cursor)
      return false;

    cursor++;
    n--;
  }

  return true;
}

//_______________________________________________

void Parser::SkipBack(char delimiter)
{
  if (source->string < cursor)
    cursor--;

  if (source->string < cursor && *cursor == delimiter)
    cursor--;

  while (source->string < cursor && *cursor != delimiter)
    cursor--;

  if (*cursor == delimiter)
    cursor++;
}

//_______________________________________________

bool Parser::GetToken(Str &token, long len)
{
  if (!*cursor)
  {
    token.Clear();
    return false;
  }

  long lenS = source->length + source->string - cursor;
  if (lenS < len)
    len = lenS;

  if (token.size <= len)
  {
    long sz = len << 1;
    char *str = new char [sz];
    if (!str)
      token.AlError();

    delete [] token.string;
    token.string = str;
    token.size = sz;
  }

  strncpy(token.string, cursor, len);
  token.string[len] = '\0';
  token.length = len;
  cursor += len;
  return true;
}

//_______________________________________________

bool Parser::GetLine(Str &token)
{
  if (!*cursor)
  {
    token.Clear();
    return false;
  }

  char *start = cursor;
  while (*cursor && *cursor != '\n')
    cursor++;

  long len = cursor - start;
  if (token.size <= len)
  {
    long sz = len << 1;
    char *str = new char [sz];
    if (!str)
      token.AlError();

    delete [] token.string;
    token.string = str;
    token.size = sz;
  }

  strncpy(token.string, start, len);
  token.string[len] = '\0';
  token.length = len;
  if (*cursor)
    cursor++;

  return true;
}

//_______________________________________________

bool Parser::SkipLine(int n)
{
  while (n)
  {
    while (*cursor && *cursor != '\n')
      cursor++;

    if (!*cursor)
      return false;

    cursor++;
    n--;
  }

  return true;
}

//_______________________________________________

void Parser::GetLeft(Str &token)
{
  long len = cursor - source->string;
  if (token.size <= len)
  {
    long sz = len << 1;
    char *str = new char [sz];
    if (!str)
      token.AlError();

    delete [] token.string;
    token.string = str;
    token.size = sz;
  }

  strncpy(token.string, source->string, len);
  token.string[len] = '\0';
  token.length = len;
}

//_______________________________________________

bool Parser::GetRight(Str &token)
{
  if (!*cursor)
  {
    token.Clear();
    return false;
  }

  long len = strlen(cursor);
  if (token.size <= len)
  {
    long sz = len << 1;
    char *str = new char [sz];
    if (!str)
      token.AlError();

    delete [] token.string;
    token.string = str;
    token.size = sz;
  }

  strcpy(token.string, cursor);
  token.length = len;
  cursor += len;
  return true;
}

//_______________________________________________

bool Parser::Compare(const Str &src) const
{
  if (!src.length)
    return false;

  return !strncmp(cursor, src.string, src.length);
}

//_______________________________________________

bool Parser::Compare(const char *src) const
{
  long len = strlen(src);
  if (!len)
    return false;

  return !strncmp(cursor, src, len);
}

//_______________________________________________

bool Parser::Contains(const Str &src)
{
  if (src.length)
  {
    char *ptr = strstr(source->string, src.string);
    if (ptr)
    {
      cursor = ptr;
      return true;
    }
  }

  return false;
}

//_______________________________________________

bool Parser::Contains(const char *src)
{
  long len = strlen(src);

  if (len)
  {
    char *ptr = strstr(source->string, src);
    if (ptr)
    {
      cursor = ptr;
      return true;
    }
  }

  return false;
}

//_______________________________________________

bool Parser::Contains(const char src)
{
  if (src)
  {
    char *ptr = strchr(source->string, src);
    if (ptr)
    {
      cursor = ptr;
      return true;
    }
  }

  return false;
}