From 752815bb2ee8cd90ff9fa85da2eaa3df5523a930 Mon Sep 17 00:00:00 2001
From: LTRData
Date: Fri, 24 May 2024 18:05:35 +0200
Subject: [PATCH] Optimizations and fixes
* HashStreamCore had issues on net46, backported new implementation instead
* Fixed some Span empty checks that had mistakenly been compares to null
* More use of new ArgumentNullException.ThrowIfNull etc, where possible
* Test cases modified to test with correct path separator for running platform
* Some test case helper methods moved to the common Helpers class
---
.../DiscUtilsRegistryStorage.cs | 25 ++--
.../Compression/BZip2DecoderStream.cs | 4 +
.../DiscUtils.Core/Compression/ZlibStream.cs | 4 +
Library/DiscUtils.Core/DiscFileSystemInfo.cs | 4 +
.../Partitions/BiosPartitionedDiskBuilder.cs | 8 ++
.../AccessControl/GenericAce.cs | 5 +-
.../GenericSecurityDescriptor.cs | 4 +
.../AccessControl/ObjectAce.cs | 9 +-
.../WindowsSecurity/AccessControl/RawAcl.cs | 6 +-
.../AccessControl/RawSecurityDescriptor.cs | 4 +
.../WindowsSecurity/NTAccount.cs | 8 ++
Library/DiscUtils.Fat/FatFileSystem.cs | 4 +
Library/DiscUtils.Fat/FileName.cs | 4 +
Library/DiscUtils.HfsPlus/AttributeKey.cs | 4 +
Library/DiscUtils.HfsPlus/CatalogKey.cs | 4 +
Library/DiscUtils.HfsPlus/Directory.cs | 4 +
Library/DiscUtils.HfsPlus/ExtentKey.cs | 4 +
Library/DiscUtils.Registry/RegistryKey.cs | 7 ++
.../SquashFileSystemBuilder.cs | 4 +
.../Builder/StreamBuilder.cs | 16 +--
Library/DiscUtils.Streams/BuiltStream.cs | 12 +-
Library/DiscUtils.Streams/StreamBuffer.cs | 4 +
.../Util/CompatExtensions.cs | 11 ++
.../DiscUtils.Streams/Util/StreamUtilities.cs | 9 +-
Library/DiscUtils.Vhd/DynamicStream.cs | 36 +++---
.../VirtualFileSystemDirectoryEntry.cs | 19 ++-
Library/DiscUtils.Xva/HashStreamCore.cs | 119 ------------------
.../DiscUtils.Xva/VirtualMachineBuilder.cs | 67 ++--------
Tests/LibraryTests/Btrfs/SampleDataTests.cs | 50 ++------
Tests/LibraryTests/Helpers/Helpers.cs | 42 ++++++-
Tests/LibraryTests/Xfs/SampleDataTests.cs | 21 ++--
31 files changed, 237 insertions(+), 285 deletions(-)
diff --git a/Library/DiscUtils.BootConfig/DiscUtilsRegistryStorage.cs b/Library/DiscUtils.BootConfig/DiscUtilsRegistryStorage.cs
index 4f51abdf0..e499addd6 100644
--- a/Library/DiscUtils.BootConfig/DiscUtilsRegistryStorage.cs
+++ b/Library/DiscUtils.BootConfig/DiscUtilsRegistryStorage.cs
@@ -29,11 +29,6 @@ namespace DiscUtils.BootConfig;
internal class DiscUtilsRegistryStorage : BaseStorage
{
- private const string ElementsPathTemplate = @"Objects\{0}\Elements";
- private const string ElementPathTemplate = @"Objects\{0}\Elements\{1:X8}";
- private const string ObjectTypePathTemplate = @"Objects\{0}\Description";
- //private const string ObjectsPath = @"Objects";
-
private readonly RegistryKey _rootKey;
public DiscUtilsRegistryStorage(RegistryKey key)
@@ -82,7 +77,7 @@ public override IEnumerable EnumerateObjects()
public override IEnumerable EnumerateElements(Guid obj)
{
- var path = string.Format(CultureInfo.InvariantCulture, ElementsPathTemplate, obj.ToString("B"));
+ var path = $@"Objects\{obj:B}\Elements";
var parentKey = _rootKey.OpenSubKey(path);
foreach (var key in parentKey.GetSubKeyNames())
{
@@ -92,7 +87,7 @@ public override IEnumerable EnumerateElements(Guid obj)
public override int GetObjectType(Guid obj)
{
- var path = string.Format(CultureInfo.InvariantCulture, ObjectTypePathTemplate, obj.ToString("B"));
+ var path = $@"Objects\{obj:B}\Description";
var descKey = _rootKey.OpenSubKey(path);
@@ -102,13 +97,13 @@ public override int GetObjectType(Guid obj)
public override bool HasValue(Guid obj, int element)
{
- var path = string.Format(CultureInfo.InvariantCulture, ElementPathTemplate, obj.ToString("B"), element);
+ var path = $@"Objects\{obj:B}\Elements\{element:X8}";
return _rootKey.OpenSubKey(path) != null;
}
public override bool ObjectExists(Guid obj)
{
- var path = string.Format(CultureInfo.InvariantCulture, ObjectTypePathTemplate, obj.ToString("B"));
+ var path = $@"Objects\{obj:B}\Description";
return _rootKey.OpenSubKey(path) != null;
}
@@ -116,7 +111,7 @@ public override bool ObjectExists(Guid obj)
public override Guid CreateObject(Guid obj, int type)
{
var realObj = obj == Guid.Empty ? Guid.NewGuid() : obj;
- var path = string.Format(CultureInfo.InvariantCulture, ObjectTypePathTemplate, realObj.ToString("B"));
+ var path = $@"Objects\{realObj:B}\Description";
var key = _rootKey.CreateSubKey(path);
key.SetValue("Type", type, RegistryValueType.Dword);
@@ -126,35 +121,35 @@ public override Guid CreateObject(Guid obj, int type)
public override void CreateElement(Guid obj, int element)
{
- var path = string.Format(CultureInfo.InvariantCulture, ElementPathTemplate, obj.ToString("B"), element);
+ var path = $@"Objects\{obj:B}\Elements\{element:X8}";
_rootKey.CreateSubKey(path);
}
public override void DeleteObject(Guid obj)
{
- var path = string.Format(CultureInfo.InvariantCulture, ObjectTypePathTemplate, obj.ToString("B"));
+ var path = $@"Objects\{obj:B}\Description";
_rootKey.DeleteSubKeyTree(path);
}
public override void DeleteElement(Guid obj, int element)
{
- var path = string.Format(CultureInfo.InvariantCulture, ElementPathTemplate, obj.ToString("B"), element);
+ var path = $@"Objects\{obj:B}\Elements\{element:X8}";
_rootKey.DeleteSubKeyTree(path);
}
private object GetValue(Guid obj, int element)
{
- var path = string.Format(CultureInfo.InvariantCulture, ElementPathTemplate, obj.ToString("B"), element);
+ var path = $@"Objects\{obj:B}\Elements\{element:X8}";
var key = _rootKey.OpenSubKey(path);
return key.GetValue("Element");
}
private void SetValue(Guid obj, int element, object value)
{
- var path = string.Format(CultureInfo.InvariantCulture, ElementPathTemplate, obj.ToString("B"), element);
+ var path = $@"Objects\{obj:B}\Elements\{element:X8}";
var key = _rootKey.OpenSubKey(path);
key.SetValue("Element", value);
}
diff --git a/Library/DiscUtils.Core/Compression/BZip2DecoderStream.cs b/Library/DiscUtils.Core/Compression/BZip2DecoderStream.cs
index 37877e634..235386a30 100644
--- a/Library/DiscUtils.Core/Compression/BZip2DecoderStream.cs
+++ b/Library/DiscUtils.Core/Compression/BZip2DecoderStream.cs
@@ -128,10 +128,14 @@ public override long Position
/// The number of bytes read.
public override int Read(byte[] buffer, int offset, int count)
{
+#if NET6_0_OR_GREATER
+ ArgumentNullException.ThrowIfNull(buffer);
+#else
if (buffer == null)
{
throw new ArgumentNullException(nameof(buffer));
}
+#endif
return Read(buffer.AsSpan(offset, count));
}
diff --git a/Library/DiscUtils.Core/Compression/ZlibStream.cs b/Library/DiscUtils.Core/Compression/ZlibStream.cs
index 4e20129d9..1d0052578 100644
--- a/Library/DiscUtils.Core/Compression/ZlibStream.cs
+++ b/Library/DiscUtils.Core/Compression/ZlibStream.cs
@@ -281,10 +281,14 @@ public override Task WriteAsync(byte[] buffer, int offset, int count, Cancellati
private static void CheckParams(byte[] buffer, int offset, int count)
{
+#if NET6_0_OR_GREATER
+ ArgumentNullException.ThrowIfNull(buffer);
+#else
if (buffer == null)
{
throw new ArgumentNullException(nameof(buffer));
}
+#endif
if (offset < 0 || offset > buffer.Length)
{
diff --git a/Library/DiscUtils.Core/DiscFileSystemInfo.cs b/Library/DiscUtils.Core/DiscFileSystemInfo.cs
index 83d50cd2f..bc57079a4 100644
--- a/Library/DiscUtils.Core/DiscFileSystemInfo.cs
+++ b/Library/DiscUtils.Core/DiscFileSystemInfo.cs
@@ -34,10 +34,14 @@ public class DiscFileSystemInfo
{
internal DiscFileSystemInfo(DiscFileSystem fileSystem, string path)
{
+#if NET6_0_OR_GREATER
+ ArgumentNullException.ThrowIfNull(path);
+#else
if (path == null)
{
throw new ArgumentNullException(nameof(path));
}
+#endif
var wrongPathSep = System.IO.Path.DirectorySeparatorChar == '\\' ? '/' : '\\';
diff --git a/Library/DiscUtils.Core/Partitions/BiosPartitionedDiskBuilder.cs b/Library/DiscUtils.Core/Partitions/BiosPartitionedDiskBuilder.cs
index cf1c99c25..10c586623 100644
--- a/Library/DiscUtils.Core/Partitions/BiosPartitionedDiskBuilder.cs
+++ b/Library/DiscUtils.Core/Partitions/BiosPartitionedDiskBuilder.cs
@@ -71,10 +71,14 @@ public BiosPartitionedDiskBuilder(long capacity, Geometry biosGeometry)
)]
public BiosPartitionedDiskBuilder(long capacity, byte[] bootSectors, Geometry biosGeometry)
{
+#if NET6_0_OR_GREATER
+ ArgumentNullException.ThrowIfNull(bootSectors);
+#else
if (bootSectors == null)
{
throw new ArgumentNullException(nameof(bootSectors));
}
+#endif
_capacity = capacity;
_biosGeometry = biosGeometry;
@@ -94,10 +98,14 @@ public BiosPartitionedDiskBuilder(long capacity, byte[] bootSectors, Geometry bi
/// The disk to clone.
public BiosPartitionedDiskBuilder(VirtualDisk sourceDisk)
{
+#if NET6_0_OR_GREATER
+ ArgumentNullException.ThrowIfNull(sourceDisk);
+#else
if (sourceDisk == null)
{
throw new ArgumentNullException(nameof(sourceDisk));
}
+#endif
_capacity = sourceDisk.Capacity;
_biosGeometry = sourceDisk.BiosGeometry;
diff --git a/Library/DiscUtils.Core/WindowsSecurity/AccessControl/GenericAce.cs b/Library/DiscUtils.Core/WindowsSecurity/AccessControl/GenericAce.cs
index b7397d614..420f0cda6 100644
--- a/Library/DiscUtils.Core/WindowsSecurity/AccessControl/GenericAce.cs
+++ b/Library/DiscUtils.Core/WindowsSecurity/AccessControl/GenericAce.cs
@@ -3,6 +3,7 @@
using LTRData.Extensions.Split;
using System;
using System.Globalization;
+using System.IO;
using System.Linq;
using System.Text;
@@ -117,7 +118,7 @@ public static bool TryCreateFromBinaryForm(byte[] binaryForm, int offset, out Ge
public static GenericAce CreateFromBinaryForm(ReadOnlySpan binaryForm)
{
- if (binaryForm == null)
+ if (binaryForm.IsEmpty)
{
throw new ArgumentNullException(nameof(binaryForm));
}
@@ -142,7 +143,7 @@ public static bool TryCreateFromBinaryForm(ReadOnlySpan binaryForm, out Ge
{
genericAce = null;
- if (binaryForm == null || 1 > binaryForm.Length)
+ if (binaryForm.IsEmpty || 1 > binaryForm.Length)
{
return false;
}
diff --git a/Library/DiscUtils.Core/WindowsSecurity/AccessControl/GenericSecurityDescriptor.cs b/Library/DiscUtils.Core/WindowsSecurity/AccessControl/GenericSecurityDescriptor.cs
index d11698951..b54d85e98 100644
--- a/Library/DiscUtils.Core/WindowsSecurity/AccessControl/GenericSecurityDescriptor.cs
+++ b/Library/DiscUtils.Core/WindowsSecurity/AccessControl/GenericSecurityDescriptor.cs
@@ -51,10 +51,14 @@ public int BinaryLength
public void GetBinaryForm(byte[] binaryForm, int offset)
{
+#if NET6_0_OR_GREATER
+ ArgumentNullException.ThrowIfNull(binaryForm);
+#else
if (null == binaryForm)
{
throw new ArgumentNullException(nameof(binaryForm));
}
+#endif
var binaryLength = BinaryLength;
if (offset < 0 || offset > binaryForm.Length - binaryLength)
diff --git a/Library/DiscUtils.Core/WindowsSecurity/AccessControl/ObjectAce.cs b/Library/DiscUtils.Core/WindowsSecurity/AccessControl/ObjectAce.cs
index d9a47c024..955369169 100644
--- a/Library/DiscUtils.Core/WindowsSecurity/AccessControl/ObjectAce.cs
+++ b/Library/DiscUtils.Core/WindowsSecurity/AccessControl/ObjectAce.cs
@@ -195,14 +195,7 @@ internal override string GetSddlForm()
inhObjType = _inheritedObjectType.ToString("D");
}
- return string.Format(CultureInfo.InvariantCulture,
- "({0};{1};{2};{3};{4};{5})",
- GetSddlAceType(AceType),
- GetSddlAceFlags(AceFlags),
- GetSddlAccessRights(AccessMask),
- objType,
- inhObjType,
- SecurityIdentifier.GetSddlForm());
+ return $"({GetSddlAceType(AceType)};{GetSddlAceFlags(AceFlags)};{GetSddlAccessRights(AccessMask)};{objType};{inhObjType};{SecurityIdentifier.GetSddlForm()})";
}
private static AceType ConvertType(AceQualifier qualifier, bool isCallback)
diff --git a/Library/DiscUtils.Core/WindowsSecurity/AccessControl/RawAcl.cs b/Library/DiscUtils.Core/WindowsSecurity/AccessControl/RawAcl.cs
index cba76aaac..66da3e9c5 100644
--- a/Library/DiscUtils.Core/WindowsSecurity/AccessControl/RawAcl.cs
+++ b/Library/DiscUtils.Core/WindowsSecurity/AccessControl/RawAcl.cs
@@ -27,7 +27,7 @@ public static bool TryParse(byte[] binaryForm, int offset, out RawAcl rawAcl) =>
public RawAcl(ReadOnlySpan binaryForm)
{
- if (binaryForm == null)
+ if (binaryForm.IsEmpty)
{
throw new ArgumentNullException(nameof(binaryForm));
}
@@ -147,10 +147,14 @@ public override void GetBinaryForm(Span binaryForm)
public void InsertAce(int index, GenericAce ace)
{
+#if NET6_0_OR_GREATER
+ ArgumentNullException.ThrowIfNull(ace);
+#else
if (ace == null)
{
throw new ArgumentNullException(nameof(ace));
}
+#endif
_list.Insert(index, ace);
}
diff --git a/Library/DiscUtils.Core/WindowsSecurity/AccessControl/RawSecurityDescriptor.cs b/Library/DiscUtils.Core/WindowsSecurity/AccessControl/RawSecurityDescriptor.cs
index 71370d29c..4b78f7d4a 100644
--- a/Library/DiscUtils.Core/WindowsSecurity/AccessControl/RawSecurityDescriptor.cs
+++ b/Library/DiscUtils.Core/WindowsSecurity/AccessControl/RawSecurityDescriptor.cs
@@ -21,10 +21,14 @@ public class RawSecurityDescriptor : GenericSecurityDescriptor
public RawSecurityDescriptor(string sddlForm)
{
+#if NET6_0_OR_GREATER
+ ArgumentNullException.ThrowIfNull(sddlForm);
+#else
if (sddlForm == null)
{
throw new ArgumentNullException(nameof(sddlForm));
}
+#endif
SetSddlForm(sddlForm.Replace(" ", ""));
diff --git a/Library/DiscUtils.Core/WindowsSecurity/NTAccount.cs b/Library/DiscUtils.Core/WindowsSecurity/NTAccount.cs
index c979d09cb..9f01586f2 100644
--- a/Library/DiscUtils.Core/WindowsSecurity/NTAccount.cs
+++ b/Library/DiscUtils.Core/WindowsSecurity/NTAccount.cs
@@ -8,6 +8,9 @@ public sealed class NTAccount : IdentityReference
public NTAccount(string name)
{
+#if NET8_0_OR_GREATER
+ ArgumentException.ThrowIfNullOrWhiteSpace(name);
+#else
if (name == null)
{
throw new ArgumentNullException(nameof(name));
@@ -17,12 +20,16 @@ public NTAccount(string name)
{
throw new ArgumentException("empty", nameof(name));
}
+#endif
Value = name;
}
public NTAccount(string domainName, string accountName)
{
+#if NET8_0_OR_GREATER
+ ArgumentException.ThrowIfNullOrWhiteSpace(accountName);
+#else
if (accountName == null)
{
throw new ArgumentNullException(nameof(accountName));
@@ -32,6 +39,7 @@ public NTAccount(string domainName, string accountName)
{
throw new ArgumentException("empty", nameof(accountName));
}
+#endif
if (domainName == null)
{
diff --git a/Library/DiscUtils.Fat/FatFileSystem.cs b/Library/DiscUtils.Fat/FatFileSystem.cs
index ed02a66e9..0fdf20f3d 100644
--- a/Library/DiscUtils.Fat/FatFileSystem.cs
+++ b/Library/DiscUtils.Fat/FatFileSystem.cs
@@ -1176,6 +1176,9 @@ public override IEnumerable GetFileSystemEntries(string path, string sea
/// The target directory name.
public override void MoveDirectory(string sourceDirectoryName, string destinationDirectoryName)
{
+#if NET8_0_OR_GREATER
+ ArgumentException.ThrowIfNullOrWhiteSpace(nameof(destinationDirectoryName));
+#else
if (string.IsNullOrEmpty(destinationDirectoryName))
{
if (destinationDirectoryName == null)
@@ -1185,6 +1188,7 @@ public override void MoveDirectory(string sourceDirectoryName, string destinatio
throw new ArgumentException("Invalid destination name (empty string)");
}
+#endif
var destId = GetDirectoryEntry(destinationDirectoryName, out var destParent);
if (destParent == null)
diff --git a/Library/DiscUtils.Fat/FileName.cs b/Library/DiscUtils.Fat/FileName.cs
index e7a31a448..7152658ac 100644
--- a/Library/DiscUtils.Fat/FileName.cs
+++ b/Library/DiscUtils.Fat/FileName.cs
@@ -92,10 +92,14 @@ public FileName(ReadOnlySpan data)
public FileName(string name, Encoding encoding)
{
+#if NET6_0_OR_GREATER
+ ArgumentNullException.ThrowIfNull(name);
+#else
if (name is null)
{
throw new ArgumentNullException(nameof(name));
}
+#endif
if (name.Length > 255)
{
diff --git a/Library/DiscUtils.HfsPlus/AttributeKey.cs b/Library/DiscUtils.HfsPlus/AttributeKey.cs
index 16aaf9aee..284514e2b 100644
--- a/Library/DiscUtils.HfsPlus/AttributeKey.cs
+++ b/Library/DiscUtils.HfsPlus/AttributeKey.cs
@@ -68,10 +68,14 @@ public override int CompareTo(BTreeKey other)
public int CompareTo(AttributeKey other)
{
+#if NET6_0_OR_GREATER
+ ArgumentNullException.ThrowIfNull(other);
+#else
if (other == null)
{
throw new ArgumentNullException(nameof(other));
}
+#endif
if (FileId != other.FileId)
{
diff --git a/Library/DiscUtils.HfsPlus/CatalogKey.cs b/Library/DiscUtils.HfsPlus/CatalogKey.cs
index b393c8922..4683e931b 100644
--- a/Library/DiscUtils.HfsPlus/CatalogKey.cs
+++ b/Library/DiscUtils.HfsPlus/CatalogKey.cs
@@ -45,10 +45,14 @@ public CatalogKey(CatalogNodeId nodeId, string name)
public int CompareTo(CatalogKey other)
{
+#if NET6_0_OR_GREATER
+ ArgumentNullException.ThrowIfNull(other);
+#else
if (other == null)
{
throw new ArgumentNullException(nameof(other));
}
+#endif
if (NodeId != other.NodeId)
{
diff --git a/Library/DiscUtils.HfsPlus/Directory.cs b/Library/DiscUtils.HfsPlus/Directory.cs
index fcd4e8e50..54595927f 100644
--- a/Library/DiscUtils.HfsPlus/Directory.cs
+++ b/Library/DiscUtils.HfsPlus/Directory.cs
@@ -79,6 +79,9 @@ public DirEntry Self
public DirEntry GetEntryByName(string name)
{
+#if NET8_0_OR_GREATER
+ ArgumentException.ThrowIfNullOrWhiteSpace(name);
+#else
if (name == null)
{
throw new ArgumentNullException(nameof(name));
@@ -88,6 +91,7 @@ public DirEntry GetEntryByName(string name)
{
throw new ArgumentException("Attempt to lookup empty file name", nameof(name));
}
+#endif
var dirEntryData = Context.Catalog.Find(new CatalogKey(NodeId, name));
if (dirEntryData == null)
diff --git a/Library/DiscUtils.HfsPlus/ExtentKey.cs b/Library/DiscUtils.HfsPlus/ExtentKey.cs
index 3ccf466d1..306d6d85a 100644
--- a/Library/DiscUtils.HfsPlus/ExtentKey.cs
+++ b/Library/DiscUtils.HfsPlus/ExtentKey.cs
@@ -47,10 +47,14 @@ public ExtentKey(CatalogNodeId cnid, uint startBlock, bool resource_fork = false
public int CompareTo(ExtentKey other)
{
+#if NET6_0_OR_GREATER
+ ArgumentNullException.ThrowIfNull(other);
+#else
if (other == null)
{
throw new ArgumentNullException(nameof(other));
}
+#endif
// Sort by file id, fork type, then starting block
if (NodeId != other.NodeId)
diff --git a/Library/DiscUtils.Registry/RegistryKey.cs b/Library/DiscUtils.Registry/RegistryKey.cs
index 0ca05efa4..878e359d6 100644
--- a/Library/DiscUtils.Registry/RegistryKey.cs
+++ b/Library/DiscUtils.Registry/RegistryKey.cs
@@ -48,8 +48,15 @@ public sealed class RegistryKey
internal RegistryKey(RegistryHive hive, KeyNodeCell cell)
{
+#if NET6_0_OR_GREATER
+ ArgumentNullException.ThrowIfNull(hive);
+ ArgumentNullException.ThrowIfNull(cell);
+ _hive = hive;
+ _cell = cell;
+#else
_hive = hive ?? throw new ArgumentNullException(nameof(hive));
_cell = cell ?? throw new ArgumentNullException(nameof(cell));
+#endif
}
///
diff --git a/Library/DiscUtils.SquashFs/SquashFileSystemBuilder.cs b/Library/DiscUtils.SquashFs/SquashFileSystemBuilder.cs
index a65c28418..87c4228a6 100644
--- a/Library/DiscUtils.SquashFs/SquashFileSystemBuilder.cs
+++ b/Library/DiscUtils.SquashFs/SquashFileSystemBuilder.cs
@@ -376,10 +376,14 @@ public override async Task BuildAsync(CancellationToken cancellationToke
/// The output stream must support seeking and writing.
public override void Build(Stream output)
{
+#if NET6_0_OR_GREATER
+ ArgumentNullException.ThrowIfNull(output);
+#else
if (output == null)
{
throw new ArgumentNullException(nameof(output));
}
+#endif
if (!output.CanWrite)
{
diff --git a/Library/DiscUtils.Streams/Builder/StreamBuilder.cs b/Library/DiscUtils.Streams/Builder/StreamBuilder.cs
index f4049369f..4543409d9 100644
--- a/Library/DiscUtils.Streams/Builder/StreamBuilder.cs
+++ b/Library/DiscUtils.Streams/Builder/StreamBuilder.cs
@@ -61,13 +61,7 @@ public virtual Task BuildAsync(CancellationToken cancellationToken)
public virtual void Build(Stream output)
{
using var src = Build();
- var buffer = new byte[64 * 1024];
- var numRead = src.Read(buffer, 0, buffer.Length);
- while (numRead != 0)
- {
- output.Write(buffer, 0, numRead);
- numRead = src.Read(buffer, 0, buffer.Length);
- }
+ src.CopyTo(output);
}
///
@@ -78,13 +72,7 @@ public virtual void Build(Stream output)
public virtual async Task BuildAsync(Stream output, CancellationToken cancellationToken)
{
using var src = await BuildAsync(cancellationToken).ConfigureAwait(false);
- var buffer = new byte[64 * 1024];
- var numRead = await src.ReadAsync(buffer, cancellationToken).ConfigureAwait(false);
- while (numRead != 0)
- {
- await output.WriteAsync(buffer.AsMemory(0, numRead), cancellationToken).ConfigureAwait(false);
- numRead = await src.ReadAsync(buffer, cancellationToken).ConfigureAwait(false);
- }
+ await src.CopyToAsync(output, cancellationToken).ConfigureAwait(false);
}
///
diff --git a/Library/DiscUtils.Streams/BuiltStream.cs b/Library/DiscUtils.Streams/BuiltStream.cs
index d438c4879..90d4af0ed 100644
--- a/Library/DiscUtils.Streams/BuiltStream.cs
+++ b/Library/DiscUtils.Streams/BuiltStream.cs
@@ -31,7 +31,7 @@ namespace DiscUtils.Streams;
public class BuiltStream : SparseStream
{
- private Stream _baseStream;
+ private ZeroStream _baseStream;
private BuilderExtent _currentExtent;
private readonly List _extents;
@@ -417,6 +417,10 @@ private struct ExtentRangeComparer : IComparer
{
public int Compare(BuilderExtent x, BuilderExtent y)
{
+#if NET6_0_OR_GREATER
+ ArgumentNullException.ThrowIfNull(x);
+ ArgumentNullException.ThrowIfNull(y);
+#else
if (x == null)
{
throw new ArgumentNullException(nameof(x));
@@ -426,6 +430,7 @@ public int Compare(BuilderExtent x, BuilderExtent y)
{
throw new ArgumentNullException(nameof(y));
}
+#endif
if (x.Start + x.Length <= y.Start)
{
@@ -448,6 +453,10 @@ private struct ExtentStartComparer : IComparer
{
public int Compare(BuilderExtent x, BuilderExtent y)
{
+#if NET6_0_OR_GREATER
+ ArgumentNullException.ThrowIfNull(x);
+ ArgumentNullException.ThrowIfNull(y);
+#else
if (x == null)
{
throw new ArgumentNullException(nameof(x));
@@ -457,6 +466,7 @@ public int Compare(BuilderExtent x, BuilderExtent y)
{
throw new ArgumentNullException(nameof(y));
}
+#endif
var val = x.Start - y.Start;
if (val < 0)
diff --git a/Library/DiscUtils.Streams/StreamBuffer.cs b/Library/DiscUtils.Streams/StreamBuffer.cs
index b73f882ae..b250bca90 100644
--- a/Library/DiscUtils.Streams/StreamBuffer.cs
+++ b/Library/DiscUtils.Streams/StreamBuffer.cs
@@ -43,10 +43,14 @@ public sealed class StreamBuffer : Buffer
/// Whether to dispose stream, when this object is disposed.
public StreamBuffer(Stream stream, Ownership ownership)
{
+#if NET6_0_OR_GREATER
+ ArgumentNullException.ThrowIfNull(stream);
+#else
if (stream == null)
{
throw new ArgumentNullException(nameof(stream));
}
+#endif
_stream = stream as SparseStream;
if (_stream == null)
diff --git a/Library/DiscUtils.Streams/Util/CompatExtensions.cs b/Library/DiscUtils.Streams/Util/CompatExtensions.cs
index 6ecd41b8e..8b158f2ba 100644
--- a/Library/DiscUtils.Streams/Util/CompatExtensions.cs
+++ b/Library/DiscUtils.Streams/Util/CompatExtensions.cs
@@ -15,20 +15,28 @@ public abstract class CompatibilityStream : Stream
{
public override Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
+#if NET6_0_OR_GREATER
+ ArgumentNullException.ThrowIfNull(buffer);
+#else
if (buffer == null)
{
throw new ArgumentNullException(nameof(buffer));
}
+#endif
return ReadAsync(buffer.AsMemory(offset, count), cancellationToken).AsTask();
}
public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
+#if NET6_0_OR_GREATER
+ ArgumentNullException.ThrowIfNull(buffer);
+#else
if (buffer == null)
{
throw new ArgumentNullException(nameof(buffer));
}
+#endif
return WriteAsync(buffer.AsMemory(offset, count), cancellationToken).AsTask();
}
@@ -229,6 +237,9 @@ public static void AppendData(this IncrementalHash hash, ReadOnlySpan data
ArrayPool.Shared.Return(bytes);
}
}
+
+ public static Task CopyToAsync(this Stream source, Stream target, CancellationToken cancellationToken)
+ => source.CopyToAsync(target, bufferSize: 80 * 1024, cancellationToken);
#endif
}
diff --git a/Library/DiscUtils.Streams/Util/StreamUtilities.cs b/Library/DiscUtils.Streams/Util/StreamUtilities.cs
index 07d8ffa09..ab052632d 100644
--- a/Library/DiscUtils.Streams/Util/StreamUtilities.cs
+++ b/Library/DiscUtils.Streams/Util/StreamUtilities.cs
@@ -39,7 +39,13 @@ public static class StreamUtilities
/// The number of bytes to read / write.
public static void AssertBufferParameters(byte[] buffer, int offset, int count)
{
- if (buffer is null)
+#if NET8_0_OR_GREATER
+ ArgumentNullException.ThrowIfNull(buffer);
+ ArgumentOutOfRangeException.ThrowIfNegative(offset);
+ ArgumentOutOfRangeException.ThrowIfNegative(count);
+ ArgumentOutOfRangeException.ThrowIfLessThan(buffer.Length, offset + count);
+#else
+ if (buffer == null)
{
throw new ArgumentNullException(nameof(buffer));
}
@@ -58,6 +64,7 @@ public static void AssertBufferParameters(byte[] buffer, int offset, int count)
{
throw new ArgumentException("buffer is too small", nameof(buffer));
}
+#endif
}
#region Stream Manipulation
diff --git a/Library/DiscUtils.Vhd/DynamicStream.cs b/Library/DiscUtils.Vhd/DynamicStream.cs
index 7a95ab0b8..b12f1b378 100644
--- a/Library/DiscUtils.Vhd/DynamicStream.cs
+++ b/Library/DiscUtils.Vhd/DynamicStream.cs
@@ -52,30 +52,36 @@ public class DynamicStream : MappedStream
internal DynamicStream(Stream fileStream, DynamicHeader dynamicHeader, long length, SparseStream parentStream,
Ownership ownsParentStream)
{
- if (fileStream == null)
- {
- throw new ArgumentNullException(nameof(fileStream));
- }
+#if NET6_0_OR_GREATER
+ ArgumentNullException.ThrowIfNull(fileStream);
+ ArgumentNullException.ThrowIfNull(dynamicHeader);
+ ArgumentNullException.ThrowIfNull(parentStream);
- if (dynamicHeader == null)
- {
- throw new ArgumentNullException(nameof(dynamicHeader));
- }
+ _fileStream = fileStream;
+ _dynamicHeader = dynamicHeader;
+ _parentStream = parentStream;
+#else
+ _fileStream = fileStream
+ ?? throw new ArgumentNullException(nameof(fileStream));
- if (parentStream == null)
- {
- throw new ArgumentNullException(nameof(parentStream));
- }
+ _dynamicHeader = dynamicHeader
+ ?? throw new ArgumentNullException(nameof(dynamicHeader));
+
+ _parentStream = parentStream
+ ?? throw new ArgumentNullException(nameof(parentStream));
+
+#endif
+#if NET8_0_OR_GREATER
+ ArgumentOutOfRangeException.ThrowIfNegative(length);
+#else
if (length < 0)
{
throw new ArgumentOutOfRangeException(nameof(length), length, "Negative lengths not allowed");
}
+#endif
- _fileStream = fileStream;
- _dynamicHeader = dynamicHeader;
_length = length;
- _parentStream = parentStream;
_ownsParentStream = ownsParentStream;
_blockBitmaps = new byte[_dynamicHeader.MaxTableEntries][];
diff --git a/Library/DiscUtils.VirtualFileSystem/VirtualFileSystemDirectoryEntry.cs b/Library/DiscUtils.VirtualFileSystem/VirtualFileSystemDirectoryEntry.cs
index 47ec0f1e4..107c655f9 100644
--- a/Library/DiscUtils.VirtualFileSystem/VirtualFileSystemDirectoryEntry.cs
+++ b/Library/DiscUtils.VirtualFileSystem/VirtualFileSystemDirectoryEntry.cs
@@ -38,21 +38,38 @@ public const UnixFilePermissions DefaultUnixFilePermissions
internal VirtualFileSystemDirectoryEntry(VirtualFileSystem fileSystem)
{
+#if NET6_0_OR_GREATER
+ ArgumentNullException.ThrowIfNull(fileSystem);
+ FileSystem = fileSystem;
+#else
FileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem));
+#endif
}
internal VirtualFileSystemDirectoryEntry(VirtualFileSystemDirectory parent, string name)
{
+#if NET6_0_OR_GREATER
+ ArgumentNullException.ThrowIfNull(parent);
+ ArgumentNullException.ThrowIfNull(parent.FileSystem);
+
+ Parent = parent;
+ FileSystem = parent.FileSystem;
+#else
Parent = parent
?? throw new ArgumentNullException(nameof(parent));
FileSystem = parent.FileSystem
?? throw new ArgumentException("FileSystem property is null", nameof(parent));
+#endif
- if (string.IsNullOrEmpty(name))
+#if NET8_0_OR_GREATER
+ ArgumentException.ThrowIfNullOrWhiteSpace(name);
+#else
+ if (string.IsNullOrWhiteSpace(name))
{
throw new ArgumentException("File names cannot be null or empty", nameof(name));
}
+#endif
parent.AddEntry(name, this);
diff --git a/Library/DiscUtils.Xva/HashStreamCore.cs b/Library/DiscUtils.Xva/HashStreamCore.cs
index 9af8f7f76..3b8e3b722 100644
--- a/Library/DiscUtils.Xva/HashStreamCore.cs
+++ b/Library/DiscUtils.Xva/HashStreamCore.cs
@@ -28,7 +28,6 @@
using DiscUtils.Streams;
using DiscUtils.Streams.Compatibility;
-#if NETSTANDARD || NETCOREAPP || NET461_OR_GREATER
internal class HashStreamCore : CompatibilityStream
{
private readonly IncrementalHash _hashAlg;
@@ -155,121 +154,3 @@ protected override void Dispose(bool disposing)
}
}
}
-#else
-internal class HashStreamDotnet : CompatibilityStream
-{
- private Stream _wrapped;
- private Ownership _ownWrapped;
-
- private HashAlgorithm _hashAlg;
-
- private long _hashPos;
-
- public HashStreamDotnet(Stream wrapped, Ownership ownsWrapped, HashAlgorithm hashAlg)
- {
- _wrapped = wrapped;
- _ownWrapped = ownsWrapped;
- _hashAlg = hashAlg;
- }
-
- public override bool CanRead => _wrapped.CanRead;
-
- public override bool CanSeek => _wrapped.CanSeek;
-
- public override bool CanWrite => _wrapped.CanWrite;
-
- public override long Length => _wrapped.Length;
-
- public override long Position
- {
- get => _wrapped.Position;
-
- set => _wrapped.Position = value;
- }
-
- public override void Flush()
- {
- _wrapped.Flush();
- }
-
- public override int Read(byte[] buffer, int offset, int count)
- {
- if (Position != _hashPos)
- {
- throw new InvalidOperationException("Reads must be contiguous");
- }
-
- var numRead = _wrapped.Read(buffer, offset, count);
-
- _hashAlg.TransformBlock(buffer, offset, numRead, buffer, offset);
- _hashPos += numRead;
-
- return numRead;
- }
-
- public override int Read(Span buffer) =>
- CompatExtensions.ReadUsingArray(this, buffer);
-
- public override long Seek(long offset, SeekOrigin origin)
- {
- return _wrapped.Seek(offset, origin);
- }
-
- public override void SetLength(long value)
- {
- _wrapped.SetLength(value);
- }
-
- public override void Write(byte[] buffer, int offset, int count)
- {
- _wrapped.Write(buffer, offset, count);
- }
-
- public override void Write(ReadOnlySpan buffer) => _wrapped.Write(buffer);
-
- public override Task FlushAsync(CancellationToken cancellationToken) =>
- _wrapped.FlushAsync(cancellationToken);
-
- public override async Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
- {
- if (Position != _hashPos)
- {
- throw new InvalidOperationException("Reads must be contiguous");
- }
-
- var numRead = await _wrapped.ReadAsync(buffer, offset, count, cancellationToken).ConfigureAwait(false);
-
- _hashAlg.TransformBlock(buffer, offset, numRead, buffer, offset);
- _hashPos += numRead;
-
- return numRead;
- }
-
- public override ValueTask ReadAsync(Memory buffer, CancellationToken cancellationToken = default) =>
- CompatExtensions.ReadUsingArrayAsync(this, buffer, cancellationToken);
-
- public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) =>
- _wrapped.WriteAsync(buffer, offset, count, cancellationToken);
-
- public override ValueTask WriteAsync(ReadOnlyMemory buffer, CancellationToken cancellationToken = default) =>
- _wrapped.WriteAsync(buffer, cancellationToken);
-
- public override void WriteByte(byte value) => _wrapped.WriteByte(value);
-
- protected override void Dispose(bool disposing)
- {
- try
- {
- if (disposing && _ownWrapped == Ownership.Dispose && _wrapped != null)
- {
- _wrapped.Dispose();
- _wrapped = null;
- }
- }
- finally
- {
- base.Dispose(disposing);
- }
- }
-}
-#endif
diff --git a/Library/DiscUtils.Xva/VirtualMachineBuilder.cs b/Library/DiscUtils.Xva/VirtualMachineBuilder.cs
index 172a51269..30048049f 100644
--- a/Library/DiscUtils.Xva/VirtualMachineBuilder.cs
+++ b/Library/DiscUtils.Xva/VirtualMachineBuilder.cs
@@ -30,6 +30,7 @@
using System.Threading.Tasks;
using DiscUtils.Archives;
using DiscUtils.Streams;
+using LTRData.Extensions.Formatting;
namespace DiscUtils.Xva;
@@ -137,25 +138,14 @@ public override Stream Build()
}
Stream chunkHashStream;
-#if NETSTANDARD || NETCOREAPP || NET461_OR_GREATER
var hashAlgCore = IncrementalHash.CreateHash(HashAlgorithmName.SHA1);
chunkHashStream = new HashStreamCore(chunkStream, Ownership.Dispose, hashAlgCore);
-#else
- HashAlgorithm hashAlgDotnet = new SHA1Managed();
- chunkHashStream = new HashStreamDotnet(chunkStream, Ownership.Dispose, hashAlgDotnet);
-#endif
tarBuilder.AddFile(string.Format(CultureInfo.InvariantCulture, "Ref:{0}/{1:D8}", diskIds[diskIdx], i), chunkHashStream);
- byte[] hash;
-#if NETSTANDARD || NETCOREAPP || NET461_OR_GREATER
- hash = hashAlgCore.GetHashAndReset();
-#else
- hashAlgDotnet.TransformFinalBlock(new byte[0], 0, 0);
- hash = hashAlgDotnet.Hash;
-#endif
+ var hash = hashAlgCore.GetHashAndReset();
- var hashString = BitConverter.ToString(hash).Replace("-", "").ToLower();
+ var hashString = hash.ToHexString();
var hashStringAscii = Encoding.ASCII.GetBytes(hashString);
tarBuilder.AddFile(string.Format(CultureInfo.InvariantCulture, "Ref:{0}/{1:D8}.checksum", diskIds[diskIdx], i), hashStringAscii);
@@ -171,25 +161,14 @@ public override Stream Build()
Stream chunkStream = new ZeroStream(Sizes.OneMiB);
Stream chunkHashStream;
-#if NETSTANDARD || NETCOREAPP || NET461_OR_GREATER
var hashAlgCore = IncrementalHash.CreateHash(HashAlgorithmName.SHA1);
chunkHashStream = new HashStreamCore(chunkStream, Ownership.Dispose, hashAlgCore);
-#else
- HashAlgorithm hashAlgDotnet = new SHA1Managed();
- chunkHashStream = new HashStreamDotnet(chunkStream, Ownership.Dispose, hashAlgDotnet);
-#endif
tarBuilder.AddFile(string.Format(CultureInfo.InvariantCulture, "Ref:{0}/{1:D8}", diskIds[diskIdx], lastActualChunk), chunkHashStream);
- byte[] hash;
-#if NETSTANDARD || NETCOREAPP || NET461_OR_GREATER
- hash = hashAlgCore.GetHashAndReset();
-#else
- hashAlgDotnet.TransformFinalBlock(new byte[0], 0, 0);
- hash = hashAlgDotnet.Hash;
-#endif
+ var hash = hashAlgCore.GetHashAndReset();
- var hashString = BitConverter.ToString(hash).Replace("-", "").ToLower();
+ var hashString = hash.ToHexString();
var hashStringAscii = Encoding.ASCII.GetBytes(hashString);
tarBuilder.AddFile(string.Format(CultureInfo.InvariantCulture, "Ref:{0}/{1:D8}.checksum", diskIds[diskIdx], lastActualChunk), hashStringAscii);
}
@@ -242,26 +221,14 @@ public override Task BuildAsync(CancellationToken cancellationToken)
chunkStream = new SubStream(diskStream, i * Sizes.OneMiB, Sizes.OneMiB);
}
- Stream chunkHashStream;
-#if NETSTANDARD || NETCOREAPP || NET461_OR_GREATER
var hashAlgCore = IncrementalHash.CreateHash(HashAlgorithmName.SHA1);
- chunkHashStream = new HashStreamCore(chunkStream, Ownership.Dispose, hashAlgCore);
-#else
- HashAlgorithm hashAlgDotnet = new SHA1Managed();
- chunkHashStream = new HashStreamDotnet(chunkStream, Ownership.Dispose, hashAlgDotnet);
-#endif
+ var chunkHashStream = new HashStreamCore(chunkStream, Ownership.Dispose, hashAlgCore);
tarBuilder.AddFile(string.Format(CultureInfo.InvariantCulture, "Ref:{0}/{1:D8}", diskIds[diskIdx], i), chunkHashStream);
- byte[] hash;
-#if NETSTANDARD || NETCOREAPP || NET461_OR_GREATER
- hash = hashAlgCore.GetHashAndReset();
-#else
- hashAlgDotnet.TransformFinalBlock(new byte[0], 0, 0);
- hash = hashAlgDotnet.Hash;
-#endif
+ var hash = hashAlgCore.GetHashAndReset();
- var hashString = BitConverter.ToString(hash).Replace("-", "").ToLower();
+ var hashString = hash.ToHexString();
var hashStringAscii = Encoding.ASCII.GetBytes(hashString);
tarBuilder.AddFile(string.Format(CultureInfo.InvariantCulture, "Ref:{0}/{1:D8}.checksum", diskIds[diskIdx], i), hashStringAscii);
@@ -276,26 +243,14 @@ public override Task BuildAsync(CancellationToken cancellationToken)
{
Stream chunkStream = new ZeroStream(Sizes.OneMiB);
- Stream chunkHashStream;
-#if NETSTANDARD || NETCOREAPP || NET461_OR_GREATER
var hashAlgCore = IncrementalHash.CreateHash(HashAlgorithmName.SHA1);
- chunkHashStream = new HashStreamCore(chunkStream, Ownership.Dispose, hashAlgCore);
-#else
- HashAlgorithm hashAlgDotnet = new SHA1Managed();
- chunkHashStream = new HashStreamDotnet(chunkStream, Ownership.Dispose, hashAlgDotnet);
-#endif
+ var chunkHashStream = new HashStreamCore(chunkStream, Ownership.Dispose, hashAlgCore);
tarBuilder.AddFile(string.Format(CultureInfo.InvariantCulture, "Ref:{0}/{1:D8}", diskIds[diskIdx], lastActualChunk), chunkHashStream);
- byte[] hash;
-#if NETSTANDARD || NETCOREAPP || NET461_OR_GREATER
- hash = hashAlgCore.GetHashAndReset();
-#else
- hashAlgDotnet.TransformFinalBlock(new byte[0], 0, 0);
- hash = hashAlgDotnet.Hash;
-#endif
+ var hash = hashAlgCore.GetHashAndReset();
- var hashString = BitConverter.ToString(hash).Replace("-", "").ToLower();
+ var hashString = hash.ToHexString();
var hashStringAscii = Encoding.ASCII.GetBytes(hashString);
tarBuilder.AddFile(string.Format(CultureInfo.InvariantCulture, "Ref:{0}/{1:D8}.checksum", diskIds[diskIdx], lastActualChunk), hashStringAscii);
}
diff --git a/Tests/LibraryTests/Btrfs/SampleDataTests.cs b/Tests/LibraryTests/Btrfs/SampleDataTests.cs
index 803b1f7b4..a918fdca9 100644
--- a/Tests/LibraryTests/Btrfs/SampleDataTests.cs
+++ b/Tests/LibraryTests/Btrfs/SampleDataTests.cs
@@ -9,7 +9,9 @@
using DiscUtils.Streams;
using DiscUtils.Vhdx;
using LibraryTests.Utilities;
+using LTRData.Extensions.Formatting;
using Xunit;
+using static LibraryTests.Helpers.Helpers;
namespace LibraryTests.Btrfs;
@@ -20,7 +22,7 @@ public void BtrfsVhdxZip()
{
DiscUtils.Setup.SetupHelper.RegisterAssembly(typeof(Disk).GetTypeInfo().Assembly);
DiscUtils.Setup.SetupHelper.RegisterAssembly(typeof(BtrfsFileSystem).GetTypeInfo().Assembly);
- using var vhdx = Helpers.Helpers.LoadTestDataFileFromGZipFile("Btrfs", "btrfs.vhdx.gz");
+ using var vhdx = LoadTestDataFileFromGZipFile("Btrfs", "btrfs.vhdx.gz");
using var diskImage = new DiskImageFile(vhdx, Ownership.Dispose);
using var disk = new Disk(new List { diskImage }, Ownership.Dispose);
var manager = new VolumeManager(disk);
@@ -47,45 +49,17 @@ public void BtrfsVhdxZip()
Assert.Equal(256UL, subvolumes[0].Id);
Assert.Equal("subvolume", subvolumes[0].Name);
- Assert.Equal("text\n", GetFileContent(@"\folder\subfolder\file", btrfs));
- Assert.Equal("f64464c2024778f347277de6fa26fe87", GetFileChecksum(@"\folder\subfolder\f64464c2024778f347277de6fa26fe87", btrfs));
- Assert.Equal("fa121c8b73cf3b01a4840b1041b35e9f", GetFileChecksum(@"\folder\subfolder\fa121c8b73cf3b01a4840b1041b35e9f", btrfs));
- IsAllZero(@"folder\subfolder\sparse", btrfs);
- Assert.Equal("test\n", GetFileContent(@"\subvolume\subvolumefolder\subvolumefile", btrfs));
- Assert.Equal("b0d5fae237588b6641f974459404d197", GetFileChecksum(@"\folder\subfolder\compressed", btrfs));
- Assert.Equal("test\n", GetFileContent(@"\folder\symlink", btrfs)); //PR#36
- Assert.Equal("b0d5fae237588b6641f974459404d197", GetFileChecksum(@"\folder\subfolder\lzo", btrfs));
+ Assert.Equal("text\n", GetFileContent(Path.Combine("folder","subfolder", "file"), btrfs));
+ Assert.Equal("f64464c2024778f347277de6fa26fe87", GetFileChecksum(Path.Combine("folder", "subfolder", "f64464c2024778f347277de6fa26fe87"), btrfs));
+ Assert.Equal("fa121c8b73cf3b01a4840b1041b35e9f", GetFileChecksum(Path.Combine("folder", "subfolder", "fa121c8b73cf3b01a4840b1041b35e9f"), btrfs));
+ AssertAllZero(Path.Combine("folder", "subfolder", "sparse"), btrfs);
+ Assert.Equal("test\n", GetFileContent(Path.Combine("subvolume", "subvolumefolder", "subvolumefile"), btrfs));
+ Assert.Equal("b0d5fae237588b6641f974459404d197", GetFileChecksum(Path.Combine("folder", "subfolder", "compressed"), btrfs));
+ Assert.Equal("test\n", GetFileContent(Path.Combine("folder", "symlink"), btrfs)); //PR#36
+ Assert.Equal("b0d5fae237588b6641f974459404d197", GetFileChecksum(Path.Combine("folder", "subfolder", "lzo"), btrfs));
}
using var subvolume = new BtrfsFileSystem(volume.Open(), new BtrfsFileSystemOptions { SubvolumeId = 256, VerifyChecksums = true });
- Assert.Equal("test\n", GetFileContent(@"\subvolumefolder\subvolumefile", subvolume));
- }
-
- private static void IsAllZero(string path, DiscFileSystem fs)
- {
- var fileInfo = fs.GetFileInfo(path);
- var buffer = new byte[4 * Sizes.OneKiB];
- using var file = fileInfo.OpenRead();
- var count = file.Read(buffer, 0, buffer.Length);
- for (var i = 0; i < count; i++)
- {
- Assert.Equal(0, buffer[i]);
- }
- }
-
- private static string GetFileContent(string path, IFileSystem fs)
- {
- var fileInfo = fs.GetFileInfo(path);
- using var file = fileInfo.OpenText();
- return file.ReadToEnd();
- }
-
- private static string GetFileChecksum(string path, DiscFileSystem fs)
- {
- var fileInfo = fs.GetFileInfo(path);
- using var md5 = MD5.Create();
- using var file = fileInfo.OpenRead();
- var checksum = md5.ComputeHash(file);
- return BitConverter.ToString(checksum).Replace("-", String.Empty).ToLower();
+ Assert.Equal("test\n", GetFileContent(Path.Combine("subvolumefolder", "subvolumefile"), subvolume));
}
}
\ No newline at end of file
diff --git a/Tests/LibraryTests/Helpers/Helpers.cs b/Tests/LibraryTests/Helpers/Helpers.cs
index 2f6c13d53..a46ee329e 100644
--- a/Tests/LibraryTests/Helpers/Helpers.cs
+++ b/Tests/LibraryTests/Helpers/Helpers.cs
@@ -1,6 +1,11 @@
-using System;
+using DiscUtils;
+using DiscUtils.Streams;
+using LTRData.Extensions.Formatting;
+using System;
using System.IO;
using System.IO.Compression;
+using System.Security.Cryptography;
+using Xunit;
namespace LibraryTests.Helpers;
@@ -36,4 +41,39 @@ public static Stream LoadTestDataFileFromGZipFile(string projectName, string dat
return ms;
}
+ public static string GetFileChecksum(string path, IFileSystem fs)
+ {
+#if NETCOREAPP
+ var fileInfo = fs.GetFileInfo(path);
+ using var file = fileInfo.OpenRead();
+ Span checksum = stackalloc byte[MD5.HashSizeInBytes];
+ MD5.HashData(file, checksum);
+ return checksum.ToHexString();
+#else
+ var fileInfo = fs.GetFileInfo(path);
+ using var md5 = MD5.Create();
+ using var file = fileInfo.OpenRead();
+ var checksum = md5.ComputeHash(file);
+ return checksum.ToHexString();
+#endif
+ }
+
+ public static void AssertAllZero(string path, IFileSystem fs)
+ {
+ var fileInfo = fs.GetFileInfo(path);
+ var buffer = new byte[4 * Sizes.OneKiB];
+ using var file = fileInfo.OpenRead();
+ var count = file.Read(buffer, 0, buffer.Length);
+ for (var i = 0; i < count; i++)
+ {
+ Assert.Equal(0, buffer[i]);
+ }
+ }
+
+ public static string GetFileContent(string path, IFileSystem fs)
+ {
+ var fileInfo = fs.GetFileInfo(path);
+ using var file = fileInfo.OpenText();
+ return file.ReadToEnd();
+ }
}
diff --git a/Tests/LibraryTests/Xfs/SampleDataTests.cs b/Tests/LibraryTests/Xfs/SampleDataTests.cs
index 3ced762d5..f15cb5124 100644
--- a/Tests/LibraryTests/Xfs/SampleDataTests.cs
+++ b/Tests/LibraryTests/Xfs/SampleDataTests.cs
@@ -10,6 +10,7 @@
using LibraryTests.Utilities;
using Xunit;
using File=System.IO.File;
+using static LibraryTests.Helpers.Helpers;
namespace LibraryTests.Xfs;
@@ -72,28 +73,22 @@ public void Xfs5VhdxZip()
private static void ValidateContent(DiscFileSystem xfs)
{
Assert.True(xfs.DirectoryExists(""));
- Assert.True(xfs.FileExists("folder\\nested\\file"));
+ Assert.True(xfs.FileExists(Path.Combine("folder", "nested", "file")));
Assert.Empty(xfs.GetFileSystemEntries("empty"));
for (var i = 1; i <= 1000; i++)
{
- Assert.True(xfs.FileExists($"folder\\file.{i}"), $"File file.{i} not found");
+ Assert.True(xfs.FileExists(Path.Combine("folder", $"file.{i}")), $"File file.{i} not found");
}
- using (var file = xfs.OpenFile("folder\\file.100", FileMode.Open))
- {
- var md5 = MD5.Create().ComputeHash(file);
- Assert.Equal("620f0b67a91f7f74151bc5be745b7110", BitConverter.ToString(md5).ToLowerInvariant().Replace("-", string.Empty));
- }
+ var md5 = GetFileChecksum(Path.Combine("folder", "file.100"), xfs);
+ Assert.Equal("620f0b67a91f7f74151bc5be745b7110", md5);
- using (var file = xfs.OpenFile("folder\\file.random", FileMode.Open))
- {
- var md5 = MD5.Create().ComputeHash(file);
- Assert.Equal("9a202a11d6e87688591eb97714ed56f1", BitConverter.ToString(md5).ToLowerInvariant().Replace("-", string.Empty));
- }
+ md5 = GetFileChecksum(Path.Combine("folder", "file.random"), xfs);
+ Assert.Equal("9a202a11d6e87688591eb97714ed56f1", md5);
for (var i = 1; i <= 999; i++)
{
- Assert.True(xfs.FileExists($"huge\\{i}"), $"File huge/{i} not found");
+ Assert.True(xfs.FileExists(Path.Combine("huge", $"{i}")), $"File huge/{i} not found");
}
}
}
\ No newline at end of file