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