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); } } }