| /* |
| * 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 "DataOutputStreamTest.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::io; |
| using namespace decaf::util; |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| void DataOutputStreamTest::testFlush() { |
| |
| try { |
| os->writeInt(9087589); |
| os->flush(); |
| openDataInputStream(); |
| int c = is->readInt(); |
| is->close(); |
| CPPUNIT_ASSERT_MESSAGE("Failed to flush correctly", 9087589 == c); |
| } catch( IOException &e ) { |
| CPPUNIT_FAIL("Exception during flush test : " + e.getMessage()); |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| void DataOutputStreamTest::testSize() { |
| |
| try { |
| os->write( (unsigned char*)&testData[0], (int)testData.size(), 0, 150 ); |
| os->close(); |
| openDataInputStream(); |
| unsigned char rbuf[150]; |
| is->read( rbuf, 150, 0, 150 ); |
| is->close(); |
| CPPUNIT_ASSERT_MESSAGE("Incorrect size returned", 150 == os->size()); |
| } catch( IOException &e ) { |
| CPPUNIT_FAIL("Exception during write test : " + e.getMessage()); |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| void DataOutputStreamTest::testWrite1() { |
| |
| try { |
| os->write( (unsigned char*)&testData[0], (int)testData.size(), 0, 150 ); |
| os->close(); |
| openDataInputStream(); |
| unsigned char* rbuf = new unsigned char[150]; |
| is->read(rbuf, 150, 0, 150); |
| is->close(); |
| CPPUNIT_ASSERT_MESSAGE("Incorrect bytes written", |
| string( (const char*)rbuf, 150 ) == testData.substr( 0, 150 ) ); |
| delete [] rbuf; |
| } catch( IOException &e ) { |
| CPPUNIT_FAIL("Exception during write test : " + e.getMessage()); |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| void DataOutputStreamTest::testWrite2() { |
| |
| try { |
| os->write( 't' ); |
| os->close(); |
| openDataInputStream(); |
| char c = is->readChar(); |
| is->close(); |
| CPPUNIT_ASSERT_MESSAGE("Incorrect int written", 't' == c); |
| } catch( IOException &e ) { |
| CPPUNIT_FAIL("Exception during write test : " + e.getMessage()); |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| void DataOutputStreamTest::testWriteBoolean() { |
| |
| try { |
| os->writeBoolean(true); |
| os->close(); |
| openDataInputStream(); |
| bool c = is->readBoolean(); |
| is->close(); |
| CPPUNIT_ASSERT_MESSAGE("Incorrect boolean written", c ); |
| } catch( IOException &e ) { |
| CPPUNIT_FAIL("Exception during writeBoolean test : " + e.getMessage()); |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| void DataOutputStreamTest::testWriteByte() { |
| try { |
| os->writeByte( (unsigned char) 127 ); |
| os->close(); |
| openDataInputStream(); |
| unsigned char c = is->readByte(); |
| is->close(); |
| CPPUNIT_ASSERT_MESSAGE("Incorrect unsigned char written", c == (unsigned char) 127); |
| } catch( IOException &e ) { |
| CPPUNIT_FAIL("Exception during writeByte test : " + e.getMessage()); |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| void DataOutputStreamTest::testWriteBytes() { |
| |
| try { |
| os->writeBytes( testData ); |
| os->close(); |
| openDataInputStream(); |
| std::vector<unsigned char> result( testData.size() ); |
| is->read( &result[0], (int)testData.size() ); |
| is->close(); |
| CPPUNIT_ASSERT_MESSAGE("Incorrect bytes written", |
| string( (const char*)&result[0], result.size() ) == testData ); |
| } catch( IOException &e ) { |
| CPPUNIT_FAIL("Exception during writeBytes test : " + e.getMessage()); |
| } |
| |
| // regression test for HARMONY-1101 |
| DataOutputStream tester(NULL); |
| tester.writeBytes(""); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| void DataOutputStreamTest::testWriteChar() { |
| try { |
| os->writeChar('T'); |
| os->close(); |
| openDataInputStream(); |
| char c = is->readChar(); |
| is->close(); |
| CPPUNIT_ASSERT_MESSAGE("Incorrect char written", 'T' == c ); |
| } catch( IOException &e ) { |
| CPPUNIT_FAIL("Exception during writeChar test : " + e.getMessage()); |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| void DataOutputStreamTest::testWriteChars() { |
| |
| try { |
| os->writeChars( testData ); |
| os->close(); |
| openDataInputStream(); |
| std::vector<unsigned char> result( testData.size() ); |
| is->read( &result[0], (int)testData.size() ); |
| is->close(); |
| CPPUNIT_ASSERT_MESSAGE("Incorrect bytes written", |
| string( (const char*)&result[0], result.size() ) == testData ); |
| } catch( IOException &e ) { |
| CPPUNIT_FAIL("Exception during writeChars test : " + e.getMessage()); |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| void DataOutputStreamTest::testWriteDouble() { |
| try { |
| os->writeDouble(908755555456.98); |
| os->close(); |
| openDataInputStream(); |
| double c = is->readDouble(); |
| is->close(); |
| CPPUNIT_ASSERT_MESSAGE("Incorrect double written", 908755555456.98 == c); |
| } catch( IOException &e ) { |
| CPPUNIT_FAIL("Exception during writeDouble test : " + e.getMessage()); |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| void DataOutputStreamTest::testWriteFloat() { |
| try { |
| os->writeFloat(9087.456f); |
| os->close(); |
| openDataInputStream(); |
| float c = is->readFloat(); |
| is->close(); |
| CPPUNIT_ASSERT_MESSAGE("Incorrect float written", c == 9087.456f); |
| } catch( IOException &e ) { |
| CPPUNIT_FAIL("Exception during writeFloattest : " + e.getMessage()); |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| void DataOutputStreamTest::testWriteInt() { |
| try { |
| os->writeInt(9087589); |
| os->close(); |
| openDataInputStream(); |
| int c = is->readInt(); |
| is->close(); |
| CPPUNIT_ASSERT_MESSAGE("Incorrect int written", 9087589 == c); |
| } catch( IOException &e ) { |
| CPPUNIT_FAIL("Exception during writeInt test : " + e.getMessage()); |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| void DataOutputStreamTest::testWriteLong() { |
| try { |
| os->writeLong(908755555456LL); |
| os->close(); |
| openDataInputStream(); |
| long long c = is->readLong(); |
| is->close(); |
| CPPUNIT_ASSERT_MESSAGE("Incorrect long written", 908755555456LL == c); |
| } catch( IOException &e ) { |
| CPPUNIT_FAIL("Exception during writeLong test" + e.getMessage()); |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| void DataOutputStreamTest::testWriteShort() { |
| try { |
| os->writeShort((short) 9087); |
| os->close(); |
| openDataInputStream(); |
| short c = is->readShort(); |
| is->close(); |
| CPPUNIT_ASSERT_MESSAGE("Incorrect short written", 9087 == c); |
| } catch( IOException &e ) { |
| CPPUNIT_FAIL("Exception during writeShort test : " + e.getMessage()); |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| void DataOutputStreamTest::testWriteUTF() { |
| string testString = "test string one"; |
| os->writeUTF( testString ); |
| os->close(); |
| openDataInputStream(); |
| CPPUNIT_ASSERT_MESSAGE("Failed to write string in UTF format", |
| is->available() == (int)testString.length() + 2 ); |
| CPPUNIT_ASSERT_MESSAGE("Incorrect string returned", |
| is->readUTF() == testString ); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| void DataOutputStreamTest::testWriteUTFStringLength() { |
| |
| // String of length 65536 of Null Characters. |
| // Expect: UTFDataFormatException. |
| std::string testStr( 65536, char('a') ); |
| CPPUNIT_ASSERT_THROW_MESSAGE( |
| "Should throw a UTFDataFormatException", |
| os->writeUTF( testStr ), |
| UTFDataFormatException ); |
| |
| baos->reset(); |
| // String of length 65535 of non Null Characters since Null encodes as UTF-8. |
| // Expect: Success. |
| testStr.resize( 65535 ); |
| CPPUNIT_ASSERT_NO_THROW_MESSAGE( |
| "String of 65535 Non-Null chars should not throw.", |
| os->writeUTF( testStr ) ); |
| |
| baos->reset(); |
| // Set one of the 65535 bytes to a value that will result in a 2 byte UTF8 encoded sequence. |
| // This will cause the string of length 65535 to have a utf length of 65536. |
| // Expect: UTFDataFormatException. |
| testStr[0] = char( 255 ); |
| CPPUNIT_ASSERT_THROW_MESSAGE( |
| "Should throw an UTFDataFormatException", |
| os->writeUTF( testStr ), |
| UTFDataFormatException ); |
| |
| // Test that a zero length string write the zero size marker. |
| ByteArrayOutputStream byteOut; |
| DataOutputStream dataOut( &byteOut ); |
| dataOut.writeUTF( "" ); |
| CPPUNIT_ASSERT( dataOut.size() == 2 ); |
| |
| std::pair<const unsigned char*, int> array = byteOut.toByteArray(); |
| ByteArrayInputStream byteIn( array.first, array.second, true ); |
| DataInputStream dataIn( &byteIn ); |
| CPPUNIT_ASSERT( dataIn.readUnsignedShort() == 0 ); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| void DataOutputStreamTest::testHelper( unsigned char* input, int inputLength, |
| unsigned char* expect, int expectLength ) { |
| |
| std::string testStr( (char*)input, inputLength ); |
| os->writeUTF( testStr ); |
| |
| std::pair<const unsigned char*, int> array = baos->toByteArray(); |
| |
| CPPUNIT_ASSERT( array.first[0] == 0x00 ); |
| CPPUNIT_ASSERT( array.first[1] == (unsigned char)( expectLength ) ); |
| |
| for( int i = 2; i < array.second; ++i ) { |
| CPPUNIT_ASSERT( array.first[i] == expect[i-2] ); |
| } |
| |
| baos->reset(); |
| |
| delete [] array.first; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| void DataOutputStreamTest::testWriteUTFEncoding() { |
| |
| // Test data with 1-byte UTF8 encoding. |
| { |
| unsigned char input[] = {0x00, 0x0B, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x57, 0x6F, 0x72, 0x6C, 0x64}; |
| unsigned char expect[] = {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 input[] = {0x00, 0xC2, 0xA9, 0xC3, 0xA6 }; |
| unsigned char expect[] = {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 input[] = {0x00, 0x04, 0xC2, 0xA9, 0xC3, 0x00, 0xA6 }; |
| unsigned char expect[] = {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) ); |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| void DataOutputStreamTest::test(){ |
| |
| 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' |
| }; |
| |
| // Create the stream with the buffer we just wrote to. |
| ByteArrayOutputStream myStream; |
| DataOutputStream writer( &myStream ); |
| |
| writer.writeByte( byteVal ); |
| writer.writeShort( shortVal ); |
| writer.writeInt( intVal ); |
| writer.writeLong( longVal ); |
| writer.writeFloat( floatVal ); |
| writer.writeDouble( doubleVal ); |
| writer.write( arrayVal, 3, 0, 3 ); |
| |
| std::pair<const unsigned char*, int> buffer = myStream.toByteArray(); |
| int ix = 0; |
| |
| unsigned char tempByte = buffer.first[ix]; |
| CPPUNIT_ASSERT( tempByte == byteVal ); |
| ix += (int)sizeof( tempByte ); |
| |
| unsigned short tempShort = 0; |
| memcpy( &tempShort, buffer.first+ix, sizeof( unsigned short ) ); |
| tempShort = util::Endian::byteSwap( tempShort ); |
| CPPUNIT_ASSERT( tempShort == shortVal ); |
| ix += (int)sizeof( tempShort ); |
| |
| unsigned int tempInt = 0; |
| memcpy( &tempInt, buffer.first+ix, sizeof( unsigned int ) ); |
| tempInt = util::Endian::byteSwap( tempInt ); |
| CPPUNIT_ASSERT( tempInt == intVal ); |
| ix += (int)sizeof( tempInt ); |
| |
| unsigned long long tempLong = 0; |
| memcpy( &tempLong, buffer.first+ix, sizeof( unsigned long long ) ); |
| tempLong = util::Endian::byteSwap( tempLong ); |
| CPPUNIT_ASSERT( tempLong == longVal ); |
| ix += (int)sizeof( tempLong ); |
| |
| float tempFloat = 0; |
| memcpy( &tempFloat, buffer.first+ix, sizeof( float ) ); |
| tempFloat = util::Endian::byteSwap( tempFloat ); |
| CPPUNIT_ASSERT( tempFloat == floatVal ); |
| ix += (int)sizeof( tempFloat ); |
| |
| double tempDouble = 0; |
| memcpy( &tempDouble, buffer.first+ix, sizeof( double ) ); |
| tempDouble = util::Endian::byteSwap( tempDouble ); |
| CPPUNIT_ASSERT( tempDouble == doubleVal ); |
| ix += (int)sizeof( tempDouble ); |
| |
| delete [] buffer.first; |
| } |