mirror of
https://github.com/kwsch/PKHeX
synced 2024-12-24 11:23:11 +00:00
47071b41f3
Existing `get`/`set` logic is flawed in that it doesn't work on Big Endian operating systems, and it allocates heap objects when it doesn't need to. `System.Buffers.Binary.BinaryPrimitives` in the `System.Memory` NuGet package provides both Little Endian and Big Endian methods to read and write data; all the `get`/`set` operations have been reworked to use this new API. This removes the need for PKHeX's manual `BigEndian` class, as all functions are already covered by the BinaryPrimitives API. The `StringConverter` has now been rewritten to accept a Span to read from & write to, no longer requiring a temporary StringBuilder. Other Fixes included: - The Super Training UI for Gen6 has been reworked according to the latest block structure additions. - Cloning a Stadium2 Save File now works correctly (opening from the Folder browser list). - Checksum & Sanity properties removed from parent PKM class, and is now implemented via interface.
53 lines
1.8 KiB
C#
53 lines
1.8 KiB
C#
using System;
|
|
using System.Runtime.CompilerServices;
|
|
|
|
namespace PKHeX.Core
|
|
{
|
|
/// <summary>
|
|
/// 4-bit decimal encoding used by some Generation 1 save file values.
|
|
/// </summary>
|
|
public static class BinaryCodedDecimal
|
|
{
|
|
/// <summary>
|
|
/// Returns a 32-bit signed integer converted from bytes in a Binary Coded Decimal format byte array.
|
|
/// </summary>
|
|
/// <param name="input">Input byte array to read from.</param>
|
|
public static int ToInt32BE(ReadOnlySpan<byte> input)
|
|
{
|
|
int result = 0;
|
|
foreach (var b in input)
|
|
PushDigits(ref result, b);
|
|
return result;
|
|
}
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
private static void PushDigits(ref int result, byte b) => result = (result * 100) + (10 * (b >> 4)) + (b & 0xf);
|
|
|
|
/// <summary>
|
|
/// Writes the <see cref="value"/> to the <see cref="data"/> buffer.
|
|
/// </summary>
|
|
public static void WriteBytesBE(Span<byte> data, int value)
|
|
{
|
|
for (int i = data.Length - 1; i >= 0; i--, value /= 100)
|
|
data[i] = (byte)((((value / 10) % 10) << 4) | (value % 10));
|
|
}
|
|
|
|
/// <inheritdoc cref="ToInt32BE(ReadOnlySpan{byte})"/>
|
|
public static int ToInt32LE(ReadOnlySpan<byte> input)
|
|
{
|
|
int result = 0;
|
|
for (int i = input.Length - 1; i >= 0; i--)
|
|
PushDigits(ref result, input[i]);
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Writes the <see cref="value"/> to the <see cref="data"/> buffer.
|
|
/// </summary>
|
|
public static void WriteBytesLE(Span<byte> data, int value)
|
|
{
|
|
for (int i = 0; i < data.Length; i++, value /= 100)
|
|
data[i] = (byte)((((value / 10) % 10) << 4) | (value % 10));
|
|
}
|
|
}
|
|
}
|