#include "StdAfx.h"
#include ".\fifobuffer.h"

/*!
	コンストラクタ
*/
CFifoBuffer::CFifoBuffer()
{
	m_buf = NULL;
	m_bufLen = 0;
	m_inBufLen = 0;
}


/*!
	デストラクタ
*/
CFifoBuffer::~CFifoBuffer(void)
{
	Close();
}


/////////////////////////////////////////////////////////////////////////////////////////
//	初期化
/////////////////////////////////////////////////////////////////////////////////////////
/*!
	初期化
*/
void CFifoBuffer::InitBuf(int bufLen)
{
	Close();

	m_buf = new char[bufLen];
	m_bufLen = bufLen;
	m_inBufLen = 0;
}

/*!
	終了
*/
void CFifoBuffer::Close()
{
	if(m_buf)
	{
		delete m_buf;
		m_buf = NULL;
		m_bufLen = 0;
		m_inBufLen = 0;
	}
}


/////////////////////////////////////////////////////////////////////////////////////////
//	読み書き
/////////////////////////////////////////////////////////////////////////////////////////
/*!
	書き込み
*/
int CFifoBuffer::WriteBuf(char *data,int dataLen)
{
	//	バッファ一杯？
	if(IsFull())
		return(0);

	//	バッファ容量を超えている？
	if(dataLen > GetFreeBuf())
		dataLen = GetFreeBuf();

	//	コピー
	memmove(m_buf + m_inBufLen, data, dataLen);
	m_inBufLen += dataLen;

	//	実際に書かれた量
	return(dataLen);
}

/*!
	読み出し
*/
int CFifoBuffer::ReadBuf(char *data,int dataLen)
{
	//	データ空？
	if(IsEmpty())
		return(0);

	//	データが足りない？
	if(dataLen > GetInBuf())
		dataLen = GetInBuf();

	//	コピー
	memmove(data, m_buf, dataLen);

	//	バッファスクロール
	m_inBufLen -= dataLen;
	memmove(m_buf, m_buf + dataLen, m_inBufLen);

	//	実際によまれた量
	return(dataLen);
}


/*!
	読み出し(バッファを消さない)
*/
int CFifoBuffer::PeekBuf(char *data, int dataLen)
{
	//	データ空？
	if(IsEmpty())
		return(0);

	//	データが足りない？
	if(dataLen > GetInBuf())
		dataLen = GetInBuf();

	//	コピー
	memmove(data, m_buf, dataLen);

	//	実際によまれた量
	return(dataLen);
}

/*!
	クリア
*/
void CFifoBuffer::Clear()
{
	m_inBufLen = 0;
}

/////////////////////////////////////////////////////////////////////////////////////////
//	バッファ直アクセス
/////////////////////////////////////////////////////////////////////////////////////////
/*!
	書き込み用ポインタ取得
*/
char *CFifoBuffer::GetWriteBuffer(int *bufLeft)
{
	if(bufLeft != NULL)
		*bufLeft = GetFreeBuf();
	return(m_buf + m_inBufLen);
}

/*!
	読み出し用ポインタ取得
*/
char *CFifoBuffer::GetReadBuffer(int *bufLeft)
{
	if(bufLeft != NULL)
		*bufLeft = GetInBuf();
	return(m_buf);
}

/*!
	書き込んだ長さを設定
*/
void CFifoBuffer::SetWritedLen(int len)
{
	//	バッファ容量を超えている？
	ASSERT(len <= GetFreeBuf());
	if(len > GetFreeBuf())
		len = GetFreeBuf();

	m_inBufLen += len;
}

/*!
	読み出した長さを設定
*/
void CFifoBuffer::SetReadedLen(int len)
{
	//	バッファ容量を超えている？
	ASSERT(len <= GetInBuf());
	if(len > GetInBuf())
		len = GetInBuf();

	//	バッファスクロール
	m_inBufLen -= len;
	memmove(m_buf, m_buf + len, m_inBufLen);
}



/////////////////////////////////////////////////////////////////////////////////////////
//	状態取得
/////////////////////////////////////////////////////////////////////////////////////////
/*!
	バッファが一杯？
*/
int CFifoBuffer::IsFull()
{
	if(GetFreeBuf() == 0)
		return(1);
	return(0);
}

/*!
	バッファが空？
*/
int CFifoBuffer::IsEmpty()
{
	if(GetInBuf() == 0)
		return(1);
	return(0);
}


/*!
	使用容量取得
*/
int CFifoBuffer::GetInBuf()
{
	return(m_inBufLen);
}

/*!
	空き容量取得
*/
int CFifoBuffer::GetFreeBuf()
{
	return(m_bufLen - m_inBufLen);
}

