mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Rewrite MemoryStorage
This commit is contained in:
parent
857bde67ee
commit
b742a37012
4 changed files with 60 additions and 124 deletions
57
src/LibHac/Fs/MemoryStorage.cs
Normal file
57
src/LibHac/Fs/MemoryStorage.cs
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace LibHac.Fs
|
||||||
|
{
|
||||||
|
public class MemoryStorage : StorageBase
|
||||||
|
{
|
||||||
|
private byte[] StorageBuffer { get; }
|
||||||
|
|
||||||
|
public MemoryStorage(byte[] buffer)
|
||||||
|
{
|
||||||
|
StorageBuffer = buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Result ReadImpl(long offset, Span<byte> destination)
|
||||||
|
{
|
||||||
|
if (destination.Length == 0)
|
||||||
|
return Result.Success;
|
||||||
|
|
||||||
|
if (!IsRangeValid(offset, destination.Length, StorageBuffer.Length))
|
||||||
|
return ResultFs.ValueOutOfRange.Log();
|
||||||
|
|
||||||
|
StorageBuffer.AsSpan((int)offset, destination.Length).CopyTo(destination);
|
||||||
|
|
||||||
|
return Result.Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Result WriteImpl(long offset, ReadOnlySpan<byte> source)
|
||||||
|
{
|
||||||
|
if (source.Length == 0)
|
||||||
|
return Result.Success;
|
||||||
|
|
||||||
|
if (!IsRangeValid(offset, source.Length, StorageBuffer.Length))
|
||||||
|
return ResultFs.ValueOutOfRange.Log();
|
||||||
|
|
||||||
|
source.CopyTo(StorageBuffer.AsSpan((int)offset));
|
||||||
|
|
||||||
|
return Result.Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Result FlushImpl()
|
||||||
|
{
|
||||||
|
return Result.Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Result SetSizeImpl(long size)
|
||||||
|
{
|
||||||
|
return ResultFs.UnsupportedOperationInMemoryStorageSetSize.Log();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Result GetSizeImpl(out long size)
|
||||||
|
{
|
||||||
|
size = StorageBuffer.Length;
|
||||||
|
|
||||||
|
return Result.Success;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
||||||
namespace LibHac.Fs
|
namespace LibHac.Fs
|
||||||
|
@ -77,6 +78,7 @@ namespace LibHac.Fs
|
||||||
|
|
||||||
protected virtual void Dispose(bool disposing) { }
|
protected virtual void Dispose(bool disposing) { }
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static bool IsRangeValid(long offset, long size, long totalSize)
|
public static bool IsRangeValid(long offset, long size, long totalSize)
|
||||||
{
|
{
|
||||||
return offset >= 0 && size >= 0 && size <= totalSize && offset <= totalSize - size;
|
return offset >= 0 && size >= 0 && size <= totalSize && offset <= totalSize - size;
|
||||||
|
|
|
@ -1,118 +0,0 @@
|
||||||
using System;
|
|
||||||
using LibHac.Fs;
|
|
||||||
|
|
||||||
namespace LibHac.FsSystem
|
|
||||||
{
|
|
||||||
public class MemoryStorage : StorageBase
|
|
||||||
{
|
|
||||||
private byte[] _buffer;
|
|
||||||
private int _start;
|
|
||||||
private int _length;
|
|
||||||
private int _capacity;
|
|
||||||
private bool _isExpandable;
|
|
||||||
|
|
||||||
public MemoryStorage() : this(0) { }
|
|
||||||
|
|
||||||
public MemoryStorage(int capacity)
|
|
||||||
{
|
|
||||||
if (capacity < 0) throw new ArgumentOutOfRangeException(nameof(capacity), "Argument must be positive");
|
|
||||||
|
|
||||||
_capacity = capacity;
|
|
||||||
_isExpandable = true;
|
|
||||||
_buffer = new byte[capacity];
|
|
||||||
}
|
|
||||||
|
|
||||||
public MemoryStorage(byte[] buffer) : this(buffer, 0, buffer.Length) { }
|
|
||||||
|
|
||||||
public MemoryStorage(byte[] buffer, int index, int count)
|
|
||||||
{
|
|
||||||
if (buffer == null) throw new NullReferenceException(nameof(buffer));
|
|
||||||
if (index < 0) throw new ArgumentOutOfRangeException(nameof(index), "Value must be non-negative.");
|
|
||||||
if (count < 0) throw new ArgumentOutOfRangeException(nameof(count), "Value must be non-negative.");
|
|
||||||
if (buffer.Length - index < count) throw new ArgumentException("Length, index and count parameters are invalid.");
|
|
||||||
|
|
||||||
_buffer = buffer;
|
|
||||||
_start = index;
|
|
||||||
_length = count;
|
|
||||||
_capacity = count;
|
|
||||||
_isExpandable = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override Result ReadImpl(long offset, Span<byte> destination)
|
|
||||||
{
|
|
||||||
if (!IsRangeValid(offset, destination.Length, _length))
|
|
||||||
return ResultFs.ValueOutOfRange.Log();
|
|
||||||
|
|
||||||
_buffer.AsSpan((int)(_start + offset), destination.Length).CopyTo(destination);
|
|
||||||
|
|
||||||
return Result.Success;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override Result WriteImpl(long offset, ReadOnlySpan<byte> source)
|
|
||||||
{
|
|
||||||
if (!IsRangeValid(offset, source.Length, _length))
|
|
||||||
return ResultFs.ValueOutOfRange.Log();
|
|
||||||
|
|
||||||
long requiredCapacity = _start + offset + source.Length;
|
|
||||||
|
|
||||||
if (requiredCapacity > _length)
|
|
||||||
{
|
|
||||||
if (requiredCapacity > _capacity) EnsureCapacity(requiredCapacity);
|
|
||||||
_length = (int)(requiredCapacity - _start);
|
|
||||||
}
|
|
||||||
|
|
||||||
source.CopyTo(_buffer.AsSpan((int)(_start + offset), source.Length));
|
|
||||||
|
|
||||||
return Result.Success;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] ToArray()
|
|
||||||
{
|
|
||||||
var array = new byte[_length];
|
|
||||||
Buffer.BlockCopy(_buffer, _start, array, 0, _length);
|
|
||||||
return array;
|
|
||||||
}
|
|
||||||
|
|
||||||
// returns a bool saying whether we allocated a new array.
|
|
||||||
private void EnsureCapacity(long value)
|
|
||||||
{
|
|
||||||
if (value < 0 || value > int.MaxValue) throw new ArgumentOutOfRangeException(nameof(value));
|
|
||||||
if (value <= _capacity) return;
|
|
||||||
|
|
||||||
long newCapacity = Math.Max(value, 256);
|
|
||||||
newCapacity = Math.Max(newCapacity, _capacity * 2);
|
|
||||||
|
|
||||||
SetCapacity((int)Math.Min(newCapacity, int.MaxValue));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SetCapacity(int value)
|
|
||||||
{
|
|
||||||
if (value < _length)
|
|
||||||
throw new ArgumentOutOfRangeException(nameof(value), "Capacity is smaller than the current length.");
|
|
||||||
|
|
||||||
if (!_isExpandable && value != _capacity) throw new NotSupportedException("MemoryStorage is not expandable.");
|
|
||||||
|
|
||||||
if (_isExpandable && value != _capacity)
|
|
||||||
{
|
|
||||||
var newBuffer = new byte[value];
|
|
||||||
Buffer.BlockCopy(_buffer, 0, newBuffer, 0, _length);
|
|
||||||
|
|
||||||
_buffer = newBuffer;
|
|
||||||
_capacity = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override Result FlushImpl() => Result.Success;
|
|
||||||
|
|
||||||
protected override Result GetSizeImpl(out long size)
|
|
||||||
{
|
|
||||||
size = _length;
|
|
||||||
return Result.Success;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override Result SetSizeImpl(long size)
|
|
||||||
{
|
|
||||||
return ResultFs.UnsupportedOperationInMemoryStorageSetSize.Log();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -6,7 +6,6 @@ using System.Security.Cryptography;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using LibHac.Fs;
|
using LibHac.Fs;
|
||||||
using LibHac.FsService;
|
using LibHac.FsService;
|
||||||
using LibHac.FsSystem;
|
|
||||||
using LibHac.Spl;
|
using LibHac.Spl;
|
||||||
using Aes = LibHac.Crypto.Aes;
|
using Aes = LibHac.Crypto.Aes;
|
||||||
|
|
||||||
|
@ -305,11 +304,7 @@ namespace LibHac
|
||||||
|
|
||||||
Array.Copy(EncryptedKeyblobs[i], 0x10, counter, 0, 0x10);
|
Array.Copy(EncryptedKeyblobs[i], 0x10, counter, 0, 0x10);
|
||||||
|
|
||||||
using (var keyblobDec = new Aes128CtrStorage(
|
Aes.DecryptCtr128(EncryptedKeyblobs[i].AsSpan(0x20), Keyblobs[i], KeyblobKeys[i], counter);
|
||||||
new MemoryStorage(EncryptedKeyblobs[i], 0x20, Keyblobs[i].Length), KeyblobKeys[i], counter, false))
|
|
||||||
{
|
|
||||||
keyblobDec.Read(0, Keyblobs[i]).ThrowIfFailure();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue