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);
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;
switch(sid) {
case UnknownRecord.SHEETEXT_0862:
case UnknownRecord.SHEETPROTECTION_0867:
- case UnknownRecord.RANGEPROTECTION_0868:
+ case FeatRecord.sid:
case EOFRecord.sid:
return true;
}
package org.apache.poi.hssf.record;
+import org.apache.poi.hssf.record.common.FtrHeader;
import org.apache.poi.util.LittleEndianOutput;
/**
public final static short sid = 0x0867;
-
+
+ private FtrHeader futureHeader;
private int isf_sharedFeatureType; // See SHAREDFEATURES_
private byte reserved; // Should always be one
/**
private byte[] rgbHdrData;
public FeatHdrRecord() {
+ futureHeader = new FtrHeader();
+ futureHeader.setRecordType(sid);
}
public short getSid() {
}
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();
}
}
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;
}
}
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;
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
private byte[] rgbFeat;
public FeatRecord() {
+ futureHeader = new FtrHeader();
+ futureHeader.setRecordType(sid);
}
public short getSid() {
}
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];
public String toString() {
StringBuffer buffer = new StringBuffer();
- buffer.append("[SHARDED FEATURE]\n");
+ buffer.append("[SHARED FEATURE]\n");
// TODO ...
}
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;
}
}
ExternalNameRecord.class,
ExternSheetRecord.class,
ExtSSTRecord.class,
+ FeatRecord.class,
+ FeatHdrRecord.class,
FilePassRecord.class,
FileSharingRecord.class,
FnGroupCountRecord.class,
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;
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;
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";
--- /dev/null
+/* ====================================================================
+ 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;
+ }
+}
\ No newline at end of file
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;
// 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());
}
/**
}
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() {
--- /dev/null
+/* ====================================================================
+ 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
+ }
+}
--- /dev/null
+/* ====================================================================
+ 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();
+ }
+}