自制Json 类库之 JsonParse

自制Json 类库之 JsonParse

JsonParse 用于解析Json文本

 

JsonParse 代码:

internal partial class JsonParse
    {
        public static Json Parse(string str)
        {
            if (str == null)
            {
                return new JsonValue(null);
            }
            using (var reader = new StringReader(str))
            {
                return ReadJson(reader);
            }
        }

        private static Json ReadJson(TextReader reader)
        {
            if (reader == null || reader.Peek() < 0)
            {
                return new JsonValue(null);
            }

            int peek = 0;

            while ((peek = reader.Peek()) >= 0)
            {
                switch (peek)
                {
                    case 32:// ' ' 空格
                        reader.Read();
                        break;

                    case 34://"
                        return new JsonValue(ReadString(reader));

                    case 39://'
                        reader.Read();
                        char tempC = (char)reader.Read();

                        if (reader.Read() != 39)
                        {
                            throw new JsonParseException("转换失败 [Char 匹配错误]");
                        }

                        return new JsonValue(tempC);
                    case 68://D
                        reader.Read();
                        return new JsonValue(DateTime.Parse(ReadString(reader)));
                    case 0x66://f
                    case 70://F
                        reader.Read();
                        if (!IsMatch(reader, "alse"))
                        {
                            throw new JsonParseException("转换失败 [False]");
                        }
                        return new JsonValue(false);
                    case 71://G
                        reader.Read();
                        return new JsonValue(Guid.Parse(ReadString(reader)));
                    case 0x6E://n
                    case 78://N
                        reader.Read();
                        if (!IsMatch(reader, "ull"))
                        {
                            throw new JsonParseException("转换失败 [Null]");
                        }

                        return new JsonValue(null);
                    case 0x74://t
                    case 84://T
                        reader.Read();
                        if (reader.Peek() == 34)//"
                        {
                            return new JsonValue(TimeSpan.Parse(ReadString(reader)));
                        }
                        else if (!IsMatch(reader, "rue"))
                        {
                            throw new JsonParseException("转换失败 [True]");
                        }

                        return new JsonValue(true);

                    case 91://[
                        return ReadJsonArray(reader);
                    case 123://{
                        return ReadJsonObject(reader);
                    default:
                        if ((peek >= 48 && peek <= 57) || peek == 46 || peek == 45)
                        {
                            return new JsonValue(ReadDecimal(reader));
                        }
                        else
                        {
                            throw new JsonParseException("转换失败 [可能原因:未知类型]");
                        }
                }
            }

            throw new JsonParseException("转换失败 [可能原因:解析的不是MyJson文本或MyJson文本不完整]");
        }

        private static string ReadString(TextReader textReader)
        {
            if (textReader.Read() != 34)//"
            {
                throw new JsonParseException("转换失败 [字符串 始 匹配失败]");
            }

            StringBuilder stringBuilder = new StringBuilder();
            int temp = 0;

            while ((temp = textReader.Read()) >= 0)
            {
                switch (temp)
                {
                    case 92:// => \
                        var tempPeek = textReader.Peek();

                        if (tempPeek == 34 || tempPeek == 92)//34 => " 92 => \
                        {
                            stringBuilder.Append((char)textReader.Read());
                        }
                        else
                        {
                            stringBuilder.Append('\\');
                        }
                        break;

                    case 34: // "
                        return stringBuilder.ToString();

                    default:
                        stringBuilder.Append(((char)temp));
                        break;
                }
            }

            throw new JsonParseException("转换失败 [字符串 终 匹配失败]");
        }

        private static decimal ReadDecimal(TextReader textReader)
        {
            StringBuilder stringBuilder = new StringBuilder();
            int temp = 0;

            while ((temp = textReader.Peek()) >= 0)
            {
                //(byte)0 = 48; (byte)9 = 57; (byte)'.' = 46; (byte)'-' = 45
                if ((48 <= temp && temp <= 57) || temp == 46 || temp == 45)
                {
                    stringBuilder.Append((char)textReader.Read());
                }
                else
                {
                    break;
                }
            }

            decimal tempDecimal = 0;

            if (!decimal.TryParse(stringBuilder.ToString(), out tempDecimal))
            {
                throw new JsonParseException(string.Format("转换失败 [decimal.TryParse()] [{0}]", stringBuilder.ToString()));
            }

            return tempDecimal;
        }

        private static JsonArray ReadJsonArray(TextReader textReader)
        {
            if (textReader.Read() != 91)// 91 => [
            {
                throw new JsonParseException("转换 MyJsonList 失败 [MyJsonList 始 匹配失败]");
            }
            var sonList = new JsonArray();
            if (textReader.Peek() != 93)//93 => ]
            {
                sonList.Add(ReadJson(textReader));
            }

            while (textReader.Peek() >= 0)
            {
                switch (textReader.Read())
                {
                    case 32:// ' ' 空格
                        break;
                    case 44:// => ,
                        sonList.Add(ReadJson(textReader));
                        break;

                    case 93://]
                        return sonList;

                    default:
                        throw new JsonParseException(string.Format("转换 MyJsonList 失败 [MyJsonList 乱码字符] [{0}]", textReader.ReadToEnd()));
                }
            }

            throw new JsonParseException("转换 MyJsonList 失败 [MyJsonList 终 匹配失败]");
        }

        private static JsonObject ReadJsonObject(TextReader textReader)
        {
            if (textReader.Read() != 123)// 123 => {
            {
                throw new JsonParseException("转换 MyJsonDictionary 失败 [MyJsonDictionary 始 匹配失败]");
            }

            var jsonObject = new JsonObject();
            int temp = 0;

            while ((temp = textReader.Peek()) >= 0)
            {
                switch (temp)
                {
                    case 32:// ' ' 空格
                        textReader.Read();
                        break;

                    case 34:// "
                        string keyText = ReadString(textReader);

                        if (!IsMatch(textReader, ":"))
                        {
                            throw new JsonParseException("转换 MyJsonDictionary 失败 [间隔符:丢失]");
                        }

                        jsonObject.Add(keyText, ReadJson(textReader));
                        break;

                    case 44:// ,
                        textReader.Read();
                        break;

                    case 125: // }
                        textReader.Read();
                        return jsonObject;

                    default:
                        throw new JsonParseException(string.Format("转换 MyJsonDictionary 失败 [MyJsonDictionary 乱码字符] [{0}]", textReader.ReadToEnd()));
                }
            }

            throw new JsonParseException("转换 MyJsonDictionary 失败 [MyJsonDictionary 终 匹配失败]");
        }

        /// <summary>
        /// 是否匹配
        /// </summary>
        private static bool IsMatch(TextReader textReader, string text)
        {
            for (int i = 0; i < text.Length; i++)
            {
                if (textReader.Read() != (int)text[i])
                {
                    return false;
                }
            }

            return true;
        }
    }

 

posted @ 2014-12-09 15:56  忤逆小旭  阅读(285)  评论(0)    收藏  举报