#ifndef BRTSTRS_H
#define BRTSTRS_H
//========================================================================================
//
//     File:		BRTStrs.h
//     Release Version:	$ 1.0d1 $
//
//     Creation Date:	4/2/93
//
//     COPYRIGHT 1993 SYMANTEC CORPORATION. ALL RIGHTS RESERVED. UNPUBLISHED -- RIGHTS
//     RESERVED UNDER THE COPYRIGHT LAWS OF THE UNITED STATES. USE OF COPYRIGHT NOTICE IS
//     PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION OR DISCLOSURE.
//
//     THIS SOFTWARE CONTAINS PROPRIETARY AND CONFIDENTIAL INFORMATION OF SYMANTEC
//     CORPORATION. USE, DISCLOSURE, OR REPRODUCTION IS PROHIBITED WITHOUT THE PRIOR
//     EXPRESS WRITTEN PERMISSION OF SYMANTEC CORPORATION.
//
//     RESTRICTED RIGHTS LEGEND
//     Use, duplication, or disclosure by the Government is subject to restrictions as set
//     forth in subparagraph (c)(l)(ii) of the Rights in Technical Data and Computer
//     Software clause at DFARS 252.227-7013. Symantec Corporation, 10201 Torre Avenue,
//     Cupertino, CA 95014.
//
//========================================================================================

#ifndef BRSTDDEF_H
#include "BRStdDef.h"
#endif

#ifndef   BRAUTODE_H
#include "BRAutoDe.h"
#endif

#ifndef BRCHARIT_H
#include "BRCharIt.h"
#endif

#ifndef BRCHARAC_H
#include "BRCharac.h"
#endif

//========================================================================================
//	CLASS BR_TString
//
//	String class implementations must satisfy the following requirements:
//
//	1) The string representation is kept in memory.
//	2) The string representation is contiguous.
//	3) The string is NUL-terminated.
//
//	This class defines a data member for the cached length of the string: fLength.
//	Assume that an implementation uses the name 'fRepresentation' for the array of
//	characters, where fRepresentation[0] is the first character in the string.
//	Then, this class has the following invariants:
//
//	fRepresentation[fLength] == 0;
//	fLength <= GrowCapacity(fLength);	// GrowCapacity does not count NUL terminator
//========================================================================================

template <class tCharacter>
class BR_TString : public _BR_CAutoDestructObject
{
public:

	~BR_TString();
	BR_TString();	
	BR_TString(const BR_TString<tCharacter> &string);	

	BR_TString<tCharacter>& operator=(const BR_TString<tCharacter>& string);
	BR_TString<tCharacter>& operator=(const tCharacter* string);
	
	BR_CharacterCount GetLength() const;

	BR_CharacterCount GetCapacity() const;

	virtual void Retrieve(tCharacter* items, 
							BR_CharacterCount numberItems, 
							BR_CharacterPosition position) const = 0;
		// Retrieve numberItems of items starting at position.
		
	virtual BR_CharacterCount GrowCapacity(BR_CharacterCount capacityNeeded) = 0;
		// Expand the string, if necessary to capacityNeeded.
		// Return the new capacity of the string.
		// The capacity of a string is never reduced (except by deleting the string).

	virtual void Replace(const tCharacter* items, 
						BR_CharacterCount numberItems, 
						BR_CharacterPosition position) = 0;
		// Replace numberItems of items starting at position.
		
	virtual void Insert(const tCharacter* items, 
						BR_CharacterCount numberItems, 
						BR_CharacterPosition position) = 0;
		// Insert characters into string just before the character at positition.
		// Insert at position GetLength() appends the characters.
		// Insert at position 0 prepends the characters.
		
	virtual void Delete(BR_CharacterCount numberItems, 
						BR_CharacterPosition position) = 0;
		// Delete numberItems characters, starting at position.
		
	virtual operator const tCharacter*() const = 0;
		// Return a pointer to the first character in the string.
		// Strings must be contiguous storage, and NUL-terminated!
	
	virtual tCharacter& operator[](BR_CharacterPosition position) = 0;
		// Retrieve by reference the character at given position.
		// The NUL-terminator at position=fLength cannot be accessed.
	
