#include "byteBuffer.h"
//#include "DNIe_util.h"

byteBuffer::byteBuffer( const char * hex ) : vector<byte>()
{
	hex2bin( hex, *this );
}

byteBuffer::byteBuffer( byte * data, size_type len )
{
	resize(len);
	if( len )
		memcpy( &at(0), data, len );
}

void byteBuffer::append( const byteBuffer & data )
{
	size_t	oldSize = size();

	if( !data.size() )
		return;

	resize(size()+data.size());

	memcpy( &at(oldSize), &data[0], data.size() );
}


void byteBuffer::assign( byte * data, size_type len )
{
	resize( len );
	if( len )
		memcpy( &at(0), data, len );
}

byteBuffer byteBuffer::substr( int offset, size_type len )
{
	if( offset < 0 )
	{
		offset = size() + offset;
		if( offset < 0 )
			offset = 0;
	}
	if( (size_type)offset >= size() )
		return byteBuffer();
	if( offset + len > size() )
		len = size() - offset;
	return byteBuffer(&at(offset),len);
}

byteBuffer byteBuffer::operator + (const byteBuffer & right)
{
	byteBuffer result(*this);
	result.append(right);
	return result;
};

byteBuffer byteBuffer::operator ^ (const byteBuffer & right)
{
	byteBuffer result(*this);

	if( right.size() > result.size() )
		result.resize( right.size() );

	for( size_t idx=0; idx<right.size(); ++idx )
		result[idx] ^= right[idx];

	return result;
};


//
// Funciones de conversion
//
byte * byteBuffer::hex2bin( const char * hex, byteBuffer & bin )
{
	ulong			binLen = (ulong)strlen(hex)/2;
	
	bin.resize(binLen);

	for( ulong idx=0; idx<binLen; idx++ )
	{
		bin[idx] = (byte)(isdigit(hex[0]) ? hex[0]-'0' : tolower(hex[0]) -'a' + 10)<<4;
		++hex;
		bin[idx] |= (byte)(isdigit(hex[0]) ? hex[0]-'0' : tolower(hex[0]) -'a' + 10);
		++hex;
	}
	return &bin[0];
}

void byteBuffer::zeroClear( void )
{
	if( size() )
		memset( &at(0), 0, size() );

	resize(0);
}