#include "BinaryStream.h"

std::optional<int> BinaryStream::getNextByteAsInt(std::basic_istream<char>* stream)
{
    return stream->get();
}

bool BinaryStream::getNextNBytes(std::basic_istream<char>* stream, char* buffer, unsigned number)
{
    char c;
    for(unsigned idx=0; idx<number; idx++)
    {
        if(stream->get(c))
        {
            buffer[idx] = c;
        }
        else
        {
            return false;
        }
    }
    return true;
}

bool BinaryStream::getNextWord(std::basic_istream<char>* stream, char* buffer)
{
    return getNextNBytes(stream, buffer, sizeof(ByteUtils::Word));
}

bool BinaryStream::getNextDWord(std::basic_istream<char>* stream, char* buffer)
{
    return getNextNBytes(stream, buffer, sizeof(ByteUtils::DWord));
}

bool BinaryStream::getNextQWord(std::basic_istream<char>* stream, char* buffer)
{
    return getNextNBytes(stream, buffer, sizeof(ByteUtils::QWord));
}

std::optional<ByteUtils::Word> BinaryStream::getNextWord(std::basic_istream<char>* stream, bool reverse)
{
    char buffer[sizeof(ByteUtils::Word)];
    if(!BinaryStream::getNextWord(stream, buffer))
    {
        return false;
    }
    return ByteUtils::ToWord(buffer, reverse);
}

std::optional<ByteUtils::DWord> BinaryStream::getNextDWord(std::basic_istream<char>* stream)
{
    char buffer[sizeof(ByteUtils::DWord)];
    if(!BinaryStream::getNextDWord(stream, buffer))
    {
        return false;
    }
    return ByteUtils::ToDWord(buffer);;
}

std::optional<ByteUtils::QWord> BinaryStream::getNextQWord(std::basic_istream<char>* stream)
{
    char buffer[sizeof(ByteUtils::QWord)];
    if(!BinaryStream::getNextQWord(stream, buffer))
    {
        return false;
    }
    return ByteUtils::ToQWord(buffer);;
}

bool BinaryStream::checkNextDWord(std::basic_istream<char>* stream, const char* target)
{
    char buffer[sizeof(ByteUtils::DWord)];
    if(!BinaryStream::getNextDWord(stream, buffer))
    {
        return false;
    }

    if(!ByteUtils::CompareDWords(buffer, target))
    {
        return false;
    }
    return true;
}

bool BinaryStream::getNextString(std::basic_istream<char>* stream, std::string& target, unsigned numBytes)
{
    char c;
    for(unsigned idx=0; idx<numBytes; idx++)
    {
        if(!stream->get(c))
        {
            return false;
        }
        target += c;
    }
    return true;
}
