示例#1
0
文件: Reader.cs 项目: TurpIF/verse
        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);
            }
        }
示例#2
0
文件: Reader.cs 项目: TurpIF/verse
        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);
                }
            }
        }
示例#3
0
文件: Reader.cs 项目: TurpIF/verse
        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);
        }
示例#4
0
        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;
            }
        }
示例#5
0
        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);
        }
示例#6
0
文件: Reader.cs 项目: TurpIF/verse
        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);
        }
示例#7
0
 public FastLookupNode(ILookupNode <TKey, TValue> shortcut, ILookupNode <TKey, TValue> fallback)
 {
     this.fallback = fallback;
     this.shortcut = shortcut;
 }