	// Convenenience functions, non-virtual, implemented using above functions.
	
	void Export(tCharacter* buffer) const;
		// Copy contents of this string to external buffer.
		// buffer will contain nul-terminated string.
		// It is client's responsibilitiy to ensure buffer is large enough.
	
	void ExportPascal(tCharacter* buffer) const;
		// Copy contents of this string to external 'pascal' buffer.
		// buffer will contain pascal string string with length byte at buffer[0].
		// It is client's responsibilitiy to ensure buffer is large enough.
	
	void ReplaceAll(const BR_TString<tCharacter> &string);
		// Replace entire contents of this string with string.
	
	void ReplaceAll(const tCharacter* items, BR_CharacterCount numberItems);
		// Replace entire contents of this string with items.

	void ReplaceAll(const tCharacter* string);
		// Replace entire contents of this string with (nul-terminated) string.
	
	void Insert(const BR_TString<tCharacter> &string, BR_CharacterPosition position);
		// Insert string at position.
	
	void Append(const BR_TString<tCharacter> &string);
		// Append string onto end of this string.
	
	void Append(const tCharacter* items, BR_CharacterCount numberItems);
		// Append items onto end of this string.
	
	void Append(const tCharacter* string);
		// Append (nul-terminated) string onto end of this string.
	
	void Append(tCharacter character);
		// Append a single character onto the end of this string.
	
	void Prepend(const tCharacter* items, BR_CharacterCount numberItems);
		// Prepend items onto beginning of this string.
		
	void Prepend(const BR_TString<tCharacter> &string);
		// Prepend string onto beginning of this string.
	
	void Truncate(BR_CharacterPosition position);
		// Truncate string at position.  Truncate(0) clears string.
	
	BR_Boolean FindSubString(const BR_TString<tCharacter> &subString,
							 BR_CharacterPosition &foundPosition,
							 BR_CharacterPosition startPosition=0) const;
		// Find a substring using the current tool.
	
	BR_Boolean FindCharacter(tCharacter character,
							 BR_CharacterPosition &foundPosition,
							 BR_CharacterPosition startPosition=0) const;
		// Find a character using the current tool.
	
	BR_TString<tCharacter>& operator+=(const BR_TString<tCharacter> &string);
		// Append string onto the end of this string.
		
	BR_TString<tCharacter>& operator+=(const tCharacter* items);
		// Append (nul-terminated) items onto the end of this string.
		
	BR_TString<tCharacter>& operator+=(tCharacter character);
		// Append a single character onto the end of this string.
		
	tCharacter operator[](BR_CharacterPosition position) const;
		// Retrieve character at given position.
		
	BR_Boolean operator==(const BR_TString<tCharacter> &string) const;
		// Is this string equal to string (as defined by current StringTool).

	BR_Boolean operator!=(const BR_TString<tCharacter> &string) const;
		// Is this string not equal to string (as defined by current StringTool).

	BR_Boolean operator<(const BR_TString<tCharacter> &string) const;
		// Is this string less than string (as defined by current StringTool).

	BR_Boolean operator>(const BR_TString<tCharacter> &string) const;
		// Is this string less than string (as defined by current StringTool).

	BR_Boolean operator<=(const BR_TString<tCharacter> &string) const;
		// Is this string less than or equal to string (as defined by current StringTool).

	BR_Boolean operator>=(const BR_TString<tCharacter> &string) const;
		// Is this string greater than or equal to string (as defined by current StringTool).

protected:

	BR_CharacterCount	fLength;
		// Cached length.
		// Must always be kept up to date, since GetLength is nonvirtual inline.

private:

	int Compare(const BR_TString<tCharacter> &string) const;
		// An implementation method.  Clients use comparision operators.
};

//----------------------------------------------------------------------------------------
//	BR_TString<tCharacter>::operator=
//----------------------------------------------------------------------------------------

template <class tCharacter>
inline BR_TString<tCharacter>& BR_TString<tCharacter>::operator=(const BR_TString<tCharacter>& string)
{
	if (&string != this)
		ReplaceAll(string);
	return *this;
}

