#ifndef BRPASSTR_H
#define BRPASSTR_H
//========================================================================================
//
//     File:		BRPasStr.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 BRTSTRS_H
#include "BRTStrs.h"
#endif

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

//========================================================================================
//	CLASS BR_TPascalString
//========================================================================================

template <unsigned char tCapacity>
class BR_TPascalStringWriter;

template <unsigned char tCapacity>
class BR_TPascalString : public BR_TString<BR_Char>
{
	friend class BR_TPascalStringWriter<tCapacity>;

public:

	~BR_TPascalString();
	BR_TPascalString();

	BR_TPascalString(const BR_TPascalString<tCapacity> &string);
	BR_TPascalString(const BR_TString<BR_Char> &string);
	BR_TPascalString(const BR_Char *items, BR_CharacterCount numberItems);

	BR_TPascalString(const BR_Char *string);
		// string points to first character of NUL-terminated string

	BR_TPascalString(const BR_PascalChar *string);
		// string points to length byte of pascal string storage

	BR_TString<BR_Char>& operator=(const BR_TString<BR_Char> &string);
	BR_TString<BR_Char>& operator=(const BR_Char *string);
		// string points to first character of NUL-terminated string

	BR_TString<BR_Char>& operator=(const BR_PascalChar* string);
		// string points to length byte of pascal string storage

	BR_CharacterCount GetCapacity() const;

	virtual BR_CharacterCount GrowCapacity(BR_CharacterCount capacityNeeded);
		// Called only when changing capacity from amount allocated by constructor.

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

	virtual void Insert(const BR_Char* 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 BR_Char*() const;
		// Return a pointer to the first character in the string.

	virtual operator const BR_PascalChar*() const;
		// Return a pointer to the length byte of the string.

	virtual BR_Char& operator[](BR_CharacterPosition position);
		// Retrieve by reference the character at given position.
		// The length byte cannot be accessed.
		// The NUL-terminator at position=fLength cannot be accessed.
		
	void ExportPascal(BR_Char* buffer) const;
		// Copy contents of this string to external 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 ExportPascal(BR_PascalChar* buffer) const;
		// Copy contents of this string to external buffer.
		// buffer will contain pascal string string with length byte at buffer[0].
		// It is client's responsibilitiy to ensure buffer is large enough.

protected:
	enum { kLengthByte = 0 };
	
	BR_Char	fStorage[tCapacity+2];

	void SetLength(unsigned char length);
};

//----------------------------------------------------------------------------------------
//	BR_TPascalString<tCapacity>::GetCapacity
//----------------------------------------------------------------------------------------

template <unsigned char tCapacity>
inline BR_CharacterCount BR_TPascalString<tCapacity>::GetCapacity() const
{
	return tCapacity;
}

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

template <unsigned char tCapacity>
inline void BR_TPascalString<tCapacity>::ExportPascal(BR_Char* buffer) const
{
	BR_BlockMove((const BR_PascalChar*)(*this), (BR_PascalChar*)buffer, GetLength()+1);
}

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

template <unsigned char tCapacity>
inline void BR_TPascalString<tCapacity>::ExportPascal(BR_PascalChar* buffer) const
{
	BR_BlockMove((const BR_PascalChar*)(*this), buffer, GetLength()+1);
}

//----------------------------------------------------------------------------------------
//	BR_TPascalString<tCapacity>::SetLength
//----------------------------------------------------------------------------------------

template <unsigned char tCapacity>
void BR_TPascalString<tCapacity>::SetLength(unsigned char length)
{
	fLength = length;
	fStorage[kLengthByte] = fLength;
	fStorage[fLength+1] = kNulCharacter;
}

//========================================================================================
//	CLASS BR_CUniversalPascalStringReader
//========================================================================================

class BR_CUniversalPascalStringReader : public BR_TUniversalStringReader<BR_Char>
{
public:
	BR_CUniversalPascalStringReader(const BR_TString<BR_Char> &string) :  
		BR_TUniversalStringReader<BR_Char>(string) {}
};

//========================================================================================
//	CLASS BR_CPascalString255
//========================================================================================

const unsigned char BR_kPascalString255Capacity = 255;

class BR_CPascalString255 : public BR_TPascalString<BR_kPascalString255Capacity>
{
public:

	~BR_CPascalString255();
	BR_CPascalString255();

	BR_CPascalString255(const BR_TString<BR_Char> &string);
	BR_CPascalString255(const BR_Char *items, BR_CharacterCount numberItems);

	BR_CPascalString255(const BR_Char *string);
		// string points to first character of NUL-terminated string

	BR_CPascalString255(const BR_PascalChar *string);
		// string points to length byte of pascal string storage

	BR_TString<BR_Char>& operator=(const BR_TString<BR_Char> &string);
	BR_TString<BR_Char>& operator=(const BR_Char *string);
		// string points to first character of NUL-terminated string

	BR_TString<BR_Char>& operator=(const BR_PascalChar* string);
		// string points to length byte of pascal string storage

};

//========================================================================================
//	CLASS BR_CPascalString255
//========================================================================================

const unsigned char BR_kPascalString32Capacity = 32;

class BR_CPascalString32 : public BR_TPascalString<BR_kPascalString32Capacity>
{
public:

	~BR_CPascalString32();
	BR_CPascalString32();

	BR_CPascalString32(const BR_TString<BR_Char> &string);
	BR_CPascalString32(const BR_Char *items, BR_CharacterCount numberItems);

	BR_CPascalString32(const BR_Char *string);
		// string points to first character of NUL-terminated string

	BR_CPascalString32(const BR_PascalChar *string);
		// string points to length byte of pascal string storage

	BR_TString<BR_Char>& operator=(const BR_TString<BR_Char> &string);
	BR_TString<BR_Char>& operator=(const BR_Char *string);
		// string points to first character of NUL-terminated string

	BR_TString<BR_Char>& operator=(const BR_PascalChar* string);
		// string points to length byte of pascal string storage

};

//========================================================================================
//	CLASS BR_TPascalStringWriter
//========================================================================================

template <unsigned char tCapacity>
class BR_TPascalStringWriter : public BR_TTextWriter<BR_Char>
{
public:
	enum {kDefaultExpansion=32};
	
	~BR_TPascalStringWriter();
	BR_TPascalStringWriter(BR_TPascalString<tCapacity> &string, 
							BR_TextWriterMode mode=BR_kTextAppend,
							unsigned short expansion=kDefaultExpansion);

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.

	BR_TPascalString<tCapacity>	&fString;
};

#ifdef qTemplateForwardReferenceCantBeBaseClassBug
//========================================================================================
//	CLASS BR_CPascalString255Writer
//========================================================================================

class BR_CPascalString255Writer : public BR_TPascalStringWriter<BR_kPascalString255Capacity>
{
public:
	BR_CPascalString255Writer(BR_CPascalString255 &string, BR_TextWriterMode mode=BR_kTextAppend) :  
		BR_TPascalStringWriter<BR_kPascalString255Capacity>(string, mode) {}
};

//========================================================================================
//	CLASS BR_TPascalStringWriter
//========================================================================================

class BR_CPascalString32Writer : public BR_TPascalStringWriter<BR_kPascalString32Capacity>
{
public:
	BR_CPascalString32Writer(BR_CPascalString32 &string, BR_TextWriterMode mode=BR_kTextAppend) :  
		BR_TPascalStringWriter<BR_kPascalString32Capacity>(string, mode) {}
};
#endif

#endif
