More work on FeatRecord/Shared Features. More is still needed though, it's still WIP
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@894018 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
e536251666
commit
869fc4e5a6
@ -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;
|
||||
|
||||
/**
|
||||
@ -52,6 +53,7 @@ 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";
|
||||
|
89
src/java/org/apache/poi/hssf/record/common/FtrHeader.java
Normal file
89
src/java/org/apache/poi/hssf/record/common/FtrHeader.java
Normal file
@ -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,8 +87,9 @@ 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(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() {
|
||||
|
89
src/testcases/org/apache/poi/hssf/record/TestFeatRecord.java
Normal file
89
src/testcases/org/apache/poi/hssf/record/TestFeatRecord.java
Normal file
@ -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();
|
||||
}
|
||||
}
|
BIN
test-data/spreadsheet/46136-NoWarnings.xls
Normal file
BIN
test-data/spreadsheet/46136-NoWarnings.xls
Normal file
Binary file not shown.
BIN
test-data/spreadsheet/46136-WithWarnings.xls
Normal file
BIN
test-data/spreadsheet/46136-WithWarnings.xls
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user