//----------------------------------------------------------------------------------------
//	BR_TString<tCharacter>::operator=
//----------------------------------------------------------------------------------------

template <class tCharacter>
inline BR_TString<tCharacter>& BR_TString<tCharacter>::operator=(const tCharacter* string)
{
	ReplaceAll(string, BR_StringLength(string));
	return *this;
}

//----------------------------------------------------------------------------------------
//	BR_TString<tCharacter>::GetLength
//----------------------------------------------------------------------------------------

template <class tCharacter>
inline BR_CharacterCount BR_TString<tCharacter>::GetLength() const
{
	return fLength;
}

//----------------------------------------------------------------------------------------
//	BR_TString<tCharacter>::Export
//----------------------------------------------------------------------------------------

template <class tCharacter>
inline void BR_TString<tCharacter>::Export(tCharacter* buffer) const
{
	BR_BlockMove((const tCharacter*)(*this), buffer, GetLength()+1);
}

//----------------------------------------------------------------------------------------
//	BR_TString<tCharacter>::ExportPascal
//----------------------------------------------------------------------------------------

template <class tCharacter>
inline void BR_TString<tCharacter>::ExportPascal(tCharacter* buffer) const
{
	BR_BlockMove((const tCharacter*)(*this), buffer+1, GetLength());
	buffer[0] = (tCharacter) GetLength();
}

//----------------------------------------------------------------------------------------
//	BR_TString<tCharacter>::ReplaceAll
//----------------------------------------------------------------------------------------

template <class tCharacter>
inline void BR_TString<tCharacter>::ReplaceAll(const BR_TString<tCharacter>& string)
{
	Replace(string, string.fLength, 0);
	Truncate(string.fLength);
}

//----------------------------------------------------------------------------------------
//	BR_TString<tCharacter>::ReplaceAll
//----------------------------------------------------------------------------------------

template <class tCharacter>
inline void BR_TString<tCharacter>::ReplaceAll(const tCharacter* items,
				BR_CharacterCount numberItems)
{
	Replace(items, numberItems, 0);
	Truncate(numberItems);
}

//----------------------------------------------------------------------------------------
//	BR_TString<tCharacter>::ReplaceAll
//----------------------------------------------------------------------------------------

template <class tCharacter>
inline void BR_TString<tCharacter>::ReplaceAll(const tCharacter* items)
{
	ReplaceAll(items, BR_StringLength(items));
}

//----------------------------------------------------------------------------------------
//	BR_TString<tCharacter>::Insert
//----------------------------------------------------------------------------------------

template <class tCharacter>
inline void BR_TString<tCharacter>::Insert(const BR_TString<tCharacter>& string,
			BR_CharacterPosition position)
{
	Insert(string, string.fLength, position);
}


//----------------------------------------------------------------------------------------
//	BR_TString<tCharacter>::Append
//----------------------------------------------------------------------------------------

template <class tCharacter>
inline void BR_TString<tCharacter>::Append(const BR_TString<tCharacter>& string)
{
	Insert(string, string.fLength, fLength);
}

//----------------------------------------------------------------------------------------
//	BR_TString<tCharacter>::Append
//----------------------------------------------------------------------------------------

template <class tCharacter>
inline void BR_TString<tCharacter>::Append(const tCharacter* items,
			BR_CharacterCount numberItems)
{
	Insert(items, numberItems, fLength);
}

//----------------------------------------------------------------------------------------
//	BR_TString<tCharacter>::Append
//----------------------------------------------------------------------------------------

template <class tCharacter>
inline void BR_TString<tCharacter>::Append(const tCharacter* string)
{
	Insert(string, BR_StringLength(string), fLength);
}

//----------------------------------------------------------------------------------------
//	BR_TString<tCharacter>::Append
//----------------------------------------------------------------------------------------

template <class tCharacter>
inline void BR_TString<tCharacter>::Append(tCharacter character)
{
	Insert(&character, 1, fLength);
}

//----------------------------------------------------------------------------------------
//	BR_TString<tCharacter>::Prepend
//----------------------------------------------------------------------------------------

template <class tCharacter>
inline void BR_TString<tCharacter>::Prepend(const tCharacter* items,
			 BR_CharacterCount numberItems)
{
	Insert(items, numberItems, 0);
}


