Helper method to report the number of blocks used in a BAT

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1689504 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Nick Burch 2015-07-06 21:15:57 +00:00
parent df179170a2
commit 92764ff10d
2 changed files with 69 additions and 2 deletions

View File

@ -30,8 +30,6 @@ import org.apache.poi.util.LittleEndian;
/**
* A block of block allocation table entries. BATBlocks are created
* only through a static factory method: createBATBlocks.
*
* @author Marc Johnson (mjohnson at apache dot org)
*/
public final class BATBlock extends BigBlock {
/**
@ -301,6 +299,21 @@ public final class BATBlock extends BigBlock {
public boolean hasFreeSectors() {
return _has_free_sectors;
}
/**
* How many sectors in this block are taken?
* Note that calling {@link #hasFreeSectors()} is much quicker
*/
public int getUsedSectors(boolean isAnXBAT) {
int usedSectors = 0;
int toCheck = _values.length;
if (isAnXBAT) toCheck--; // Last is a chain location
for(int k=0; k<toCheck; k++) {
if(_values[k] != POIFSConstants.UNUSED_BLOCK) {
usedSectors ++;
}
}
return usedSectors;
}
public int getValueAt(int relativeOffset) {
if(relativeOffset >= _values.length) {

View File

@ -26,6 +26,7 @@ import java.util.List;
import junit.framework.TestCase;
import org.apache.poi.poifs.common.POIFSBigBlockSize;
import org.apache.poi.poifs.common.POIFSConstants;
/**
@ -283,6 +284,59 @@ public final class TestBATBlock extends TestCase {
);
}
public void testUsedSectors() throws Exception {
POIFSBigBlockSize b512 = POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS;
POIFSBigBlockSize b4096 = POIFSConstants.LARGER_BIG_BLOCK_SIZE_DETAILS;
// Try first with 512 block sizes, which can hold 128 entries
BATBlock block512 = BATBlock.createEmptyBATBlock(b512, false);
assertEquals(true, block512.hasFreeSectors());
assertEquals(0, block512.getUsedSectors(false));
// Allocate a few
block512.setValueAt(0, 42);
block512.setValueAt(10, 42);
block512.setValueAt(20, 42);
assertEquals(true, block512.hasFreeSectors());
assertEquals(3, block512.getUsedSectors(false));
// Allocate all
for (int i=0; i<b512.getBATEntriesPerBlock(); i++) {
block512.setValueAt(i, 82);
}
// Check
assertEquals(false, block512.hasFreeSectors());
assertEquals(128, block512.getUsedSectors(false));
assertEquals(127, block512.getUsedSectors(true));
// Release one
block512.setValueAt(10, POIFSConstants.UNUSED_BLOCK);
assertEquals(true, block512.hasFreeSectors());
assertEquals(127, block512.getUsedSectors(false));
assertEquals(126, block512.getUsedSectors(true));
// Now repeat with 4096 block sizes
BATBlock block4096 = BATBlock.createEmptyBATBlock(b4096, false);
assertEquals(true, block4096.hasFreeSectors());
assertEquals(0, block4096.getUsedSectors(false));
block4096.setValueAt(0, 42);
block4096.setValueAt(10, 42);
block4096.setValueAt(20, 42);
assertEquals(true, block4096.hasFreeSectors());
assertEquals(3, block4096.getUsedSectors(false));
// Allocate all
for (int i=0; i<b4096.getBATEntriesPerBlock(); i++) {
block4096.setValueAt(i, 82);
}
// Check
assertEquals(false, block4096.hasFreeSectors());
assertEquals(1024, block4096.getUsedSectors(false));
assertEquals(1023, block4096.getUsedSectors(true));
}
public void testGetBATBlockAndIndex() throws Exception {
HeaderBlock header = new HeaderBlock(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS);
List<BATBlock> blocks = new ArrayList<BATBlock>();