]> source.dussan.org Git - poi.git/commitdiff
Fix for bug 46917 - PageItemRecord(SXPI) can contain multiple field infos
authorJosh Micich <josh@apache.org>
Thu, 26 Mar 2009 17:42:18 +0000 (17:42 +0000)
committerJosh Micich <josh@apache.org>
Thu, 26 Mar 2009 17:42:18 +0000 (17:42 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@758770 13f79535-47bb-0310-9956-ffa450edef68

src/documentation/content/xdocs/changes.xml
src/documentation/content/xdocs/status.xml
src/java/org/apache/poi/hssf/record/pivottable/PageItemRecord.java
src/testcases/org/apache/poi/hssf/record/pivot/AllPivotRecordTests.java
src/testcases/org/apache/poi/hssf/record/pivot/TestPageItemRecord.java [new file with mode: 0644]

index 577e2c1d1258bbec8e54d453fd937ba31417a411..c1b43012273eb2dec65db1f89d512d68e0a37814 100644 (file)
@@ -37,6 +37,7 @@
 
                <!-- Don't forget to update status.xml too! -->
         <release version="3.5-beta6" date="2009-??-??">
+           <action dev="POI-DEVELOPERS" type="fix">46917 - Fixed PageItemRecord(SXPI) to allow multiple field infos</action>
            <action dev="POI-DEVELOPERS" type="fix">46904 - Fix POIFS issue with duplicate block 0 references on very old BIFF5/BIFF7 files</action>
            <action dev="POI-DEVELOPERS" type="fix">46840 - PageSettingsBlock should include HEADERFOOTER record</action>
            <action dev="POI-DEVELOPERS" type="fix">46885 - update cell type when setting cached formula result in XSSFCell</action>
index af309e998fbf270e1987b9dd3f2adf813af92fe8..bc383a2694da1eca9c1dad8dfef1bb599cdefc8a 100644 (file)
@@ -34,6 +34,7 @@
        <!-- Don't forget to update changes.xml too! -->
     <changes>
         <release version="3.5-beta6" date="2009-??-??">
+           <action dev="POI-DEVELOPERS" type="fix">46917 - Fixed PageItemRecord(SXPI) to allow multiple field infos</action>
            <action dev="POI-DEVELOPERS" type="fix">46904 - Fix POIFS issue with duplicate block 0 references on very old BIFF5/BIFF7 files</action>
            <action dev="POI-DEVELOPERS" type="fix">46840 - PageSettingsBlock should include HEADERFOOTER record</action>
            <action dev="POI-DEVELOPERS" type="fix">46885 - update cell type when setting cached formula result in XSSFCell</action>
index 8dd476c2a4465ac7962805b60614ad49ea6708a8..ebcb843cc89af9a2b5cec57303408748df3940cd 100644 (file)
@@ -17,6 +17,7 @@
 
 package org.apache.poi.hssf.record.pivottable;
 
+import org.apache.poi.hssf.record.RecordFormatException;
 import org.apache.poi.hssf.record.RecordInputStream;
 import org.apache.poi.hssf.record.StandardRecord;
 import org.apache.poi.util.HexDump;
@@ -30,26 +31,63 @@ import org.apache.poi.util.LittleEndianOutput;
 public final class PageItemRecord extends StandardRecord {
        public static final short sid = 0x00B6;
 
-       private int isxvi;
-       private int isxvd;
-       private int idObj;
-       
+       private static final class FieldInfo {
+               public static final int ENCODED_SIZE = 6;
+               /** Index to the View Item SXVI(0x00B2) record */
+               private int _isxvi;
+               /** Index to the {@link ViewFieldsRecord} SXVD(0x00B1) record */
+               private int _isxvd;
+               /** Object ID for the drop-down arrow */
+               private int _idObj;
+
+               public FieldInfo(RecordInputStream in) {
+                       _isxvi = in.readShort();
+                       _isxvd = in.readShort();
+                       _idObj = in.readShort();
+               }
+
+               protected void serialize(LittleEndianOutput out) {
+                       out.writeShort(_isxvi);
+                       out.writeShort(_isxvd);
+                       out.writeShort(_idObj);
+               }
+
+               public void appendDebugInfo(StringBuffer sb) {
+                       sb.append('(');
+                       sb.append( "isxvi=").append(HexDump.shortToHex(_isxvi));
+                       sb.append(" isxvd=").append(HexDump.shortToHex(_isxvd));
+                       sb.append(" idObj=").append(HexDump.shortToHex(_idObj));
+                       sb.append(')');
+               }
+       }
+
+       private final FieldInfo[] _fieldInfos;
+
        public PageItemRecord(RecordInputStream in) {
-               isxvi = in.readShort();
-               isxvd = in.readShort();
-               idObj = in.readShort();
+               int dataSize = in.remaining();
+               if (dataSize % FieldInfo.ENCODED_SIZE != 0) {
+                       throw new RecordFormatException("Bad data size " + dataSize);
+               }
+
+               int nItems = dataSize / FieldInfo.ENCODED_SIZE;
+
+               FieldInfo[] fis = new FieldInfo[nItems];
+               for (int i = 0; i < fis.length; i++) {
+                       fis[i] = new FieldInfo(in);
+               }
+               _fieldInfos = fis;
        }
-       
+
        @Override
        protected void serialize(LittleEndianOutput out) {
-               out.writeShort(isxvi);
-               out.writeShort(isxvd);
-               out.writeShort(idObj);
+               for (int i = 0; i < _fieldInfos.length; i++) {
+                       _fieldInfos[i].serialize(out);
+               }
        }
 
        @Override
        protected int getDataSize() {
-               return 2 + 2 + 2;
+               return _fieldInfos.length * FieldInfo.ENCODED_SIZE;
        }
 
        @Override
@@ -59,14 +97,15 @@ public final class PageItemRecord extends StandardRecord {
 
        @Override
        public String toString() {
-               StringBuffer buffer = new StringBuffer();
-
-               buffer.append("[SXPI]\n");
-               buffer.append("    .isxvi      =").append(HexDump.shortToHex(isxvi)).append('\n');
-               buffer.append("    .isxvd      =").append(HexDump.shortToHex(isxvd)).append('\n');
-               buffer.append("    .idObj      =").append(HexDump.shortToHex(idObj)).append('\n');
+               StringBuffer sb = new StringBuffer();
 
-               buffer.append("[/SXPI]\n");
-               return buffer.toString();
+               sb.append("[SXPI]\n");
+               for (int i = 0; i < _fieldInfos.length; i++) {
+                       sb.append("    item[").append(i).append("]=");
+                       _fieldInfos[i].appendDebugInfo(sb);
+                       sb.append('\n');
+               }
+               sb.append("[/SXPI]\n");
+               return sb.toString();
        }
 }
index 39546135ad96bb922a803f79745aea5502501744..1787317b80e3f6d3f0cb8c486498836ed5cdeb5d 100644 (file)
@@ -31,6 +31,8 @@ public final class AllPivotRecordTests {
                TestSuite result = new TestSuite(AllPivotRecordTests.class.getName());
                
                result.addTestSuite(TestExtendedPivotTableViewFieldsRecord.class);
+               result.addTestSuite(TestPageItemRecord.class);
+               result.addTestSuite(TestViewFieldsRecord.class);
                return result;
        }
 }
diff --git a/src/testcases/org/apache/poi/hssf/record/pivot/TestPageItemRecord.java b/src/testcases/org/apache/poi/hssf/record/pivot/TestPageItemRecord.java
new file mode 100644 (file)
index 0000000..7cf3b49
--- /dev/null
@@ -0,0 +1,63 @@
+/* ====================================================================
+   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.pivot;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.TestCase;
+
+import org.apache.poi.hssf.record.RecordInputStream;
+import org.apache.poi.hssf.record.TestcaseRecordInputStream;
+import org.apache.poi.hssf.record.pivottable.PageItemRecord;
+import org.apache.poi.util.HexRead;
+
+/**
+ * Tests for {@link PageItemRecord}
+ * 
+ * @author Josh Micich
+ */
+public final class TestPageItemRecord extends TestCase {
+       
+       public void testMoreThanOneInfoItem_bug46917() {
+               byte[] data = HexRead.readFromString("01 02 03 04 05 06 07 08 09 0A 0B 0C");
+               RecordInputStream in = TestcaseRecordInputStream.create(PageItemRecord.sid, data);
+               PageItemRecord rec = new PageItemRecord(in);
+               if (in.remaining() == 6) {
+                       throw new AssertionFailedError("Identified bug 46917");
+               }
+               assertEquals(0, in.remaining());
+               
+               assertEquals(4+data.length, rec.getRecordSize());
+       }
+       
+       public void testSerialize() {
+               confirmSerialize("01 02 03 04 05 06");
+               confirmSerialize("01 02 03 04 05 06 07 08 09 0A 0B 0C");
+               confirmSerialize("01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12");
+       }
+
+       private static PageItemRecord confirmSerialize(String hexDump) {
+               byte[] data = HexRead.readFromString(hexDump);
+               RecordInputStream in = TestcaseRecordInputStream.create(PageItemRecord.sid, data);
+               PageItemRecord rec = new PageItemRecord(in);
+               assertEquals(0, in.remaining());
+               assertEquals(4+data.length, rec.getRecordSize());
+               byte[] data2 = rec.serialize();
+               TestcaseRecordInputStream.confirmRecordEncoding(PageItemRecord.sid, data, data2);
+               return rec;
+       }
+}