mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2025-02-09 13:14:46 +01:00
Replace hex string converter and move StringUtils
This commit is contained in:
parent
a9632c8d00
commit
b5dabe78f5
@ -3,6 +3,7 @@ using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using LibHac.Util;
|
||||
|
||||
namespace LibHac.Bcat.Detail.Service.Core
|
||||
{
|
||||
|
@ -2,7 +2,7 @@
|
||||
using System.Diagnostics;
|
||||
using LibHac.Bcat.Detail.Ipc;
|
||||
using LibHac.Bcat.Detail.Service.Core;
|
||||
using LibHac.Common;
|
||||
using LibHac.Util;
|
||||
|
||||
namespace LibHac.Bcat.Detail.Service
|
||||
{
|
||||
|
@ -2,6 +2,7 @@
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
using LibHac.Common;
|
||||
using LibHac.Util;
|
||||
|
||||
namespace LibHac.Bcat
|
||||
{
|
||||
|
@ -2,6 +2,7 @@
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
using LibHac.Common;
|
||||
using LibHac.Util;
|
||||
|
||||
namespace LibHac.Bcat
|
||||
{
|
||||
|
@ -2,6 +2,7 @@
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
using LibHac.Common;
|
||||
using LibHac.Util;
|
||||
|
||||
namespace LibHac.Bcat
|
||||
{
|
||||
|
@ -4,6 +4,7 @@ using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using LibHac.Common;
|
||||
using LibHac.Crypto;
|
||||
using LibHac.Util;
|
||||
|
||||
namespace LibHac.Boot
|
||||
{
|
||||
|
@ -7,6 +7,7 @@ using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using LibHac.Common.Keys;
|
||||
using LibHac.Diag;
|
||||
using LibHac.Util;
|
||||
|
||||
namespace LibHac.Boot
|
||||
{
|
||||
|
@ -2,6 +2,7 @@
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using LibHac.Util;
|
||||
|
||||
namespace LibHac.Common
|
||||
{
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
using LibHac.Util;
|
||||
|
||||
namespace LibHac.Common
|
||||
{
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
using LibHac.Util;
|
||||
|
||||
namespace LibHac.Common
|
||||
{
|
||||
|
@ -5,6 +5,7 @@ using System.IO;
|
||||
using System.Runtime.CompilerServices;
|
||||
using LibHac.Fs;
|
||||
using LibHac.Spl;
|
||||
using LibHac.Util;
|
||||
|
||||
namespace LibHac.Common.Keys
|
||||
{
|
||||
@ -148,7 +149,7 @@ namespace LibHac.Common.Keys
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!Utilities.TryToBytes(ctx.CurrentValue, key))
|
||||
if (!StringUtils.TryFromHexString(ctx.CurrentValue, key))
|
||||
{
|
||||
key.Clear();
|
||||
|
||||
@ -204,13 +205,13 @@ namespace LibHac.Common.Keys
|
||||
var rightsId = new RightsId();
|
||||
var titleKey = new AccessKey();
|
||||
|
||||
if (!Utilities.TryToBytes(ctx.CurrentKey, SpanHelpers.AsByteSpan(ref rightsId)))
|
||||
if (!StringUtils.TryFromHexString(ctx.CurrentKey, SpanHelpers.AsByteSpan(ref rightsId)))
|
||||
{
|
||||
logger?.LogMessage($"Invalid rights ID \"{ctx.CurrentKey.ToString()}\" in title key file");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!Utilities.TryToBytes(ctx.CurrentValue, SpanHelpers.AsByteSpan(ref titleKey)))
|
||||
if (!StringUtils.TryFromHexString(ctx.CurrentValue, SpanHelpers.AsByteSpan(ref titleKey)))
|
||||
{
|
||||
logger?.LogMessage($"Invalid title key \"{ctx.CurrentValue.ToString()}\" in title key file");
|
||||
continue;
|
||||
@ -261,7 +262,7 @@ namespace LibHac.Common.Keys
|
||||
Delimiter,
|
||||
Value,
|
||||
WhiteSpace2,
|
||||
End,
|
||||
End
|
||||
}
|
||||
|
||||
private static ReaderStatus GetKeyValuePair(ref KvPairReaderContext reader)
|
||||
|
@ -4,6 +4,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using LibHac.Fs;
|
||||
using LibHac.Spl;
|
||||
using LibHac.Util;
|
||||
|
||||
using Type = LibHac.Common.Keys.KeyInfo.KeyType;
|
||||
using RangeType = LibHac.Common.Keys.KeyInfo.KeyRangeType;
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using LibHac.Diag;
|
||||
using LibHac.Util;
|
||||
|
||||
namespace LibHac.Common.Keys
|
||||
{
|
||||
@ -140,7 +141,7 @@ namespace LibHac.Common.Keys
|
||||
byte index = default;
|
||||
|
||||
// Try to get the index of the key name
|
||||
if (!keyName.Slice(keyName.Length - 2, 2).TryToBytes(SpanHelpers.AsSpan(ref index)))
|
||||
if (!StringUtils.TryFromHexString(keyName.Slice(keyName.Length - 2, 2), SpanHelpers.AsSpan(ref index)))
|
||||
return false;
|
||||
|
||||
// Check if the index is in this key's range
|
||||
|
@ -3,6 +3,7 @@ using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using LibHac.Fs;
|
||||
using LibHac.FsSystem;
|
||||
using LibHac.Util;
|
||||
|
||||
namespace LibHac.Common
|
||||
{
|
||||
|
@ -3,6 +3,7 @@ using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using LibHac.Util;
|
||||
|
||||
namespace LibHac.Common
|
||||
{
|
||||
|
@ -3,6 +3,7 @@ using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using LibHac.Util;
|
||||
|
||||
namespace LibHac.Common
|
||||
{
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
using LibHac.Util;
|
||||
|
||||
namespace LibHac.Common
|
||||
{
|
||||
|
@ -3,6 +3,7 @@ using System.Buffers;
|
||||
using System.Buffers.Text;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using LibHac.Util;
|
||||
|
||||
namespace LibHac.Common
|
||||
{
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
using LibHac.Util;
|
||||
|
||||
namespace LibHac.Common
|
||||
{
|
||||
|
@ -3,6 +3,7 @@ using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using LibHac.Common;
|
||||
using LibHac.Util;
|
||||
|
||||
namespace LibHac.Crypto
|
||||
{
|
||||
|
@ -8,6 +8,7 @@ using LibHac.Fs.Fsa;
|
||||
using LibHac.FsSrv;
|
||||
using LibHac.FsSrv.Sf;
|
||||
using LibHac.FsSystem;
|
||||
using LibHac.Util;
|
||||
|
||||
namespace LibHac.Fs
|
||||
{
|
||||
|
@ -4,6 +4,7 @@ using System.IO;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs.Fsa;
|
||||
using LibHac.FsSystem;
|
||||
using LibHac.Util;
|
||||
|
||||
namespace LibHac.Fs
|
||||
{
|
||||
|
@ -2,6 +2,7 @@
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
using LibHac.Common;
|
||||
using LibHac.Util;
|
||||
|
||||
namespace LibHac.Fs
|
||||
{
|
||||
|
@ -4,6 +4,7 @@ using LibHac.Common;
|
||||
using LibHac.Fs.Fsa;
|
||||
using LibHac.FsSrv;
|
||||
using LibHac.FsSystem;
|
||||
using LibHac.Util;
|
||||
using static LibHac.Fs.CommonMountNames;
|
||||
|
||||
namespace LibHac.Fs.Shim
|
||||
|
@ -2,6 +2,7 @@
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs.Fsa;
|
||||
using LibHac.FsSrv;
|
||||
using LibHac.Util;
|
||||
|
||||
namespace LibHac.Fs.Shim
|
||||
{
|
||||
|
@ -5,6 +5,7 @@ using LibHac.Common;
|
||||
using LibHac.Fs.Fsa;
|
||||
using LibHac.FsSrv;
|
||||
using LibHac.FsSystem;
|
||||
using LibHac.Util;
|
||||
using static LibHac.Fs.CommonMountNames;
|
||||
|
||||
namespace LibHac.Fs.Shim
|
||||
|
@ -10,6 +10,7 @@ using LibHac.FsSystem;
|
||||
using LibHac.Kvdb;
|
||||
using LibHac.Ncm;
|
||||
using LibHac.Spl;
|
||||
using LibHac.Util;
|
||||
|
||||
namespace LibHac.FsSrv
|
||||
{
|
||||
|
@ -9,6 +9,7 @@ using LibHac.FsSystem;
|
||||
using LibHac.FsSrv.Creators;
|
||||
using LibHac.FsSystem.NcaUtils;
|
||||
using LibHac.Spl;
|
||||
using LibHac.Util;
|
||||
using RightsId = LibHac.Fs.RightsId;
|
||||
|
||||
namespace LibHac.FsSrv
|
||||
|
@ -2,6 +2,7 @@
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using LibHac.FsSystem;
|
||||
using LibHac.Util;
|
||||
|
||||
namespace LibHac.FsSrv
|
||||
{
|
||||
|
@ -4,6 +4,7 @@ using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using LibHac.Util;
|
||||
|
||||
namespace LibHac.FsSrv.Sf
|
||||
{
|
||||
|
@ -2,6 +2,7 @@
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using LibHac.Fs.Fsa;
|
||||
using LibHac.Util;
|
||||
|
||||
namespace LibHac.FsSystem
|
||||
{
|
||||
@ -38,7 +39,7 @@ namespace LibHac.FsSystem
|
||||
}
|
||||
else
|
||||
{
|
||||
string entryName = Utilities.GetUtf8StringNullTerminated(entry.Name);
|
||||
string entryName = StringUtils.NullTerminatedUtf8ToString(entry.Name);
|
||||
entry.Size = GetAesXtsFileSize(PathTools.Combine(Path.ToString(), entryName).ToU8Span());
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ using System.Runtime.InteropServices;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using LibHac.Fs.Fsa;
|
||||
using LibHac.Util;
|
||||
|
||||
namespace LibHac.FsSystem
|
||||
{
|
||||
@ -63,7 +64,7 @@ namespace LibHac.FsSystem
|
||||
|
||||
if (!Mode.HasFlag(OpenDirectoryMode.NoFileSize))
|
||||
{
|
||||
string entryName = Utilities.GetUtf8StringNullTerminated(entry.Name);
|
||||
string entryName = StringUtils.NullTerminatedUtf8ToString(entry.Name);
|
||||
string entryFullPath = PathTools.Combine(_path.ToString(), entryName);
|
||||
|
||||
rc = ParentFileSystem.GetConcatenationFileSize(out long fileSize, entryFullPath.ToU8Span());
|
||||
@ -122,7 +123,7 @@ namespace LibHac.FsSystem
|
||||
}
|
||||
else
|
||||
{
|
||||
string name = Utilities.GetUtf8StringNullTerminated(entry.Name);
|
||||
string name = StringUtils.NullTerminatedUtf8ToString(entry.Name);
|
||||
var fullPath = PathTools.Combine(_path.ToString(), name).ToU8Span();
|
||||
|
||||
return ParentFileSystem.IsConcatenationFile(fullPath);
|
||||
|
@ -6,6 +6,7 @@ using System.Runtime.InteropServices;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using LibHac.Fs.Fsa;
|
||||
using LibHac.Util;
|
||||
|
||||
namespace LibHac.FsSystem
|
||||
{
|
||||
|
@ -2,6 +2,7 @@
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using LibHac.Fs.Fsa;
|
||||
using LibHac.Util;
|
||||
|
||||
namespace LibHac.FsSystem
|
||||
{
|
||||
|
@ -2,6 +2,7 @@
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using LibHac.Fs.Fsa;
|
||||
using LibHac.Util;
|
||||
|
||||
namespace LibHac.FsSystem
|
||||
{
|
||||
|
@ -5,6 +5,7 @@ using System.IO;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using LibHac.Fs.Fsa;
|
||||
using LibHac.Util;
|
||||
|
||||
namespace LibHac.FsSystem
|
||||
{
|
||||
|
@ -4,6 +4,7 @@ using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using LibHac.Util;
|
||||
|
||||
namespace LibHac.FsSystem
|
||||
{
|
||||
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using LibHac.Fs.Fsa;
|
||||
using LibHac.Util;
|
||||
|
||||
namespace LibHac.FsSystem
|
||||
{
|
||||
|
@ -2,9 +2,9 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Runtime.CompilerServices;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using LibHac.Fs.Fsa;
|
||||
using LibHac.Util;
|
||||
|
||||
namespace LibHac.FsSystem
|
||||
{
|
||||
@ -35,7 +35,7 @@ namespace LibHac.FsSystem
|
||||
|
||||
if (!CanReturnEntry(isDir, Mode)) continue;
|
||||
|
||||
ReadOnlySpan<byte> name = Utilities.GetUtf8Bytes(localEntry.Name);
|
||||
ReadOnlySpan<byte> name = StringUtils.StringToUtf8(localEntry.Name);
|
||||
DirectoryEntryType type = isDir ? DirectoryEntryType.Directory : DirectoryEntryType.File;
|
||||
long length = isDir ? 0 : ((FileInfo)localEntry).Length;
|
||||
|
||||
|
@ -7,6 +7,7 @@ using LibHac.Common.Keys;
|
||||
using LibHac.Crypto;
|
||||
using LibHac.Diag;
|
||||
using LibHac.Fs;
|
||||
using LibHac.Util;
|
||||
|
||||
namespace LibHac.FsSystem.NcaUtils
|
||||
{
|
||||
|
@ -1,9 +1,9 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using LibHac.Fs.Fsa;
|
||||
using LibHac.Util;
|
||||
|
||||
namespace LibHac.FsSystem
|
||||
{
|
||||
|
@ -5,6 +5,7 @@ using LibHac.Crypto;
|
||||
using LibHac.Fs;
|
||||
using LibHac.Fs.Fsa;
|
||||
using LibHac.FsSystem.Detail;
|
||||
using LibHac.Util;
|
||||
|
||||
namespace LibHac.FsSystem
|
||||
{
|
||||
|
@ -5,6 +5,7 @@ using System.Runtime.InteropServices;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using LibHac.FsSystem.Detail;
|
||||
using LibHac.Util;
|
||||
|
||||
namespace LibHac.FsSystem
|
||||
{
|
||||
|
@ -4,6 +4,7 @@ using System.IO.Enumeration;
|
||||
using System.Runtime.CompilerServices;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using LibHac.Util;
|
||||
|
||||
namespace LibHac.FsSystem
|
||||
{
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using LibHac.Fs;
|
||||
using LibHac.Util;
|
||||
|
||||
namespace LibHac.FsSystem.RomFs
|
||||
{
|
||||
@ -83,7 +84,7 @@ namespace LibHac.FsSystem.RomFs
|
||||
|
||||
public bool TryOpenFile(string path, out T fileInfo)
|
||||
{
|
||||
FindPathRecursive(Utilities.GetUtf8Bytes(path), out RomEntryKey key);
|
||||
FindPathRecursive(StringUtils.StringToUtf8(path), out RomEntryKey key);
|
||||
|
||||
if (FileTable.TryGetValue(ref key, out RomKeyValuePair<FileRomEntry> keyValuePair))
|
||||
{
|
||||
@ -116,7 +117,7 @@ namespace LibHac.FsSystem.RomFs
|
||||
/// otherwise, <see langword="false"/>.</returns>
|
||||
public bool TryOpenDirectory(string path, out FindPosition position)
|
||||
{
|
||||
FindPathRecursive(Utilities.GetUtf8Bytes(path), out RomEntryKey key);
|
||||
FindPathRecursive(StringUtils.StringToUtf8(path), out RomEntryKey key);
|
||||
|
||||
if (DirectoryTable.TryGetValue(ref key, out RomKeyValuePair<DirectoryRomEntry> keyValuePair))
|
||||
{
|
||||
@ -169,7 +170,7 @@ namespace LibHac.FsSystem.RomFs
|
||||
position.NextFile = entry.NextSibling;
|
||||
info = entry.Info;
|
||||
|
||||
name = Utilities.GetUtf8String(nameBytes);
|
||||
name = StringUtils.Utf8ToString(nameBytes);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -193,7 +194,7 @@ namespace LibHac.FsSystem.RomFs
|
||||
ref DirectoryRomEntry entry = ref DirectoryTable.GetValueReference(position.NextDirectory, out Span<byte> nameBytes);
|
||||
position.NextDirectory = entry.NextSibling;
|
||||
|
||||
name = Utilities.GetUtf8String(nameBytes);
|
||||
name = StringUtils.Utf8ToString(nameBytes);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -207,7 +208,7 @@ namespace LibHac.FsSystem.RomFs
|
||||
public void AddFile(string path, ref T fileInfo)
|
||||
{
|
||||
path = PathTools.Normalize(path);
|
||||
ReadOnlySpan<byte> pathBytes = Utilities.GetUtf8Bytes(path);
|
||||
ReadOnlySpan<byte> pathBytes = StringUtils.StringToUtf8(path);
|
||||
|
||||
if (path == "/") throw new ArgumentException("Path cannot be empty");
|
||||
|
||||
@ -223,7 +224,7 @@ namespace LibHac.FsSystem.RomFs
|
||||
{
|
||||
path = PathTools.Normalize(path);
|
||||
|
||||
CreateDirectoryRecursive(Utilities.GetUtf8Bytes(path));
|
||||
CreateDirectoryRecursive(StringUtils.StringToUtf8(path));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -1,8 +1,8 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using LibHac.Fs.Fsa;
|
||||
using LibHac.Util;
|
||||
|
||||
namespace LibHac.FsSystem.RomFs
|
||||
{
|
||||
|
@ -3,6 +3,7 @@ using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using LibHac.Util;
|
||||
|
||||
namespace LibHac.FsSystem.Save
|
||||
{
|
||||
@ -59,7 +60,7 @@ namespace LibHac.FsSystem.Save
|
||||
position.NextFile = entry.NextSibling;
|
||||
info = entry.Value;
|
||||
|
||||
name = Utilities.GetUtf8StringNullTerminated(nameBytes);
|
||||
name = StringUtils.NullTerminatedUtf8ToString(nameBytes);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -85,7 +86,7 @@ namespace LibHac.FsSystem.Save
|
||||
|
||||
position.NextDirectory = entry.NextSibling;
|
||||
|
||||
name = Utilities.GetUtf8StringNullTerminated(nameBytes);
|
||||
name = StringUtils.NullTerminatedUtf8ToString(nameBytes);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using LibHac.Fs.Fsa;
|
||||
using LibHac.Util;
|
||||
|
||||
namespace LibHac.FsSystem.Save
|
||||
{
|
||||
|
@ -3,8 +3,8 @@ using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using LibHac.Util;
|
||||
|
||||
namespace LibHac.FsSystem.Save
|
||||
{
|
||||
|
@ -3,6 +3,7 @@ using System.Diagnostics;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using LibHac.Fs.Fsa;
|
||||
using LibHac.Util;
|
||||
|
||||
namespace LibHac.FsSystem
|
||||
{
|
||||
|
@ -5,6 +5,7 @@ using LibHac.Common;
|
||||
using LibHac.Diag;
|
||||
using LibHac.Fs;
|
||||
using LibHac.Fs.Fsa;
|
||||
using LibHac.Util;
|
||||
|
||||
namespace LibHac.FsSystem
|
||||
{
|
||||
|
@ -2,6 +2,7 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using LibHac.Common;
|
||||
using LibHac.Util;
|
||||
|
||||
namespace LibHac.Kvdb
|
||||
{
|
||||
|
@ -4,6 +4,7 @@ using System.IO;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using LibHac.Common;
|
||||
using LibHac.Util;
|
||||
|
||||
namespace LibHac
|
||||
{
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using LibHac.Common;
|
||||
using LibHac.Util;
|
||||
|
||||
namespace LibHac.Sm
|
||||
{
|
||||
|
@ -12,6 +12,7 @@ using LibHac.FsSystem.NcaUtils;
|
||||
using LibHac.FsSystem.Save;
|
||||
using LibHac.Ncm;
|
||||
using LibHac.Ns;
|
||||
using LibHac.Util;
|
||||
|
||||
namespace LibHac
|
||||
{
|
||||
|
233
src/LibHac/Util/Impl/HexConverter.cs
Normal file
233
src/LibHac/Util/Impl/HexConverter.cs
Normal file
@ -0,0 +1,233 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace LibHac.Util.Impl
|
||||
{
|
||||
internal static class HexConverter
|
||||
{
|
||||
public enum Casing : uint
|
||||
{
|
||||
// Output [ '0' .. '9' ] and [ 'A' .. 'F' ].
|
||||
Upper = 0,
|
||||
|
||||
// Output [ '0' .. '9' ] and [ 'a' .. 'f' ].
|
||||
// This works because values in the range [ 0x30 .. 0x39 ] ([ '0' .. '9' ])
|
||||
// already have the 0x20 bit set, so ORing them with 0x20 is a no-op,
|
||||
// while outputs in the range [ 0x41 .. 0x46 ] ([ 'A' .. 'F' ])
|
||||
// don't have the 0x20 bit set, so ORing them maps to
|
||||
// [ 0x61 .. 0x66 ] ([ 'a' .. 'f' ]), which is what we want.
|
||||
Lower = 0x2020U,
|
||||
}
|
||||
|
||||
// We want to pack the incoming byte into a single integer [ 0000 HHHH 0000 LLLL ],
|
||||
// where HHHH and LLLL are the high and low nibbles of the incoming byte. Then
|
||||
// subtract this integer from a constant minuend as shown below.
|
||||
//
|
||||
// [ 1000 1001 1000 1001 ]
|
||||
// - [ 0000 HHHH 0000 LLLL ]
|
||||
// =========================
|
||||
// [ *YYY **** *ZZZ **** ]
|
||||
//
|
||||
// The end result of this is that YYY is 0b000 if HHHH <= 9, and YYY is 0b111 if HHHH >= 10.
|
||||
// Similarly, ZZZ is 0b000 if LLLL <= 9, and ZZZ is 0b111 if LLLL >= 10.
|
||||
// (We don't care about the value of asterisked bits.)
|
||||
//
|
||||
// To turn a nibble in the range [ 0 .. 9 ] into hex, we calculate hex := nibble + 48 (ascii '0').
|
||||
// To turn a nibble in the range [ 10 .. 15 ] into hex, we calculate hex := nibble - 10 + 65 (ascii 'A').
|
||||
// => hex := nibble + 55.
|
||||
// The difference in the starting ASCII offset is (55 - 48) = 7, depending on whether the nibble is <= 9 or >= 10.
|
||||
// Since 7 is 0b111, this conveniently matches the YYY or ZZZ value computed during the earlier subtraction.
|
||||
|
||||
// The commented out code below is code that directly implements the logic described above.
|
||||
|
||||
// uint packedOriginalValues = (((uint)value & 0xF0U) << 4) + ((uint)value & 0x0FU);
|
||||
// uint difference = 0x8989U - packedOriginalValues;
|
||||
// uint add7Mask = (difference & 0x7070U) >> 4; // line YYY and ZZZ back up with the packed values
|
||||
// uint packedResult = packedOriginalValues + add7Mask + 0x3030U /* ascii '0' */;
|
||||
|
||||
// The code below is equivalent to the commented out code above but has been tweaked
|
||||
// to allow codegen to make some extra optimizations.
|
||||
|
||||
// The low byte of the packed result contains the hex representation of the incoming byte's low nibble.
|
||||
// The adjacent byte of the packed result contains the hex representation of the incoming byte's high nibble.
|
||||
|
||||
// Finally, write to the output buffer starting with the *highest* index so that codegen can
|
||||
// elide all but the first bounds check. (This only works if 'startingIndex' is a compile-time constant.)
|
||||
|
||||
// The JIT can elide bounds checks if 'startingIndex' is constant and if the caller is
|
||||
// writing to a span of known length (or the caller has already checked the bounds of the
|
||||
// furthest access).
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void ToBytesBuffer(byte value, Span<byte> buffer, int startingIndex = 0, Casing casing = Casing.Upper)
|
||||
{
|
||||
uint difference = ((value & 0xF0U) << 4) + (value & 0x0FU) - 0x8989U;
|
||||
uint packedResult = ((((uint)(-(int)difference) & 0x7070U) >> 4) + difference + 0xB9B9U) | (uint)casing;
|
||||
|
||||
buffer[startingIndex + 1] = (byte)packedResult;
|
||||
buffer[startingIndex] = (byte)(packedResult >> 8);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void ToCharsBuffer(byte value, Span<char> buffer, int startingIndex = 0, Casing casing = Casing.Upper)
|
||||
{
|
||||
uint difference = ((value & 0xF0U) << 4) + (value & 0x0FU) - 0x8989U;
|
||||
uint packedResult = ((((uint)(-(int)difference) & 0x7070U) >> 4) + difference + 0xB9B9U) | (uint)casing;
|
||||
|
||||
buffer[startingIndex + 1] = (char)(packedResult & 0xFF);
|
||||
buffer[startingIndex] = (char)(packedResult >> 8);
|
||||
}
|
||||
|
||||
public static void EncodeToUtf16(ReadOnlySpan<byte> bytes, Span<char> chars, Casing casing = Casing.Upper)
|
||||
{
|
||||
Debug.Assert(chars.Length >= bytes.Length * 2);
|
||||
|
||||
for (int pos = 0; pos < bytes.Length; ++pos)
|
||||
{
|
||||
ToCharsBuffer(bytes[pos], chars, pos * 2, casing);
|
||||
}
|
||||
}
|
||||
|
||||
public static unsafe string ToString(ReadOnlySpan<byte> bytes, Casing casing = Casing.Upper)
|
||||
{
|
||||
fixed (byte* bytesPtr = bytes)
|
||||
{
|
||||
// Todo: Make lambda static in C# 9
|
||||
return string.Create(bytes.Length * 2, (Ptr: (IntPtr)bytesPtr, bytes.Length, casing), (chars, args) =>
|
||||
{
|
||||
var ros = new ReadOnlySpan<byte>((byte*)args.Ptr, args.Length);
|
||||
EncodeToUtf16(ros, chars, args.casing);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static char ToCharUpper(int value)
|
||||
{
|
||||
value &= 0xF;
|
||||
value += '0';
|
||||
|
||||
if (value > '9')
|
||||
{
|
||||
value += ('A' - ('9' + 1));
|
||||
}
|
||||
|
||||
return (char)value;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static char ToCharLower(int value)
|
||||
{
|
||||
value &= 0xF;
|
||||
value += '0';
|
||||
|
||||
if (value > '9')
|
||||
{
|
||||
value += ('a' - ('9' + 1));
|
||||
}
|
||||
|
||||
return (char)value;
|
||||
}
|
||||
|
||||
public static bool TryDecodeFromUtf16(ReadOnlySpan<char> chars, Span<byte> bytes)
|
||||
{
|
||||
return TryDecodeFromUtf16(chars, bytes, out _);
|
||||
}
|
||||
|
||||
public static bool TryDecodeFromUtf16(ReadOnlySpan<char> chars, Span<byte> bytes, out int charsProcessed)
|
||||
{
|
||||
Debug.Assert(chars.Length % 2 == 0, "Un-even number of characters provided");
|
||||
Debug.Assert(chars.Length / 2 == bytes.Length, "Target buffer not right-sized for provided characters");
|
||||
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
int byteLo = 0;
|
||||
int byteHi = 0;
|
||||
while (j < bytes.Length)
|
||||
{
|
||||
byteLo = FromChar(chars[i + 1]);
|
||||
byteHi = FromChar(chars[i]);
|
||||
|
||||
// byteHi hasn't been shifted to the high half yet, so the only way the bitwise or produces this pattern
|
||||
// is if either byteHi or byteLo was not a hex character.
|
||||
if ((byteLo | byteHi) == 0xFF)
|
||||
break;
|
||||
|
||||
bytes[j++] = (byte)((byteHi << 4) | byteLo);
|
||||
i += 2;
|
||||
}
|
||||
|
||||
if (byteLo == 0xFF)
|
||||
i++;
|
||||
|
||||
charsProcessed = i;
|
||||
return (byteLo | byteHi) != 0xFF;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int FromChar(int c)
|
||||
{
|
||||
return c >= CharToHexLookup.Length ? 0xFF : CharToHexLookup[c];
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int FromUpperChar(int c)
|
||||
{
|
||||
return c > 71 ? 0xFF : CharToHexLookup[c];
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int FromLowerChar(int c)
|
||||
{
|
||||
if ((uint)(c - '0') <= '9' - '0')
|
||||
return c - '0';
|
||||
|
||||
if ((uint)(c - 'a') <= 'f' - 'a')
|
||||
return c - 'a' + 10;
|
||||
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool IsHexChar(int c)
|
||||
{
|
||||
return FromChar(c) != 0xFF;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool IsHexUpperChar(int c)
|
||||
{
|
||||
return (uint)(c - '0') <= 9 || (uint)(c - 'A') <= ('F' - 'A');
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool IsHexLowerChar(int c)
|
||||
{
|
||||
return (uint)(c - '0') <= 9 || (uint)(c - 'a') <= ('f' - 'a');
|
||||
}
|
||||
|
||||
/// <summary>Map from an ASCII char to its hex value, e.g. arr['b'] == 11. 0xFF means it's not a hex digit.</summary>
|
||||
public static ReadOnlySpan<byte> CharToHexLookup => new byte[]
|
||||
{
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 15
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 31
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 47
|
||||
0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 63
|
||||
0xFF, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 79
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 95
|
||||
0xFF, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 111
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 127
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 143
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 159
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 175
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 191
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 207
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 223
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 239
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF // 255
|
||||
};
|
||||
}
|
||||
}
|
@ -1,7 +1,8 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using LibHac.Util.Impl;
|
||||
|
||||
namespace LibHac.Common
|
||||
namespace LibHac.Util
|
||||
{
|
||||
public static class StringUtils
|
||||
{
|
||||
@ -159,11 +160,23 @@ namespace LibHac.Common
|
||||
return iDest;
|
||||
}
|
||||
|
||||
public static ReadOnlySpan<byte> StringToUtf8(string value)
|
||||
{
|
||||
return Encoding.UTF8.GetBytes(value).AsSpan();
|
||||
}
|
||||
|
||||
public static string Utf8ToString(ReadOnlySpan<byte> value)
|
||||
{
|
||||
return Encoding.UTF8.GetString(value);
|
||||
}
|
||||
|
||||
public static string NullTerminatedUtf8ToString(ReadOnlySpan<byte> value)
|
||||
{
|
||||
int length = GetLength(value);
|
||||
|
||||
return Encoding.UTF8.GetString(value.Slice(0, length));
|
||||
}
|
||||
|
||||
public static string Utf8ZToString(ReadOnlySpan<byte> value)
|
||||
{
|
||||
return Utf8ToString(value.Slice(0, GetLength(value)));
|
||||
@ -184,5 +197,69 @@ namespace LibHac.Common
|
||||
return (uint)(c - (byte)'0') <= 9 ||
|
||||
(c | 0x20u) - (byte)'a' <= 'f' - 'a';
|
||||
}
|
||||
|
||||
public static bool TryFromHexString(ReadOnlySpan<char> chars, Span<byte> outputBytes)
|
||||
{
|
||||
if ((uint)chars.Length % 2 != 0)
|
||||
return false;
|
||||
|
||||
uint bytesLength = (uint)chars.Length / 2;
|
||||
|
||||
if ((uint)outputBytes.Length >= bytesLength)
|
||||
{
|
||||
Span<byte> bytes = outputBytes.Slice(0, (int)bytesLength);
|
||||
return HexConverter.TryDecodeFromUtf16(chars, bytes);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static byte[] ToBytes(this string input)
|
||||
{
|
||||
return FromHexString(input);
|
||||
}
|
||||
|
||||
public static byte[] FromHexString(string input)
|
||||
{
|
||||
if ((uint)input.Length % 2 != 0)
|
||||
throw new FormatException("Hex input must be a multiple of 2.");
|
||||
|
||||
var result = new byte[input.Length >> 1];
|
||||
|
||||
if (!HexConverter.TryDecodeFromUtf16(input, result))
|
||||
{
|
||||
throw new FormatException("Hex input contains invalid characters.");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void FromHexString(ReadOnlySpan<char> chars, Span<byte> outputBytes)
|
||||
{
|
||||
if ((uint)chars.Length % 2 != 0)
|
||||
throw new FormatException("Hex input must be a multiple of 2.");
|
||||
|
||||
uint bytesLength = (uint)chars.Length / 2;
|
||||
|
||||
if ((uint)outputBytes.Length >= bytesLength)
|
||||
{
|
||||
Span<byte> bytes = outputBytes.Slice(0, (int)bytesLength);
|
||||
|
||||
if (!HexConverter.TryDecodeFromUtf16(chars, bytes))
|
||||
{
|
||||
throw new FormatException("Hex input contains invalid characters.");
|
||||
}
|
||||
}
|
||||
|
||||
throw new ArgumentException("Buffer is not large enough to fit the input hex string.", nameof(outputBytes));
|
||||
}
|
||||
|
||||
public static string ToHexString(this byte[] bytes) => ToHexString((ReadOnlySpan<byte>)bytes);
|
||||
public static string ToHexString(this Span<byte> bytes) => ToHexString((ReadOnlySpan<byte>)bytes);
|
||||
|
||||
public static string ToHexString(this ReadOnlySpan<byte> bytes)
|
||||
{
|
||||
return HexConverter.ToString(bytes);
|
||||
}
|
||||
}
|
||||
}
|
@ -67,27 +67,6 @@ namespace LibHac
|
||||
return a1.SequenceEqual(a2);
|
||||
}
|
||||
|
||||
public static ReadOnlySpan<byte> GetUtf8Bytes(string value)
|
||||
{
|
||||
return Encoding.UTF8.GetBytes(value).AsSpan();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static string GetUtf8String(ReadOnlySpan<byte> value)
|
||||
{
|
||||
return Encoding.UTF8.GetString(value);
|
||||
}
|
||||
|
||||
public static string GetUtf8StringNullTerminated(ReadOnlySpan<byte> value)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < value.Length && value[i] != 0; i++) { }
|
||||
|
||||
value = value.Slice(0, i);
|
||||
|
||||
return Encoding.UTF8.GetString(value);
|
||||
}
|
||||
|
||||
public static bool IsEmpty(this byte[] array) => ((ReadOnlySpan<byte>)array).IsEmpty();
|
||||
public static bool IsEmpty(this Span<byte> span) => ((ReadOnlySpan<byte>)span).IsEmpty();
|
||||
|
||||
@ -234,147 +213,6 @@ namespace LibHac
|
||||
return Encoding.UTF8.GetString(reader.ReadBytes(size), 0, size);
|
||||
}
|
||||
|
||||
private static bool TryHexToInt(char c, out int value)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case '0':
|
||||
value = 0; break;
|
||||
case '1':
|
||||
value = 1; break;
|
||||
case '2':
|
||||
value = 2; break;
|
||||
case '3':
|
||||
value = 3; break;
|
||||
case '4':
|
||||
value = 4; break;
|
||||
case '5':
|
||||
value = 5; break;
|
||||
case '6':
|
||||
value = 6; break;
|
||||
case '7':
|
||||
value = 7; break;
|
||||
case '8':
|
||||
value = 8; break;
|
||||
case '9':
|
||||
value = 9; break;
|
||||
case 'a':
|
||||
case 'A':
|
||||
value = 10; break;
|
||||
case 'b':
|
||||
case 'B':
|
||||
value = 11; break;
|
||||
case 'c':
|
||||
case 'C':
|
||||
value = 12; break;
|
||||
case 'd':
|
||||
case 'D':
|
||||
value = 13; break;
|
||||
case 'e':
|
||||
case 'E':
|
||||
value = 14; break;
|
||||
case 'f':
|
||||
case 'F':
|
||||
value = 15; break;
|
||||
default:
|
||||
value = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static readonly byte[,] ByteLookup = {
|
||||
{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f},
|
||||
{0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0}
|
||||
};
|
||||
|
||||
public static byte[] ToBytes(this string input)
|
||||
{
|
||||
var result = new byte[(input.Length + 1) >> 1];
|
||||
int lastcell = result.Length - 1;
|
||||
int lastchar = input.Length - 1;
|
||||
for (int i = 0; i < input.Length; i++)
|
||||
{
|
||||
if (!TryHexToInt(input[lastchar - i], out int hexInt))
|
||||
{
|
||||
throw new FormatException($"Unrecognized hex char {input[lastchar - i]}");
|
||||
}
|
||||
|
||||
result[lastcell - (i >> 1)] |= ByteLookup[i & 1, hexInt];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static bool TryToBytes(this string input, out byte[] bytes)
|
||||
{
|
||||
var result = new byte[(input.Length + 1) >> 1];
|
||||
int lastcell = result.Length - 1;
|
||||
int lastchar = input.Length - 1;
|
||||
for (int i = 0; i < input.Length; i++)
|
||||
{
|
||||
if (!TryHexToInt(input[lastchar - i], out int hexInt))
|
||||
{
|
||||
bytes = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
result[lastcell - (i >> 1)] |= ByteLookup[i & 1, hexInt];
|
||||
}
|
||||
bytes = result;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool TryToBytes(this ReadOnlySpan<char> input, Span<byte> output)
|
||||
{
|
||||
if (input.Length != output.Length * 2)
|
||||
return false;
|
||||
|
||||
int lastcell = output.Length - 1;
|
||||
int lastchar = input.Length - 1;
|
||||
for (int i = 0; i < input.Length; i++)
|
||||
{
|
||||
if (!TryHexToInt(input[lastchar - i], out int hexInt))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
output[lastcell - (i >> 1)] |= ByteLookup[i & 1, hexInt];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static readonly uint[] Lookup32 = CreateLookup32();
|
||||
|
||||
private static uint[] CreateLookup32()
|
||||
{
|
||||
var result = new uint[256];
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
string s = i.ToString("X2");
|
||||
result[i] = s[0] + ((uint)s[1] << 16);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static string ToHexString(this byte[] bytes) => ToHexString(bytes.AsSpan());
|
||||
|
||||
public static string ToHexString(this Span<byte> bytes) => ToHexString((ReadOnlySpan<byte>)bytes);
|
||||
|
||||
public static string ToHexString(this ReadOnlySpan<byte> bytes)
|
||||
{
|
||||
uint[] lookup32 = Lookup32;
|
||||
var result = new char[bytes.Length * 2];
|
||||
for (int i = 0; i < bytes.Length; i++)
|
||||
{
|
||||
uint val = lookup32[bytes[i]];
|
||||
result[2 * i] = (char)val;
|
||||
result[2 * i + 1] = (char)(val >> 16);
|
||||
}
|
||||
return new string(result);
|
||||
}
|
||||
|
||||
public static long MediaToReal(long media)
|
||||
{
|
||||
return MediaSize * media;
|
||||
|
@ -6,6 +6,7 @@ using LibHac.Common;
|
||||
using LibHac.Crypto;
|
||||
using LibHac.Fs;
|
||||
using LibHac.FsSystem;
|
||||
using LibHac.Util;
|
||||
using static hactoolnet.Print;
|
||||
|
||||
namespace hactoolnet
|
||||
@ -67,7 +68,7 @@ namespace hactoolnet
|
||||
AesXtsFileHeader header = xtsFile.Header;
|
||||
uint magic = header.Magic;
|
||||
|
||||
PrintItem(sb, colLen, " Magic:", Utilities.GetUtf8String(SpanHelpers.AsReadOnlyByteSpan(in magic)));
|
||||
PrintItem(sb, colLen, " Magic:", StringUtils.Utf8ToString(SpanHelpers.AsReadOnlyByteSpan(in magic)));
|
||||
PrintItem(sb, colLen, " Content Type:", GetContentType(contentType));
|
||||
PrintItem(sb, colLen, " Content Size:", $"{header.Size:x12}");
|
||||
PrintItem(sb, colLen, " Header HMAC:", header.Signature);
|
||||
|
@ -4,6 +4,7 @@ using System.Text;
|
||||
using LibHac;
|
||||
using LibHac.Fs;
|
||||
using LibHac.FsSystem;
|
||||
using LibHac.Util;
|
||||
using static hactoolnet.Print;
|
||||
|
||||
namespace hactoolnet
|
||||
|
@ -4,6 +4,7 @@ using System.Text;
|
||||
using LibHac;
|
||||
using LibHac.Common.Keys;
|
||||
using LibHac.Fs;
|
||||
using LibHac.Util;
|
||||
|
||||
namespace hactoolnet
|
||||
{
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using LibHac.Crypto;
|
||||
using LibHac.Util;
|
||||
using Xunit;
|
||||
|
||||
namespace LibHac.Tests
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System.Linq;
|
||||
using LibHac.FsSystem;
|
||||
using LibHac.Util;
|
||||
using Xunit;
|
||||
|
||||
namespace LibHac.Tests
|
||||
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using LibHac.Util;
|
||||
using Xunit;
|
||||
|
||||
namespace LibHac.Tests.CryptoTests
|
||||
|
@ -2,6 +2,7 @@
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using LibHac.Fs.Fsa;
|
||||
using LibHac.Util;
|
||||
using Xunit;
|
||||
|
||||
namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
|
@ -3,6 +3,7 @@ using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using LibHac.Fs.Fsa;
|
||||
using LibHac.FsSystem;
|
||||
using LibHac.Util;
|
||||
using Xunit;
|
||||
|
||||
namespace LibHac.Tests.Fs
|
||||
|
@ -1,5 +1,6 @@
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using LibHac.Util;
|
||||
using Xunit;
|
||||
|
||||
namespace LibHac.Tests.Fs
|
||||
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using LibHac.Common;
|
||||
using LibHac.FsSystem;
|
||||
using LibHac.Util;
|
||||
using Xunit;
|
||||
|
||||
namespace LibHac.Tests
|
||||
|
Loading…
x
Reference in New Issue
Block a user