#include "Message.h"

#include <cstdlib>

using std::memcpy;

void MyResizeHandler::resize (Buffer *oldBuffer) {
  int newSize = oldBuffer->length() + 4;
  char *newData = new char[newSize];
  memcpy (newData, &(*oldBuffer)[0], oldBuffer->length());
  delete[] oldBuffer->buffer;
  oldBuffer->buffer = newData;
  oldBuffer->len = newSize;
  return;
}

//Message Konstruktor
Message::Message(Buffer *buffer) : myBuffer (buffer), pos (0), resHandler (NULL) {
  short int i = 0x1;
  char *c = (char *) &i;
  if (*c == 0x1) {
    littleEndian = true;
  } else {
		littleEndian = false;
  }
}

bool Message::write(int8_t c) {
	return writeBytes(reinterpret_cast<char*>(&c), 1);
}

bool Message::write(int16_t s) {
	return writeBytes(reinterpret_cast<char*>(&s), 2);
}

bool Message::write(int32_t d) {
	return writeBytes(reinterpret_cast<char*>(&d), 4);
}

bool Message::read(int8_t &c) {
  return readBytes(reinterpret_cast<char*>(&c), 1);
}

bool Message::read(int16_t &s) {
  return readBytes(reinterpret_cast<char*>(&s), 2);
}

bool Message::read(int32_t &d) {
  return readBytes(reinterpret_cast<char*>(&d), 4);
}

void Message::reset() {
	pos = 0;
}

Buffer *Message::getBuffer() {
  return myBuffer;
}

void Message::register_resize_handler(ResizeHandler *hndl) {
	resHandler = hndl;
}

bool Message::writeBytes(char* bytes, int number) {
	if (myBuffer->length() - pos < number) {
		if (resHandler == NULL) {
			return false;
		} else {
			resHandler->resize(myBuffer);
		}
	}
	if (littleEndian) {
		for (int i = number-1; i >= 0; --i) {
			(*myBuffer)[pos++] = bytes[i];
		}
	} else {
		memcpy(&(*myBuffer)[pos], bytes, number);
		pos += number;
	}
	return true;
}

bool Message::readBytes(char* bytes, int number) {
	if (myBuffer->length() - pos < number) {
		if (resHandler == NULL) {
			return false;
		} else {
			resHandler->resize(myBuffer);
		}
	}
	if (littleEndian) {
		for (int i = number-1; i >= 0; --i) {
			 bytes[i] = (*myBuffer)[pos++];
		}
	} else {
		memcpy(bytes, &(*myBuffer)[pos], number);
		pos += number;
	}
	return true;
}
