blob: 92c2ce3c6c45bdab69f5ceb2d34709ee68d46f90 [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 "InflaterTest.h"
#include <decaf/util/zip/Deflater.h>
#include <decaf/util/zip/Inflater.h>
#include <decaf/util/zip/Adler32.h>
#include <decaf/util/zip/CRC32.h>
#include <vector>
using namespace std;
using namespace decaf;
using namespace decaf::lang;
using namespace decaf::lang::exceptions;
using namespace decaf::util;
using namespace decaf::util::zip;
////////////////////////////////////////////////////////////////////////////////
InflaterTest::InflaterTest() {
}
////////////////////////////////////////////////////////////////////////////////
InflaterTest::~InflaterTest() {
}
////////////////////////////////////////////////////////////////////////////////
void InflaterTest::setUp() {
}
////////////////////////////////////////////////////////////////////////////////
void InflaterTest::tearDown() {
}
////////////////////////////////////////////////////////////////////////////////
void InflaterTest::testEnd() {
// test method of java.util.zip.inflater.end()
unsigned char byteArray[] = { 5, 2, 3, 7, 8 };
int r = 0;
Inflater inflate;
inflate.setInput( byteArray, 5, 0, 5 );
inflate.end();
try {
inflate.reset();
inflate.setInput( byteArray, 5, 0, 5 );
} catch( IllegalStateException& e ) {
r = 1;
}
CPPUNIT_ASSERT_EQUAL_MESSAGE( "inflate can still be used after end is called", 1, r );
Inflater i;
i.end();
// check for exception
i.end();
}
////////////////////////////////////////////////////////////////////////////////
void InflaterTest::testFinished() {
static const std::size_t SIZE = 10;
unsigned char byteArray[] = { 1, 3, 4, 7, 8, 'e', 'r', 't', 'y', '5' };
std::vector<unsigned char> outPutBuf( 500 );
std::vector<unsigned char> outPutInf( 500 );
Deflater deflater;
deflater.setInput( byteArray, SIZE, 0, SIZE );
deflater.finish();
while( !deflater.finished() ) {
deflater.deflate( outPutBuf );
}
Inflater inflate;
try {
while( !( inflate.finished() ) ) {
if( inflate.needsInput() ) {
inflate.setInput( outPutBuf );
}
inflate.inflate( outPutInf );
}
CPPUNIT_ASSERT_MESSAGE(
"the method finished() returned false when no more data needs to be decompressed",
inflate.finished() );
} catch( DataFormatException& e ) {
CPPUNIT_FAIL( "Invalid input to be decompressed" );
}
for( std::size_t i = 0; i < SIZE; i++ ) {
CPPUNIT_ASSERT_MESSAGE( "Final decompressed data does not equal the original data",
byteArray[i] == outPutInf[i] );
}
CPPUNIT_ASSERT_EQUAL_MESSAGE(
"final decompressed data contained more bytes than original - finished()",
0, (int)outPutInf[SIZE]);
}
////////////////////////////////////////////////////////////////////////////////
void InflaterTest::testGetAdler() {
static const int DICT_SIZE = 7;
static const int ARRAY_SIZE = 15;
unsigned char dictionary[] = { 'e', 'r', 't', 'a', 'b', 2, 3 };
unsigned char byteArray[] = { 4, 5, 3, 2, 'a', 'b', 6, 7, 8, 9, 0, 's', '3', 'w', 'r' };
std::vector<unsigned char> outPutBuf( 100 );
std::vector<unsigned char> outPutInf( 100 );
Deflater defl;
defl.setDictionary( dictionary, DICT_SIZE, 0, DICT_SIZE );
defl.setInput( byteArray, ARRAY_SIZE, 0, ARRAY_SIZE );
defl.finish();
while( !defl.finished() ) {
defl.deflate( outPutBuf );
}
defl.end();
// getting the checkSum value through the Adler32 class
Adler32 adl;
adl.update( dictionary, DICT_SIZE, 0, DICT_SIZE );
long long checkSumR = adl.getValue();
Inflater inflateDiction;
inflateDiction.setInput( outPutBuf );
inflateDiction.inflate( outPutInf );
CPPUNIT_ASSERT_MESSAGE( "Inflater did not detect the need for a Dictionary",
inflateDiction.needsDictionary() );
CPPUNIT_ASSERT_MESSAGE(
"the checksum value returned by getAdler() is not the same as the checksum returned "
"by creating the adler32 instance",
checkSumR == inflateDiction.getAdler() );
}
////////////////////////////////////////////////////////////////////////////////
void InflaterTest::testGetRemaining() {
unsigned char byteArray[] = { 1, 3, 5, 6, 7 };
Inflater inflate;
CPPUNIT_ASSERT_EQUAL_MESSAGE( "upon creating an instance of inflate, getRemaining returned a non zero value",
0, (int)inflate.getRemaining());
inflate.setInput( byteArray, 5, 0, 5 );
CPPUNIT_ASSERT_MESSAGE(
"getRemaining returned zero when there is input in the input buffer",
inflate.getRemaining() != 0 );
}
////////////////////////////////////////////////////////////////////////////////
void InflaterTest::testInflateVector() {
static const std::size_t SIZE = 39;
unsigned char byteArray[] = { 120, (unsigned char) -38, 75, (unsigned char) -54, 73,
(unsigned char) -52, 80, 40, 46, 41, (unsigned char) -54,
(unsigned char) -52, 75, 87, 72, (unsigned char) -50,
(unsigned char) -49, 43, 73, (unsigned char) -52,
(unsigned char) -52, 43, 86, 72, 2, 10, 34, 99,
(unsigned char) -123, (unsigned char) -60, (unsigned char) -68, 20,
(unsigned char) -80, 32, 0, (unsigned char) -101, (unsigned char) -69,
17, 84 };
std::string codedString = "blah string contains blahblahblahblah and blah";
std::vector<unsigned char> outPutBuf( byteArray, byteArray + SIZE );
std::vector<unsigned char> outPutInf( 500, 0 );
Inflater inflate;
try {
while( !( inflate.finished() ) ) {
if( inflate.needsInput() ) {
inflate.setInput( outPutBuf );
}
inflate.inflate( outPutInf );
}
} catch( DataFormatException& e ) {
CPPUNIT_FAIL("Invalid input to be decompressed");
}
for( std::size_t i = 0; i < codedString.length(); i++ ) {
CPPUNIT_ASSERT_MESSAGE( "Final decompressed data does not equal the original data",
codedString[i] == outPutInf[i] );
}
CPPUNIT_ASSERT_EQUAL_MESSAGE( "final decompressed data contained more bytes than original - inflateB",
0, (int)outPutInf[codedString.length()] );
// testing for an empty input array
outPutBuf.clear();
outPutBuf.resize( 500 );
outPutInf.assign( outPutInf.size(), 0 );
std::vector<unsigned char> emptyArray( 11, 0 );
int x = 0;
Deflater defEmpty( 3 );
defEmpty.setInput( emptyArray );
while( !( defEmpty.needsInput() ) ) {
x += defEmpty.deflate( outPutBuf, x, (int)outPutBuf.size() - x );
}
defEmpty.finish();
while( !( defEmpty.finished() ) ) {
x += defEmpty.deflate( outPutBuf, x, (int)outPutBuf.size() - x );
}
CPPUNIT_ASSERT_MESSAGE( "the total number of unsigned char from deflate did not equal "
"getTotalOut - inflate(unsigned char)",
(long long)x == defEmpty.getBytesWritten() );
CPPUNIT_ASSERT_MESSAGE(
"the number of input unsigned char from the array did not correspond with getTotalIn - inflate(unsigned char)",
(std::size_t)defEmpty.getBytesRead() == emptyArray.size() );
Inflater infEmpty;
try {
while( !( infEmpty.finished() ) ) {
if( infEmpty.needsInput() ) {
infEmpty.setInput( outPutBuf );
}
infEmpty.inflate( outPutInf );
}
} catch( DataFormatException& e ) {
CPPUNIT_FAIL( "Invalid input to be decompressed" );
}
for( std::size_t i = 0; i < 11; i++ ) {
CPPUNIT_ASSERT_MESSAGE( "Final decompressed data does not equal the original data",
emptyArray[i] == outPutInf[i] );
CPPUNIT_ASSERT_EQUAL_MESSAGE( "Final decompressed data does not equal zero",
0, (int)outPutInf[i] );
}
CPPUNIT_ASSERT_EQUAL_MESSAGE( "Final decompressed data contains more element than original data",
0, (int)outPutInf[11] );
}
////////////////////////////////////////////////////////////////////////////////
void InflaterTest::testInflateB1() {
static const std::size_t CODEDATA_SIZE = 39;
unsigned char codedData[] = { 120, (unsigned char) -38, 75, (unsigned char) -54, 73,
(unsigned char) -52, 80, 40, 46, 41, (unsigned char) -54,
(unsigned char) -52, 75, 87, 72, (unsigned char) -50,
(unsigned char) -49, 43, 73, (unsigned char) -52, (unsigned char) -52,
43, 86, 72, 2, 10, 34, 99, (unsigned char) -123, (unsigned char) -60,
(unsigned char) -68, 20, (unsigned char) -80, 32, 0, (unsigned char) -101,
(unsigned char) -69, 17, 84 };
std::string codedString = "blah string contains blahblahblahblah and blah";
Inflater infl1;
Inflater infl2;
std::vector<unsigned char> result( 100 );
std::size_t decLen = 0;
infl1.setInput( codedData, CODEDATA_SIZE, 0, CODEDATA_SIZE );
try {
decLen = infl1.inflate( result );
} catch( DataFormatException& e ) {
CPPUNIT_FAIL("Unexpected DataFormatException");
}
infl1.end();
CPPUNIT_ASSERT_EQUAL( codedString, std::string( result.begin(), result.begin() + decLen ) );
codedData[5] = 0;
infl2.setInput( codedData, CODEDATA_SIZE, 0, CODEDATA_SIZE );
CPPUNIT_ASSERT_THROW_MESSAGE(
"Expected DataFormatException",
decLen = infl2.inflate( result ),
DataFormatException );
infl2.end();
}
////////////////////////////////////////////////////////////////////////////////
void InflaterTest::testInflateBII() {
static const std::size_t SIZE = 39;
unsigned char byteArray[] = { 120, (unsigned char) -38, 75, (unsigned char) -54, 73,
(unsigned char) -52, 80, 40, 46, 41, (unsigned char) -54,
(unsigned char) -52, 75, 87, 72, (unsigned char) -50,
(unsigned char) -49, 43, 73, (unsigned char) -52,
(unsigned char) -52, 43, 86, 72, 2, 10, 34, 99,
(unsigned char) -123, (unsigned char) -60, (unsigned char) -68,
20, (unsigned char) -80, 32, 0, (unsigned char) -101,
(unsigned char) -69, 17, 84 };
std::string codedString = "blah string contains blahblahblahblah and blah";
std::vector<unsigned char> outPutBuf( byteArray, byteArray + SIZE );
std::vector<unsigned char> outPutInf( 100 );
int y = 0;
Inflater inflate;
try {
while( !( inflate.finished() ) ) {
if( inflate.needsInput() ) {
inflate.setInput( outPutBuf );
}
y += inflate.inflate( outPutInf, y, (int)outPutInf.size() - y );
}
} catch( DataFormatException& e ) {
CPPUNIT_FAIL("Invalid input to be decompressed");
}
for( std::size_t i = 0; i < codedString.length(); i++ ) {
CPPUNIT_ASSERT_MESSAGE(
"Final decompressed data does not equal the original data",
codedString[i] == outPutInf[i]);
}
CPPUNIT_ASSERT_EQUAL_MESSAGE( "final decompressed data contained more bytes than original - inflateB",
0, (int)outPutInf[codedString.length()]);
// test boundary checks
inflate.reset();
int r = 0;
int offSet = 0;
int lengthError = 101;
try {
if( inflate.needsInput() ) {
inflate.setInput( outPutBuf );
}
inflate.inflate( outPutInf, offSet, lengthError );
} catch( DataFormatException& e ) {
CPPUNIT_FAIL("Invalid input to be decompressed");
} catch( IndexOutOfBoundsException& e ) {
r = 1;
}
CPPUNIT_ASSERT_EQUAL_MESSAGE( "out of bounds error did not get caught", 1, r );
}
////////////////////////////////////////////////////////////////////////////////
void InflaterTest::testInflateBII1() {
static const std::size_t CODEDATA_SIZE = 39;
unsigned char codedData[] = { 120, (unsigned char) -38, 75, (unsigned char) -54, 73,
(unsigned char) -52, 80, 40, 46, 41, (unsigned char) -54,
(unsigned char) -52, 75, 87, 72, (unsigned char) -50,
(unsigned char) -49, 43, 73, (unsigned char) -52,
(unsigned char) -52, 43, 86, 72, 2, 10,
34, 99, (unsigned char) -123, (unsigned char) -60,
(unsigned char) -68, 20, (unsigned char) -80, 32, 0,
(unsigned char) -101, (unsigned char) -69, 17, 84 };
std::string codedString = "blah string";
Inflater infl1;
Inflater infl2;
std::vector<unsigned char> result( 100 );
std::size_t decLen = 0;
infl1.setInput( codedData, CODEDATA_SIZE, 0, CODEDATA_SIZE );
try {
decLen = infl1.inflate( result, 10, 11 );
CPPUNIT_ASSERT( decLen != 0 );
} catch( DataFormatException& e ) {
CPPUNIT_FAIL("Unexpected DataFormatException");
}
std::string outputStr;
for( std::size_t ix = 10; ix < decLen + 10; ++ix ) {
outputStr += (char)result[ix];
}
infl1.end();
CPPUNIT_ASSERT_EQUAL( codedString, outputStr );
codedData[5] = 0;
infl2.setInput( codedData, CODEDATA_SIZE, 0, CODEDATA_SIZE );
CPPUNIT_ASSERT_THROW_MESSAGE(
"Expected DataFormatException",
decLen = infl2.inflate( result, 10, 11 ),
DataFormatException );
infl2.end();
}
////////////////////////////////////////////////////////////////////////////////
void InflaterTest::testConstructor() {
Inflater inflate;
CPPUNIT_ASSERT_MESSAGE( "failed to create the instance of inflater",
inflate.getBytesRead() == 0LL );
}
////////////////////////////////////////////////////////////////////////////////
void InflaterTest::testConstructorZ() {
static const std::size_t SIZE = 10;
// note does not throw exception if deflater has a header, but inflater
// doesn't or vice versa.
unsigned char byteArray[] = { 1, 3, 4, 7, 8, 'e', 'r', 't', 'y', '5' };
std::vector<unsigned char> outPutBuf( 500 );
Deflater deflater;
deflater.setInput( byteArray, SIZE, 0, SIZE );
deflater.finish();
int read = 0;
while( !deflater.finished() ) {
read = deflater.deflate( outPutBuf, read, (int)outPutBuf.size() - read );
}
deflater.end();
Inflater inflate( true );
std::vector<unsigned char> outPutInf( 500 );
int r = 0;
try {
while( !( inflate.finished() ) ) {
if( inflate.needsInput() ) {
inflate.setInput( outPutBuf );
}
inflate.inflate( outPutInf );
}
for( std::size_t i = 0; i < SIZE; i++ ) {
CPPUNIT_ASSERT_EQUAL_MESSAGE(
"the output array from inflate should contain 0 because the header of inflate "
"and deflate did not match, but this failed",
0, (int)outPutBuf[i] );
}
} catch( DataFormatException& e ) {
r = 1;
}
CPPUNIT_ASSERT_EQUAL_MESSAGE( "Error: exception should be thrown because of header inconsistency", 1, r );
}
////////////////////////////////////////////////////////////////////////////////
void InflaterTest::testNeedsDictionary() {
static const int DICT_SIZE = 7;
static const int ARRAY_SIZE = 15;
// This test is very close to getAdler()
std::vector<unsigned char> dictionary( DICT_SIZE );
dictionary[0] = 'e';
dictionary[1] = 'r';
dictionary[2] = 't';
dictionary[3] = 'a';
dictionary[4] = 'b';
dictionary[5] = 2;
dictionary[6] = 3;
unsigned char byteArray[] = { 4, 5, 3, 2, 'a', 'b', 6, 7, 8, 9, 0, 's', '3', 'w', 'r' };
std::vector<unsigned char> outPutBuf( 100 );
Deflater defl;
defl.setDictionary( dictionary, 0, DICT_SIZE );
defl.setInput( byteArray, ARRAY_SIZE, 0, ARRAY_SIZE );
defl.finish();
while( !defl.finished() ) {
defl.deflate( outPutBuf );
}
// note: this flag is set after inflate is called
std::vector<unsigned char> outPutInf( 500 );
// testing with dictionary set.
Inflater inflateDiction;
if( inflateDiction.needsInput() ) {
inflateDiction.setInput( outPutBuf );
}
try {
CPPUNIT_ASSERT_EQUAL_MESSAGE( "should return 0 because needs dictionary",
0, (int)inflateDiction.inflate( outPutInf ) );
} catch( DataFormatException& e ) {
CPPUNIT_FAIL("Should not cause exception");
}
CPPUNIT_ASSERT_MESSAGE(
"method needsDictionary returned false when dictionary was used in deflater",
inflateDiction.needsDictionary() );
// Recompress without a Dictionary
outPutBuf.assign( outPutBuf.size(), 0 );
outPutInf.assign( outPutInf.size(), 0 );
defl.reset();
defl.setInput( byteArray, ARRAY_SIZE, 0, ARRAY_SIZE );
defl.finish();
while( !defl.finished() ) {
defl.deflate( outPutBuf );
}
defl.end();
// testing without dictionary
Inflater inflate;
try {
inflate.setInput( outPutBuf );
inflate.inflate( outPutInf );
CPPUNIT_ASSERT_MESSAGE(
"method needsDictionary returned true when dictionary was not used in deflater",
!inflate.needsDictionary() );
} catch( DataFormatException& e ) {
CPPUNIT_FAIL( "Input to inflate is invalid or corrupted - needsDictionary" );
}
Inflater inf;
CPPUNIT_ASSERT( !inf.needsDictionary() );
CPPUNIT_ASSERT_EQUAL( 0LL, inf.getBytesRead() );
CPPUNIT_ASSERT_EQUAL( 0LL, inf.getBytesWritten() );
}
////////////////////////////////////////////////////////////////////////////////
void InflaterTest::testNeedsInput() {
Inflater inflate;
CPPUNIT_ASSERT_MESSAGE(
"needsInput give the wrong bool value as a result of no input buffer",
inflate.needsInput() );
static const std::size_t SIZE = 12;
unsigned char byteArray[] = { 2, 3, 4, 't', 'y', 'u', 'e', 'w', 7, 6, 5, 9 };
inflate.setInput( byteArray, SIZE, 0, SIZE );
CPPUNIT_ASSERT_MESSAGE(
"methodNeedsInput returned true when the input buffer is full",
!inflate.needsInput() );
inflate.reset();
std::vector<unsigned char> byteArrayEmpty( 0 );;
inflate.setInput( byteArrayEmpty );
inflate.needsInput();
CPPUNIT_ASSERT_MESSAGE(
"needsInput give wrong bool value as a result of an empty input buffer",
inflate.needsInput() );
}
////////////////////////////////////////////////////////////////////////////////
void InflaterTest::testReset() {
static const std::size_t SIZE = 10;
// note does not throw exception if deflater has a header, but inflater
// doesn't or vice versa.
unsigned char byteArray[] = { 1, 3, 4, 7, 8, 'e', 'r', 't', 'y', '5' };
std::vector<unsigned char> outPutBuf( 500 );
Deflater deflater;
deflater.setInput( byteArray, SIZE, 0, SIZE );
deflater.finish();
int read = 0;
while( !deflater.finished() ) {
read = deflater.deflate( outPutBuf, read, (int)outPutBuf.size() - read );
}
deflater.end();
std::vector<unsigned char> outPutInf( 100 );
int y = 0;
Inflater inflate;
try {
while( !( inflate.finished() ) ) {
if( inflate.needsInput() ) {
inflate.setInput( outPutBuf );
}
y += inflate.inflate( outPutInf, y, (int)outPutInf.size() - y );
}
} catch( DataFormatException& e ) {
CPPUNIT_FAIL("Invalid input to be decompressed");
}
for( std::size_t i = 0; i < SIZE; i++ ) {
CPPUNIT_ASSERT_MESSAGE( "Final decompressed data does not equal the original data",
byteArray[i] == outPutInf[i] );
}
CPPUNIT_ASSERT_EQUAL_MESSAGE( "final decompressed data contained more bytes than original - reset",
0, (int)outPutInf[SIZE] );
// testing that resetting the inflater will also return the correct
// decompressed data
inflate.reset();
try {
while( !( inflate.finished() ) ) {
if( inflate.needsInput() ) {
inflate.setInput( outPutBuf );
}
inflate.inflate( outPutInf );
}
} catch( DataFormatException& e ) {
CPPUNIT_FAIL("Invalid input to be decompressed");
}
for( std::size_t i = 0; i < SIZE; i++ ) {
CPPUNIT_ASSERT_MESSAGE( "Final decompressed data does not equal the original data",
byteArray[i] == outPutInf[i] );
}
CPPUNIT_ASSERT_EQUAL_MESSAGE( "final decompressed data contained more bytes than original - reset",
0, (int)outPutInf[SIZE]);
}
////////////////////////////////////////////////////////////////////////////////
void InflaterTest::testSetInputB() {
static const std::size_t SIZE = 12;
unsigned char byteArray[] = { 2, 3, 4, 't', 'y', 'u', 'e', 'w', 7, 6, 5, 9 };
Inflater inflate;
inflate.setInput( byteArray, SIZE, 0, SIZE );
CPPUNIT_ASSERT_MESSAGE( "setInputB did not deliver any unsigned char to the input buffer",
inflate.getRemaining() != 0 );
}
////////////////////////////////////////////////////////////////////////////////
void InflaterTest::testSetInputBIII() {
static const std::size_t SIZE = 12;
unsigned char byteArray[] = { 2, 3, 4, 't', 'y', 'u', 'e', 'w', 7, 6, 5, 9 };
int offSet = 6;
int length = 6;
Inflater inflate;
inflate.setInput( byteArray, SIZE, offSet, length );
CPPUNIT_ASSERT_MESSAGE( "setInputBII did not deliver the right number of bytes to the input buffer",
inflate.getRemaining() == length );
// boundary check
inflate.reset();
int r = 0;
try {
inflate.setInput( byteArray, SIZE, 100, 100 );
} catch( IndexOutOfBoundsException& e ) {
r = 1;
}
CPPUNIT_ASSERT_EQUAL_MESSAGE( "boundary check is not present for setInput", 1, r );
}
////////////////////////////////////////////////////////////////////////////////
void InflaterTest::testGetBytesRead() {
Deflater def;
Inflater inf;
CPPUNIT_ASSERT_EQUAL( 0LL, def.getBytesWritten() );
CPPUNIT_ASSERT_EQUAL( 0LL, def.getBytesRead() );
// Encode a String into bytes
std::string inputString = "blahblahblah??";
std::vector<unsigned char> input( inputString.begin(), inputString.end() );
// Compress the bytes
std::vector<unsigned char> output( 100 );
def.setInput( input );
def.finish();
def.deflate( output );
inf.setInput( output );
int compressedDataLength = inf.inflate( input );
CPPUNIT_ASSERT_EQUAL( (long long)compressedDataLength, inf.getBytesWritten() );
CPPUNIT_ASSERT_EQUAL( 16LL, inf.getBytesRead() );
}
////////////////////////////////////////////////////////////////////////////////
void InflaterTest::testGetBytesWritten() {
Deflater def;
Inflater inf;
CPPUNIT_ASSERT_EQUAL( 0LL, def.getBytesRead() );
CPPUNIT_ASSERT_EQUAL( 0LL, def.getBytesWritten() );
// Encode a String into bytes
std::string inputString = "blahblahblah??";
std::vector<unsigned char> input( inputString.begin(), inputString.end() );
// Compress the bytes
std::vector<unsigned char> output( 100 );
def.setInput( input );
def.finish();
def.deflate( output );
inf.setInput( output );
int compressedDataLength = inf.inflate( input );
CPPUNIT_ASSERT_EQUAL( 16LL, inf.getBytesRead() );
CPPUNIT_ASSERT_EQUAL( compressedDataLength, (int)inf.getBytesWritten() );
CPPUNIT_ASSERT_EQUAL( 14LL, inf.getBytesWritten() );
}
////////////////////////////////////////////////////////////////////////////////
void InflaterTest::testInflate() {
Inflater inf;
std::vector<unsigned char> empty(0);
int res = inf.inflate( empty );
CPPUNIT_ASSERT_EQUAL( 0, (int)res );
// Regression for HARMONY-2508
Inflater inflater;
std::vector<unsigned char> b( 1024 );
CPPUNIT_ASSERT_EQUAL( 0, (int)inflater.inflate( b ) );
inflater.end();
{
Inflater inflater;
unsigned char array[] = { (unsigned char) -1 };
inflater.setInput( array, 1, 0, 1 );
try {
inflater.inflate( b );
// The RI detects malformed data on the malformed input { -1 }. Both
// this implementation and the native zlib API return "need input"
// on that data. This is an error if the stream is exhausted, but
// not one that results in an exception in the Inflater API.
CPPUNIT_ASSERT( inflater.needsInput() );
} catch( DataFormatException& e ) {
// expected
}
}
{
Inflater inflater2;
unsigned char array[] = { (unsigned char) -1, (unsigned char) -1, (unsigned char) -1 };
inflater2.setInput( array, 3, 0, 3);
try {
inflater2.inflate( b );
} catch( DataFormatException& e ) {
// expected
}
}
}
////////////////////////////////////////////////////////////////////////////////
void InflaterTest::testSetDictionaryB() {
int i = 0;
std::string inputString = "blah string contains blahblahblahblah and blah";
std::vector<unsigned char> input( inputString.begin(), inputString.end() );
std::string dictionary1String = "blah";
std::vector<unsigned char> dictionary1( dictionary1String.begin(), dictionary1String.end() );
std::string dictionary2String = "1234";
std::vector<unsigned char> dictionary2( dictionary2String.begin(), dictionary2String.end() );
std::vector<unsigned char> outputNo( 100 );
std::vector<unsigned char> output1( 100 );
std::vector<unsigned char> output2( 100 );
Deflater defDictNo( 9 );
Deflater defDict1( 9 );
Deflater defDict2( 9 );
defDict1.setDictionary( dictionary1 );
defDict2.setDictionary( dictionary2 );
defDictNo.setInput( input );
defDict1.setInput( input );
defDict2.setInput( input );
defDictNo.finish();
defDict1.finish();
defDict2.finish();
int dataLenNo = defDictNo.deflate( outputNo );
int dataLen1 = defDict1.deflate( output1 );
int dataLen2 = defDict2.deflate( output2 );
bool passNo1 = false;
bool passNo2 = false;
bool pass12 = false;
for( i = 0; i < ( dataLenNo < dataLen1 ? dataLenNo : dataLen1 ); i++ ) {
if( outputNo[i] != output1[i] ) {
passNo1 = true;
break;
}
}
for( i = 0; i < ( dataLenNo < dataLen1 ? dataLenNo : dataLen2 ); i++ ) {
if( outputNo[i] != output2[i] ) {
passNo2 = true;
break;
}
}
for( i = 0; i < ( dataLen1 < dataLen2 ? dataLen1 : dataLen2 ); i++ ) {
if( output1[i] != output2[i] ) {
pass12 = true;
break;
}
}
CPPUNIT_ASSERT_MESSAGE( "Compressed data the same for stream with dictionary and without it.", passNo1 );
CPPUNIT_ASSERT_MESSAGE( "Compressed data the same for stream with dictionary and without it.", passNo2 );
CPPUNIT_ASSERT_MESSAGE( "Compressed data the same for stream with different dictionaries.", pass12 );
Inflater inflNo;
Inflater infl1;
Inflater infl2;
std::vector<unsigned char> result(100);
int decLen;
inflNo.setInput( outputNo, 0, dataLenNo );
decLen = inflNo.inflate( result );
CPPUNIT_ASSERT( !inflNo.needsDictionary() );
inflNo.end();
CPPUNIT_ASSERT_EQUAL( inputString, std::string( result.begin(), result.begin() + decLen ) );
infl1.setInput( output1, 0, dataLen1 );
decLen = infl1.inflate( result );
CPPUNIT_ASSERT( infl1.needsDictionary() );
infl1.setDictionary( dictionary1 );
decLen = infl1.inflate( result );
infl1.end();
CPPUNIT_ASSERT_EQUAL( inputString, std::string( result.begin(), result.begin() + decLen ) );
infl2.setInput( output2, 0, dataLen2 );
decLen = infl2.inflate( result );
CPPUNIT_ASSERT(infl2.needsDictionary());
infl2.setDictionary( dictionary2 );
decLen = infl2.inflate( result );
infl2.end();
CPPUNIT_ASSERT_EQUAL(inputString, std::string( result.begin(), result.begin() + decLen ) );
{
Inflater inflNo;
Inflater infl1;
inflNo.setInput( outputNo, 0, dataLenNo );
CPPUNIT_ASSERT_THROW_MESSAGE(
"IllegalArgumentException expected.",
infl1.setDictionary( dictionary1 ),
IllegalArgumentException );
inflNo.end();
infl1.setInput( output1, 0, dataLen1 );
decLen = infl1.inflate( result );
CPPUNIT_ASSERT( infl1.needsDictionary() );
CPPUNIT_ASSERT_THROW_MESSAGE(
"IllegalArgumentException expected.",
infl1.setDictionary( dictionary2 ),
IllegalArgumentException );
infl1.end();
}
}
////////////////////////////////////////////////////////////////////////////////
void InflaterTest::testSetDictionaryBIII() {
int i = 0;
std::string inputString = "blah string contains blahblahblahblah and blah";
std::vector<unsigned char> input( inputString.begin(), inputString.end() );
std::string dictionary1String = "blah";
std::vector<unsigned char> dictionary1( dictionary1String.begin(), dictionary1String.end() );
std::string dictionary2String = "blahblahblah";
std::vector<unsigned char> dictionary2( dictionary2String.begin(), dictionary2String.end() );
std::vector<unsigned char> output1( 100 );
std::vector<unsigned char> output2( 100 );
std::vector<unsigned char> output3( 100 );
Deflater defDict1( 9 );
Deflater defDict2( 9 );
Deflater defDict3( 9 );
defDict1.setDictionary( dictionary1 );
defDict2.setDictionary( dictionary2 );
defDict3.setDictionary( dictionary2, 4, 4 );
defDict1.setInput( input );
defDict2.setInput( input );
defDict3.setInput( input );
defDict1.finish();
defDict2.finish();
defDict3.finish();
int dataLen1 = defDict1.deflate( output1 );
int dataLen2 = defDict2.deflate( output2 );
int dataLen3 = defDict3.deflate( output3 );
bool pass12 = false;
bool pass23 = false;
bool pass13 = true;
for( i = 0; i < ( dataLen1 < dataLen2 ? dataLen1 : dataLen2 ); i++ ) {
if( output1[i] != output2[i] ) {
pass12 = true;
break;
}
}
for( i = 0; i < ( dataLen2 < dataLen3 ? dataLen2 : dataLen3 ); i++ ) {
if( output2[i] != output3[i] ) {
pass23 = true;
break;
}
}
for( i = 0; i < ( dataLen1 < dataLen3 ? dataLen1 : dataLen3 ); i++ ) {
if( output1[i] != output3[i] ) {
pass13 = false;
break;
}
}
CPPUNIT_ASSERT_MESSAGE( "Compressed data the same for stream with different dictionaries.", pass12 );
CPPUNIT_ASSERT_MESSAGE( "Compressed data the same for stream with different dictionaries.", pass23 );
CPPUNIT_ASSERT_MESSAGE( "Compressed data the differs for stream with the same dictionaries.", pass13 );
Inflater infl1;
Inflater infl2;
Inflater infl3;
std::vector<unsigned char> result(100);
int decLen;
infl1.setInput( output1, 0, dataLen1 );
decLen = infl1.inflate( result );
CPPUNIT_ASSERT( infl1.needsDictionary() );
infl1.setDictionary( dictionary2, 4, 4 );
decLen = infl1.inflate( result );
infl1.end();
CPPUNIT_ASSERT_EQUAL( inputString, std::string( result.begin(), result.begin() + decLen ) );
infl2.setInput( output2, 0, dataLen2 );
decLen = infl2.inflate( result );
CPPUNIT_ASSERT(infl2.needsDictionary());
CPPUNIT_ASSERT_THROW_MESSAGE(
"IllegalArgumentException expected.",
infl2.setDictionary( dictionary1 ),
IllegalArgumentException );
infl2.end();
infl3.setInput( output3, 0, dataLen3 );
decLen = infl3.inflate( result );
CPPUNIT_ASSERT( infl3.needsDictionary() );
infl3.setDictionary( dictionary1 );
decLen = infl3.inflate( result );
infl3.end();
CPPUNIT_ASSERT_EQUAL( inputString, std::string( result.begin(), result.begin() + decLen ) );
}