Refactor the small block reader creation, so that POIFSHeaderDumper can dump the sbat structure too

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1688030 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Nick Burch 2015-06-28 17:53:24 +00:00
parent 1b1d5835b6
commit 2362cacb3e
3 changed files with 93 additions and 21 deletions

View File

@ -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()) {
}
}
}
}
}

View File

@ -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;
}
}

Binary file not shown.