401 lines
14 KiB
C#
401 lines
14 KiB
C#
using System;
|
|
using System.Globalization;
|
|
using System.Runtime.CompilerServices;
|
|
|
|
namespace CPF.Windows.Json.Serializer
|
|
{
|
|
internal class PrimitiveNormal : DefaultJsonFormatter
|
|
{
|
|
#if !Net4
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
#endif
|
|
[FuncLable(FuncType.SameType)]
|
|
internal static void WriteValue(int value, JsonSerializerHandler handler)
|
|
{
|
|
// Gotta special case this, we can't negate it
|
|
if (value == int.MinValue)
|
|
{
|
|
handler.WriteString("-2147483648");
|
|
return;
|
|
}
|
|
if (value == int.MaxValue)
|
|
{
|
|
handler.WriteString("2147483647");
|
|
return;
|
|
}
|
|
var ptr = 35;
|
|
char[] buffer = new char[36];
|
|
uint copy;
|
|
if (value < 0)
|
|
{
|
|
handler.WriteChar('-');
|
|
copy = (uint)(-value);
|
|
}
|
|
else
|
|
copy = (uint)value;
|
|
|
|
do
|
|
{
|
|
byte ix = (byte)(copy % 100);
|
|
copy /= 100;
|
|
|
|
var chars = SpecialTypeNormal. DigitPairs[ix];
|
|
buffer[ptr--] = chars.Second;
|
|
buffer[ptr--] = chars.First;
|
|
} while (copy != 0);
|
|
|
|
if (buffer[ptr + 1] == '0')
|
|
{
|
|
ptr++;
|
|
}
|
|
|
|
handler.WriteChars(buffer, ptr + 1, 35 - ptr);
|
|
}
|
|
#if !Net4
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
#endif
|
|
[FuncLable(FuncType.SameType)]
|
|
internal static void WriteValue(uint value, JsonSerializerHandler handler)
|
|
{
|
|
if (value == uint.MaxValue)
|
|
{
|
|
handler.WriteString("4294967295");
|
|
return;
|
|
}
|
|
var ptr = 35;
|
|
char[] buffer = new char[36];
|
|
var copy = value;
|
|
|
|
do
|
|
{
|
|
byte ix = (byte)(copy % 100);
|
|
copy /= 100;
|
|
|
|
var chars = SpecialTypeNormal.DigitPairs[ix];
|
|
buffer[ptr--] = chars.Second;
|
|
buffer[ptr--] = chars.First;
|
|
} while (copy != 0);
|
|
|
|
if (buffer[ptr + 1] == '0')
|
|
{
|
|
ptr++;
|
|
}
|
|
|
|
handler.WriteChars(buffer, ptr + 1, 35 - ptr);
|
|
}
|
|
#if !Net4
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
#endif
|
|
[FuncLable(FuncType.SameType)]
|
|
internal static void WriteValue(long value, JsonSerializerHandler handler)
|
|
{
|
|
if (value == long.MinValue)
|
|
{
|
|
handler.WriteString("-9223372036854775808");
|
|
return;
|
|
}
|
|
char[] buffer = new char[36];
|
|
var ptr = 35;
|
|
|
|
ulong copy;
|
|
if (value < 0)
|
|
{
|
|
handler.WriteChar('-');
|
|
copy = (ulong)(-value);
|
|
}
|
|
else
|
|
{
|
|
copy = (ulong)value;
|
|
}
|
|
|
|
do
|
|
{
|
|
byte ix = (byte)(copy % 100);
|
|
copy /= 100;
|
|
|
|
var chars = SpecialTypeNormal.DigitPairs[ix];
|
|
buffer[ptr--] = chars.Second;
|
|
buffer[ptr--] = chars.First;
|
|
} while (copy != 0);
|
|
|
|
if (buffer[ptr + 1] == '0')
|
|
{
|
|
ptr++;
|
|
}
|
|
|
|
handler.WriteChars(buffer, ptr + 1, 35 - ptr);
|
|
}
|
|
#if !Net4
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
#endif
|
|
[FuncLable(FuncType.SameType)]
|
|
internal static void WriteValue(ulong value, JsonSerializerHandler handler)
|
|
{
|
|
if (value == ulong.MaxValue)
|
|
{
|
|
handler.WriteString("18446744073709551615");
|
|
return;
|
|
}
|
|
|
|
var ptr = 35;
|
|
char[] buffer = new char[36];
|
|
var copy = value;
|
|
|
|
do
|
|
{
|
|
byte ix = (byte)(copy % 100);
|
|
copy /= 100;
|
|
|
|
var chars = SpecialTypeNormal.DigitPairs[ix];
|
|
buffer[ptr--] = chars.Second;
|
|
buffer[ptr--] = chars.First;
|
|
} while (copy != 0);
|
|
|
|
if (buffer[ptr + 1] == '0')
|
|
{
|
|
ptr++;
|
|
}
|
|
|
|
handler.WriteChars(buffer, ptr + 1, 35 - ptr);
|
|
}
|
|
#if !Net4
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
#endif
|
|
[FuncLable(FuncType.SameType)]
|
|
internal static void WriteValue(float value, JsonSerializerHandler handler)
|
|
{
|
|
switch (value)
|
|
{
|
|
case float.NaN:
|
|
handler.WriteString("\"NaN\"");
|
|
return;
|
|
case float.NegativeInfinity:
|
|
handler.WriteString("\"-Infinity\"");
|
|
return;
|
|
case float.PositiveInfinity:
|
|
handler.WriteString("\"Infinity\"");
|
|
return;
|
|
}
|
|
handler.WriteString(value.ToString("R",CultureInfo.InvariantCulture));
|
|
}
|
|
#if !Net4
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
#endif
|
|
[FuncLable(FuncType.SameType)]
|
|
internal static void WriteValue(decimal value, JsonSerializerHandler handler)
|
|
{
|
|
handler.WriteString(value.ToString(CultureInfo.InvariantCulture));
|
|
}
|
|
#if !Net4
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
#endif
|
|
[FuncLable(FuncType.SameType)]
|
|
internal static void WriteValue(double value, JsonSerializerHandler handler)
|
|
{
|
|
switch (value)
|
|
{
|
|
case double.NaN:
|
|
handler.WriteString("\"NaN\"");
|
|
return;
|
|
case double.NegativeInfinity:
|
|
handler.WriteString("\"-Infinity\"");
|
|
return;
|
|
case double.PositiveInfinity:
|
|
handler.WriteString("\"Infinity\"");
|
|
return;
|
|
}
|
|
handler.WriteString(value.ToString("R", CultureInfo.InvariantCulture));
|
|
}
|
|
#if !Net4
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
#endif
|
|
[FuncLable(FuncType.SameType)]
|
|
internal static void WriteValue(byte value, JsonSerializerHandler handler)
|
|
{
|
|
WriteValue((int)value, handler);
|
|
}
|
|
#if !Net4
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
#endif
|
|
[FuncLable(FuncType.SameType)]
|
|
internal static void WriteValue(sbyte value, JsonSerializerHandler handler)
|
|
{
|
|
WriteValue((int)value, handler);
|
|
}
|
|
#if !Net4
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
#endif
|
|
[FuncLable(FuncType.SameType)]
|
|
internal static void WriteValue(short value, JsonSerializerHandler handler)
|
|
{
|
|
WriteValue((int)value, handler);
|
|
}
|
|
#if !Net4
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
#endif
|
|
[FuncLable(FuncType.SameType)]
|
|
internal static void WriteValue(ushort value, JsonSerializerHandler handler)
|
|
{
|
|
WriteValue((int)value, handler);
|
|
}
|
|
#if !Net4
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
#endif
|
|
[FuncLable(FuncType.SameType)]
|
|
internal static void WriteValue(bool value, JsonSerializerHandler handler)
|
|
{
|
|
handler.WriteString(value ? "true" : "false");
|
|
}
|
|
#if !Net4
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
#endif
|
|
[FuncLable(FuncType.SameType)]
|
|
internal static void WriteValue(char value, JsonSerializerHandler handler)
|
|
{
|
|
WriteValue(char.ToString(value), handler);
|
|
}
|
|
#if !Net4
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
#endif
|
|
[FuncLable(FuncType.SameType)]
|
|
internal static unsafe void WriteValue(string value, JsonSerializerHandler handler)
|
|
{
|
|
/*
|
|
string = quotation-mark *char quotation-mark
|
|
|
|
char = unescaped /
|
|
escape (
|
|
%x22 / ; " quotation mark U+0022
|
|
%x5C / ; \ reverse solidus U+005C
|
|
%x2F / ; / solidus U+002F
|
|
%x62 / ; b backspace U+0008
|
|
%x66 / ; f form feed U+000C
|
|
%x6E / ; n line feed U+000A
|
|
%x72 / ; r carriage return U+000D
|
|
%x74 / ; t tab U+0009
|
|
%x75 4HEXDIG ) ; uXXXX U+XXXX
|
|
|
|
escape = %x5C ; \
|
|
|
|
quotation-mark = %x22 ; "
|
|
|
|
unescaped = %x20-21 / %x23-5B / %x5D-10FFFF
|
|
*/
|
|
if (value == null)
|
|
{
|
|
handler.WriteString("null");
|
|
return;
|
|
}
|
|
//handler.Writer.EnsureCapacity(handler.Writer.Capacity + value.Length);
|
|
handler.WriteString("\"");
|
|
fixed (char* strFixed = value)
|
|
{
|
|
char* str = strFixed;
|
|
char c;
|
|
var len = value.Length;
|
|
while (len > 0)
|
|
{
|
|
c = *str;
|
|
str++;
|
|
len--;
|
|
|
|
if (c == '\\')//\u005c //%x5c a\\b => a\u005cb
|
|
{
|
|
handler.WriteString(@"\\");
|
|
continue;
|
|
}
|
|
|
|
if (c == '"')//\u0022 //%x22
|
|
{
|
|
handler.WriteString("\\\"");
|
|
continue;
|
|
}
|
|
switch (c)
|
|
{
|
|
//%x00-x19
|
|
case '\u0000': handler.WriteString(@"\u0000"); continue;
|
|
case '\u0001': handler.WriteString(@"\u0001"); continue;
|
|
case '\u0002': handler.WriteString(@"\u0002"); continue;
|
|
case '\u0003': handler.WriteString(@"\u0003"); continue;
|
|
case '\u0004': handler.WriteString(@"\u0004"); continue;
|
|
case '\u0005': handler.WriteString(@"\u0005"); continue;
|
|
case '\u0006': handler.WriteString(@"\u0006"); continue;
|
|
case '\u0007': handler.WriteString(@"\u0007"); continue;
|
|
case '\u0008': handler.WriteString(@"\b"); continue;
|
|
case '\u0009': handler.WriteString(@"\t"); continue;
|
|
case '\u000A': handler.WriteString(@"\n"); continue;
|
|
case '\u000B': handler.WriteString(@"\u000b"); continue;
|
|
case '\u000C': handler.WriteString(@"\f"); continue;
|
|
case '\u000D': handler.WriteString(@"\r"); continue;
|
|
case '\u000E': handler.WriteString(@"\u000e"); continue;
|
|
case '\u000F': handler.WriteString(@"\u000f"); continue;
|
|
case '\u0010': handler.WriteString(@"\u0010"); continue;
|
|
case '\u0011': handler.WriteString(@"\u0011"); continue;
|
|
case '\u0012': handler.WriteString(@"\u0012"); continue;
|
|
case '\u0013': handler.WriteString(@"\u0013"); continue;
|
|
case '\u0014': handler.WriteString(@"\u0014"); continue;
|
|
case '\u0015': handler.WriteString(@"\u0015"); continue;
|
|
case '\u0016': handler.WriteString(@"\u0016"); continue;
|
|
case '\u0017': handler.WriteString(@"\u0017"); continue;
|
|
case '\u0018': handler.WriteString(@"\u0018"); continue;
|
|
case '\u0019': handler.WriteString(@"\u0019"); continue;
|
|
case '\u001A': handler.WriteString(@"\u001a"); continue;
|
|
case '\u001B': handler.WriteString(@"\u001b"); continue;
|
|
case '\u001C': handler.WriteString(@"\u001c"); continue;
|
|
case '\u001D': handler.WriteString(@"\u001d"); continue;
|
|
case '\u001E': handler.WriteString(@"\u001e"); continue;
|
|
case '\u001F': handler.WriteString(@"\u001f"); continue;
|
|
/*JavaScript */
|
|
case '\u0085': // Next Line
|
|
handler.WriteString(@"\u0085"); continue;
|
|
case '\u2028': // Line Separator
|
|
handler.WriteString(@"\u2028"); continue;
|
|
case '\u2029': // Paragraph Separator
|
|
handler.WriteString(@"\u2029"); continue;
|
|
default: handler.WriteChar(c); continue;
|
|
}
|
|
}
|
|
}
|
|
handler.WriteString("\"");
|
|
}
|
|
#if !Net4
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
#endif
|
|
[FuncLable(FuncType.SameType)]
|
|
internal static void WriteValue(IntPtr value, JsonSerializerHandler handler)
|
|
{
|
|
WriteValue((long)value, handler);
|
|
}
|
|
#if !Net4
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
#endif
|
|
[FuncLable(FuncType.SameType)]
|
|
internal static void WriteValue(UIntPtr value, JsonSerializerHandler handler)
|
|
{
|
|
WriteValue((ulong)value, handler);
|
|
}
|
|
|
|
#if !Net4
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
#endif
|
|
[FuncLable(FuncType.SameType)]
|
|
internal static void WriteValue(object obj, JsonSerializerHandler handler)
|
|
{
|
|
if (obj == null)
|
|
{
|
|
handler.WriteString("null");
|
|
return;
|
|
}
|
|
var type = obj.GetType();
|
|
if (type.IsAnonymousType() || type == typeof(object))
|
|
SpecialConditions.WriteDynamic(obj, handler);
|
|
else
|
|
{
|
|
var jumpAction = SerializerObjectJump.GetThreadSafetyJumpAction(type);
|
|
jumpAction(obj, handler);
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|