git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@894018 13f79535-47bb-0310-9956-ffa450edef68tags/REL_3_7_BETA1
@@ -162,6 +162,8 @@ public final class BiffViewer { | |||
case ExtSSTRecord.sid: return new ExtSSTRecord(in); | |||
case ExtendedFormatRecord.sid: return new ExtendedFormatRecord(in); | |||
case ExternSheetRecord.sid: return new ExternSheetRecord(in); | |||
case FeatRecord.sid: return new FeatRecord(in); | |||
case FeatHdrRecord.sid: return new FeatHdrRecord(in); | |||
case FilePassRecord.sid: return new FilePassRecord(in); | |||
case FileSharingRecord.sid: return new FileSharingRecord(in); | |||
case FnGroupCountRecord.sid: return new FnGroupCountRecord(in); |
@@ -34,6 +34,7 @@ import org.apache.poi.hssf.record.DimensionsRecord; | |||
import org.apache.poi.hssf.record.DrawingRecord; | |||
import org.apache.poi.hssf.record.DrawingSelectionRecord; | |||
import org.apache.poi.hssf.record.EOFRecord; | |||
import org.apache.poi.hssf.record.FeatRecord; | |||
import org.apache.poi.hssf.record.FormulaRecord; | |||
import org.apache.poi.hssf.record.GridsetRecord; | |||
import org.apache.poi.hssf.record.GutsRecord; | |||
@@ -341,7 +342,7 @@ final class RecordOrderer { | |||
switch(sid) { | |||
case UnknownRecord.SHEETEXT_0862: | |||
case UnknownRecord.SHEETPROTECTION_0867: | |||
case UnknownRecord.RANGEPROTECTION_0868: | |||
case FeatRecord.sid: | |||
case EOFRecord.sid: | |||
return true; | |||
} |
@@ -17,6 +17,7 @@ | |||
package org.apache.poi.hssf.record; | |||
import org.apache.poi.hssf.record.common.FtrHeader; | |||
import org.apache.poi.util.LittleEndianOutput; | |||
/** | |||
@@ -51,7 +52,8 @@ public final class FeatHdrRecord extends StandardRecord { | |||
public final static short sid = 0x0867; | |||
private FtrHeader futureHeader; | |||
private int isf_sharedFeatureType; // See SHAREDFEATURES_ | |||
private byte reserved; // Should always be one | |||
/** | |||
@@ -63,6 +65,8 @@ public final class FeatHdrRecord extends StandardRecord { | |||
private byte[] rgbHdrData; | |||
public FeatHdrRecord() { | |||
futureHeader = new FtrHeader(); | |||
futureHeader.setRecordType(sid); | |||
} | |||
public short getSid() { | |||
@@ -70,9 +74,11 @@ public final class FeatHdrRecord extends StandardRecord { | |||
} | |||
public FeatHdrRecord(RecordInputStream in) { | |||
futureHeader = new FtrHeader(in); | |||
isf_sharedFeatureType = in.readShort(); | |||
reserved = in.readByte(); | |||
cbHdrData = in.readLong(); | |||
cbHdrData = in.readInt(); | |||
// Don't process this just yet, need the BOFRecord | |||
rgbHdrData = in.readRemainder(); | |||
} | |||
@@ -88,13 +94,15 @@ public final class FeatHdrRecord extends StandardRecord { | |||
} | |||
public void serialize(LittleEndianOutput out) { | |||
futureHeader.serialize(out); | |||
out.writeShort(isf_sharedFeatureType); | |||
out.writeByte(reserved); | |||
out.writeLong(cbHdrData); | |||
out.writeInt((int)cbHdrData); | |||
out.write(rgbHdrData); | |||
} | |||
protected int getDataSize() { | |||
return 2+1+4+rgbHdrData.length; | |||
return 12 + 2+1+4+rgbHdrData.length; | |||
} | |||
} |
@@ -17,6 +17,7 @@ | |||
package org.apache.poi.hssf.record; | |||
import org.apache.poi.hssf.record.common.FtrHeader; | |||
import org.apache.poi.hssf.record.common.Ref8U; | |||
import org.apache.poi.util.LittleEndianOutput; | |||
@@ -29,14 +30,14 @@ import org.apache.poi.util.LittleEndianOutput; | |||
public final class FeatRecord extends StandardRecord { | |||
public final static short sid = 0x0868; | |||
private FtrHeader futureHeader; | |||
/** | |||
* See SHAREDFEATURES_* on {@link FeatHdrRecord} | |||
*/ | |||
private int isf_sharedFeatureType; | |||
private byte reserved1; // Should always be zero | |||
private long reserved2; // Should always be zero | |||
/** The number of refs */ | |||
private int cref; | |||
/** Only matters if type is ISFFEC2 */ | |||
private long cbFeatData; | |||
private int reserved3; // Should always be zero | |||
@@ -45,6 +46,8 @@ public final class FeatRecord extends StandardRecord { | |||
private byte[] rgbFeat; | |||
public FeatRecord() { | |||
futureHeader = new FtrHeader(); | |||
futureHeader.setRecordType(sid); | |||
} | |||
public short getSid() { | |||
@@ -52,11 +55,13 @@ public final class FeatRecord extends StandardRecord { | |||
} | |||
public FeatRecord(RecordInputStream in) { | |||
futureHeader = new FtrHeader(in); | |||
isf_sharedFeatureType = in.readShort(); | |||
reserved1 = in.readByte(); | |||
reserved2 = in.readLong(); | |||
cref = in.readUShort(); | |||
cbFeatData = in.readLong(); | |||
reserved2 = in.readInt(); | |||
int cref = in.readUShort(); | |||
cbFeatData = in.readInt(); | |||
reserved3 = in.readShort(); | |||
cellRefs = new Ref8U[cref]; | |||
@@ -69,7 +74,7 @@ public final class FeatRecord extends StandardRecord { | |||
public String toString() { | |||
StringBuffer buffer = new StringBuffer(); | |||
buffer.append("[SHARDED FEATURE]\n"); | |||
buffer.append("[SHARED FEATURE]\n"); | |||
// TODO ... | |||
@@ -78,13 +83,23 @@ public final class FeatRecord extends StandardRecord { | |||
} | |||
public void serialize(LittleEndianOutput out) { | |||
futureHeader.serialize(out); | |||
out.writeShort(isf_sharedFeatureType); | |||
out.writeByte(reserved1); | |||
out.writeInt((int)reserved2); | |||
out.writeShort(cellRefs.length); | |||
out.writeInt((int)cbFeatData); | |||
out.writeShort(reserved3); | |||
// TODO ... | |||
for(int i=0; i<cellRefs.length; i++) { | |||
cellRefs[i].serialize(out); | |||
} | |||
out.write(rgbFeat); | |||
} | |||
protected int getDataSize() { | |||
return -1; // TODO | |||
return 12 + 2+1+4+2+4+2+Ref8U.getDataSize()+rgbFeat.length; | |||
} | |||
} |
@@ -143,6 +143,8 @@ public final class RecordFactory { | |||
ExternalNameRecord.class, | |||
ExternSheetRecord.class, | |||
ExtSSTRecord.class, | |||
FeatRecord.class, | |||
FeatHdrRecord.class, | |||
FilePassRecord.class, | |||
FileSharingRecord.class, | |||
FnGroupCountRecord.class, |
@@ -234,12 +234,18 @@ public final class RecordInputStream implements LittleEndianInput { | |||
return _dataInput.readShort(); | |||
} | |||
/** | |||
* Reads a 32 bit, signed value | |||
*/ | |||
public int readInt() { | |||
checkRecordPosition(LittleEndian.INT_SIZE); | |||
_currentDataOffset += LittleEndian.INT_SIZE; | |||
return _dataInput.readInt(); | |||
} | |||
/** | |||
* Reads a 64 bit, signed value | |||
*/ | |||
public long readLong() { | |||
checkRecordPosition(LittleEndian.LONG_SIZE); | |||
_currentDataOffset += LittleEndian.LONG_SIZE; |
@@ -56,7 +56,6 @@ public final class UnknownRecord extends StandardRecord { | |||
public static final int QUICKTIP_0800 = 0x0800; | |||
public static final int SHEETEXT_0862 = 0x0862; // OOO calls this SHEETLAYOUT | |||
public static final int SHEETPROTECTION_0867 = 0x0867; | |||
public static final int RANGEPROTECTION_0868 = 0x0868; | |||
public static final int HEADER_FOOTER_089C = 0x089C; | |||
private int _sid; | |||
@@ -173,7 +172,6 @@ public final class UnknownRecord extends StandardRecord { | |||
case 0x0863: return "BOOKEXT"; | |||
case 0x0864: return "SXADDL"; // Pivot Table Additional Info | |||
case SHEETPROTECTION_0867: return "SHEETPROTECTION"; | |||
case RANGEPROTECTION_0868: return "RANGEPROTECTION"; | |||
case 0x086B: return "DATALABEXTCONTENTS"; | |||
case 0x086C: return "CELLWATCH"; | |||
case 0x0874: return "DROPDOWNOBJIDS"; |
@@ -0,0 +1,89 @@ | |||
/* ==================================================================== | |||
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.common; | |||
import org.apache.poi.hssf.record.RecordInputStream; | |||
import org.apache.poi.util.LittleEndianOutput; | |||
/** | |||
* Title: FtrHeader (Future Record Header) common record part | |||
* <P> | |||
* This record part specifies a header for a Ftr (Future) | |||
* style record, which includes extra attributes above and | |||
* beyond those of a traditional record. | |||
*/ | |||
public final class FtrHeader { | |||
/** This MUST match the type on the containing record */ | |||
private short recordType; | |||
/** This is a FrtFlags */ | |||
private short grbitFrt; | |||
/** MUST be 8 bytes and all zero */ | |||
private byte[] reserved; | |||
public FtrHeader() { | |||
reserved = new byte[8]; | |||
} | |||
public FtrHeader(RecordInputStream in) { | |||
recordType = in.readShort(); | |||
grbitFrt = in.readShort(); | |||
reserved = new byte[8]; | |||
in.read(reserved, 0, 8); | |||
} | |||
public String toString() { | |||
StringBuffer buffer = new StringBuffer(); | |||
buffer.append(" [FUTURE HEADER]\n"); | |||
buffer.append(" Type " + recordType); | |||
buffer.append(" Flags " + grbitFrt); | |||
buffer.append(" [/FUTURE HEADER]\n"); | |||
return buffer.toString(); | |||
} | |||
public void serialize(LittleEndianOutput out) { | |||
out.writeShort(recordType); | |||
out.writeShort(grbitFrt); | |||
out.write(reserved); | |||
} | |||
public static int getDataSize() { | |||
return 12; | |||
} | |||
public short getRecordType() { | |||
return recordType; | |||
} | |||
public void setRecordType(short recordType) { | |||
this.recordType = recordType; | |||
} | |||
public short getGrbitFrt() { | |||
return grbitFrt; | |||
} | |||
public void setGrbitFrt(short grbitFrt) { | |||
this.grbitFrt = grbitFrt; | |||
} | |||
public byte[] getReserved() { | |||
return reserved; | |||
} | |||
public void setReserved(byte[] reserved) { | |||
this.reserved = reserved; | |||
} | |||
} |
@@ -27,6 +27,7 @@ import org.apache.poi.hssf.record.ContinueRecord; | |||
import org.apache.poi.hssf.record.DVALRecord; | |||
import org.apache.poi.hssf.record.DVRecord; | |||
import org.apache.poi.hssf.record.EOFRecord; | |||
import org.apache.poi.hssf.record.FeatHdrRecord; | |||
import org.apache.poi.hssf.record.Record; | |||
import org.apache.poi.hssf.record.SelectionRecord; | |||
import org.apache.poi.hssf.record.WindowTwoRecord; | |||
@@ -86,9 +87,10 @@ public final class TestHSSFEventFactory extends TestCase { | |||
// Check that the last few records are as we expect | |||
// (Makes sure we don't accidently skip the end ones) | |||
int numRec = recs.length; | |||
assertEquals(DVALRecord.class, recs[numRec-3].getClass()); | |||
assertEquals(DVRecord.class, recs[numRec-2].getClass()); | |||
assertEquals(EOFRecord.class, recs[numRec-1].getClass()); | |||
assertEquals(DVALRecord.class, recs[numRec-4].getClass()); | |||
assertEquals(DVRecord.class, recs[numRec-3].getClass()); | |||
assertEquals(FeatHdrRecord.class, recs[numRec-2].getClass()); | |||
assertEquals(EOFRecord.class, recs[numRec-1].getClass()); | |||
} | |||
/** | |||
@@ -110,7 +112,7 @@ public final class TestHSSFEventFactory extends TestCase { | |||
} | |||
private static class MockHSSFListener implements HSSFListener { | |||
private final List records = new ArrayList(); | |||
private final List<Record> records = new ArrayList<Record>(); | |||
public MockHSSFListener() {} | |||
public Record[] getRecords() { |
@@ -0,0 +1,89 @@ | |||
/* ==================================================================== | |||
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 org.apache.poi.hssf.HSSFTestDataSamples; | |||
import org.apache.poi.hssf.model.InternalWorkbook; | |||
import org.apache.poi.hssf.usermodel.HSSFTestHelper; | |||
import org.apache.poi.hssf.usermodel.HSSFWorkbook; | |||
import junit.framework.TestCase; | |||
/** | |||
* Tests for <tt>FeatRecord</tt> | |||
* | |||
* @author Josh Micich | |||
*/ | |||
public final class TestFeatRecord extends TestCase { | |||
public void testWithoutFeatRecord() throws Exception { | |||
HSSFWorkbook hssf = | |||
HSSFTestDataSamples.openSampleWorkbook("46136-WithWarnings.xls"); | |||
InternalWorkbook wb = HSSFTestHelper.getWorkbookForTest(hssf); | |||
int countFR = 0; | |||
int countFRH = 0; | |||
for(Record r : wb.getRecords()) { | |||
if(r instanceof FeatRecord) { | |||
countFR++; | |||
} else if (r.getSid() == FeatRecord.sid) { | |||
countFR++; | |||
} | |||
if(r instanceof FeatHdrRecord) { | |||
countFRH++; | |||
} else if (r.getSid() == FeatHdrRecord.sid) { | |||
countFRH++; | |||
} | |||
} | |||
assertEquals(0, countFR); | |||
assertEquals(0, countFRH); | |||
} | |||
/** | |||
* TODO - make this work! | |||
* (Need to have the Internal Workbook capture it or something) | |||
*/ | |||
public void DISABLEDtestReadFeatRecord() throws Exception { | |||
HSSFWorkbook hssf = | |||
HSSFTestDataSamples.openSampleWorkbook("46136-NoWarnings.xls"); | |||
InternalWorkbook wb = HSSFTestHelper.getWorkbookForTest(hssf); | |||
FeatRecord fr = null; | |||
int countFR = 0; | |||
int countFRH = 0; | |||
for(Record r : wb.getRecords()) { | |||
if(r instanceof FeatRecord) { | |||
fr = (FeatRecord)r; | |||
countFR++; | |||
} else if (r.getSid() == FeatRecord.sid) { | |||
fail("FeatRecord SID found but not created correctly!"); | |||
} | |||
if(r instanceof FeatHdrRecord) { | |||
countFRH++; | |||
} else if (r.getSid() == FeatHdrRecord.sid) { | |||
fail("FeatHdrRecord SID found but not created correctly!"); | |||
} | |||
} | |||
assertEquals(1, countFR); | |||
assertEquals(1, countFRH); | |||
assertNotNull(fr); | |||
// Now check the contents are as expected | |||
} | |||
} |
@@ -0,0 +1,33 @@ | |||
/* ==================================================================== | |||
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.usermodel; | |||
import org.apache.poi.hssf.model.InternalWorkbook; | |||
/** | |||
* Helper class for HSSF tests that aren't within the | |||
* HSSF UserModel package, but need to do internal | |||
* UserModel things. | |||
*/ | |||
public class HSSFTestHelper { | |||
/** | |||
* Lets non UserModel tests at the low level Workbook | |||
*/ | |||
public static InternalWorkbook getWorkbookForTest(HSSFWorkbook wb) { | |||
return wb.getWorkbook(); | |||
} | |||
} |