// $Id: BRbInputBuffer.cpp,v 1.9 2003/02/21 01:59:06 yuya Exp $

#include "BRbInputBuffer.h"

////////////////////////////////////////////////////////////////////////////////

#define READTYPE(type)                                    \
    can_read(sizeof(type));                               \
    const type value = *((type*)(m_buffer + m_position)); \
    m_position += sizeof(type);                           \
    return value;

////////////////////////////////////////////////////////////////////////////////

BRbInputBuffer::BRbInputBuffer(char* buffer, int length)
{
	initialize(buffer, length);
}

BRbInputBuffer::BRbInputBuffer(VALUE buffer)
{
	initialize(RSTRING(buffer)->ptr, RSTRING(buffer)->len);
}

BRbInputBuffer::~BRbInputBuffer()
{
	if ( m_buffer ) {
		delete[] m_buffer;
	}

	m_position = 0;
	m_length   = 0;
	m_buffer   = 0;
}

////////////////////////////////////////////////////////////////////////////////

inline byte
BRbInputBuffer::read_byte()
{
	READTYPE(byte);
}

inline word
BRbInputBuffer::read_word()
{
	READTYPE(word);
}

inline dword
BRbInputBuffer::read_dword()
{
	READTYPE(dword);
}

inline void
BRbInputBuffer::read_bytes(void* buffer, int size)
{
	read_bytes_at(m_position, buffer, size);
	m_position += size;
}

inline void
BRbInputBuffer::read_bytes_at(dword position, void* buffer, dword size)
{
	can_read(size);
	::memcpy(buffer, m_buffer + position, size);
}

////////////////////////////////////////////////////////////////////////////////

inline void
BRbInputBuffer::initialize(char* buffer, int length)
{
	m_position = 0;
	m_length   = length;
	m_buffer   = new char[m_length];
	memcpy(m_buffer, buffer, m_length);
}

inline void
BRbInputBuffer::can_read(int size)
{
	if ( m_position + size > m_length ) {
		throw "EOF was detected. that was not expected.";
	}
}

////////////////////////////////////////////////////////////////////////////////
