// Written by John Newbigin
// jn@it.swin.edu.au
// Copyright (c) 1999 John Newbigin
// Covered by the terms of the GPL.

// This is a huge string class
// that means char * with built in memory management

// all the modification functions should return a pointer to a HugeString
// that way, we can do copy on write strings.

// I don't exactly know what the benefits of this are, but it will prove a good
// programming task :).

#include <string.h>

#include "string.h"

HugeString::HugeString()
{
	string    = 0;
	alloclen  = 0;
	allocsize = 256;
	stringlen = 0;
	refCount  = 1;
}

HugeString::~HugeString()
{
	if(alloclen > 0)
	{
		delete[] string;
	}
}

int HugeString::GrowString(int blocks)
{
	char *newstr = new char[alloclen + allocsize];
	int newlen = alloclen + (blocks * allocsize);
	if(newstr)
	{
		if(string)
		{
			strcpy(newstr, string);
			delete[] string;
		}
		else
		{
			newstr[0] = 0;
		}
		alloclen = newlen;
		string = newstr;
	}
	// else raise an exception!!!!!!!!
	return alloclen;
}

int HugeString::cat(char *str)
{
	if(refCount > 1)
	{
		// we have to clone the string
		// I'll do this later though...
	}
	int slen = strlen(str);
	int length = slen + stringlen + 1;
	if(length > alloclen)
	{
		length -= alloclen;  // how much we need to add
		int blocks = length / allocsize;
		if((blocks * alloclen) < length)
		{
			blocks++;
		}
		GrowString(blocks);
	}
	strcat(string, str);
	stringlen = strlen(string);
	return stringlen;
}

int HugeString::cat(char c)
{
	char s[2]="x";
	s[0] = c;
	return cat(s);
}

int HugeString::clear()
{
	if(string)
	{
		string[0] = 0;
		stringlen = 0;
	}
	return stringlen;
}

char *HugeString::pchar()
{
	return string;
}

int HugeString::incRefCount()
{
	return ++refCount;
}

int HugeString::decRefCount()
{
	refCount--;
	int r=refCount;
	if(refCount == 0)
	{
		delete this;
	}
	return r;
}
