Author: josh
Date: Wed Dec 23 04:35:37 2009
New Revision: 893402
URL: http://svn.apache.org/viewvc?rev=893402&view=rev
Log:
Simplified InterfaceHdrRecord and InterfaceEndRecord (some rework after bug
47251 / r892862).
Modified:
poi/trunk/src/java/org/apache/poi/hssf/dev/BiffViewer.java
poi/trunk/src/java/org/apache/poi/hssf/model/InternalWorkbook.java
poi/trunk/src/java/org/apache/poi/hssf/record/InterfaceEndRecord.java
poi/trunk/src/java/org/apache/poi/hssf/record/InterfaceHdrRecord.java
poi/trunk/src/java/org/apache/poi/hssf/record/RecordFactory.java
poi/trunk/src/testcases/org/apache/poi/hssf/record/AllRecordTests.java
poi/trunk/src/testcases/org/apache/poi/hssf/record/TestInterfaceEndRecord.java
poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestSanityChecker.java
Modified: poi/trunk/src/java/org/apache/poi/hssf/dev/BiffViewer.java
URL:
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/dev/BiffViewer.java?rev=893402&r1=893401&r2=893402&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/dev/BiffViewer.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/dev/BiffViewer.java Wed Dec 23
04:35:37 2009
@@ -180,7 +180,7 @@
case HorizontalPageBreakRecord.sid: return new
HorizontalPageBreakRecord(in);
case HyperlinkRecord.sid: return new
HyperlinkRecord(in);
case IndexRecord.sid: return new
IndexRecord(in);
- case InterfaceEndRecord.sid: return new
InterfaceEndRecord(in);
+ case InterfaceEndRecord.sid: return
InterfaceEndRecord.create(in);
case InterfaceHdrRecord.sid: return new
InterfaceHdrRecord(in);
case IterationRecord.sid: return new
IterationRecord(in);
case LabelRecord.sid: return new
LabelRecord(in);
@@ -367,13 +367,13 @@
* <tr><td>--noint</td><td>do not output interpretation of BIFF
records</td></tr>
* <tr><td>--out</td><td>send output to <fileName>.out</td></tr>
* <tr><td>--rawhex</td><td>output raw hex dump of whole workbook
stream</td></tr>
- * <tr><td>--escher</td><td>turn on deserialization of escher records
(default is off)</td></tr>
- * <tr><td>--noheader</td><td>do not print record header (default is
on)</td></tr>
+ * <tr><td>--escher</td><td>turn on deserialization of escher records
(default is off)</td></tr>
+ * <tr><td>--noheader</td><td>do not print record header (default is
on)</td></tr>
* </table>
*
*/
public static void main(String[] args) {
-
+ // args = new String[] { "--out", "", };
CommandArgs cmdArgs;
try {
cmdArgs = CommandArgs.parse(args);
@@ -419,12 +419,12 @@
private final Writer _hexDumpWriter;
private final List<String> _headers;
private final boolean _zeroAlignEachRecord;
- private final boolean _noHeader;
+ private final boolean _noHeader;
public BiffRecordListener(Writer hexDumpWriter, boolean
zeroAlignEachRecord, boolean noHeader) {
_hexDumpWriter = hexDumpWriter;
_zeroAlignEachRecord = zeroAlignEachRecord;
- _noHeader = noHeader;
- _headers = new ArrayList<String>();
+ _noHeader = noHeader;
+ _headers = new ArrayList<String>();
}
public void processRecord(int globalOffset, int recordCounter,
int sid, int dataSize,
Modified: poi/trunk/src/java/org/apache/poi/hssf/model/InternalWorkbook.java
URL:
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/model/InternalWorkbook.java?rev=893402&r1=893401&r2=893402&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/model/InternalWorkbook.java
(original)
+++ poi/trunk/src/java/org/apache/poi/hssf/model/InternalWorkbook.java Wed Dec
23 04:35:37 2009
@@ -340,35 +340,35 @@
retval.records.setRecords(records);
List<FormatRecord> formats = retval.formats;
- records.add(retval.createBOF());
- records.add(retval.createInterfaceHdr());
- records.add(retval.createMMS());
- records.add(retval.createInterfaceEnd());
- records.add(retval.createWriteAccess());
- records.add(retval.createCodepage());
- records.add(retval.createDSF());
- records.add(retval.createTabId());
+ records.add(createBOF());
+ records.add(new InterfaceHdrRecord(CODEPAGE));
+ records.add(createMMS());
+ records.add(InterfaceEndRecord.instance);
+ records.add(createWriteAccess());
+ records.add(createCodepage());
+ records.add(createDSF());
+ records.add(createTabId());
retval.records.setTabpos(records.size() - 1);
- records.add(retval.createFnGroupCount());
+ records.add(createFnGroupCount());
records.add(createWindowProtect());
records.add(createProtect());
retval.records.setProtpos(records.size() - 1);
records.add(createPassword());
records.add(createProtectionRev4());
- records.add(retval.createPasswordRev4());
+ records.add(createPasswordRev4());
retval.windowOne = createWindowOne();
records.add(retval.windowOne);
- records.add(retval.createBackup());
+ records.add(createBackup());
retval.records.setBackuppos(records.size() - 1);
- records.add(retval.createHideObj());
- records.add(retval.createDateWindow1904());
- records.add(retval.createPrecision());
+ records.add(createHideObj());
+ records.add(createDateWindow1904());
+ records.add(createPrecision());
records.add(createRefreshAll());
- records.add(retval.createBookBool());
- records.add(retval.createFont());
- records.add(retval.createFont());
- records.add(retval.createFont());
- records.add(retval.createFont());
+ records.add(createBookBool());
+ records.add(createFont());
+ records.add(createFont());
+ records.add(createFont());
+ records.add(createFont());
retval.records.setFontpos( records.size() - 1 ); // last font record
position
retval.numfonts = 4;
@@ -1054,12 +1054,6 @@
return retval;
}
- private static InterfaceHdrRecord createInterfaceHdr() {
- InterfaceHdrRecord retval = new InterfaceHdrRecord();
-
- retval.setCodepage(CODEPAGE);
- return retval;
- }
private static MMSRecord createMMS() {
MMSRecord retval = new MMSRecord();
@@ -1069,10 +1063,6 @@
return retval;
}
- private static InterfaceEndRecord createInterfaceEnd() {
- return new InterfaceEndRecord();
- }
-
/**
* creates the WriteAccess record containing the logged in user's name
*/
Modified: poi/trunk/src/java/org/apache/poi/hssf/record/InterfaceEndRecord.java
URL:
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/InterfaceEndRecord.java?rev=893402&r1=893401&r2=893402&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/InterfaceEndRecord.java
(original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/InterfaceEndRecord.java Wed
Dec 23 04:35:37 2009
@@ -18,9 +18,6 @@
package org.apache.poi.hssf.record;
import org.apache.poi.util.LittleEndianOutput;
-import org.apache.poi.util.HexDump;
-import org.apache.poi.util.POILogger;
-import org.apache.poi.util.POILogFactory;
/**
* Title: Interface End Record (0x00E2)<P>
@@ -28,50 +25,39 @@
* (has no fields)<P>
* REFERENCE: PG 324 Microsoft Excel 97 Developer's Kit (ISBN:
1-57231-498-2)<P>
* @author Andrew C. Oliver (acoliver at apache dot org)
- * @version 2.0-pre
*/
public final class InterfaceEndRecord extends StandardRecord {
- private static POILogger logger =
POILogFactory.getLogger(InterfaceEndRecord.class);
- public final static short sid = 0x00E2;
+ public static final short sid = 0x00E2;
+ public static final InterfaceEndRecord instance = new InterfaceEndRecord();
- private byte[] _unknownData;
-
- public InterfaceEndRecord()
- {
+ private InterfaceEndRecord() {
+ // enforce singleton
}
- public InterfaceEndRecord(RecordInputStream in)
- {
- if(in.available() > 0){
- _unknownData = in.readRemainder();
- logger.log(POILogger.WARN, "encountered unexpected " +
- _unknownData.length + " bytes in InterfaceEndRecord");
+ public static Record create(RecordInputStream in) {
+ switch (in.remaining()) {
+ case 0:
+ return instance;
+ case 2:
+ return new InterfaceHdrRecord(in);
}
+ throw new RecordFormatException("Invalid record data size: " +
in.remaining());
}
- public String toString()
- {
- StringBuffer buffer = new StringBuffer();
-
- buffer.append("[INTERFACEEND]\n");
- buffer.append("
unknownData=").append(HexDump.toHex(_unknownData)).append("\n");
- buffer.append("[/INTERFACEEND]\n");
- return buffer.toString();
+ public String toString() {
+ return "[INTERFACEEND/]\n";
}
public void serialize(LittleEndianOutput out) {
- if(_unknownData != null) out.write(_unknownData);
+ // no instance data
}
protected int getDataSize() {
- int size = 0;
- if(_unknownData != null) size += _unknownData.length;
- return size;
+ return 0;
}
- public short getSid()
- {
+ public short getSid() {
return sid;
}
}
Modified: poi/trunk/src/java/org/apache/poi/hssf/record/InterfaceHdrRecord.java
URL:
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/InterfaceHdrRecord.java?rev=893402&r1=893401&r2=893402&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/InterfaceHdrRecord.java
(original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/InterfaceHdrRecord.java Wed
Dec 23 04:35:37 2009
@@ -1,4 +1,3 @@
-
/* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
@@ -15,86 +14,53 @@
See the License for the specific language governing permissions and
limitations under the License.
==================================================================== */
-
package org.apache.poi.hssf.record;
+import org.apache.poi.util.HexDump;
import org.apache.poi.util.LittleEndianOutput;
/**
- * Title: Interface Header Record<P>
+ * Title: Interface Header Record (0x00E1)<P>
* Description: Defines the beginning of Interface records (MMS)<P>
* REFERENCE: PG 324 Microsoft Excel 97 Developer's Kit (ISBN:
1-57231-498-2)<P>
* @author Andrew C. Oliver (acoliver at apache dot org)
- * @version 2.0-pre
*/
-
-public final class InterfaceHdrRecord
- extends StandardRecord
-{
- public final static short sid = 0xe1;
- private short field_1_codepage; // = 0;
+public final class InterfaceHdrRecord extends StandardRecord {
+ public final static short sid = 0x00E1;
+ private final int _codepage;
/**
* suggested (and probably correct) default
*/
+ public final static int CODEPAGE = 0x04B0;
- public final static short CODEPAGE = ( short ) 0x4b0;
-
- public InterfaceHdrRecord()
- {
+ public InterfaceHdrRecord(int codePage) {
+ _codepage = codePage;
}
- public InterfaceHdrRecord(RecordInputStream in)
- {
- field_1_codepage = in.readShort();
- }
-
- /**
- * set the codepage for the file
- *
- * @param cp - the codepage
- * @see #CODEPAGE
- */
-
- public void setCodepage(short cp)
- {
- field_1_codepage = cp;
- }
-
- /**
- * get the codepage for the file
- *
- * @return the codepage
- * @see #CODEPAGE
- */
-
- public short getCodepage()
- {
- return field_1_codepage;
+ public InterfaceHdrRecord(RecordInputStream in) {
+ _codepage = in.readShort();
}
- public String toString()
- {
+ public String toString() {
StringBuffer buffer = new StringBuffer();
buffer.append("[INTERFACEHDR]\n");
- buffer.append(" .codepage = ")
- .append(Integer.toHexString(getCodepage())).append("\n");
+ buffer.append(" .codepage =
").append(HexDump.shortToHex(_codepage)).append("\n");
buffer.append("[/INTERFACEHDR]\n");
return buffer.toString();
}
public void serialize(LittleEndianOutput out) {
- out.writeShort(getCodepage());
+ out.writeShort(_codepage);
}
protected int getDataSize() {
return 2;
}
- public short getSid()
- {
+ public short getSid() {
return sid;
}
}
Modified: poi/trunk/src/java/org/apache/poi/hssf/record/RecordFactory.java
URL:
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/RecordFactory.java?rev=893402&r1=893401&r2=893402&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/RecordFactory.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/RecordFactory.java Wed Dec 23
04:35:37 2009
@@ -20,6 +20,7 @@
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.*;
@@ -44,10 +45,10 @@
Class<? extends Record> getRecordClass();
}
- private static final class ReflectionRecordCreator implements
I_RecordCreator {
+ private static final class ReflectionConstructorRecordCreator
implements I_RecordCreator {
private final Constructor<? extends Record> _c;
- public ReflectionRecordCreator(Constructor<? extends Record> c)
{
+ public ReflectionConstructorRecordCreator(Constructor<? extends
Record> c) {
_c = c;
}
public Record create(RecordInputStream in) {
@@ -68,6 +69,33 @@
return _c.getDeclaringClass();
}
}
+ /**
+ * A "create" method is used instead of the usual constructor if the
created record might
+ * be of a different class to the declaring class.
+ */
+ private static final class ReflectionMethodRecordCreator implements
I_RecordCreator {
+
+ private final Method _m;
+ public ReflectionMethodRecordCreator(Method m) {
+ _m = m;
+ }
+ public Record create(RecordInputStream in) {
+ Object[] args = { in, };
+ try {
+ return (Record) _m.invoke(null, args);
+ } catch (IllegalArgumentException e) {
+ throw new RuntimeException(e);
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException(e);
+ } catch (InvocationTargetException e) {
+ throw new RecordFormatException("Unable to
construct record instance" , e.getTargetException());
+ }
+ }
+ @SuppressWarnings("unchecked")
+ public Class<? extends Record> getRecordClass() {
+ return (Class<? extends Record>) _m.getDeclaringClass();
+ }
+ }
private static final Class<?>[] CONSTRUCTOR_ARGS = {
RecordInputStream.class, };
@@ -355,11 +383,9 @@
throw new RuntimeException("duplicate record
class (" + recClass.getName() + ")");
}
- short sid;
- Constructor<? extends Record> constructor;
+ int sid;
try {
sid = recClass.getField("sid").getShort(null);
- constructor =
recClass.getConstructor(CONSTRUCTOR_ARGS);
} catch (Exception illegalArgumentException) {
throw new RecordFormatException(
"Unable to determine record types");
@@ -370,12 +396,27 @@
throw new RuntimeException("duplicate record
sid 0x" + Integer.toHexString(sid).toUpperCase()
+ " for classes (" +
recClass.getName() + ") and (" + prevClass.getName() + ")");
}
- result.put(key, new
ReflectionRecordCreator(constructor));
+ result.put(key, getRecordCreator(recClass));
}
// result.put(Integer.valueOf(0x0406),
result.get(Integer.valueOf(0x06)));
return result;
}
+ private static I_RecordCreator getRecordCreator(Class<? extends Record>
recClass) {
+ try {
+ Constructor<? extends Record> constructor;
+ constructor = recClass.getConstructor(CONSTRUCTOR_ARGS);
+ return new
ReflectionConstructorRecordCreator(constructor);
+ } catch (NoSuchMethodException e) {
+ // fall through and look for other construction methods
+ }
+ try {
+ Method m = recClass.getDeclaredMethod("create",
CONSTRUCTOR_ARGS);
+ return new ReflectionMethodRecordCreator(m);
+ } catch (NoSuchMethodException e) {
+ throw new RuntimeException("Failed to find constructor
or create method for (" + recClass.getName() + ").");
+ }
+ }
/**
* Create an array of records from an input stream
*
Modified: poi/trunk/src/testcases/org/apache/poi/hssf/record/AllRecordTests.java
URL:
http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/hssf/record/AllRecordTests.java?rev=893402&r1=893401&r2=893402&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/hssf/record/AllRecordTests.java
(original)
+++ poi/trunk/src/testcases/org/apache/poi/hssf/record/AllRecordTests.java Wed
Dec 23 04:35:37 2009
@@ -62,6 +62,7 @@
result.addTestSuite(TestFontRecord.class);
result.addTestSuite(TestFormulaRecord.class);
result.addTestSuite(TestHyperlinkRecord.class);
+ result.addTestSuite(TestInterfaceEndRecord.class);
result.addTestSuite(TestLabelRecord.class);
result.addTestSuite(TestMergeCellsRecord.class);
result.addTestSuite(TestNameRecord.class);
Modified:
poi/trunk/src/testcases/org/apache/poi/hssf/record/TestInterfaceEndRecord.java
URL:
http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/hssf/record/TestInterfaceEndRecord.java?rev=893402&r1=893401&r2=893402&view=diff
==============================================================================
---
poi/trunk/src/testcases/org/apache/poi/hssf/record/TestInterfaceEndRecord.java
(original)
+++
poi/trunk/src/testcases/org/apache/poi/hssf/record/TestInterfaceEndRecord.java
Wed Dec 23 04:35:37 2009
@@ -34,13 +34,14 @@
public final class TestInterfaceEndRecord extends TestCase {
public void testCreate() {
- InterfaceEndRecord record = new InterfaceEndRecord();
+ InterfaceEndRecord record = InterfaceEndRecord.instance;
assertEquals(0, record.getDataSize());
}
/**
* Silently swallow unexpected contents in InterfaceEndRecord.
- * Although it violates the spec, Excel silently reads such files.
+ * Although it violates the spec, Excel silently converts this
+ * data to an {...@link InterfaceHdrRecord}.
*/
public void testUnexpectedBytes_bug47251(){
String hex = "" +
@@ -50,7 +51,9 @@
byte[] data = HexRead.readFromString(hex);
List<Record> records = RecordFactory.createRecords(new
ByteArrayInputStream(data));
assertEquals(3, records.size());
- InterfaceEndRecord r = (InterfaceEndRecord)records.get(1);
- assertEquals("[E2, 00, 02, 00, B0, 04]", HexDump.toHex(r.serialize()));
+ Record rec1 = records.get(1);
+ assertEquals(InterfaceHdrRecord.class, rec1.getClass());
+ InterfaceHdrRecord r = (InterfaceHdrRecord)rec1;
+ assertEquals("[E1, 00, 02, 00, B0, 04]", HexDump.toHex(r.serialize()));
}
-}
\ No newline at end of file
+}
Modified:
poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestSanityChecker.java
URL:
http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestSanityChecker.java?rev=893402&r1=893401&r2=893402&view=diff
==============================================================================
---
poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestSanityChecker.java
(original)
+++
poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestSanityChecker.java
Wed Dec 23 04:35:37 2009
@@ -39,15 +39,15 @@
* @author Glen Stampoultzis (glens at apache.org)
*/
public final class TestSanityChecker extends TestCase {
-
+ private static final Record INTERFACEHDR = new
InterfaceHdrRecord(InterfaceHdrRecord.CODEPAGE);
private static BoundSheetRecord createBoundSheetRec() {
return new BoundSheetRecord("Sheet1");
}
public void testCheckRecordOrder() {
final SanityChecker c = new SanityChecker();
- List records = new ArrayList();
+ List<Record> records = new ArrayList<Record>();
records.add(new BOFRecord());
- records.add(new InterfaceHdrRecord());
+ records.add(INTERFACEHDR);
records.add(createBoundSheetRec());
records.add(EOFRecord.instance);
CheckRecord[] check = {
@@ -71,15 +71,15 @@
confirmBadRecordOrder(check, new Record[] {
new BOFRecord(),
createBoundSheetRec(),
- new InterfaceHdrRecord(),
+ INTERFACEHDR,
EOFRecord.instance,
});
confirmBadRecordOrder(check, new Record[] {
new BOFRecord(),
- new InterfaceHdrRecord(),
+ INTERFACEHDR,
createBoundSheetRec(),
- new InterfaceHdrRecord(),
+ INTERFACEHDR,
EOFRecord.instance,
});
@@ -92,19 +92,19 @@
});
confirmBadRecordOrder(check, new Record[] {
- new InterfaceHdrRecord(),
+ INTERFACEHDR,
createBoundSheetRec(),
EOFRecord.instance,
});
confirmBadRecordOrder(check, new Record[] {
new BOFRecord(),
- new InterfaceHdrRecord(),
+ INTERFACEHDR,
EOFRecord.instance,
});
confirmBadRecordOrder(check, new Record[] {
- new InterfaceHdrRecord(),
+ INTERFACEHDR,
createBoundSheetRec(),
new BOFRecord(),
EOFRecord.instance,
@@ -113,7 +113,7 @@
confirmBadRecordOrder(check, new Record[] {
new BOFRecord(),
createBoundSheetRec(),
- new InterfaceHdrRecord(),
+ INTERFACEHDR,
EOFRecord.instance,
});
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]