More unit tests for NPOIFS writing, and correct a bug in how bats get allocated in xbats. (Some issues still remain)

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1589800 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Nick Burch 2014-04-24 17:25:10 +00:00
parent 9d0167f5de
commit d99d2e559e
2 changed files with 81 additions and 34 deletions

View File

@ -530,7 +530,9 @@ public class NPOIFSFileSystem extends BlockStore
if(xbat == null) { if(xbat == null) {
// Oh joy, we need a new XBAT too... // Oh joy, we need a new XBAT too...
xbat = createBAT(offset+1, false); xbat = createBAT(offset+1, false);
// Allocate our new BAT as the first block in the XBAT
xbat.setValueAt(0, offset); xbat.setValueAt(0, offset);
// And allocate the XBAT in the BAT
bat.setValueAt(1, POIFSConstants.DIFAT_SECTOR_BLOCK); bat.setValueAt(1, POIFSConstants.DIFAT_SECTOR_BLOCK);
// Will go one place higher as XBAT added in // Will go one place higher as XBAT added in
@ -546,12 +548,14 @@ public class NPOIFSFileSystem extends BlockStore
} }
_xbat_blocks.add(xbat); _xbat_blocks.add(xbat);
_header.setXBATCount(_xbat_blocks.size()); _header.setXBATCount(_xbat_blocks.size());
} } else {
// Allocate us in the XBAT // Allocate our BAT in the existing XBAT with space
for(int i=0; i<bigBlockSize.getXBATEntriesPerBlock(); i++) { for(int i=0; i<bigBlockSize.getXBATEntriesPerBlock(); i++) {
if(xbat.getValueAt(i) == POIFSConstants.UNUSED_BLOCK) { if(xbat.getValueAt(i) == POIFSConstants.UNUSED_BLOCK) {
xbat.setValueAt(i, offset); xbat.setValueAt(i, offset);
} break;
}
}
} }
} else { } else {
// Store us in the header // Store us in the header
@ -566,6 +570,10 @@ public class NPOIFSFileSystem extends BlockStore
return offset+1; return offset+1;
} }
protected long size() throws IOException {
return _data.size();
}
@Override @Override
protected ChainLoopDetector getChainLoopDetector() throws IOException { protected ChainLoopDetector getChainLoopDetector() throws IOException {
return new ChainLoopDetector(_data.size()); return new ChainLoopDetector(_data.size());

View File

@ -47,6 +47,30 @@ import org.junit.Test;
public final class TestNPOIFSFileSystem { public final class TestNPOIFSFileSystem {
private static final POIDataSamples _inst = POIDataSamples.getPOIFSInstance(); private static final POIDataSamples _inst = POIDataSamples.getPOIFSInstance();
protected static void assertBATCount(NPOIFSFileSystem fs, int expectedBAT, int expectedXBAT) throws IOException {
int foundBAT = 0;
int foundXBAT = 0;
int sz = (int)(fs.size() / fs.getBigBlockSize());
for (int i=0; i<sz; i++) {
if(fs.getNextBlock(i) == POIFSConstants.FAT_SECTOR_BLOCK) {
foundBAT++;
}
if(fs.getNextBlock(i) == POIFSConstants.DIFAT_SECTOR_BLOCK) {
foundXBAT++;
}
}
assertEquals("Wrong number of BATs", expectedBAT, foundBAT);
assertEquals("Wrong number of XBATs with " + expectedBAT + " BATs", expectedXBAT, foundXBAT);
}
protected static HeaderBlock writeOutAndReadHeader(NPOIFSFileSystem fs) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
fs.writeFilesystem(baos);
HeaderBlock header = new HeaderBlock(new ByteArrayInputStream(baos.toByteArray()));
return header;
}
@Test @Test
public void basicOpen() throws Exception { public void basicOpen() throws Exception {
NPOIFSFileSystem fsA, fsB; NPOIFSFileSystem fsA, fsB;
@ -355,6 +379,9 @@ public final class TestNPOIFSFileSystem {
// Allocate it, then ask again // Allocate it, then ask again
fs.setNextBlock(100, POIFSConstants.END_OF_CHAIN); fs.setNextBlock(100, POIFSConstants.END_OF_CHAIN);
assertEquals(101, fs.getFreeBlock()); assertEquals(101, fs.getFreeBlock());
// All done
fs.close();
} }
/** /**
@ -388,6 +415,8 @@ public final class TestNPOIFSFileSystem {
assertEquals(false, fs.getBATBlockAndIndex(128).getBlock().hasFreeSectors()); assertEquals(false, fs.getBATBlockAndIndex(128).getBlock().hasFreeSectors());
fail("Should only be one BAT"); fail("Should only be one BAT");
} catch(IndexOutOfBoundsException e) {} } catch(IndexOutOfBoundsException e) {}
assertBATCount(fs, 1, 0);
// Now ask for a free one, will need to extend the file // Now ask for a free one, will need to extend the file
assertEquals(129, fs.getFreeBlock()); assertEquals(129, fs.getFreeBlock());
@ -397,6 +426,9 @@ public final class TestNPOIFSFileSystem {
assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(128)); assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(128));
assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(129)); assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(129));
// We now have 2 BATs, but no XBATs
assertBATCount(fs, 2, 0);
// Fill up to hold 109 BAT blocks // Fill up to hold 109 BAT blocks
for(int i=0; i<109; i++) { for(int i=0; i<109; i++) {
@ -414,6 +446,15 @@ public final class TestNPOIFSFileSystem {
fail("Should only be 109 BATs"); fail("Should only be 109 BATs");
} catch(IndexOutOfBoundsException e) {} } catch(IndexOutOfBoundsException e) {}
// We now have 109 BATs, but no XBATs
assertBATCount(fs, 109, 0);
// Ask for it to be written out, and check the header
HeaderBlock header = writeOutAndReadHeader(fs);
assertEquals(109, header.getBATCount());
assertEquals(0, header.getXBATCount());
// Ask for another, will get our first XBAT // Ask for another, will get our first XBAT
free = fs.getFreeBlock(); free = fs.getFreeBlock();
@ -423,6 +464,11 @@ public final class TestNPOIFSFileSystem {
assertEquals(false, fs.getBATBlockAndIndex(110*128).getBlock().hasFreeSectors()); assertEquals(false, fs.getBATBlockAndIndex(110*128).getBlock().hasFreeSectors());
fail("Should only be 110 BATs"); fail("Should only be 110 BATs");
} catch(IndexOutOfBoundsException e) {} } catch(IndexOutOfBoundsException e) {}
assertBATCount(fs, 110, 1);
header = writeOutAndReadHeader(fs);
assertEquals(110, header.getBATCount());
assertEquals(1, header.getXBATCount());
// Fill the XBAT, which means filling 127 BATs // Fill the XBAT, which means filling 127 BATs
@ -433,6 +479,7 @@ public final class TestNPOIFSFileSystem {
free = fs.getFreeBlock(); free = fs.getFreeBlock();
fs.setNextBlock(free, POIFSConstants.END_OF_CHAIN); fs.setNextBlock(free, POIFSConstants.END_OF_CHAIN);
} }
assertBATCount(fs, i+1, 1);
} }
// Should now have 109+127 = 236 BATs // Should now have 109+127 = 236 BATs
@ -441,6 +488,7 @@ public final class TestNPOIFSFileSystem {
assertEquals(false, fs.getBATBlockAndIndex(236*128).getBlock().hasFreeSectors()); assertEquals(false, fs.getBATBlockAndIndex(236*128).getBlock().hasFreeSectors());
fail("Should only be 236 BATs"); fail("Should only be 236 BATs");
} catch(IndexOutOfBoundsException e) {} } catch(IndexOutOfBoundsException e) {}
assertBATCount(fs, 236, 1);
// Ask for another, will get our 2nd XBAT // Ask for another, will get our 2nd XBAT
@ -453,39 +501,27 @@ public final class TestNPOIFSFileSystem {
} catch(IndexOutOfBoundsException e) {} } catch(IndexOutOfBoundsException e) {}
// Check the counts // Check the counts now
int numBATs = 0; assertBATCount(fs, 237, 2);
int numXBATs = 0;
for(int i=0; i<237*128; i++) {
if(fs.getNextBlock(i) == POIFSConstants.FAT_SECTOR_BLOCK) {
numBATs++;
}
if(fs.getNextBlock(i) == POIFSConstants.DIFAT_SECTOR_BLOCK) {
numXBATs++;
}
}
if(1==2) {
// TODO Fix this
assertEquals(237, numBATs);
assertEquals(2, numXBATs);
}
// Check the header
header = writeOutAndReadHeader(fs);
// Write it out
// Now, write it out, and read it back in again fully
ByteArrayOutputStream baos = new ByteArrayOutputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream();
fs.writeFilesystem(baos); fs.writeFilesystem(baos);
// Check the header is correct // TODO Correct this to work
HeaderBlock header = new HeaderBlock(new ByteArrayInputStream(baos.toByteArray())); if(1==2) {
if(1==2) { // Check that it is seen correctly
// TODO Fix this
assertEquals(237, header.getBATCount());
assertEquals(2, header.getXBATCount());
// Now check the filesystem sees it correct too
fs = new NPOIFSFileSystem(new ByteArrayInputStream(baos.toByteArray())); fs = new NPOIFSFileSystem(new ByteArrayInputStream(baos.toByteArray()));
// TODO assertBATCount(fs, 237, 2);
} // TODO Do some more checks
}
// All done
fs.close();
} }
/** /**
@ -560,6 +596,9 @@ public final class TestNPOIFSFileSystem {
assertEquals(null, inf.getApplicationName()); assertEquals(null, inf.getApplicationName());
assertEquals(null, inf.getAuthor()); assertEquals(null, inf.getAuthor());
assertEquals(null, inf.getSubject()); assertEquals(null, inf.getSubject());
// Finish
inp.close();
} }
} }