This repository has been archived by the owner on May 26, 2023. It is now read-only.
forked from Cysharp/ZString
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request Cysharp#30 from udaken/rewrite-format-parser
Improved compatibility of Format String
- Loading branch information
Showing
11 changed files
with
3,820 additions
and
7,242 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
using System; | ||
using System.Text; | ||
using System.Buffers; | ||
using System.Runtime.CompilerServices; | ||
|
||
namespace Cysharp.Text | ||
{ | ||
internal static partial class Utf16FormatHelper | ||
{ | ||
const char sp = (char)' '; | ||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
public static void FormatTo<TBufferWriter, T>(ref TBufferWriter sb, T arg, int width, ReadOnlySpan<char> format, string argName) | ||
where TBufferWriter : IBufferWriter<char> | ||
{ | ||
if (width <= 0) // leftJustify | ||
{ | ||
var span = sb.GetSpan(0); | ||
if (!Utf16ValueStringBuilder.FormatterCache<T>.TryFormatDelegate(arg, span, out var argWritten, format)) | ||
{ | ||
sb.Advance(0); | ||
span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); | ||
if (!Utf16ValueStringBuilder.FormatterCache<T>.TryFormatDelegate(arg, span, out argWritten, format)) | ||
{ | ||
ExceptionUtil.ThrowArgumentException(argName); | ||
} | ||
} | ||
sb.Advance(argWritten); | ||
|
||
width *= -1; | ||
int padding = width - argWritten; | ||
if (width > 0 && padding > 0) | ||
{ | ||
var paddingSpan = sb.GetSpan(padding); | ||
paddingSpan.Fill(sp); | ||
sb.Advance(padding); | ||
} | ||
} | ||
else | ||
{ | ||
FormatToRightJustify(ref sb, arg, width, format, argName); | ||
} | ||
} | ||
|
||
private static void FormatToRightJustify<TBufferWriter, T>(ref TBufferWriter sb, T arg, int width, ReadOnlySpan<char> format, string argName) | ||
where TBufferWriter : IBufferWriter<char> | ||
{ | ||
if (typeof(T) == typeof(string)) | ||
{ | ||
var s = Unsafe.As<string>(arg); | ||
int padding = width - s.Length; | ||
if (padding > 0) | ||
{ | ||
var paddingSpan = sb.GetSpan(padding); | ||
paddingSpan.Fill(sp); | ||
sb.Advance(padding); | ||
} | ||
|
||
var span = sb.GetSpan(s.Length); | ||
s.AsSpan().CopyTo(span); | ||
sb.Advance(s.Length); | ||
} | ||
else | ||
{ | ||
Span<char> s = stackalloc char[typeof(T).IsValueType ? Unsafe.SizeOf<T>() * 8 : 1024]; | ||
|
||
if (!Utf16ValueStringBuilder.FormatterCache<T>.TryFormatDelegate(arg, s, out var charsWritten, format)) | ||
{ | ||
s = stackalloc char[s.Length * 2]; | ||
if (!Utf16ValueStringBuilder.FormatterCache<T>.TryFormatDelegate(arg, s, out charsWritten, format)) | ||
{ | ||
ExceptionUtil.ThrowArgumentException(argName); | ||
} | ||
} | ||
|
||
int padding = width - charsWritten; | ||
if (padding > 0) | ||
{ | ||
var paddingSpan = sb.GetSpan(padding); | ||
paddingSpan.Fill(sp); | ||
sb.Advance(padding); | ||
} | ||
|
||
var span = sb.GetSpan(charsWritten); | ||
s.CopyTo(span); | ||
sb.Advance(charsWritten); | ||
} | ||
} | ||
} | ||
|
||
internal static partial class Utf8FormatHelper | ||
{ | ||
const byte sp = (byte)' '; | ||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
public static void FormatTo<TBufferWriter, T>(ref TBufferWriter sb, T arg, int width, StandardFormat format, string argName) | ||
where TBufferWriter : IBufferWriter<byte> | ||
{ | ||
if (width <= 0) // leftJustify | ||
{ | ||
var span = sb.GetSpan(0); | ||
if (!Utf8ValueStringBuilder.FormatterCache<T>.TryFormatDelegate(arg, span, out var argWritten, format)) | ||
{ | ||
sb.Advance(0); | ||
span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); | ||
if (!Utf8ValueStringBuilder.FormatterCache<T>.TryFormatDelegate(arg, span, out argWritten, format)) | ||
{ | ||
ExceptionUtil.ThrowArgumentException(argName); | ||
} | ||
} | ||
sb.Advance(argWritten); | ||
|
||
width *= -1; | ||
int padding = width - argWritten; | ||
if (width > 0 && padding > 0) | ||
{ | ||
var paddingSpan = sb.GetSpan(padding); | ||
paddingSpan.Fill(sp); | ||
sb.Advance(padding); | ||
} | ||
} | ||
else | ||
{ | ||
FormatToRightJustify(ref sb, arg, width, format, argName); | ||
} | ||
} | ||
|
||
private static void FormatToRightJustify<TBufferWriter, T>(ref TBufferWriter sb, T arg, int width, StandardFormat format, string argName) | ||
where TBufferWriter : IBufferWriter<byte> | ||
{ | ||
if (typeof(T) == typeof(string)) | ||
{ | ||
var s = Unsafe.As<string>(arg); | ||
int padding = width - s.Length; | ||
if (padding > 0) | ||
{ | ||
var paddingSpan = sb.GetSpan(padding); | ||
paddingSpan.Fill(sp); | ||
sb.Advance(padding); | ||
} | ||
|
||
ZString.AppendChars(ref sb, s.AsSpan()); | ||
} | ||
else | ||
{ | ||
Span<byte> s = stackalloc byte[typeof(T).IsValueType ? Unsafe.SizeOf<T>() * 8 : 1024]; | ||
|
||
if (!Utf8ValueStringBuilder.FormatterCache<T>.TryFormatDelegate(arg, s, out var charsWritten, format)) | ||
{ | ||
s = stackalloc byte[s.Length * 2]; | ||
if (!Utf8ValueStringBuilder.FormatterCache<T>.TryFormatDelegate(arg, s, out charsWritten, format)) | ||
{ | ||
ExceptionUtil.ThrowArgumentException(argName); | ||
} | ||
} | ||
|
||
int padding = width - charsWritten; | ||
if (padding > 0) | ||
{ | ||
var paddingSpan = sb.GetSpan(padding); | ||
paddingSpan.Fill(sp); | ||
sb.Advance(padding); | ||
} | ||
|
||
var span = sb.GetSpan(charsWritten); | ||
s.CopyTo(span); | ||
sb.Advance(charsWritten); | ||
} | ||
} | ||
} | ||
|
||
} |
Oops, something went wrong.