blob: e0ebc10f0481a3ba764b368af6100de2edc51542 [file] [log] [blame]
/*
* 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 )
}