/*TITLE char vector optimization */

/****keyword-flag*** "%v %f %n" */
/* "7 28-Mar-98,21:22:14 VECTOR.CPP" */

#include "common.h"

SVector<char>::SVector()
{
	m_Rep = new VectorCharRep;
	m_Rep->m_Count = 1;
	m_Rep->m_Data = new char[m_Rep->m_Count];
	memcpy(m_Rep->m_Data,"",m_Rep->m_Count);
	m_Rep->m_RefCount = 1;
}

SVector<char>::SVector(ArrayIndex p_Count)
{
	m_Rep = new VectorCharRep;
	m_Rep->m_Count = p_Count+1;
	m_Rep->m_Data = new char[m_Rep->m_Count];
	memset(m_Rep->m_Data,0,m_Rep->m_Count);
	m_Rep->m_RefCount = 1;
}

SVector<char>::SVector(ArrayIndex p_Count, char *p_Data)
{
	m_Rep = new VectorCharRep;
	m_Rep->m_Count = p_Count+1;
	m_Rep->m_Data = new char[m_Rep->m_Count];
	m_Rep->m_RefCount = 1;
	memcpy(m_Rep->m_Data,p_Data,p_Count);
	m_Rep->m_Data[p_Count] = 0;
}

SVector<char>::SVector(char *p_Data)
{
	m_Rep = new VectorCharRep;
	m_Rep->m_Count = strlen(p_Data) + 1;
	m_Rep->m_Data = new char[m_Rep->m_Count];
	m_Rep->m_RefCount = 1;
	memcpy((void *)m_Rep->m_Data,p_Data,m_Rep->m_Count);
}

SVector<char>::SVector(const SVector<char>& p_Vector)
{
	if (this == &p_Vector)
		return;

	m_Rep = p_Vector.m_Rep;
	m_Rep->m_RefCount++;
}


SVector<char>& SVector<char>::operator=(const SVector<char>& p_Vector)
{
	if (this == &p_Vector)
		return *this;

	m_Rep->m_RefCount --;
	if (m_Rep->m_RefCount <= 0)
		{
		if (m_Rep->m_Count > 0)
			delete [] m_Rep->m_Data;
		delete m_Rep;
		}

	m_Rep = p_Vector.m_Rep;
	m_Rep->m_RefCount++;
	return *this;
}


int SVector<char>::operator!=(const SVector<char>& p_Vector)
{
	if (this->operator==(p_Vector))
		return 0;
	else
		return 1;
}

int SVector<char>::operator!=(char *p_Data)
{
	if (this->operator==(p_Data))
		return 0;
	else
		return 1;
}

int SVector<char>::operator==(const SVector<char>& p_Vector)
{
	if (this == &p_Vector)
		return 1;
	if (m_Rep->m_Count != p_Vector.m_Rep->m_Count)
		return 0;
	if (m_Rep->m_Count == 0)
		return 1;
	if (memcmp(m_Rep->m_Data,p_Vector.m_Rep->m_Data,m_Rep->m_Count*sizeof(char)) == 0)
		return 1;
	return 0;
}


int SVector<char>::operator==(char *p_Data)
{
	unsigned CompareLength = strlen(p_Data) + 1;

	if (CompareLength != m_Rep->m_Count)
		return 0;

	if (memcmp((void *)m_Rep->m_Data,(void *)p_Data, strlen(p_Data)) == 0)
		return 1;

	return 0;
}


void SVector<char>::SetSize(ArrayIndex p_NewCount)
{
	char *TempPtr;
	ArrayIndex Smaller;

	p_NewCount ++; // account for null byte

	TempPtr = new char[p_NewCount];
	Smaller = min(p_NewCount, m_Rep->m_Count);
	memcpy(TempPtr,m_Rep->m_Data,Smaller);	

	m_Rep->m_RefCount --;
	if (m_Rep->m_RefCount <= 0)
		{
		if (m_Rep->m_Count > 0)
			delete [] m_Rep->m_Data;
		delete m_Rep;
		}

	m_Rep = new VectorCharRep;
	m_Rep->m_Data = TempPtr;
	m_Rep->m_Count = p_NewCount;
	m_Rep->m_RefCount = 1;
}

ostream& operator<<(ostream& os, const SVector<char>& Str)
{
	os << (const char*)Str;

	return os;
}

istream& operator >> (istream& is, SVector<char>& Str)
{
    const short BUFLEN = 80;

    char Buf[BUFLEN];
    String Str1;
    String Str2;

    if (is.peek() == '\n')
        is.ignore();
    memset(Buf,0,BUFLEN);
    is.get(Buf,BUFLEN,'\n');
    Str2 = Buf;

    while ((is.fail() == 0) && (is.peek() != '\n'))
        {
        Str1 = Str1 + Str2;
        memset(Buf,0,BUFLEN);
        is.get(Buf,BUFLEN,'\n');
        Str2 = Buf;
        }

    Str = Str1 + Str2;

    return is;
}

SVector<char> SVector<char>::Mid(ArrayIndex p_Start, ArrayIndex p_Length)
{
	return SVector<char>(p_Length,(char *)m_Rep->m_Data+p_Start);
}

SVector<char> SVector<char>::operator +(const SVector<char>& p_Vector)
{
	ArrayIndex OldLength = m_Rep->m_Count - 1;
	ArrayIndex NewLength = OldLength + p_Vector.m_Rep->m_Count - 1;

	SVector<char> temp = SVector<char>(NewLength);
	memcpy((void *)temp.m_Rep->m_Data,m_Rep->m_Data,m_Rep->m_Count);
	memcpy((void *)(temp.m_Rep->m_Data+OldLength),
		p_Vector.m_Rep->m_Data,p_Vector.m_Rep->m_Count);

	return temp;
}

INLINE char& SVector<char>::operator[](ArrayIndex p_ArrayIndex)
{
qfassert (this && (p_ArrayIndex < m_Rep->m_Count));
return m_Rep->m_Data[p_ArrayIndex];
}

INLINE ArrayIndex SVector<char>::GetSize()
{
	return m_Rep->m_Count - 1;
}

INLINE SVector<char>::operator const char *() const
{
	return m_Rep->m_Data;
}

INLINE void *SVector<char>::GetDataAddress()
{
	return (void *)m_Rep->m_Data;
}

INLINE SVector<char>::~SVector()
{
	m_Rep->m_RefCount --;
	if (m_Rep->m_RefCount <= 0)
		{
		if (m_Rep->m_Count > 0)
			delete [] m_Rep->m_Data;
		delete m_Rep;
		}
}

int SVector<char>::Instr(char* p_Search, ArrayIndex p_Start)
{
  ArrayIndex i;
  int SearchLength = strlen(p_Search);
  ArrayIndex TargetLength = GetSize();
  char *Target = (char*)GetDataAddress();
  char *Search = p_Search;
  int Result = -1;

  for (i = p_Start; i < TargetLength - SearchLength + 1; i ++)
     {
       if (memcmp(Target+i,Search,SearchLength) == 0)
        {
        Result = i;
        break;
        }
     }

  return Result;
}


