JsonSeparatorNamingPolicy
using System.Buffers;
using System.Globalization;
namespace System.Text.Json
{
internal abstract class JsonSeparatorNamingPolicy : JsonNamingPolicy
{
private enum SeparatorState
{
NotStarted,
UppercaseLetter,
LowercaseLetterOrDigit,
SpaceSeparator
}
private readonly bool _lowercase;
private readonly char _separator;
internal JsonSeparatorNamingPolicy(bool lowercase, char separator)
{
_lowercase = lowercase;
_separator = separator;
}
public sealed override string ConvertName(string name)
{
if (name == null)
ThrowHelper.ThrowArgumentNullException("name");
return ConvertNameCore(_separator, _lowercase, name.AsSpan());
}
private unsafe static string ConvertNameCore(char separator, bool lowercase, ReadOnlySpan<char> chars)
{
<>c__DisplayClass4_0 <>c__DisplayClass4_;
<>c__DisplayClass4_.rentedBuffer = null;
int num = (int)(1.2 * (double)chars.Length);
Span<char> span = (num > 128) ? ((Span<char>)(<>c__DisplayClass4_.rentedBuffer = ArrayPool<char>.Shared.Rent(num))) : new Span<char>(stackalloc byte[256], 128);
Span<char> destination = span;
SeparatorState separatorState = SeparatorState.NotStarted;
<>c__DisplayClass4_.charsWritten = 0;
for (int i = 0; i < chars.Length; i++) {
char c = chars[i];
UnicodeCategory unicodeCategory = char.GetUnicodeCategory(c);
switch (unicodeCategory) {
case UnicodeCategory.UppercaseLetter:
switch (separatorState) {
case SeparatorState.LowercaseLetterOrDigit:
case SeparatorState.SpaceSeparator:
<ConvertNameCore>g__WriteChar|4_0(separator, ref destination, ref <>c__DisplayClass4_);
break;
case SeparatorState.UppercaseLetter:
if (i + 1 < chars.Length && char.IsLower(chars[i + 1]))
<ConvertNameCore>g__WriteChar|4_0(separator, ref destination, ref <>c__DisplayClass4_);
break;
}
if (lowercase)
c = char.ToLowerInvariant(c);
<ConvertNameCore>g__WriteChar|4_0(c, ref destination, ref <>c__DisplayClass4_);
separatorState = SeparatorState.UppercaseLetter;
break;
case UnicodeCategory.LowercaseLetter:
case UnicodeCategory.DecimalDigitNumber:
if (separatorState == SeparatorState.SpaceSeparator)
<ConvertNameCore>g__WriteChar|4_0(separator, ref destination, ref <>c__DisplayClass4_);
if (!lowercase && unicodeCategory == UnicodeCategory.LowercaseLetter)
c = char.ToUpperInvariant(c);
<ConvertNameCore>g__WriteChar|4_0(c, ref destination, ref <>c__DisplayClass4_);
separatorState = SeparatorState.LowercaseLetterOrDigit;
break;
case UnicodeCategory.SpaceSeparator:
if (separatorState != 0)
separatorState = SeparatorState.SpaceSeparator;
break;
default:
<ConvertNameCore>g__WriteChar|4_0(c, ref destination, ref <>c__DisplayClass4_);
separatorState = SeparatorState.NotStarted;
break;
}
}
span = destination.Slice(0, <>c__DisplayClass4_.charsWritten);
string result = span.ToString();
if (<>c__DisplayClass4_.rentedBuffer != null) {
span = destination.Slice(0, <>c__DisplayClass4_.charsWritten);
span.Clear();
ArrayPool<char>.Shared.Return(<>c__DisplayClass4_.rentedBuffer, false);
}
return result;
}
}
}