mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-08-19 19:18:05 +00:00
code reviews
This commit is contained in:
@@ -6,10 +6,11 @@ namespace QuanTAlib;
|
||||
/// <summary>
|
||||
/// A lightweight struct representing a time-value pair.
|
||||
/// Pure data type: 16 bytes (long + double).
|
||||
/// Implements ISpanFormattable for allocation-free formatting.
|
||||
/// </summary>
|
||||
[SkipLocalsInit]
|
||||
[StructLayout(LayoutKind.Auto)]
|
||||
public readonly record struct TValue(long Time, double Value)
|
||||
public readonly record struct TValue(long Time, double Value) : ISpanFormattable
|
||||
{
|
||||
public DateTime AsDateTime => new(Time, DateTimeKind.Utc);
|
||||
|
||||
@@ -37,4 +38,90 @@ public readonly record struct TValue(long Time, double Value)
|
||||
};
|
||||
return $"[{AsDateTime:yyyy-MM-dd HH:mm:ss}, {valueStr}]";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Formats the TValue using the specified format string.
|
||||
/// Note: Custom format and formatProvider are not supported by TValue.
|
||||
/// If a non-null/non-empty format is provided, a NotSupportedException is thrown.
|
||||
/// </summary>
|
||||
/// <param name="format">Must be null or empty; custom formats are not supported.</param>
|
||||
/// <param name="formatProvider">Ignored; TValue uses its own fixed format.</param>
|
||||
/// <returns>The string representation of this TValue.</returns>
|
||||
/// <exception cref="NotSupportedException">Thrown when a non-null/non-empty format is provided.</exception>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public string ToString(string? format, IFormatProvider? formatProvider)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(format))
|
||||
throw new NotSupportedException($"Custom format '{format}' is not supported by TValue. Use ToString() for the default format.");
|
||||
|
||||
return ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Formats the TValue into the provided span without heap allocation.
|
||||
/// Format: "[yyyy-MM-dd HH:mm:ss, value]"
|
||||
/// </summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool TryFormat(Span<char> destination, out int charsWritten, ReadOnlySpan<char> format, IFormatProvider? provider)
|
||||
{
|
||||
charsWritten = 0;
|
||||
|
||||
// Early reject for buffers too small to hold even the timestamp portion.
|
||||
// This is a heuristic check; actual buffer-overflow protection is performed
|
||||
// by the explicit length checks that guard each write operation below.
|
||||
if (destination.Length < 24)
|
||||
return false;
|
||||
|
||||
// Write opening bracket
|
||||
destination[0] = '[';
|
||||
int pos = 1;
|
||||
|
||||
// Format datetime: yyyy-MM-dd HH:mm:ss (19 chars)
|
||||
if (!AsDateTime.TryFormat(destination.Slice(pos), out int dtChars, "yyyy-MM-dd HH:mm:ss", provider))
|
||||
return false;
|
||||
pos += dtChars;
|
||||
|
||||
// Write separator
|
||||
if (pos + 2 > destination.Length)
|
||||
return false;
|
||||
destination[pos++] = ',';
|
||||
destination[pos++] = ' ';
|
||||
|
||||
// Format value
|
||||
if (double.IsPositiveInfinity(Value))
|
||||
{
|
||||
if (pos + 1 > destination.Length)
|
||||
return false;
|
||||
destination[pos++] = (char)0x221E; //
|
||||
}
|
||||
else if (double.IsNegativeInfinity(Value))
|
||||
{
|
||||
if (pos + 2 > destination.Length)
|
||||
return false;
|
||||
destination[pos++] = '-';
|
||||
destination[pos++] = (char)0x221E; // -
|
||||
}
|
||||
else if (double.IsNaN(Value))
|
||||
{
|
||||
if (pos + 3 > destination.Length)
|
||||
return false;
|
||||
destination[pos++] = 'N';
|
||||
destination[pos++] = 'a';
|
||||
destination[pos++] = 'N';
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!Value.TryFormat(destination.Slice(pos), out int valueChars, "F2", provider))
|
||||
return false;
|
||||
pos += valueChars;
|
||||
}
|
||||
|
||||
// Write closing bracket
|
||||
if (pos + 1 > destination.Length)
|
||||
return false;
|
||||
destination[pos++] = ']';
|
||||
|
||||
charsWritten = pos;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user