loopDetector.claim(nextAt); ByteBuffer fatData = getBlockAt(nextAt); xfat = BATBlock.createBATBlock(bigBlockSize, fatData); xfat.setOurBlockIndex(nextAt); nextAt = xfat.getValueAt(bigBlockSize.getXBATEntriesPerBlock()); _xbat_blocks.add(xfat); int fatAt = xfat.getValueAt(j); if(fatAt == POIFSConstants.UNUSED_BLOCK || fatAt == POIFSConstants.END_OF_CHAIN) break; readBAT(fatAt, loopDetector); loopDetector.claim(nextAt); ByteBuffer fatData = getBlockAt(nextAt); sfat = BATBlock.createBATBlock(bigBlockSize, fatData); sfat.setOurBlockIndex(nextAt); sbats.add(sfat); nextAt = getNextBlock(nextAt);
/** * Returns the BATBlock that handles the specified offset, * and the relative index within it, for the mini stream. * The List of BATBlocks must be in sequential order */ public static BATBlockAndIndex getSBATBlockAndIndex(final int offset, final HeaderBlock header, final List<BATBlock> sbats) { return getBATBlockAndIndex(offset, header, sbats); }
/** * Create a single BATBlock from the byte buffer, which must hold at least * one big block of data to be read. */ public static BATBlock createBATBlock(final POIFSBigBlockSize bigBlockSize, ByteBuffer data) { // Create an empty block BATBlock block = new BATBlock(bigBlockSize); // Fill it byte[] buffer = new byte[LittleEndian.INT_SIZE]; for(int i=0; i<block._values.length; i++) { data.get(buffer); block._values[i] = LittleEndian.getInt(buffer); } block.recomputeFree(); // All done return block; }
private void readBAT(int batAt, ChainLoopDetector loopDetector) throws IOException { loopDetector.claim(batAt); ByteBuffer fatData = getBlockAt(batAt); BATBlock bat = BATBlock.createBATBlock(bigBlockSize, fatData); bat.setOurBlockIndex(batAt); _bat_blocks.add(bat); } private BATBlock createBAT(int offset, boolean isBAT) throws IOException {
private BATBlock createBAT(int offset, boolean isBAT) throws IOException { // Create a new BATBlock BATBlock newBAT = BATBlock.createEmptyBATBlock(bigBlockSize, !isBAT); newBAT.setOurBlockIndex(offset); // Ensure there's a spot in the file for it ByteBuffer buffer = ByteBuffer.allocate(bigBlockSize.getBigBlockSize()); int writeTo = (1+offset) * bigBlockSize.getBigBlockSize(); // Header isn't in BATs _data.write(buffer, writeTo); // All done return newBAT; }
for (BATBlock sbat : _sbat_blocks) { if (sbat.hasFreeSectors()) { int sbatValue = sbat.getValueAt(j); if (sbatValue == POIFSConstants.UNUSED_BLOCK) { BATBlock newSBAT = BATBlock.createEmptyBATBlock(_filesystem.getBigBlockSizeDetails(), false); int batForSBAT = _filesystem.getFreeBlock(); newSBAT.setOurBlockIndex(batForSBAT);
if(bat.hasFreeSectors()) { int batValue = bat.getValueAt(j); if(batValue == POIFSConstants.UNUSED_BLOCK) { bat.setValueAt(0, POIFSConstants.FAT_SECTOR_BLOCK); _bat_blocks.add(bat); if(x.hasFreeSectors()) { xbat = x; break; xbat.setValueAt(0, offset); bat.setValueAt(1, POIFSConstants.DIFAT_SECTOR_BLOCK); _header.setXBATStart(offset); } else { _xbat_blocks.get(_xbat_blocks.size()-1).setValueAt( bigBlockSize.getXBATEntriesPerBlock(), offset ); if(xbat.getValueAt(i) == POIFSConstants.UNUSED_BLOCK) { xbat.setValueAt(i, offset); break;
/** * Writes the SBATs to their backing blocks, and updates * the mini-stream size in the properties. Stream size is * based on full blocks used, not the data within the streams */ void syncWithDataSource() throws IOException { int blocksUsed = 0; for (BATBlock sbat : _sbat_blocks) { ByteBuffer block = _filesystem.getBlockAt(sbat.getOurBlockIndex()); sbat.writeData(block); if (!sbat.hasFreeSectors()) { blocksUsed += _filesystem.getBigBlockSizeDetails().getBATEntriesPerBlock(); } else { blocksUsed += sbat.getUsedSectors(false); } } // Set the size on the root in terms of the number of SBAT blocks // RootProperty.setSize does the sbat -> bytes conversion for us _filesystem._get_property_table().getRoot().setSize(blocksUsed); } }
/** * Works out what block follows the specified one. */ @Override protected int getNextBlock(final int offset) { BATBlockAndIndex bai = getBATBlockAndIndex(offset); return bai.getBlock().getValueAt( bai.getIndex() ); }
public static long calculateMaximumSize(final HeaderBlock header) { return calculateMaximumSize(header.getBigBlockSize(), header.getBATCount()); }
ByteBuffer block = getBlockAt(bat.getOurBlockIndex()); bat.writeData(block); ByteBuffer block = getBlockAt(bat.getOurBlockIndex()); bat.writeData(block);
calculateXBATStorageRequirements(bigBlockSize, entries.length); BATBlock[] blocks = new BATBlock[ block_count ]; int index = 0; new BATBlock(bigBlockSize, entries, j, (remaining > _entries_per_xbat_block) ? j + _entries_per_xbat_block blocks[ index ].setXBATChain(bigBlockSize, startBlock + index + 1); blocks[ index ].setXBATChain(bigBlockSize, POIFSConstants.END_OF_CHAIN);
/** * Creates a single BATBlock, with all the values set to empty. */ public static BATBlock createEmptyBATBlock(final POIFSBigBlockSize bigBlockSize, boolean isXBAT) { BATBlock block = new BATBlock(bigBlockSize); if(isXBAT) { block.setXBATChain(bigBlockSize, POIFSConstants.END_OF_CHAIN); } return block; }
/** * Create an array of BATBlocks from an array of int block * allocation table entries * * @param entries the array of int entries * * @return the newly created array of BATBlocks */ public static BATBlock [] createBATBlocks(final POIFSBigBlockSize bigBlockSize, final int [] entries) { int block_count = calculateStorageRequirements(bigBlockSize, entries.length); BATBlock[] blocks = new BATBlock[ block_count ]; int index = 0; int remaining = entries.length; int _entries_per_block = bigBlockSize.getBATEntriesPerBlock(); for (int j = 0; j < entries.length; j += _entries_per_block) { blocks[ index++ ] = new BATBlock(bigBlockSize, entries, j, (remaining > _entries_per_block) ? j + _entries_per_block : entries.length); remaining -= _entries_per_block; } return blocks; }
/** * Returns the BATBlock that handles the specified offset, * and the relative index within it */ protected BATBlockAndIndex getBATBlockAndIndex(final int offset) { return BATBlock.getSBATBlockAndIndex( offset, _header, _sbat_blocks ); }
/** * Writes the SBATs to their backing blocks */ protected void syncWithDataSource() throws IOException { for(BATBlock sbat : _sbat_blocks) { ByteBuffer block = _filesystem.getBlockAt(sbat.getOurBlockIndex()); BlockAllocationTableWriter.writeBlock(sbat, block); } } }
/** * Creates a single BATBlock, with all the values set to empty. */ public static BATBlock createEmptyBATBlock(final POIFSBigBlockSize bigBlockSize, boolean isXBAT) { BATBlock block = new BATBlock(bigBlockSize); if(isXBAT) { final int _entries_per_xbat_block = bigBlockSize.getXBATEntriesPerBlock(); block._values[ _entries_per_xbat_block ] = POIFSConstants.END_OF_CHAIN; } return block; }
/** * 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); }
if(sbat.hasFreeSectors()) { int sbatValue = sbat.getValueAt(j); if(sbatValue == POIFSConstants.UNUSED_BLOCK) { BATBlock newSBAT = BATBlock.createEmptyBATBlock(_filesystem.getBigBlockSizeDetails(), false); int batForSBAT = _filesystem.getFreeBlock(); newSBAT.setOurBlockIndex(batForSBAT);
if(bat.hasFreeSectors()) { int batValue = bat.getValueAt(j); if(batValue == POIFSConstants.UNUSED_BLOCK) { bat.setValueAt(0, POIFSConstants.FAT_SECTOR_BLOCK); _bat_blocks.add(bat); if(x.hasFreeSectors()) { xbat = x; break; xbat.setValueAt(0, offset); bat.setValueAt(1, POIFSConstants.DIFAT_SECTOR_BLOCK); _header.setXBATStart(offset); } else { _xbat_blocks.get(_xbat_blocks.size()-1).setValueAt( bigBlockSize.getXBATEntriesPerBlock(), offset ); if(xbat.getValueAt(i) == POIFSConstants.UNUSED_BLOCK) { xbat.setValueAt(i, offset); break;