/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <decaf/io/DataInputStream.h>

using namespace std;
using namespace decaf;
using namespace decaf::io;
using namespace decaf::util;
using namespace decaf::lang;
using namespace decaf::lang::exceptions;

////////////////////////////////////////////////////////////////////////////////
DataInputStream::DataInputStream( InputStream* inputStream, bool own )
 : FilterInputStream( inputStream, own ) {}

////////////////////////////////////////////////////////////////////////////////
DataInputStream::~DataInputStream() {}

////////////////////////////////////////////////////////////////////////////////
int DataInputStream::read( std::vector<unsigned char>& buffer )
    throw ( io::IOException ) {

    try {
        return this->read( &buffer[0], 0, buffer.size() );
    }
    DECAF_CATCH_RETHROW( IOException )
    DECAF_CATCHALL_THROW( IOException )
}

////////////////////////////////////////////////////////////////////////////////
int DataInputStream::read( unsigned char* buffer,
                           std::size_t offset,
                           std::size_t length )
    throw ( IOException, IndexOutOfBoundsException, NullPointerException ) {

    try {

        if( buffer == NULL ) {
            throw NullPointerException(
                __FILE__, __LINE__,
                "DataInputStream::read - Buffer is null" );
        }

        return inputStream->read( &buffer[offset], length );
    }
    DECAF_CATCH_RETHROW( IndexOutOfBoundsException )
    DECAF_CATCH_RETHROW( NullPointerException )
    DECAF_CATCH_RETHROW( IOException )
    DECAF_CATCHALL_THROW( IOException )
}

////////////////////////////////////////////////////////////////////////////////
bool DataInputStream::readBoolean()
    throw( IOException, EOFException ) {

    try {
        unsigned char value = 0;
        readAllData( &value, sizeof(value) );
        return (bool)( value != 0 );
    }
    DECAF_CATCH_RETHROW( EOFException )
    DECAF_CATCH_RETHROW( IOException )
    DECAF_CATCHALL_THROW( IOException )
}

////////////////////////////////////////////////////////////////////////////////
char DataInputStream::readByte()
    throw ( IOException, EOFException ) {

    try {
        unsigned char value = 0;
        readAllData( &value, sizeof(value) );
        return (char)( value );
    }
    DECAF_CATCH_RETHROW( EOFException )
    DECAF_CATCH_RETHROW( IOException )
    DECAF_CATCHALL_THROW( IOException )
}

////////////////////////////////////////////////////////////////////////////////
unsigned char DataInputStream::readUnsignedByte()
    throw ( IOException, EOFException ) {

    try {
        unsigned char value = 0;
        readAllData( &value, sizeof(value) );
        return value;
    }
    DECAF_CATCH_RETHROW( EOFException )
    DECAF_CATCH_RETHROW( IOException )
    DECAF_CATCHALL_THROW( IOException )
}

////////////////////////////////////////////////////////////////////////////////
char DataInputStream::readChar() throw ( IOException, EOFException ) {
    try {
        unsigned char value = 0;
        readAllData( &value, sizeof(value) );
        return (char)( value );
    }
    DECAF_CATCH_RETHROW( EOFException )
    DECAF_CATCH_RETHROW( IOException )
    DECAF_CATCHALL_THROW( IOException )
}

////////////////////////////////////////////////////////////////////////////////
short DataInputStream::readShort() throw ( io::IOException, io::EOFException ) {
    try {
        short value = 0;
        unsigned char buffer[sizeof(value)] = {0};
        readAllData( buffer, sizeof(value) );
        value |= (buffer[0] << 8 | buffer[1] << 0);
        return value;
    }
    DECAF_CATCH_RETHROW( EOFException )
    DECAF_CATCH_RETHROW( IOException )
    DECAF_CATCHALL_THROW( IOException )
}

////////////////////////////////////////////////////////////////////////////////
unsigned short DataInputStream::readUnsignedShort()
    throw ( io::IOException, io::EOFException ) {
    try {
        unsigned short value = 0;
        unsigned char buffer[sizeof(value)] = {0};
        readAllData( buffer, sizeof(value) );
        value |= (buffer[0] << 8 | buffer[1] << 0);
        return value;
    }
    DECAF_CATCH_RETHROW( EOFException )
    DECAF_CATCH_RETHROW( IOException )
    DECAF_CATCHALL_THROW( IOException )
}

////////////////////////////////////////////////////////////////////////////////
int DataInputStream::readInt() throw ( io::IOException, io::EOFException ) {
    try {
        unsigned int value = 0;
        unsigned char buffer[sizeof(value)] = {0};
        readAllData( buffer, sizeof(value) );
        value |= (buffer[0] << 24 | buffer[1] << 16 |
                  buffer[2] << 8 | buffer[3] << 0);
        return value;
    }
    DECAF_CATCH_RETHROW( EOFException )
    DECAF_CATCH_RETHROW( IOException )
    DECAF_CATCHALL_THROW( IOException )
}

////////////////////////////////////////////////////////////////////////////////
double DataInputStream::readDouble() throw ( io::IOException, io::EOFException ) {
    try {
        unsigned long long lvalue = this->readLong();
        double value = 0.0;
        memcpy( &value, &lvalue, sizeof( unsigned long long ) );
        return value;
    }
    DECAF_CATCH_RETHROW( EOFException )
    DECAF_CATCH_RETHROW( IOException )
    DECAF_CATCHALL_THROW( IOException )
}

////////////////////////////////////////////////////////////////////////////////
float DataInputStream::readFloat() throw ( io::IOException, io::EOFException ) {
    try {
        unsigned int lvalue = this->readInt();
        float value = 0.0f;
        memcpy( &value, &lvalue, sizeof( unsigned int ) );
        return value;
    }
    DECAF_CATCH_RETHROW( EOFException )
    DECAF_CATCH_RETHROW( IOException )
    DECAF_CATCHALL_THROW( IOException )
}

