/* $Id$ */

#include "throw.h"
#include "util.h"

void Util::Explode16(unsigned char *buf, const uint16_t &value)
{
	// xxx endianness
	buf[0] = value >> 8;
	buf[1] = value & 0xFF;
}

void Util::Explode32(unsigned char *buf, const uint32_t &value)
{
	// xxx endianness
	buf[0] = value >> 24;
	buf[1] = value >> 16;
	buf[2] = value >> 8;
	buf[3] = value & 0xFF;
}

void Util::Implode16(uint16_t &value, const unsigned char *buf)
{
	// xxx endianness
	value = (buf[0] << 8) | buf[1];
}

void Util::Implode32(uint32_t &value, const unsigned char *buf)
{
	// xxx endianness
	value = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
}

std::string Util::ReadLine(CFileRead &f)
{
	// xxx dirty - do it right (with fgets in file class oslt)

	std::string s;

	for (;;)
	{
		char ch;
		if (f.Read(&ch, 1) != 1)
			Throw("Premature EOF");

		if (ch == 0x0D)
			continue;

		if (ch == 0x0A)
			break;

		s += std::string(1, ch);
	}

	return s;
}

void Util::TokenizeCSV(std::vector<std::string> &v, const std::string &s)
{
	v.clear();

	std::string tmps;

	for (std::string::const_iterator i(s.begin()); i != s.end(); ++i)
	{
		const char ch(*i);

		if (ch == '"')
			continue;

		if (ch == ',')
		{
			v.push_back(tmps);
			tmps.clear();
			continue;
		}

		tmps += std::string(1, ch);
	}

	v.push_back(tmps);
}

static uint8_t FromHexOne(const char ch)
{
	if (ch >= '0' && ch <= '9')
		return ch - '0';

	if (ch >= 'A' && ch <= 'F')
		return ch - 'A' + 0x0A;

	if (ch >= 'a' && ch <= 'f')
		return ch - 'a' + 0x0A;

	Throw("Invalid hex character 0x%02X", ch);
}

uint8_t Util::FromHex(const char *hex)
{
	return (FromHexOne(hex[0]) << 4) | FromHexOne(hex[1]);
}
