PKHeX/PKHeX.Core/MysteryGifts/WC7Full.cs
Kurt 47071b41f3
Refactoring: Span-based value writes and method signatures (#3361)
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.
2022-01-02 21:35:59 -08:00

59 lines
No EOL
2 KiB
C#

using System;
namespace PKHeX.Core
{
public sealed class WC7Full
{
public const int Size = 0x310;
private const int GiftStart = Size - WC7.Size;
public readonly byte[] Data;
public readonly WC7 Gift;
public byte RestrictVersion { get => Data[0]; set => Data[0] = value; }
public byte RestrictLanguage { get => Data[0x1FF]; set => Data[0x1FF] = value; }
public WC7Full(byte[] data)
{
Data = data;
var wc7 = data.SliceEnd(GiftStart);
Gift = new WC7(wc7);
var now = DateTime.Now;
Gift.RawDate = WC7.SetDate((uint)now.Year, (uint)now.Month, (uint)now.Day);
Gift.RestrictVersion = RestrictVersion;
Gift.RestrictLanguage = RestrictLanguage;
}
public static WC7[] GetArray(ReadOnlySpan<byte> wc7Full, ReadOnlySpan<byte> data)
{
var countfull = wc7Full.Length / Size;
var countgift = data.Length / WC7.Size;
var result = new WC7[countfull + countgift];
var now = DateTime.Now;
for (int i = 0; i < countfull; i++)
result[i] = ReadWC7(wc7Full, i * Size, now);
for (int i = 0; i < countgift; i++)
result[i + countfull] = ReadWC7Only(data, i * WC7.Size);
return result;
}
private static WC7 ReadWC7(ReadOnlySpan<byte> data, int ofs, DateTime date)
{
var slice = data.Slice(ofs + GiftStart, WC7.Size).ToArray();
return new WC7(slice)
{
RestrictVersion = data[ofs],
RestrictLanguage = data[ofs + 0x1FF],
RawDate = WC7.SetDate((uint) date.Year, (uint) date.Month, (uint) date.Day),
};
}
private static WC7 ReadWC7Only(ReadOnlySpan<byte> data, int ofs)
{
var slice = data.Slice(ofs, WC7.Size).ToArray();
return new WC7(slice);
}
}
}