/* ==================================================================== 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.hwpf.model; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.HashSet; import java.util.Locale; import org.apache.logging.log4j.Logger; import org.apache.poi.logging.PoiLogManager; import org.apache.poi.hwpf.HWPFDocument; import org.apache.poi.hwpf.model.types.FibBaseAbstractType; import org.apache.poi.hwpf.model.types.FibRgLw97AbstractType; import org.apache.poi.hwpf.model.types.FibRgW97AbstractType; import org.apache.poi.util.IOUtils; import org.apache.poi.util.Internal; import org.apache.poi.util.LittleEndian; import org.apache.poi.util.LittleEndianConsts; import static org.apache.logging.log4j.util.Unbox.box; /** *
The File Information Block (FIB). Holds pointers * to various bits of the file, and lots of flags which * specify properties of the document. *
* Quote from * "[MS-DOC] -- v20110315, Word (.doc) Binary File Format; page 76 / 621" */ public int getFcPlfLst() { return _fieldHandler.getFieldOffset( FIBFieldHandler.PLFLST ); } @Deprecated public int getLcbPlcfLst() { return _fieldHandler.getFieldSize(FIBFieldHandler.PLCFLST); } public int getLcbPlfLst() { return _fieldHandler.getFieldSize( FIBFieldHandler.PLFLST ); } @Deprecated public void setFcPlcfLst( int fcPlcfLst ) { _fieldHandler.setFieldOffset( FIBFieldHandler.PLCFLST, fcPlcfLst ); } public void setFcPlfLst( int fcPlfLst ) { _fieldHandler.setFieldOffset( FIBFieldHandler.PLFLST, fcPlfLst ); } @Deprecated public void setLcbPlcfLst( int lcbPlcfLst ) { _fieldHandler.setFieldSize( FIBFieldHandler.PLCFLST, lcbPlcfLst ); } public void setLcbPlfLst( int lcbPlfLst ) { _fieldHandler.setFieldSize( FIBFieldHandler.PLFLST, lcbPlfLst ); } /** * An unsigned integer that specifies an offset in the Table Stream. A * PlfLfo that contains list formatting override information begins at this * offset. If lcbPlfLfo is zero, fcPlfLfo is undefined and MUST be ignored. *
* Quote from * "[MS-DOC] -- v20110315, Word (.doc) Binary File Format; page 76 / 621" */ public int getFcPlfLfo() { return _fieldHandler.getFieldOffset( FIBFieldHandler.PLFLFO ); } public int getLcbPlfLfo() { return _fieldHandler.getFieldSize(FIBFieldHandler.PLFLFO); } /** * @return Offset in table stream of the STTBF that records bookmark names * in the main document */ public int getFcSttbfbkmk() { return _fieldHandler.getFieldOffset( FIBFieldHandler.STTBFBKMK ); } public void setFcSttbfbkmk( int offset ) { _fieldHandler.setFieldOffset( FIBFieldHandler.STTBFBKMK, offset ); } /** * @return Count of bytes in Sttbfbkmk */ public int getLcbSttbfbkmk() { return _fieldHandler.getFieldSize( FIBFieldHandler.STTBFBKMK ); } public void setLcbSttbfbkmk( int length ) { _fieldHandler.setFieldSize( FIBFieldHandler.STTBFBKMK, length ); } /** * @return Offset in table stream of the PLCF that records the beginning CP * offsets of bookmarks in the main document. See BKF structure * definition. */ public int getFcPlcfbkf() { return _fieldHandler.getFieldOffset( FIBFieldHandler.PLCFBKF ); } public void setFcPlcfbkf( int offset ) { _fieldHandler.setFieldOffset( FIBFieldHandler.PLCFBKF, offset ); } /** * @return Count of bytes in Plcfbkf */ public int getLcbPlcfbkf() { return _fieldHandler.getFieldSize( FIBFieldHandler.PLCFBKF ); } public void setLcbPlcfbkf( int length ) { _fieldHandler.setFieldSize( FIBFieldHandler.PLCFBKF, length ); } /** * @return Offset in table stream of the PLCF that records the ending CP * offsets of bookmarks recorded in the main document. No structure * is stored in this PLCF. */ public int getFcPlcfbkl() { return _fieldHandler.getFieldOffset( FIBFieldHandler.PLCFBKL ); } public void setFcPlcfbkl( int offset ) { _fieldHandler.setFieldOffset( FIBFieldHandler.PLCFBKL, offset ); } /** * @return Count of bytes in Plcfbkl */ public int getLcbPlcfbkl() { return _fieldHandler.getFieldSize( FIBFieldHandler.PLCFBKL ); } public void setLcbPlcfbkl( int length ) { _fieldHandler.setFieldSize( FIBFieldHandler.PLCFBKL, length ); } public void setFcPlfLfo(int fcPlfLfo) { _fieldHandler.setFieldOffset(FIBFieldHandler.PLFLFO, fcPlfLfo); } public void setLcbPlfLfo(int lcbPlfLfo) { _fieldHandler.setFieldSize(FIBFieldHandler.PLFLFO, lcbPlfLfo); } public int getFcSttbfffn() { return _fieldHandler.getFieldOffset(FIBFieldHandler.STTBFFFN); } public int getLcbSttbfffn() { return _fieldHandler.getFieldSize(FIBFieldHandler.STTBFFFN); } public void setFcSttbfffn(int fcSttbFffn) { _fieldHandler.setFieldOffset(FIBFieldHandler.STTBFFFN, fcSttbFffn); } public void setLcbSttbfffn(int lcbSttbFffn) { _fieldHandler.setFieldSize(FIBFieldHandler.STTBFFFN, lcbSttbFffn); } public int getFcSttbfRMark() { return _fieldHandler.getFieldOffset(FIBFieldHandler.STTBFRMARK); } public int getLcbSttbfRMark() { return _fieldHandler.getFieldSize(FIBFieldHandler.STTBFRMARK); } public void setFcSttbfRMark(int fcSttbfRMark) { _fieldHandler.setFieldOffset(FIBFieldHandler.STTBFRMARK, fcSttbfRMark); } public void setLcbSttbfRMark(int lcbSttbfRMark) { _fieldHandler.setFieldSize(FIBFieldHandler.STTBFRMARK, lcbSttbfRMark); } /** * Return the offset to the PlcfHdd, in the table stream, * i.e. fcPlcfHdd */ public int getPlcfHddOffset() { return _fieldHandler.getFieldOffset(FIBFieldHandler.PLCFHDD); } /** * Return the size of the PlcfHdd, in the table stream, * i.e. lcbPlcfHdd */ public int getPlcfHddSize() { return _fieldHandler.getFieldSize(FIBFieldHandler.PLCFHDD); } public void setPlcfHddOffset(int fcPlcfHdd) { _fieldHandler.setFieldOffset(FIBFieldHandler.PLCFHDD, fcPlcfHdd); } public void setPlcfHddSize(int lcbPlcfHdd) { _fieldHandler.setFieldSize(FIBFieldHandler.PLCFHDD, lcbPlcfHdd); } public int getFcSttbSavedBy() { return _fieldHandler.getFieldOffset(FIBFieldHandler.STTBSAVEDBY); } public int getLcbSttbSavedBy() { return _fieldHandler.getFieldSize(FIBFieldHandler.STTBSAVEDBY); } public void setFcSttbSavedBy(int fcSttbSavedBy) { _fieldHandler.setFieldOffset(FIBFieldHandler.STTBSAVEDBY, fcSttbSavedBy); } public void setLcbSttbSavedBy(int fcSttbSavedBy) { _fieldHandler.setFieldSize(FIBFieldHandler.STTBSAVEDBY, fcSttbSavedBy); } public int getModifiedLow() { return _fieldHandler.getFieldOffset(FIBFieldHandler.PLFLFO); } public int getModifiedHigh() { return _fieldHandler.getFieldSize(FIBFieldHandler.PLFLFO); } public void setModifiedLow(int modifiedLow) { _fieldHandler.setFieldOffset(FIBFieldHandler.PLFLFO, modifiedLow); } public void setModifiedHigh(int modifiedHigh) { _fieldHandler.setFieldSize(FIBFieldHandler.PLFLFO, modifiedHigh); } /** * How many bytes of the main stream contain real data. */ public int getCbMac() { return _fibRgLw.getCbMac(); } /** * Updates the count of the number of bytes in the * main stream which contain real data */ public void setCbMac( int cbMac ) { _fibRgLw.setCbMac( cbMac ); } /** * @return length of specified subdocument text stream in characters */ public int getSubdocumentTextStreamLength( SubdocumentType type ) { if ( type == null ) throw new IllegalArgumentException( "argument 'type' is null" ); return _fibRgLw.getSubdocumentTextStreamLength( type ); } public void setSubdocumentTextStreamLength( SubdocumentType type, int length ) { if ( type == null ) throw new IllegalArgumentException( "argument 'type' is null" ); if ( length < 0 ) throw new IllegalArgumentException( "Subdocument length can't be less than 0 (passed value is " + length + "). " + "If there is no subdocument " + "length must be set to zero." ); _fibRgLw.setSubdocumentTextStreamLength( type, length ); } public void clearOffsetsSizes() { _fieldHandler.clearFields(); } public int getFieldsPlcfOffset( FieldsDocumentPart part ) { return _fieldHandler.getFieldOffset( part.getFibFieldsField() ); } public int getFieldsPlcfLength( FieldsDocumentPart part ) { return _fieldHandler.getFieldSize( part.getFibFieldsField() ); } public void setFieldsPlcfOffset( FieldsDocumentPart part, int offset ) { _fieldHandler.setFieldOffset( part.getFibFieldsField(), offset ); } public void setFieldsPlcfLength( FieldsDocumentPart part, int length ) { _fieldHandler.setFieldSize( part.getFibFieldsField(), length ); } @Deprecated public int getFcPlcffldAtn() { return _fieldHandler.getFieldOffset(FIBFieldHandler.PLCFFLDATN); } @Deprecated public int getLcbPlcffldAtn() { return _fieldHandler.getFieldSize(FIBFieldHandler.PLCFFLDATN); } @Deprecated public void setFcPlcffldAtn( int offset ) { _fieldHandler.setFieldOffset( FIBFieldHandler.PLCFFLDATN, offset ); } @Deprecated public void setLcbPlcffldAtn( int size ) { _fieldHandler.setFieldSize( FIBFieldHandler.PLCFFLDATN, size ); } @Deprecated public int getFcPlcffldEdn() { return _fieldHandler.getFieldOffset(FIBFieldHandler.PLCFFLDEDN); } @Deprecated public int getLcbPlcffldEdn() { return _fieldHandler.getFieldSize(FIBFieldHandler.PLCFFLDEDN); } @Deprecated public void setFcPlcffldEdn( int offset ) { _fieldHandler.setFieldOffset( FIBFieldHandler.PLCFFLDEDN, offset ); } @Deprecated public void setLcbPlcffldEdn( int size ) { _fieldHandler.setFieldSize( FIBFieldHandler.PLCFFLDEDN, size ); } @Deprecated public int getFcPlcffldFtn() { return _fieldHandler.getFieldOffset(FIBFieldHandler.PLCFFLDFTN); } @Deprecated public int getLcbPlcffldFtn() { return _fieldHandler.getFieldSize(FIBFieldHandler.PLCFFLDFTN); } @Deprecated public void setFcPlcffldFtn( int offset ) { _fieldHandler.setFieldOffset( FIBFieldHandler.PLCFFLDFTN, offset ); } @Deprecated public void setLcbPlcffldFtn( int size ) { _fieldHandler.setFieldSize( FIBFieldHandler.PLCFFLDFTN, size ); } @Deprecated public int getFcPlcffldHdr() { return _fieldHandler.getFieldOffset(FIBFieldHandler.PLCFFLDHDR); } @Deprecated public int getLcbPlcffldHdr() { return _fieldHandler.getFieldSize(FIBFieldHandler.PLCFFLDHDR); } @Deprecated public void setFcPlcffldHdr( int offset ) { _fieldHandler.setFieldOffset( FIBFieldHandler.PLCFFLDHDR, offset ); } @Deprecated public void setLcbPlcffldHdr( int size ) { _fieldHandler.setFieldSize( FIBFieldHandler.PLCFFLDHDR, size ); } @Deprecated public int getFcPlcffldHdrtxbx() { return _fieldHandler.getFieldOffset(FIBFieldHandler.PLCFFLDHDRTXBX); } @Deprecated public int getLcbPlcffldHdrtxbx() { return _fieldHandler.getFieldSize(FIBFieldHandler.PLCFFLDHDRTXBX); } @Deprecated public void setFcPlcffldHdrtxbx( int offset ) { _fieldHandler.setFieldOffset( FIBFieldHandler.PLCFFLDHDRTXBX, offset ); } @Deprecated public void setLcbPlcffldHdrtxbx( int size ) { _fieldHandler.setFieldSize( FIBFieldHandler.PLCFFLDHDRTXBX, size ); } @Deprecated public int getFcPlcffldMom() { return _fieldHandler.getFieldOffset(FIBFieldHandler.PLCFFLDMOM); } @Deprecated public int getLcbPlcffldMom() { return _fieldHandler.getFieldSize(FIBFieldHandler.PLCFFLDMOM); } @Deprecated public void setFcPlcffldMom( int offset ) { _fieldHandler.setFieldOffset( FIBFieldHandler.PLCFFLDMOM, offset ); } @Deprecated public void setLcbPlcffldMom( int size ) { _fieldHandler.setFieldSize( FIBFieldHandler.PLCFFLDMOM, size ); } @Deprecated public int getFcPlcffldTxbx() { return _fieldHandler.getFieldOffset(FIBFieldHandler.PLCFFLDTXBX); } @Deprecated public int getLcbPlcffldTxbx() { return _fieldHandler.getFieldSize(FIBFieldHandler.PLCFFLDTXBX); } @Deprecated public void setFcPlcffldTxbx( int offset ) { _fieldHandler.setFieldOffset( FIBFieldHandler.PLCFFLDTXBX, offset ); } @Deprecated public void setLcbPlcffldTxbx( int size ) { _fieldHandler.setFieldSize( FIBFieldHandler.PLCFFLDTXBX, size ); } public int getFSPAPlcfOffset( FSPADocumentPart part ) { return _fieldHandler.getFieldOffset( part.getFibFieldsField() ); } public int getFSPAPlcfLength( FSPADocumentPart part ) { return _fieldHandler.getFieldSize( part.getFibFieldsField() ); } public void setFSPAPlcfOffset( FSPADocumentPart part, int offset ) { _fieldHandler.setFieldOffset( part.getFibFieldsField(), offset ); } public void setFSPAPlcfLength( FSPADocumentPart part, int length ) { _fieldHandler.setFieldSize( part.getFibFieldsField(), length ); } /** * @return Offset in the Table Stream at which the {@link OfficeArtContent} exists. */ public int getFcDggInfo() { return _fieldHandler.getFieldOffset(FIBFieldHandler.DGGINFO); } /** * Returns the size, in bytes, of the {@link OfficeArtContent} at the offset {@link #getFcDggInfo()}. *
* If {@code 0}, there MUST NOT be any drawings in the document. * * @return Size, in bytes, of the {@link OfficeArtContent} at the offset {@link #getFcDggInfo()}. */ public int getLcbDggInfo() { return _fieldHandler.getFieldSize(FIBFieldHandler.DGGINFO); } public int getNotesDescriptorsOffset( NoteType noteType ) { return _fieldHandler.getFieldOffset( noteType .getFibDescriptorsFieldIndex() ); } public void setNotesDescriptorsOffset( NoteType noteType, int offset ) { _fieldHandler.setFieldOffset( noteType.getFibDescriptorsFieldIndex(), offset ); } public int getNotesDescriptorsSize( NoteType noteType ) { return _fieldHandler.getFieldSize( noteType .getFibDescriptorsFieldIndex() ); } public void setNotesDescriptorsSize( NoteType noteType, int offset ) { _fieldHandler.setFieldSize( noteType.getFibDescriptorsFieldIndex(), offset ); } public int getNotesTextPositionsOffset( NoteType noteType ) { return _fieldHandler.getFieldOffset( noteType .getFibTextPositionsFieldIndex() ); } public void setNotesTextPositionsOffset( NoteType noteType, int offset ) { _fieldHandler.setFieldOffset( noteType.getFibTextPositionsFieldIndex(), offset ); } public int getNotesTextPositionsSize( NoteType noteType ) { return _fieldHandler.getFieldSize( noteType .getFibTextPositionsFieldIndex() ); } public void setNotesTextPositionsSize( NoteType noteType, int offset ) { _fieldHandler.setFieldSize( noteType.getFibTextPositionsFieldIndex(), offset ); } public void writeTo( byte[] mainStream, ByteArrayOutputStream tableStream ) throws IOException { _cbRgFcLcb = _fieldHandler.getFieldsCount(); _fibBase.serialize( mainStream, 0 ); int offset = FibBaseAbstractType.getSize(); LittleEndian.putUShort( mainStream, offset, _csw ); offset += LittleEndianConsts.SHORT_SIZE; _fibRgW.serialize( mainStream, offset ); offset += FibRgW97AbstractType.getSize(); LittleEndian.putUShort( mainStream, offset, _cslw ); offset += LittleEndianConsts.SHORT_SIZE; ( (FibRgLw97) _fibRgLw ).serialize( mainStream, offset ); offset += FibRgLw97AbstractType.getSize(); LittleEndian.putUShort( mainStream, offset, _cbRgFcLcb ); offset += LittleEndianConsts.SHORT_SIZE; _fieldHandler.writeTo( mainStream, offset, tableStream ); offset += _cbRgFcLcb * LittleEndianConsts.INT_SIZE * 2; LittleEndian.putUShort( mainStream, offset, _cswNew ); offset += LittleEndianConsts.SHORT_SIZE; if ( _cswNew != 0 ) { LittleEndian.putUShort( mainStream, offset, _nFibNew ); offset += LittleEndianConsts.SHORT_SIZE; System.arraycopy( _fibRgCswNew, 0, mainStream, offset, _fibRgCswNew.length ); } } public int getSize() { return FibBaseAbstractType.getSize() + LittleEndianConsts.SHORT_SIZE + FibRgW97AbstractType.getSize() + LittleEndianConsts.SHORT_SIZE + FibRgLw97AbstractType.getSize() + LittleEndianConsts.SHORT_SIZE + _fieldHandler.sizeInBytes(); } public FibBase getFibBase() { return _fibBase; } }