mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Add remaining GetRightsId methods and U8StringBuilder
This commit is contained in:
parent
fdd7eebb4b
commit
9934f477d5
5 changed files with 180 additions and 6 deletions
38
src/LibHac/Common/PaddingStructs.cs
Normal file
38
src/LibHac/Common/PaddingStructs.cs
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace LibHac.Common
|
||||||
|
{
|
||||||
|
// In order for the Visual Studio debugger to accurately display a struct, every offset
|
||||||
|
// in the struct that is used for the debugger display must be part of a field.
|
||||||
|
// These padding structs make it easier to accomplish that.
|
||||||
|
[StructLayout(LayoutKind.Sequential, Size = 0x20)]
|
||||||
|
internal struct Padding20
|
||||||
|
{
|
||||||
|
[DebuggerBrowsable(DebuggerBrowsableState.Never)] private readonly ulong Padding00;
|
||||||
|
[DebuggerBrowsable(DebuggerBrowsableState.Never)] private readonly ulong Padding08;
|
||||||
|
[DebuggerBrowsable(DebuggerBrowsableState.Never)] private readonly ulong Padding10;
|
||||||
|
[DebuggerBrowsable(DebuggerBrowsableState.Never)] private readonly ulong Padding18;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential, Size = 0x40)]
|
||||||
|
internal struct Padding40
|
||||||
|
{
|
||||||
|
[DebuggerBrowsable(DebuggerBrowsableState.Never)] private readonly Padding20 Padding00;
|
||||||
|
[DebuggerBrowsable(DebuggerBrowsableState.Never)] private readonly Padding20 Padding20;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential, Size = 0x80)]
|
||||||
|
internal struct Padding80
|
||||||
|
{
|
||||||
|
[DebuggerBrowsable(DebuggerBrowsableState.Never)] private readonly Padding40 Padding00;
|
||||||
|
[DebuggerBrowsable(DebuggerBrowsableState.Never)] private readonly Padding40 Padding40;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential, Size = 0x100)]
|
||||||
|
internal struct Padding100
|
||||||
|
{
|
||||||
|
[DebuggerBrowsable(DebuggerBrowsableState.Never)] private readonly Padding80 Padding00;
|
||||||
|
[DebuggerBrowsable(DebuggerBrowsableState.Never)] private readonly Padding80 Padding80;
|
||||||
|
}
|
||||||
|
}
|
86
src/LibHac/Common/U8StringBuilder.cs
Normal file
86
src/LibHac/Common/U8StringBuilder.cs
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
namespace LibHac.Common
|
||||||
|
{
|
||||||
|
[DebuggerDisplay("{ToString()}")]
|
||||||
|
public ref struct U8StringBuilder
|
||||||
|
{
|
||||||
|
private const int NullTerminatorLength = 1;
|
||||||
|
|
||||||
|
private readonly Span<byte> _buffer;
|
||||||
|
private int _length;
|
||||||
|
|
||||||
|
public bool Overflowed { get; private set; }
|
||||||
|
public int Capacity => _buffer.Length - NullTerminatorLength;
|
||||||
|
|
||||||
|
public U8StringBuilder(Span<byte> buffer)
|
||||||
|
{
|
||||||
|
_buffer = buffer;
|
||||||
|
_length = 0;
|
||||||
|
Overflowed = false;
|
||||||
|
|
||||||
|
ThrowIfBufferLengthIsZero();
|
||||||
|
|
||||||
|
AddNullTerminator();
|
||||||
|
}
|
||||||
|
|
||||||
|
public U8StringBuilder Append(ReadOnlySpan<byte> value)
|
||||||
|
{
|
||||||
|
if (Overflowed) return this;
|
||||||
|
|
||||||
|
int valueLength = StringUtils.GetLength(value);
|
||||||
|
|
||||||
|
if (!HasAdditionalCapacity(valueLength))
|
||||||
|
{
|
||||||
|
Overflowed = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
value.Slice(0, valueLength).CopyTo(_buffer.Slice(_length));
|
||||||
|
_length += valueLength;
|
||||||
|
AddNullTerminator();
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public U8StringBuilder Append(byte value)
|
||||||
|
{
|
||||||
|
if (Overflowed) return this;
|
||||||
|
|
||||||
|
if (!HasAdditionalCapacity(1))
|
||||||
|
{
|
||||||
|
Overflowed = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
_buffer[_length] = value;
|
||||||
|
_length++;
|
||||||
|
AddNullTerminator();
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool HasCapacity(int requiredCapacity)
|
||||||
|
{
|
||||||
|
return requiredCapacity <= Capacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool HasAdditionalCapacity(int requiredAdditionalCapacity)
|
||||||
|
{
|
||||||
|
return HasCapacity(_length + requiredAdditionalCapacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddNullTerminator()
|
||||||
|
{
|
||||||
|
_buffer[_length] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ThrowIfBufferLengthIsZero()
|
||||||
|
{
|
||||||
|
if (_buffer.Length == 0) throw new ArgumentException("Buffer length must be greater than 0.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString() => StringUtils.Utf8ZToString(_buffer);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,6 @@
|
||||||
using LibHac.FsService;
|
using LibHac.Common;
|
||||||
|
using LibHac.FsService;
|
||||||
|
using LibHac.FsSystem;
|
||||||
using LibHac.Ncm;
|
using LibHac.Ncm;
|
||||||
using LibHac.Spl;
|
using LibHac.Spl;
|
||||||
|
|
||||||
|
@ -14,6 +16,31 @@ namespace LibHac.Fs
|
||||||
return fsProxy.GetRightsId(out rightsId, programId, storageId);
|
return fsProxy.GetRightsId(out rightsId, programId, storageId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Result GetRightsId(this FileSystemClient fs, out RightsId rightsId, U8Span path)
|
||||||
|
{
|
||||||
|
rightsId = default;
|
||||||
|
|
||||||
|
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
|
||||||
|
|
||||||
|
Result rc = FsPath.FromSpan(out FsPath fsPath, path);
|
||||||
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
|
return fsProxy.GetRightsIdByPath(out rightsId, ref fsPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Result GetRightsId(this FileSystemClient fs, out RightsId rightsId, out byte keyGeneration, U8Span path)
|
||||||
|
{
|
||||||
|
rightsId = default;
|
||||||
|
keyGeneration = default;
|
||||||
|
|
||||||
|
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
|
||||||
|
|
||||||
|
Result rc = FsPath.FromSpan(out FsPath fsPath, path);
|
||||||
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
|
return fsProxy.GetRightsIdAndKeyGenerationByPath(out rightsId, out keyGeneration, ref fsPath);
|
||||||
|
}
|
||||||
|
|
||||||
public static Result RegisterExternalKey(this FileSystemClient fs, ref RightsId rightsId, ref AccessKey key)
|
public static Result RegisterExternalKey(this FileSystemClient fs, ref RightsId rightsId, ref AccessKey key)
|
||||||
{
|
{
|
||||||
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
|
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
|
||||||
|
|
|
@ -2,18 +2,33 @@
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using LibHac.Common;
|
using LibHac.Common;
|
||||||
|
using LibHac.Fs;
|
||||||
|
|
||||||
namespace LibHac.FsSystem
|
namespace LibHac.FsSystem
|
||||||
{
|
{
|
||||||
[DebuggerDisplay("{ToString()}")]
|
[DebuggerDisplay("{ToString()}")]
|
||||||
[StructLayout(LayoutKind.Explicit, Size = MaxLength + 1)]
|
[StructLayout(LayoutKind.Sequential, Size = MaxLength + 1)]
|
||||||
public struct FsPath
|
public struct FsPath
|
||||||
{
|
{
|
||||||
internal const int MaxLength = 0x300;
|
internal const int MaxLength = 0x300;
|
||||||
|
|
||||||
[FieldOffset(0)] private byte _str;
|
#if DEBUG
|
||||||
|
[DebuggerBrowsable(DebuggerBrowsableState.Never)] private readonly Padding100 Padding000;
|
||||||
|
[DebuggerBrowsable(DebuggerBrowsableState.Never)] private readonly Padding100 Padding100;
|
||||||
|
[DebuggerBrowsable(DebuggerBrowsableState.Never)] private readonly Padding100 Padding200;
|
||||||
|
[DebuggerBrowsable(DebuggerBrowsableState.Never)] private readonly byte Padding300;
|
||||||
|
#endif
|
||||||
|
|
||||||
public Span<byte> Str => SpanHelpers.CreateSpan(ref _str, MaxLength + 1);
|
public Span<byte> Str => SpanHelpers.AsByteSpan(ref this);
|
||||||
|
|
||||||
|
public static Result FromSpan(out FsPath fsPath, ReadOnlySpan<byte> path)
|
||||||
|
{
|
||||||
|
fsPath = new FsPath();
|
||||||
|
|
||||||
|
U8StringBuilder builder = new U8StringBuilder(fsPath.Str).Append(path);
|
||||||
|
|
||||||
|
return builder.Overflowed ? ResultFs.TooLongPath : Result.Success;
|
||||||
|
}
|
||||||
|
|
||||||
public static implicit operator U8Span(FsPath value) => new U8Span(value.Str);
|
public static implicit operator U8Span(FsPath value) => new U8Span(value.Str);
|
||||||
public override string ToString() => StringUtils.Utf8ZToString(Str);
|
public override string ToString() => StringUtils.Utf8ZToString(Str);
|
||||||
|
|
|
@ -1,8 +1,16 @@
|
||||||
namespace LibHac.Ncm
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
namespace LibHac.Ncm
|
||||||
{
|
{
|
||||||
|
[DebuggerDisplay("{" + nameof(Value) + "}")]
|
||||||
public struct TitleId
|
public struct TitleId
|
||||||
{
|
{
|
||||||
public ulong Value;
|
public readonly ulong Value;
|
||||||
|
|
||||||
|
public TitleId(ulong value)
|
||||||
|
{
|
||||||
|
Value = value;
|
||||||
|
}
|
||||||
|
|
||||||
public static explicit operator ulong(TitleId titleId) => titleId.Value;
|
public static explicit operator ulong(TitleId titleId) => titleId.Value;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue