diff --git a/OpenMcdf.Tests/DirectoryEntryTests.cs b/OpenMcdf.Tests/DirectoryEntryTests.cs new file mode 100644 index 0000000..96ea171 --- /dev/null +++ b/OpenMcdf.Tests/DirectoryEntryTests.cs @@ -0,0 +1,28 @@ +namespace OpenMcdf.Tests; + +[TestClass] +public sealed class DirectoryEntryTests +{ + [TestMethod] + [DataRow("", "", 0)] + [DataRow("", "longer", -1)] + [DataRow("longer", "", 1)] + [DataRow("a", "a", 0)] + [DataRow("a", "b", -1)] + [DataRow("b", "a", 1)] + public void EnumerateEntryInfos(string nameX, string nameY, int expectedCompare) + { + DirectoryEntry entryX = new() + { + NameString = nameX, + }; + + DirectoryEntry entryY = new() + { + NameString = nameY, + }; + + int actualCompare = DirectoryEntryComparer.Default.Compare(entryX, entryY); + Assert.AreEqual(expectedCompare, actualCompare); + } +} diff --git a/OpenMcdf.Tests/StorageTests.cs b/OpenMcdf.Tests/StorageTests.cs index 6e021eb..653db80 100644 --- a/OpenMcdf.Tests/StorageTests.cs +++ b/OpenMcdf.Tests/StorageTests.cs @@ -41,14 +41,14 @@ public void OpenStorage(string fileName) public void CreateStorage(Version version, int subStorageCount) { using MemoryStream memoryStream = new(); + + // Test adding right sibling using (var rootStorage = RootStorage.Create(memoryStream, version, StorageModeFlags.LeaveOpen)) { for (int i = 0; i < subStorageCount; i++) rootStorage.CreateStorage($"Test{i}"); - rootStorage.TraceDirectoryEntries(DebugWriter.Default); } - memoryStream.Position = 0; using (var rootStorage = RootStorage.Open(memoryStream, StorageModeFlags.LeaveOpen)) { IEnumerable entries = rootStorage.EnumerateEntries(); @@ -58,6 +58,22 @@ public void CreateStorage(Version version, int subStorageCount) rootStorage.OpenStorage($"Test{i}"); } + // Test adding left sibling + using (var rootStorage = RootStorage.Create(memoryStream, version, StorageModeFlags.LeaveOpen)) + { + for (int i = 0; i < subStorageCount; i++) + rootStorage.CreateStorage($"Test{subStorageCount - i}"); + } + + using (var rootStorage = RootStorage.Open(memoryStream, StorageModeFlags.LeaveOpen)) + { + IEnumerable entries = rootStorage.EnumerateEntries(); + Assert.AreEqual(subStorageCount, entries.Count()); + + for (int i = 0; i < subStorageCount; i++) + rootStorage.OpenStorage($"Test{subStorageCount - i}"); + } + #if WINDOWS using (var rootStorage = StructuredStorage.Storage.Open(memoryStream)) { @@ -66,12 +82,55 @@ public void CreateStorage(Version version, int subStorageCount) for (int i = 0; i < subStorageCount; i++) { - using StructuredStorage.Storage storage = rootStorage.OpenStorage($"Test{i}"); + using StructuredStorage.Storage storage = rootStorage.OpenStorage($"Test{subStorageCount - i}"); } } #endif } + [TestMethod] + public void CreateInvalidStorageName() + { + using MemoryStream memoryStream = new(); + using var rootStorage = RootStorage.Create(memoryStream); + Assert.ThrowsException(() => rootStorage.CreateStorage("!")); + Assert.ThrowsException(() => rootStorage.CreateStorage("/")); + Assert.ThrowsException(() => rootStorage.CreateStorage(":")); + Assert.ThrowsException(() => rootStorage.CreateStorage("\\")); + } + + [TestMethod] + [DataRow(Version.V3, 0)] + [DataRow(Version.V3, 1)] + [DataRow(Version.V4, 0)] + [DataRow(Version.V4, 1)] + public void CreateStorageFile(Version version, int subStorageCount) + { + string fileName = Path.GetTempFileName(); + + try + { + using (var rootStorage = RootStorage.Create(fileName, version)) + { + for (int i = 0; i < subStorageCount; i++) + rootStorage.CreateStorage($"Test{i}"); + } + + using (var rootStorage = RootStorage.OpenRead(fileName)) + { + IEnumerable entries = rootStorage.EnumerateEntries(); + Assert.AreEqual(subStorageCount, entries.Count()); + + for (int i = 0; i < subStorageCount; i++) + rootStorage.OpenStorage($"Test{i}"); + } + } + finally + { + File.Delete(fileName); + } + } + [TestMethod] [DataRow(Version.V3)] [DataRow(Version.V4)] @@ -99,6 +158,8 @@ public void DeleteSingleStorage(Version version) { rootStorage.Delete("Test"); Assert.AreEqual(0, rootStorage.EnumerateEntries().Count()); + + rootStorage.Delete("NonExistentEntry"); } using (var rootStorage = RootStorage.Open(memoryStream)) @@ -191,15 +252,17 @@ public void DeleteStorageRecursively(Version version) using MemoryStream memoryStream = new(); using (var rootStorage = RootStorage.Create(memoryStream, version, StorageModeFlags.LeaveOpen)) { - Storage storage = rootStorage.CreateStorage("Test"); + Storage storage = rootStorage.CreateStorage("Storage"); Assert.AreEqual(1, rootStorage.EnumerateEntries().Count()); - using CfbStream stream = storage.CreateStream("Test"); + Storage subStorage = storage.CreateStorage("SubStorage"); + using CfbStream subStream = subStorage.CreateStream("SubStream"); + Assert.AreEqual(1, storage.EnumerateEntries().Count()); } using (var rootStorage = RootStorage.Open(memoryStream, StorageModeFlags.LeaveOpen)) { - rootStorage.Delete("Test"); + rootStorage.Delete("Storage"); Assert.AreEqual(0, rootStorage.EnumerateEntries().Count()); } @@ -235,20 +298,66 @@ public void Consolidate(Version version) { byte[] buffer = new byte[4096]; + string fileName = Path.GetTempFileName(); + + try + { + using MemoryStream memoryStream = new(); + using var rootStorage = RootStorage.Create(memoryStream, version, StorageModeFlags.LeaveOpen); + using (CfbStream stream = rootStorage.CreateStream("Test")) + stream.Write(buffer, 0, buffer.Length); + + Assert.AreEqual(1, rootStorage.EnumerateEntries().Count()); + + rootStorage.Flush(true); + + int originalMemoryStreamLength = (int)memoryStream.Length; + + rootStorage.Delete("Test"); + + rootStorage.Flush(true); + + Assert.IsTrue(originalMemoryStreamLength > memoryStream.Length); + } + finally + { + File.Delete(fileName); + } + } + + [TestMethod] + [DataRow(Version.V3)] + [DataRow(Version.V4)] + public void GetAndSetMetadata(Version version) + { using MemoryStream memoryStream = new(); - using var rootStorage = RootStorage.Create(memoryStream, version, StorageModeFlags.LeaveOpen); - CfbStream stream = rootStorage.CreateStream("Test"); - Assert.AreEqual(1, rootStorage.EnumerateEntries().Count()); - stream.Write(buffer, 0, buffer.Length); - rootStorage.Flush(); + Guid guid = Guid.NewGuid(); + DateTime now = DateTime.UtcNow; + + using (var rootStorage = RootStorage.Create(memoryStream, version, StorageModeFlags.LeaveOpen)) + { + Storage storage = rootStorage.CreateStorage("Storage"); - int originalMemoryStreamLength = (int)memoryStream.Length; + Assert.AreEqual(Guid.Empty, storage.CLISD); + Assert.AreNotEqual(DirectoryEntry.ZeroFileTime, storage.CreationTime); + Assert.AreNotEqual(DirectoryEntry.ZeroFileTime, storage.ModifiedTime); + Assert.AreEqual(0U, storage.StateBits); - rootStorage.Delete("Test"); + storage.CLISD = guid; + storage.CreationTime = now; + storage.ModifiedTime = now; + storage.StateBits = 1U; + } - rootStorage.Flush(true); + using (var rootStorage = RootStorage.Open(memoryStream)) + { + Storage storage = rootStorage.OpenStorage("Storage"); - Assert.IsTrue(originalMemoryStreamLength > memoryStream.Length); + Assert.AreEqual(guid, storage.CLISD); + Assert.AreEqual(now, storage.CreationTime); + Assert.AreEqual(now, storage.ModifiedTime); + Assert.AreEqual(1U, storage.StateBits); + } } } diff --git a/OpenMcdf.Tests/StreamExtensions.cs b/OpenMcdf.Tests/StreamExtensions.cs new file mode 100644 index 0000000..a370949 --- /dev/null +++ b/OpenMcdf.Tests/StreamExtensions.cs @@ -0,0 +1,27 @@ +namespace OpenMcdf.Tests; + +internal static class StreamExtensions +{ + public static void Write(this Stream stream, byte[] buffer, WriteMode mode) + { +#if (!NETSTANDARD2_0 && !NETFRAMEWORK) + switch (mode) + { + case WriteMode.Array: + stream.Write(buffer, 0, buffer.Length); + break; + case WriteMode.Span: + stream.Write(buffer); + break; + case WriteMode.SingleByte: + { + for (int i = 0; i < buffer.Length; i++) + stream.WriteByte(buffer[i]); + break; + } + } +#else + stream.Write(buffer, 0, buffer.Length); +#endif + } +} diff --git a/OpenMcdf.Tests/StreamTests.cs b/OpenMcdf.Tests/StreamTests.cs index de1ec7a..6adc176 100644 --- a/OpenMcdf.Tests/StreamTests.cs +++ b/OpenMcdf.Tests/StreamTests.cs @@ -1,6 +1,11 @@ -using System; +namespace OpenMcdf.Tests; -namespace OpenMcdf.Tests; +enum WriteMode +{ + SingleByte, + Array, + Span +} [TestClass] public sealed class StreamTests @@ -20,27 +25,7 @@ public void OpenStream(string fileName) } [TestMethod] - [DataRow(Version.V3, 0)] - [DataRow(Version.V3, 63)] - [DataRow(Version.V3, 64)] - [DataRow(Version.V3, 65)] - [DataRow(Version.V3, 511)] - [DataRow(Version.V3, 512)] - [DataRow(Version.V3, 513)] - [DataRow(Version.V3, 4095)] - [DataRow(Version.V3, 4096)] - [DataRow(Version.V3, 4097)] - [DataRow(Version.V3, 65536)] - [DataRow(Version.V4, 0)] - [DataRow(Version.V4, 63)] - [DataRow(Version.V4, 64)] - [DataRow(Version.V4, 65)] - [DataRow(Version.V4, 511)] - [DataRow(Version.V4, 512)] - [DataRow(Version.V4, 513)] - [DataRow(Version.V4, 4095)] - [DataRow(Version.V4, 4096)] - [DataRow(Version.V4, 4097)] + [DynamicData(nameof(TestData.ShortVersionsAndSizes), typeof(TestData))] public void ReadViaCopyTo(Version version, int length) { // Test files are filled with bytes equal to their position modulo 256 @@ -62,33 +47,11 @@ public void ReadViaCopyTo(Version version, int length) #if (!NETSTANDARD2_0 && !NETFRAMEWORK) [TestMethod] - [DataRow(Version.V3, 0)] - [DataRow(Version.V3, 63)] - [DataRow(Version.V3, 64)] - [DataRow(Version.V3, 65)] - [DataRow(Version.V3, 511)] - [DataRow(Version.V3, 512)] - [DataRow(Version.V3, 513)] - [DataRow(Version.V3, 4095)] - [DataRow(Version.V3, 4096)] - [DataRow(Version.V3, 4097)] - [DataRow(Version.V3, 65536)] - [DataRow(Version.V4, 0)] - [DataRow(Version.V4, 63)] - [DataRow(Version.V4, 64)] - [DataRow(Version.V4, 65)] - [DataRow(Version.V4, 511)] - [DataRow(Version.V4, 512)] - [DataRow(Version.V4, 513)] - [DataRow(Version.V4, 4095)] - [DataRow(Version.V4, 4096)] - [DataRow(Version.V4, 4097)] + [DynamicData(nameof(TestData.ShortVersionsAndSizes), typeof(TestData))] public void ReadSpan(Version version, int length) { // Test files are filled with bytes equal to their position modulo 256 - byte[] expectedBuffer = new byte[length]; - for (int i = 0; i < length; i++) - expectedBuffer[i] = ((byte)i); + byte[] expectedBuffer = TestData.CreateByteArray(length); string fileName = $"TestStream_v{(int)version}_{length}.cfs"; using var rootStorage = RootStorage.OpenRead(fileName); @@ -104,27 +67,7 @@ public void ReadSpan(Version version, int length) #endif [TestMethod] - [DataRow(Version.V3, 0)] - [DataRow(Version.V3, 63)] - [DataRow(Version.V3, 64)] - [DataRow(Version.V3, 65)] - [DataRow(Version.V3, 511)] - [DataRow(Version.V3, 512)] - [DataRow(Version.V3, 513)] - [DataRow(Version.V3, 4095)] - [DataRow(Version.V3, 4096)] - [DataRow(Version.V3, 4097)] - [DataRow(Version.V3, 65536)] - [DataRow(Version.V4, 0)] - [DataRow(Version.V4, 63)] - [DataRow(Version.V4, 64)] - [DataRow(Version.V4, 65)] - [DataRow(Version.V4, 511)] - [DataRow(Version.V4, 512)] - [DataRow(Version.V4, 513)] - [DataRow(Version.V4, 4095)] - [DataRow(Version.V4, 4096)] - [DataRow(Version.V4, 4097)] + [DynamicData(nameof(TestData.ShortVersionsAndSizes), typeof(TestData))] public void ReadSingleByte(Version version, int length) { string fileName = $"TestStream_v{(int)version}_{length}.cfs"; @@ -165,88 +108,28 @@ public void Seek(Version version, int length) } [TestMethod] - [DataRow(Version.V3, 0)] - [DataRow(Version.V3, 63)] - [DataRow(Version.V3, 64)] // Mini-stream sector size - [DataRow(Version.V3, 65)] - [DataRow(Version.V3, 511)] - [DataRow(Version.V3, 512)] // Multiple stream sectors - [DataRow(Version.V3, 513)] - [DataRow(Version.V3, 4095)] - [DataRow(Version.V3, 4096)] - [DataRow(Version.V3, 4097)] - [DataRow(Version.V3, 128 * 512)] // Multiple FAT sectors - [DataRow(Version.V3, 1024 * 4096)] // Multiple FAT sectors - [DataRow(Version.V3, 7087616)] // First DIFAT chain - [DataRow(Version.V3, 2 * 7087616)] // Long DIFAT chain - [DataRow(Version.V4, 0)] - [DataRow(Version.V4, 63)] - [DataRow(Version.V4, 64)] // Mini-stream sector size - [DataRow(Version.V4, 65)] - [DataRow(Version.V4, 511)] - [DataRow(Version.V4, 512)] - [DataRow(Version.V4, 513)] - [DataRow(Version.V4, 4095)] - [DataRow(Version.V4, 4096)] // Multiple stream sectors - [DataRow(Version.V4, 4097)] - [DataRow(Version.V4, 1024 * 4096)] // Multiple FAT sectors (1024 * 4096) - [DataRow(Version.V4, 7087616 * 4)] // First DIFAT chain - [DataRow(Version.V4, 2 * 7087616 * 4)] // Long DIFAT chain - public void Write(Version version, int length) => WriteCore(version, length, false); + [DynamicData(nameof(TestData.VersionsAndSizes), typeof(TestData))] + public void WriteArray(Version version, int length) => WriteCore(version, length, WriteMode.Array); #if (!NETSTANDARD2_0 && !NETFRAMEWORK) [TestMethod] - [DataRow(Version.V3, 0)] - [DataRow(Version.V3, 63)] - [DataRow(Version.V3, 64)] // Mini-stream sector size - [DataRow(Version.V3, 65)] - [DataRow(Version.V3, 511)] - [DataRow(Version.V3, 512)] // Multiple stream sectors - [DataRow(Version.V3, 513)] - [DataRow(Version.V3, 4095)] - [DataRow(Version.V3, 4096)] - [DataRow(Version.V3, 4097)] - [DataRow(Version.V3, 128 * 512)] // Multiple FAT sectors - [DataRow(Version.V3, 1024 * 4096)] // Multiple FAT sectors - [DataRow(Version.V3, 7087616)] // First DIFAT chain - [DataRow(Version.V3, 2 * 7087616)] // Long DIFAT chain - [DataRow(Version.V4, 0)] - [DataRow(Version.V4, 63)] - [DataRow(Version.V4, 64)] // Mini-stream sector size - [DataRow(Version.V4, 65)] - [DataRow(Version.V4, 511)] - [DataRow(Version.V4, 512)] - [DataRow(Version.V4, 513)] - [DataRow(Version.V4, 4095)] - [DataRow(Version.V4, 4096)] // Multiple stream sectors - [DataRow(Version.V4, 4097)] - [DataRow(Version.V4, 1024 * 4096)] // Multiple FAT sectors (1024 * 4096) - [DataRow(Version.V4, 7087616 * 4)] // First DIFAT chain - [DataRow(Version.V4, 2 * 7087616 * 4)] // Long DIFAT chain - public void WriteSpan(Version version, int length) => WriteCore(version, length, true); + [DynamicData(nameof(TestData.VersionsAndSizes), typeof(TestData))] + public void WriteSpan(Version version, int length) => WriteCore(version, length, WriteMode.Span); + + [TestMethod] + [DynamicData(nameof(TestData.ShortVersionsAndSizes), typeof(TestData))] + public void WriteSingleByte(Version version, int length) => WriteCore(version, length, WriteMode.SingleByte); #endif - static void WriteCore(Version version, int length, bool preferSpan) + static void WriteCore(Version version, int length, WriteMode mode) { using MemoryStream memoryStream = new(); using var rootStorage = RootStorage.Create(memoryStream, version); using CfbStream stream = rootStorage.CreateStream("TestStream"); Assert.AreEqual(0, stream.Length); - // Fill with bytes equal to their position modulo 256 - byte[] expectedBuffer = new byte[length]; - for (int i = 0; i < length; i++) - expectedBuffer[i] = (byte)i; - -#if (!NETSTANDARD2_0 && !NETFRAMEWORK) - if (preferSpan) - stream.Write(expectedBuffer); - else - stream.Write(expectedBuffer, 0, expectedBuffer.Length); -#else - stream.Write(expectedBuffer, 0, expectedBuffer.Length); -#endif - + byte[] expectedBuffer = TestData.CreateByteArray(length); + stream.Write(expectedBuffer, mode); Assert.AreEqual(length, stream.Length); Assert.AreEqual(length, stream.Position); @@ -260,39 +143,10 @@ static void WriteCore(Version version, int length, bool preferSpan) } [TestMethod] - [DataRow(Version.V3, 0)] - [DataRow(Version.V3, 63)] - [DataRow(Version.V3, 64)] // Mini-stream sector size - [DataRow(Version.V3, 65)] - [DataRow(Version.V3, 511)] - [DataRow(Version.V3, 512)] // Multiple stream sectors - [DataRow(Version.V3, 513)] - [DataRow(Version.V3, 4095)] - [DataRow(Version.V3, 4096)] - [DataRow(Version.V3, 4097)] - [DataRow(Version.V3, 128 * 512)] // Multiple FAT sectors - [DataRow(Version.V3, 1024 * 4096)] // Multiple FAT sectors - [DataRow(Version.V3, 7087616)] // First DIFAT chain - [DataRow(Version.V3, 2 * 7087616)] // Long DIFAT chain - [DataRow(Version.V4, 0)] - [DataRow(Version.V4, 63)] - [DataRow(Version.V4, 64)] // Mini-stream sector size - [DataRow(Version.V4, 65)] - [DataRow(Version.V4, 511)] - [DataRow(Version.V4, 512)] - [DataRow(Version.V4, 513)] - [DataRow(Version.V4, 4095)] - [DataRow(Version.V4, 4096)] // Multiple stream sectors - [DataRow(Version.V4, 4097)] - [DataRow(Version.V4, 1024 * 4096)] // Multiple FAT sectors (1024 * 4096) - [DataRow(Version.V4, 7087616 * 4)] // First DIFAT chain - [DataRow(Version.V4, 2 * 7087616 * 4)] // Long DIFAT chain + [DynamicData(nameof(TestData.VersionsAndSizes), typeof(TestData))] public void WriteThenRead(Version version, int length) { - // Fill with bytes equal to their position modulo 256 - byte[] expectedBuffer = new byte[length]; - for (int i = 0; i < length; i++) - expectedBuffer[i] = (byte)i; + byte[] expectedBuffer = TestData.CreateByteArray(length); using MemoryStream memoryStream = new(); using (var rootStorage = RootStorage.Create(memoryStream, version, StorageModeFlags.LeaveOpen)) @@ -329,39 +183,10 @@ public void WriteThenRead(Version version, int length) #if WINDOWS [TestMethod] - [DataRow(Version.V3, 0)] - [DataRow(Version.V3, 63)] - [DataRow(Version.V3, 64)] // Mini-stream sector size - [DataRow(Version.V3, 65)] - [DataRow(Version.V3, 511)] - [DataRow(Version.V3, 512)] // Multiple stream sectors - [DataRow(Version.V3, 513)] - [DataRow(Version.V3, 4095)] - [DataRow(Version.V3, 4096)] - [DataRow(Version.V3, 4097)] - [DataRow(Version.V3, 128 * 512)] // Multiple FAT sectors - [DataRow(Version.V3, 1024 * 4096)] // Multiple FAT sectors - [DataRow(Version.V3, 7087616)] // First DIFAT chain - [DataRow(Version.V3, 2 * 7087616)] // Long DIFAT chain - [DataRow(Version.V4, 0)] - [DataRow(Version.V4, 63)] - [DataRow(Version.V4, 64)] // Mini-stream sector size - [DataRow(Version.V4, 65)] - [DataRow(Version.V4, 511)] - [DataRow(Version.V4, 512)] - [DataRow(Version.V4, 513)] - [DataRow(Version.V4, 4095)] - [DataRow(Version.V4, 4096)] // Multiple stream sectors - [DataRow(Version.V4, 4097)] - [DataRow(Version.V4, 1024 * 4096)] // Multiple FAT sectors (1024 * 4096) - [DataRow(Version.V4, 7087616 * 4)] // First DIFAT chain - [DataRow(Version.V4, 2 * 7087616 * 4)] // Long DIFAT chain + [DynamicData(nameof(TestData.VersionsAndSizes), typeof(TestData))] public void StructuredStorageWriteThenRead(Version version, int length) { - // Fill with bytes equal to their position modulo 256 - byte[] expectedBuffer = new byte[length]; - for (int i = 0; i < length; i++) - expectedBuffer[i] = (byte)i; + byte[] expectedBuffer = TestData.CreateByteArray(length); using MemoryStream memoryStream = new(); string fileName = Path.GetTempFileName(); @@ -390,27 +215,7 @@ public void StructuredStorageWriteThenRead(Version version, int length) #endif [TestMethod] - [DataRow(Version.V3, 0)] - [DataRow(Version.V3, 256)] - [DataRow(Version.V3, 63)] - [DataRow(Version.V3, 64)] - [DataRow(Version.V3, 65)] - [DataRow(Version.V3, 511)] - [DataRow(Version.V3, 512)] - [DataRow(Version.V3, 513)] - [DataRow(Version.V3, 4095)] - [DataRow(Version.V3, 4096)] - [DataRow(Version.V3, 4097)] - [DataRow(Version.V4, 0)] - [DataRow(Version.V4, 63)] - [DataRow(Version.V4, 64)] - [DataRow(Version.V4, 65)] - [DataRow(Version.V4, 511)] - [DataRow(Version.V4, 512)] - [DataRow(Version.V4, 513)] - [DataRow(Version.V4, 4095)] - [DataRow(Version.V4, 4096)] - [DataRow(Version.V4, 4097)] + [DynamicData(nameof(TestData.ShortVersionsAndSizes), typeof(TestData))] public void WriteMultiple(Version version, int length) { const int IterationCount = 2048; @@ -419,10 +224,7 @@ public void WriteMultiple(Version version, int length) using CfbStream stream = rootStorage.CreateStream("TestStream"); Assert.AreEqual(0, stream.Length); - // Fill with bytes equal to their position modulo 256 - byte[] expectedBuffer = new byte[length]; - for (int i = 0; i < length; i++) - expectedBuffer[i] = (byte)i; + byte[] expectedBuffer = TestData.CreateByteArray(length); for (int i = 0; i < IterationCount; i++) { @@ -458,39 +260,10 @@ public void CreateMultipleStreams(Version version, int streamCount) } [TestMethod] - [DataRow(Version.V3, 0)] - [DataRow(Version.V3, 63)] - [DataRow(Version.V3, 64)] // Mini-stream sector size - [DataRow(Version.V3, 65)] - [DataRow(Version.V3, 511)] - [DataRow(Version.V3, 512)] // Multiple stream sectors - [DataRow(Version.V3, 513)] - [DataRow(Version.V3, 4095)] - [DataRow(Version.V3, 4096)] - [DataRow(Version.V3, 4097)] - [DataRow(Version.V3, 128 * 512)] // Multiple FAT sectors - [DataRow(Version.V3, 1024 * 4096)] // Multiple FAT sectors - [DataRow(Version.V3, 7087616)] // First DIFAT chain - [DataRow(Version.V3, 2 * 7087616)] // Long DIFAT chain - [DataRow(Version.V4, 0)] - [DataRow(Version.V4, 63)] - [DataRow(Version.V4, 64)] // Mini-stream sector size - [DataRow(Version.V4, 65)] - [DataRow(Version.V4, 511)] - [DataRow(Version.V4, 512)] - [DataRow(Version.V4, 513)] - [DataRow(Version.V4, 4095)] - [DataRow(Version.V4, 4096)] // Multiple stream sectors - [DataRow(Version.V4, 4097)] - [DataRow(Version.V4, 1024 * 4096)] // Multiple FAT sectors (1024 * 4096) - [DataRow(Version.V4, 7087616 * 4)] // First DIFAT chain - [DataRow(Version.V4, 2 * 7087616 * 4)] // Long DIFAT chain + [DynamicData(nameof(TestData.VersionsAndSizes), typeof(TestData))] public void Modify(Version version, int length) { - // Fill with bytes equal to their position modulo 256 - byte[] expectedBuffer = new byte[length]; - for (int i = 0; i < length; i++) - expectedBuffer[i] = (byte)i; + byte[] expectedBuffer = TestData.CreateByteArray(length); using MemoryStream memoryStream = new(); using (var rootStorage = RootStorage.Create(memoryStream, version, StorageModeFlags.LeaveOpen)) @@ -534,39 +307,25 @@ public void Modify(Version version, int length) } [TestMethod] - [DataRow(Version.V3, 0)] - [DataRow(Version.V3, 63)] - [DataRow(Version.V3, 64)] // Mini-stream sector size - [DataRow(Version.V3, 65)] - [DataRow(Version.V3, 511)] - [DataRow(Version.V3, 512)] // Multiple stream sectors - [DataRow(Version.V3, 513)] - [DataRow(Version.V3, 4095)] - [DataRow(Version.V3, 4096)] - [DataRow(Version.V3, 4097)] - [DataRow(Version.V3, 128 * 512)] // Multiple FAT sectors - [DataRow(Version.V3, 1024 * 4096)] // Multiple FAT sectors - [DataRow(Version.V3, 7087616)] // First DIFAT chain - [DataRow(Version.V3, 2 * 7087616)] // Long DIFAT chain - [DataRow(Version.V4, 0)] - [DataRow(Version.V4, 63)] - [DataRow(Version.V4, 64)] // Mini-stream sector size - [DataRow(Version.V4, 65)] - [DataRow(Version.V4, 511)] - [DataRow(Version.V4, 512)] - [DataRow(Version.V4, 513)] - [DataRow(Version.V4, 4095)] - [DataRow(Version.V4, 4096)] // Multiple stream sectors - [DataRow(Version.V4, 4097)] - [DataRow(Version.V4, 1024 * 4096)] // Multiple FAT sectors (1024 * 4096) - [DataRow(Version.V4, 7087616 * 4)] // First DIFAT chain - [DataRow(Version.V4, 2 * 7087616 * 4)] // Long DIFAT chain - public void ModifyCommit(Version version, int length) + [DynamicData(nameof(TestData.VersionsAndSizes), typeof(TestData))] + public void ModifyCommitArray(Version version, int length) => ModifyCommit(version, length, WriteMode.Array); + +#if (!NETSTANDARD2_0 && !NETFRAMEWORK) + [TestMethod] + [DynamicData(nameof(TestData.VersionsAndSizes), typeof(TestData))] + public void ModifyCommitSpan(Version version, int length) => ModifyCommit(version, length, WriteMode.Span); +#endif + +#if (!NETSTANDARD2_0 && !NETFRAMEWORK) + [TestMethod] + [DynamicData(nameof(TestData.VersionsAndSizes), typeof(TestData))] + public void ModifyCommitSingleByte(Version version, int length) => ModifyCommit(version, length, WriteMode.SingleByte); +#endif + + void ModifyCommit(Version version, int length, WriteMode writeMode) { // Fill with bytes equal to their position modulo 256 - byte[] expectedBuffer = new byte[length]; - for (int i = 0; i < length; i++) - expectedBuffer[i] = (byte)i; + byte[] expectedBuffer = TestData.CreateByteArray(length); using MemoryStream memoryStream = new(); using (var rootStorage = RootStorage.Create(memoryStream, version, StorageModeFlags.LeaveOpen)) @@ -579,11 +338,13 @@ public void ModifyCommit(Version version, int length) using (var rootStorage = RootStorage.Open(memoryStream, StorageModeFlags.LeaveOpen | StorageModeFlags.Transacted)) { - using CfbStream stream = rootStorage.CreateStream("TestStream2"); - Assert.AreEqual(0, stream.Length); + using (CfbStream stream = rootStorage.CreateStream("TestStream2")) + { + Assert.AreEqual(0, stream.Length); + + stream.Write(expectedBuffer, writeMode); + } - stream.Write(expectedBuffer, 0, expectedBuffer.Length); - stream.Flush(); rootStorage.Commit(); } @@ -612,39 +373,10 @@ public void ModifyCommit(Version version, int length) } [TestMethod] - [DataRow(Version.V3, 0)] - [DataRow(Version.V3, 63)] - [DataRow(Version.V3, 64)] // Mini-stream sector size - [DataRow(Version.V3, 65)] - [DataRow(Version.V3, 511)] - [DataRow(Version.V3, 512)] // Multiple stream sectors - [DataRow(Version.V3, 513)] - [DataRow(Version.V3, 4095)] - [DataRow(Version.V3, 4096)] - [DataRow(Version.V3, 4097)] - [DataRow(Version.V3, 128 * 512)] // Multiple FAT sectors - [DataRow(Version.V3, 1024 * 4096)] // Multiple FAT sectors - [DataRow(Version.V3, 7087616)] // First DIFAT chain - [DataRow(Version.V3, 2 * 7087616)] // Long DIFAT chain - [DataRow(Version.V4, 0)] - [DataRow(Version.V4, 63)] - [DataRow(Version.V4, 64)] // Mini-stream sector size - [DataRow(Version.V4, 65)] - [DataRow(Version.V4, 511)] - [DataRow(Version.V4, 512)] - [DataRow(Version.V4, 513)] - [DataRow(Version.V4, 4095)] - [DataRow(Version.V4, 4096)] // Multiple stream sectors - [DataRow(Version.V4, 4097)] - [DataRow(Version.V4, 1024 * 4096)] // Multiple FAT sectors (1024 * 4096) - [DataRow(Version.V4, 7087616 * 4)] // First DIFAT chain - [DataRow(Version.V4, 2 * 7087616 * 4)] // Long DIFAT chain + [DynamicData(nameof(TestData.VersionsAndSizes), typeof(TestData))] public void TransactedRead(Version version, int length) { - // Fill with bytes equal to their position modulo 256 - byte[] expectedBuffer = new byte[length]; - for (int i = 0; i < length; i++) - expectedBuffer[i] = (byte)i; + byte[] expectedBuffer = TestData.CreateByteArray(length); using MemoryStream memoryStream = new(); using (var rootStorage = RootStorage.Create(memoryStream, version, StorageModeFlags.LeaveOpen)) @@ -665,39 +397,10 @@ public void TransactedRead(Version version, int length) } [TestMethod] - [DataRow(Version.V3, 0)] - [DataRow(Version.V3, 63)] - [DataRow(Version.V3, 64)] // Mini-stream sector size - [DataRow(Version.V3, 65)] - [DataRow(Version.V3, 511)] - [DataRow(Version.V3, 512)] // Multiple stream sectors - [DataRow(Version.V3, 513)] - [DataRow(Version.V3, 4095)] - [DataRow(Version.V3, 4096)] - [DataRow(Version.V3, 4097)] - [DataRow(Version.V3, 128 * 512)] // Multiple FAT sectors - [DataRow(Version.V3, 1024 * 4096)] // Multiple FAT sectors - [DataRow(Version.V3, 7087616)] // First DIFAT chain - [DataRow(Version.V3, 2 * 7087616)] // Long DIFAT chain - [DataRow(Version.V4, 0)] - [DataRow(Version.V4, 63)] - [DataRow(Version.V4, 64)] // Mini-stream sector size - [DataRow(Version.V4, 65)] - [DataRow(Version.V4, 511)] - [DataRow(Version.V4, 512)] - [DataRow(Version.V4, 513)] - [DataRow(Version.V4, 4095)] - [DataRow(Version.V4, 4096)] // Multiple stream sectors - [DataRow(Version.V4, 4097)] - [DataRow(Version.V4, 1024 * 4096)] // Multiple FAT sectors (1024 * 4096) - [DataRow(Version.V4, 7087616 * 4)] // First DIFAT chain - [DataRow(Version.V4, 2 * 7087616 * 4)] // Long DIFAT chain + [DynamicData(nameof(TestData.VersionsAndSizes), typeof(TestData))] public void ModifyRevert(Version version, int length) { - // Fill with bytes equal to their position modulo 256 - byte[] expectedBuffer = new byte[length]; - for (int i = 0; i < length; i++) - expectedBuffer[i] = (byte)i; + byte[] expectedBuffer = TestData.CreateByteArray(length); using MemoryStream memoryStream = new(); using (var rootStorage = RootStorage.Create(memoryStream, version, StorageModeFlags.LeaveOpen)) @@ -735,46 +438,14 @@ public void ModifyRevert(Version version, int length) } [TestMethod] - [DataRow(Version.V3, 0)] - [DataRow(Version.V3, 63)] - [DataRow(Version.V3, 64)] // Mini-stream sector size - [DataRow(Version.V3, 2 * 64)] // Simplest case (1 sector => 2) - [DataRow(Version.V3, 65)] - [DataRow(Version.V3, 511)] - [DataRow(Version.V3, 512)] // Multiple stream sectors - [DataRow(Version.V3, 513)] - [DataRow(Version.V3, 4095)] - [DataRow(Version.V3, 4096)] - [DataRow(Version.V3, 4097)] - [DataRow(Version.V3, 128 * 512)] // Multiple FAT sectors - [DataRow(Version.V3, 1024 * 4096)] // Multiple FAT sectors - [DataRow(Version.V3, 7087616)] // First DIFAT chain - [DataRow(Version.V3, 2 * 7087616)] // Long DIFAT chain - [DataRow(Version.V4, 0)] - [DataRow(Version.V4, 63)] - [DataRow(Version.V4, 64)] // Mini-stream sector size - [DataRow(Version.V4, 65)] - [DataRow(Version.V4, 511)] - [DataRow(Version.V4, 512)] - [DataRow(Version.V4, 513)] - [DataRow(Version.V4, 4095)] - [DataRow(Version.V4, 4096)] // Multiple stream sectors - [DataRow(Version.V4, 2 * 4096)] // Simplest case (1 sector => 2) - [DataRow(Version.V4, 4097)] - [DataRow(Version.V4, 1024 * 4096)] // Multiple FAT sectors (1024 * 4096) - [DataRow(Version.V4, 7087616 * 4)] // First DIFAT chain - [DataRow(Version.V4, 2 * 7087616 * 4)] // Long DIFAT chain + [DynamicData(nameof(TestData.VersionsAndSizes), typeof(TestData))] public void Shrink(Version version, int length) { using MemoryStream memoryStream = new(); using var rootStorage = RootStorage.Create(memoryStream, version); using CfbStream stream = rootStorage.CreateStream("Test"); - // Fill with bytes equal to their position modulo 256 - byte[] expectedBuffer = new byte[length]; - for (int i = 0; i < length; i++) - expectedBuffer[i] = (byte)i; - + byte[] expectedBuffer = TestData.CreateByteArray(length); stream.Write(expectedBuffer, 0, expectedBuffer.Length); Assert.AreEqual(length, stream.Length); @@ -805,10 +476,7 @@ public void MiniFatToFat(Version version) using CfbStream stream = rootStorage.CreateStream("Test"); int length = 256; - // Fill with bytes equal to their position modulo 256 - byte[] expectedBuffer = new byte[length]; - for (int i = 0; i < length; i++) - expectedBuffer[i] = (byte)i; + byte[] expectedBuffer = TestData.CreateByteArray(length); int iterations = (int)Header.MiniStreamCutoffSize / length; for (int i = 0; i < iterations; i++) @@ -837,11 +505,7 @@ public void FatToMiniFat(Version version) using var rootStorage = RootStorage.Create(memoryStream, version); using CfbStream stream = rootStorage.CreateStream("Test"); - // Fill with bytes equal to their position modulo 256 - byte[] expectedBuffer = new byte[length]; - for (int i = 0; i < length; i++) - expectedBuffer[i] = (byte)i; - + byte[] expectedBuffer = TestData.CreateByteArray(length); int iterations = (int)Header.MiniStreamCutoffSize / length; for (int i = 0; i < iterations; i++) stream.Write(expectedBuffer, 0, expectedBuffer.Length); @@ -868,26 +532,7 @@ public void FatToMiniFat(Version version) } [TestMethod] - [DataRow(Version.V3, 0)] - [DataRow(Version.V3, 63)] - [DataRow(Version.V3, 64)] - [DataRow(Version.V3, 65)] - [DataRow(Version.V3, 511)] - [DataRow(Version.V3, 512)] - [DataRow(Version.V3, 513)] - [DataRow(Version.V3, 4095)] - [DataRow(Version.V3, 4096)] - [DataRow(Version.V3, 4097)] - [DataRow(Version.V4, 0)] - [DataRow(Version.V4, 63)] - [DataRow(Version.V4, 64)] - [DataRow(Version.V4, 65)] - [DataRow(Version.V4, 511)] - [DataRow(Version.V4, 512)] - [DataRow(Version.V4, 513)] - [DataRow(Version.V4, 4095)] - [DataRow(Version.V4, 4096)] - [DataRow(Version.V4, 4097)] + [DynamicData(nameof(TestData.ShortVersionsAndSizes), typeof(TestData))] public void CopyFromStream(Version version, int length) { using MemoryStream memoryStream = new(); diff --git a/OpenMcdf.Tests/TestData.cs b/OpenMcdf.Tests/TestData.cs new file mode 100644 index 0000000..b307839 --- /dev/null +++ b/OpenMcdf.Tests/TestData.cs @@ -0,0 +1,70 @@ +namespace OpenMcdf.Tests; + +internal static class TestData +{ + /// + /// Fill with bytes equal to their position modulo 256 + /// + public static byte[] CreateByteArray(int length) + { + byte[] expectedBuffer = new byte[length]; + for (int i = 0; i < length; i++) + expectedBuffer[i] = (byte)i; + return expectedBuffer; + } + + public static IEnumerable ShortVersionsAndSizes { get; } = new[] + { + new object[] { Version.V3, 0 }, + [Version.V3, 63], + [Version.V3, 64], // Mini-stream sector size + [Version.V3, 65], + [Version.V3, 511], + [Version.V3, 512], // Multiple stream sectors + [Version.V3, 513], + [Version.V3, 4095], + [Version.V3, 4096], + [Version.V3, 4097], + [Version.V4, 0], + [Version.V4, 63], + [Version.V4, 64], // Mini-stream sector size + [Version.V4, 65], + [Version.V4, 511], + [Version.V4, 512], + [Version.V4, 513], + [Version.V4, 4095], + [Version.V4, 4096], // Multiple stream sectors + [Version.V4, 4097], + }; + + public static IEnumerable VersionsAndSizes { get; } = new[] + { + new object[] { Version.V3, 0 }, + [Version.V3, 63], + [Version.V3, 64], // Mini-stream sector size + [Version.V3, 65], + [Version.V3, 511], + [Version.V3, 512], // Multiple stream sectors + [Version.V3, 513], + [Version.V3, 4095], + [Version.V3, 4096], + [Version.V3, 4097], + [Version.V3, 128 * 512], // Multiple FAT sectors + [Version.V3, 1024 * 4096], // Multiple FAT sectors + [Version.V3, 7087616], // First DIFAT chain + [Version.V3, 2 * 7087616], // Long DIFAT chain + [Version.V4, 0], + [Version.V4, 63], + [Version.V4, 64], // Mini-stream sector size + [Version.V4, 65], + [Version.V4, 511], + [Version.V4, 512], + [Version.V4, 513], + [Version.V4, 4095], + [Version.V4, 4096], // Multiple stream sectors + [Version.V4, 4097], + [Version.V4, 1024 * 4096], // Multiple FAT sectors (1024 * 4096 + [Version.V4, 7087616 * 4], // First DIFAT chain + [Version.V4, 2 * 7087616 * 4], // Long DIFAT chain + }; +} diff --git a/OpenMcdf/DirectoryEntry.cs b/OpenMcdf/DirectoryEntry.cs index 297c3a3..cf49616 100644 --- a/OpenMcdf/DirectoryEntry.cs +++ b/OpenMcdf/DirectoryEntry.cs @@ -1,4 +1,5 @@ -using System.Runtime.InteropServices; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.InteropServices; using System.Text; namespace OpenMcdf; @@ -228,6 +229,7 @@ public void Recycle(StorageType storageType, string name) public EntryInfo ToEntryInfo(string path) => new(EntryType, path, NameString, StreamLength, CLSID, CreationTime, ModifiedTime); + [ExcludeFromCodeCoverage] public override string ToString() => $"{Id}: \"{NameString}\""; public DirectoryEntry Clone() diff --git a/OpenMcdf/DirectoryTree.cs b/OpenMcdf/DirectoryTree.cs index 4209156..9ab9f3c 100644 --- a/OpenMcdf/DirectoryTree.cs +++ b/OpenMcdf/DirectoryTree.cs @@ -1,4 +1,5 @@ using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; namespace OpenMcdf; @@ -195,7 +196,8 @@ public void Remove(DirectoryEntry entry) } } - public void WriteTrace(TextWriter writer) + [ExcludeFromCodeCoverage] + internal void WriteTrace(TextWriter writer) { if (root.ChildId == StreamId.NoStream) { diff --git a/OpenMcdf/Fat.cs b/OpenMcdf/Fat.cs index 8614159..af8214e 100644 --- a/OpenMcdf/Fat.cs +++ b/OpenMcdf/Fat.cs @@ -1,6 +1,7 @@ using System.Buffers.Binary; using System.Collections; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; namespace OpenMcdf; @@ -144,6 +145,7 @@ public uint Add(FatEnumerator fatEnumerator, uint startIndex) IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + [ExcludeFromCodeCoverage] internal void WriteTrace(TextWriter writer) { byte[] data = new byte[Context.SectorSize]; @@ -179,6 +181,7 @@ internal void WriteTrace(TextWriter writer) writer.WriteLine($"Used sectors: {usedCount}"); } + [ExcludeFromCodeCoverage] internal void Validate() { long fatSectorCount = 0; @@ -200,5 +203,6 @@ internal void Validate() throw new FormatException($"DIFAT sector count mismatch: Expected: {Context.Header.DifatSectorCount} Actual: {difatSectorCount}."); } + [ExcludeFromCodeCoverage] internal long GetFreeSectorCount() => this.Count(entry => entry.IsFree); } diff --git a/OpenMcdf/FatChainEnumerator.cs b/OpenMcdf/FatChainEnumerator.cs index 263d116..e3af3cc 100644 --- a/OpenMcdf/FatChainEnumerator.cs +++ b/OpenMcdf/FatChainEnumerator.cs @@ -1,5 +1,6 @@ using System.Collections; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; namespace OpenMcdf; @@ -65,12 +66,8 @@ public bool MoveNext() return true; } - if (SectorType.IsFreeOrEndOfChain(current)) - { - index = uint.MaxValue; - current = uint.MaxValue; + if (index == uint.MaxValue) return false; - } uint value = fat[current]; if (value is SectorType.EndOfChain) @@ -198,7 +195,7 @@ public uint Shrink(uint requiredChainLength) uint lastId = current; while (MoveNext()) { - if (lastId is not SectorType.EndOfChain and not SectorType.Free) + if (!SectorType.IsFreeOrEndOfChain(lastId)) { if (index == requiredChainLength) fat[lastId] = SectorType.EndOfChain; @@ -237,5 +234,6 @@ public void Reset(uint startSectorId) current = uint.MaxValue; } + [ExcludeFromCodeCoverage] public override string ToString() => $"Index: {index} Current: {current}"; } diff --git a/OpenMcdf/FatEntry.cs b/OpenMcdf/FatEntry.cs index 915eb85..d6e430c 100644 --- a/OpenMcdf/FatEntry.cs +++ b/OpenMcdf/FatEntry.cs @@ -1,13 +1,14 @@ -namespace OpenMcdf; +using System.Diagnostics.CodeAnalysis; + +namespace OpenMcdf; /// /// Encapsulates an entry in the File Allocation Table (FAT). /// internal record struct FatEntry(uint Index, uint Value) { - internal static readonly FatEntry Invalid = new(uint.MaxValue, uint.MaxValue); - public readonly bool IsFree => Value == SectorType.Free; + [ExcludeFromCodeCoverage] public override readonly string ToString() => $"#{Index}: {Value}"; } diff --git a/OpenMcdf/FatEnumerator.cs b/OpenMcdf/FatEnumerator.cs index 7519000..34f542d 100644 --- a/OpenMcdf/FatEnumerator.cs +++ b/OpenMcdf/FatEnumerator.cs @@ -1,4 +1,5 @@ using System.Collections; +using System.Diagnostics.CodeAnalysis; namespace OpenMcdf; @@ -89,5 +90,6 @@ public void Reset() value = uint.MaxValue; } + [ExcludeFromCodeCoverage] public override string ToString() => $"{Current}"; } diff --git a/OpenMcdf/Header.cs b/OpenMcdf/Header.cs index 0ab4c6a..4593a4b 100644 --- a/OpenMcdf/Header.cs +++ b/OpenMcdf/Header.cs @@ -1,4 +1,6 @@ -namespace OpenMcdf; +using System.Diagnostics.CodeAnalysis; + +namespace OpenMcdf; /// /// The structure at the beginning of a compound file. @@ -180,5 +182,6 @@ public bool Equals(Header? other) && Difat.SequenceEqual(other.Difat); } + [ExcludeFromCodeCoverage] public override string ToString() => $"MajorVersion: {MajorVersion}, MinorVersion: {MinorVersion}, FirstDirectorySectorId: {FirstDirectorySectorId}, FirstMiniFatSectorId: {FirstMiniFatSectorId}"; } diff --git a/OpenMcdf/MiniFat.cs b/OpenMcdf/MiniFat.cs index 3579660..1432e48 100644 --- a/OpenMcdf/MiniFat.cs +++ b/OpenMcdf/MiniFat.cs @@ -1,6 +1,7 @@ using System.Buffers.Binary; using System.Collections; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; namespace OpenMcdf; @@ -140,7 +141,8 @@ public uint Add(MiniFatEnumerator miniFatEnumerator, uint startIndex) return entry.Index; } - internal void Trace(TextWriter writer) + [ExcludeFromCodeCoverage] + internal void WriteTrace(TextWriter writer) { using MiniFatEnumerator miniFatEnumerator = new(ContextSite); @@ -150,6 +152,7 @@ internal void Trace(TextWriter writer) writer.WriteLine("End of Mini FAT =============="); } + [ExcludeFromCodeCoverage] internal void Validate() { using MiniFatEnumerator miniFatEnumerator = new(ContextSite); diff --git a/OpenMcdf/MiniFatChainEnumerator.cs b/OpenMcdf/MiniFatChainEnumerator.cs index 0b8fe17..2a9aee7 100644 --- a/OpenMcdf/MiniFatChainEnumerator.cs +++ b/OpenMcdf/MiniFatChainEnumerator.cs @@ -1,5 +1,6 @@ using System.Collections; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; namespace OpenMcdf; @@ -204,5 +205,6 @@ public void Reset() current = uint.MaxValue; } + [ExcludeFromCodeCoverage] public override string ToString() => $"Index: {index} Current: {current}"; } diff --git a/OpenMcdf/MiniSector.cs b/OpenMcdf/MiniSector.cs index e20f134..b8accc2 100644 --- a/OpenMcdf/MiniSector.cs +++ b/OpenMcdf/MiniSector.cs @@ -1,4 +1,6 @@ -namespace OpenMcdf; +using System.Diagnostics.CodeAnalysis; + +namespace OpenMcdf; /// /// Encapsulates information about a mini sector in a compound file. @@ -7,12 +9,8 @@ /// The sector length internal record struct MiniSector(uint Id, int Length) { - public static readonly MiniSector EndOfChain = new(SectorType.EndOfChain, int.MaxValue); - public readonly bool IsValid => Id <= SectorType.Maximum; - public readonly bool IsEndOfChain => Id is SectorType.EndOfChain or SectorType.Free; - /// /// The position of the mini sector in the mini FAT stream. /// @@ -43,5 +41,6 @@ readonly void ThrowIfInvalid() throw new InvalidOperationException($"Invalid mini FAT sector ID: {Id}."); } + [ExcludeFromCodeCoverage] public override readonly string ToString() => $"{Id}"; } diff --git a/OpenMcdf/RootStorage.cs b/OpenMcdf/RootStorage.cs index 08a0bc2..85c713d 100644 --- a/OpenMcdf/RootStorage.cs +++ b/OpenMcdf/RootStorage.cs @@ -1,4 +1,6 @@ -namespace OpenMcdf; +using System.Diagnostics.CodeAnalysis; + +namespace OpenMcdf; public enum Version : ushort { @@ -174,13 +176,15 @@ public void SwitchTo(Stream stream) _ = new RootContext(ContextSite, stream, Version.Unknown, contextFlags); } + [ExcludeFromCodeCoverage] internal void Trace(TextWriter writer) { writer.WriteLine(Context.Header); Context.Fat.WriteTrace(writer); - Context.MiniFat.Trace(writer); + Context.MiniFat.WriteTrace(writer); } + [ExcludeFromCodeCoverage] internal void Validate() { Context.Fat.Validate(); diff --git a/OpenMcdf/Sector.cs b/OpenMcdf/Sector.cs index d7d3657..6145207 100644 --- a/OpenMcdf/Sector.cs +++ b/OpenMcdf/Sector.cs @@ -1,4 +1,6 @@ -namespace OpenMcdf; +using System.Diagnostics.CodeAnalysis; + +namespace OpenMcdf; /// /// Encapsulates information about a sector in a compound file. @@ -9,12 +11,6 @@ internal record struct Sector(uint Id, int Length) { public static readonly Sector EndOfChain = new(SectorType.EndOfChain, 0); - /// - /// Compound File Binary File Format only specifies that ENDOFCHAIN ends the DIFAT chain - /// but some implementations use FREESECT - /// - public readonly bool IsEndOfChain => Id is SectorType.EndOfChain or SectorType.Free; - public readonly bool IsValid => Id <= SectorType.Maximum; /// @@ -47,5 +43,6 @@ readonly void ThrowIfInvalid() throw new InvalidOperationException($"Invalid FAT sector ID: {Id}."); } + [ExcludeFromCodeCoverage] public override readonly string ToString() => $"{Id}"; } diff --git a/OpenMcdf/Storage.cs b/OpenMcdf/Storage.cs index 64b2937..eb1ebb9 100644 --- a/OpenMcdf/Storage.cs +++ b/OpenMcdf/Storage.cs @@ -169,8 +169,8 @@ public void CopyTo(Storage destination) } else if (entry.Type is StorageType.Stream) { - CfbStream stream = new(ContextSite, entry, this); - CfbStream destinationStream = destination.CreateStream(entry.NameString); + using CfbStream stream = new(ContextSite, entry, this); + using CfbStream destinationStream = destination.CreateStream(entry.NameString); stream.CopyTo(destinationStream); } }