blob: 8a703a3e97abeb17e9725e11b0f38f070c8cd986 [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 "DataInputStreamTest.h"
#include <decaf/lang/Integer.h>
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif
using namespace std;
using namespace decaf;
using namespace decaf::lang;
using namespace decaf::lang::exceptions;
using namespace decaf::io;
using namespace decaf::util;
////////////////////////////////////////////////////////////////////////////////
void DataInputStreamTest::testConstructor() {
try {
os->writeChar('t');
os->close();
openDataInputStream();
} catch (IOException e) {
CPPUNIT_FAIL("IOException during constructor test : " + e.getMessage());
}
try {
is->close();
} catch (IOException e) {
CPPUNIT_FAIL("IOException during constructor test : " + e.getMessage());
}
}
////////////////////////////////////////////////////////////////////////////////
void DataInputStreamTest::testRead1() {
try {
std::vector<unsigned char> test( testData.begin(), testData.end() );
os->write( &test[0], (int)test.size() );
os->close();
openDataInputStream();
std::vector<unsigned char> result;
result.resize( testData.length() );
is->read( &result[0], (int)testData.length() );
CPPUNIT_ASSERT_MESSAGE( "Incorrect data read",
string( (const char*)&result[0], result.size() ) == testData );
} catch( IOException &e ) {
CPPUNIT_FAIL("IOException during read test : " + e.getMessage());
}
}
////////////////////////////////////////////////////////////////////////////////
void DataInputStreamTest::testRead2() {
try {
std::vector<unsigned char> temp( testData.begin(), testData.end() );
os->write( &temp[0], (int)temp.size() );
os->close();
openDataInputStream();
unsigned char* result = new unsigned char[ testData.length() ];
is->read( result, (int)testData.length(), 0, (int)testData.length() );
CPPUNIT_ASSERT_MESSAGE("Incorrect data read",
string( (const char*)result, (int)testData.size() ) == testData );
delete [] result;
} catch( IOException &e ) {
CPPUNIT_FAIL("IOException during read test : " + e.getMessage());
}
}
////////////////////////////////////////////////////////////////////////////////
void DataInputStreamTest::test_readBoolean() {
try {
os->writeBoolean(true);
os->close();
openDataInputStream();
CPPUNIT_ASSERT_MESSAGE("Incorrect boolean written", is->readBoolean() );
} catch( IOException &e ) {
CPPUNIT_FAIL("readBoolean test failed : " + e.getMessage());
}
}
////////////////////////////////////////////////////////////////////////////////
void DataInputStreamTest::test_readByte() {
try {
os->writeByte( (unsigned char) 127);
os->close();
openDataInputStream();
CPPUNIT_ASSERT_MESSAGE("Incorrect byte read", is->readByte() == (unsigned char) 127);
} catch( IOException &e ) {
CPPUNIT_FAIL("IOException during readByte test : " + e.getMessage());
}
}
////////////////////////////////////////////////////////////////////////////////
void DataInputStreamTest::test_readChar() {
try {
os->writeChar('t');
os->close();
openDataInputStream();
CPPUNIT_ASSERT_MESSAGE("Incorrect char read", 't' == is->readChar());
} catch( IOException &e ) {
CPPUNIT_FAIL("IOException during readChar test : " + e.getMessage());
}
}
////////////////////////////////////////////////////////////////////////////////
void DataInputStreamTest::test_readDouble() {
try {
os->writeDouble(2345.76834720202);
os->close();
openDataInputStream();
CPPUNIT_ASSERT_MESSAGE("Incorrect double read",
2345.76834720202 == is->readDouble());
} catch( IOException &e ) {
CPPUNIT_FAIL("IOException during readDouble test" + e.getMessage());
}
}
////////////////////////////////////////////////////////////////////////////////
void DataInputStreamTest::test_readFloat() {
try {
os->writeFloat(29.08764f);
os->close();
openDataInputStream();
CPPUNIT_ASSERT_MESSAGE("Incorrect float read", is->readFloat() == 29.08764f);
} catch( IOException &e ) {
CPPUNIT_FAIL("readFloat test failed : " + e.getMessage());
}
}
////////////////////////////////////////////////////////////////////////////////
void DataInputStreamTest::test_readFully1() {
std::vector<unsigned char> temp( testData.begin(), testData.end() );
os->write( &temp[0], (int)temp.size() );
os->close();
openDataInputStream();
std::vector<unsigned char> result;
result.resize( testData.length() );
is->readFully( &result[0], (int)testData.length() );
string expected = "";
for( size_t ix = 0; ix < result.size(); ++ix ) {
expected += (char)result[ix];
}
CPPUNIT_ASSERT_MESSAGE("Incorrect data read", expected == testData );
CPPUNIT_ASSERT_THROW_MESSAGE(
"should throw IndexOutOfBoundsException",
is->readFully( &result[0], -1 ),
IndexOutOfBoundsException );
}
////////////////////////////////////////////////////////////////////////////////
void DataInputStreamTest::test_readFully2() {
std::vector<unsigned char> temp( testData.begin(), testData.end() );
os->write( &temp[0], (int)temp.size() );
openDataInputStream();
unsigned char* rbytes = new unsigned char[ testData.length() ];
is->readFully( rbytes, (int)testData.length() );
string expected = "";
for( size_t ix = 0; ix < testData.length(); ++ix ) {
expected += (char)rbytes[ix];
}
CPPUNIT_ASSERT_MESSAGE("Incorrect data read", expected == testData );
CPPUNIT_ASSERT_THROW_MESSAGE(
"should throw IndexOutOfBoundsException",
is->readFully( &temp[0], (int)temp.size(), -1, -1 ),
IndexOutOfBoundsException );
CPPUNIT_ASSERT_THROW_MESSAGE(
"should throw IndexOutOfBoundsException",
is->readFully( &temp[0], (int)temp.size(), 0, -1 ),
IndexOutOfBoundsException );
CPPUNIT_ASSERT_THROW_MESSAGE(
"should throw IndexOutOfBoundsException",
is->readFully( &temp[0], (int)temp.size(), 1, -1 ),
IndexOutOfBoundsException );
is->readFully( &temp[0], (int)temp.size(), -1, 0 );
is->readFully( &temp[0], (int)temp.size(), 0, 0 );
is->readFully( &temp[0], (int)temp.size(), 1, 0 );
CPPUNIT_ASSERT_THROW_MESSAGE(
"should throw IndexOutOfBoundsException",
is->readFully( &temp[0], (int)temp.size(), -1, 1 ),
IndexOutOfBoundsException );
CPPUNIT_ASSERT_THROW_MESSAGE(
"should throw IndexOutOfBoundsException",
is->readFully( &temp[0], (int)temp.size(), 0, Integer::MAX_VALUE ),
IndexOutOfBoundsException );
CPPUNIT_ASSERT_THROW_MESSAGE(
"should throw IndexOutOfBoundsException",
is->readFully( &temp[0], (int)temp.size(), 1, Integer::MAX_VALUE ),
IndexOutOfBoundsException );
delete [] rbytes;
}
////////////////////////////////////////////////////////////////////////////////
void DataInputStreamTest::test_readFullyNullArray() {
std::vector<unsigned char> test( 5000 );
DataInputStream is( new ByteArrayInputStream( test ), true );
unsigned char* nullByteArray = NULL;
is.readFully( nullByteArray, 0, 0, 0);
is.readFully( nullByteArray, 0, 1, 0);
CPPUNIT_ASSERT_THROW_MESSAGE(
"should throw NullPointerException",
is.readFully( nullByteArray, 0, 0, 1),
NullPointerException );
CPPUNIT_ASSERT_THROW_MESSAGE(
"should throw NullPointerException",
is.readFully( nullByteArray, 0, 1, 1),
NullPointerException );
CPPUNIT_ASSERT_THROW_MESSAGE(
"should throw NullPointerException",
is.readFully( nullByteArray, 0, 1, Integer::MAX_VALUE),
NullPointerException );
}
////////////////////////////////////////////////////////////////////////////////
void DataInputStreamTest::test_readFullyNullStream() {
DataInputStream is(NULL);
unsigned char* byteArray = new unsigned char[testData.length()];
is.readFully( byteArray, (int)testData.length(), 0, 0 );
is.readFully( byteArray, (int)testData.length(), 1, 0 );
CPPUNIT_ASSERT_THROW_MESSAGE(
"should throw NullPointerException",
is.readFully( byteArray, (int)testData.length(), 1, 1 ),
NullPointerException );
CPPUNIT_ASSERT_THROW_MESSAGE(
"should throw NullPointerException",
is.readFully( byteArray, (int)testData.length(), 0, 1 ),
NullPointerException );
CPPUNIT_ASSERT_THROW_MESSAGE(
"should throw NullPointerException",
is.readFully( byteArray, (int)testData.length(), 0, Integer::MAX_VALUE ),
NullPointerException );
delete [] byteArray;
}
////////////////////////////////////////////////////////////////////////////////
void DataInputStreamTest::test_readFullyNullStreamNullArray() {
DataInputStream is(NULL);
unsigned char* nullByteArray = NULL;
is.readFully( nullByteArray, 0, 0, 0 );
is.readFully( nullByteArray, 0, 1, 0 );
CPPUNIT_ASSERT_THROW_MESSAGE(
"should throw NullPointerException",
is.readFully( nullByteArray, 0, 0, 1),
NullPointerException );
CPPUNIT_ASSERT_THROW_MESSAGE(
"should throw NullPointerException",
is.readFully( nullByteArray, 0, 1, 1),
NullPointerException );
CPPUNIT_ASSERT_THROW_MESSAGE(
"should throw NullPointerException",
is.readFully( nullByteArray, 0, 1, Integer::MAX_VALUE),
NullPointerException );
}
////////////////////////////////////////////////////////////////////////////////
void DataInputStreamTest::test_readInt() {
try {
os->writeInt(768347202);
os->close();
openDataInputStream();
CPPUNIT_ASSERT_MESSAGE("Incorrect int read", 768347202 == is->readInt());
} catch( IOException &e ) {
CPPUNIT_FAIL("IOException during readInt test : " + e.getMessage());
}
}
////////////////////////////////////////////////////////////////////////////////
void DataInputStreamTest::test_readLong() {
try {
os->writeLong(9875645283333LL);
os->close();
openDataInputStream();
CPPUNIT_ASSERT_MESSAGE("Incorrect long read", 9875645283333LL == is->readLong());
} catch( IOException &e ) {
CPPUNIT_FAIL("read long test failed : " + e.getMessage());
}
}
////////////////////////////////////////////////////////////////////////////////
void DataInputStreamTest::test_readShort() {
try {
os->writeShort(9875);
os->close();
openDataInputStream();
CPPUNIT_ASSERT_MESSAGE("Incorrect short read", is->readShort() == (short) 9875);
} catch( IOException &e ) {
CPPUNIT_FAIL("Exception during read short test : " + e.getMessage());
}
}
////////////////////////////////////////////////////////////////////////////////
void DataInputStreamTest::test_readUnsignedByte() {
try {
os->writeByte((unsigned char) -127);
os->close();
openDataInputStream();
CPPUNIT_ASSERT_MESSAGE("Incorrect byte read", 129 == is->readUnsignedByte());
} catch( IOException &e ) {
CPPUNIT_FAIL("IOException during readUnsignedByte test : " + e.getMessage());
}
}
////////////////////////////////////////////////////////////////////////////////
void DataInputStreamTest::test_readUnsignedShort() {
os->writeShort(9875);
os->close();
openDataInputStream();
CPPUNIT_ASSERT_MESSAGE("Incorrect short read", 9875 == is->readUnsignedShort());
}
////////////////////////////////////////////////////////////////////////////////
void DataInputStreamTest::test_skipBytes() {
try {
std::vector<unsigned char> temp( testData.begin(), testData.end() );
os->write( &temp[0], (int)temp.size() );
os->close();
openDataInputStream();
is->skip( 100 );
std::vector<unsigned char> result( 50 );
is->read( &result[0], 50 );
is->close();
CPPUNIT_ASSERT_MESSAGE("Incorrect data read",
string( (const char*)&result[0], 50) == testData.substr( 100, 50) );
} catch( IOException &e ) {
CPPUNIT_FAIL("IOException during skipBytes test 1 : " + e.getMessage());
}
try {
std::size_t skipped = 0;
openDataInputStream();
CPPUNIT_ASSERT_NO_THROW_MESSAGE(
"Should throw an EOFException",
skipped = (std::size_t)is->skip( 500000 ) );
CPPUNIT_ASSERT_MESSAGE(
"Skipped should report " +
Integer::toString( (int)testData.length() ) + " not " +
Integer::toString( (int)skipped ),
skipped == testData.length() );
} catch( IOException &e ) {
CPPUNIT_FAIL("IOException during skipBytes test 2 : " + e.getMessage());
}
}
////////////////////////////////////////////////////////////////////////////////
void DataInputStreamTest::test(){
unsigned char buffer[30];
int ix = 0;
unsigned char byteVal = (unsigned char)'T';
unsigned short shortVal = 5;
unsigned int intVal = 10000;
unsigned long long longVal = 1000000000;
float floatVal = 10.0f;
double doubleVal = 100.0;
unsigned char arrayVal[3] = {
'a', 'b', 'c'
};
int size = sizeof(char);
memcpy( (char*)(buffer+ix), (char*)&byteVal, size );
ix += size;
size = sizeof(unsigned short);
unsigned short tempShort = util::Endian::byteSwap(shortVal);
memcpy( (char*)(buffer+ix), (char*)&tempShort, size );
ix += size;
size = sizeof(unsigned int);
unsigned int tempInt = util::Endian::byteSwap(intVal);
memcpy( (char*)(buffer+ix), (char*)&tempInt, size );
ix += size;
size = sizeof(unsigned long long);
unsigned long long tempLong = util::Endian::byteSwap(longVal);
memcpy( (char*)(buffer+ix), (char*)&tempLong, size );
ix += size;
size = sizeof(float);
float tempFloat = util::Endian::byteSwap(floatVal);
memcpy( (char*)(buffer+ix), (char*)&tempFloat, size );
ix += size;
size = sizeof(double);
double tempDouble = util::Endian::byteSwap(doubleVal);
memcpy( (char*)(buffer+ix), (char*)&tempDouble, size );
ix += size;
size = 3;
memcpy( (char*)(buffer+ix), (char*)&arrayVal, size );
ix += size;
// Create the stream with the buffer we just wrote to.
ByteArrayInputStream myStream( buffer, 30 );
DataInputStream reader( &myStream );
byteVal = reader.readByte();
//std::cout << "Byte Value = " << byteVal << std::endl;
CPPUNIT_ASSERT( byteVal == (unsigned char)'T' );
shortVal = reader.readShort();
//std::cout << "short Value = " << shortVal << std::endl;
CPPUNIT_ASSERT( shortVal == 5 );
intVal = reader.readInt();
//std::cout << "int Value = " << intVal << std::endl;
CPPUNIT_ASSERT( intVal == 10000 );
longVal = reader.readLong();
//std::cout << "long long Value = " << longVal << std::endl;
CPPUNIT_ASSERT( longVal == 1000000000 );
floatVal = reader.readFloat();
//std::cout << "float Value = " << floatVal << std::endl;
CPPUNIT_ASSERT( floatVal == 10.0f );
doubleVal = reader.readDouble();
//std::cout << "double Value = " << doubleVal << std::endl;
CPPUNIT_ASSERT( doubleVal == 100.0 );
reader.read( arrayVal, 3, 0, 3 );
//std::cout << "char[0] Value = " << (int)arrayVal[0] << std::endl;
CPPUNIT_ASSERT( arrayVal[0] == 'a' );
//std::cout << "char[1] Value = " << (int)arrayVal[1] << std::endl;
CPPUNIT_ASSERT( arrayVal[1] == 'b' );
//std::cout << "char[2] Value = " << (int)arrayVal[2] << std::endl;
CPPUNIT_ASSERT( arrayVal[2] == 'c' );
}
////////////////////////////////////////////////////////////////////////////////
void DataInputStreamTest::testString() {
std::string data1 = "This is a Test";
std::string data2 = "of the readString method";
std::string data3 = "This one should fail";
std::vector<unsigned char> buffer;
buffer.insert( buffer.begin(), data1.begin(), data1.end() );
buffer.push_back( '\0' );
buffer.insert( buffer.end(), data2.begin(), data2.end() );
buffer.push_back( '\0' );
buffer.insert( buffer.end(), data3.begin(), data3.end() );
// Create the stream with the buffer we just wrote to.
ByteArrayInputStream myStream( buffer );
DataInputStream reader( &myStream );
std::string result1 = reader.readString();
std::string result2 = reader.readString();
CPPUNIT_ASSERT( result1 == data1 );
CPPUNIT_ASSERT( result2 == data2 );
try{
std::string result3 = reader.readString();
CPPUNIT_ASSERT( false );
} catch(...){
CPPUNIT_ASSERT( true );
}
try{
unsigned char buffer2[1];
reader.readFully( buffer2, 0 );
} catch(...){
CPPUNIT_ASSERT( false );
}
}
////////////////////////////////////////////////////////////////////////////////
void DataInputStreamTest::testUTF() {
std::string data1 = "This is a Test";
std::string data2 = "of the readString method";
std::string data3 = "This one should fail";
char sizeData[sizeof(short)] = {0};
short tempShort = 0;
std::vector<unsigned char> buffer;
tempShort = util::Endian::byteSwap( ((unsigned short)data1.size()) );
memcpy( sizeData, (char*)&tempShort, sizeof( short ) );
buffer.insert( buffer.end(), sizeData, sizeData + sizeof(short) );
buffer.insert( buffer.end(), data1.begin(), data1.end() );
tempShort = util::Endian::byteSwap( ((unsigned short)data2.size()) );
memcpy( sizeData, (char*)&tempShort, sizeof( short ) );
buffer.insert( buffer.end(), sizeData, sizeData + sizeof(short) );
buffer.insert( buffer.end(), data2.begin(), data2.end() );
tempShort = util::Endian::byteSwap( (unsigned short)(data3.size() + 10 ) );
memcpy( sizeData, (char*)&tempShort, sizeof( short ) );
buffer.insert( buffer.end(), sizeData, sizeData + sizeof(short) );
buffer.insert( buffer.end(), data3.begin(), data3.end() );
// Create the stream with the buffer we just wrote to.
ByteArrayInputStream myStream( buffer );
DataInputStream reader( &myStream );
std::string result1 = reader.readUTF();
std::string result2 = reader.readUTF();
CPPUNIT_ASSERT( result1 == data1 );
CPPUNIT_ASSERT( result2 == data2 );
try{
std::string result3 = reader.readUTF();
CPPUNIT_ASSERT( false );
} catch(...){
CPPUNIT_ASSERT( true );
}
}
////////////////////////////////////////////////////////////////////////////////
void DataInputStreamTest::testHelper( unsigned char* input, int inputLength,
unsigned char* expect, int expectLength ) {
ByteArrayInputStream myStream( input, inputLength );
DataInputStream reader( &myStream );
std::string result = reader.readUTF();
for( std::size_t i = 0; i < result.length(); ++i ) {
CPPUNIT_ASSERT( (unsigned char)result[i] == expect[i] );
}
}
////////////////////////////////////////////////////////////////////////////////
void DataInputStreamTest::testUTFDecoding() {
// Test data with 1-byte UTF8 encoding.
{
unsigned char expect[] = {0x00, 0x0B, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x57, 0x6F, 0x72, 0x6C, 0x64};
unsigned char input[] = { 0x00, 0x0E ,0xC0, 0x80, 0x0B, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x57, 0x6F, 0x72, 0x6C, 0x64};
testHelper( input, (int) sizeof(input) / (int) sizeof(unsigned char),
expect, (int) sizeof(expect) / (int) sizeof(unsigned char) );
}
// Test data with 2-byte UT8 encoding.
{
unsigned char expect[] = {0x00, 0xC2, 0xA9, 0xC3, 0xA6 };
unsigned char input[] = { 0x00, 0x0A, 0xC0, 0x80, 0xC3, 0x82, 0xC2, 0xA9, 0xC3, 0x83, 0xC2, 0xA6 };
testHelper( input, (int) sizeof(input) / (int) sizeof(unsigned char),
expect, (int) sizeof(expect) / (int) sizeof(unsigned char) );
}
// Test data with 1-byte and 2-byte encoding with embedded NULL's.
{
unsigned char expect[] = {0x00, 0x04, 0xC2, 0xA9, 0xC3, 0x00, 0xA6 };
unsigned char input[] = { 0x00, 0x0D, 0xC0, 0x80, 0x04, 0xC3, 0x82, 0xC2, 0xA9, 0xC3, 0x83, 0xC0, 0x80, 0xC2, 0xA6 };
testHelper( input, (int) sizeof(input) / (int) sizeof(unsigned char),
expect, (int) sizeof(expect) / (int) sizeof(unsigned char) );
}
// Test with bad UTF-8 encoding, missing 2nd byte of two byte value
{
unsigned char input[] = { 0x00, 0x0D, 0xC0, 0x80, 0x04, 0xC3, 0x82, 0xC2, 0xC2, 0xC3, 0x83, 0xC0, 0x80, 0xC2, 0xA6 };
ByteArrayInputStream myStream( input, (int) sizeof(input) / (int) sizeof(unsigned char) );
DataInputStream reader( &myStream );
CPPUNIT_ASSERT_THROW_MESSAGE(
"Should throw a UTFDataFormatException",
reader.readUTF(),
UTFDataFormatException );
}
// Test with bad UTF-8 encoding, encoded value greater than 255
{
unsigned char input[] = { 0x00, 0x0D, 0xC0, 0x80, 0x04, 0xC3, 0x82, 0xC2, 0xC2, 0xC3, 0x83, 0xC0, 0x80, 0xC2, 0xA6 };
ByteArrayInputStream myStream( input, (int) sizeof(input) / (int) sizeof(unsigned char) );
DataInputStream reader( &myStream );
CPPUNIT_ASSERT_THROW_MESSAGE(
"Should throw a UTFDataFormatException",
reader.readUTF(),
UTFDataFormatException );
}
// Test data with value greater than 255 in 2-byte encoding.
{
unsigned char input[] = {0x00, 0x04, 0xC8, 0xA9, 0xC3, 0xA6};
ByteArrayInputStream myStream( input, (int) sizeof(input) / (int) sizeof(unsigned char) );
DataInputStream reader( &myStream );
CPPUNIT_ASSERT_THROW_MESSAGE(
"Should throw a UTFDataFormatException",
reader.readUTF(),
UTFDataFormatException );
}
// Test data with value greater than 255 in 3-byte encoding.
{
unsigned char input[] = {0x00, 0x05, 0xE8, 0xA8, 0xA9, 0xC3, 0xA6};
ByteArrayInputStream myStream( input, (int) sizeof(input) / (int) sizeof(unsigned char) );
DataInputStream reader( &myStream );
CPPUNIT_ASSERT_THROW_MESSAGE(
"Should throw a UTFDataFormatException",
reader.readUTF(),
UTFDataFormatException );
}
// Test with three byte encode that's missing a last byte.
{
unsigned char input[] = {0x00, 0x02, 0xE8, 0xA8};
ByteArrayInputStream myStream( input, (int) sizeof(input) / (int) sizeof(unsigned char) );
DataInputStream reader( &myStream );
CPPUNIT_ASSERT_THROW_MESSAGE(
"Should throw a UTFDataFormatException",
reader.readUTF(),
UTFDataFormatException );
}
}