1 2 17 18 19 package org.apache.poi.hssf.record; 20 21 import junit.framework.TestCase; 22 import org.apache.poi.hssf.usermodel.HSSFSheet; 23 import org.apache.poi.hssf.usermodel.HSSFWorkbook; 24 import org.apache.poi.util.HexRead; 25 import org.apache.poi.util.LittleEndian; 26 import org.apache.poi.util.LittleEndianConsts; 27 import org.apache.poi.util.TempFile; 28 29 import java.io.*; 30 import java.util.Arrays ; 31 import java.util.Iterator ; 32 33 37 38 public class TestSSTRecord 39 extends TestCase 40 { 41 private String _test_file_path; 42 private static final String _test_file_path_property = "HSSF.testdata.path"; 43 44 49 50 public TestSSTRecord( String name ) 51 { 52 super( name ); 53 _test_file_path = System.getProperty( _test_file_path_property ); 54 } 55 56 61 62 public void testProcessContinueRecord() 63 throws IOException 64 { 65 byte[] testdata = HexRead.readData( _test_file_path + File.separator + "BigSSTRecord" ); 66 byte[] input = new byte[testdata.length - 4]; 67 68 System.arraycopy( testdata, 4, input, 0, input.length ); 69 SSTRecord record = 70 new SSTRecord( LittleEndian.getShort( testdata, 0 ), 71 LittleEndian.getShort( testdata, 2 ), input ); 72 byte[] continueRecord = HexRead.readData( _test_file_path + File.separator + "BigSSTRecordCR" ); 73 74 input = new byte[continueRecord.length - 4]; 75 System.arraycopy( continueRecord, 4, input, 0, input.length ); 76 record.processContinueRecord( input ); 77 assertEquals( 1464, record.getNumStrings() ); 78 assertEquals( 688, record.getNumUniqueStrings() ); 79 assertEquals( 688, record.countStrings() ); 80 byte[] ser_output = record.serialize(); 81 int offset = 0; 82 short type = LittleEndian.getShort( ser_output, offset ); 83 84 offset += LittleEndianConsts.SHORT_SIZE; 85 short length = LittleEndian.getShort( ser_output, offset ); 86 87 offset += LittleEndianConsts.SHORT_SIZE; 88 byte[] recordData = new byte[length]; 89 90 System.arraycopy( ser_output, offset, recordData, 0, length ); 91 offset += length; 92 SSTRecord testRecord = new SSTRecord( type, length, recordData ); 93 94 assertEquals( ContinueRecord.sid, 95 LittleEndian.getShort( ser_output, offset ) ); 96 offset += LittleEndianConsts.SHORT_SIZE; 97 length = LittleEndian.getShort( ser_output, offset ); 98 offset += LittleEndianConsts.SHORT_SIZE; 99 byte[] cr = new byte[length]; 100 101 System.arraycopy( ser_output, offset, cr, 0, length ); 102 offset += length; 103 assertEquals( offset, ser_output.length ); 104 testRecord.processContinueRecord( cr ); 105 assertEquals( record, testRecord ); 106 107 testdata = HexRead.readData( _test_file_path + File.separator + "BigSSTRecord2" ); 109 input = new byte[testdata.length - 4]; 110 System.arraycopy( testdata, 4, input, 0, input.length ); 111 record = new SSTRecord( LittleEndian.getShort( testdata, 0 ), 112 LittleEndian.getShort( testdata, 2 ), input ); 113 byte[] continueRecord1 = HexRead.readData( _test_file_path + File.separator + "BigSSTRecord2CR1" ); 114 115 input = new byte[continueRecord1.length - 4]; 116 System.arraycopy( continueRecord1, 4, input, 0, input.length ); 117 record.processContinueRecord( input ); 118 byte[] continueRecord2 = HexRead.readData( _test_file_path + File.separator + "BigSSTRecord2CR2" ); 119 120 input = new byte[continueRecord2.length - 4]; 121 System.arraycopy( continueRecord2, 4, input, 0, input.length ); 122 record.processContinueRecord( input ); 123 byte[] continueRecord3 = HexRead.readData( _test_file_path + File.separator + "BigSSTRecord2CR3" ); 124 125 input = new byte[continueRecord3.length - 4]; 126 System.arraycopy( continueRecord3, 4, input, 0, input.length ); 127 record.processContinueRecord( input ); 128 byte[] continueRecord4 = HexRead.readData( _test_file_path + File.separator + "BigSSTRecord2CR4" ); 129 130 input = new byte[continueRecord4.length - 4]; 131 System.arraycopy( continueRecord4, 4, input, 0, input.length ); 132 record.processContinueRecord( input ); 133 byte[] continueRecord5 = HexRead.readData( _test_file_path + File.separator + "BigSSTRecord2CR5" ); 134 135 input = new byte[continueRecord5.length - 4]; 136 System.arraycopy( continueRecord5, 4, input, 0, input.length ); 137 record.processContinueRecord( input ); 138 byte[] continueRecord6 = HexRead.readData( _test_file_path + File.separator + "BigSSTRecord2CR6" ); 139 140 input = new byte[continueRecord6.length - 4]; 141 System.arraycopy( continueRecord6, 4, input, 0, input.length ); 142 record.processContinueRecord( input ); 143 byte[] continueRecord7 = HexRead.readData( _test_file_path + File.separator + "BigSSTRecord2CR7" ); 144 145 input = new byte[continueRecord7.length - 4]; 146 System.arraycopy( continueRecord7, 4, input, 0, input.length ); 147 record.processContinueRecord( input ); 148 assertEquals( 158642, record.getNumStrings() ); 149 assertEquals( 5249, record.getNumUniqueStrings() ); 150 assertEquals( 5249, record.countStrings() ); 151 ser_output = record.serialize(); 152 offset = 0; 153 type = LittleEndian.getShort( ser_output, offset ); 154 offset += LittleEndianConsts.SHORT_SIZE; 155 length = LittleEndian.getShort( ser_output, offset ); 156 offset += LittleEndianConsts.SHORT_SIZE; 157 recordData = new byte[length]; 158 System.arraycopy( ser_output, offset, recordData, 0, length ); 159 offset += length; 160 testRecord = new SSTRecord( type, length, recordData ); 161 for ( int count = 0; count < 7; count++ ) 162 { 163 assertEquals( ContinueRecord.sid, 164 LittleEndian.getShort( ser_output, offset ) ); 165 offset += LittleEndianConsts.SHORT_SIZE; 166 length = LittleEndian.getShort( ser_output, offset ); 167 offset += LittleEndianConsts.SHORT_SIZE; 168 cr = new byte[length]; 169 System.arraycopy( ser_output, offset, cr, 0, length ); 170 testRecord.processContinueRecord( cr ); 171 offset += length; 172 } 173 assertEquals( offset, ser_output.length ); 174 assertEquals( record, testRecord ); 175 assertEquals( record.countStrings(), testRecord.countStrings() ); 176 } 177 178 183 184 public void testHugeStrings() 185 throws IOException 186 { 187 SSTRecord record = new SSTRecord(); 188 byte[][] bstrings = 189 { 190 new byte[9000], new byte[7433], new byte[9002], 191 new byte[16998] 192 }; 193 String [] strings = new String [bstrings.length]; 194 int total_length = 0; 195 196 for ( int k = 0; k < bstrings.length; k++ ) 197 { 198 Arrays.fill( bstrings[k], (byte) ( 'a' + k ) ); 199 strings[k] = new String ( bstrings[k] ); 200 record.addString( strings[k] ); 201 total_length += 3 + bstrings[k].length; 202 } 203 204 total_length += 8; 206 207 total_length += 4; 209 210 total_length += ( 6 * 4 ); 212 byte[] content = new byte[record.getRecordSize()]; 213 214 record.serialize( 0, content ); 215 assertEquals( total_length, content.length ); 216 for ( int index = 0; index != content.length; ) 217 { 218 short record_type = LittleEndian.getShort( content, index ); 219 220 index += LittleEndianConsts.SHORT_SIZE; 221 short record_length = LittleEndian.getShort( content, index ); 222 223 index += LittleEndianConsts.SHORT_SIZE; 224 byte[] data = new byte[record_length]; 225 226 System.arraycopy( content, index, data, 0, record_length ); 227 index += record_length; 228 if ( record_type == SSTRecord.sid ) 229 { 230 record = new SSTRecord( record_type, record_length, data ); 231 } 232 else 233 { 234 record.processContinueRecord( data ); 235 } 236 } 237 assertEquals( strings.length, record.getNumStrings() ); 238 assertEquals( strings.length, record.getNumUniqueStrings() ); 239 assertEquals( strings.length, record.countStrings() ); 240 for ( int k = 0; k < strings.length; k++ ) 241 { 242 assertEquals( strings[k], record.getString( k ) ); 243 } 244 record = new SSTRecord(); 245 bstrings[1] = new byte[bstrings[1].length - 1]; 246 for ( int k = 0; k < bstrings.length; k++ ) 247 { 248 if ( ( bstrings[k].length % 2 ) == 1 ) 249 { 250 Arrays.fill( bstrings[k], (byte) ( 'a' + k ) ); 251 strings[k] = new String ( bstrings[k] ); 252 } 253 else 254 { 255 char[] data = new char[bstrings[k].length / 2]; 256 257 Arrays.fill( data, (char) ( '\u2122' + k ) ); 258 strings[k] = new String ( data ); 259 } 260 record.addString( strings[k] ); 261 } 262 content = new byte[record.getRecordSize()]; 263 record.serialize( 0, content ); 264 total_length--; 265 assertEquals( total_length, content.length ); 266 for ( int index = 0; index != content.length; ) 267 { 268 short record_type = LittleEndian.getShort( content, index ); 269 270 index += LittleEndianConsts.SHORT_SIZE; 271 short record_length = LittleEndian.getShort( content, index ); 272 273 index += LittleEndianConsts.SHORT_SIZE; 274 byte[] data = new byte[record_length]; 275 276 System.arraycopy( content, index, data, 0, record_length ); 277 index += record_length; 278 if ( record_type == SSTRecord.sid ) 279 { 280 record = new SSTRecord( record_type, record_length, data ); 281 } 282 else 283 { 284 record.processContinueRecord( data ); 285 } 286 } 287 assertEquals( strings.length, record.getNumStrings() ); 288 assertEquals( strings.length, record.getNumUniqueStrings() ); 289 assertEquals( strings.length, record.countStrings() ); 290 for ( int k = 0; k < strings.length; k++ ) 291 { 292 assertEquals( strings[k], record.getString( k ) ); 293 } 294 } 295 296 301 public void testSSTRecordBug() 302 throws IOException 303 { 304 305 SSTRecord record = new SSTRecord(); 308 309 record.addString( "Hello" ); 313 314 long testvalue = 1000000000000L; 317 318 for ( int k = 0; k < 2000; k++ ) 319 { 320 record.addString( String.valueOf( testvalue++ ) ); 321 } 322 byte[] content = new byte[record.getRecordSize()]; 323 324 record.serialize( 0, content ); 325 assertEquals( (byte) 13, content[4 + 8228] ); 326 assertEquals( (byte) 13, content[4 + 8228 * 2] ); 327 assertEquals( (byte) 13, content[4 + 8228 * 3] ); 328 } 329 330 333 public void testSimpleAddString() 334 { 335 SSTRecord record = new SSTRecord(); 336 String s1 = "Hello world"; 337 338 String s2 = "Hello world\u2122"; 340 341 assertEquals( 0, record.addString( s1 ) ); 342 assertEquals( s1, record.getString( 0 ) ); 343 assertEquals( 1, record.countStrings() ); 344 assertEquals( 1, record.getNumStrings() ); 345 assertEquals( 1, record.getNumUniqueStrings() ); 346 assertEquals( 0, record.addString( s1 ) ); 347 assertEquals( s1, record.getString( 0 ) ); 348 assertEquals( 1, record.countStrings() ); 349 assertEquals( 2, record.getNumStrings() ); 350 assertEquals( 1, record.getNumUniqueStrings() ); 351 assertEquals( 1, record.addString( s2 ) ); 352 assertEquals( s2, record.getString( 1 ) ); 353 assertEquals( 2, record.countStrings() ); 354 assertEquals( 3, record.getNumStrings() ); 355 assertEquals( 2, record.getNumUniqueStrings() ); 356 Iterator iter = record.getStrings(); 357 358 while ( iter.hasNext() ) 359 { 360 UnicodeString ucs = (UnicodeString) iter.next(); 361 362 if ( ucs.getString().equals( s1 ) ) 363 { 364 assertEquals( (byte) 0, ucs.getOptionFlags() ); 365 } 366 else if ( ucs.getString().equals( s2 ) ) 367 { 368 assertEquals( (byte) 1, ucs.getOptionFlags() ); 369 } 370 else 371 { 372 fail( "cannot match string: " + ucs.getString() ); 373 } 374 } 375 } 376 377 382 383 public void testReaderConstructor() 384 throws IOException 385 { 386 byte[] testdata = HexRead.readData( _test_file_path + File.separator + "BigSSTRecord" ); 387 byte[] input = new byte[testdata.length - 4]; 388 389 System.arraycopy( testdata, 4, input, 0, input.length ); 390 SSTRecord record = new SSTRecord( LittleEndian.getShort( testdata, 0 ), 391 LittleEndian.getShort( testdata, 2 ), 392 input ); 393 394 assertEquals( 1464, record.getNumStrings() ); 395 assertEquals( 688, record.getNumUniqueStrings() ); 396 assertEquals( 492, record.countStrings() ); 397 assertEquals( "Consolidated B-24J Liberator The Dragon & His Tai", 399 record.getDeserializer().getUnfinishedString() ); 400 assertTrue( !record.getDeserializer().isWideChar() ); 403 } 404 405 408 409 public void testSimpleConstructor() 410 { 411 SSTRecord record = new SSTRecord(); 412 413 assertEquals( 0, record.getNumStrings() ); 414 assertEquals( 0, record.getNumUniqueStrings() ); 415 assertEquals( 0, record.countStrings() ); 416 assertEquals( 0, record.getDeserializer().getContinuationCharsRead() ); 417 assertEquals( "", record.getDeserializer().getUnfinishedString() ); 418 assertTrue( !record.getDeserializer().isWideChar() ); 421 byte[] output = record.serialize(); 422 byte[] expected = 423 { 424 (byte) record.getSid(), (byte) ( record.getSid() >> 8 ), 425 (byte) 8, (byte) 0, (byte) 0, (byte) 0, (byte) 0, 426 (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0 427 }; 428 429 assertEquals( expected.length, output.length ); 430 for ( int k = 0; k < expected.length; k++ ) 431 { 432 assertEquals( String.valueOf( k ), expected[k], output[k] ); 433 } 434 } 435 436 441 442 public static void main( String [] ignored_args ) 443 { 444 System.out.println( "Testing hssf.record.SSTRecord functionality" ); 445 junit.textui.TestRunner.run( TestSSTRecord.class ); 446 } 447 448 451 public void testReadWriteDuplicatedRichText1() 452 throws Exception 453 { 454 File file = new File( _test_file_path + File.separator + "duprich1.xls" ); 455 InputStream stream = new FileInputStream( file ); 456 HSSFWorkbook wb = new HSSFWorkbook( stream ); 457 stream.close(); 458 HSSFSheet sheet = wb.getSheetAt( 1 ); 459 assertEquals( "01/05 (Wed) ", sheet.getRow( 0 ).getCell( (short) 8 ).getStringCellValue() ); 460 assertEquals( "01/05 (Wed)", sheet.getRow( 1 ).getCell( (short) 8 ).getStringCellValue() ); 461 462 file = TempFile.createTempFile( "testout", "xls" ); 463 FileOutputStream outStream = new FileOutputStream( file ); 464 wb.write( outStream ); 465 outStream.close(); 466 file.delete(); 467 468 file = new File( _test_file_path + File.separator + "duprich2.xls" ); 470 stream = new FileInputStream( file ); 471 wb = new HSSFWorkbook( stream ); 472 stream.close(); 473 sheet = wb.getSheetAt( 0 ); 474 int row = 0; 475 assertEquals( "Testing ", sheet.getRow( row++ ).getCell( (short) 0 ).getStringCellValue() ); 476 assertEquals( "rich", sheet.getRow( row++ ).getCell( (short) 0 ).getStringCellValue() ); 477 assertEquals( "text", sheet.getRow( row++ ).getCell( (short) 0 ).getStringCellValue() ); 478 assertEquals( "strings", sheet.getRow( row++ ).getCell( (short) 0 ).getStringCellValue() ); 479 assertEquals( "Testing ", sheet.getRow( row++ ).getCell( (short) 0 ).getStringCellValue() ); 480 assertEquals( "Testing", sheet.getRow( row++ ).getCell( (short) 0 ).getStringCellValue() ); 481 482 file = TempFile.createTempFile( "testout", ".xls" ); 484 outStream = new FileOutputStream( file ); 485 wb.write( outStream ); 486 outStream.close(); 487 file.delete(); 488 } 489 490 } 491 | Popular Tags |