From f73c479d1b5766d9354e34da2b2d381c565616a2 Mon Sep 17 00:00:00 2001 From: Josh Micich Date: Mon, 1 Jun 2009 23:13:29 +0000 Subject: [PATCH] Fixed non-use of 10 sample files (named 'BigSSTRecord*'). Resurrected SSTRecord test (commented out in r353769). git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@780874 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/poi/hssf/record/SSTRecord.java | 22 -- .../apache/poi/hssf/record/TestSSTRecord.java | 240 ++++++++---------- 2 files changed, 105 insertions(+), 157 deletions(-) diff --git a/src/java/org/apache/poi/hssf/record/SSTRecord.java b/src/java/org/apache/poi/hssf/record/SSTRecord.java index 98bd075e34..d87b06320e 100644 --- a/src/java/org/apache/poi/hssf/record/SSTRecord.java +++ b/src/java/org/apache/poi/hssf/record/SSTRecord.java @@ -176,28 +176,6 @@ public final class SSTRecord extends ContinuableRecord { return sid; } - /** - * @return hashcode - */ - public int hashCode() - { - return field_2_num_unique_strings; - } - - public boolean equals( Object o ) - { - if ( ( o == null ) || ( o.getClass() != this.getClass() ) ) - { - return false; - } - SSTRecord other = (SSTRecord) o; - - return ( ( field_1_num_strings == other - .field_1_num_strings ) && ( field_2_num_unique_strings == other - .field_2_num_unique_strings ) && field_3_strings - .equals( other.field_3_strings ) ); - } - /** * Fill the fields from the data *

diff --git a/src/testcases/org/apache/poi/hssf/record/TestSSTRecord.java b/src/testcases/org/apache/poi/hssf/record/TestSSTRecord.java index eb58e96616..4a9b7c0b8c 100644 --- a/src/testcases/org/apache/poi/hssf/record/TestSSTRecord.java +++ b/src/testcases/org/apache/poi/hssf/record/TestSSTRecord.java @@ -17,141 +17,127 @@ package org.apache.poi.hssf.record; +import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; import java.util.Arrays; import java.util.Iterator; +import junit.framework.AssertionFailedError; import junit.framework.TestCase; import org.apache.poi.hssf.HSSFTestDataSamples; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.util.HexRead; import org.apache.poi.util.LittleEndian; /** * @author Marc Johnson (mjohnson at apache dot org) * @author Glen Stampoultzis (glens at apache.org) */ - public final class TestSSTRecord extends TestCase { /** - * test processContinueRecord + * decodes hexdump files and concatenates the results + * @param hexDumpFileNames names of sample files in the hssf test data directory */ - public void testProcessContinueRecord() { -//jmh byte[] testdata = HexRead.readData( _test_file_path + File.separator + "BigSSTRecord" ); -//jmh byte[] input = new byte[testdata.length - 4]; -//jmh -//jmh System.arraycopy( testdata, 4, input, 0, input.length ); -//jmh SSTRecord record = -//jmh new SSTRecord( LittleEndian.getShort( testdata, 0 ), -//jmh LittleEndian.getShort( testdata, 2 ), input ); -//jmh byte[] continueRecord = HexRead.readData( _test_file_path + File.separator + "BigSSTRecordCR" ); -//jmh -//jmh input = new byte[continueRecord.length - 4]; -//jmh System.arraycopy( continueRecord, 4, input, 0, input.length ); -//jmh record.processContinueRecord( input ); -//jmh assertEquals( 1464, record.getNumStrings() ); -//jmh assertEquals( 688, record.getNumUniqueStrings() ); -//jmh assertEquals( 688, record.countStrings() ); -//jmh byte[] ser_output = record.serialize(); -//jmh int offset = 0; -//jmh short type = LittleEndian.getShort( ser_output, offset ); -//jmh -//jmh offset += LittleEndianConsts.SHORT_SIZE; -//jmh short length = LittleEndian.getShort( ser_output, offset ); -//jmh -//jmh offset += LittleEndianConsts.SHORT_SIZE; -//jmh byte[] recordData = new byte[length]; -//jmh -//jmh System.arraycopy( ser_output, offset, recordData, 0, length ); -//jmh offset += length; -//jmh SSTRecord testRecord = new SSTRecord( type, length, recordData ); -//jmh -//jmh assertEquals( ContinueRecord.sid, -//jmh LittleEndian.getShort( ser_output, offset ) ); -//jmh offset += LittleEndianConsts.SHORT_SIZE; -//jmh length = LittleEndian.getShort( ser_output, offset ); -//jmh offset += LittleEndianConsts.SHORT_SIZE; -//jmh byte[] cr = new byte[length]; -//jmh -//jmh System.arraycopy( ser_output, offset, cr, 0, length ); -//jmh offset += length; -//jmh assertEquals( offset, ser_output.length ); -//jmh testRecord.processContinueRecord( cr ); -//jmh assertEquals( record, testRecord ); -//jmh -//jmh // testing based on new bug report -//jmh testdata = HexRead.readData( _test_file_path + File.separator + "BigSSTRecord2" ); -//jmh input = new byte[testdata.length - 4]; -//jmh System.arraycopy( testdata, 4, input, 0, input.length ); -//jmh record = new SSTRecord( LittleEndian.getShort( testdata, 0 ), -//jmh LittleEndian.getShort( testdata, 2 ), input ); -//jmh byte[] continueRecord1 = HexRead.readData( _test_file_path + File.separator + "BigSSTRecord2CR1" ); -//jmh -//jmh input = new byte[continueRecord1.length - 4]; -//jmh System.arraycopy( continueRecord1, 4, input, 0, input.length ); -//jmh record.processContinueRecord( input ); -//jmh byte[] continueRecord2 = HexRead.readData( _test_file_path + File.separator + "BigSSTRecord2CR2" ); -//jmh -//jmh input = new byte[continueRecord2.length - 4]; -//jmh System.arraycopy( continueRecord2, 4, input, 0, input.length ); -//jmh record.processContinueRecord( input ); -//jmh byte[] continueRecord3 = HexRead.readData( _test_file_path + File.separator + "BigSSTRecord2CR3" ); -//jmh -//jmh input = new byte[continueRecord3.length - 4]; -//jmh System.arraycopy( continueRecord3, 4, input, 0, input.length ); -//jmh record.processContinueRecord( input ); -//jmh byte[] continueRecord4 = HexRead.readData( _test_file_path + File.separator + "BigSSTRecord2CR4" ); -//jmh -//jmh input = new byte[continueRecord4.length - 4]; -//jmh System.arraycopy( continueRecord4, 4, input, 0, input.length ); -//jmh record.processContinueRecord( input ); -//jmh byte[] continueRecord5 = HexRead.readData( _test_file_path + File.separator + "BigSSTRecord2CR5" ); -//jmh -//jmh input = new byte[continueRecord5.length - 4]; -//jmh System.arraycopy( continueRecord5, 4, input, 0, input.length ); -//jmh record.processContinueRecord( input ); -//jmh byte[] continueRecord6 = HexRead.readData( _test_file_path + File.separator + "BigSSTRecord2CR6" ); -//jmh -//jmh input = new byte[continueRecord6.length - 4]; -//jmh System.arraycopy( continueRecord6, 4, input, 0, input.length ); -//jmh record.processContinueRecord( input ); -//jmh byte[] continueRecord7 = HexRead.readData( _test_file_path + File.separator + "BigSSTRecord2CR7" ); -//jmh -//jmh input = new byte[continueRecord7.length - 4]; -//jmh System.arraycopy( continueRecord7, 4, input, 0, input.length ); -//jmh record.processContinueRecord( input ); -//jmh assertEquals( 158642, record.getNumStrings() ); -//jmh assertEquals( 5249, record.getNumUniqueStrings() ); -//jmh assertEquals( 5249, record.countStrings() ); -//jmh ser_output = record.serialize(); -//jmh offset = 0; -//jmh type = LittleEndian.getShort( ser_output, offset ); -//jmh offset += LittleEndianConsts.SHORT_SIZE; -//jmh length = LittleEndian.getShort( ser_output, offset ); -//jmh offset += LittleEndianConsts.SHORT_SIZE; -//jmh recordData = new byte[length]; -//jmh System.arraycopy( ser_output, offset, recordData, 0, length ); -//jmh offset += length; -//jmh testRecord = new SSTRecord( type, length, recordData ); -//jmh for ( int count = 0; count < 7; count++ ) -//jmh { -//jmh assertEquals( ContinueRecord.sid, -//jmh LittleEndian.getShort( ser_output, offset ) ); -//jmh offset += LittleEndianConsts.SHORT_SIZE; -//jmh length = LittleEndian.getShort( ser_output, offset ); -//jmh offset += LittleEndianConsts.SHORT_SIZE; -//jmh cr = new byte[length]; -//jmh System.arraycopy( ser_output, offset, cr, 0, length ); -//jmh testRecord.processContinueRecord( cr ); -//jmh offset += length; -//jmh } -//jmh assertEquals( offset, ser_output.length ); -//jmh assertEquals( record, testRecord ); -//jmh assertEquals( record.countStrings(), testRecord.countStrings() ); + private static byte[] concatHexDumps(String... hexDumpFileNames) { + int nFiles = hexDumpFileNames.length; + ByteArrayOutputStream baos = new ByteArrayOutputStream(nFiles * 8228); + for (int i = 0; i < nFiles; i++) { + String sampleFileName = hexDumpFileNames[i]; + InputStream is = HSSFTestDataSamples.openSampleFileStream(sampleFileName); + BufferedReader br = new BufferedReader(new InputStreamReader(is)); + try { + while (true) { + String line = br.readLine(); + if (line == null) { + break; + } + baos.write(HexRead.readFromString(line)); + } + is.close(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + return baos.toByteArray(); + } + + /** + * @param rawData serialization of one {@link SSTRecord} and zero or more {@link ContinueRecord}s + */ + private static SSTRecord createSSTFromRawData(byte[] rawData) { + RecordInputStream in = new RecordInputStream(new ByteArrayInputStream(rawData)); + in.nextRecord(); + SSTRecord result = new SSTRecord(in); + assertEquals(0, in.remaining()); + assertTrue(!in.hasNextRecord()); + return result; + } + + /** + * SST is often split over several {@link ContinueRecord}s + */ + public void testContinuedRecord() { + byte[] origData; + SSTRecord record; + byte[] ser_output; + + origData = concatHexDumps("BigSSTRecord", "BigSSTRecordCR"); + record = createSSTFromRawData(origData); + assertEquals( 1464, record.getNumStrings() ); + assertEquals( 688, record.getNumUniqueStrings() ); + assertEquals( 688, record.countStrings() ); + ser_output = record.serialize(); + assertTrue(Arrays.equals(origData, ser_output)); + + // testing based on new bug report + origData = concatHexDumps("BigSSTRecord2", "BigSSTRecord2CR1", "BigSSTRecord2CR2", "BigSSTRecord2CR3", + "BigSSTRecord2CR4", "BigSSTRecord2CR5", "BigSSTRecord2CR6", "BigSSTRecord2CR7"); + record = createSSTFromRawData(origData); + + + assertEquals( 158642, record.getNumStrings() ); + assertEquals( 5249, record.getNumUniqueStrings() ); + assertEquals( 5249, record.countStrings() ); + ser_output = record.serialize(); + if (false) { // set true to observe make sure areSameSSTs() is working + ser_output[11000] = 'X'; + } + + SSTRecord rec2 = createSSTFromRawData(ser_output); + if (!areSameSSTs(record, rec2)) { + throw new AssertionFailedError("large SST re-serialized incorrectly"); + } + if (false) { + // TODO - trivial differences in ContinueRecord break locations + // Sample data should be checked against what most recent Excel version produces. + // maybe tweaks are required in ContinuableRecordOutput + assertTrue(Arrays.equals(origData, ser_output)); + } + } + + private boolean areSameSSTs(SSTRecord a, SSTRecord b) { + + if (a.getNumStrings() != b.getNumStrings()) { + return false; + } + int nElems = a.getNumUniqueStrings(); + if (nElems != b.getNumUniqueStrings()) { + return false; + } + for(int i=0; i