#if !defined(BRBLSTRM_H) && !defined(__BEDRC__)
#define BRBLSTRM_H
//========================================================================================
//
//     File:		BRBlStrm.h
//     Release Version:	$ 1.0d1 $
//
//     Creation Date:	October 22, 1990
//
//     COPYRIGHT 1990-93 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 BCSTOREU_H
#include "BCStoreU.h"
#endif

#ifndef BCCOLLU_H
#include "BCCollU.h"
#endif

#ifndef BRSTREAM_H
#include "BRStream.h"
#endif

#ifndef BRBLOCK_H
#include "BRBlock.h"
#endif

//========================================================================================
// CLASS BR_CBlockedStream
//========================================================================================

class BR_CBlockedStream : public BR_CStream
{
public:
	BR_CBlockedStream(BR_CBlock::BlockSize newSize);
	virtual~ BR_CBlockedStream();

	virtual BR_Boolean Read(void* buffer,
							StreamBufferSize& nBytes);

	virtual BR_Boolean Write(void* buffer,
							 StreamBufferSize& nBytes);

	virtual BR_Boolean Move(StreamIndex newOffset,
							StreamIndex oldOffset);

	virtual BR_Boolean InsertBytes(StreamIndex offset,
								   BR_Char* pBytes,
								   StreamBufferSize& nBytes);

	virtual BR_Boolean DeleteBytes(StreamIndex offset,
								   StreamBufferSize nBytes);
	virtual void Clear();

protected:
	void AppendBlock(BR_CBlock *block);

	BR_CBlock* CreateBlock() const;

	BR_CBlock* GetBlock(const BC_Index blockNo);
	BR_CBlock::BlockSize GetBlockSize() const;
	BR_CBlock* GetOffsetBlock(StreamIndex offset);
	BR_CBlock* GetNextBlock(BR_CBlock& block);
	BC_Index GetNumBlocks() const;

	void InsertBlock(BR_CBlock *block, BC_Index pos);

	void InsertNewBlocks(unsigned short nBlocks, BC_Index position);

	BR_CBlock* SplitBlock(BR_CBlock& block);
	BR_CBlock* SplitBlock(BR_CBlock& block,
						  const StreamIndex offset);

private:
	typedef BR_Boolean(BR_CBlock::*BlockIO)(void* ,
											unsigned long&);
	typedef unsigned long(* GetNBytes)(BR_CBlock& ,
									   const unsigned long,
									   const unsigned long);
							   
	BR_Boolean ReadOrWrite(BlockIO blockIOFunc,
						   void* buffer,
						   unsigned long& numBytes,
						   GetNBytes getNumBytesFunc);
						   
	BR_Boolean AppendBlocks(BR_CBlock& block1,
							BR_CBlock& block2,
							StreamIndex offset1,
							StreamIndex offset2);

	BR_Boolean FindBlock(BR_CBlock*& pBlock,
						 StreamIndex findOffset,
						 StreamIndex& offset);

	BR_Boolean GetTheBlock(BR_CBlock*& block,
						   StreamIndex findOffset,
						   StreamIndex& offset);

	BR_Boolean MoveBackwards(StreamIndex newOffset,
							 StreamIndex offset);
	BR_Boolean MoveForwards(StreamIndex newOffset,
							StreamIndex offset);

	BR_CBlock::BlockSize fBlockSize;
		// Absolute block size
		
	BC_TUnboundedCollection<BR_CBlock *, BC_CUnmanaged> fBlockList;
	
	BR_CBlock* fCurrentBlock;
		// The current block


	BR_SETCLASSNAME(BR_CBlockedStream);
};

//----------------------------------------------------------------------------------------
// BR_CBlockedStream::GetBlockSize
//----------------------------------------------------------------------------------------

inline BR_CBlock::BlockSize BR_CBlockedStream::GetBlockSize() const
{
	return fBlockSize;
}

//----------------------------------------------------------------------------------------
// BR_CBlockedStream::GetNumBlocks
//----------------------------------------------------------------------------------------

inline BC_Index BR_CBlockedStream::GetNumBlocks() const
{
	return fBlockList.Length();
}

//----------------------------------------------------------------------------------------
// BR_CBlockedStream::GetBlock
//----------------------------------------------------------------------------------------

inline BR_CBlock* BR_CBlockedStream::GetBlock(const BC_Index blockNo)
{
	return fBlockList[blockNo];
}
#endif
