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.Spl;
|
||||
|
||||
|
@ -14,6 +16,31 @@ namespace LibHac.Fs
|
|||
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)
|
||||
{
|
||||
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
|
||||
|
|
|
@ -2,18 +2,33 @@
|
|||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
|
||||
namespace LibHac.FsSystem
|
||||
{
|
||||
[DebuggerDisplay("{ToString()}")]
|
||||
[StructLayout(LayoutKind.Explicit, Size = MaxLength + 1)]
|
||||
[StructLayout(LayoutKind.Sequential, Size = MaxLength + 1)]
|
||||
public struct FsPath
|
||||
{
|
||||
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 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 ulong Value;
|
||||
public readonly ulong Value;
|
||||
|
||||
public TitleId(ulong value)
|
||||
{
|
||||
Value = value;
|
||||
}
|
||||
|
||||
public static explicit operator ulong(TitleId titleId) => titleId.Value;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue