Example #1
0
        public object Read(object value, ProtoReader source)
        {
            var type = ExpectedType;

            if (source.WireType == WireType.Null)
            {
                return(Helpers.IsValueType(type) ? Activator.CreateInstance(type) : null);
            }

            if (!RequiresOldValue)
            {
                value = null;
            }
            bool shouldEnd;
            int  newTypeRefKey;
            int  newObjectKey;
            int  typeKey = _baseKey;
            bool isDynamic;
            bool isLateReference;

            BclHelpers.NetObjectOptions options = _options;
            SubItemToken token = NetObjectHelpers.ReadNetObject_Start(
                ref value,
                source,
                ref type,
                options,
                out isDynamic,
                out isLateReference,
                ref typeKey,
                out newObjectKey,
                out newTypeRefKey,
                out shouldEnd);

            if (shouldEnd)
            {
                object oldValue = value;
                if (typeKey >= 0)
                {
                    // can be only for builtins
                    options &= ~BclHelpers.NetObjectOptions.LateSet;

                    if (typeKey == _baseKey && _baseKeySerializer != null)
                    {
                        if (isLateReference)
                        {
                            if (_lateReferenceTail == null)
                            {
                                throw new ProtoException("Late reference can't be deserialized for type " + ExpectedType.Name);
                            }
                            value = _lateReferenceTail.Read(value, source);
                        }
                        else
                        {
                            value = _baseKeySerializer.Read(value, source);
                        }
                    }
                    else
                    {
                        Debug.Assert(isDynamic);
                        value = ProtoReader.ReadObject(value, typeKey, source);
                    }
                }
                else
                {
                    if (isDynamic)
                    {
                        if (source.TryReadBuiltinType(ref value, Helpers.GetTypeCode(type), true))
                        {
                            options |= BclHelpers.NetObjectOptions.LateSet;
                        }
                        else
                        {
                            throw new ProtoException("Dynamic type is not a contract-type: " + type.Name);
                        }
                    }
                    else
                    {
                        if (isLateReference)
                        {
                            if (_lateReferenceTail == null)
                            {
                                throw new ProtoException("Late reference can't be deserialized for type " + ExpectedType.Name);
                            }
                            value = _lateReferenceTail.Read(value, source);
                        }
                        else
                        {
                            if (_tail == null)
                            {
                                throw new ProtoException("Dynamic type expected but no type info was read");
                            }
                            else
                            {
                                // ensure consistent behavior with emit version
                                value = _tail.Read(_tail.RequiresOldValue ? value : null, source);
                            }
                        }
                    }
                }
                NetObjectHelpers.ReadNetObject_EndWithNoteNewObject(value, source, oldValue, type, newObjectKey, newTypeRefKey, options, token);
            }
            else
            {
                if (Helpers.IsValueType(ExpectedType) && value == null)
                {
                    value = Activator.CreateInstance(ExpectedType);
                }
                ProtoReader.EndSubItem(token, source);
            }
            return(value);
        }