public object Read(object value, ProtoReader source)
        {
            object[] values       = new object[_members.Length];
            bool     invokeCtor   = false;
            int      reservedTrap = -1;

            if (value == null)
            {
                reservedTrap = ProtoReader.ReserveNoteObject(source);
                invokeCtor   = true;
            }
            var token = ProtoReader.StartSubItem(source);

            for (int i = 0; i < values.Length; i++)
            {
                values[i] = GetValue(value, i);
            }
            int field;

            while ((field = source.ReadFieldHeader()) > 0)
            {
                invokeCtor = true;
                if (field <= _tails.Length)
                {
                    IProtoSerializer tail = _tails[field - 1];
                    values[field - 1] = _tails[field - 1].Read(tail.RequiresOldValue ? values[field - 1] : null, source);
                }
                else
                {
                    source.SkipField();
                }
            }
            ProtoReader.EndSubItem(token, source);
            if (invokeCtor)
            {
                var r = _ctor.Invoke(values);
                // inside references won't work, but from outside will
                // this is a common problem when deserializing immutable types
                ProtoReader.NoteReservedTrappedObject(reservedTrap, r, source);
                return(r);
            }
            return(value);
        }
Exemple #2
0
        public object Read(object value, ProtoReader source)
        {
            int reservedTrap = -1;

            if (!Helpers.IsValueType(ExpectedType))
            {
                reservedTrap = ProtoReader.ReserveNoteObject(source);
            }
            // convert the incoming value
            object[] args = { value };
            value = _toTail.Invoke(null, args); // don't note, references are not to surrogate but to the final object
            // invoke the tail and convert the outgoing value
            args[0] = _rootTail.Read(value, source);
            var r = _fromTail.Invoke(null, args);

            if (!Helpers.IsValueType(ExpectedType))
            {
                ProtoReader.NoteReservedTrappedObject(reservedTrap, r, source);
            }
            return(r);
        }
Exemple #3
0
        public override object Read(object value, ProtoReader source)
        {
            int    trappedKey      = ProtoReader.ReserveNoteObject(source);
            object builderInstance = _builderFactory.Invoke(null, null);

            object[] args = new object[1];

            if (AppendToCollection && value != null && ((IList)value).Count != 0)
            {
                if (_addRange != null)
                {
                    args[0] = value;
                    _addRange.Invoke(builderInstance, args);
                }
                else
                {
                    foreach (object item in (IList)value)
                    {
                        args[0] = item;
                        _add.Invoke(builderInstance, args);
                    }
                }
            }

            ListHelpers.Read(null, null,
                             o =>
            {
                args[0] = o;
                _add.Invoke(builderInstance, args);
            },
                             source);

            var r = _finish.Invoke(builderInstance, null);

            ProtoReader.NoteReservedTrappedObject(trappedKey, r, source);
            return(r);
        }
Exemple #4
0
        public override object Read(object value, ProtoReader source)
        {
            Array     result       = null;
            BasicList list         = null;
            int       reservedTrap = -1;
            int       index        = 0;
            int?      length       = null;

            _listHelpers.Read(
                () =>
            {
                if (source.TryReadFieldHeader(ListHelpers.FieldLength))
                {
                    // we write length to construct an array before deserializing
                    // so we can handle references to array from inside it

                    length = source.ReadInt32();
                    return(true);
                }
                return(false);
            },
                () =>
            {
                if (length != null)
                {
                    if (length.Value > _readLengthLimit)
                    {
                        ThrowExceededLengthLimit(length.Value, _readLengthLimit);
                    }

                    // TODO use same instance when length equals, don't forget to NoteObject
                    int oldLen;
                    result = Read_CreateInstance(value, length.Value, -1, out oldLen, source);
                    index  = oldLen;
                }
                else
                {
                    reservedTrap = ProtoReader.ReserveNoteObject(source);
                    list         = new BasicList();
                }
            },
                v =>
            {
                if (result != null)
                {
                    result.SetValue(v, index++);
                }
                else
                {
                    list.Add(v);
                }
            },
                source);

            if (result == null)
            {
                int oldLen;
                result = Read_CreateInstance(value, list.Count, reservedTrap, out oldLen, source);
                list.CopyTo(result, oldLen);
            }
            return(result);
        }