////////////////////////////////////////////////////////////////////////////////
long long DataInputStream::readLong()
    throw ( io::IOException, io::EOFException ) {
    try {
        unsigned long long value = 0;
        unsigned char buffer[sizeof(value)] = {0};
        readAllData( buffer, sizeof(value) );

        // Have to do it this way because on Solaris and Cygwin we get all
        // kinds of warnings when shifting a byte up into a long long.
        unsigned long long byte1 = buffer[0] & 0x00000000000000FFULL;
        unsigned long long byte2 = buffer[1] & 0x00000000000000FFULL;
        unsigned long long byte3 = buffer[2] & 0x00000000000000FFULL;
        unsigned long long byte4 = buffer[3] & 0x00000000000000FFULL;
        unsigned long long byte5 = buffer[4] & 0x00000000000000FFULL;
        unsigned long long byte6 = buffer[5] & 0x00000000000000FFULL;
        unsigned long long byte7 = buffer[6] & 0x00000000000000FFULL;
        unsigned long long byte8 = buffer[7] & 0x00000000000000FFULL;

        value = ( byte1 << 56 | byte2 << 48 | byte3 << 40 | byte4 << 32 |
                  byte5 << 24 | byte6 << 16 | byte7 << 8  | byte8 << 0 );

        return value;
    }
    DECAF_CATCH_RETHROW( EOFException )
    DECAF_CATCH_RETHROW( IOException )
    DECAF_CATCHALL_THROW( IOException )
}

////////////////////////////////////////////////////////////////////////////////
std::string DataInputStream::readString()
    throw ( io::IOException, io::EOFException ) {
    try {
        size_t size = 1024;
        std::vector<char> buffer;
        buffer.resize( size );
        size_t pos = 0;

        while( true ) {

            if( inputStream->read( (unsigned char*)( &buffer[pos] ), 1 ) == -1 ) {
                throw EOFException(
                    __FILE__, __LINE__,
                    "DataInputStream::readString - Reached EOF" );
            }

            // if null is found we are done
            if( buffer[pos] == '\0' ){
                break;
            }

            // Resize to hold more if we exceed current size
            if( ++pos > size ) {
                buffer.resize( (size *= 2) );
            }
        }

        return &buffer[0];
    }
    DECAF_CATCH_RETHROW( EOFException )
    DECAF_CATCH_RETHROW( IOException )
    DECAF_CATCHALL_THROW( IOException )
}

////////////////////////////////////////////////////////////////////////////////
std::string DataInputStream::readUTF()
    throw ( io::IOException, io::EOFException ) {
    try {
        std::vector<unsigned char> buffer;
        unsigned short length = readUnsignedShort();
        buffer.resize(length + 1);  // Add one for a null charactor.

        std::size_t n = 0;
        while( n < length ) {
            int count = inputStream->read( &buffer[n], (length - n) );
            if( count == -1 ) {
                throw EOFException(
                    __FILE__, __LINE__,
                    "DataInputStream::readUTF - Reached EOF" );
            }
            n += count;
        }

        return (char*)&buffer[0];
    }
    DECAF_CATCH_RETHROW( EOFException )
    DECAF_CATCH_RETHROW( IOException )
    DECAF_CATCHALL_THROW( IOException )
}

////////////////////////////////////////////////////////////////////////////////
void DataInputStream::readFully( std::vector< unsigned char >& buffer )
    throw ( io::IOException, io::EOFException ) {
    try {
        if( buffer.empty() ) {
            return;
        }
        this->readFully( &buffer[0], 0, buffer.size() );
    }
    DECAF_CATCH_RETHROW( EOFException )
    DECAF_CATCH_RETHROW( IOException )
    DECAF_CATCHALL_THROW( IOException )
}

////////////////////////////////////////////////////////////////////////////////
void DataInputStream::readFully( unsigned char* buffer,
                                 std::size_t offset,
                                 std::size_t length )
    throw ( io::IOException,
            io::EOFException,
            lang::exceptions::IndexOutOfBoundsException,
            lang::exceptions::NullPointerException )
{
    try {

        if( buffer == NULL ) {
            throw NullPointerException(
                __FILE__, __LINE__,
                "DataInputStream::readFully - Buffer is null" );
        }

        std::size_t n = 0;
        while( n < length ) {
            int count = inputStream->read( &buffer[offset + n], (length - n) );
            if( count == -1 ) {
                throw EOFException(
                    __FILE__, __LINE__,
                    "DataInputStream::readFully - Reached EOF" );
            }
            n += count;
        }
    }
    DECAF_CATCH_RETHROW( IndexOutOfBoundsException )
    DECAF_CATCH_RETHROW( NullPointerException )
    DECAF_CATCH_RETHROW( EOFException )
    DECAF_CATCH_RETHROW( IOException )
    DECAF_CATCHALL_THROW( IOException )
}

////////////////////////////////////////////////////////////////////////////////
std::size_t DataInputStream::skip( std::size_t num )
    throw( io::IOException, lang::exceptions::UnsupportedOperationException ) {
    try {
        std::size_t total = 0;
        std::size_t cur = 0;

        while( ( total < num ) &&
               ( ( cur = inputStream->skip( num-total ) ) > 0 ) ) {
            total += cur;
        }

        return total;
    }
    DECAF_CATCH_RETHROW( UnsupportedOperationException )
    DECAF_CATCH_RETHROW( IOException )
    DECAF_CATCHALL_THROW( IOException )
}
