示例#1
0
        private static ListTreeNode <MsgPackValue> _Parse(ListTreeNode <MsgPackValue> tree, ArraySegment <Byte> bytes)
        {
            var formatType = GetFormat(bytes);

            if (formatType.IsArray())
            {
                var array = tree.AddValue(bytes, ValueNodeType.Array);

                uint count;
                bytes = GetItemCount(bytes, formatType, out count);
                for (var i = 0; i < count; ++i)
                {
                    var child = _Parse(array, bytes);
                    bytes = bytes.Advance(child.Value.Bytes.Count);
                }

                array.SetValueBytesCount(bytes.Offset - array.Value.Bytes.Offset);

                return(array);
            }
            else if (formatType.IsMap())
            {
                var obj = tree.AddValue(bytes, ValueNodeType.Object);

                uint count;
                bytes = GetItemCount(bytes, formatType, out count);
                for (var i = 0; i < count; ++i)
                {
                    // key
                    var key = _Parse(obj, bytes);
                    bytes = bytes.Advance(key.Value.Bytes.Count);

                    // value
                    var value = _Parse(obj, bytes);
                    bytes = bytes.Advance(value.Value.Bytes.Count);
                }

                obj.SetValueBytesCount(bytes.Offset - obj.Value.Bytes.Offset);

                return(obj);
            }
            else
            {
                var body       = GetBody(bytes, formatType);
                var headerSize = body.Offset - bytes.Offset;
                var size       = headerSize + body.Count;

                var value = tree.AddValue(bytes.Take(size), ValueNodeType.Null);
                return(value);
            }
        }
示例#2
0
        private static ListTreeNode <JsonValue> ParseString(ListTreeNode <JsonValue> tree, Utf8String segment)
        {
            int pos;

            if (segment.TrySearchAscii((Byte)'"', 1, out pos))
            {
                return(tree.AddValue(segment.Subbytes(0, pos + 1).Bytes, ValueNodeType.String));
            }
            else
            {
                throw new ParserException("no close string: " + segment);
            }
        }
示例#3
0
        /// <summary>
        /// Expected null, boolean, integer, number
        /// </summary>
        /// <param name="segment"></param>
        /// <param name="valueType"></param>
        /// <param name="parentIndex"></param>
        /// <returns></returns>
        private static ListTreeNode <JsonValue> ParsePrimitive(ListTreeNode <JsonValue> tree, Utf8String segment,
                                                               ValueNodeType valueType)
        {
            var i = 1;

            for (; i < segment.ByteLength; ++i)
            {
                if (Char.IsWhiteSpace((char)segment[i]) ||
                    segment[i] == '}' ||
                    segment[i] == ']' ||
                    segment[i] == ',' ||
                    segment[i] == ':'
                    )
                {
                    break;
                }
            }
            return(tree.AddValue(segment.Subbytes(0, i).Bytes, valueType));
        }
示例#4
0
        public static IEnumerable <ListTreeNode <T> > GetNodes <T>(this ListTreeNode <T> self,
                                                                   JsonPointer jsonPointer)
            where T : IListTreeItem, IValue <T>
        {
            if (jsonPointer.Path.Count == 0)
            {
                yield return(self);

                yield break;
            }

            if (self.IsArray())
            {
                // array
                if (jsonPointer[0][0] == '*')
                {
                    // wildcard
                    foreach (var child in self.ArrayItems())
                    {
                        foreach (var childChild in child.GetNodes(jsonPointer.Unshift()))
                        {
                            yield return(childChild);
                        }
                    }
                }
                else
                {
                    var index = jsonPointer[0].ToInt32();
                    var child = self.ArrayItems().Skip(index).First();
                    foreach (var childChild in child.GetNodes(jsonPointer.Unshift()))
                    {
                        yield return(childChild);
                    }
                }
            }
            else if (self.IsMap())
            {
                // object
                if (jsonPointer[0][0] == '*')
                {
                    // wildcard
                    foreach (var kv in self.ObjectItems())
                    {
                        foreach (var childChild in kv.Value.GetNodes(jsonPointer.Unshift()))
                        {
                            yield return(childChild);
                        }
                    }
                }
                else
                {
                    ListTreeNode <T> child;
                    try
                    {
                        child = self.ObjectItems().First(x => x.Key.GetUtf8String() == jsonPointer[0]).Value;
                    }
                    catch (Exception)
                    {
                        // key
                        self.AddKey(jsonPointer[0]);
                        // value
                        self.AddValue(default(ArraySegment <byte>), ValueNodeType.Object);

                        child = self.ObjectItems().First(x => x.Key.GetUtf8String() == jsonPointer[0]).Value;
                    }

                    foreach (var childChild in child.GetNodes(jsonPointer.Unshift()))
                    {
                        yield return(childChild);
                    }
                }
            }
            else
            {
                throw new NotImplementedException();
            }
        }
