AssetRipper_AssetRipper/Source/AssetRipper.Yaml/YamlScalarNode.FloatingPointHexNode.cs
ds5678 13edc04cd1 Huge yaml export memory improvements
* Export MonoBehaviour byte arrays as scalars rather than sequences
* Do not serialize yaml scalars, especially not for byte arrays
* Eliminate unnecessary state for yaml scalars
* Create a new type hierarchy for yaml scalars
* Implement hexidecimal emission of floating point scalars
* Implement hexidecimal emission of numeric lists
* Resolves #1422
* Resolves #1409
* Resolves #1381
* Related to #927
* Related to #695
2024-08-04 14:32:11 -07:00

50 lines
1.4 KiB
C#

using System.Globalization;
using System.Numerics;
using System.Runtime.CompilerServices;
namespace AssetRipper.Yaml;
public abstract partial class YamlScalarNode
{
/// <summary>
/// Hexidecimal representation of a floating point number. <see href="https://docs.unity3d.com/2022.3/Documentation/Manual/FormatDescription.html"/>
/// </summary>
/// <remarks>
/// This is the only lossless way to represent a floating point number in YAML.
/// However, the output is less readable than the default representation.
/// </remarks>
/// <typeparam name="T">The floating point type.</typeparam>
/// <param name="value"></param>
private sealed class FloatingPointHexNode<T>(T value) : YamlScalarNode where T : IBinaryFloatingPointIeee754<T>
{
private protected override void EmitCore(Emitter emitter)
{
emitter.Write(Value);
}
public override string Value
{
get
{
if (typeof(T) == typeof(float))
{
float single = Unsafe.As<T, float>(ref value);
uint hex = BitConverter.SingleToUInt32Bits(single);
return $"0x{hex:x8}({single.ToString(CultureInfo.InvariantCulture)})";
}
else if (typeof(T) == typeof(double))
{
double single = Unsafe.As<T, double>(ref value);
ulong hex = BitConverter.DoubleToUInt64Bits(single);
return $"0x{hex:x16}({single.ToString(CultureInfo.InvariantCulture)})";
}
else
{
// This can't happen
return value.ToString() ?? "";
}
}
}
}
}