diff options
author | Nick Burch <nick@apache.org> | 2010-12-29 01:34:56 +0000 |
---|---|---|
committer | Nick Burch <nick@apache.org> | 2010-12-29 01:34:56 +0000 |
commit | ada898d0cf1ac89a05e4b65897c5e47c0f15774c (patch) | |
tree | c2fdfdf469e8e0fb91ed92ff38b8c9aefaa832ce /src/java/org/apache | |
parent | 628081356ee489554823252627903e889babd659 (diff) | |
download | poi-ada898d0cf1ac89a05e4b65897c5e47c0f15774c.tar.gz poi-ada898d0cf1ac89a05e4b65897c5e47c0f15774c.zip |
More NPOIFS XBAT updates
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1053504 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/java/org/apache')
-rw-r--r-- | src/java/org/apache/poi/poifs/filesystem/NPOIFSFileSystem.java | 96 |
1 files changed, 55 insertions, 41 deletions
diff --git a/src/java/org/apache/poi/poifs/filesystem/NPOIFSFileSystem.java b/src/java/org/apache/poi/poifs/filesystem/NPOIFSFileSystem.java index 9f491313ec..6cc5730164 100644 --- a/src/java/org/apache/poi/poifs/filesystem/NPOIFSFileSystem.java +++ b/src/java/org/apache/poi/poifs/filesystem/NPOIFSFileSystem.java @@ -312,6 +312,17 @@ public class NPOIFSFileSystem extends BlockStore bat.setOurBlockIndex(batAt); _bat_blocks.add(bat); } + 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; + } /** * Load the block at the given offset. @@ -377,12 +388,7 @@ public class NPOIFSFileSystem extends BlockStore // First up, do we have any spare ones? int offset = 0; for(int i=0; i<_bat_blocks.size(); i++) { - boolean isXBAT = (i >= _header.getBATCount()); - int numSectors = bigBlockSize.getBATEntriesPerBlock(); - if(isXBAT) { - numSectors = bigBlockSize.getXBATEntriesPerBlock(); - } // Check this one BATBlock bat = _bat_blocks.get(i); @@ -397,54 +403,62 @@ public class NPOIFSFileSystem extends BlockStore } } - // Move onto the next BAT/XBAT + // Move onto the next BAT offset += numSectors; } - // If we get here, then there aren't any - // free sectors in any of the BATs or XBATs - // So, we need to extend the file and add another - boolean isBAT = true; - if(_header.getBATCount() >= 109) { - isBAT = false; - } - - // 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); + // If we get here, then there aren't any free sectors + // in any of the BATs, so we need another BAT + BATBlock bat = createBAT(offset, true); + bat.setValueAt(0, POIFSConstants.FAT_SECTOR_BLOCK); + _bat_blocks.add(bat); - // Allocate ourself within ourselves, at the first point - if(isBAT) { - newBAT.setValueAt(0, POIFSConstants.FAT_SECTOR_BLOCK); + // Now store a reference to the BAT in the required place + if(_header.getBATCount() >= 109) { + // Needs to come from an XBAT + BATBlock xbat = null; + for(BATBlock x : _xbat_blocks) { + if(x.hasFreeSectors()) { + xbat = x; + break; + } + } + if(xbat == null) { + // Oh joy, we need a new XBAT too... + xbat = createBAT(offset+1, false); + xbat.setValueAt(0, offset); + bat.setValueAt(offset+1, POIFSConstants.DIFAT_SECTOR_BLOCK); + + // Will go one place higher as XBAT added in + offset++; + + // Chain it + if(_xbat_blocks.size() == 0) { + _header.setXBATStart(offset); + } else { + _xbat_blocks.get(_xbat_blocks.size()-1).setValueAt( + bigBlockSize.getXBATEntriesPerBlock(), offset + ); + } + _xbat_blocks.add(xbat); + _header.setXBATCount(_xbat_blocks.size()); + } + // Allocate us in the XBAT + for(int i=0; i<bigBlockSize.getXBATEntriesPerBlock(); i++) { + if(xbat.getValueAt(i) == POIFSConstants.UNUSED_BLOCK) { + xbat.setValueAt(i, offset); + } + } } else { - newBAT.setValueAt(0, POIFSConstants.DIFAT_SECTOR_BLOCK); - } - - // Store us - _bat_blocks.add(newBAT); - if(isBAT) { - // Put it in the BAT array in the header + // Store us in the header int[] newBATs = new int[_header.getBATCount()+1]; System.arraycopy(_header.getBATArray(), 0, newBATs, 0, newBATs.length-1); newBATs[newBATs.length-1] = offset; _header.setBATArray(newBATs); _header.setBATCount(newBATs.length); - } else if(_header.getXBATCount() == 0) { - // Store our first XBAT offset in the header - _header.setXBATStart(offset); - _header.setXBATCount(1); - } else { - // Chain it off the last XBAT - BATBlock lastXBAT = _bat_blocks.get(_bat_blocks.size()-1); - lastXBAT.setValueAt(bigBlockSize.getNextXBATChainOffset(), offset); - _header.setXBATCount(_header.getXBATCount()+1); } - // The first offset stores us, but the 2nd is free + // The current offset stores us, but the next one is free return offset+1; } |