]> source.dussan.org Git - poi.git/commitdiff
Helper method to report the number of blocks used in a BAT
authorNick Burch <nick@apache.org>
Mon, 6 Jul 2015 21:15:57 +0000 (21:15 +0000)
committerNick Burch <nick@apache.org>
Mon, 6 Jul 2015 21:15:57 +0000 (21:15 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1689504 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/poi/poifs/storage/BATBlock.java
src/testcases/org/apache/poi/poifs/storage/TestBATBlock.java

index 8712e65f6fb3fad221dae2ce773ad29bbc08d295..53099644ac325243f9ac84e1e0056633e5d76d79 100644 (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) {
index 3fc77b839c9ebd4ab2ac005b9c243260a65a6455..11c7070e9347d70da53ecc11ad01261a57aed14d 100644 (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>();