//----------------------------------------------------------------------------------------
//	BR_TString<tCharacter>::Prepend
//----------------------------------------------------------------------------------------

template <class tCharacter>
inline void BR_TString<tCharacter>::Prepend(const BR_TString<tCharacter>& string)
{
	Insert(string, string.fLength, 0);
}


//----------------------------------------------------------------------------------------
//	BR_TString<tCharacter>::Truncate
//----------------------------------------------------------------------------------------

template <class tCharacter>
inline void BR_TString<tCharacter>::Truncate(BR_CharacterPosition position)
{
	Delete(fLength - position, position);
}


//----------------------------------------------------------------------------------------
//	BR_TString<tCharacter>::operator+=
//----------------------------------------------------------------------------------------

template <class tCharacter>
inline BR_TString<tCharacter>& BR_TString<tCharacter>::operator+=(const BR_TString<tCharacter>& string)
{
	Append(string);
	return *this;
}

//----------------------------------------------------------------------------------------
//	BR_TString<tCharacter>::operator+=
//----------------------------------------------------------------------------------------

template <class tCharacter>
inline BR_TString<tCharacter>& BR_TString<tCharacter>::operator+=(const tCharacter* string)
{
	Append(string);
	return *this;
}

//----------------------------------------------------------------------------------------
//	BR_TString<tCharacter>::operator+=
//----------------------------------------------------------------------------------------

template <class tCharacter>
inline BR_TString<tCharacter>& BR_TString<tCharacter>::operator+=(tCharacter character)
{
	Append(character);
	return *this;
}

//----------------------------------------------------------------------------------------
//	BR_TString<tCharacter>::operator[]
//----------------------------------------------------------------------------------------

template <class tCharacter>
inline tCharacter BR_TString<tCharacter>::operator[](BR_CharacterPosition position) const
{
	tCharacter temp;
	Retrieve(&temp, 1, position);
	return temp;
}


//========================================================================================
//	CLASS BR_TBoundedString
//========================================================================================

template <class tCharacter, unsigned short tCapacity>
class BR_TBoundedString : public BR_TString<tCharacter>
{
public:

	~BR_TBoundedString();
	BR_TBoundedString();
	BR_TBoundedString(const BR_TBoundedString<tCharacter, tCapacity> &string);
	BR_TBoundedString(const BR_TString<tCharacter> &string);
	BR_TBoundedString(const tCharacter *items, BR_CharacterCount numberItems);
	BR_TBoundedString(const tCharacter *items);
	
	BR_TString<tCharacter>& operator=(const BR_TString<tCharacter>& string);
	BR_TString<tCharacter>& operator=(const tCharacter* string);
	
	BR_CharacterCount GetCapacity() const;

	virtual BR_CharacterCount GrowCapacity(BR_CharacterCount capacityNeeded);
		// Return tCapacity.  The capacity of bounded strings never changes.

	virtual void Retrieve(tCharacter* items, 
							BR_CharacterCount numberItems, 
							BR_CharacterPosition position) const;
		// Retrieve numberItems of items starting at position.
		
	virtual void Replace(const tCharacter* items, 
							BR_CharacterCount numberItems, 
							BR_CharacterPosition position);
		// Replace numberItems of items starting at position.

	virtual void Insert(const tCharacter* items, 
							BR_CharacterCount numberItems, 
							BR_CharacterPosition position);
		// Insert characters into string just before the character at positition.
		// Insert at position GetLength() appends the characters.
		// Insert at position 0 prepends the characters.
		
	virtual void Delete(BR_CharacterCount numberItems, BR_CharacterPosition position);
		// Delete numberItems characters, starting at position.
		
	virtual operator const tCharacter*() const;
		// Return a pointer to the first character in of the string.
		// Strings must be contiguous storage, and NUL-terminated!

	virtual tCharacter& operator[](BR_CharacterPosition position);
		// Retrieve by reference the character at given position.
		// The NUL-terminator at position=fLength cannot be accessed.
	
protected:

	tCharacter			fRepresentation[tCapacity+1];

	void SetLength(unsigned char length);
};

