private static object DeserializeArray(JsonReaderBase reader)
        {
            if (reader.ReadChar() != '[')
            {
                throw new FormatException();
            }
            var collection = new List <object>();
            var first      = true;

            while (true)
            {
                reader.SkipSpace();
                if (reader.IsEnd)
                {
                    throw new FormatException("配列の閉じ括弧が見つかりません。");
                }
                if (reader.Peek() == ']')
                {
                    reader.ReadChar();
                    break;
                }
                if (!first)
                {
                    if (reader.Peek() != ',')
                    {
                        throw new FormatException("配列の区切り文字が見つかりません。");
                    }
                    reader.ReadChar();
                }
                reader.SkipSpace();
                collection.Add(Deserialize(reader));
                first = false;
            }
            return(collection.ToArray());
        }
        private static object DeserializeObject(JsonReaderBase reader)
        {
            if (reader.ReadChar() != '{')
            {
                throw new FormatException();
            }
            var dic   = new Dictionary <string, object>();
            var first = true;

            while (true)
            {
                reader.SkipSpace();
                if (reader.IsEnd)
                {
                    throw new FormatException("オブジェクトの閉じ括弧が見つかりません。");
                }
                if (reader.Peek() == '}')
                {
                    reader.ReadChar();
                    break;
                }
                if (!first)
                {
                    if (reader.Peek() != ',')
                    {
                        throw new FormatException("オブジェクトの区切り文字','が見つかりません。");
                    }
                    reader.ReadChar();
                }
                reader.SkipSpace();
                var key = DeserializeString(reader);
                reader.SkipSpace();
                if (reader.Peek() != ':')
                {
                    throw new FormatException("オブジェクトの区切り文字':'が見つかりません。");
                }
                reader.ReadChar();
                reader.SkipSpace();
                var value = Deserialize(reader);
                dic[key] = value;
                first    = false;
            }
            return(dic);
        }
        private static object Deserialize(JsonReaderBase reader)
        {
            reader.SkipSpace();
            switch (reader.Peek())
            {
            case '[':
                return(DeserializeArray(reader));

            case '{':
                return(DeserializeObject(reader));

            case '"':
                return(DeserializeString(reader));

            case 't':     // true
                if (reader.ReadStr(4) != "true")
                {
                    throw new FormatException();
                }
                return(true);

            case 'f':     // false
                if (reader.ReadStr(5) != "false")
                {
                    throw new FormatException();
                }
                return(false);

            case 'n':     // null
                if (reader.ReadStr(4) != "null")
                {
                    throw new FormatException();
                }
                return(null);

            case '0':
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
            case '9':
                return(DeserializeNumber(1, reader));

            case '-':
                reader.ReadChar();
                return(DeserializeNumber(-1, reader));

            default:
                throw new FormatException();
            }
        }
        private static object DeserializeNumber(int sign, JsonReaderBase reader)
        {
            var sb = new StringBuilder();
            var is_end_of_numeric = false;

            while (!is_end_of_numeric && !reader.IsEnd)
            {
                char c = reader.Peek();
                switch (c)
                {
                case '0':
                case '1':
                case '2':
                case '3':
                case '4':
                case '5':
                case '6':
                case '7':
                case '8':
                case '9':
                case '.':
                case 'e':
                case 'E':
                    sb.Append(reader.ReadChar());
                    break;

                default:
                    is_end_of_numeric = true;
                    break;
                }
            }
            var text = sb.ToString();

            Int32 value_int32;

            if (Int32.TryParse(text, NumberStyles.None, CultureInfo.InvariantCulture.NumberFormat, out value_int32))
            {
                return(sign * value_int32);
            }

            Int64 value_int64;

            if (Int64.TryParse(text, NumberStyles.None, CultureInfo.InvariantCulture.NumberFormat, out value_int64))
            {
                return(sign * value_int64);
            }

            if (sign > 0)
            {
                UInt32 value_uint32;
                if (UInt32.TryParse(text, NumberStyles.None, CultureInfo.InvariantCulture.NumberFormat, out value_uint32))
                {
                    return(value_int32);
                }

                UInt64 value_uint64;
                if (UInt64.TryParse(text, NumberStyles.None, CultureInfo.InvariantCulture.NumberFormat, out value_uint64))
                {
                    return(value_int64);
                }
            }

            Decimal value_decimal;
            var     success_decimal = Decimal.TryParse(text, NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent, CultureInfo.InvariantCulture.NumberFormat, out value_decimal);
            Double  value_double;
            var     success_double = Double.TryParse(text, NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent, CultureInfo.InvariantCulture.NumberFormat, out value_double);

            if (success_decimal)
            {
                if (success_double)
                {
                    return(sign * value_double);
                }
                else
                {
                    return(sign * value_decimal);
                }
            }
            else
            {
                if (success_double)
                {
                    return(sign * value_double);
                }
                else
                {
                    throw new FormatException("不正な形式の数値が見つかりました。");
                }
            }
        }
        private static string DeserializeString(JsonReaderBase reader)
        {
            if (reader.ReadChar() != '"')
            {
                throw new FormatException();
            }
            var sb = new StringBuilder();

            while (!reader.IsEnd)
            {
                char c = reader.ReadChar();
                if (c == '"')
                {
                    break;
                }
                if (c == '\\')
                {
                    char c2 = reader.ReadChar();
                    switch (c2)
                    {
                    case 'b':
                        sb.Append('\b');
                        break;

                    case 'f':
                        sb.Append('\f');
                        break;

                    case 'n':
                        sb.Append('\n');
                        break;

                    case 'r':
                        sb.Append('\r');
                        break;

                    case 't':
                        sb.Append('\t');
                        break;

                    case 'u':
                    {
                        var s  = reader.ReadStr(4);
                        var ch = char.ConvertFromUtf32(Int32.Parse(s, NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture));
                        sb.Append(ch);
                    }
                    break;

                    case '"':
                    case '\\':
                    case '/':
                        sb.Append(c2);
                        break;

                    default:
                        throw new FormatException("不正なエスケープシーケンスが見つかりました。");
                    }
                }
                else
                {
                    sb.Append(c);
                }
            }
            return(sb.ToString());
        }