示例#1
0
  /**
   * Read and process the PropertiesTable and the FAT / XFAT blocks, so that we're ready to work
   * with the file
   */
  private void readCoreContents() throws IOException {
    // Grab the block size
    bigBlockSize = _header.getBigBlockSize();

    // Each block should only ever be used by one of the
    //  FAT, XFAT or Property Table. Ensure it does
    ChainLoopDetector loopDetector = getChainLoopDetector();

    // Read the FAT blocks
    for (int fatAt : _header.getBATArray()) {
      readBAT(fatAt, loopDetector);
    }

    // Work out how many FAT blocks remain in the XFATs
    int remainingFATs = _header.getBATCount() - _header.getBATArray().length;

    // Now read the XFAT blocks, and the FATs within them
    BATBlock xfat;
    int nextAt = _header.getXBATIndex();
    for (int i = 0; i < _header.getXBATCount(); i++) {
      loopDetector.claim(nextAt);
      ByteBuffer fatData = getBlockAt(nextAt);
      xfat = BATBlock.createBATBlock(bigBlockSize, fatData);
      xfat.setOurBlockIndex(nextAt);
      nextAt = xfat.getValueAt(bigBlockSize.getXBATEntriesPerBlock());
      _xbat_blocks.add(xfat);

      // Process all the (used) FATs from this XFAT
      int xbatFATs = Math.min(remainingFATs, bigBlockSize.getXBATEntriesPerBlock());
      for (int j = 0; j < xbatFATs; j++) {
        int fatAt = xfat.getValueAt(j);
        if (fatAt == POIFSConstants.UNUSED_BLOCK || fatAt == POIFSConstants.END_OF_CHAIN) break;
        readBAT(fatAt, loopDetector);
      }
      remainingFATs -= xbatFATs;
    }

    // We're now able to load steams
    // Use this to read in the properties
    _property_table = new NPropertyTable(_header, this);

    // Finally read the Small Stream FAT (SBAT) blocks
    BATBlock sfat;
    List<BATBlock> sbats = new ArrayList<BATBlock>();
    _mini_store = new NPOIFSMiniStore(this, _property_table.getRoot(), sbats, _header);
    nextAt = _header.getSBATStart();
    for (int i = 0; i < _header.getSBATCount(); i++) {
      loopDetector.claim(nextAt);
      ByteBuffer fatData = getBlockAt(nextAt);
      sfat = BATBlock.createBATBlock(bigBlockSize, fatData);
      sfat.setOurBlockIndex(nextAt);
      sbats.add(sfat);
      nextAt = getNextBlock(nextAt);
    }
  }
示例#2
0
  /** Constructor, intended for writing */
  public NPOIFSFileSystem() {
    this(true);

    // Mark us as having a single empty BAT at offset 0
    _header.setBATCount(1);
    _header.setBATArray(new int[] {0});
    _bat_blocks.add(BATBlock.createEmptyBATBlock(bigBlockSize, false));
    setNextBlock(0, POIFSConstants.FAT_SECTOR_BLOCK);

    // Now associate the properties with the empty block
    _property_table.setStartBlock(1);
    setNextBlock(1, POIFSConstants.END_OF_CHAIN);
  }
示例#3
0
  private NPOIFSFileSystem(boolean newFS) {
    _header = new HeaderBlock(bigBlockSize);
    _property_table = new NPropertyTable(_header);
    _mini_store =
        new NPOIFSMiniStore(this, _property_table.getRoot(), new ArrayList<BATBlock>(), _header);
    _xbat_blocks = new ArrayList<BATBlock>();
    _bat_blocks = new ArrayList<BATBlock>();
    _root = null;

    if (newFS) {
      // Data needs to initially hold just the header block,
      //  a single bat block, and an empty properties section
      _data = new ByteArrayBackedDataSource(new byte[bigBlockSize.getBigBlockSize() * 3]);
    }
  }
示例#4
0
  /** Has our in-memory objects write their state to their backing blocks */
  private void syncWithDataSource() throws IOException {
    // HeaderBlock
    HeaderBlockWriter hbw = new HeaderBlockWriter(_header);
    hbw.writeBlock(getBlockAt(-1));

    // BATs
    for (BATBlock bat : _bat_blocks) {
      ByteBuffer block = getBlockAt(bat.getOurBlockIndex());
      BlockAllocationTableWriter.writeBlock(bat, block);
    }

    // SBATs
    _mini_store.syncWithDataSource();

    // Properties
    _property_table.write(new NPOIFSStream(this, _header.getPropertyStart()));
  }
示例#5
0
 /**
  * remove an entry
  *
  * @param entry to be removed
  */
 void remove(EntryNode entry) {
   _property_table.removeProperty(entry.getProperty());
 }
示例#6
0
 /**
  * Get the root entry
  *
  * @return the root entry
  */
 public DirectoryNode getRoot() {
   if (_root == null) {
     _root = new DirectoryNode(_property_table.getRoot(), this, null);
   }
   return _root;
 }
示例#7
0
 /**
  * add a new DirectoryProperty to the FileSystem
  *
  * @param directory the DirectoryProperty being added
  */
 void addDirectory(final DirectoryProperty directory) {
   _property_table.addProperty(directory);
 }
示例#8
0
 /**
  * add a new POIFSDocument to the FileSytem
  *
  * @param document the POIFSDocument being added
  */
 void addDocument(final NPOIFSDocument document) {
   _property_table.addProperty(document.getDocumentProperty());
 }