//----------------------------------------------------------------------------------------
//	BR_TBoundedString<tCharacter, tCapacity>::GetCapacity
//----------------------------------------------------------------------------------------

template <class tCharacter, unsigned short tCapacity>
inline BR_CharacterCount BR_TBoundedString<tCharacter, tCapacity>::GetCapacity() const
{
	return tCapacity;
}

//----------------------------------------------------------------------------------------
//	BR_TBoundedString<tCharacter, tCapacity>::operator=
//----------------------------------------------------------------------------------------

template <class tCharacter, unsigned short tCapacity>
inline BR_TString<tCharacter>& 
BR_TBoundedString<tCharacter, tCapacity>::operator=(const BR_TString<tCharacter>& string)
{
	if (&string != this)
		ReplaceAll(string);
	return *this;
}

//----------------------------------------------------------------------------------------
//	BR_TBoundedString<tCharacter, tCapacity>::operator=
//----------------------------------------------------------------------------------------

template <class tCharacter, unsigned short tCapacity>
inline BR_TString<tCharacter>& 
BR_TBoundedString<tCharacter, tCapacity>::operator=(const tCharacter* string)
{
	ReplaceAll(string, BR_StringLength(string));
	return *this;
}

//----------------------------------------------------------------------------------------
//	BR_TBoundedString<tCharacter, tCapacity>::SetLength
//----------------------------------------------------------------------------------------

template <class tCharacter, unsigned short tCapacity>
inline void BR_TBoundedString<tCharacter, tCapacity>::SetLength(unsigned char length)
{
	fLength = length;
	fRepresentation[length] = kNulCharacter;
}

//========================================================================================
//	CLASS BR_TDynamicString
//========================================================================================

template <class tCharacter>
class BR_TDynamicString : public BR_TString<tCharacter>
{
public:

	~BR_TDynamicString();
	BR_TDynamicString(const BR_TDynamicString<tCharacter> &string);
	BR_TDynamicString(const BR_TString<tCharacter> &string);
	BR_TDynamicString(const tCharacter *items, BR_CharacterCount numberItems);
	BR_TDynamicString(const tCharacter *items);

	BR_TString<tCharacter>& operator=(const BR_TString<tCharacter>& string);
	BR_TString<tCharacter>& operator=(const tCharacter* string);
	
	BR_CharacterCount GetCapacity() const;

	virtual BR_CharacterCount GrowCapacity(BR_CharacterCount capacityNeeded);
		// Expand the string, if necessary to capacityNeeded.
		// Return the new capacity of the string.
		// The capacity of a string is never reduced (except by deleting the string).
		
	virtual void Retrieve(tCharacter* items, 
								BR_CharacterCount numberItems, 
								BR_CharacterPosition position) const;
		// Retrieve numberItems of items starting at position.
		
	virtual void Replace(const tCharacter* items, 
								BR_CharacterCount numberItems, 
								BR_CharacterPosition position);
		// Replace numberItems of items starting at position.
		
	virtual void Insert(const tCharacter* items, 
								BR_CharacterCount numberItems, 
								BR_CharacterPosition position);
		// Insert characters into string just before the character at positition.
		// Insert at position GetLength() appends the characters.
		// Insert at position 0 prepends the characters.
		
	virtual void Delete(BR_CharacterCount numberItems, BR_CharacterPosition position);
		// Delete numberItems characters, starting at position.
		
	virtual operator const tCharacter*() const;
		// Return a pointer to the first character in of the string.
		// Strings must be contiguous storage, and NUL-terminated!

	virtual tCharacter& operator[](BR_CharacterPosition position);
		// Retrieve by reference the character at given position.
	
protected:

	tCharacter	*fRepresentation;

	BR_TDynamicString(BR_CharacterCount capacity=0);

	void Resize(BR_CharacterCount newCapacity);

	void SetLength(unsigned char length);

private:

	void AllocateRepresentation(BR_CharacterCount capacity);

	BR_CharacterCount	fCapacity;
};


//----------------------------------------------------------------------------------------
//	BR_TBoundedString<tCharacter, tCapacity>::GetCapacity
//----------------------------------------------------------------------------------------

template <class tCharacter>
inline BR_CharacterCount BR_TDynamicString<tCharacter>::GetCapacity() const
{
	return fCapacity;
}

//----------------------------------------------------------------------------------------
//	BR_TDynamicString<tCharacter, tCapacity>::operator=
//----------------------------------------------------------------------------------------

template <class tCharacter>
inline BR_TString<tCharacter>& 
BR_TDynamicString<tCharacter>::operator=(const BR_TString<tCharacter>& string)
{
	if (&string != this)
		ReplaceAll(string);
	return *this;
}

//----------------------------------------------------------------------------------------
//	BR_TDynamicString<tCharacter, tCapacity>::operator=
//----------------------------------------------------------------------------------------

template <class tCharacter>
inline BR_TString<tCharacter>& 
BR_TDynamicString<tCharacter>::operator=(const tCharacter* string)
{
	ReplaceAll(string, BR_StringLength(string));
	return *this;
}

//----------------------------------------------------------------------------------------
//	BR_TDynamicString<tCharacter, tCapacity>::SetLength
//----------------------------------------------------------------------------------------

template <class tCharacter>
inline void BR_TDynamicString<tCharacter>::SetLength(unsigned char length)
{
	fLength = length;
	fRepresentation[length] = kNulCharacter;
}

//----------------------------------------------------------------------------------------
//	BR_TDynamicString<tCharacter, tCapacity>::SetLength
//----------------------------------------------------------------------------------------

template <class tCharacter>
inline void BR_TDynamicString<tCharacter>::AllocateRepresentation(BR_CharacterCount capacity)
{
	fRepresentation = new tCharacter[capacity+1];
	fCapacity=capacity;
	SetLength(0);
}

//========================================================================================
//	CLASS BR_TUniversalStringReader
//========================================================================================

template <class tCharacter>
class BR_TUniversalStringReader : public BR_TTextReader<tCharacter>
{
public:
	BR_TUniversalStringReader(const BR_TString<tCharacter> &string);

protected:

	virtual void GetNextBuffer();
		// Get another buffer from text data structure.
		// Updates fStart, fLimit, and fNext.
		// Must ensure that fNext==fStart, fStart<=fLimit

	virtual void GetPreviousBuffer();
		// Gets previous buffer from text data structure.
		// Updates fStart, fLimit, and fNext.
		// Must ensure that fNext==fLimit, fStart<=fLimit

	const BR_TString<tCharacter>	&fString;
};

//========================================================================================
//	CLASS BR_TUniversalStringFilter
//========================================================================================

template <class tCharacter>
class BR_TUniversalStringFilter : public BR_TTextFilter<tCharacter>
{
public:
	BR_TUniversalStringFilter(BR_TString<tCharacter> &string);

protected:

	virtual void GetNextBuffer();
		// Get another buffer from text data structure.
		// Updates fStart, fLimit, and fNext.
		// Must ensure that fNext==fStart, fStart<=fLimit

	virtual void GetPreviousBuffer();
		// Gets previous buffer from text data structure.
		// Updates fStart, fLimit, and fNext.
		// Must ensure that fNext==fLimit, fStart<=fLimit

	BR_TString<tCharacter>	&fString;
};

//========================================================================================
//	CLASS BR_TStringWriter
//========================================================================================

template <class tCharacter, class tString>
class BR_TStringWriter: public BR_TTextWriter<tCharacter>
{
public:
	enum {kDefaultExpansion=32};
	
	~BR_TStringWriter();
	BR_TStringWriter(tString &string, 
					 BR_TextWriterMode mode=BR_kTextAppend,
					 unsigned short expansion=kDefaultExpansion);
	
	void SetExpansion(unsigned short expansion = kDefaultExpansion)
		{ fExpansion = expansion; }
	
protected:
	virtual void FlushAndGetNextBuffer();
		// Flush the current buffer.
		// Get another buffer from string, update fNext and fLimit.

	void FlushAndUpdateText();
		// Flush the current buffer.
		// Do whatever may be necessary to restore text structure to valid state,
		// ... e.g. restore NUL termination, cached length member, etc.
		// This method is called from destructor.

	tString	&fString;
	unsigned short fExpansion;
};

#endif
