001: /* ====================================================================
002: Licensed to the Apache Software Foundation (ASF) under one or more
003: contributor license agreements. See the NOTICE file distributed with
004: this work for additional information regarding copyright ownership.
005: The ASF licenses this file to You under the Apache License, Version 2.0
006: (the "License"); you may not use this file except in compliance with
007: the License. You may obtain a copy of the License at
008:
009: http://www.apache.org/licenses/LICENSE-2.0
010:
011: Unless required by applicable law or agreed to in writing, software
012: distributed under the License is distributed on an "AS IS" BASIS,
013: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: See the License for the specific language governing permissions and
015: limitations under the License.
016: ==================================================================== */
017:
018: package org.apache.poi.hwpf.model;
019:
020: import java.util.HashSet;
021: import java.util.HashMap;
022: import java.util.Arrays;
023: import java.io.IOException;
024:
025: import org.apache.poi.hwpf.model.io.HWPFOutputStream;
026:
027: import org.apache.poi.util.LittleEndian;
028: import org.apache.poi.util.POILogFactory;
029: import org.apache.poi.util.POILogger;
030:
031: public class FIBFieldHandler {
032: public static final int STSHFORIG = 0;
033: public static final int STSHF = 1;
034: public static final int PLCFFNDREF = 2;
035: public static final int PLCFFNDTXT = 3;
036: public static final int PLCFANDREF = 4;
037: public static final int PLCFANDTXT = 5;
038: public static final int PLCFSED = 6;
039: public static final int PLCFPAD = 7;
040: public static final int PLCFPHE = 8;
041: public static final int STTBGLSY = 9;
042: public static final int PLCFGLSY = 10;
043: public static final int PLCFHDD = 11;
044: public static final int PLCFBTECHPX = 12;
045: public static final int PLCFBTEPAPX = 13;
046: public static final int PLCFSEA = 14;
047: public static final int STTBFFFN = 15;
048: public static final int PLCFFLDMOM = 16;
049: public static final int PLCFFLDHDR = 17;
050: public static final int PLCFFLDFTN = 18;
051: public static final int PLCFFLDATN = 19;
052: public static final int PLCFFLDMCR = 20;
053: public static final int STTBFBKMK = 21;
054: public static final int PLCFBKF = 22;
055: public static final int PLCFBKL = 23;
056: public static final int CMDS = 24;
057: public static final int PLCMCR = 25;
058: public static final int STTBFMCR = 26;
059: public static final int PRDRVR = 27;
060: public static final int PRENVPORT = 28;
061: public static final int PRENVLAND = 29;
062: public static final int WSS = 30;
063: public static final int DOP = 31;
064: public static final int STTBFASSOC = 32;
065: public static final int CLX = 33;
066: public static final int PLCFPGDFTN = 34;
067: public static final int AUTOSAVESOURCE = 35;
068: public static final int GRPXSTATNOWNERS = 36;//validated
069: public static final int STTBFATNBKMK = 37;
070: public static final int PLCFDOAMOM = 38;
071: public static final int PLCDOAHDR = 39;
072: public static final int PLCSPAMOM = 40;
073: public static final int PLCSPAHDR = 41;
074: public static final int PLCFATNBKF = 42;
075: public static final int PLCFATNBKL = 43;
076: public static final int PMS = 44;
077: public static final int FORMFLDSTTBS = 45;
078: public static final int PLCFENDREF = 46;
079: public static final int PLCFENDTXT = 47;
080: public static final int PLCFFLDEDN = 48;
081: public static final int PLCFPGDEDN = 49;
082: public static final int DGGINFO = 50;
083: public static final int STTBFRMARK = 51;
084: public static final int STTBCAPTION = 52;
085: public static final int STTBAUTOCAPTION = 53;
086: public static final int PLCFWKB = 54;
087: public static final int PLCFSPL = 55;
088: public static final int PLCFTXBXTXT = 56;
089: public static final int PLCFFLDTXBX = 57;//validated
090: public static final int PLCFHDRTXBXTXT = 58;
091: public static final int PLCFFLDHDRTXBX = 59;
092: public static final int STWUSER = 60;
093: public static final int STTBTTMBD = 61;
094: public static final int UNUSED = 62;
095: public static final int PGDMOTHER = 63;
096: public static final int BKDMOTHER = 64;
097: public static final int PGDFTN = 65;
098: public static final int BKDFTN = 66;
099: public static final int PGDEDN = 67;
100: public static final int BKDEDN = 68;
101: public static final int STTBFINTFLD = 69;
102: public static final int ROUTESLIP = 70;
103: public static final int STTBSAVEDBY = 71;
104: public static final int STTBFNM = 72;
105: public static final int PLCFLST = 73;
106: public static final int PLFLFO = 74;
107: public static final int PLCFTXBXBKD = 75;//validated
108: public static final int PLCFTXBXHDRBKD = 76;
109: public static final int DOCUNDO = 77;
110: public static final int RGBUSE = 78;
111: public static final int USP = 79;
112: public static final int USKF = 80;
113: public static final int PLCUPCRGBUSE = 81;
114: public static final int PLCUPCUSP = 82;
115: public static final int STTBGLSYSTYLE = 83;
116: public static final int PLGOSL = 84;
117: public static final int PLCOCX = 85;
118: public static final int PLCFBTELVC = 86;
119: public static final int MODIFIED = 87;
120: public static final int PLCFLVC = 88;
121: public static final int PLCASUMY = 89;
122: public static final int PLCFGRAM = 90;
123: public static final int STTBLISTNAMES = 91;
124: public static final int STTBFUSSR = 92;
125:
126: private static POILogger log = POILogFactory
127: .getLogger(FIBFieldHandler.class);
128:
129: private static final int FIELD_SIZE = LittleEndian.INT_SIZE * 2;
130:
131: private HashMap _unknownMap = new HashMap();
132: private int[] _fields;
133:
134: public FIBFieldHandler(byte[] mainStream, int offset,
135: byte[] tableStream, HashSet offsetList, boolean areKnown) {
136: int numFields = LittleEndian.getShort(mainStream, offset);
137: offset += LittleEndian.SHORT_SIZE;
138: _fields = new int[numFields * 2];
139:
140: for (int x = 0; x < numFields; x++) {
141: int fieldOffset = (x * FIELD_SIZE) + offset;
142: int dsOffset = LittleEndian.getInt(mainStream, fieldOffset);
143: fieldOffset += LittleEndian.INT_SIZE;
144: int dsSize = LittleEndian.getInt(mainStream, fieldOffset);
145:
146: if (offsetList.contains(new Integer(x)) ^ areKnown) {
147: if (dsSize > 0) {
148: if (dsOffset + dsSize > tableStream.length) {
149: log.log(POILogger.WARN,
150: "Unhandled data structure points to outside the buffer. "
151: + "offset = " + dsOffset
152: + ", length = " + dsSize
153: + ", buffer length = "
154: + tableStream.length);
155: } else {
156: UnhandledDataStructure unhandled = new UnhandledDataStructure(
157: tableStream, dsOffset, dsSize);
158: _unknownMap.put(new Integer(x), unhandled);
159: }
160: }
161: }
162: _fields[x * 2] = dsOffset;
163: _fields[(x * 2) + 1] = dsSize;
164: }
165: }
166:
167: public void clearFields() {
168: Arrays.fill(_fields, 0);
169: }
170:
171: public int getFieldOffset(int field) {
172: return _fields[field * 2];
173: }
174:
175: public int getFieldSize(int field) {
176: return _fields[(field * 2) + 1];
177: }
178:
179: public void setFieldOffset(int field, int offset) {
180: _fields[field * 2] = offset;
181: }
182:
183: public void setFieldSize(int field, int size) {
184: _fields[(field * 2) + 1] = size;
185: }
186:
187: public int sizeInBytes() {
188: return (_fields.length * LittleEndian.INT_SIZE)
189: + LittleEndian.SHORT_SIZE;
190: }
191:
192: void writeTo(byte[] mainStream, int offset,
193: HWPFOutputStream tableStream) throws IOException {
194: int length = _fields.length / 2;
195: LittleEndian.putShort(mainStream, offset, (short) length);
196: offset += LittleEndian.SHORT_SIZE;
197:
198: for (int x = 0; x < length; x++) {
199: UnhandledDataStructure ds = (UnhandledDataStructure) _unknownMap
200: .get(new Integer(x));
201: if (ds != null) {
202: LittleEndian.putInt(mainStream, offset, tableStream
203: .getOffset());
204: offset += LittleEndian.INT_SIZE;
205: byte[] buf = ds.getBuf();
206: tableStream.write(buf);
207: LittleEndian.putInt(mainStream, offset, buf.length);
208: offset += LittleEndian.INT_SIZE;
209: } else {
210: LittleEndian.putInt(mainStream, offset, _fields[x * 2]);
211: offset += LittleEndian.INT_SIZE;
212: LittleEndian.putInt(mainStream, offset,
213: _fields[(x * 2) + 1]);
214: offset += LittleEndian.INT_SIZE;
215: }
216: }
217: }
218: }
|