From c3dc1597d0632cdae2015e8ec236221f54daf819 Mon Sep 17 00:00:00 2001 From: Glen Parker Date: Mon, 4 Mar 2024 16:07:29 -0800 Subject: [PATCH] Encoding, Cleanup Add utility to get the Latin1 encoding. Get rid of Streams.BytesToString() and .StringToBytes() methods. Provide extension methods on Encoding to take the place of deleted Streams methods. Use Latin1 encoding like any other Encoding. Minor cleanup. --- .../ApplePartitionMap/PartitionMapEntry.cs | 6 +- Library/DiscUtils.Core/Archives/TarFile.cs | 16 ++- Library/DiscUtils.Core/Archives/TarHeader.cs | 42 +++--- .../LogicalDiskManager/DatabaseHeader.cs | 8 +- .../LogicalDiskManager/DatabaseRecord.cs | 14 +- .../LogicalDiskManager/PrivateHeader.cs | 12 +- .../LogicalDiskManager/TocBlock.cs | 10 +- .../DiscUtils.Core/Partitions/GptHeader.cs | 9 +- Library/DiscUtils.Fat/FatFileSystem.cs | 12 +- Library/DiscUtils.Fat/FileName.cs | 3 +- .../ScsiInquiryStandardResponse.cs | 9 +- .../DiscUtils.Iso9660/BaseVolumeDescriptor.cs | 2 +- .../DiscUtils.Iso9660/BootValidationEntry.cs | 10 +- .../DiscUtils.Iso9660/BootVolumeDescriptor.cs | 7 +- Library/DiscUtils.Iso9660/IsoUtilities.cs | 10 +- .../RockRidge/PosixNameSystemUseEntry.cs | 6 +- .../DiscUtils.Iso9660/Susp/SystemUseEntry.cs | 5 +- .../MetadataLogicalVolumeSection.cs | 16 ++- Library/DiscUtils.Lvm/PhysicalVolume.cs | 7 +- Library/DiscUtils.Lvm/PhysicalVolumeLabel.cs | 11 +- Library/DiscUtils.Lvm/PvHeader.cs | 25 ++-- Library/DiscUtils.Lvm/VolumeGroupMetadata.cs | 10 +- Library/DiscUtils.Ntfs/BiosParameterBlock.cs | 11 +- Library/DiscUtils.Ntfs/FixupRecordBase.cs | 10 +- .../DiscUtils.Ntfs/NtfsFileSystemChecker.cs | 5 +- Library/DiscUtils.Registry/Cell.cs | 7 +- Library/DiscUtils.Registry/KeyNodeCell.cs | 10 +- Library/DiscUtils.Registry/SecurityCell.cs | 3 +- .../SubKeyHashedListCell.cs | 9 +- .../SubKeyIndirectListCell.cs | 9 +- Library/DiscUtils.Registry/ValueCell.cs | 12 +- Library/DiscUtils.Sdi/FileHeader.cs | 4 +- Library/DiscUtils.Sdi/SectionRecord.cs | 6 +- Library/DiscUtils.SquashFs/DirectoryRecord.cs | 4 +- Library/DiscUtils.SquashFs/MetablockReader.cs | 7 +- .../Util/CompatExtensions.cs | 42 +----- .../Util/EncodingExtensions.cs | 55 ++++++++ .../Util/EncodingUtilities.cs | 20 +++ .../DiscUtils.Streams/Util/EndianUtilities.cs | 121 +----------------- Library/DiscUtils.Swap/SwapHeader.cs | 15 ++- Library/DiscUtils.Vdi/HeaderRecord.cs | 12 +- Library/DiscUtils.Vdi/PreHeaderRecord.cs | 8 +- Library/DiscUtils.Vhd/DynamicHeader.cs | 10 +- Library/DiscUtils.Vhd/Footer.cs | 21 +-- Library/DiscUtils.Vhd/Header.cs | 7 +- Library/DiscUtils.Vhd/ParentLocator.cs | 14 +- Library/DiscUtils.Vhdx/DiskImageFileInfo.cs | 5 +- Library/DiscUtils.Vhdx/HeaderInfo.cs | 5 +- Library/DiscUtils.Vhdx/MetadataTableInfo.cs | 5 +- Library/DiscUtils.Vhdx/RegionTableInfo.cs | 5 +- Library/DiscUtils.Wim/FileHeader.cs | 4 +- .../DiscUtils.Xfs/BlockDirectoryDataEntry.cs | 6 +- .../DiscUtils.Xfs/ShortformDirectoryEntry.cs | 10 +- 53 files changed, 398 insertions(+), 314 deletions(-) create mode 100644 Library/DiscUtils.Streams/Util/EncodingExtensions.cs create mode 100644 Library/DiscUtils.Streams/Util/EncodingUtilities.cs diff --git a/Library/DiscUtils.Core/ApplePartitionMap/PartitionMapEntry.cs b/Library/DiscUtils.Core/ApplePartitionMap/PartitionMapEntry.cs index 560056354..39f2bcc5b 100644 --- a/Library/DiscUtils.Core/ApplePartitionMap/PartitionMapEntry.cs +++ b/Library/DiscUtils.Core/ApplePartitionMap/PartitionMapEntry.cs @@ -84,12 +84,14 @@ public int Size public int ReadFrom(ReadOnlySpan buffer) { + var latin1Encoding = EncodingUtilities.GetLatin1Encoding(); + Signature = EndianUtilities.ToUInt16BigEndian(buffer); MapEntries = EndianUtilities.ToUInt32BigEndian(buffer.Slice(4)); PhysicalBlockStart = EndianUtilities.ToUInt32BigEndian(buffer.Slice(8)); PhysicalBlocks = EndianUtilities.ToUInt32BigEndian(buffer.Slice(12)); - Name = EndianUtilities.BytesToString(buffer.Slice(16, 32)).TrimEnd('\0'); - Type = EndianUtilities.BytesToString(buffer.Slice(48, 32)).TrimEnd('\0'); + Name = latin1Encoding.GetString(buffer.Slice(16, 32)).TrimEnd('\0'); + Type = latin1Encoding.GetString(buffer.Slice(48, 32)).TrimEnd('\0'); LogicalBlockStart = EndianUtilities.ToUInt32BigEndian(buffer.Slice(80)); LogicalBlocks = EndianUtilities.ToUInt32BigEndian(buffer.Slice(84)); Flags = EndianUtilities.ToUInt32BigEndian(buffer.Slice(88)); diff --git a/Library/DiscUtils.Core/Archives/TarFile.cs b/Library/DiscUtils.Core/Archives/TarFile.cs index 2a1f11d0a..71c7a0607 100644 --- a/Library/DiscUtils.Core/Archives/TarFile.cs +++ b/Library/DiscUtils.Core/Archives/TarFile.cs @@ -20,15 +20,15 @@ // DEALINGS IN THE SOFTWARE. // -namespace DiscUtils.Archives; - using LTRData.Extensions.Buffers; -using Streams; +using DiscUtils.Streams; using System; using System.Buffers; using System.Collections.Generic; using System.IO; +namespace DiscUtils.Archives; + /// /// Minimal tar file format implementation. /// @@ -75,7 +75,11 @@ public TarFile(Stream fileStream) try { _fileStream.ReadExactly(buffer, 0, (int)hdr.FileLength); - long_path = EndianUtilities.BytesToString(TarHeader.ReadNullTerminatedString(buffer.AsSpan(0, (int)hdr.FileLength))); + + long_path = EncodingUtilities + .GetLatin1Encoding() + .GetString(TarHeader.ReadNullTerminatedString(buffer.AsSpan(0, (int)hdr.FileLength))); + _fileStream.Position += -(buffer.Length & 511) & 511; } finally @@ -225,7 +229,9 @@ public static IEnumerable EnumerateFiles(Stream archive) { archive.ReadExactly(data, 0, (int)hdr.FileLength); - long_path = EndianUtilities.BytesToString(TarHeader.ReadNullTerminatedString(data.AsSpan(0, (int)hdr.FileLength))); + long_path = EncodingUtilities + .GetLatin1Encoding() + .GetString(TarHeader.ReadNullTerminatedString(data.AsSpan(0, (int)hdr.FileLength))); } finally { diff --git a/Library/DiscUtils.Core/Archives/TarHeader.cs b/Library/DiscUtils.Core/Archives/TarHeader.cs index e95fd04f6..dbbd53b5a 100644 --- a/Library/DiscUtils.Core/Archives/TarHeader.cs +++ b/Library/DiscUtils.Core/Archives/TarHeader.cs @@ -20,11 +20,10 @@ // DEALINGS IN THE SOFTWARE. // -namespace DiscUtils.Archives; - -using Streams; using System; -using System.Linq; +using DiscUtils.Streams; + +namespace DiscUtils.Archives; public sealed class TarHeader { @@ -69,7 +68,9 @@ public TarHeader(byte[] buffer, int offset) public TarHeader(ReadOnlySpan buffer) { - FileName = EndianUtilities.BytesToString(ReadNullTerminatedString(buffer.Slice(0, 100))); + var latin1Encoding = EncodingUtilities.GetLatin1Encoding(); + + FileName = latin1Encoding.GetString(ReadNullTerminatedString(buffer.Slice(0, 100))); FileMode = (UnixFilePermissions)OctalToLong(ReadNullTerminatedString(buffer.Slice(100, 8))); OwnerId = (int)OctalToLong(ReadNullTerminatedString(buffer.Slice(108, 8))); GroupId = (int)OctalToLong(ReadNullTerminatedString(buffer.Slice(116, 8))); @@ -77,11 +78,11 @@ public TarHeader(ReadOnlySpan buffer) ModificationTime = DateTimeOffset.FromUnixTimeSeconds((uint)OctalToLong(ReadNullTerminatedString(buffer.Slice(136, 12)))); CheckSum = (int)OctalToLong(ReadNullTerminatedString(buffer.Slice(148, 8))); FileType = (UnixFileType)buffer[156]; - LinkName = EndianUtilities.BytesToString(ReadNullTerminatedString(buffer.Slice(157, 100))); - Magic = EndianUtilities.BytesToString(ReadNullTerminatedString(buffer.Slice(257, 6))); + LinkName = latin1Encoding.GetString(ReadNullTerminatedString(buffer.Slice(157, 100))); + Magic = latin1Encoding.GetString(ReadNullTerminatedString(buffer.Slice(257, 6))); Version = (int)OctalToLong(ReadNullTerminatedString(buffer.Slice(263, 2))); - OwnerName = EndianUtilities.BytesToString(ReadNullTerminatedString(buffer.Slice(265, 32))); - GroupName = EndianUtilities.BytesToString(ReadNullTerminatedString(buffer.Slice(297, 32))); + OwnerName = latin1Encoding.GetString(ReadNullTerminatedString(buffer.Slice(265, 32))); + GroupName = latin1Encoding.GetString(ReadNullTerminatedString(buffer.Slice(297, 32))); DevMajor = (int)OctalToLong(ReadNullTerminatedString(buffer.Slice(329, 8))); DevMinor = (int)OctalToLong(ReadNullTerminatedString(buffer.Slice(337, 8))); @@ -89,8 +90,7 @@ public TarHeader(ReadOnlySpan buffer) if (!prefix.IsEmpty) { - var parentPath = EndianUtilities.BytesToString(prefix); - FileName = $"{parentPath}/{FileName}"; + FileName = $"{latin1Encoding.GetString(prefix)}/{FileName}"; } LastAccessTime = DateTimeOffset.FromUnixTimeSeconds((uint)OctalToLong(ReadNullTerminatedString(buffer.Slice(476, 12)))); @@ -153,9 +153,11 @@ public void WriteTo(Span buffer) { buffer.Clear(); + var latin1Encoding = EncodingUtilities.GetLatin1Encoding(); + if (FileName.Length < 100) { - EndianUtilities.StringToBytes(FileName, buffer.Slice(0, 99)); + latin1Encoding.GetBytes(FileName, buffer.Slice(0, 99)); } else { @@ -167,17 +169,17 @@ public void WriteTo(Span buffer) } var prefix = FileName.AsSpan(0, split); - EndianUtilities.StringToBytes(prefix, buffer.Slice(345, 130)); + latin1Encoding.GetBytes(prefix, buffer.Slice(345, 130)); var filename = FileName.AsSpan(split + 1); - EndianUtilities.StringToBytes(filename, buffer.Slice(0, 99)); + latin1Encoding.GetBytes(filename, buffer.Slice(0, 99)); } - EndianUtilities.StringToBytes(LongToOctal((long)FileMode, 7), buffer.Slice(100, 7)); - EndianUtilities.StringToBytes(LongToOctal(OwnerId, 7), buffer.Slice(108, 7)); - EndianUtilities.StringToBytes(LongToOctal(GroupId, 7), buffer.Slice(116, 7)); - EndianUtilities.StringToBytes(LongToOctal(FileLength, 11), buffer.Slice(124, 11)); - EndianUtilities.StringToBytes(LongToOctal(ModificationTime.ToUnixTimeSeconds(), 11), buffer.Slice(136, 11)); + latin1Encoding.GetBytes(LongToOctal((long)FileMode, 7), buffer.Slice(100, 7)); + latin1Encoding.GetBytes(LongToOctal(OwnerId, 7), buffer.Slice(108, 7)); + latin1Encoding.GetBytes(LongToOctal(GroupId, 7), buffer.Slice(116, 7)); + latin1Encoding.GetBytes(LongToOctal(FileLength, 11), buffer.Slice(124, 11)); + latin1Encoding.GetBytes(LongToOctal(ModificationTime.ToUnixTimeSeconds(), 11), buffer.Slice(136, 11)); buffer.Slice(148, 8).Fill((byte)' '); @@ -189,7 +191,7 @@ public void WriteTo(Span buffer) checkSum += buffer[i]; } - EndianUtilities.StringToBytes(LongToOctal(checkSum, 7), buffer.Slice(148, 7)); + latin1Encoding.GetBytes(LongToOctal(checkSum, 7), buffer.Slice(148, 7)); buffer[155] = 0; } diff --git a/Library/DiscUtils.Core/LogicalDiskManager/DatabaseHeader.cs b/Library/DiscUtils.Core/LogicalDiskManager/DatabaseHeader.cs index 35ff43bda..0a5b9a89d 100644 --- a/Library/DiscUtils.Core/LogicalDiskManager/DatabaseHeader.cs +++ b/Library/DiscUtils.Core/LogicalDiskManager/DatabaseHeader.cs @@ -53,15 +53,17 @@ internal class DatabaseHeader public void ReadFrom(ReadOnlySpan buffer) { - Signature = EndianUtilities.BytesToString(buffer.Slice(0x00, 4)); + var latin1Encoding = EncodingUtilities.GetLatin1Encoding(); + + Signature = latin1Encoding.GetString(buffer.Slice(0x00, 4)); NumVBlks = EndianUtilities.ToUInt32BigEndian(buffer.Slice(0x04)); BlockSize = EndianUtilities.ToUInt32BigEndian(buffer.Slice(0x08)); HeaderSize = EndianUtilities.ToUInt32BigEndian(buffer.Slice(0x0C)); Unknown1 = EndianUtilities.ToUInt16BigEndian(buffer.Slice(0x10)); VersionNum = EndianUtilities.ToUInt16BigEndian(buffer.Slice(0x12)); VersionDenom = EndianUtilities.ToUInt16BigEndian(buffer.Slice(0x14)); - GroupName = EndianUtilities.BytesToString(buffer.Slice(0x16, 31)).Trim('\0'); - DiskGroupId = EndianUtilities.BytesToString(buffer.Slice(0x35, 0x40)).Trim('\0'); + GroupName = latin1Encoding.GetString(buffer.Slice(0x16, 31)).Trim('\0'); + DiskGroupId = latin1Encoding.GetString(buffer.Slice(0x35, 0x40)).Trim('\0'); // May be wrong way round... CommittedSequence = EndianUtilities.ToInt64BigEndian(buffer.Slice(0x75)); diff --git a/Library/DiscUtils.Core/LogicalDiskManager/DatabaseRecord.cs b/Library/DiscUtils.Core/LogicalDiskManager/DatabaseRecord.cs index add481e9e..58e5443f0 100644 --- a/Library/DiscUtils.Core/LogicalDiskManager/DatabaseRecord.cs +++ b/Library/DiscUtils.Core/LogicalDiskManager/DatabaseRecord.cs @@ -85,7 +85,10 @@ protected static string ReadVarString(byte[] buffer, ref int offset) { int length = buffer[offset]; - var result = EndianUtilities.BytesToString(buffer, offset + 1, length); + var result = EncodingUtilities + .GetLatin1Encoding() + .GetString(buffer, offset + 1, length); + offset += length + 1; return result; } @@ -116,7 +119,10 @@ protected static ulong ReadULong(byte[] buffer, ref int offset) protected static string ReadString(byte[] buffer, int len, ref int offset) { offset += len; - return EndianUtilities.BytesToString(buffer, offset - len, len); + + return EncodingUtilities + .GetLatin1Encoding() + .GetString(buffer, offset - len, len); } protected static Guid ReadBinaryGuid(byte[] buffer, ref int offset) @@ -129,7 +135,9 @@ protected static Guid ReadBinaryGuid(byte[] buffer, ref int offset) protected virtual void DoReadFrom(ReadOnlySpan buffer) { - Signature = EndianUtilities.BytesToString(buffer.Slice(0x00, 4)); + var latin1Encoding = EncodingUtilities.GetLatin1Encoding(); + + Signature = latin1Encoding.GetString(buffer.Slice(0x00, 4)); Label = EndianUtilities.ToUInt32BigEndian(buffer.Slice(0x04)); Counter = EndianUtilities.ToUInt32BigEndian(buffer.Slice(0x08)); Valid = EndianUtilities.ToUInt32BigEndian(buffer.Slice(0x0C)); diff --git a/Library/DiscUtils.Core/LogicalDiskManager/PrivateHeader.cs b/Library/DiscUtils.Core/LogicalDiskManager/PrivateHeader.cs index 739adae43..0988466b9 100644 --- a/Library/DiscUtils.Core/LogicalDiskManager/PrivateHeader.cs +++ b/Library/DiscUtils.Core/LogicalDiskManager/PrivateHeader.cs @@ -52,17 +52,19 @@ internal class PrivateHeader public void ReadFrom(ReadOnlySpan buffer) { - Signature = EndianUtilities.BytesToString(buffer.Slice(0x00, 8)); + var latin1Encoding = EncodingUtilities.GetLatin1Encoding(); + + Signature = latin1Encoding.GetString(buffer.Slice(0x00, 8)); Checksum = EndianUtilities.ToUInt32BigEndian(buffer.Slice(0x08)); Version = EndianUtilities.ToUInt32BigEndian(buffer.Slice(0x0C)); Timestamp = DateTime.FromFileTimeUtc(EndianUtilities.ToInt64BigEndian(buffer.Slice(0x10))); Unknown2 = EndianUtilities.ToInt64BigEndian(buffer.Slice(0x18)); Unknown3 = EndianUtilities.ToInt64BigEndian(buffer.Slice(0x20)); Unknown4 = EndianUtilities.ToInt64BigEndian(buffer.Slice(0x28)); - DiskId = EndianUtilities.BytesToString(buffer.Slice(0x30, 0x40)).Trim('\0'); - HostId = EndianUtilities.BytesToString(buffer.Slice(0x70, 0x40)).Trim('\0'); - DiskGroupId = EndianUtilities.BytesToString(buffer.Slice(0xB0, 0x40)).Trim('\0'); - DiskGroupName = EndianUtilities.BytesToString(buffer.Slice(0xF0, 31)).Trim('\0'); + DiskId = latin1Encoding.GetString(buffer.Slice(0x30, 0x40)).Trim('\0'); + HostId = latin1Encoding.GetString(buffer.Slice(0x70, 0x40)).Trim('\0'); + DiskGroupId = latin1Encoding.GetString(buffer.Slice(0xB0, 0x40)).Trim('\0'); + DiskGroupName = latin1Encoding.GetString(buffer.Slice(0xF0, 31)).Trim('\0'); Unknown5 = EndianUtilities.ToUInt32BigEndian(buffer.Slice(0x10F)); DataStartLba = EndianUtilities.ToInt64BigEndian(buffer.Slice(0x11B)); DataSizeLba = EndianUtilities.ToInt64BigEndian(buffer.Slice(0x123)); diff --git a/Library/DiscUtils.Core/LogicalDiskManager/TocBlock.cs b/Library/DiscUtils.Core/LogicalDiskManager/TocBlock.cs index 1bcde5e1a..17f469183 100644 --- a/Library/DiscUtils.Core/LogicalDiskManager/TocBlock.cs +++ b/Library/DiscUtils.Core/LogicalDiskManager/TocBlock.cs @@ -20,8 +20,8 @@ // DEALINGS IN THE SOFTWARE. // -using DiscUtils.Streams; using System; +using DiscUtils.Streams; namespace DiscUtils.LogicalDiskManager; @@ -45,17 +45,19 @@ internal class TocBlock public void ReadFrom(ReadOnlySpan buffer) { - Signature = EndianUtilities.BytesToString(buffer.Slice(0x00, 8)); + var latin1Encoding = EncodingUtilities.GetLatin1Encoding(); + + Signature = latin1Encoding.GetString(buffer.Slice(0x00, 8)); Checksum = EndianUtilities.ToUInt32BigEndian(buffer.Slice(0x08)); SequenceNumber = EndianUtilities.ToInt64BigEndian(buffer.Slice(0x0C)); Unknown1 = EndianUtilities.ToInt64BigEndian(buffer.Slice(0x14)); Unknown2 = EndianUtilities.ToInt64BigEndian(buffer.Slice(0x1C)); - Item1Str = EndianUtilities.BytesToString(buffer.Slice(0x24, 10)).Trim('\0'); + Item1Str = latin1Encoding.GetString(buffer.Slice(0x24, 10)).Trim('\0'); Item1Start = EndianUtilities.ToInt64BigEndian(buffer.Slice(0x2E)); Item1Size = EndianUtilities.ToInt64BigEndian(buffer.Slice(0x36)); Unknown3 = EndianUtilities.ToUInt32BigEndian(buffer.Slice(0x3E)); Unknown4 = EndianUtilities.ToUInt32BigEndian(buffer.Slice(0x42)); - Item2Str = EndianUtilities.BytesToString(buffer.Slice(0x46, 10)).Trim('\0'); + Item2Str = latin1Encoding.GetString(buffer.Slice(0x46, 10)).Trim('\0'); Item2Start = EndianUtilities.ToInt64BigEndian(buffer.Slice(0x50)); Item2Size = EndianUtilities.ToInt64BigEndian(buffer.Slice(0x58)); Unknown5 = EndianUtilities.ToUInt32BigEndian(buffer.Slice(0x60)); diff --git a/Library/DiscUtils.Core/Partitions/GptHeader.cs b/Library/DiscUtils.Core/Partitions/GptHeader.cs index e01b4989a..c6009dddd 100644 --- a/Library/DiscUtils.Core/Partitions/GptHeader.cs +++ b/Library/DiscUtils.Core/Partitions/GptHeader.cs @@ -77,7 +77,9 @@ public GptHeader(GptHeader toCopy) public bool ReadFrom(ReadOnlySpan buffer) { - Signature = EndianUtilities.BytesToString(buffer.Slice(0, 8)); + var latin1Encoding = EncodingUtilities.GetLatin1Encoding(); + + Signature = latin1Encoding.GetString(buffer.Slice(0, 8)); Version = EndianUtilities.ToUInt32LittleEndian(buffer.Slice(8)); HeaderSize = EndianUtilities.ToInt32LittleEndian(buffer.Slice(12)); Crc = EndianUtilities.ToUInt32LittleEndian(buffer.Slice(16)); @@ -111,7 +113,10 @@ public void WriteTo(Span buffer) Buffer.CopyTo(buffer); // Next, write the fields - EndianUtilities.StringToBytes(Signature, buffer.Slice(0, 8)); + EncodingUtilities + .GetLatin1Encoding() + .GetBytes(Signature, buffer.Slice(0, 8)); + EndianUtilities.WriteBytesLittleEndian(Version, buffer.Slice(8)); EndianUtilities.WriteBytesLittleEndian(HeaderSize, buffer.Slice(12)); EndianUtilities.WriteBytesLittleEndian((uint)0, buffer.Slice(16)); diff --git a/Library/DiscUtils.Fat/FatFileSystem.cs b/Library/DiscUtils.Fat/FatFileSystem.cs index 9a4e8d892..9c05e9b16 100644 --- a/Library/DiscUtils.Fat/FatFileSystem.cs +++ b/Library/DiscUtils.Fat/FatFileSystem.cs @@ -1498,7 +1498,9 @@ private static void WriteBPB( bootSector[2] = 0x90; // OEM Name - EndianUtilities.StringToBytes("DISCUTIL", bootSector.Slice(3, 8)); + EncodingUtilities + .GetLatin1Encoding() + .GetBytes("DISCUTIL", bootSector.Slice(3, 8)); // Bytes Per Sector (512) bootSector[11] = 0; @@ -1610,11 +1612,13 @@ private static void WriteBS(Span bootSector, bool isFloppy, uint volId, st // Volume Id EndianUtilities.WriteBytesLittleEndian(volId, bootSector.Slice(3)); + var encoding = EncodingUtilities.GetLatin1Encoding(); + // Volume Label - EndianUtilities.StringToBytes(label.PadRight(11, ' ').AsSpan(0, 11), bootSector.Slice(7, 11)); + encoding.GetBytes(label.PadRight(11, ' ').AsSpan(0, 11), bootSector.Slice(7, 11)); // File System Type - EndianUtilities.StringToBytes(fsType, bootSector.Slice(18, 8)); + encoding.GetBytes(fsType, bootSector.Slice(18, 8)); } private static FatType DetectFATType(byte[] bpb) @@ -1927,7 +1931,7 @@ public static FatFileSystem FormatFloppy(Stream stream, FloppyDiskType type, str } else { - throw new ArgumentException("Unrecognised Floppy Disk type", nameof(type)); + throw new ArgumentException("Unrecognized Floppy Disk type", nameof(type)); } stream.Write(bpb); diff --git a/Library/DiscUtils.Fat/FileName.cs b/Library/DiscUtils.Fat/FileName.cs index 1693d8102..a9feefd03 100644 --- a/Library/DiscUtils.Fat/FileName.cs +++ b/Library/DiscUtils.Fat/FileName.cs @@ -25,6 +25,7 @@ using System.Runtime.InteropServices; using System.Text; using DiscUtils.Internal; +using DiscUtils.Streams; using DiscUtils.Streams.Compatibility; namespace DiscUtils.Fat; @@ -105,7 +106,7 @@ public FileName(string name, Encoding encoding) Span bytes = stackalloc byte[encoding.GetByteCount(name)]; - encoding.GetBytes(name.AsSpan(), bytes); + encoding.GetBytes(name, bytes); if (bytes.Length == 0) { diff --git a/Library/DiscUtils.Iscsi/ScsiInquiryStandardResponse.cs b/Library/DiscUtils.Iscsi/ScsiInquiryStandardResponse.cs index ca38b9c94..2adeee9d8 100644 --- a/Library/DiscUtils.Iscsi/ScsiInquiryStandardResponse.cs +++ b/Library/DiscUtils.Iscsi/ScsiInquiryStandardResponse.cs @@ -58,12 +58,13 @@ public override void ReadFrom(byte[] buffer, int offset, int count) return; } + var latin1Encoding = EncodingUtilities.GetLatin1Encoding(); + DeviceType = (LunClass)(buffer[0] & 0x1F); Removable = (buffer[1] & 0x80) != 0; SpecificationVersion = buffer[2]; - - VendorId = EndianUtilities.BytesToString(buffer, 8, 8); - ProductId = EndianUtilities.BytesToString(buffer, 16, 16); - ProductRevision = EndianUtilities.BytesToString(buffer, 32, 4); + VendorId = latin1Encoding.GetString(buffer, 8, 8); + ProductId = latin1Encoding.GetString(buffer, 16, 16); + ProductRevision = latin1Encoding.GetString(buffer, 32, 4); } } \ No newline at end of file diff --git a/Library/DiscUtils.Iso9660/BaseVolumeDescriptor.cs b/Library/DiscUtils.Iso9660/BaseVolumeDescriptor.cs index 7bfff2499..5981a4949 100644 --- a/Library/DiscUtils.Iso9660/BaseVolumeDescriptor.cs +++ b/Library/DiscUtils.Iso9660/BaseVolumeDescriptor.cs @@ -20,9 +20,9 @@ // DEALINGS IN THE SOFTWARE. // -using DiscUtils.Streams.Compatibility; using System; using System.Text; +using DiscUtils.Streams; namespace DiscUtils.Iso9660; diff --git a/Library/DiscUtils.Iso9660/BootValidationEntry.cs b/Library/DiscUtils.Iso9660/BootValidationEntry.cs index c8bf07bb8..d0fa2f1e8 100644 --- a/Library/DiscUtils.Iso9660/BootValidationEntry.cs +++ b/Library/DiscUtils.Iso9660/BootValidationEntry.cs @@ -46,7 +46,9 @@ public BootValidationEntry(byte[] src, int offset) HeaderId = _data[0]; PlatformId = _data[1]; - ManfId = EndianUtilities.BytesToString(_data, 4, 24).AsSpan().TrimEnd('\0').TrimEnd(' ').ToString(); + ManfId = EncodingUtilities + .GetLatin1Encoding() + .GetString(_data, 4, 24).AsSpan().TrimEnd('\0').TrimEnd(' ').ToString(); } public bool ChecksumValid @@ -68,7 +70,11 @@ internal void WriteTo(byte[] buffer, int offset) Array.Clear(buffer, offset, 0x20); buffer[offset + 0x00] = HeaderId; buffer[offset + 0x01] = PlatformId; - EndianUtilities.StringToBytes(ManfId, buffer, offset + 0x04, 24); + + EncodingUtilities + .GetLatin1Encoding() + .GetBytes(ManfId, 0, ManfId.Length, buffer, offset + 4); + buffer[offset + 0x1E] = 0x55; buffer[offset + 0x1F] = 0xAA; EndianUtilities.WriteBytesLittleEndian(CalcChecksum(buffer, offset), buffer, offset + 0x1C); diff --git a/Library/DiscUtils.Iso9660/BootVolumeDescriptor.cs b/Library/DiscUtils.Iso9660/BootVolumeDescriptor.cs index 12f1fdddd..14ce2a4c8 100644 --- a/Library/DiscUtils.Iso9660/BootVolumeDescriptor.cs +++ b/Library/DiscUtils.Iso9660/BootVolumeDescriptor.cs @@ -20,8 +20,8 @@ // DEALINGS IN THE SOFTWARE. // -using DiscUtils.Streams; using System; +using DiscUtils.Streams; namespace DiscUtils.Iso9660; @@ -50,7 +50,10 @@ internal override void WriteTo(Span buffer) { base.WriteTo(buffer); - EndianUtilities.StringToBytes(ElToritoSystemIdentifier, buffer.Slice(7, 0x20)); + EncodingUtilities + .GetLatin1Encoding() + .GetBytes(ElToritoSystemIdentifier, buffer.Slice(7, 0x20)); + EndianUtilities.WriteBytesLittleEndian(CatalogSector, buffer.Slice(0x47)); } } \ No newline at end of file diff --git a/Library/DiscUtils.Iso9660/IsoUtilities.cs b/Library/DiscUtils.Iso9660/IsoUtilities.cs index 9944c205b..1e29731c1 100644 --- a/Library/DiscUtils.Iso9660/IsoUtilities.cs +++ b/Library/DiscUtils.Iso9660/IsoUtilities.cs @@ -360,7 +360,9 @@ internal static DateTime ToDateTimeFromVolumeDescriptorTime(ReadOnlySpan d return DateTime.MinValue; } - var strForm = EndianUtilities.BytesToString(data.Slice(0, 16)); + var strForm = EncodingUtilities + .GetLatin1Encoding() + .GetString(data.Slice(0, 16)); // Work around bugs in burning software that may use zero bytes (rather than '0' characters) strForm = strForm.Replace('\0', '0'); @@ -398,7 +400,11 @@ internal static void ToVolumeDescriptorTimeFromUTC(Span buffer, DateTime d } var strForm = dateTime.ToString("yyyyMMddHHmmssff", CultureInfo.InvariantCulture); - EndianUtilities.StringToBytes(strForm, buffer.Slice(0, 16)); + + EncodingUtilities + .GetLatin1Encoding() + .GetBytes(strForm, buffer.Slice(0, 16)); + buffer[16] = 0; } diff --git a/Library/DiscUtils.Iso9660/RockRidge/PosixNameSystemUseEntry.cs b/Library/DiscUtils.Iso9660/RockRidge/PosixNameSystemUseEntry.cs index c28a58d3f..53626aca6 100644 --- a/Library/DiscUtils.Iso9660/RockRidge/PosixNameSystemUseEntry.cs +++ b/Library/DiscUtils.Iso9660/RockRidge/PosixNameSystemUseEntry.cs @@ -20,8 +20,8 @@ // DEALINGS IN THE SOFTWARE. // -using DiscUtils.Streams; using System; +using DiscUtils.Streams; namespace DiscUtils.Iso9660; @@ -35,6 +35,8 @@ public PosixNameSystemUseEntry(string name, byte length, byte version, ReadOnlyS CheckAndSetCommonProperties(name, length, version, 5, 1); Flags = data[4]; - NameData = EndianUtilities.BytesToString(data.Slice(5, length - 5)); + NameData = EncodingUtilities + .GetLatin1Encoding() + .GetString(data.Slice(5, length - 5)); } } \ No newline at end of file diff --git a/Library/DiscUtils.Iso9660/Susp/SystemUseEntry.cs b/Library/DiscUtils.Iso9660/Susp/SystemUseEntry.cs index a30a88aa0..54231a33c 100644 --- a/Library/DiscUtils.Iso9660/Susp/SystemUseEntry.cs +++ b/Library/DiscUtils.Iso9660/Susp/SystemUseEntry.cs @@ -44,7 +44,10 @@ public static SystemUseEntry Parse(ReadOnlySpan data, Encoding encoding, S return null; } - var name = EndianUtilities.BytesToString(data.Slice(0, 2)); + var name = EncodingUtilities + .GetLatin1Encoding() + .GetString(data.Slice(0, 2)); + length = data[2]; var version = data[3]; diff --git a/Library/DiscUtils.Lvm/MetadataLogicalVolumeSection.cs b/Library/DiscUtils.Lvm/MetadataLogicalVolumeSection.cs index 2646cc503..b0a19b33a 100644 --- a/Library/DiscUtils.Lvm/MetadataLogicalVolumeSection.cs +++ b/Library/DiscUtils.Lvm/MetadataLogicalVolumeSection.cs @@ -20,16 +20,16 @@ // DEALINGS IN THE SOFTWARE. // -namespace DiscUtils.Lvm; - using System; using System.IO; using System.Collections.Generic; -using DiscUtils.Streams; using System.Linq; using System.Runtime.InteropServices; +using DiscUtils.Streams; using LTRData.Extensions.Buffers; +namespace DiscUtils.Lvm; + internal class MetadataLogicalVolumeSection { public string Name; @@ -43,12 +43,12 @@ internal class MetadataLogicalVolumeSection public List Segments; private Dictionary _pvs; private ulong _extentSize; + internal void Parse(string head, TextReader data) { var segments = new List(); Name = head.AsSpan().Trim().TrimEnd('{').TrimEnd().ToString(); string line; - Span guid = stackalloc byte[16]; while ((line = Metadata.ReadLine(data)) != null) { @@ -60,7 +60,13 @@ internal void Parse(string head, TextReader data) { case "id": Id = Metadata.ParseStringValue(parameter.Value.Span); - EndianUtilities.StringToBytes(Id.Replace("-", String.Empty), guid); + + Span guid = stackalloc byte[16]; + + EncodingUtilities + .GetLatin1Encoding() + .GetBytes(Id.Replace("-", String.Empty).AsSpan(0, 16), guid); + // Mark it as a version 4 GUID guid[7] = (byte)((guid[7] | 0x40) & 0x4f); guid[8] = (byte)((guid[8] | 0x80) & 0xbf); diff --git a/Library/DiscUtils.Lvm/PhysicalVolume.cs b/Library/DiscUtils.Lvm/PhysicalVolume.cs index 947eeb2b4..bd86851fc 100644 --- a/Library/DiscUtils.Lvm/PhysicalVolume.cs +++ b/Library/DiscUtils.Lvm/PhysicalVolume.cs @@ -24,10 +24,8 @@ namespace DiscUtils.Lvm; using System; using System.IO; -using System.Linq; using DiscUtils.Partitions; using DiscUtils.Streams; -using DiscUtils.Streams.Compatibility; internal class PhysicalVolume { @@ -94,7 +92,10 @@ private static bool SearchLabel(Stream content, out PhysicalVolumeLabel pvLabel) return false; } - var label = EndianUtilities.BytesToString(buffer, 0x0, 0x8); + var label = EncodingUtilities + .GetLatin1Encoding() + .GetString(buffer, 0x0, 0x8); + if (label == PhysicalVolumeLabel.LABEL_ID) { pvLabel = new PhysicalVolumeLabel(); diff --git a/Library/DiscUtils.Lvm/PhysicalVolumeLabel.cs b/Library/DiscUtils.Lvm/PhysicalVolumeLabel.cs index a3a46de81..36bb7489f 100644 --- a/Library/DiscUtils.Lvm/PhysicalVolumeLabel.cs +++ b/Library/DiscUtils.Lvm/PhysicalVolumeLabel.cs @@ -20,11 +20,11 @@ // DEALINGS IN THE SOFTWARE. // -namespace DiscUtils.Lvm; - using DiscUtils.Streams; using System; +namespace DiscUtils.Lvm; + internal class PhysicalVolumeLabel : IByteArraySerializable { public const string LABEL_ID = "LABELONE"; @@ -43,12 +43,15 @@ internal class PhysicalVolumeLabel : IByteArraySerializable /// public int ReadFrom(ReadOnlySpan buffer) { - Label = EndianUtilities.BytesToString(buffer.Slice(0, 0x8)); + var latin1Encoding = EncodingUtilities.GetLatin1Encoding(); + + Label = latin1Encoding.GetString(buffer.Slice(0, 0x8)); Sector = EndianUtilities.ToUInt64LittleEndian(buffer.Slice(0x8)); Crc = EndianUtilities.ToUInt32LittleEndian(buffer.Slice(0x10)); CalculatedCrc = PhysicalVolume.CalcCrc(buffer.Slice(0x14, PhysicalVolume.SECTOR_SIZE - 0x14)); Offset = EndianUtilities.ToUInt32LittleEndian(buffer.Slice(0x14)); - Label2 = EndianUtilities.BytesToString(buffer.Slice(0x18, 0x8)); + Label2 = latin1Encoding.GetString(buffer.Slice(0x18, 0x8)); + return Size; } diff --git a/Library/DiscUtils.Lvm/PvHeader.cs b/Library/DiscUtils.Lvm/PvHeader.cs index 0c09c31a2..0040819e6 100644 --- a/Library/DiscUtils.Lvm/PvHeader.cs +++ b/Library/DiscUtils.Lvm/PvHeader.cs @@ -20,13 +20,13 @@ // DEALINGS IN THE SOFTWARE. // -namespace DiscUtils.Lvm; - using DiscUtils.Streams; using System; using System.Collections.Generic; using System.Text; +namespace DiscUtils.Lvm; + internal class PvHeader : IByteArraySerializable { public string Uuid; @@ -71,15 +71,16 @@ void IByteArraySerializable.WriteTo(Span buffer) private static string ReadUuid(ReadOnlySpan buffer) { - var sb = new StringBuilder() - .Append(EndianUtilities.BytesToString(buffer.Slice(0, 0x6))).Append('-') - .Append(EndianUtilities.BytesToString(buffer.Slice(0x6, 0x4))).Append('-') - .Append(EndianUtilities.BytesToString(buffer.Slice(0xA, 0x4))).Append('-') - .Append(EndianUtilities.BytesToString(buffer.Slice(0xE, 0x4))).Append('-') - .Append(EndianUtilities.BytesToString(buffer.Slice(0x12, 0x4))).Append('-') - .Append(EndianUtilities.BytesToString(buffer.Slice(0x16, 0x4))).Append('-') - .Append(EndianUtilities.BytesToString(buffer.Slice(0x1A, 0x6))); - - return sb.ToString(); + var latin1Encoding = EncodingUtilities.GetLatin1Encoding(); + + return new StringBuilder() + .Append(latin1Encoding.GetString(buffer.Slice(0, 0x6))).Append('-') + .Append(latin1Encoding.GetString(buffer.Slice(0x6, 0x4))).Append('-') + .Append(latin1Encoding.GetString(buffer.Slice(0xA, 0x4))).Append('-') + .Append(latin1Encoding.GetString(buffer.Slice(0xE, 0x4))).Append('-') + .Append(latin1Encoding.GetString(buffer.Slice(0x12, 0x4))).Append('-') + .Append(latin1Encoding.GetString(buffer.Slice(0x16, 0x4))).Append('-') + .Append(latin1Encoding.GetString(buffer.Slice(0x1A, 0x6))) + .ToString(); } } diff --git a/Library/DiscUtils.Lvm/VolumeGroupMetadata.cs b/Library/DiscUtils.Lvm/VolumeGroupMetadata.cs index b53bab11d..184562f1a 100644 --- a/Library/DiscUtils.Lvm/VolumeGroupMetadata.cs +++ b/Library/DiscUtils.Lvm/VolumeGroupMetadata.cs @@ -20,13 +20,13 @@ // DEALINGS IN THE SOFTWARE. // -namespace DiscUtils.Lvm; - using DiscUtils.Streams; using System; using System.Collections.Generic; using System.IO; +namespace DiscUtils.Lvm; + internal class VolumeGroupMetadata : IByteArraySerializable { public const string VgMetadataMagic = " LVM2 x[5A%r0N*>"; @@ -47,9 +47,11 @@ internal class VolumeGroupMetadata : IByteArraySerializable /// public int ReadFrom(ReadOnlySpan buffer) { + var latin1Encoding = EncodingUtilities.GetLatin1Encoding(); + Crc = EndianUtilities.ToUInt32LittleEndian(buffer); CalculatedCrc = PhysicalVolume.CalcCrc(buffer.Slice(0x4, PhysicalVolume.SECTOR_SIZE - 0x4)); - Magic = EndianUtilities.BytesToString(buffer.Slice(0x4, 0x10)); + Magic = latin1Encoding.GetString(buffer.Slice(0x4, 0x10)); Version = EndianUtilities.ToUInt32LittleEndian(buffer.Slice(0x14)); Start = EndianUtilities.ToUInt64LittleEndian(buffer.Slice(0x18)); Length = EndianUtilities.ToUInt64LittleEndian(buffer.Slice(0x20)); @@ -71,7 +73,7 @@ public int ReadFrom(ReadOnlySpan buffer) var checksum = PhysicalVolume.CalcCrc(buffer.Slice((int) location.Offset, (int) location.Length)); if (location.Checksum != checksum) throw new IOException("invalid metadata checksum"); - Metadata = EndianUtilities.BytesToString(buffer.Slice((int)location.Offset, (int)location.Length)); + Metadata = latin1Encoding.GetString(buffer.Slice((int)location.Offset, (int)location.Length)); ParsedMetadata = Lvm.Metadata.Parse(Metadata); break; } diff --git a/Library/DiscUtils.Ntfs/BiosParameterBlock.cs b/Library/DiscUtils.Ntfs/BiosParameterBlock.cs index 85e4e968e..23f5e12c8 100644 --- a/Library/DiscUtils.Ntfs/BiosParameterBlock.cs +++ b/Library/DiscUtils.Ntfs/BiosParameterBlock.cs @@ -22,9 +22,10 @@ using System; using System.Buffers; -using System.Globalization; using System.IO; +using System.Text; using System.Runtime.InteropServices; + using System.Security.Cryptography; using DiscUtils.Streams; using DiscUtils.Streams.Compatibility; @@ -132,9 +133,11 @@ internal static BiosParameterBlock Initialized(Geometry diskGeometry, int cluste internal static BiosParameterBlock FromBytes(ReadOnlySpan bytes) { + var latin1Encoding = EncodingUtilities.GetLatin1Encoding(); + var bpb = new BiosParameterBlock { - OemId = EndianUtilities.BytesToString(bytes.Slice(0x03, 8)), + OemId = latin1Encoding.GetString(bytes.Slice(0x03, 8)), BytesPerSector = EndianUtilities.ToUInt16LittleEndian(bytes.Slice(0x0B)), TotalSectors16 = EndianUtilities.ToUInt16LittleEndian(bytes.Slice(0x13)), TotalSectors32 = EndianUtilities.ToUInt32LittleEndian(bytes.Slice(0x20)), @@ -166,7 +169,9 @@ internal static BiosParameterBlock FromBytes(ReadOnlySpan bytes) internal void ToBytes(Span buffer) { - EndianUtilities.StringToBytes(OemId, buffer.Slice(0x03, 8)); + var latin1Encoding = EncodingUtilities.GetLatin1Encoding(); + + latin1Encoding.GetBytes(OemId, buffer.Slice(0x03, 8)); EndianUtilities.WriteBytesLittleEndian(BytesPerSector, buffer.Slice(0x0B)); buffer[0x0D] = EncodeSingleByteSize(SectorsPerCluster); EndianUtilities.WriteBytesLittleEndian(ReservedSectors, buffer.Slice(0x0E)); diff --git a/Library/DiscUtils.Ntfs/FixupRecordBase.cs b/Library/DiscUtils.Ntfs/FixupRecordBase.cs index 5447871dc..0d344dee6 100644 --- a/Library/DiscUtils.Ntfs/FixupRecordBase.cs +++ b/Library/DiscUtils.Ntfs/FixupRecordBase.cs @@ -86,7 +86,10 @@ public void FromStream(Stream stream, int length, bool ignoreMagic = false) public void FromBytes(Span buffer, bool ignoreMagic = false) { - var diskMagic = EndianUtilities.BytesToString(buffer.Slice(0x00, 4)); + var diskMagic = EncodingUtilities + .GetLatin1Encoding() + .GetString(buffer.Slice(0x00, 4)); + if (Magic == null) { Magic = diskMagic; @@ -125,7 +128,10 @@ public void ToBytes(Span buffer) ProtectBuffer(buffer); - EndianUtilities.StringToBytes(Magic, buffer.Slice(0x00, 4)); + EncodingUtilities + .GetLatin1Encoding() + .GetBytes(Magic, buffer.Slice(0x00, 4)); + EndianUtilities.WriteBytesLittleEndian(UpdateSequenceOffset, buffer.Slice(0x04)); EndianUtilities.WriteBytesLittleEndian(UpdateSequenceCount, buffer.Slice(0x06)); diff --git a/Library/DiscUtils.Ntfs/NtfsFileSystemChecker.cs b/Library/DiscUtils.Ntfs/NtfsFileSystemChecker.cs index df5b62621..3aa9334d7 100644 --- a/Library/DiscUtils.Ntfs/NtfsFileSystemChecker.cs +++ b/Library/DiscUtils.Ntfs/NtfsFileSystemChecker.cs @@ -426,7 +426,10 @@ private void PreVerifyMft(File file) { mftStream.ReadExactly(recordData); - var magic = EndianUtilities.BytesToString(recordData, 0, 4); + var magic = EncodingUtilities + .GetLatin1Encoding() + .GetString(recordData, 0, 4); + if (magic != "FILE") { if (bitmap.IsPresent(index)) diff --git a/Library/DiscUtils.Registry/Cell.cs b/Library/DiscUtils.Registry/Cell.cs index 6e4ae5ea6..8adab663f 100644 --- a/Library/DiscUtils.Registry/Cell.cs +++ b/Library/DiscUtils.Registry/Cell.cs @@ -20,8 +20,8 @@ // DEALINGS IN THE SOFTWARE. // -using DiscUtils.Streams; using System; +using DiscUtils.Streams; namespace DiscUtils.Registry; @@ -45,7 +45,10 @@ public Cell(int index) internal static Cell Parse(RegistryHive hive, int index, ReadOnlySpan buffer) { - var type = EndianUtilities.BytesToString(buffer.Slice(0, 2)); + var type = EncodingUtilities + .GetLatin1Encoding() + .GetString(buffer.Slice(0, 2)); + Cell result = type switch { "nk" => new KeyNodeCell(index), diff --git a/Library/DiscUtils.Registry/KeyNodeCell.cs b/Library/DiscUtils.Registry/KeyNodeCell.cs index bb5ac57f4..7264d96d3 100644 --- a/Library/DiscUtils.Registry/KeyNodeCell.cs +++ b/Library/DiscUtils.Registry/KeyNodeCell.cs @@ -80,6 +80,8 @@ public override int Size public override int ReadFrom(ReadOnlySpan buffer) { + var latin1Encoding = EncodingUtilities.GetLatin1Encoding(); + Flags = (RegistryKeyFlags)EndianUtilities.ToUInt16LittleEndian(buffer.Slice(0x02)); Timestamp = DateTime.FromFileTimeUtc(EndianUtilities.ToInt64LittleEndian(buffer.Slice(0x04))); ParentIndex = EndianUtilities.ToInt32LittleEndian(buffer.Slice(0x10)); @@ -95,14 +97,16 @@ public override int ReadFrom(ReadOnlySpan buffer) IndexInParent = EndianUtilities.ToInt32LittleEndian(buffer.Slice(0x44)); int nameLength = EndianUtilities.ToInt16LittleEndian(buffer.Slice(0x48)); ClassNameLength = EndianUtilities.ToInt16LittleEndian(buffer.Slice(0x4A)); - Name = EndianUtilities.BytesToString(buffer.Slice(0x4C, nameLength)); + Name = latin1Encoding.GetString(buffer.Slice(0x4C, nameLength)); return 0x4C + nameLength; } public override void WriteTo(Span buffer) { - EndianUtilities.StringToBytes("nk", buffer.Slice(0, 2)); + var latin1Encoding = EncodingUtilities.GetLatin1Encoding(); + + latin1Encoding.GetBytes("nk", buffer.Slice(0, 2)); EndianUtilities.WriteBytesLittleEndian((ushort)Flags, buffer.Slice(0x02)); EndianUtilities.WriteBytesLittleEndian(Timestamp.ToFileTimeUtc(), buffer.Slice(0x04)); EndianUtilities.WriteBytesLittleEndian(ParentIndex, buffer.Slice(0x10)); @@ -115,7 +119,7 @@ public override void WriteTo(Span buffer) EndianUtilities.WriteBytesLittleEndian(IndexInParent, buffer.Slice(0x44)); EndianUtilities.WriteBytesLittleEndian((ushort)Name.Length, buffer.Slice(0x48)); EndianUtilities.WriteBytesLittleEndian(ClassNameLength, buffer.Slice(0x4A)); - EndianUtilities.StringToBytes(Name, buffer.Slice(0x4C, Name.Length)); + latin1Encoding.GetBytes(Name, buffer.Slice(0x4C, Name.Length)); } public override string ToString() diff --git a/Library/DiscUtils.Registry/SecurityCell.cs b/Library/DiscUtils.Registry/SecurityCell.cs index 8aafc6371..a2d67559e 100644 --- a/Library/DiscUtils.Registry/SecurityCell.cs +++ b/Library/DiscUtils.Registry/SecurityCell.cs @@ -73,9 +73,10 @@ public override int ReadFrom(ReadOnlySpan buffer) public override void WriteTo(Span buffer) { + var latin1Encoding = EncodingUtilities.GetLatin1Encoding(); var sd = SecurityDescriptor.GetSecurityDescriptorBinaryForm(); - EndianUtilities.StringToBytes("sk", buffer.Slice(0, 2)); + latin1Encoding.GetBytes("sk", buffer.Slice(0, 2)); EndianUtilities.WriteBytesLittleEndian(PreviousIndex, buffer.Slice(0x04)); EndianUtilities.WriteBytesLittleEndian(NextIndex, buffer.Slice(0x08)); EndianUtilities.WriteBytesLittleEndian(UsageCount, buffer.Slice(0x0C)); diff --git a/Library/DiscUtils.Registry/SubKeyHashedListCell.cs b/Library/DiscUtils.Registry/SubKeyHashedListCell.cs index 128d44749..daf90fbd8 100644 --- a/Library/DiscUtils.Registry/SubKeyHashedListCell.cs +++ b/Library/DiscUtils.Registry/SubKeyHashedListCell.cs @@ -61,7 +61,9 @@ public override int Size public override int ReadFrom(ReadOnlySpan buffer) { - _hashType = EndianUtilities.BytesToString(buffer.Slice(0, 2)); + var latin1Encoding = EncodingUtilities.GetLatin1Encoding(); + + _hashType = latin1Encoding.GetString(buffer.Slice(0, 2)); _numElements = EndianUtilities.ToInt16LittleEndian(buffer.Slice(2)); _subKeyIndexes = new List(_numElements); @@ -77,7 +79,10 @@ public override int ReadFrom(ReadOnlySpan buffer) public override void WriteTo(Span buffer) { - EndianUtilities.StringToBytes(_hashType, buffer.Slice(0, 2)); + EncodingUtilities + .GetLatin1Encoding() + .GetBytes(_hashType, buffer.Slice(0, 2)); + EndianUtilities.WriteBytesLittleEndian(_numElements, buffer.Slice(0x2)); for (var i = 0; i < _numElements; ++i) { diff --git a/Library/DiscUtils.Registry/SubKeyIndirectListCell.cs b/Library/DiscUtils.Registry/SubKeyIndirectListCell.cs index cba49b332..598c8f9cd 100644 --- a/Library/DiscUtils.Registry/SubKeyIndirectListCell.cs +++ b/Library/DiscUtils.Registry/SubKeyIndirectListCell.cs @@ -69,7 +69,9 @@ public override int Size public override int ReadFrom(ReadOnlySpan buffer) { - ListType = EndianUtilities.BytesToString(buffer.Slice(0, 2)); + var latin1Encoding = EncodingUtilities.GetLatin1Encoding(); + + ListType = latin1Encoding.GetString(buffer.Slice(0, 2)); int numElements = EndianUtilities.ToInt16LittleEndian(buffer.Slice(2)); CellIndexes = new List(numElements); @@ -83,7 +85,10 @@ public override int ReadFrom(ReadOnlySpan buffer) public override void WriteTo(Span buffer) { - EndianUtilities.StringToBytes(ListType, buffer.Slice(0, 2)); + EncodingUtilities + .GetLatin1Encoding() + .GetBytes(ListType, buffer.Slice(0, 2)); + EndianUtilities.WriteBytesLittleEndian((ushort)CellIndexes.Count, buffer.Slice(2)); for (var i = 0; i < CellIndexes.Count; ++i) { diff --git a/Library/DiscUtils.Registry/ValueCell.cs b/Library/DiscUtils.Registry/ValueCell.cs index acd651bd5..32c82c9e2 100644 --- a/Library/DiscUtils.Registry/ValueCell.cs +++ b/Library/DiscUtils.Registry/ValueCell.cs @@ -20,8 +20,8 @@ // DEALINGS IN THE SOFTWARE. // -using DiscUtils.Streams; using System; +using DiscUtils.Streams; namespace DiscUtils.Registry; @@ -64,7 +64,9 @@ public override int ReadFrom(ReadOnlySpan buffer) if ((_flags & ValueFlags.Named) != 0) { - Name = EndianUtilities.BytesToString(buffer.Slice(0x14, nameLen)).Trim('\0'); + Name = EncodingUtilities + .GetLatin1Encoding() + .GetString(buffer.Slice(0x14, nameLen)).Trim('\0'); } return 0x14 + nameLen; @@ -85,7 +87,9 @@ public override void WriteTo(Span buffer) nameLen = Name.Length; } - EndianUtilities.StringToBytes("vk", buffer.Slice(0, 2)); + var latin1Encoding = EncodingUtilities.GetLatin1Encoding(); + + latin1Encoding.GetBytes("vk", buffer.Slice(0, 2)); EndianUtilities.WriteBytesLittleEndian(nameLen, buffer.Slice(0x02)); EndianUtilities.WriteBytesLittleEndian(DataLength, buffer.Slice(0x04)); EndianUtilities.WriteBytesLittleEndian(DataIndex, buffer.Slice(0x08)); @@ -93,7 +97,7 @@ public override void WriteTo(Span buffer) EndianUtilities.WriteBytesLittleEndian((ushort)_flags, buffer.Slice(0x10)); if (nameLen != 0) { - EndianUtilities.StringToBytes(Name, buffer.Slice(0x14, nameLen)); + latin1Encoding.GetBytes(Name, buffer.Slice(0x14, nameLen)); } } } \ No newline at end of file diff --git a/Library/DiscUtils.Sdi/FileHeader.cs b/Library/DiscUtils.Sdi/FileHeader.cs index d8321e1cd..4bf0122ed 100644 --- a/Library/DiscUtils.Sdi/FileHeader.cs +++ b/Library/DiscUtils.Sdi/FileHeader.cs @@ -45,7 +45,9 @@ internal class FileHeader public void ReadFrom(ReadOnlySpan buffer) { - Tag = EndianUtilities.BytesToString(buffer.Slice(0, 8)); + Tag = EncodingUtilities + .GetLatin1Encoding() + .GetString(buffer.Slice(0, 8)); if (Tag != "$SDI0001") { diff --git a/Library/DiscUtils.Sdi/SectionRecord.cs b/Library/DiscUtils.Sdi/SectionRecord.cs index 7fff2ca27..5a9cb4856 100644 --- a/Library/DiscUtils.Sdi/SectionRecord.cs +++ b/Library/DiscUtils.Sdi/SectionRecord.cs @@ -20,8 +20,8 @@ // DEALINGS IN THE SOFTWARE. // -using DiscUtils.Streams; using System; +using DiscUtils.Streams; namespace DiscUtils.Sdi; @@ -37,7 +37,9 @@ internal class SectionRecord public void ReadFrom(ReadOnlySpan buffer) { - SectionType = EndianUtilities.BytesToString(buffer.Slice(0, 8)).TrimEnd('\0'); + var latin1Encoding = EncodingUtilities.GetLatin1Encoding(); + + SectionType = latin1Encoding.GetString(buffer.Slice(0, 8)).TrimEnd('\0'); Attr = EndianUtilities.ToUInt64LittleEndian(buffer.Slice(8)); Offset = EndianUtilities.ToInt64LittleEndian(buffer.Slice(16)); Size = EndianUtilities.ToInt64LittleEndian(buffer.Slice(24)); diff --git a/Library/DiscUtils.SquashFs/DirectoryRecord.cs b/Library/DiscUtils.SquashFs/DirectoryRecord.cs index 7b42fb90d..ea84d24a2 100644 --- a/Library/DiscUtils.SquashFs/DirectoryRecord.cs +++ b/Library/DiscUtils.SquashFs/DirectoryRecord.cs @@ -45,11 +45,13 @@ public int ReadFrom(ReadOnlySpan buffer) public void WriteTo(Span buffer) { + var latin1Encoding = EncodingUtilities.GetLatin1Encoding(); + EndianUtilities.WriteBytesLittleEndian(Offset, buffer); EndianUtilities.WriteBytesLittleEndian(InodeNumber, buffer.Slice(2)); EndianUtilities.WriteBytesLittleEndian((ushort)Type, buffer.Slice(4)); EndianUtilities.WriteBytesLittleEndian((ushort)(Name.Length - 1), buffer.Slice(6)); - EndianUtilities.StringToBytes(Name, buffer.Slice(8, Name.Length)); + latin1Encoding.GetBytes(Name, buffer.Slice(8, Name.Length)); } public static DirectoryRecord ReadFrom(MetablockReader reader) diff --git a/Library/DiscUtils.SquashFs/MetablockReader.cs b/Library/DiscUtils.SquashFs/MetablockReader.cs index 2a984cad7..7eb0f6904 100644 --- a/Library/DiscUtils.SquashFs/MetablockReader.cs +++ b/Library/DiscUtils.SquashFs/MetablockReader.cs @@ -173,14 +173,17 @@ public short ReadShort() public string ReadString(int len) { var block = _context.ReadMetaBlock(_start + _currentBlockStart); + var latin1Encoding = EncodingUtilities.GetLatin1Encoding(); if (block.Available - _currentOffset < len) { Span buffer = stackalloc byte[len]; buffer = buffer.Slice(0, Read(buffer)); - return EndianUtilities.BytesToString(buffer); + return latin1Encoding.GetString(buffer); } - var result = EndianUtilities.BytesToString(block.Data, _currentOffset, len); + + var result = latin1Encoding.GetString(block.Data, _currentOffset, len); + _currentOffset += len; return result; } diff --git a/Library/DiscUtils.Streams/Util/CompatExtensions.cs b/Library/DiscUtils.Streams/Util/CompatExtensions.cs index a57c7b946..44bd892aa 100644 --- a/Library/DiscUtils.Streams/Util/CompatExtensions.cs +++ b/Library/DiscUtils.Streams/Util/CompatExtensions.cs @@ -1,5 +1,4 @@ -using LTRData.Extensions.Async; -using System; +using System; using System.Buffers; using System.Collections.Generic; using System.IO; @@ -8,6 +7,7 @@ using System.Text; using System.Threading; using System.Threading.Tasks; +using LTRData.Extensions.Async; namespace DiscUtils.Streams.Compatibility; @@ -160,44 +160,6 @@ public static void Convert(this Encoder decoder, ReadOnlySpan chars, Span< } } - public static string GetString(this Encoding encoding, ReadOnlySpan bytes) - { - var buffer = ArrayPool.Shared.Rent(bytes.Length); - try - { - bytes.CopyTo(buffer); - return encoding.GetString(buffer, 0, bytes.Length); - } - finally - { - ArrayPool.Shared.Return(buffer); - } - } - - public static int GetBytes(this Encoding encoding, ReadOnlySpan chars, Span bytes) - { - var str = ArrayPool.Shared.Rent(chars.Length); - try - { - chars.CopyTo(str); - var buffer = ArrayPool.Shared.Rent(encoding.GetByteCount(str, 0, chars.Length)); - try - { - var length = encoding.GetBytes(str, 0, chars.Length, buffer, 0); - buffer.AsSpan(0, length).CopyTo(bytes); - return length; - } - finally - { - ArrayPool.Shared.Return(buffer); - } - } - finally - { - ArrayPool.Shared.Return(str); - } - } - public static void NextBytes(this Random random, Span buffer) { var bytes = new byte[buffer.Length]; diff --git a/Library/DiscUtils.Streams/Util/EncodingExtensions.cs b/Library/DiscUtils.Streams/Util/EncodingExtensions.cs new file mode 100644 index 000000000..b3bf54eed --- /dev/null +++ b/Library/DiscUtils.Streams/Util/EncodingExtensions.cs @@ -0,0 +1,55 @@ +using System.Text; +using System.Buffers; +using System; + +namespace DiscUtils.Streams; + +public static class EncodingExtensions +{ + public static int GetBytes(this Encoding encoding, string chars, Span bytes) + { + return encoding.GetBytes(chars.AsSpan(), bytes); + } + +#if !NETSTANDARD2_1_OR_GREATER && !NETCOREAPP + public static int GetBytes(this Encoding encoding, ReadOnlySpan chars, Span bytes) + { + var str = ArrayPool.Shared.Rent(chars.Length); + try + { + chars.CopyTo(str); + var buffer = ArrayPool.Shared.Rent(encoding.GetByteCount(str, 0, chars.Length)); + try + { + var length = encoding.GetBytes(str, 0, chars.Length, buffer, 0); + buffer.AsSpan(0, length).CopyTo(bytes); + return length; + } + finally + { + ArrayPool.Shared.Return(buffer); + } + } + finally + { + ArrayPool.Shared.Return(str); + } + } +#endif + +#if !NETSTANDARD2_1_OR_GREATER && !NETCOREAPP + public static string GetString(this Encoding encoding, ReadOnlySpan bytes) + { + var buffer = ArrayPool.Shared.Rent(bytes.Length); + try + { + bytes.CopyTo(buffer); + return encoding.GetString(buffer, 0, bytes.Length); + } + finally + { + ArrayPool.Shared.Return(buffer); + } + } +#endif +} diff --git a/Library/DiscUtils.Streams/Util/EncodingUtilities.cs b/Library/DiscUtils.Streams/Util/EncodingUtilities.cs new file mode 100644 index 000000000..1c131d516 --- /dev/null +++ b/Library/DiscUtils.Streams/Util/EncodingUtilities.cs @@ -0,0 +1,20 @@ +using System.Text; + +namespace DiscUtils.Streams; + +public static class EncodingUtilities +{ + /// + /// Retrieve the Latin1 encoding. This encoding is also known as iso-8859-1, + /// by its codepage 28591, and by its Windows codepage 1252. + /// + /// Encoding + public static Encoding GetLatin1Encoding() + { +#if NET6_0_OR_GREATER + return Encoding.Latin1; +#else + return Encoding.GetEncoding("Latin1"); +#endif + } +} diff --git a/Library/DiscUtils.Streams/Util/EndianUtilities.cs b/Library/DiscUtils.Streams/Util/EndianUtilities.cs index 2c97318dc..95e3cbe2a 100644 --- a/Library/DiscUtils.Streams/Util/EndianUtilities.cs +++ b/Library/DiscUtils.Streams/Util/EndianUtilities.cs @@ -595,121 +595,6 @@ public static ReadOnlySpan StringToLittleEndianUnicodeBytesToString(ReadOn return MemoryMarshal.AsBytes(chars); } - /// - /// Primitive conversion from Unicode to ASCII that preserves special characters. - /// - /// The string to convert. - /// The buffer to fill. - /// The start of the string in the buffer. - /// The number of characters to convert. - /// The built-in ASCIIEncoding converts characters of codepoint > 127 to ?, - /// this preserves those code points by removing the top 16 bits of each character. - public static void StringToBytes(string value, byte[] dest, int offset, int count) - { - Encoding.GetEncoding(28591).GetBytes(value, 0, Math.Min(count, value.Length), dest, offset); - } - - /// - /// Primitive conversion from Unicode to ASCII that preserves special characters. - /// - /// The string to convert. - /// The buffer to fill. - /// The built-in ASCIIEncoding converts characters of codepoint > 127 to ?, - /// this preserves those code points by removing the top 16 bits of each character. - public static void StringToBytes(string value, Span dest) - { -#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP - Encoding.GetEncoding(28591).GetBytes(value.AsSpan(0, Math.Min(dest.Length, value.Length)), dest); -#else - var buffer = ArrayPool.Shared.Rent(dest.Length); - try - { - Array.Clear(buffer, 0, dest.Length); - StringToBytes(value, buffer, 0, dest.Length); - buffer.AsSpan(0, dest.Length).CopyTo(dest); - } - finally - { - ArrayPool.Shared.Return(buffer); - } -#endif - } - - /// - /// Primitive conversion from Unicode to ASCII that preserves special characters. - /// - /// The string to convert. - /// The buffer to fill. - /// The built-in ASCIIEncoding converts characters of codepoint > 127 to ?, - /// this preserves those code points by removing the top 16 bits of each character. - public static int StringToBytes(ReadOnlySpan value, Span dest) - { -#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP - return Encoding.GetEncoding(28591).GetBytes(value.Slice(0, Math.Min(dest.Length, value.Length)), dest); -#else - var chars = ArrayPool.Shared.Rent(value.Length); - try - { - value.CopyTo(chars); - var buffer = ArrayPool.Shared.Rent(dest.Length); - try - { - Array.Clear(buffer, 0, dest.Length); - var numBytes = Encoding.GetEncoding(28591).GetBytes(chars, 0, value.Length, buffer, 0); - buffer.AsSpan(0, numBytes).CopyTo(dest); - return numBytes; - } - finally - { - ArrayPool.Shared.Return(buffer); - } - } - finally - { - ArrayPool.Shared.Return(chars); - } -#endif - } - - /// - /// Primitive conversion from ASCII to Unicode that preserves special characters. - /// - /// The data to convert. - /// The first byte to convert. - /// The number of bytes to convert. - /// The string. - /// The built-in ASCIIEncoding converts characters of codepoint > 127 to ?, - /// this preserves those code points. - public static string BytesToString(byte[] data, int offset, int count) - { - return Encoding.GetEncoding(28591).GetString(data, offset, count); - } - - /// - /// Primitive conversion from ASCII to Unicode that preserves special characters. - /// - /// The data to convert. - /// The string. - /// The built-in ASCIIEncoding converts characters of codepoint > 127 to ?, - /// this preserves those code points. - public static string BytesToString(ReadOnlySpan data) - { -#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP - return Encoding.GetEncoding(28591).GetString(data); -#else - var buffer = ArrayPool.Shared.Rent(data.Length); - try - { - data.CopyTo(buffer); - return Encoding.GetEncoding(28591).GetString(buffer, 0, data.Length); - } - finally - { - ArrayPool.Shared.Return(buffer); - } -#endif - } - /// /// Primitive conversion from ASCII to Unicode that stops at a null-terminator. /// @@ -728,7 +613,7 @@ public static string BytesToZString(byte[] data, int offset, int count) count = z - offset; } - return Encoding.GetEncoding(28591).GetString(data, offset, count); + return EncodingUtilities.GetLatin1Encoding().GetString(data, offset, count); } /// @@ -748,13 +633,13 @@ public static string BytesToZString(ReadOnlySpan data) } #if NETSTANDARD2_1_OR_GREATER || NETCOREAPP - return Encoding.GetEncoding(28591).GetString(data); + return EncodingUtilities.GetLatin1Encoding().GetString(data); #else var buffer = ArrayPool.Shared.Rent(data.Length); try { data.CopyTo(buffer); - return Encoding.GetEncoding(28591).GetString(buffer, 0, data.Length); + return EncodingUtilities.GetLatin1Encoding().GetString(buffer, 0, data.Length); } finally { diff --git a/Library/DiscUtils.Swap/SwapHeader.cs b/Library/DiscUtils.Swap/SwapHeader.cs index 0076f49c3..fd3b2eba5 100644 --- a/Library/DiscUtils.Swap/SwapHeader.cs +++ b/Library/DiscUtils.Swap/SwapHeader.cs @@ -53,17 +53,28 @@ public int Size public int ReadFrom(ReadOnlySpan buffer) { - Magic = EndianUtilities.BytesToString(buffer.Slice(PageSize - 10, 10)); - if (Magic != Magic1 && Magic != Magic2) return Size; + Magic = EncodingUtilities + .GetLatin1Encoding() + .GetString(buffer.Slice(PageSize - 10, 10)); + + if (Magic != Magic1 && Magic != Magic2) + { + return Size; + } Version = EndianUtilities.ToUInt32LittleEndian(buffer.Slice(0x400)); LastPage = EndianUtilities.ToUInt32LittleEndian(buffer.Slice(0x404)); BadPages = EndianUtilities.ToUInt32LittleEndian(buffer.Slice(0x408)); Uuid = EndianUtilities.ToGuidLittleEndian(buffer.Slice(0x40c)); + var volume = buffer.Slice(0x41c, 16); var nullIndex = volume.IndexOf((byte)0); + if (nullIndex > 0) + { Volume = Encoding.UTF8.GetString(volume.Slice(0, nullIndex)); + } + return Size; } diff --git a/Library/DiscUtils.Vdi/HeaderRecord.cs b/Library/DiscUtils.Vdi/HeaderRecord.cs index 9c002e460..834f72cb2 100644 --- a/Library/DiscUtils.Vdi/HeaderRecord.cs +++ b/Library/DiscUtils.Vdi/HeaderRecord.cs @@ -106,11 +106,13 @@ public void Read(FileVersion version, Stream s) public int Read(FileVersion version, ReadOnlySpan buffer) { + var latin1Encoding = EncodingUtilities.GetLatin1Encoding(); + if (version.Major == 0) { ImageType = (ImageType)EndianUtilities.ToUInt32LittleEndian(buffer.Slice(0)); Flags = (ImageFlags)EndianUtilities.ToUInt32LittleEndian(buffer.Slice(4)); - Comment = EndianUtilities.BytesToString(buffer.Slice(8, 256)).TrimEnd('\0'); + Comment = latin1Encoding.GetString(buffer.Slice(8, 256)).TrimEnd('\0'); LegacyGeometry = new GeometryRecord(); LegacyGeometry.Read(buffer.Slice(264)); DiskSize = EndianUtilities.ToInt64LittleEndian(buffer.Slice(280)); @@ -131,7 +133,7 @@ public int Read(FileVersion version, ReadOnlySpan buffer) HeaderSize = EndianUtilities.ToUInt32LittleEndian(buffer.Slice(0)); ImageType = (ImageType)EndianUtilities.ToUInt32LittleEndian(buffer.Slice(4)); Flags = (ImageFlags)EndianUtilities.ToUInt32LittleEndian(buffer.Slice(8)); - Comment = EndianUtilities.BytesToString(buffer.Slice(12, 256)).TrimEnd('\0'); + Comment = latin1Encoding.GetString(buffer.Slice(12, 256)).TrimEnd('\0'); BlocksOffset = EndianUtilities.ToUInt32LittleEndian(buffer.Slice(268)); DataOffset = EndianUtilities.ToUInt32LittleEndian(buffer.Slice(272)); LegacyGeometry = new GeometryRecord(); @@ -183,11 +185,13 @@ public async ValueTask WriteAsync(Stream s, CancellationToken cancellationToken) public int Write(Span buffer) { + var latin1Encoding = EncodingUtilities.GetLatin1Encoding(); + if (_fileVersion.Major == 0) { EndianUtilities.WriteBytesLittleEndian((uint)ImageType, buffer.Slice(0)); EndianUtilities.WriteBytesLittleEndian((uint)Flags, buffer.Slice(4)); - EndianUtilities.StringToBytes(Comment, buffer.Slice(8, 256)); + latin1Encoding.GetBytes(Comment.AsSpan(), buffer.Slice(8, 256)); LegacyGeometry.Write(buffer.Slice(264)); EndianUtilities.WriteBytesLittleEndian(DiskSize, buffer.Slice(280)); EndianUtilities.WriteBytesLittleEndian(BlockSize, buffer.Slice(288)); @@ -202,7 +206,7 @@ public int Write(Span buffer) EndianUtilities.WriteBytesLittleEndian(HeaderSize, buffer.Slice(0)); EndianUtilities.WriteBytesLittleEndian((uint)ImageType, buffer.Slice(4)); EndianUtilities.WriteBytesLittleEndian((uint)Flags, buffer.Slice(8)); - EndianUtilities.StringToBytes(Comment, buffer.Slice(12, 256)); + latin1Encoding.GetBytes(Comment.AsSpan(), buffer.Slice(12, 256)); EndianUtilities.WriteBytesLittleEndian(BlocksOffset, buffer.Slice(268)); EndianUtilities.WriteBytesLittleEndian(DataOffset, buffer.Slice(272)); LegacyGeometry.Write(buffer.Slice(276)); diff --git a/Library/DiscUtils.Vdi/PreHeaderRecord.cs b/Library/DiscUtils.Vdi/PreHeaderRecord.cs index 69135d266..7cbe7eff3 100644 --- a/Library/DiscUtils.Vdi/PreHeaderRecord.cs +++ b/Library/DiscUtils.Vdi/PreHeaderRecord.cs @@ -49,7 +49,9 @@ public static PreHeaderRecord Initialized() public int Read(ReadOnlySpan buffer) { - FileInfo = EndianUtilities.BytesToString(buffer.Slice(0, 64)).TrimEnd('\0'); + var latin1Encoding = EncodingUtilities.GetLatin1Encoding(); + + FileInfo = latin1Encoding.GetString(buffer.Slice(0, 64)).TrimEnd('\0'); Signature = EndianUtilities.ToUInt32LittleEndian(buffer.Slice(64)); Version = new FileVersion(EndianUtilities.ToUInt32LittleEndian(buffer.Slice(68))); return Size; @@ -71,7 +73,9 @@ public void Write(Stream s) public void Write(Span buffer) { - EndianUtilities.StringToBytes(FileInfo, buffer.Slice(0, 64)); + var latin1Encoding = EncodingUtilities.GetLatin1Encoding(); + + latin1Encoding.GetBytes(FileInfo.AsSpan(), buffer.Slice(0, 64)); EndianUtilities.WriteBytesLittleEndian(Signature, buffer.Slice(64)); EndianUtilities.WriteBytesLittleEndian(Version.Value, buffer.Slice(68)); } diff --git a/Library/DiscUtils.Vhd/DynamicHeader.cs b/Library/DiscUtils.Vhd/DynamicHeader.cs index 72b5ec6c9..6e9fb725f 100644 --- a/Library/DiscUtils.Vhd/DynamicHeader.cs +++ b/Library/DiscUtils.Vhd/DynamicHeader.cs @@ -86,9 +86,11 @@ public DynamicHeader(DynamicHeader toCopy) public static DynamicHeader FromBytes(ReadOnlySpan data) { + var latin1Encoding = EncodingUtilities.GetLatin1Encoding(); + var result = new DynamicHeader { - Cookie = EndianUtilities.BytesToString(data.Slice(0, 8)), + Cookie = latin1Encoding.GetString(data.Slice(0, 8)), DataOffset = EndianUtilities.ToInt64BigEndian(data.Slice(8)), TableOffset = EndianUtilities.ToInt64BigEndian(data.Slice(16)), HeaderVersion = EndianUtilities.ToUInt32BigEndian(data.Slice(24)), @@ -98,9 +100,9 @@ public static DynamicHeader FromBytes(ReadOnlySpan data) ParentUniqueId = EndianUtilities.ToGuidBigEndian(data.Slice(40)), ParentTimestamp = Footer.EpochUtc.AddSeconds(EndianUtilities.ToUInt32BigEndian(data.Slice(56))), ParentUnicodeName = Encoding.BigEndianUnicode.GetString(data.Slice(64, 512)).TrimEnd('\0'), - ParentLocators = new ParentLocator[8] }; + for (var i = 0; i < 8; ++i) { result.ParentLocators[i] = ParentLocator.FromBytes(data.Slice(576 + i * 24)); @@ -111,7 +113,9 @@ public static DynamicHeader FromBytes(ReadOnlySpan data) public void ToBytes(Span data) { - EndianUtilities.StringToBytes(Cookie, data.Slice(0, 8)); + var latin1Encoding = EncodingUtilities.GetLatin1Encoding(); + + latin1Encoding.GetBytes(Cookie.AsSpan(), data.Slice(0, 8)); EndianUtilities.WriteBytesBigEndian(DataOffset, data.Slice(8)); EndianUtilities.WriteBytesBigEndian(TableOffset, data.Slice(16)); EndianUtilities.WriteBytesBigEndian(HeaderVersion, data.Slice(24)); diff --git a/Library/DiscUtils.Vhd/Footer.cs b/Library/DiscUtils.Vhd/Footer.cs index 88f20e8f5..d696fb7b7 100644 --- a/Library/DiscUtils.Vhd/Footer.cs +++ b/Library/DiscUtils.Vhd/Footer.cs @@ -22,6 +22,7 @@ using System; using DiscUtils.Streams; +using DiscUtils.Streams.Compatibility; namespace DiscUtils.Vhd; @@ -143,16 +144,18 @@ private uint CalculateChecksum() public static Footer FromBytes(ReadOnlySpan buffer) { - var result = new Footer + var latin1Encoding = EncodingUtilities.GetLatin1Encoding(); + + return new Footer { - Cookie = EndianUtilities.BytesToString(buffer.Slice(0, 8)), + Cookie = latin1Encoding.GetString(buffer.Slice(0, 8)), Features = EndianUtilities.ToUInt32BigEndian(buffer.Slice(8)), FileFormatVersion = EndianUtilities.ToUInt32BigEndian(buffer.Slice(12)), DataOffset = EndianUtilities.ToInt64BigEndian(buffer.Slice(16)), Timestamp = EpochUtc.AddSeconds(EndianUtilities.ToUInt32BigEndian(buffer.Slice(24))), - CreatorApp = EndianUtilities.BytesToString(buffer.Slice(28, 4)), + CreatorApp = latin1Encoding.GetString(buffer.Slice(28, 4)), CreatorVersion = EndianUtilities.ToUInt32BigEndian(buffer.Slice(32)), - CreatorHostOS = EndianUtilities.BytesToString(buffer.Slice(36, 4)), + CreatorHostOS = latin1Encoding.GetString(buffer.Slice(36, 4)), OriginalSize = EndianUtilities.ToInt64BigEndian(buffer.Slice(40)), CurrentSize = EndianUtilities.ToInt64BigEndian(buffer.Slice(48)), Geometry = new Geometry(EndianUtilities.ToUInt16BigEndian(buffer.Slice(56)), buffer[58], buffer[59]), @@ -161,20 +164,20 @@ public static Footer FromBytes(ReadOnlySpan buffer) UniqueId = EndianUtilities.ToGuidBigEndian(buffer.Slice(68)), SavedState = buffer[84] }; - - return result; } public void ToBytes(Span buffer) { - EndianUtilities.StringToBytes(Cookie, buffer.Slice(0, 8)); + var latin1Encoding = EncodingUtilities.GetLatin1Encoding(); + + latin1Encoding.GetBytes(Cookie.AsSpan(), buffer.Slice(0, 8)); EndianUtilities.WriteBytesBigEndian(Features, buffer.Slice(8)); EndianUtilities.WriteBytesBigEndian(FileFormatVersion, buffer.Slice(12)); EndianUtilities.WriteBytesBigEndian(DataOffset, buffer.Slice(16)); EndianUtilities.WriteBytesBigEndian((uint)(Timestamp - EpochUtc).TotalSeconds, buffer.Slice(24)); - EndianUtilities.StringToBytes(CreatorApp, buffer.Slice(28, 4)); + latin1Encoding.GetBytes(CreatorApp.AsSpan(), buffer.Slice(28, 4)); EndianUtilities.WriteBytesBigEndian(CreatorVersion, buffer.Slice(32)); - EndianUtilities.StringToBytes(CreatorHostOS, buffer.Slice(36, 4)); + latin1Encoding.GetBytes(CreatorHostOS.AsSpan(), buffer.Slice(36, 4)); EndianUtilities.WriteBytesBigEndian(OriginalSize, buffer.Slice(40)); EndianUtilities.WriteBytesBigEndian(CurrentSize, buffer.Slice(48)); EndianUtilities.WriteBytesBigEndian((ushort)Geometry.Cylinders, buffer.Slice(56)); diff --git a/Library/DiscUtils.Vhd/Header.cs b/Library/DiscUtils.Vhd/Header.cs index 632cbc4ac..43ec7abdf 100644 --- a/Library/DiscUtils.Vhd/Header.cs +++ b/Library/DiscUtils.Vhd/Header.cs @@ -40,11 +40,12 @@ public static Header FromStream(Stream stream) public static Header FromBytes(ReadOnlySpan data) { - var result = new Header + var latin1Encoding = EncodingUtilities.GetLatin1Encoding(); + + return new Header { - Cookie = EndianUtilities.BytesToString(data.Slice(0, 8)), + Cookie = latin1Encoding.GetString(data.Slice(0, 8)), DataOffset = EndianUtilities.ToInt64BigEndian(data.Slice(8)) }; - return result; } } \ No newline at end of file diff --git a/Library/DiscUtils.Vhd/ParentLocator.cs b/Library/DiscUtils.Vhd/ParentLocator.cs index 1288448d7..e5aaca2ae 100644 --- a/Library/DiscUtils.Vhd/ParentLocator.cs +++ b/Library/DiscUtils.Vhd/ParentLocator.cs @@ -20,8 +20,9 @@ // DEALINGS IN THE SOFTWARE. // -using DiscUtils.Streams; using System; +using DiscUtils.Streams; +using DiscUtils.Streams.Compatibility; namespace DiscUtils.Vhd; @@ -50,19 +51,22 @@ public ParentLocator(ParentLocator toCopy) public static ParentLocator FromBytes(ReadOnlySpan data) { - var result = new ParentLocator + var latin1Encoding = EncodingUtilities.GetLatin1Encoding(); + + return new ParentLocator { - PlatformCode = EndianUtilities.BytesToString(data.Slice(0, 4)), + PlatformCode = latin1Encoding.GetString(data.Slice(0, 4)), PlatformDataSpace = EndianUtilities.ToInt32BigEndian(data.Slice(4)), PlatformDataLength = EndianUtilities.ToInt32BigEndian(data.Slice(8)), PlatformDataOffset = EndianUtilities.ToInt64BigEndian(data.Slice(16)) }; - return result; } internal void ToBytes(Span data) { - EndianUtilities.StringToBytes(PlatformCode, data.Slice(0, 4)); + var latin1Encoding = EncodingUtilities.GetLatin1Encoding(); + + latin1Encoding.GetBytes(PlatformCode.AsSpan(), data.Slice(0, 4)); EndianUtilities.WriteBytesBigEndian(PlatformDataSpace, data.Slice(4)); EndianUtilities.WriteBytesBigEndian(PlatformDataLength, data.Slice(8)); EndianUtilities.WriteBytesBigEndian((uint)0, data.Slice(12)); diff --git a/Library/DiscUtils.Vhdx/DiskImageFileInfo.cs b/Library/DiscUtils.Vhdx/DiskImageFileInfo.cs index c9d26451a..e49087739 100644 --- a/Library/DiscUtils.Vhdx/DiskImageFileInfo.cs +++ b/Library/DiscUtils.Vhdx/DiskImageFileInfo.cs @@ -210,7 +210,10 @@ public string Signature { Span buffer = stackalloc byte[8]; EndianUtilities.WriteBytesLittleEndian(_fileHeader.Signature, buffer); - return EndianUtilities.BytesToString(buffer); + + return EncodingUtilities + .GetLatin1Encoding() + .GetString(buffer); } } } \ No newline at end of file diff --git a/Library/DiscUtils.Vhdx/HeaderInfo.cs b/Library/DiscUtils.Vhdx/HeaderInfo.cs index d0b15578b..1bb62981e 100644 --- a/Library/DiscUtils.Vhdx/HeaderInfo.cs +++ b/Library/DiscUtils.Vhdx/HeaderInfo.cs @@ -117,7 +117,10 @@ public string Signature { Span buffer = stackalloc byte[4]; EndianUtilities.WriteBytesLittleEndian(_header.Signature, buffer); - return EndianUtilities.BytesToString(buffer); + + return EncodingUtilities + .GetLatin1Encoding() + .GetString(buffer); } } diff --git a/Library/DiscUtils.Vhdx/MetadataTableInfo.cs b/Library/DiscUtils.Vhdx/MetadataTableInfo.cs index d552bb309..97493f8ea 100644 --- a/Library/DiscUtils.Vhdx/MetadataTableInfo.cs +++ b/Library/DiscUtils.Vhdx/MetadataTableInfo.cs @@ -59,7 +59,10 @@ public string Signature { Span buffer = stackalloc byte[8]; EndianUtilities.WriteBytesLittleEndian(_table.Signature, buffer); - return EndianUtilities.BytesToString(buffer); + + return EncodingUtilities + .GetLatin1Encoding() + .GetString(buffer); } } diff --git a/Library/DiscUtils.Vhdx/RegionTableInfo.cs b/Library/DiscUtils.Vhdx/RegionTableInfo.cs index 34b8ecc81..b39dc5233 100644 --- a/Library/DiscUtils.Vhdx/RegionTableInfo.cs +++ b/Library/DiscUtils.Vhdx/RegionTableInfo.cs @@ -67,7 +67,10 @@ public string Signature { Span buffer = stackalloc byte[4]; EndianUtilities.WriteBytesLittleEndian(_table.Signature, buffer); - return EndianUtilities.BytesToString(buffer); + + return EncodingUtilities + .GetLatin1Encoding() + .GetString(buffer); } } diff --git a/Library/DiscUtils.Wim/FileHeader.cs b/Library/DiscUtils.Wim/FileHeader.cs index 2ab060388..73a0c83bd 100644 --- a/Library/DiscUtils.Wim/FileHeader.cs +++ b/Library/DiscUtils.Wim/FileHeader.cs @@ -46,7 +46,9 @@ internal class FileHeader : IByteArraySerializable public int ReadFrom(ReadOnlySpan buffer) { - Tag = EndianUtilities.BytesToString(buffer.Slice(0, 8)); + var latin1Encoding = EncodingUtilities.GetLatin1Encoding(); + + Tag = latin1Encoding.GetString(buffer.Slice(0, 8)); HeaderSize = EndianUtilities.ToUInt32LittleEndian(buffer.Slice(8)); Version = EndianUtilities.ToUInt32LittleEndian(buffer.Slice(12)); Flags = (FileFlags)EndianUtilities.ToUInt32LittleEndian(buffer.Slice(16)); diff --git a/Library/DiscUtils.Xfs/BlockDirectoryDataEntry.cs b/Library/DiscUtils.Xfs/BlockDirectoryDataEntry.cs index 6543a7d7e..17ac97a5d 100644 --- a/Library/DiscUtils.Xfs/BlockDirectoryDataEntry.cs +++ b/Library/DiscUtils.Xfs/BlockDirectoryDataEntry.cs @@ -20,8 +20,8 @@ // DEALINGS IN THE SOFTWARE. // -using DiscUtils.Streams; using System; +using DiscUtils.Streams; namespace DiscUtils.Xfs; @@ -79,6 +79,8 @@ public override int ReadFrom(ReadOnlySpan buffer) /// public override string ToString() { - return $"{Inode}: {EndianUtilities.BytesToString(Name, 0, NameLength)}"; + var latin1Encoding = EncodingUtilities.GetLatin1Encoding(); + + return $"{Inode}: {latin1Encoding.GetString(Name, 0, NameLength)}"; } } diff --git a/Library/DiscUtils.Xfs/ShortformDirectoryEntry.cs b/Library/DiscUtils.Xfs/ShortformDirectoryEntry.cs index f087071f7..6a18f52b5 100644 --- a/Library/DiscUtils.Xfs/ShortformDirectoryEntry.cs +++ b/Library/DiscUtils.Xfs/ShortformDirectoryEntry.cs @@ -20,10 +20,10 @@ // DEALINGS IN THE SOFTWARE. // -namespace DiscUtils.Xfs; - -using DiscUtils.Streams; using System; +using DiscUtils.Streams; + +namespace DiscUtils.Xfs; internal class ShortformDirectoryEntry : IByteArraySerializable, IDirectoryEntry { @@ -81,6 +81,8 @@ void IByteArraySerializable.WriteTo(Span buffer) /// public override string ToString() { - return $"{Inode}: {EndianUtilities.BytesToString(Name, 0, NameLength)}"; + var latin1Encoding = EncodingUtilities.GetLatin1Encoding(); + + return $"{Inode}: {latin1Encoding.GetString(Name, 0, NameLength)}"; } }