From d6578850ab9a4e7bbafb6eff103dea2f10af735e Mon Sep 17 00:00:00 2001 From: Nick Burch Date: Wed, 29 Dec 2010 01:05:01 +0000 Subject: XBAT logic in NPOIFS was incorrect - it's a chain of doubly indirect, not singly indirect BATs. Start to correct git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1053495 13f79535-47bb-0310-9956-ffa450edef68 --- .../poi/poifs/filesystem/NDocumentInputStream.java | 2 - .../poi/poifs/filesystem/NPOIFSFileSystem.java | 24 +++++++---- .../org/apache/poi/poifs/storage/BATBlock.java | 48 +++++++++++----------- 3 files changed, 42 insertions(+), 32 deletions(-) (limited to 'src/java') diff --git a/src/java/org/apache/poi/poifs/filesystem/NDocumentInputStream.java b/src/java/org/apache/poi/poifs/filesystem/NDocumentInputStream.java index 52c06f808b..2595ba0259 100644 --- a/src/java/org/apache/poi/poifs/filesystem/NDocumentInputStream.java +++ b/src/java/org/apache/poi/poifs/filesystem/NDocumentInputStream.java @@ -29,8 +29,6 @@ import org.apache.poi.util.LittleEndianInput; /** * This class provides methods to read a DocumentEntry managed by a * {@link POIFSFileSystem} instance. - * - * @author Marc Johnson (mjohnson at apache dot org) */ public final class NDocumentInputStream extends InputStream implements LittleEndianInput { /** returned by read operations if we're at end of document */ diff --git a/src/java/org/apache/poi/poifs/filesystem/NPOIFSFileSystem.java b/src/java/org/apache/poi/poifs/filesystem/NPOIFSFileSystem.java index a397136c20..9f491313ec 100644 --- a/src/java/org/apache/poi/poifs/filesystem/NPOIFSFileSystem.java +++ b/src/java/org/apache/poi/poifs/filesystem/NPOIFSFileSystem.java @@ -77,6 +77,7 @@ public class NPOIFSFileSystem extends BlockStore private NPOIFSMiniStore _mini_store; private NPropertyTable _property_table; + private List _xbat_blocks; private List _bat_blocks; private HeaderBlock _header; private DirectoryNode _root; @@ -98,6 +99,7 @@ public class NPOIFSFileSystem extends BlockStore _header = new HeaderBlock(bigBlockSize); _property_table = new NPropertyTable(_header); _mini_store = new NPOIFSMiniStore(this, _property_table.getRoot(), new ArrayList(), _header); + _xbat_blocks = new ArrayList(); _bat_blocks = new ArrayList(); _root = null; } @@ -264,14 +266,10 @@ public class NPOIFSFileSystem extends BlockStore // Read the FAT blocks for(int fatAt : _header.getBATArray()) { - loopDetector.claim(fatAt); - ByteBuffer fatData = getBlockAt(fatAt); - BATBlock bat = BATBlock.createBATBlock(bigBlockSize, fatData); - bat.setOurBlockIndex(fatAt); - _bat_blocks.add(bat); + readBAT(fatAt, loopDetector); } - // Now read the XFAT blocks + // Now read the XFAT blocks, and the FATs within them BATBlock xfat; int nextAt = _header.getXBATIndex(); for(int i=0; i<_header.getXBATCount(); i++) { @@ -280,8 +278,13 @@ public class NPOIFSFileSystem extends BlockStore xfat = BATBlock.createBATBlock(bigBlockSize, fatData); xfat.setOurBlockIndex(nextAt); nextAt = xfat.getValueAt(bigBlockSize.getXBATEntriesPerBlock()); + _xbat_blocks.add(xfat); - _bat_blocks.add(xfat); + for(int j=0; j bats) { POIFSBigBlockSize bigBlockSize = header.getBigBlockSize(); - // Are we in the BAT or XBAT range - int batRangeEndsAt = bigBlockSize.getBATEntriesPerBlock() * - header.getBATCount(); - - if(offset < batRangeEndsAt) { - int whichBAT = (int)Math.floor(offset / bigBlockSize.getBATEntriesPerBlock()); - int index = offset % bigBlockSize.getBATEntriesPerBlock(); - return new BATBlockAndIndex( index, bats.get(whichBAT) ); - } - - // XBATs hold slightly less - int relOffset = offset - batRangeEndsAt; - int whichXBAT = (int)Math.floor(relOffset / bigBlockSize.getXBATEntriesPerBlock()); - int index = relOffset % bigBlockSize.getXBATEntriesPerBlock(); - return new BATBlockAndIndex( - index, - bats.get(header.getBATCount() + whichXBAT) - ); + int whichBAT = (int)Math.floor(offset / bigBlockSize.getBATEntriesPerBlock()); + int index = offset % bigBlockSize.getBATEntriesPerBlock(); + return new BATBlockAndIndex( index, bats.get(whichBAT) ); } /** -- cgit v1.2.3