Use the Unsafe class in RomFsDictionary

This commit is contained in:
Alex Barney 2019-02-25 12:37:30 -06:00
parent 1c918f705b
commit 4d655cdd19
2 changed files with 11 additions and 8 deletions

View file

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace LibHac.IO.RomFs namespace LibHac.IO.RomFs
@ -13,8 +14,7 @@ namespace LibHac.IO.RomFs
private int[] Buckets { get; set; } private int[] Buckets { get; set; }
private byte[] Entries { get; set; } private byte[] Entries { get; set; }
// Hack around not being able to get the size of generic structures private readonly int _sizeOfEntry = Unsafe.SizeOf<RomFsEntry>();
private readonly int _sizeOfEntry = 12 + Marshal.SizeOf<T>();
public RomFsDictionary(IStorage bucketStorage, IStorage entryStorage) public RomFsDictionary(IStorage bucketStorage, IStorage entryStorage)
{ {
@ -68,13 +68,12 @@ namespace LibHac.IO.RomFs
public ref T GetValueReference(int offset) public ref T GetValueReference(int offset)
{ {
ref RomFsEntry entry = ref MemoryMarshal.Cast<byte, RomFsEntry>(Entries.AsSpan(offset))[0]; return ref Unsafe.As<byte, RomFsEntry>(ref Entries[offset]).Value;
return ref entry.Value;
} }
public ref T GetValueReference(int offset, out Span<byte> name) public ref T GetValueReference(int offset, out Span<byte> name)
{ {
ref RomFsEntry entry = ref MemoryMarshal.Cast<byte, RomFsEntry>(Entries.AsSpan(offset))[0]; ref RomFsEntry entry = ref Unsafe.As<byte, RomFsEntry>(ref Entries[offset]);
name = Entries.AsSpan(offset + _sizeOfEntry, entry.KeyLength); name = Entries.AsSpan(offset + _sizeOfEntry, entry.KeyLength);
return ref entry.Value; return ref entry.Value;
@ -249,7 +248,7 @@ namespace LibHac.IO.RomFs
private ref RomFsEntry GetEntryReference(int offset, out Span<byte> name) private ref RomFsEntry GetEntryReference(int offset, out Span<byte> name)
{ {
ref RomFsEntry entry = ref MemoryMarshal.Cast<byte, RomFsEntry>(Entries.AsSpan(offset))[0]; ref RomFsEntry entry = ref Unsafe.As<byte, RomFsEntry>(ref Entries[offset]);
name = Entries.AsSpan(offset + _sizeOfEntry, entry.KeyLength); name = Entries.AsSpan(offset + _sizeOfEntry, entry.KeyLength);
return ref entry; return ref entry;
@ -257,7 +256,7 @@ namespace LibHac.IO.RomFs
private ref RomFsEntry GetEntryReference(int offset, out Span<byte> name, int nameLength) private ref RomFsEntry GetEntryReference(int offset, out Span<byte> name, int nameLength)
{ {
ref RomFsEntry entry = ref MemoryMarshal.Cast<byte, RomFsEntry>(Entries.AsSpan(offset))[0]; ref RomFsEntry entry = ref Unsafe.As<byte, RomFsEntry>(ref Entries[offset]);
name = Entries.AsSpan(offset + _sizeOfEntry, nameLength); name = Entries.AsSpan(offset + _sizeOfEntry, nameLength);
return ref entry; return ref entry;

View file

@ -35,8 +35,12 @@
<ItemGroup Condition=" '$(TargetFramework)' == 'net46' "> <ItemGroup Condition=" '$(TargetFramework)' == 'net46' ">
<PackageReference Include="System.Numerics.Vectors" Version="4.5.0" /> <PackageReference Include="System.Numerics.Vectors" Version="4.5.0" />
<PackageReference Include="System.Memory" Version="4.5.1" /> <PackageReference Include="System.Memory" Version="4.5.2" />
<PackageReference Include="System.Buffers" Version="4.5.0" /> <PackageReference Include="System.Buffers" Version="4.5.0" />
</ItemGroup> </ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp2.1' ">
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="4.5.2" />
</ItemGroup>
</Project> </Project>