1 2 17 18 package org.apache.poi.hwpf.model; 19 20 import org.apache.poi.poifs.common.POIFSConstants; 21 import org.apache.poi.util.LittleEndian; 22 23 import java.util.ArrayList ; 24 import java.util.List ; 25 import java.util.Arrays ; 26 27 43 public class PAPFormattedDiskPage extends FormattedDiskPage 44 { 45 46 private static final int BX_SIZE = 13; 47 private static final int FC_SIZE = 4; 48 49 private ArrayList _papxList = new ArrayList (); 50 private ArrayList _overFlow; 51 private byte[] _dataStream; 52 53 54 public PAPFormattedDiskPage(byte[] dataStream) 55 { 56 _dataStream = dataStream; 57 } 58 59 62 public PAPFormattedDiskPage(byte[] documentStream, byte[] dataStream, int offset, int fcMin) 63 { 64 super(documentStream, offset); 65 66 for (int x = 0; x < _crun; x++) 67 { 68 _papxList.add(new PAPX(getStart(x) - fcMin, getEnd(x) - fcMin, getGrpprl(x), getParagraphHeight(x), dataStream)); 69 } 70 _fkp = null; 71 _dataStream = dataStream; 72 } 73 74 79 public void fill(List filler) 80 { 81 _papxList.addAll(filler); 82 } 83 84 96 ArrayList getOverflow() 97 { 98 return _overFlow; 99 } 100 101 106 public PAPX getPAPX(int index) 107 { 108 return (PAPX)_papxList.get(index); 109 } 110 111 117 protected byte[] getGrpprl(int index) 118 { 119 int papxOffset = 2 * LittleEndian.getUnsignedByte(_fkp, _offset + (((_crun + 1) * FC_SIZE) + (index * BX_SIZE))); 120 int size = 2 * LittleEndian.getUnsignedByte(_fkp, _offset + papxOffset); 121 if(size == 0) 122 { 123 size = 2 * LittleEndian.getUnsignedByte(_fkp, _offset + ++papxOffset); 124 } 125 else 126 { 127 size--; 128 } 129 130 byte[] papx = new byte[size]; 131 System.arraycopy(_fkp, _offset + ++papxOffset, papx, 0, size); 132 return papx; 133 } 134 135 142 protected byte[] toByteArray(int fcMin) 143 { 144 byte[] buf = new byte[512]; 145 int size = _papxList.size(); 146 int grpprlOffset = 0; 147 int bxOffset = 0; 148 int fcOffset = 0; 149 byte[] lastGrpprl = new byte[0]; 150 151 int totalSize = FC_SIZE; 153 154 int index = 0; 155 for (; index < size; index++) 156 { 157 byte[] grpprl = ((PAPX)_papxList.get(index)).getGrpprl(); 158 int grpprlLength = grpprl.length; 159 160 if(grpprlLength > 488) 162 { 163 grpprlLength = 8; } 165 166 int addition = 0; 169 if (!Arrays.equals(grpprl, lastGrpprl)) 170 { 171 addition = (FC_SIZE + BX_SIZE + grpprlLength + 1); 172 } 173 else 174 { 175 addition = (FC_SIZE + BX_SIZE); 176 } 177 178 totalSize += addition; 179 180 if (totalSize > 511 + (index % 2)) 183 { 184 totalSize -= addition; 185 break; 186 } 187 188 if (grpprlLength % 2 > 0) 190 { 191 totalSize += 1; 192 } 193 else 194 { 195 totalSize += 2; 196 } 197 lastGrpprl = grpprl; 198 } 199 200 if (index != size) 202 { 203 _overFlow = new ArrayList (); 204 _overFlow.addAll(_papxList.subList(index, size)); 205 } 206 207 buf[511] = (byte)index; 209 210 bxOffset = (FC_SIZE * index) + FC_SIZE; 211 grpprlOffset = 511; 212 213 PAPX papx = null; 214 lastGrpprl = new byte[0]; 215 for (int x = 0; x < index; x++) 216 { 217 papx = (PAPX)_papxList.get(x); 218 byte[] phe = papx.getParagraphHeight().toByteArray(); 219 byte[] grpprl = papx.getGrpprl(); 220 221 if(grpprl.length > 488) 223 { 224 int hugeGrpprlOffset = papx.getHugeGrpprlOffset(); 226 if(hugeGrpprlOffset == -1) { 228 throw new UnsupportedOperationException ( 229 "This Paragraph has no dataStream storage."); 230 } 231 else { 233 int maxHugeGrpprlSize = LittleEndian.getUShort(_dataStream, 235 hugeGrpprlOffset); 236 237 if (maxHugeGrpprlSize < grpprl.length-2) throw new UnsupportedOperationException ( 239 "This Paragraph's dataStream storage is too small."); 240 } 241 242 System.arraycopy(grpprl, 2, _dataStream, hugeGrpprlOffset + 2, 244 grpprl.length - 2); LittleEndian.putUShort(_dataStream, hugeGrpprlOffset, grpprl.length - 2); 246 247 int istd = LittleEndian.getUShort(grpprl, 0); 249 grpprl = new byte[8]; 250 LittleEndian.putUShort(grpprl, 0, istd); 251 LittleEndian.putUShort(grpprl, 2, 0x6646); LittleEndian.putInt(grpprl, 4, hugeGrpprlOffset); 253 } 254 255 boolean same = Arrays.equals(lastGrpprl, grpprl); 256 if (!same) 257 { 258 grpprlOffset -= (grpprl.length + (2 - grpprl.length % 2)); 259 grpprlOffset -= (grpprlOffset % 2); 260 } 261 LittleEndian.putInt(buf, fcOffset, papx.getStart() + fcMin); 262 buf[bxOffset] = (byte)(grpprlOffset/2); 263 System.arraycopy(phe, 0, buf, bxOffset + 1, phe.length); 264 265 if (!same) 269 { 270 int copyOffset = grpprlOffset; 271 if ( (grpprl.length % 2) > 0) 272 { 273 buf[copyOffset++] = (byte) ( (grpprl.length + 1) / 2); 274 } 275 else 276 { 277 buf[++copyOffset] = (byte) ( (grpprl.length) / 2); 278 copyOffset++; 279 } 280 System.arraycopy(grpprl, 0, buf, copyOffset, grpprl.length); 281 lastGrpprl = grpprl; 282 } 283 284 bxOffset += BX_SIZE; 285 fcOffset += FC_SIZE; 286 287 } 288 289 LittleEndian.putInt(buf, fcOffset, papx.getEnd() + fcMin); 290 return buf; 291 } 292 293 298 private ParagraphHeight getParagraphHeight(int index) 299 { 300 int pheOffset = _offset + 1 + (((_crun + 1) * 4) + (index * 13)); 301 302 ParagraphHeight phe = new ParagraphHeight(_fkp, pheOffset); 303 304 return phe; 305 } 306 } 307 | Popular Tags |