public ReaderStatus ReadToObject <TObject>(ReaderState state, ILookupNode <int, ReaderCallback <ReaderState, JSONValue, int, TObject> > root, ref TObject target) { state.PullIgnored(); switch (state.Current) { case '[': return(this.ReadToObjectFromArray(state, root, ref target)); case '{': return(this.ReadToObjectFromObject(state, root, ref target)); default: return(this.Skip(state) ? ReaderStatus.Ignored : ReaderStatus.Failed); } }
public ReaderStatus ReadToObject <TObject>(ReaderState state, ILookupNode <char, ReaderCallback <ReaderState, RawProtobufValue, char, TObject> > root, ref TObject target) { if (!state.ObjectBegin(out var backup)) { return(state.TrySkipValue() ? ReaderStatus.Succeeded : ReaderStatus.Failed); } while (true) { state.ReadHeader(); // Stop reading complex object when no more field can be read if (state.FieldIndex <= 0) { state.ObjectEnd(backup); return(ReaderStatus.Succeeded); } var node = root.Follow('_'); if (state.FieldIndex > 9) { foreach (var digit in state.FieldIndex.ToString(CultureInfo.InvariantCulture)) { node = node.Follow(digit); } } else { node = node.Follow((char)('0' + state.FieldIndex)); } if (!(node.HasValue ? node.Value(this, state, ref target) == ReaderStatus.Succeeded : state.TrySkipValue())) { return(ReaderStatus.Failed); } } }
private ReaderStatus ReadToObjectFromArray <TObject>(ReaderState state, ILookupNode <int, ReaderCallback <ReaderState, JSONValue, int, TObject> > root, ref TObject target) { state.Read(); for (var index = 0;; ++index) { state.PullIgnored(); if (state.Current == ']') { break; } // Read comma separator if any if (index > 0) { if (!state.PullExpected(',')) { return(ReaderStatus.Failed); } state.PullIgnored(); } // Build and move to array index var node = root.Follow(index); // Read array value if (!(node.HasValue ? node.Value(this, state, ref target) != ReaderStatus.Failed : this.Skip(state))) { return(ReaderStatus.Failed); } } state.Read(); return(ReaderStatus.Succeeded); }
public ReaderStatus ReadToObject <TObject>(ReaderState state, ILookupNode <char, ReaderCallback <ReaderState, string, char, TObject> > root, ref TObject target) { if (state.Current == -1) { return(ReaderStatus.Succeeded); } while (true) { // Parse field name var empty = true; // FIXME: handle % encoding in field names var node = root; while (QueryStringCharacter.IsUnreserved(state.Current)) { empty = false; node = node.Follow((char)state.Current); state.Pull(); } if (empty) { state.Error("empty field name"); return(ReaderStatus.Failed); } // Parse field value switch (state.Current) { case '=': state.Pull(); state.Location = QueryStringLocation.ValueBegin; if (!(node.HasValue ? node.Value(this, state, ref target) == ReaderStatus.Succeeded : this.ReadToValue(state, out _) == ReaderStatus.Succeeded)) { return(ReaderStatus.Failed); } break; default: state.Location = QueryStringLocation.ValueEnd; if (node.HasValue && node.Value(this, state, ref target) != ReaderStatus.Succeeded) { return(ReaderStatus.Failed); } break; } if (state.Location != QueryStringLocation.ValueEnd) { throw new InvalidOperationException( "internal error, please report an issue on GitHub: https://github.com/r3c/verse/issues"); } // Expect either field separator or end of stream if (state.Current == -1) { return(ReaderStatus.Succeeded); } if (!QueryStringCharacter.IsSeparator(state.Current)) { state.Error("unexpected character"); return(ReaderStatus.Failed); } state.Pull(); // Check for end of stream (in case of dangling separator e.g. "?k&") and resume loop if (state.Current == -1) { return(ReaderStatus.Succeeded); } state.Location = QueryStringLocation.Sequence; } }
public ReaderStatus ReadToObject <TObject>(ReaderState state, ILookupNode <int, ReaderCallback <ReaderState, ProtobufValue, int, TObject> > root, ref TObject target) { var current = state.Stream.ReadByte(); if (current < 0) { return(ReaderStatus.Succeeded); } // Read field number and wire type var index = (current >> 3) & 15; var wire = (WireType)(current & 7); while ((current & 128) != 0) { current = state.Stream.ReadByte(); index = (index << 8) + current; } // Decode value ProtoBinding field; /* * if (index >= 0 && index < this.bindings.Length && this.bindings[index].Type != ProtoType.Undefined) * field = this.bindings[index]; * else if (!this.rejectUnknown) * field = ProtoBinding.Empty; * else * { * state.RaiseError("field {0} with wire type {1} is unknown", index, wire); * * return false; * } */ field = default; switch (wire) { case WireType.Fixed32: var u32 = ReaderHelper.ReadInt32(state); switch (field.Type) { case ProtoType.Fixed32: state.Value = new ProtobufValue(u32); break; case ProtoType.Float: unsafe { state.Value = new ProtobufValue(*((float *)&u32)); } break; case ProtoType.SFixed32: state.Value = new ProtobufValue((int)u32); break; case ProtoType.Undefined: break; default: state.RaiseError("field {0} is incompatible with wire type {1}", field.Name, wire); return(ReaderStatus.Failed); } break; case WireType.Fixed64: var u64 = ReaderHelper.ReadInt64(state); switch (field.Type) { case ProtoType.Double: unsafe { state.Value = new ProtobufValue(*((double *)&u64)); } break; case ProtoType.Fixed64: state.Value = new ProtobufValue(u64); break; case ProtoType.SFixed64: state.Value = new ProtobufValue((long)u64); break; case ProtoType.Undefined: break; default: state.RaiseError("field {0} is incompatible with wire type {1}", field.Name, wire); return(ReaderStatus.Failed); } break; case WireType.GroupBegin: if (field.Type != ProtoType.Undefined) { state.RaiseError("groups are not supported"); return(ReaderStatus.Failed); } break; case WireType.GroupEnd: if (field.Type != ProtoType.Undefined) { state.RaiseError("groups are not supported"); return(ReaderStatus.Failed); } break; case WireType.LengthDelimited: switch (field.Type) { case ProtoType.Custom: throw new NotImplementedException(); case ProtoType.String: var length = ReaderHelper.ReadVarInt(state); /* * if (length > this.maximumLength) * { * state.RaiseError("number of bytes in field {0} ({1}) exceeds allowed maximum ({2})", field.Name, length, this.maximumLength); * * return false; * } */ var buffer = new byte[length]; if (state.Stream.Read(buffer, 0, (int)length) != (int)length) { return(ReaderStatus.Failed); } state.Value = new ProtobufValue(Encoding.UTF8.GetString(buffer)); break; case ProtoType.Undefined: break; default: state.RaiseError("field {0} is incompatible with wire type {1}", field.Name, wire); return(ReaderStatus.Failed); } return(ReaderStatus.Failed); case WireType.VarInt: var varint = ReaderHelper.ReadVarInt(state); switch (field.Type) { case ProtoType.Boolean: state.Value = new ProtobufValue(varint != 0); break; case ProtoType.Int32: state.Value = new ProtobufValue((int)varint); break; case ProtoType.Int64: state.Value = new ProtobufValue((long)varint); break; case ProtoType.SInt32: case ProtoType.SInt64: state.Value = new ProtobufValue((-(long)(varint & 1)) ^ (long)(varint >> 1)); break; case ProtoType.UInt32: case ProtoType.UInt64: state.Value = new ProtobufValue(varint); break; case ProtoType.Undefined: break; default: state.RaiseError("field {0} is incompatible with wire type {1}", field.Name, wire); return(ReaderStatus.Failed); } break; default: state.RaiseError("field {0} has unsupported wire type {1}", field.Name, wire); return(ReaderStatus.Failed); } /* * return this.fields[index] != null * ? this.fields[index](state, ref entity) * : Reader<TObject>.Ignore(state); */ return(ReaderStatus.Failed); }
private ReaderStatus ReadToObjectFromObject <TObject>(ReaderState state, ILookupNode <int, ReaderCallback <ReaderState, JSONValue, int, TObject> > root, ref TObject target) { state.Read(); for (var index = 0;; ++index) { state.PullIgnored(); if (state.Current == '}') { break; } // Read comma separator if any if (index > 0) { if (!state.PullExpected(',')) { return(ReaderStatus.Failed); } state.PullIgnored(); } if (!state.PullExpected('"')) { return(ReaderStatus.Failed); } // Read and move to object key var node = root; while (state.Current != '"') { if (!state.PullCharacter(out var character)) { state.Error("invalid character in object key"); return(ReaderStatus.Failed); } node = node.Follow(character); } state.Read(); // Read object separator state.PullIgnored(); if (!state.PullExpected(':')) { return(ReaderStatus.Failed); } // Read object value state.PullIgnored(); if (node.HasValue) { if (node.Value(this, state, ref target) == ReaderStatus.Failed) { return(ReaderStatus.Failed); } } else { if (!this.Skip(state)) { return(ReaderStatus.Failed); } } } state.Read(); return(ReaderStatus.Succeeded); }
public FastLookupNode(ILookupNode <TKey, TValue> shortcut, ILookupNode <TKey, TValue> fallback) { this.fallback = fallback; this.shortcut = shortcut; }