mirror of https://github.com/apache/poi.git
[github-182] Fix root property size calculation. Thanks to netmackan. This closes #182
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1878721 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
ff67cdf116
commit
0181d2abd9
|
@ -252,7 +252,7 @@ public class POIFSMiniStore extends BlockStore
|
||||||
if (!sbat.hasFreeSectors()) {
|
if (!sbat.hasFreeSectors()) {
|
||||||
blocksUsed += _filesystem.getBigBlockSizeDetails().getBATEntriesPerBlock();
|
blocksUsed += _filesystem.getBigBlockSizeDetails().getBATEntriesPerBlock();
|
||||||
} else {
|
} else {
|
||||||
blocksUsed += sbat.getUsedSectors(false);
|
blocksUsed += sbat.getOccupiedSize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Set the size on the root in terms of the number of SBAT blocks
|
// Set the size on the root in terms of the number of SBAT blocks
|
||||||
|
|
|
@ -192,6 +192,27 @@ public final class BATBlock implements BlockWritable {
|
||||||
return usedSectors;
|
return usedSectors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* How much of this block is occupied?.
|
||||||
|
* This counts the number of sectors up and including the last used sector.
|
||||||
|
* Note that this is different from {@link #getUsedSectors(boolean)} which
|
||||||
|
* could be smaller as it does not count unused sectors where there are
|
||||||
|
* used ones after it (i.e. fragmentation).
|
||||||
|
*
|
||||||
|
* @since POI 5.0.0
|
||||||
|
*/
|
||||||
|
public int getOccupiedSize() {
|
||||||
|
int usedSectors = _values.length;
|
||||||
|
for (int k = _values.length - 1; k >= 0; k--) {
|
||||||
|
if(_values[k] == POIFSConstants.UNUSED_BLOCK) {
|
||||||
|
usedSectors--;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return usedSectors;
|
||||||
|
}
|
||||||
|
|
||||||
public int getValueAt(int relativeOffset) {
|
public int getValueAt(int relativeOffset) {
|
||||||
if(relativeOffset >= _values.length) {
|
if(relativeOffset >= _values.length) {
|
||||||
throw new ArrayIndexOutOfBoundsException(
|
throw new ArrayIndexOutOfBoundsException(
|
||||||
|
@ -201,6 +222,7 @@ public final class BATBlock implements BlockWritable {
|
||||||
}
|
}
|
||||||
return _values[relativeOffset];
|
return _values[relativeOffset];
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setValueAt(int relativeOffset, int value) {
|
public void setValueAt(int relativeOffset, int value) {
|
||||||
int oldValue = _values[relativeOffset];
|
int oldValue = _values[relativeOffset];
|
||||||
_values[relativeOffset] = value;
|
_values[relativeOffset] = value;
|
||||||
|
@ -221,6 +243,7 @@ public final class BATBlock implements BlockWritable {
|
||||||
public void setOurBlockIndex(int index) {
|
public void setOurBlockIndex(int index) {
|
||||||
this.ourBlockIndex = index;
|
this.ourBlockIndex = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve where in the file we live
|
* Retrieve where in the file we live
|
||||||
*/
|
*/
|
||||||
|
@ -237,7 +260,6 @@ public final class BATBlock implements BlockWritable {
|
||||||
* @exception IOException on problems writing to the specified
|
* @exception IOException on problems writing to the specified
|
||||||
* stream
|
* stream
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public void writeBlocks(final OutputStream stream) throws IOException {
|
public void writeBlocks(final OutputStream stream) throws IOException {
|
||||||
// Save it out
|
// Save it out
|
||||||
stream.write( serialize() );
|
stream.write( serialize() );
|
||||||
|
|
|
@ -176,6 +176,67 @@ public final class TestBATBlock {
|
||||||
assertEquals(1023, block4096.getUsedSectors(true));
|
assertEquals(1023, block4096.getUsedSectors(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOccupiedSize() {
|
||||||
|
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);
|
||||||
|
assertTrue(block512.hasFreeSectors());
|
||||||
|
assertEquals(0, block512.getUsedSectors(false));
|
||||||
|
|
||||||
|
// Allocate a few
|
||||||
|
block512.setValueAt(0, 42);
|
||||||
|
block512.setValueAt(10, 42);
|
||||||
|
block512.setValueAt(20, 42);
|
||||||
|
assertTrue(block512.hasFreeSectors());
|
||||||
|
assertEquals(21, block512.getOccupiedSize());
|
||||||
|
|
||||||
|
// Release one in the middle should not lower size
|
||||||
|
block512.setValueAt(10, POIFSConstants.UNUSED_BLOCK);
|
||||||
|
assertTrue(block512.hasFreeSectors());
|
||||||
|
assertEquals(21, block512.getOccupiedSize());
|
||||||
|
|
||||||
|
// Release the last one should lower the size
|
||||||
|
block512.setValueAt(20, POIFSConstants.UNUSED_BLOCK);
|
||||||
|
assertTrue(block512.hasFreeSectors());
|
||||||
|
assertEquals(1, block512.getOccupiedSize());
|
||||||
|
|
||||||
|
// Release first one should lower the size
|
||||||
|
block512.setValueAt(0, POIFSConstants.UNUSED_BLOCK);
|
||||||
|
assertTrue(block512.hasFreeSectors());
|
||||||
|
assertEquals(0, block512.getOccupiedSize());
|
||||||
|
|
||||||
|
// Set the last one
|
||||||
|
block512.setValueAt(127, 42);
|
||||||
|
assertTrue(block512.hasFreeSectors());
|
||||||
|
assertEquals(128, block512.getOccupiedSize());
|
||||||
|
|
||||||
|
block512.setValueAt(126, 42);
|
||||||
|
assertTrue(block512.hasFreeSectors());
|
||||||
|
assertEquals(128, block512.getOccupiedSize());
|
||||||
|
|
||||||
|
block512.setValueAt(127, POIFSConstants.UNUSED_BLOCK);
|
||||||
|
assertTrue(block512.hasFreeSectors());
|
||||||
|
assertEquals(127, block512.getOccupiedSize());
|
||||||
|
|
||||||
|
// Allocate all
|
||||||
|
for (int i = 0; i < b512.getBATEntriesPerBlock(); i++) {
|
||||||
|
block512.setValueAt(i, 82);
|
||||||
|
}
|
||||||
|
// Check
|
||||||
|
assertFalse(block512.hasFreeSectors());
|
||||||
|
assertEquals(128, block512.getOccupiedSize());
|
||||||
|
|
||||||
|
// Release some in the beginning should not lower size
|
||||||
|
block512.setValueAt(0, POIFSConstants.UNUSED_BLOCK);
|
||||||
|
block512.setValueAt(1, POIFSConstants.UNUSED_BLOCK);
|
||||||
|
block512.setValueAt(13, POIFSConstants.UNUSED_BLOCK);
|
||||||
|
assertTrue(block512.hasFreeSectors());
|
||||||
|
assertEquals(128, block512.getOccupiedSize());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetBATBlockAndIndex() {
|
public void testGetBATBlockAndIndex() {
|
||||||
HeaderBlock header = new HeaderBlock(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS);
|
HeaderBlock header = new HeaderBlock(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS);
|
||||||
|
|
Loading…
Reference in New Issue