示例#5
0
        private static ListTreeNode <JsonValue> ParseObject(ListTreeNode <JsonValue> tree, Utf8String segment)
        {
            var obj = tree.AddValue(segment.Bytes, ValueNodeType.Object);

            var closeChar = '}';
            var isFirst   = true;
            var current   = segment.Subbytes(1);

            while (true)
            {
                {
                    // skip white space
                    int nextToken;
                    if (!current.TrySearchByte(x => !Char.IsWhiteSpace((char)x), out nextToken))
                    {
                        throw new ParserException("no white space expected");
                    }
                    current = current.Subbytes(nextToken);
                }

                {
                    if (current[0] == closeChar)
                    {
                        break;
                    }
                }

                if (isFirst)
                {
                    isFirst = false;
                }
                else
                {
                    // search ',' or closeChar
                    int keyPos;
                    if (!current.TrySearchByte(x => x == ',', out keyPos))
                    {
                        throw new ParserException("',' expected");
                    }
                    current = current.Subbytes(keyPos + 1);
                }

                {
                    // skip white space
                    int nextToken;
                    if (!current.TrySearchByte(x => !Char.IsWhiteSpace((char)x), out nextToken))
                    {
                        throw new ParserException("not whitespace expected");
                    }
                    current = current.Subbytes(nextToken);
                }

                // key
                var key = Parse(obj, current);
                if (!key.IsString())
                {
                    throw new ParserException("object key must string: " + key.Value.Segment);
                }
                current = current.Subbytes(key.Value.Segment.ByteLength);

                // search ':'
                int valuePos;
                if (!current.TrySearchByte(x => x == ':', out valuePos))
                {
                    throw new ParserException(": is not found");
                }
                current = current.Subbytes(valuePos + 1);

                {
                    // skip white space
                    int nextToken;
                    if (!current.TrySearchByte(x => !Char.IsWhiteSpace((char)x), out nextToken))
                    {
                        throw new ParserException("not whitespace expected");
                    }
                    current = current.Subbytes(nextToken);
                }

                // value
                var value = Parse(obj, current);
                current = current.Subbytes(value.Value.Segment.ByteLength);
            }

            // fix obj range
            var count = current.Bytes.Offset + 1 - segment.Bytes.Offset;

            obj.SetValueBytesCount(count);

            return(obj);
        }
示例#6
0
        private static ListTreeNode <JsonValue> ParseArray(ListTreeNode <JsonValue> tree, Utf8String segment)
        {
            var array = tree.AddValue(segment.Bytes, ValueNodeType.Array);

            var closeChar = ']';
            var isFirst   = true;
            var current   = segment.Subbytes(1);

            while (true)
            {
                {
                    // skip white space
                    int nextToken;
                    if (!current.TrySearchByte(x => !Char.IsWhiteSpace((char)x), out nextToken))
                    {
                        throw new ParserException("no white space expected");
                    }
                    current = current.Subbytes(nextToken);
                }

                {
                    if (current[0] == closeChar)
                    {
                        break;
                    }
                }

                if (isFirst)
                {
                    isFirst = false;
                }
                else
                {
                    // search ',' or closeChar
                    int keyPos;
                    if (!current.TrySearchByte(x => x == ',', out keyPos))
                    {
                        throw new ParserException("',' expected");
                    }
                    current = current.Subbytes(keyPos + 1);
                }

                {
                    // skip white space
                    int nextToken;
                    if (!current.TrySearchByte(x => !Char.IsWhiteSpace((char)x), out nextToken))
                    {
                        throw new ParserException("not whitespace expected");
                    }
                    current = current.Subbytes(nextToken);
                }

                // value
                var child = Parse(array, current);
                current = current.Subbytes(child.Value.Segment.ByteLength);
            }

            // fix array range
            var count = current.Bytes.Offset + 1 - segment.Bytes.Offset;

            array.SetValueBytesCount(count);

            return(array);
        }