#include "servermessagebase.h"
#include "connectionprofiler.h"
#include <QIODevice>
#include <QAbstractEventDispatcher>
#include <QTime>
#include <QDebug>

ServerMessageBase::ServerMessageBase()
{
}

void ServerMessageBase::readBytes( QIODevice *device, char *buffer, int len ) const
{
    int got = 0;
    bool more = true;
    while( got < len )
    {
        got += device->read( buffer + got, len - got);
        if( got < len )
        {
            QAbstractEventDispatcher::instance()->processEvents(QEventLoop::ExcludeSocketNotifiers);
            more = device->waitForReadyRead( -1 );
        }
    }

    if( got < len )
    {
        qWarning("opps short read %d bytes", len - got);
    }
    if( device->inherits("QTcpSocket"))
        ConnectionProfiler::instance()->addReadBytes(got);
}

bool ServerMessageBase::readBool( QIODevice *device ) const
{
    return readUint8( device ) == 0x01 ? true : false;
}

quint8 ServerMessageBase::readUint8( QIODevice *device ) const
{
    quint8 result = 0;
    char buffer[1] = {0};
    readBytes( device, buffer, 1);
    result |= (buffer[0] ) & 0x000000FF;
    return result;
}

quint16 ServerMessageBase::readUint16( QIODevice *device, bool bigEndian ) const
{
    quint16 result = 0;
    char buffer[2] = {0};
    readBytes( device, buffer, 2);

    if( bigEndian )
      reverse( buffer, 2 );

    result |= (buffer[0] << 8) & 0x0000FF00;
    result |= (buffer[1] ) & 0x000000FF;

    return result;
}

quint32 ServerMessageBase::readUint32( QIODevice *device, bool bigEndian  ) const
{
    quint32 result = 0;
    char buffer[4] = {0};

    readBytes( device, buffer, 4);

    if( bigEndian )
        reverse( buffer, 4 );

    result |= (buffer[0] << 24) & 0xFF000000;
    result |= (buffer[1] << 16) & 0x00FF0000;
    result |= (buffer[2] << 8) & 0x0000FF00;
    result |= (buffer[3] ) & 0x000000FF;

    return result;
}

void ServerMessageBase::reverse(char *buffer, int length) const
{
        int i, j;
        char temp;

        for (i = 0, j = length - 1; i < j; i++, j--)
        {
                temp = buffer[i];
                buffer[i] = buffer[j];
                buffer[j] = temp;
        }
}

Uint8Reader::Uint8Reader() : ServerMessageBase(), m_value(0)
{

}

bool Uint8Reader::loadMessage( QIODevice *device )
{
    m_value = readUint8(device);
    return true;
}

quint8 Uint8Reader::value()
{
    return m_value;
}

