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