diff --git a/src/java/org/apache/poi/poifs/dev/POIFSHeaderDumper.java b/src/java/org/apache/poi/poifs/dev/POIFSHeaderDumper.java index 78ed986a4..7856015e7 100644 --- a/src/java/org/apache/poi/poifs/dev/POIFSHeaderDumper.java +++ b/src/java/org/apache/poi/poifs/dev/POIFSHeaderDumper.java @@ -24,9 +24,10 @@ import java.lang.reflect.Method; import org.apache.poi.poifs.common.POIFSBigBlockSize; import org.apache.poi.poifs.common.POIFSConstants; +import org.apache.poi.poifs.property.DirectoryProperty; +import org.apache.poi.poifs.property.Property; import org.apache.poi.poifs.property.PropertyTable; import org.apache.poi.poifs.storage.BlockAllocationTableReader; -import org.apache.poi.poifs.storage.BlockList; import org.apache.poi.poifs.storage.HeaderBlock; import org.apache.poi.poifs.storage.ListManagedBlock; import org.apache.poi.poifs.storage.RawDataBlockList; @@ -59,6 +60,7 @@ public class POIFSHeaderDumper { } public static void viewFile(final String filename) throws Exception { + System.out.println("Dumping headers from: " + filename); InputStream inp = new FileInputStream(filename); // Header @@ -79,18 +81,22 @@ public class POIFSHeaderDumper { header_block.getXBATCount(), header_block.getXBATIndex(), data_blocks); - displayBATReader(batReader); + displayBATReader("Big Blocks", batReader); // Properties Table PropertyTable properties = new PropertyTable(header_block, data_blocks); // Mini Fat - BlockList sbat = - SmallBlockTableReader.getSmallDocumentBlocks( + BlockAllocationTableReader sbatReader = + SmallBlockTableReader._getSmallDocumentBlockReader( bigBlockSize, data_blocks, properties.getRoot(), header_block.getSBATStart() ); + displayBATReader("Small Blocks", sbatReader); + + // Summary of the properties + displayPropertiesSummary(properties); } public static void displayHeader(HeaderBlock header_block) throws Exception { @@ -98,6 +104,8 @@ public class POIFSHeaderDumper { System.out.println(" Block size: " + header_block.getBigBlockSize().getBigBlockSize()); System.out.println(" BAT (FAT) header blocks: " + header_block.getBATArray().length); System.out.println(" BAT (FAT) block count: " + header_block.getBATCount()); + if (header_block.getBATCount() > 0) + System.out.println(" BAT (FAT) block 1 at: " + header_block.getBATArray()[0]); System.out.println(" XBAT (FAT) block count: " + header_block.getXBATCount()); System.out.println(" XBAT (FAT) block 1 at: " + header_block.getXBATIndex()); System.out.println(" SBAT (MiniFAT) block count: " + header_block.getSBATCount()); @@ -125,8 +133,8 @@ public class POIFSHeaderDumper { System.out.println(""); } - public static void displayBATReader(BlockAllocationTableReader batReader) throws Exception { - System.out.println("Sectors, as referenced from the FAT:"); + public static void displayBATReader(String type, BlockAllocationTableReader batReader) throws Exception { + System.out.println("Sectors, as referenced from the "+type+" FAT:"); Field entriesF = batReader.getClass().getDeclaredField("_entries"); entriesF.setAccessible(true); IntList entries = (IntList)entriesF.get(batReader); @@ -149,4 +157,24 @@ public class POIFSHeaderDumper { System.out.println(""); } + + public static void displayPropertiesSummary(PropertyTable properties) { + System.out.println("Properties and their block start:"); + displayProperties(properties.getRoot(), ""); + System.out.println(""); + } + public static void displayProperties(DirectoryProperty prop, String indent) { + indent = indent + " "; + System.out.println(prop.getName()); + for (Property cp : prop) { + if (cp instanceof DirectoryProperty) { + displayProperties((DirectoryProperty)cp, indent); + } else { + // TODO + if (cp.shouldUseSmallBlocks()) { + + } + } + } + } } diff --git a/src/java/org/apache/poi/poifs/storage/SmallBlockTableReader.java b/src/java/org/apache/poi/poifs/storage/SmallBlockTableReader.java index 8b6efd36e..2f9528318 100644 --- a/src/java/org/apache/poi/poifs/storage/SmallBlockTableReader.java +++ b/src/java/org/apache/poi/poifs/storage/SmallBlockTableReader.java @@ -25,13 +25,66 @@ import org.apache.poi.poifs.property.RootProperty; /** * This class implements reading the small document block list from an * existing file - * - * @author Marc Johnson (mjohnson at apache dot org) */ public final class SmallBlockTableReader { + private static BlockList prepareSmallDocumentBlocks( + final POIFSBigBlockSize bigBlockSize, + final RawDataBlockList blockList, final RootProperty root, + final int sbatStart) + throws IOException + { + // Fetch the blocks which hold the Small Blocks stream + ListManagedBlock [] smallBlockBlocks = + blockList.fetchBlocks(root.getStartBlock(), -1); + + // Turn that into a list + BlockList list =new SmallDocumentBlockList( + SmallDocumentBlock.extract(bigBlockSize, smallBlockBlocks)); + + return list; + } + private static BlockAllocationTableReader prepareReader( + final POIFSBigBlockSize bigBlockSize, + final RawDataBlockList blockList, final BlockList list, + final RootProperty root, final int sbatStart) + throws IOException + { + // Process the SBAT and blocks + return new BlockAllocationTableReader(bigBlockSize, + blockList.fetchBlocks(sbatStart, -1), + list); + } + + /** + * Fetch the small document block reader from an existing file, normally + * needed for debugging and low level dumping. You should typically call + * {@link #getSmallDocumentBlocks(POIFSBigBlockSize, RawDataBlockList, RootProperty, int)} + * instead. + * + * @param blockList the raw data from which the small block table + * will be extracted + * @param root the root property (which contains the start block + * and small block table size) + * @param sbatStart the start block of the SBAT + * + * @return the small document block reader + * + * @exception IOException + */ + public static BlockAllocationTableReader _getSmallDocumentBlockReader( + final POIFSBigBlockSize bigBlockSize, + final RawDataBlockList blockList, final RootProperty root, + final int sbatStart) + throws IOException + { + BlockList list = prepareSmallDocumentBlocks( + bigBlockSize, blockList, root, sbatStart); + return prepareReader( + bigBlockSize, blockList, list, root, sbatStart); + } /** - * fetch the small document block list from an existing file + * Fetch the small document block list from an existing file * * @param blockList the raw data from which the small block table * will be extracted @@ -49,18 +102,9 @@ public final class SmallBlockTableReader { final int sbatStart) throws IOException { - // Fetch the blocks which hold the Small Blocks stream - ListManagedBlock [] smallBlockBlocks = - blockList.fetchBlocks(root.getStartBlock(), -1); - - // Turn that into a list - BlockList list =new SmallDocumentBlockList( - SmallDocumentBlock.extract(bigBlockSize, smallBlockBlocks)); - - // Process - new BlockAllocationTableReader(bigBlockSize, - blockList.fetchBlocks(sbatStart, -1), - list); + BlockList list = prepareSmallDocumentBlocks( + bigBlockSize, blockList, root, sbatStart); + prepareReader(bigBlockSize, blockList, list, root, sbatStart); return list; } } diff --git a/test-data/openxml4j/sample.xlsx b/test-data/openxml4j/sample.xlsx index a275cf417..328a9e392 100644 Binary files a/test-data/openxml4j/sample.xlsx and b/test-data/openxml4j/sample.xlsx differ