| /* ==================================================================== |
| 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. |
| ==================================================================== */ |
| |
| package org.apache.poi.hssf.record; |
| |
| import static org.junit.Assert.assertArrayEquals; |
| |
| import java.util.List; |
| |
| import junit.framework.AssertionFailedError; |
| import junit.framework.TestCase; |
| |
| import org.apache.poi.util.HexRead; |
| |
| /** |
| * Tests the serialization and deserialization of the ObjRecord class works correctly. |
| * Test data taken directly from a real Excel file. |
| * |
| * @author Yegor Kozlov |
| */ |
| public final class TestObjRecord extends TestCase { |
| /** |
| * OBJ record data containing two sub-records. |
| * The data taken directly from a real Excel file. |
| * |
| * [OBJ] |
| * [ftCmo] |
| * [ftEnd] |
| */ |
| private static final byte[] recdata = HexRead.readFromString("" |
| + "15 00 12 00 06 00 01 00 11 60 " |
| + "F4 02 41 01 14 10 1F 02 00 00 " |
| +"00 00 00 00 00 00" |
| // TODO - this data seems to require two extra bytes padding. not sure where original file is. |
| // it's not bug 38607 attachment 17639 |
| ); |
| |
| /** |
| * Hex dump from |
| * offset 0x2072 in att 22076 of bug 45133 |
| */ |
| private static final byte[] recdataNeedingPadding = HexRead.readFromString("" |
| + "5D 00 20 00" |
| + "15 00 12 00 00 00 01 00 11 60 00 00 00 00 38 6F CC 03 00 00 00 00 06 00 02 00 00 00 00 00 00 00" |
| ); |
| |
| public void testLoad() { |
| ObjRecord record = new ObjRecord(TestcaseRecordInputStream.create(ObjRecord.sid, recdata)); |
| |
| assertEquals(26, record.getRecordSize() - 4); |
| |
| List<SubRecord> subrecords = record.getSubRecords(); |
| assertEquals(2, subrecords.size() ); |
| assertTrue(subrecords.get(0) instanceof CommonObjectDataSubRecord); |
| assertTrue(subrecords.get(1) instanceof EndSubRecord ); |
| |
| } |
| |
| public void testStore() { |
| ObjRecord record = new ObjRecord(TestcaseRecordInputStream.create(ObjRecord.sid, recdata)); |
| |
| byte [] recordBytes = record.serialize(); |
| assertEquals(26, recordBytes.length - 4); |
| byte[] subData = new byte[recdata.length]; |
| System.arraycopy(recordBytes, 4, subData, 0, subData.length); |
| assertArrayEquals(recdata, subData); |
| } |
| |
| public void testConstruct() { |
| ObjRecord record = new ObjRecord(); |
| CommonObjectDataSubRecord ftCmo = new CommonObjectDataSubRecord(); |
| ftCmo.setObjectType( CommonObjectDataSubRecord.OBJECT_TYPE_COMMENT); |
| ftCmo.setObjectId( 1024 ); |
| ftCmo.setLocked( true ); |
| ftCmo.setPrintable( true ); |
| ftCmo.setAutofill( true ); |
| ftCmo.setAutoline( true ); |
| record.addSubRecord(ftCmo); |
| EndSubRecord ftEnd = new EndSubRecord(); |
| record.addSubRecord(ftEnd); |
| |
| //serialize and read again |
| byte [] recordBytes = record.serialize(); |
| //cut off the record header |
| byte [] bytes = new byte[recordBytes.length-4]; |
| System.arraycopy(recordBytes, 4, bytes, 0, bytes.length); |
| |
| record = new ObjRecord(TestcaseRecordInputStream.create(ObjRecord.sid, bytes)); |
| List<SubRecord> subrecords = record.getSubRecords(); |
| assertEquals( 2, subrecords.size() ); |
| assertTrue( subrecords.get(0) instanceof CommonObjectDataSubRecord); |
| assertTrue( subrecords.get(1) instanceof EndSubRecord ); |
| } |
| |
| public void testReadWriteWithPadding_bug45133() { |
| ObjRecord record = new ObjRecord(TestcaseRecordInputStream.create(recdataNeedingPadding)); |
| |
| if (record.getRecordSize() == 34) { |
| throw new AssertionFailedError("Identified bug 45133"); |
| } |
| |
| assertEquals(36, record.getRecordSize()); |
| |
| List<SubRecord> subrecords = record.getSubRecords(); |
| assertEquals(3, subrecords.size() ); |
| assertEquals(CommonObjectDataSubRecord.class, subrecords.get(0).getClass()); |
| assertEquals(GroupMarkerSubRecord.class, subrecords.get(1).getClass()); |
| assertEquals(EndSubRecord.class, subrecords.get(2).getClass()); |
| } |
| |
| /** |
| * Check that ObjRecord tolerates and preserves padding to a 4-byte boundary |
| * (normally padding is to a 2-byte boundary). |
| */ |
| public void test4BytePadding() { |
| // actual data from file saved by Excel 2007 |
| byte[] data = HexRead.readFromString("" |
| + "15 00 12 00 1E 00 01 00 11 60 B4 6D 3C 01 C4 06 " |
| + "49 06 00 00 00 00 00 00 00 00 00 00"); |
| // this data seems to have 2 extra bytes of padding more than usual |
| // the total may have been padded to the nearest quad-byte length |
| RecordInputStream in = TestcaseRecordInputStream.create(ObjRecord.sid, data); |
| // check read OK |
| ObjRecord record = new ObjRecord(in); |
| // check that it re-serializes to the same data |
| byte[] ser = record.serialize(); |
| TestcaseRecordInputStream.confirmRecordEncoding(ObjRecord.sid, data, ser); |
| } |
| } |