public void TestFetchBlocks() { // strategy: // // 1. Set up a single BAT block from which to construct a // BAT. create nonsense blocks in the raw data block ArrayList // corresponding to the indices in the BAT block. // 2. The indices will include very short documents (0 and 1 // block in Length), longer documents, and some screwed up // documents (one with a loop, one that will peek into // another document's data, one that includes an unused // document, one that includes a reserved (BAT) block, one // that includes a reserved (XBAT) block, and one that // points off into space somewhere LocalRawDataBlockList list = new LocalRawDataBlockList(); byte[] data = new byte[512]; int offset = 0; LittleEndian.PutInt(data, offset, -3); // for the BAT block itself offset += LittleEndianConsts.INT_SIZE; // document 1: Is at end of file alReady; start block = -2 // document 2: has only one block; start block = 1 LittleEndian.PutInt(data, offset, -2); offset += LittleEndianConsts.INT_SIZE; // document 3: has a loop in it; start block = 2 LittleEndian.PutInt(data, offset, 2); offset += LittleEndianConsts.INT_SIZE; // document 4: peeks into document 2's data; start block = 3 LittleEndian.PutInt(data, offset, 4); offset += LittleEndianConsts.INT_SIZE; LittleEndian.PutInt(data, offset, 1); offset += LittleEndianConsts.INT_SIZE; // document 5: includes an unused block; start block = 5 LittleEndian.PutInt(data, offset, 6); offset += LittleEndianConsts.INT_SIZE; LittleEndian.PutInt(data, offset, -1); offset += LittleEndianConsts.INT_SIZE; // document 6: includes a BAT block; start block = 7 LittleEndian.PutInt(data, offset, 8); offset += LittleEndianConsts.INT_SIZE; LittleEndian.PutInt(data, offset, 0); offset += LittleEndianConsts.INT_SIZE; // document 7: includes an XBAT block; start block = 9 LittleEndian.PutInt(data, offset, 10); offset += LittleEndianConsts.INT_SIZE; LittleEndian.PutInt(data, offset, -4); offset += LittleEndianConsts.INT_SIZE; // document 8: goes off into space; start block = 11; LittleEndian.PutInt(data, offset, 1000); offset += LittleEndianConsts.INT_SIZE; // document 9: no screw ups; start block = 12; int index = 13; for (; offset < 508; offset += LittleEndianConsts.INT_SIZE) { LittleEndian.PutInt(data, offset, index++); } LittleEndian.PutInt(data, offset, -2); list.Add(new RawDataBlock(new MemoryStream(data))); list.Fill(1); int[] blocks = { 0 }; BlockAllocationTableReader table = new BlockAllocationTableReader(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS, 1, blocks, 0, -2, list); int[] start_blocks = { -2, 1, 2, 3, 5, 7, 9, 11, 12}; int[] expected_Length = { 0, 1, -1, -1, -1, -1, -1, -1, 116 }; for (int j = 0; j < start_blocks.Length; j++) { try { ListManagedBlock[] dataBlocks = table.FetchBlocks(start_blocks[j],-1, list); if (expected_Length[j] == -1) { Assert.Fail("document " + j + " should have failed"); } else { Assert.AreEqual(expected_Length[j], dataBlocks.Length); } } catch (IOException) { if (expected_Length[j] == -1) { // no problem, we expected a failure here } else { throw; } } } }
public void TestReadingConstructor() { // create a document, minus the header block, and use that to // create a RawDataBlockList. The document will exist entire // of BATBlocks and XBATBlocks // // we will create two XBAT blocks, which will encompass 128 // BAT blocks between them, and two extra BAT blocks which // will be in the block array passed to the constructor. This // makes a total of 130 BAT blocks, which will encompass // 16,640 blocks, for a file size of some 8.5 megabytes. // // Naturally, we'll fake that out ... // // map of blocks: // block 0: xbat block 0 // block 1: xbat block 1 // block 2: bat block 0 // block 3: bat block 1 // blocks 4-130: bat blocks 2-128, contained in xbat block 0 // block 131: bat block 129, contained in xbat block 1 // blocks 132-16639: fictitious blocks, faked out. All blocks // whose index Is evenly divisible by 256 // will be unused LocalRawDataBlockList list = new LocalRawDataBlockList(); list.CreateNewXBATBlock(4, 130, 1); list.CreateNewXBATBlock(131, 131, -2); for (int j = 0; j < 130; j++) { list.CreateNewBATBlock(j * 128); } list.Fill(132); int[] blocks = { 2,3 }; BlockAllocationTableReader table = new BlockAllocationTableReader( POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS, 130, blocks, 2, 0, list); for (int i = 0; i < (130 * 128); i++) { if (i % 256 == 0) { Assert.IsTrue( !table.IsUsed(i), "verifying block " + i + " Is unused"); } else if (i % 256 == 255) { Assert.AreEqual( POIFSConstants.END_OF_CHAIN, table.GetNextBlockIndex(i), "Verify end of chain for block " + i); } else { Assert.AreEqual(i + 1, table.GetNextBlockIndex(i), "Verify next index for block " + i); } } }