/** * 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); } }
/** 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); }
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]); } }
/** 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())); }
/** * remove an entry * * @param entry to be removed */ void remove(EntryNode entry) { _property_table.removeProperty(entry.getProperty()); }
/** * Get the root entry * * @return the root entry */ public DirectoryNode getRoot() { if (_root == null) { _root = new DirectoryNode(_property_table.getRoot(), this, null); } return _root; }
/** * add a new DirectoryProperty to the FileSystem * * @param directory the DirectoryProperty being added */ void addDirectory(final DirectoryProperty directory) { _property_table.addProperty(directory); }
/** * add a new POIFSDocument to the FileSytem * * @param document the POIFSDocument being added */ void addDocument(final NPOIFSDocument document) { _property_table.addProperty(document.getDocumentProperty()); }