public void TestInPlaceNPOIFSWrite() { NPOIFSFileSystem fs = null; DirectoryEntry root = null; DocumentNode sinfDoc = null; DocumentNode dinfDoc = null; SummaryInformation sinf = null; DocumentSummaryInformation dinf = null; // We need to work on a File for in-place changes, so create a temp one FileInfo copy = TempFile.CreateTempFile("Test-HPSF", "ole2"); //copy.DeleteOnExit(); // Copy a test file over to a temp location Stream inp = _samples.OpenResourceAsStream("TestShiftJIS.doc"); FileStream out1 = new FileStream(copy.FullName, FileMode.Create); IOUtils.Copy(inp, out1); inp.Close(); out1.Close(); // Open the copy in Read/write mode fs = new NPOIFSFileSystem(copy, false); root = fs.Root; // Read the properties in there sinfDoc = (DocumentNode)root.GetEntry(SummaryInformation.DEFAULT_STREAM_NAME); dinfDoc = (DocumentNode)root.GetEntry(DocumentSummaryInformation.DEFAULT_STREAM_NAME); InputStream sinfStream = new NDocumentInputStream(sinfDoc); sinf = (SummaryInformation)PropertySetFactory.Create(sinfStream); sinfStream.Close(); Assert.AreEqual(131077, sinf.OSVersion); InputStream dinfStream = new NDocumentInputStream(dinfDoc); dinf = (DocumentSummaryInformation)PropertySetFactory.Create(dinfStream); dinfStream.Close(); Assert.AreEqual(131077, dinf.OSVersion); // Check they start as we expect Assert.AreEqual("Reiichiro Hori", sinf.Author); Assert.AreEqual("Microsoft Word 9.0", sinf.ApplicationName); Assert.AreEqual("\u7b2c1\u7ae0", sinf.Title); Assert.AreEqual("", dinf.Company); Assert.AreEqual(null, dinf.Manager); // Do an in-place replace via an InputStream new NPOIFSDocument(sinfDoc).ReplaceContents(sinf.ToInputStream()); new NPOIFSDocument(dinfDoc).ReplaceContents(dinf.ToInputStream()); // Check it didn't Get Changed sinfDoc = (DocumentNode)root.GetEntry(SummaryInformation.DEFAULT_STREAM_NAME); dinfDoc = (DocumentNode)root.GetEntry(DocumentSummaryInformation.DEFAULT_STREAM_NAME); InputStream sinfStream2 = new NDocumentInputStream(sinfDoc); sinf = (SummaryInformation)PropertySetFactory.Create(sinfStream2); sinfStream2.Close(); Assert.AreEqual(131077, sinf.OSVersion); InputStream dinfStream2 = new NDocumentInputStream(dinfDoc); dinf = (DocumentSummaryInformation)PropertySetFactory.Create(dinfStream2); dinfStream2.Close(); Assert.AreEqual(131077, dinf.OSVersion); // Start again! fs.Close(); inp = _samples.OpenResourceAsStream("TestShiftJIS.doc"); out1 = new FileStream(copy.FullName, FileMode.Open, FileAccess.ReadWrite); IOUtils.Copy(inp, out1); inp.Close(); out1.Close(); fs = new NPOIFSFileSystem(new FileStream(copy.FullName, FileMode.Open, FileAccess.ReadWrite), null, false, true); root = fs.Root; // Read the properties in once more sinfDoc = (DocumentNode)root.GetEntry(SummaryInformation.DEFAULT_STREAM_NAME); dinfDoc = (DocumentNode)root.GetEntry(DocumentSummaryInformation.DEFAULT_STREAM_NAME); InputStream sinfStream3 = new NDocumentInputStream(sinfDoc); sinf = (SummaryInformation)PropertySetFactory.Create(sinfStream3); sinfStream3.Close(); Assert.AreEqual(131077, sinf.OSVersion); InputStream dinfStream3 = new NDocumentInputStream(dinfDoc); dinf = (DocumentSummaryInformation)PropertySetFactory.Create(dinfStream3); dinfStream3.Close(); Assert.AreEqual(131077, dinf.OSVersion); // Have them write themselves in-place with no Changes Stream soufStream = new NDocumentOutputStream(sinfDoc); sinf.Write(soufStream); soufStream.Close(); Stream doufStream = new NDocumentOutputStream(dinfDoc); dinf.Write(doufStream); doufStream.Close(); // And also write to some bytes for Checking MemoryStream sinfBytes = new MemoryStream(); sinf.Write(sinfBytes); MemoryStream dinfBytes = new MemoryStream(); dinf.Write(dinfBytes); // Check that the filesystem can give us back the same bytes sinfDoc = (DocumentNode)root.GetEntry(SummaryInformation.DEFAULT_STREAM_NAME); dinfDoc = (DocumentNode)root.GetEntry(DocumentSummaryInformation.DEFAULT_STREAM_NAME); InputStream sinfStream4 = new NDocumentInputStream(sinfDoc); byte[] sinfData = IOUtils.ToByteArray(sinfStream4); sinfStream4.Close(); InputStream dinfStream4 = new NDocumentInputStream(dinfDoc); byte[] dinfData = IOUtils.ToByteArray(dinfStream4); dinfStream4.Close(); Assert.That(sinfBytes.ToArray(), new EqualConstraint(sinfData)); Assert.That(dinfBytes.ToArray(), new EqualConstraint(dinfData)); // Read back in as-is InputStream sinfStream5 = new NDocumentInputStream(sinfDoc); sinf = (SummaryInformation)PropertySetFactory.Create(sinfStream5); sinfStream5.Close(); Assert.AreEqual(131077, sinf.OSVersion); InputStream dinfStream5 = new NDocumentInputStream(dinfDoc); dinf = (DocumentSummaryInformation)PropertySetFactory.Create(dinfStream5); dinfStream5.Close(); Assert.AreEqual(131077, dinf.OSVersion); Assert.AreEqual("Reiichiro Hori", sinf.Author); Assert.AreEqual("Microsoft Word 9.0", sinf.ApplicationName); Assert.AreEqual("\u7b2c1\u7ae0", sinf.Title); Assert.AreEqual("", dinf.Company); Assert.AreEqual(null, dinf.Manager); // Now alter a few of them sinf.Author = (/*setter*/ "Changed Author"); sinf.Title = (/*setter*/ "Le titre \u00e9tait chang\u00e9"); dinf.Manager = (/*setter*/ "Changed Manager"); // Save this into the filesystem Stream soufStream2 = new NDocumentOutputStream(sinfDoc); sinf.Write(soufStream2); soufStream2.Close(); Stream doufStream2 = new NDocumentOutputStream(dinfDoc); dinf.Write(doufStream2); doufStream2.Close(); // Read them back in again sinfDoc = (DocumentNode)root.GetEntry(SummaryInformation.DEFAULT_STREAM_NAME); InputStream sinfStream6 = new NDocumentInputStream(sinfDoc); sinf = (SummaryInformation)PropertySetFactory.Create(sinfStream6); sinfStream6.Close(); Assert.AreEqual(131077, sinf.OSVersion); dinfDoc = (DocumentNode)root.GetEntry(DocumentSummaryInformation.DEFAULT_STREAM_NAME); InputStream dinfStream6 = new NDocumentInputStream(dinfDoc); dinf = (DocumentSummaryInformation)PropertySetFactory.Create(dinfStream6); dinfStream6.Close(); Assert.AreEqual(131077, dinf.OSVersion); Assert.AreEqual("Changed Author", sinf.Author); Assert.AreEqual("Microsoft Word 9.0", sinf.ApplicationName); Assert.AreEqual("Le titre \u00e9tait chang\u00e9", sinf.Title); Assert.AreEqual("", dinf.Company); Assert.AreEqual("Changed Manager", dinf.Manager); // Close the whole filesystem, and open it once more fs.WriteFileSystem(); fs.Close(); fs = new NPOIFSFileSystem(new FileStream(copy.FullName, FileMode.Open)); root = fs.Root; // Re-check on load sinfDoc = (DocumentNode)root.GetEntry(SummaryInformation.DEFAULT_STREAM_NAME); InputStream sinfStream7 = new NDocumentInputStream(sinfDoc); sinf = (SummaryInformation)PropertySetFactory.Create(sinfStream7); sinfStream7.Close(); Assert.AreEqual(131077, sinf.OSVersion); dinfDoc = (DocumentNode)root.GetEntry(DocumentSummaryInformation.DEFAULT_STREAM_NAME); InputStream dinfStream7 = new NDocumentInputStream(dinfDoc); dinf = (DocumentSummaryInformation)PropertySetFactory.Create(dinfStream7); dinfStream7.Close(); Assert.AreEqual(131077, dinf.OSVersion); Assert.AreEqual("Changed Author", sinf.Author); Assert.AreEqual("Microsoft Word 9.0", sinf.ApplicationName); Assert.AreEqual("Le titre \u00e9tait chang\u00e9", sinf.Title); Assert.AreEqual("", dinf.Company); Assert.AreEqual("Changed Manager", dinf.Manager); // Tidy up fs.Close(); copy.Delete(); }
public void TestWriteThenReplace() { NPOIFSFileSystem fs = new NPOIFSFileSystem(); // Starts empty BATBlock bat = fs.GetBATBlockAndIndex(0).Block; Assert.AreEqual(POIFSConstants.FAT_SECTOR_BLOCK, bat.GetValueAt(0)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, bat.GetValueAt(1)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, bat.GetValueAt(2)); // Write something that uses a main stream byte[] main4106 = new byte[4106]; main4106[0] = unchecked ((byte)-10); main4106[4105] = unchecked ((byte)-11); DocumentEntry normal = fs.Root.CreateDocument( "Normal", new MemoryStream(main4106)); // Should have used 9 blocks Assert.AreEqual(POIFSConstants.FAT_SECTOR_BLOCK, bat.GetValueAt(0)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, bat.GetValueAt(1)); Assert.AreEqual(3, bat.GetValueAt(2)); Assert.AreEqual(4, bat.GetValueAt(3)); Assert.AreEqual(5, bat.GetValueAt(4)); Assert.AreEqual(6, bat.GetValueAt(5)); Assert.AreEqual(7, bat.GetValueAt(6)); Assert.AreEqual(8, bat.GetValueAt(7)); Assert.AreEqual(9, bat.GetValueAt(8)); Assert.AreEqual(10, bat.GetValueAt(9)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, bat.GetValueAt(10)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, bat.GetValueAt(11)); normal = (DocumentEntry)fs.Root.GetEntry("Normal"); Assert.AreEqual(4106, normal.Size); Assert.AreEqual(4106, ((DocumentNode)normal).Property.Size); // Replace with one still big enough for a main stream, but one block smaller byte[] main4096 = new byte[4096]; main4096[0] = unchecked ((byte)-10); main4096[4095] = unchecked ((byte)-11); NDocumentOutputStream nout = new NDocumentOutputStream(normal); nout.Write(main4096); nout.Close(); // Will have dropped to 8 Assert.AreEqual(POIFSConstants.FAT_SECTOR_BLOCK, bat.GetValueAt(0)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, bat.GetValueAt(1)); Assert.AreEqual(3, bat.GetValueAt(2)); Assert.AreEqual(4, bat.GetValueAt(3)); Assert.AreEqual(5, bat.GetValueAt(4)); Assert.AreEqual(6, bat.GetValueAt(5)); Assert.AreEqual(7, bat.GetValueAt(6)); Assert.AreEqual(8, bat.GetValueAt(7)); Assert.AreEqual(9, bat.GetValueAt(8)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, bat.GetValueAt(9)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, bat.GetValueAt(10)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, bat.GetValueAt(11)); normal = (DocumentEntry)fs.Root.GetEntry("Normal"); Assert.AreEqual(4096, normal.Size); Assert.AreEqual(4096, ((DocumentNode)normal).Property.Size); // Write and check fs = TestNPOIFSFileSystem.WriteOutAndReadBack(fs); bat = fs.GetBATBlockAndIndex(0).Block; // Will have properties, but otherwise the same Assert.AreEqual(POIFSConstants.FAT_SECTOR_BLOCK, bat.GetValueAt(0)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, bat.GetValueAt(1)); Assert.AreEqual(3, bat.GetValueAt(2)); Assert.AreEqual(4, bat.GetValueAt(3)); Assert.AreEqual(5, bat.GetValueAt(4)); Assert.AreEqual(6, bat.GetValueAt(5)); Assert.AreEqual(7, bat.GetValueAt(6)); Assert.AreEqual(8, bat.GetValueAt(7)); Assert.AreEqual(9, bat.GetValueAt(8)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, bat.GetValueAt(9)); // End of Normal Assert.AreEqual(POIFSConstants.END_OF_CHAIN, bat.GetValueAt(10)); // Props Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, bat.GetValueAt(11)); normal = (DocumentEntry)fs.Root.GetEntry("Normal"); Assert.AreEqual(4096, normal.Size); Assert.AreEqual(4096, ((DocumentNode)normal).Property.Size); // Make longer, take 1 block After the properties too normal = (DocumentEntry)fs.Root.GetEntry("Normal"); nout = new NDocumentOutputStream(normal); nout.Write(main4106); nout.Close(); Assert.AreEqual(POIFSConstants.FAT_SECTOR_BLOCK, bat.GetValueAt(0)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, bat.GetValueAt(1)); Assert.AreEqual(3, bat.GetValueAt(2)); Assert.AreEqual(4, bat.GetValueAt(3)); Assert.AreEqual(5, bat.GetValueAt(4)); Assert.AreEqual(6, bat.GetValueAt(5)); Assert.AreEqual(7, bat.GetValueAt(6)); Assert.AreEqual(8, bat.GetValueAt(7)); Assert.AreEqual(9, bat.GetValueAt(8)); Assert.AreEqual(11, bat.GetValueAt(9)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, bat.GetValueAt(10)); // Props Assert.AreEqual(POIFSConstants.END_OF_CHAIN, bat.GetValueAt(11)); // Normal Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, bat.GetValueAt(12)); normal = (DocumentEntry)fs.Root.GetEntry("Normal"); Assert.AreEqual(4106, normal.Size); Assert.AreEqual(4106, ((DocumentNode)normal).Property.Size); // Make it small, will trigger the SBAT stream and free lots up byte[] mini = new byte[] { 42, 0, 1, 2, 3, 4, 42 }; normal = (DocumentEntry)fs.Root.GetEntry("Normal"); nout = new NDocumentOutputStream(normal); nout.Write(mini); nout.Close(); Assert.AreEqual(POIFSConstants.FAT_SECTOR_BLOCK, bat.GetValueAt(0)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, bat.GetValueAt(1)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, bat.GetValueAt(2)); // SBAT Assert.AreEqual(POIFSConstants.END_OF_CHAIN, bat.GetValueAt(3)); // Mini Stream Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, bat.GetValueAt(4)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, bat.GetValueAt(5)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, bat.GetValueAt(6)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, bat.GetValueAt(7)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, bat.GetValueAt(8)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, bat.GetValueAt(9)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, bat.GetValueAt(10)); // Props Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, bat.GetValueAt(11)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, bat.GetValueAt(12)); normal = (DocumentEntry)fs.Root.GetEntry("Normal"); Assert.AreEqual(7, normal.Size); Assert.AreEqual(7, ((DocumentNode)normal).Property.Size); // Finally back to big again nout = new NDocumentOutputStream(normal); nout.Write(main4096); nout.Close(); // Will keep the mini stream, now empty Assert.AreEqual(POIFSConstants.FAT_SECTOR_BLOCK, bat.GetValueAt(0)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, bat.GetValueAt(1)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, bat.GetValueAt(2)); // SBAT Assert.AreEqual(POIFSConstants.END_OF_CHAIN, bat.GetValueAt(3)); // Mini Stream Assert.AreEqual(5, bat.GetValueAt(4)); Assert.AreEqual(6, bat.GetValueAt(5)); Assert.AreEqual(7, bat.GetValueAt(6)); Assert.AreEqual(8, bat.GetValueAt(7)); Assert.AreEqual(9, bat.GetValueAt(8)); Assert.AreEqual(11, bat.GetValueAt(9)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, bat.GetValueAt(10)); // Props Assert.AreEqual(12, bat.GetValueAt(11)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, bat.GetValueAt(12)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, bat.GetValueAt(13)); normal = (DocumentEntry)fs.Root.GetEntry("Normal"); Assert.AreEqual(4096, normal.Size); Assert.AreEqual(4096, ((DocumentNode)normal).Property.Size); // Save, re-load, re-check fs = TestNPOIFSFileSystem.WriteOutAndReadBack(fs); bat = fs.GetBATBlockAndIndex(0).Block; Assert.AreEqual(POIFSConstants.FAT_SECTOR_BLOCK, bat.GetValueAt(0)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, bat.GetValueAt(1)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, bat.GetValueAt(2)); // SBAT Assert.AreEqual(POIFSConstants.END_OF_CHAIN, bat.GetValueAt(3)); // Mini Stream Assert.AreEqual(5, bat.GetValueAt(4)); Assert.AreEqual(6, bat.GetValueAt(5)); Assert.AreEqual(7, bat.GetValueAt(6)); Assert.AreEqual(8, bat.GetValueAt(7)); Assert.AreEqual(9, bat.GetValueAt(8)); Assert.AreEqual(11, bat.GetValueAt(9)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, bat.GetValueAt(10)); // Props Assert.AreEqual(12, bat.GetValueAt(11)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, bat.GetValueAt(12)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, bat.GetValueAt(13)); normal = (DocumentEntry)fs.Root.GetEntry("Normal"); Assert.AreEqual(4096, normal.Size); Assert.AreEqual(4096, ((DocumentNode)normal).Property.Size); fs.Close(); }