1 2 17 18 19 package org.apache.poi.poifs.filesystem; 20 21 import java.io.*; 22 23 import java.util.*; 24 25 import org.apache.poi.poifs.common.POIFSConstants; 26 import org.apache.poi.poifs.dev.POIFSViewable; 27 import org.apache.poi.poifs.property.DocumentProperty; 28 import org.apache.poi.poifs.property.Property; 29 import org.apache.poi.poifs.storage.BlockWritable; 30 import org.apache.poi.poifs.storage.ListManagedBlock; 31 import org.apache.poi.poifs.storage.DocumentBlock; 32 import org.apache.poi.poifs.storage.RawDataBlock; 33 import org.apache.poi.poifs.storage.SmallDocumentBlock; 34 import org.apache.poi.util.HexDump; 35 36 41 42 public class POIFSDocument 43 implements BATManaged, BlockWritable, POIFSViewable 44 { 45 private DocumentProperty _property; 46 private int _size; 47 48 private SmallBlockStore _small_store; 50 private BigBlockStore _big_store; 51 52 61 62 public POIFSDocument(final String name, final RawDataBlock [] blocks, 63 final int length) 64 throws IOException 65 { 66 _size = length; 67 _big_store = new BigBlockStore(blocks); 68 _property = new DocumentProperty(name, _size); 69 _small_store = new SmallBlockStore(new BlockWritable[ 0 ]); 70 _property.setDocument(this); 71 } 72 73 80 81 public POIFSDocument(final String name, 82 final SmallDocumentBlock [] blocks, final int length) 83 { 84 _size = length; 85 try 86 { 87 _big_store = new BigBlockStore(new RawDataBlock[ 0 ]); 88 } 89 catch (IOException ignored) 90 { 91 92 } 94 _property = new DocumentProperty(name, _size); 95 _small_store = new SmallBlockStore(blocks); 96 _property.setDocument(this); 97 } 98 99 108 109 public POIFSDocument(final String name, final ListManagedBlock [] blocks, 110 final int length) 111 throws IOException 112 { 113 _size = length; 114 _property = new DocumentProperty(name, _size); 115 _property.setDocument(this); 116 if (Property.isSmall(_size)) 117 { 118 _big_store = new BigBlockStore(new RawDataBlock[ 0 ]); 119 _small_store = new SmallBlockStore(blocks); 120 } 121 else 122 { 123 _big_store = new BigBlockStore(blocks); 124 _small_store = new SmallBlockStore(new BlockWritable[ 0 ]); 125 } 126 } 127 128 136 137 public POIFSDocument(final String name, final InputStream stream) 138 throws IOException 139 { 140 List blocks = new ArrayList(); 141 142 _size = 0; 143 while (true) 144 { 145 DocumentBlock block = new DocumentBlock(stream); 146 int blockSize = block.size(); 147 148 if (blockSize > 0) 149 { 150 blocks.add(block); 151 _size += blockSize; 152 } 153 if (block.partiallyRead()) 154 { 155 break; 156 } 157 } 158 DocumentBlock[] bigBlocks = 159 ( DocumentBlock [] ) blocks.toArray(new DocumentBlock[ 0 ]); 160 161 _big_store = new BigBlockStore(bigBlocks); 162 _property = new DocumentProperty(name, _size); 163 _property.setDocument(this); 164 if (_property.shouldUseSmallBlocks()) 165 { 166 _small_store = 167 new SmallBlockStore(SmallDocumentBlock.convert(bigBlocks, 168 _size)); 169 _big_store = new BigBlockStore(new DocumentBlock[ 0 ]); 170 } 171 else 172 { 173 _small_store = new SmallBlockStore(new BlockWritable[ 0 ]); 174 } 175 } 176 177 188 189 public POIFSDocument(final String name, final int size, 190 final POIFSDocumentPath path, 191 final POIFSWriterListener writer) 192 throws IOException 193 { 194 _size = size; 195 _property = new DocumentProperty(name, _size); 196 _property.setDocument(this); 197 if (_property.shouldUseSmallBlocks()) 198 { 199 _small_store = new SmallBlockStore(path, name, size, writer); 200 _big_store = new BigBlockStore(new Object [ 0 ]); 201 } 202 else 203 { 204 _small_store = new SmallBlockStore(new BlockWritable[ 0 ]); 205 _big_store = new BigBlockStore(path, name, size, writer); 206 } 207 } 208 209 214 215 public BlockWritable [] getSmallBlocks() 216 { 217 return _small_store.getBlocks(); 218 } 219 220 223 224 public int getSize() 225 { 226 return _size; 227 } 228 229 235 236 void read(final byte [] buffer, final int offset) 237 { 238 if (_property.shouldUseSmallBlocks()) 239 { 240 SmallDocumentBlock.read(_small_store.getBlocks(), buffer, offset); 241 } 242 else 243 { 244 DocumentBlock.read(_big_store.getBlocks(), buffer, offset); 245 } 246 } 247 248 253 254 DocumentProperty getDocumentProperty() 255 { 256 return _property; 257 } 258 259 260 261 270 271 public void writeBlocks(final OutputStream stream) 272 throws IOException 273 { 274 _big_store.writeBlocks(stream); 275 } 276 277 278 279 280 285 286 public int countBlocks() 287 { 288 return _big_store.countBlocks(); 289 } 290 291 297 298 public void setStartBlock(final int index) 299 { 300 _property.setStartBlock(index); 301 } 302 303 304 305 306 312 313 public Object [] getViewableArray() 314 { 315 Object [] results = new Object [ 1 ]; 316 String result; 317 318 try 319 { 320 ByteArrayOutputStream output = new ByteArrayOutputStream(); 321 BlockWritable[] blocks = null; 322 323 if (_big_store.isValid()) 324 { 325 blocks = _big_store.getBlocks(); 326 } 327 else if (_small_store.isValid()) 328 { 329 blocks = _small_store.getBlocks(); 330 } 331 if (blocks != null) 332 { 333 for (int k = 0; k < blocks.length; k++) 334 { 335 blocks[ k ].writeBlocks(output); 336 } 337 byte[] data = output.toByteArray(); 338 339 if (data.length > _property.getSize()) 340 { 341 byte[] tmp = new byte[ _property.getSize() ]; 342 343 System.arraycopy(data, 0, tmp, 0, tmp.length); 344 data = tmp; 345 } 346 output = new ByteArrayOutputStream(); 347 HexDump.dump(data, 0, output, 0); 348 result = output.toString(); 349 } 350 else 351 { 352 result = "<NO DATA>"; 353 } 354 } 355 catch (IOException e) 356 { 357 result = e.getMessage(); 358 } 359 results[ 0 ] = result; 360 return results; 361 } 362 363 370 371 public Iterator getViewableIterator() 372 { 373 return Collections.EMPTY_LIST.iterator(); 374 } 375 376 383 384 public boolean preferArray() 385 { 386 return true; 387 } 388 389 395 396 public String getShortDescription() 397 { 398 StringBuffer buffer = new StringBuffer (); 399 400 buffer.append("Document: \"").append(_property.getName()) 401 .append("\""); 402 buffer.append(" size = ").append(getSize()); 403 return buffer.toString(); 404 } 405 406 407 private class SmallBlockStore 408 { 409 private SmallDocumentBlock[] smallBlocks; 410 private POIFSDocumentPath path; 411 private String name; 412 private int size; 413 private POIFSWriterListener writer; 414 415 420 421 SmallBlockStore(final Object [] blocks) 422 { 423 smallBlocks = new SmallDocumentBlock[ blocks.length ]; 424 for (int j = 0; j < blocks.length; j++) 425 { 426 smallBlocks[ j ] = ( SmallDocumentBlock ) blocks[ j ]; 427 } 428 this.path = null; 429 this.name = null; 430 this.size = -1; 431 this.writer = null; 432 } 433 434 443 444 SmallBlockStore(final POIFSDocumentPath path, final String name, 445 final int size, final POIFSWriterListener writer) 446 { 447 smallBlocks = new SmallDocumentBlock[ 0 ]; 448 this.path = path; 449 this.name = name; 450 this.size = size; 451 this.writer = writer; 452 } 453 454 457 458 boolean isValid() 459 { 460 return ((smallBlocks.length > 0) || (writer != null)); 461 } 462 463 466 467 BlockWritable [] getBlocks() 468 { 469 if (isValid() && (writer != null)) 470 { 471 ByteArrayOutputStream stream = 472 new ByteArrayOutputStream(size); 473 DocumentOutputStream dstream = 474 new DocumentOutputStream(stream, size); 475 476 writer.processPOIFSWriterEvent(new POIFSWriterEvent(dstream, 477 path, name, size)); 478 smallBlocks = SmallDocumentBlock.convert(stream.toByteArray(), 479 size); 480 } 481 return smallBlocks; 482 } 483 } 485 private class BigBlockStore 486 { 487 private DocumentBlock[] bigBlocks; 488 private POIFSDocumentPath path; 489 private String name; 490 private int size; 491 private POIFSWriterListener writer; 492 493 500 501 BigBlockStore(final Object [] blocks) 502 throws IOException 503 { 504 bigBlocks = new DocumentBlock[ blocks.length ]; 505 for (int j = 0; j < blocks.length; j++) 506 { 507 if (blocks[ j ] instanceof DocumentBlock) 508 { 509 bigBlocks[ j ] = ( DocumentBlock ) blocks[ j ]; 510 } 511 else 512 { 513 bigBlocks[ j ] = 514 new DocumentBlock(( RawDataBlock ) blocks[ j ]); 515 } 516 } 517 this.path = null; 518 this.name = null; 519 this.size = -1; 520 this.writer = null; 521 } 522 523 533 534 BigBlockStore(final POIFSDocumentPath path, final String name, 535 final int size, final POIFSWriterListener writer) 536 { 537 bigBlocks = new DocumentBlock[ 0 ]; 538 this.path = path; 539 this.name = name; 540 this.size = size; 541 this.writer = writer; 542 } 543 544 547 548 boolean isValid() 549 { 550 return ((bigBlocks.length > 0) || (writer != null)); 551 } 552 553 556 557 DocumentBlock [] getBlocks() 558 { 559 if (isValid() && (writer != null)) 560 { 561 ByteArrayOutputStream stream = 562 new ByteArrayOutputStream(size); 563 DocumentOutputStream dstream = 564 new DocumentOutputStream(stream, size); 565 566 writer.processPOIFSWriterEvent(new POIFSWriterEvent(dstream, 567 path, name, size)); 568 bigBlocks = DocumentBlock.convert(stream.toByteArray(), size); 569 } 570 return bigBlocks; 571 } 572 573 580 581 void writeBlocks(OutputStream stream) 582 throws IOException 583 { 584 if (isValid()) 585 { 586 if (writer != null) 587 { 588 DocumentOutputStream dstream = 589 new DocumentOutputStream(stream, size); 590 591 writer.processPOIFSWriterEvent( 592 new POIFSWriterEvent(dstream, path, name, size)); 593 dstream.writeFiller(countBlocks() 594 * POIFSConstants 595 .BIG_BLOCK_SIZE, DocumentBlock 596 .getFillByte()); 597 } 598 else 599 { 600 for (int k = 0; k < bigBlocks.length; k++) 601 { 602 bigBlocks[ k ].writeBlocks(stream); 603 } 604 } 605 } 606 } 607 608 611 612 int countBlocks() 613 { 614 int rval = 0; 615 616 if (isValid()) 617 { 618 if (writer != null) 619 { 620 rval = (size + POIFSConstants.BIG_BLOCK_SIZE - 1) 621 / POIFSConstants.BIG_BLOCK_SIZE; 622 } 623 else 624 { 625 rval = bigBlocks.length; 626 } 627 } 628 return rval; 629 } 630 } } 633 | Popular Tags |