#include <cstring>
#include <netinet/in.h>

#include "common/stream/Stream.h"

Stream::Stream() : error(false), writeIndex(0), readIndex(0) {
}

Stream::Stream(size_t capacity) : data(capacity), error(false), writeIndex(0), readIndex(0) {
}

bool Stream::hasData() const {
    return readIndex < writeIndex;
}

bool Stream::hasError() const {
    return error;
}

void Stream::clearError() {
    error = false;
}

void Stream::write(const void* writeData, size_t length) {
    if(data.write(writeIndex, writeData, length)) {
        writeIndex += length;
    } else {
        error = true;
    }
}

void Stream::write(const char* writeData) {
    write(writeData, strlen(writeData));
}

void Stream::writeUnsignedChar(u8 uc) {
    write(&uc, sizeof (u8));
}

void Stream::writeUnsignedShort(u16 us) {
    us = htons(us);
    write(&us, sizeof (u16));
}

void Stream::writeUnsignedInt(u32 ui) {
    ui = htonl(ui);
    write(&ui, sizeof (u32));
}

void Stream::read(void* buffer, size_t length) {
    if(readIndex + length <= writeIndex && data.read(readIndex, buffer, length)) {
        readIndex += length;
    } else {
        error = true;
    }
}

u8 Stream::readUnsignedChar() {
    u8 uc;
    read(&uc, sizeof (u8));
    return uc;
}

u16 Stream::readUnsignedShort() {
    u16 us;
    read(&us, sizeof (u16));
    us = ntohs(us);
    return us;
}

u32 Stream::readUnsignedInt() {
    u32 ui;
    read(&ui, sizeof (u32));
    ui = ntohl(ui);
    return ui;
}

bool Stream::readSocket(int socket) {
    readIndex = 0;
    return data.readSocket(socket, writeIndex);
}

void Stream::sendToSocket(int socket) const {
    data.sendToSocket(socket, writeIndex);
}