using System; using System.Runtime.CompilerServices; namespace PKHeX.Core { /// /// 4-bit decimal encoding used by some Generation 1 save file values. /// public static class BinaryCodedDecimal { /// /// Returns a 32-bit signed integer converted from bytes in a Binary Coded Decimal format byte array. /// /// Input byte array to read from. /// Offset to start reading at. /// Length of array to read. public static int ToInt32BE(byte[] input, int offset, int length) { var span = new ReadOnlySpan(input, offset, length); return ToInt32BE(span); } /// public static int ToInt32BE(ReadOnlySpan 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); /// /// Returns the specified 32-bit signed integer value as an array of Binary Coded Decimal format bytes. /// /// 32-bit signed integer to convert. /// Desired size of returned array. public static byte[] GetBytesBE(int value, int size) { byte[] data = new byte[size]; WriteBytesBE(data, value); return data; } public static void WriteBytesBE(Span data, int value) { for (int i = 0; i < data.Length; i++) { int p = value % 100; value /= 100; data[^(1+i)] = (byte) (p / 10 << 4 | p % 10); } } /// /// Big Endian instead of Little Endian public static int ToInt32LE(byte[] data, int offset, int length) { var span = new ReadOnlySpan(data, offset, length); return ToInt32LE(span); } /// public static int ToInt32LE(ReadOnlySpan input) { int result = 0; for (int i = input.Length - 1; i >= 0; i--) PushDigits(ref result, input[i]); return result; } /// /// Little Endian instead of Big Endian public static byte[] GetBytesLE(int value, int size) { byte[] data = new byte[size]; WriteBytesLE(data, value); return data; } /// /// Writes the to the buffer. /// public static void WriteBytesLE(Span data, int value) { for (int i = 0; i < data.Length; i++) { int p = value % 100; value /= 100; data[i] = (byte) (p / 10 << 4 | p % 10); } } } }