Add U8StringBuilder format options

This commit is contained in:
Alex Barney 2020-04-10 10:49:44 -07:00
parent da78e7e8ce
commit 939c495db6
2 changed files with 136 additions and 0 deletions

View file

@ -168,5 +168,15 @@ namespace LibHac.Common
{
return Utf8ToString(value.Slice(0, GetLength(value)));
}
public static bool IsAlpha(byte c)
{
return (c | 0x20u) - (byte)'A' <= 'Z' - 'A';
}
public static bool IsDigit(byte c)
{
return (uint)(c - (byte)'0') <= 9;
}
}
}

View file

@ -1,4 +1,6 @@
using System;
using System.Buffers;
using System.Buffers.Text;
using System.Diagnostics;
namespace LibHac.Common
@ -63,6 +65,36 @@ namespace LibHac.Common
return this;
}
public U8StringBuilder AppendFormat(byte value, char format = 'G', byte precision = 255) =>
AppendFormatUInt64(value, format, precision);
public U8StringBuilder AppendFormat(sbyte value, char format = 'G', byte precision = 255) =>
AppendFormatInt64(value, 0xff, format, precision);
public U8StringBuilder AppendFormat(ushort value, char format = 'G', byte precision = 255) =>
AppendFormatUInt64(value, format, precision);
public U8StringBuilder AppendFormat(short value, char format = 'G', byte precision = 255) =>
AppendFormatInt64(value, 0xffff, format, precision);
public U8StringBuilder AppendFormat(uint value, char format = 'G', byte precision = 255) =>
AppendFormatUInt64(value, format, precision);
public U8StringBuilder AppendFormat(int value, char format = 'G', byte precision = 255) =>
AppendFormatInt64(value, 0xffffff, format, precision);
public U8StringBuilder AppendFormat(ulong value, char format = 'G', byte precision = 255) =>
AppendFormatUInt64(value, format, precision);
public U8StringBuilder AppendFormat(long value, char format = 'G', byte precision = 255) =>
AppendFormatInt64(value, 0xffffffff, format, precision);
public U8StringBuilder AppendFormat(float value, char format = 'G', byte precision = 255) =>
AppendFormatFloat(value, format, precision);
public U8StringBuilder AppendFormat(double value, char format = 'G', byte precision = 255) =>
AppendFormatDouble(value, format, precision);
private readonly bool HasCapacity(int requiredCapacity)
{
return requiredCapacity <= Capacity;
@ -83,6 +115,100 @@ namespace LibHac.Common
if (_buffer.Length == 0) throw new ArgumentException("Buffer length must be greater than 0.");
}
private U8StringBuilder AppendFormatInt64(long value, ulong mask, char format, byte precision)
{
if (Overflowed) return this;
// Remove possible sign extension if needed
if (mask == 'x' | mask == 'X')
{
value &= (long)mask;
}
// Exclude the null terminator from the buffer because Utf8Formatter doesn't handle it
Span<byte> availableBuffer = _buffer.Slice(_length, Capacity - _length);
bool bufferLargeEnough = Utf8Formatter.TryFormat(value, availableBuffer, out int bytesWritten,
new StandardFormat(format, precision));
if (!bufferLargeEnough)
{
Overflowed = true;
return this;
}
_length += bytesWritten;
AddNullTerminator();
return this;
}
private U8StringBuilder AppendFormatUInt64(ulong value, char format, byte precision)
{
if (Overflowed) return this;
// Exclude the null terminator from the buffer because Utf8Formatter doesn't handle it
Span<byte> availableBuffer = _buffer.Slice(_length, Capacity - _length);
bool bufferLargeEnough = Utf8Formatter.TryFormat(value, availableBuffer, out int bytesWritten,
new StandardFormat(format, precision));
if (!bufferLargeEnough)
{
Overflowed = true;
return this;
}
_length += bytesWritten;
AddNullTerminator();
return this;
}
private U8StringBuilder AppendFormatFloat(float value, char format, byte precision)
{
if (Overflowed) return this;
// Exclude the null terminator from the buffer because Utf8Formatter doesn't handle it
Span<byte> availableBuffer = _buffer.Slice(_length, Capacity - _length);
bool bufferLargeEnough = Utf8Formatter.TryFormat(value, availableBuffer, out int bytesWritten,
new StandardFormat(format, precision));
if (!bufferLargeEnough)
{
Overflowed = true;
return this;
}
_length += bytesWritten;
AddNullTerminator();
return this;
}
private U8StringBuilder AppendFormatDouble(double value, char format, byte precision)
{
if (Overflowed) return this;
// Exclude the null terminator from the buffer because Utf8Formatter doesn't handle it
Span<byte> availableBuffer = _buffer.Slice(_length, Capacity - _length);
bool bufferLargeEnough = Utf8Formatter.TryFormat(value, availableBuffer, out int bytesWritten,
new StandardFormat(format, precision));
if (!bufferLargeEnough)
{
Overflowed = true;
return this;
}
_length += bytesWritten;
AddNullTerminator();
return this;
}
public override readonly string ToString() => StringUtils.Utf8ZToString(_buffer);
}
}