2023-11-21 23:05:03 +08:00

1248 lines
42 KiB
C#

using System;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
namespace CPF.Windows.Json.Deserialize
{
internal class PrimitiveResolve : DefaultJsonResolve
{
#region pregenerated metas
internal static MethodInfo _ReadEscapeString = GetMethodInfo(nameof(ReadEscapeString));
#endregion
[FuncLable(FuncType.SameType)]
#if !Net4
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
internal static int ReadInt(JsonReader reader, JsonDeserializeHandler handler)
{
int c = reader.BeforAnnotation();
// max: 2147483647
// min: -2147483648
// digits: 10
long ret = 0;
bool negative = false;
if (c == '-')
{
negative = true;
c = reader.GetChar();
}
if (c < '0' || c > '9')
throw new JsonDeserializationTypeResolutionException(reader, typeof(int));
bool isFirstDigitZero = c == '0';
c = c - '0';
ret += c;
if (reader.Remaining == 0)
return (int)(ret * (negative ? -1 : 1));
// digit #2
c = reader.GetChar();
if (c < '0' || c > '9')
{
reader.RollbackChar();
return (int)(ret * (negative ? -1 : 1));
}
if (isFirstDigitZero)
throw new JsonDeserializationTypeResolutionException(reader, typeof(int));
c = c - '0';
ret *= 10;
ret += c;
while (reader.Remaining > 0)
{
c = reader.GetChar();
if (c < '0' || c > '9')
{
reader.RollbackChar();
goto Return;
}
c = c - '0';
ret *= 10;
ret += c;
}
// 9999999999 > int.Max
Return: checked
{
return (int)(ret * (negative ? -1 : 1));
}
}
[FuncLable(FuncType.SameType)]
#if !Net4
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
internal static uint ReadUInt(JsonReader reader, JsonDeserializeHandler handler)
{
int c = reader.BeforAnnotation();
//MaxValue = 4294967295; 10
//MinValue = 0;
if (c < '0' || c > '9')
if (c == '-' && reader.GetChar() == '0')
return 0;
else
throw new JsonDeserializationTypeResolutionException(typeof(uint));
long ret = 0;
var firstDigitZero = c == '0';
c = c - '0';
ret += (uint)c;
if (reader.Remaining == 0)
return (uint)ret;
c = reader.GetChar();
if (c < '0' || c > '9')
{
reader.RollbackChar();
return (uint)ret;
}
if (firstDigitZero)
throw new JsonDeserializationTypeResolutionException(reader, typeof(uint));
c = c - '0';
ret *= 10;
ret += c;
while (reader.Remaining > 0)
{
c = reader.GetChar();
if (c < '0' || c > '9')
{
reader.RollbackChar();
goto Return;
}
c = c - '0';
ret *= 10;
ret += (uint)c;
}
Return: checked
{
return (uint)ret;
}
}
[FuncLable(FuncType.SameType)]
#if !Net4
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
internal static long ReadLong(JsonReader reader, JsonDeserializeHandler handler)
{
int c = reader.BeforAnnotation();
//MaxValue = 9223372036854775807; 19
//MinValue = -9223372036854775808; 20
//ulong 18446744073709551615; 20
ulong ret = 0;
var negative = false;
if (c == '-')
{
negative = true;
c = reader.GetChar();
}
if (c < '0' || c > '9')
throw new JsonDeserializationTypeResolutionException(reader, typeof(long));
var firstDigitZero = c == '0';
c = c - '0';
ret += (uint)c;
if (reader.Remaining == 0)
return ((long)ret * (negative ? -1 : 1));
c = reader.GetChar();
if (c < '0' || c > '9')
{
reader.RollbackChar();
return ((long)ret * (negative ? -1 : 1));
}
if (firstDigitZero)
throw new JsonDeserializationTypeResolutionException(reader, typeof(long));
c = c - '0';
ret *= 10;
ret += (uint)c;
while (reader.Remaining > 0)
{
c = reader.GetChar();
if (c < '0' || c > '9')
{
reader.RollbackChar();
goto Return;
}
c = c - '0';
ret *= 10;
ret += (uint)c;
}
if (ret == 9223372036854775808 && negative)
return long.MinValue;
Return: checked
{
return ((long)ret * (negative ? -1 : 1));
}
}
[FuncLable(FuncType.SameType)]
#if !Net4
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
internal static ulong ReadULong(JsonReader reader, JsonDeserializeHandler handler)
{
uint c = reader.BeforAnnotation();
if (c < '0' || c > '9')
if (c == '-' && reader.GetChar() == '0')
return 0;
else
throw new JsonDeserializationTypeResolutionException(typeof(ulong));
//MaxValue = 18446744073709551615; 20
//MinValue = 0;
ulong ret = 0;
var firstDigitZero = c == '0';
c = c - '0';
ret += c;
if (reader.Remaining == 0)
return ret;
c = reader.GetChar();
if (c < '0' || c > '9')
{
reader.RollbackChar();
return ret;
}
if (firstDigitZero)
throw new JsonDeserializationTypeResolutionException(reader, typeof(uint));
c = c - '0';
ret *= 10;
ret += c;
int num = 2;
while (reader.Remaining > 0)
{
++num;
c = reader.GetChar();
if (c < '0' || c > '9')
{
reader.RollbackChar();
goto Return;
}
if (num == 20)
{
checked
{
c = c - '0';
ret *= 10;
ret += c;
}
}
else
{
c = c - '0';
ret *= 10;
ret += c;
}
}
Return: checked
{
return ret;
}
}
[FuncLable(FuncType.SameType)]
#if !Net4
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
internal static string ReadEscapeString(JsonReader reader, JsonDeserializeHandler handler)
{
var c = reader.BeforAnnotation();
if (c == '"')
{
int start = reader.Length - reader.Remaining;
int length = 0;
StringBuilder charBufferSb = reader.CharBufferSb ?? new StringBuilder();
int sbStart = charBufferSb.Length;
while (reader.Remaining > 0)
{
c = reader.GetChar();
if (c == '"')//end
{
if (length > 0)
{
if (reader.Json != null)
charBufferSb.Append(reader.Json, start, length);
else
charBufferSb.Append(reader.Buffer, start, length);
}
return charBufferSb.ToString(sbStart, charBufferSb.Length - sbStart);
}
if (c != '\\')
{
++length;
continue;
}
if (length > 0)
{
if (reader.Json != null)
charBufferSb.Append(reader.Json, start, length);
else
charBufferSb.Append(reader.Buffer, start, length);
start += length;
length = 0;
}
/*
string s = "a\\\\b";
string s = "a\\u005cb";
*/
start += 2;
if (reader.Remaining < 1) // \后面必须接任意一个符号,否则字符串有误
throw new JsonDeserializationTypeResolutionException(reader, typeof(string));
c = reader.GetChar();
switch (c)
{
case '"': charBufferSb.Append('"'); continue;
case '\\': charBufferSb.Append('\\'); continue;
case '/': charBufferSb.Append('/'); continue;
case 'b': charBufferSb.Append('\b'); continue;
case 'f': charBufferSb.Append('\f'); continue;
case 'n': charBufferSb.Append('\n'); continue;
case 'r': charBufferSb.Append('\r'); continue;
case 't': charBufferSb.Append('\t'); continue;
case 'u':
{ // \\uXXXX
if (reader.Remaining > 4)//4+'"'
{
int idx = charBufferSb.Length;
charBufferSb.Append(reader.GetChar());
charBufferSb.Append(reader.GetChar());
charBufferSb.Append(reader.GetChar());
charBufferSb.Append(reader.GetChar());
int unicode = (((((charBufferSb[idx].CharToNumber() * 16) + charBufferSb[++idx].CharToNumber()) * 16) + charBufferSb[++idx].CharToNumber()) * 16) + charBufferSb[++idx].CharToNumber();
charBufferSb.Remove(idx - 3, 4);
charBufferSb.Append((char)unicode);
start += 4;
continue;
}
throw new JsonWrongCharacterException(reader, "It should be four hexadecimal digits , such as \\uFFFF");
}
default:
throw new JsonWrongCharacterException(reader, c);
}
}
}
else if (c == 'n' && reader.StrCompair("ull"))
return null;
throw new JsonDeserializationTypeResolutionException(reader, typeof(string));
}
[FuncLable(FuncType.SameType)]
#if !Net4
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
internal static char ReadEscapeChar(JsonReader reader, JsonDeserializeHandler handler)
{
var c = reader.BeforAnnotation();
if (c == '"')
{
c = reader.GetChar();
if (c != '\\')//char 只有1位
{
if (reader.GetChar() == '"')
return c;
throw new JsonWrongCharacterException(reader);
}
c = reader.GetChar();
switch (c)
{
case '"': { c = reader.GetChar(); if (c == '"') return '"'; throw new JsonWrongCharacterException(reader); }
case '\\': { c = reader.GetChar(); if (c == '"') return '\\'; throw new JsonWrongCharacterException(reader); }
case '/': { c = reader.GetChar(); if (c == '"') return '/'; throw new JsonWrongCharacterException(reader); }
case 'b': { c = reader.GetChar(); if (c == '"') return '\b'; throw new JsonWrongCharacterException(reader); }
case 'f': { c = reader.GetChar(); if (c == '"') return '\f'; throw new JsonWrongCharacterException(reader); }
case 'n': { c = reader.GetChar(); if (c == '"') return '\n'; throw new JsonWrongCharacterException(reader); }
case 'r': { c = reader.GetChar(); if (c == '"') return '\r'; throw new JsonWrongCharacterException(reader); }
case 't': { c = reader.GetChar(); if (c == '"') return '\t'; throw new JsonWrongCharacterException(reader); }
case 'u':
{
if (reader.Remaining < 4)
throw new JsonWrongCharacterException(reader);
int unicode = (((((reader.GetChar().CharToNumber() * 16) + reader.GetChar().CharToNumber()) * 16) + reader.GetChar().CharToNumber()) * 16) + reader.GetChar().CharToNumber();
if (reader.GetChar() == '"')
return (char)unicode;
break;
}
}
}
throw new JsonDeserializationTypeResolutionException(reader, typeof(char));
}
#if !Net4
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
[FuncLable(FuncType.SameType)]
internal static IntPtr ReadIntPtr(JsonReader reader, JsonDeserializeHandler handler)
{
if (IntPtr.Size == 4)
{
return new IntPtr(ReadInt(reader, handler));
}
else
{
return new IntPtr(ReadLong(reader, handler));
}
}
#if !Net4
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
[FuncLable(FuncType.SameType)]
internal static UIntPtr ReadUIntPtr(JsonReader reader, JsonDeserializeHandler handler)
{
return new UIntPtr(ReadULong(reader, handler));
}
#if !Net4
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
[FuncLable(FuncType.SameType)]
internal static byte ReadByte(JsonReader reader, JsonDeserializeHandler handler)
{
checked
{
return (byte)ReadInt(reader, handler);
}
}
#if !Net4
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
[FuncLable(FuncType.SameType)]
internal static sbyte ReadSByte(JsonReader reader, JsonDeserializeHandler handler)
{
checked
{
return (sbyte)ReadInt(reader, handler);
}
}
#if !Net4
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
[FuncLable(FuncType.SameType)]
internal static short ReadShort(JsonReader reader, JsonDeserializeHandler handler)
{
checked
{
return (short)ReadInt(reader, handler);
}
}
#if !Net4
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
[FuncLable(FuncType.SameType)]
internal static ushort ReadUShort(JsonReader reader, JsonDeserializeHandler handler)
{
checked
{
return (ushort)ReadInt(reader, handler);
}
}
/*
[-]0[.Num* [e/E +/- Num*]]
[-]Num[*][.Num* [e/E +/- Num*]]
*/
private static readonly double[] DoubleDividers = new[] {
1.0,
10.0,
100.0,
1000.0,
10000.0,
100000.0,
1000000.0,
10000000.0,
100000000.0,
1000000000.0,
10000000000.0,
};
#if !Net4
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
[FuncLable(FuncType.SameType)]
internal static unsafe double ReadDouble(JsonReader reader, JsonDeserializeHandler handler)
{
char c = reader.BeforAnnotation();
if (c == '\"')
{
switch (reader.GetChar())
{
case 'N':
if (reader.StrCompair("aN\""))
return double.NaN;
break;
case '-':
if (reader.StrCompair("Infinity\""))
return double.NegativeInfinity;
break;
case 'I':
if (reader.StrCompair("nfinity\""))
return double.PositiveInfinity;
break;
}
throw new JsonDeserializationTypeResolutionException(typeof(double));
}
reader.RollbackChar();
var idx = 0;
var prev = -1;
var firstDigitIdx = -1;
var firstValidCharIdx = -1;
var decimalPointIdx = -1;
var eIdx = -1;
var pointer = reader.Pointer;
while (reader.Remaining > 0)
{
c = reader.GetChar();
if (c >= '0' && c <= '9')
{
if (firstDigitIdx < 0)
{
firstDigitIdx = idx;
if (firstValidCharIdx < 0)
{
firstValidCharIdx = idx;
}
}
}
else
{
if (c == '+')
{
if (!(prev == 'e' || prev == 'E'))
{
throw new JsonWrongCharacterException();
}
firstValidCharIdx = idx;
}
else
{
if (c == '-')
{
if (prev != -1 && !(prev == 'e' || prev == 'E'))
{
throw new JsonWrongCharacterException();
}
firstValidCharIdx = idx;
}
else
{
if (c == 'e' || c == 'E')
{
if (eIdx >= 0 || firstDigitIdx < 0)
{
throw new JsonWrongCharacterException();
}
eIdx = idx;
}
else
{
if (c == '.')
{
if (eIdx >= 0 || decimalPointIdx >= 0)
{
throw new JsonWrongCharacterException();
}
decimalPointIdx = idx;
}
else
{
reader.RollbackChar();
break;
}
}
}
}
}
idx++;
prev = c;
}
if (firstDigitIdx == -1) throw new JsonWrongCharacterException();
if (firstDigitIdx == -1) throw new JsonWrongCharacterException();
if (pointer[idx - 1] == '.') throw new JsonWrongCharacterException();
if (idx >= 2 && pointer[0] == '0')
{
var secondChar = pointer[1];
if (secondChar != '.' && secondChar != 'e' && secondChar != 'E')
{
throw new JsonWrongCharacterException();
}
}
if (idx >= 3 && pointer[0] == '-' && pointer[1] == '0')
{
var secondChar = pointer[2];
if (secondChar != '.' && secondChar != 'e' && secondChar != 'E')
{
throw new JsonWrongCharacterException();
}
}
if (eIdx < 0)
{
var endIdx = idx;
while (decimalPointIdx >= 0 && endIdx > 1 && pointer[endIdx - 1] == '0')
{
endIdx--;
}
var startIdx =
decimalPointIdx < 0 ?
firstDigitIdx :
Math.Min(decimalPointIdx, firstDigitIdx);
while (startIdx < endIdx && pointer[startIdx] == '0')
{
startIdx++;
}
var hasIntegerComponent = pointer[startIdx] != '.';
var includesDecimalPoint = decimalPointIdx >= 0;
var lastCharIs5 = endIdx > 1 && pointer[endIdx - 1] == '5';
var maxChars = 5 +
(hasIntegerComponent ? 1 : 0) +
(includesDecimalPoint ? 1 : 0) +
(lastCharIs5 ? 1 : 0);
if (endIdx - startIdx <= maxChars)
{
if (decimalPointIdx == endIdx - 1)
{
decimalPointIdx = -1;
endIdx--;
}
var n = 0;
for (idx = startIdx; idx < endIdx; ++idx)
{
if (idx != decimalPointIdx)
n = n * 10 + pointer[idx] - '0';
}
if (pointer[firstValidCharIdx] == '-')
{
n = -n;
}
var result = (double)n;
if (decimalPointIdx >= 0)
{
result /= DoubleDividers[endIdx - decimalPointIdx - 1];
}
return result;
}
}
return double.Parse(new string(pointer, 0, idx), CultureInfo.InvariantCulture);
}
private static readonly decimal[] DecimalMultipliers = new[] {
1m,
0.1m,
0.01m,
0.001m,
0.0001m,
0.00001m,
0.000001m,
0.0000001m,
0.00000001m,
0.000000001m,
0.0000000001m,
0.00000000001m,
0.000000000001m,
0.0000000000001m,
0.00000000000001m,
0.000000000000001m,
0.0000000000000001m,
0.00000000000000001m
};
#if !Net4
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
[FuncLable(FuncType.SameType)]
internal static unsafe decimal ReadDecimal(JsonReader reader, JsonDeserializeHandler handler)
{
reader.BeforAnnotation();
reader.RollbackChar();
var idx = 0;
char c;
var prev = -1;
var firstDigitIdx = -1;
var firstValidCharIdx = -1;
var decimalPointIdx = -1;
var eIdx = -1;
var pointer = reader.Pointer;
while (reader.Remaining > 0)
{
c = reader.GetChar();
if (c >= '0' && c <= '9')
{
if (firstDigitIdx < 0)
{
firstDigitIdx = idx;
if (firstValidCharIdx < 0)
{
firstValidCharIdx = idx;
}
}
}
else
{
if (c == '+')
{
if (!(prev == 'e' || prev == 'E'))
{
throw new JsonWrongCharacterException();
}
firstValidCharIdx = idx;
}
else
{
if (c == '-')
{
if (prev != -1 && !(prev == 'e' || prev == 'E'))
{
throw new JsonWrongCharacterException();
}
firstValidCharIdx = idx;
}
else
{
if (c == 'e' || c == 'E')
{
if (eIdx >= 0 || firstDigitIdx < 0)
{
throw new JsonWrongCharacterException();
}
eIdx = idx;
}
else
{
if (c == '.')
{
if (eIdx >= 0 || decimalPointIdx >= 0)
{
throw new JsonWrongCharacterException();
}
decimalPointIdx = idx;
}
else
{
reader.RollbackChar();
break;
}
}
}
}
}
idx++;
prev = c;
}
if (firstDigitIdx == -1) throw new JsonWrongCharacterException();
if (firstDigitIdx == -1) throw new JsonWrongCharacterException();
if (pointer[idx - 1] == '.') throw new JsonWrongCharacterException();
if (idx >= 2 && pointer[0] == '0')
{
var secondChar = pointer[1];
if (secondChar != '.' && secondChar != 'e' && secondChar != 'E')
{
throw new JsonWrongCharacterException();
}
}
if (idx >= 3 && pointer[0] == '-' && pointer[1] == '0')
{
var secondChar = pointer[2];
if (secondChar != '.' && secondChar != 'e' && secondChar != 'E')
{
throw new JsonWrongCharacterException();
}
}
if (eIdx < 0)
{
var endIdx = idx;
var maxChars = decimalPointIdx < 0 ? 18 : 19;
if (endIdx - firstDigitIdx <= maxChars)
{
if (decimalPointIdx == endIdx - 1)
{
decimalPointIdx = -1;
endIdx--;
}
var negative = pointer[firstValidCharIdx] == '-';
decimal result;
var n1 = 0; // we use int rather than long so as to work well on 32-bit runtime
for (idx = firstDigitIdx; idx < endIdx && n1 < 100000000; ++idx)
{
if (idx != decimalPointIdx)
{
n1 = n1 * 10 + pointer[idx] - '0';
}
}
if (negative)
{
n1 = -n1;
}
if (idx == endIdx)
{
result = n1;
}
else
{
var n2 = 0;
var multiplier = 1;
while (idx < endIdx)
{
if (idx != decimalPointIdx)
{
multiplier *= 10;
n2 = n2 * 10 + pointer[idx] - '0';
}
idx++;
}
if (negative)
{
n2 = -n2;
}
result = (long)n1 * multiplier + n2;
}
if (decimalPointIdx > 0)
{
result *= DecimalMultipliers[endIdx - decimalPointIdx - 1];
}
return result;
}
}
return decimal.Parse(new string(pointer, 0, idx), NumberStyles.Float, CultureInfo.InvariantCulture);
}
private static readonly float[] SingleDividers = {
1.0f,
10.0f,
100.0f,
1000.0f,
10000.0f,
100000.0f,
1000000.0f,
10000000.0f,
100000000.0f,
1000000000.0f,
10000000000.0f,
};
#if !Net4
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
[FuncLable(FuncType.SameType)]
internal static unsafe float ReadFloat(JsonReader reader, JsonDeserializeHandler handler)
{
char c = reader.BeforAnnotation();
if (c == '\"')
{
switch (reader.GetChar())
{
case 'N':
if (reader.StrCompair("aN\""))
return float.NaN;
break;
case '-':
if (reader.StrCompair("Infinity\""))
return float.NegativeInfinity;
break;
case 'I':
if (reader.StrCompair("nfinity\""))
return float.PositiveInfinity;
break;
}
throw new JsonDeserializationTypeResolutionException(typeof(float));
}
reader.RollbackChar();
var idx = 0;
c = '0';
var prev = -1;
var firstDigitIdx = -1;
var firstValidCharIdx = -1;
var decimalPointIdx = -1;
var eIdx = -1;
var pointer = reader.Pointer;
while (reader.Remaining > 0)
{
c = reader.GetChar();
if (c >= '0' && c <= '9')
{
if (firstDigitIdx < 0)
{
firstDigitIdx = idx;
if (firstValidCharIdx < 0)
{
firstValidCharIdx = idx;
}
}
}
else
{
if (c == '+')
{
if (!(prev == 'e' || prev == 'E'))
{
throw new JsonWrongCharacterException();
}
firstValidCharIdx = idx;
}
else
{
if (c == '-')
{
if (prev != -1 && !(prev == 'e' || prev == 'E'))
{
throw new JsonWrongCharacterException();
}
firstValidCharIdx = idx;
}
else
{
if (c == 'e' || c == 'E')
{
if (eIdx >= 0 || firstDigitIdx < 0)
{
throw new JsonWrongCharacterException();
}
eIdx = idx;
}
else
{
if (c == '.')
{
if (eIdx >= 0 || decimalPointIdx >= 0)
{
throw new JsonWrongCharacterException();
}
decimalPointIdx = idx;
}
else
{
reader.RollbackChar();
break;
}
}
}
}
}
idx++;
prev = c;
}
if (firstDigitIdx == -1) throw new JsonWrongCharacterException();
if (firstDigitIdx == -1) throw new JsonWrongCharacterException();
if (pointer[idx - 1] == '.') throw new JsonWrongCharacterException();
if (idx >= 2 && pointer[0] == '0')
{
var secondChar = pointer[1];
if (secondChar != '.' && secondChar != 'e' && secondChar != 'E')
{
throw new JsonWrongCharacterException();
}
}
if (idx >= 3 && pointer[0] == '-' && pointer[1] == '0')
{
var secondChar = pointer[2];
if (secondChar != '.' && secondChar != 'e' && secondChar != 'E')
{
throw new JsonWrongCharacterException();
}
}
if (eIdx < 0)
{
var endIdx = idx;
while (decimalPointIdx >= 0 && endIdx > 1 && pointer[endIdx - 1] == '0')
{
endIdx--;
}
var startIdx =
decimalPointIdx < 0 ?
firstDigitIdx :
Math.Min(decimalPointIdx, firstDigitIdx);
while (startIdx < endIdx && pointer[startIdx] == '0')
{
startIdx++;
}
var hasIntegerComponent = pointer[startIdx] != '.';
var includesDecimalPoint = decimalPointIdx >= 0;
var maxChars =
6 +
(hasIntegerComponent ? 1 : 0) +
(includesDecimalPoint ? 1 : 0);
if (endIdx - startIdx <= maxChars)
{
if (decimalPointIdx == endIdx - 1)
{
decimalPointIdx = -1;
endIdx--;
}
var n = 0;
for (idx = startIdx; idx < endIdx; idx++)
{
if (idx != decimalPointIdx)
{
n = n * 10 + pointer[idx] - '0';
}
}
if (pointer[firstValidCharIdx] == '-')
{
n = -n;
}
var result = (float)n;
if (decimalPointIdx >= 0)
{
result /= SingleDividers[endIdx - decimalPointIdx - 1];
}
return result;
}
}
return float.Parse(new string(pointer, 0, idx), CultureInfo.InvariantCulture);
}
#if !Net4
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
[FuncLable(FuncType.SameType)]
internal static bool ReadBool(JsonReader reader, JsonDeserializeHandler handler)
{
char c = reader.BeforAnnotation();
if (c == 'f' && reader.StrCompair("alse"))
{
return false;
}
if (c == 't' && reader.StrCompair("rue"))
{
return true;
}
throw new JsonDeserializationTypeResolutionException(reader, typeof(bool));
}
#if !Net4
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
[FuncLable(FuncType.SameType)]
internal static unsafe object ReadObject(JsonReader reader, JsonDeserializeHandler handler)
{
char c = reader.BeforAnnotation();
switch (c)
{
case 'f':
if (reader.StrCompair("alse"))
return false;
break;
case 't':
if (reader.StrCompair("rue"))
return true;
break;
case 'n':
if (reader.StrCompair("ull"))
return null;
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '-':
{
int idx = 1;
bool negative = c == '-';
while (reader.Remaining > 0)
{
++idx;
c = reader.GetChar();
if (c == 'e' || c == 'E' || c == '.')
{
reader.Remaining += idx;
reader.Pointer -= idx;
return ReadDouble(reader, handler);
//double
}
else if (c < '0' || c > '9')
{
goto Return;
}
}
Return:
reader.Remaining += idx;
reader.Pointer -= idx;
if (idx <= 19)
{
//long
return ReadLong(reader, handler);
}
else if (idx == 20)
{
double d = ReadDouble(reader, handler);
if (negative)
{
if (d >= long.MinValue)
return (long)d;
return d;
}//double
else
{
if (d >= ulong.MaxValue)
return d;
else
return (ulong)d;
}//ulong
}
else
{
return ReadDouble(reader, handler);
//double
}
}
case '[':
{
if (reader.ReadBoolArrayRight())
return new JArray();
JArray list = new JArray();
int moveNext = 1;
while (moveNext-- > 0)
{
list.Add(ReadObject(reader, handler));
if (reader.ReadBoolComma())
moveNext++;
}
reader.ReadArrayRight();
return list;
}
case '{':
{
if (reader.ReadBoolObjRight())
return new JObject();
JObject dictionary = new JObject();
int moveNext = 1;
while (moveNext-- > 0)
{
var key = ReadEscapeString(reader, handler);
reader.ReadColon();
var value = ReadObject(reader, handler);
dictionary.Add(key, value);
if (reader.ReadBoolComma())
moveNext++;
}
reader.ReadObjRight();
return dictionary;
}
case '"':
{
reader.RollbackChar();
return ReadEscapeString(reader, handler);
}
}
throw new JsonDeserializationTypeResolutionException(reader, typeof(object));
}
private static MethodInfo GetMethodInfo(string name)
{
return typeof(PrimitiveResolve).GetMethod(name, BindingFlags.NonPublic | BindingFlags.Static);
}
}
}