Example #1
0
        /// <summary>
        /// Writes an *implementation specific* bundled .NET object, including (as options) type-metadata, identity/re-use, etc.
        /// </summary>
        public static void WriteNetObject(object value, ProtoWriter dest, int key, NetObjectOptions options)
        {
#if FEAT_IKVM
            throw new NotSupportedException();
#else
            if (dest == null) throw new ArgumentNullException("dest");
            bool dynamicType = (options & NetObjectOptions.DynamicType) != 0,
                 asReference = (options & NetObjectOptions.AsReference) != 0;
            WireType wireType = dest.WireType;
            SubItemToken token = ProtoWriter.StartSubItem(null, dest);
            bool writeObject = true;
            if (asReference)
            {
                bool existing;
                int objectKey = dest.NetCache.AddObjectKey(value, out existing);
                ProtoWriter.WriteFieldHeader(existing ? FieldExistingObjectKey : FieldNewObjectKey, WireType.Variant, dest);
                ProtoWriter.WriteInt32(objectKey, dest);
                if (existing)
                {
                    writeObject = false;
                }
            }

            if (writeObject)
            {
                if (dynamicType)
                {
                    bool existing;
                    Type type = value.GetType();

                    if (!(value is string))
                    {
                        key = dest.GetTypeKey(ref type);
                        if (key < 0) throw new InvalidOperationException("Dynamic type is not a contract-type: " + type.Name);
                    }
                    int typeKey = dest.NetCache.AddObjectKey(type, out existing);
                    ProtoWriter.WriteFieldHeader(existing ? FieldExistingTypeKey : FieldNewTypeKey, WireType.Variant, dest);
                    ProtoWriter.WriteInt32(typeKey, dest);
                    if (!existing)
                    {
                        ProtoWriter.WriteFieldHeader(FieldTypeName, WireType.String, dest);
                        ProtoWriter.WriteString(dest.SerializeType(type), dest);
                    }
                    
                }
                ProtoWriter.WriteFieldHeader(FieldObject, wireType, dest);
                if (value is string)
                {
                    ProtoWriter.WriteString((string)value, dest);
                }
                else { 
                    ProtoWriter.WriteObject(value, key, dest);
                }
            }
            ProtoWriter.EndSubItem(token, dest);
#endif
        }
        /// <summary>
        /// Reads an *implementation specific* bundled .NET object, including (as options) type-metadata, identity/re-use, etc.
        /// </summary>
        public static object ReadNetObject(object value, ProtoReader source, int key, Type type, NetObjectOptions options)
        {
            SubItemToken token = ProtoReader.StartSubItem(source);
            int fieldNumber;
            int newObjectKey = -1, newTypeKey = -1, tmp;
            while ((fieldNumber = source.ReadFieldHeader()) > 0)
            {
                switch (fieldNumber)
                {
                    case FieldExistingObjectKey:
                        tmp = source.ReadInt32();
                        value = source.NetCache.GetKeyedObject(tmp);
                        break;
                    case FieldNewObjectKey:
                        newObjectKey = source.ReadInt32();
                        break;
                    case FieldExistingTypeKey:
                        tmp = source.ReadInt32();
                        type = (Type)source.NetCache.GetKeyedObject(tmp);
                        key = source.GetTypeKey(ref type);
                        break;
                    case FieldNewTypeKey:
                        newTypeKey = source.ReadInt32();
                        break;
                    case FieldTypeName:
                        string typeName = source.ReadString();
                        type = source.DeserializeType(typeName);
                        if(type == null)
                        {
                            throw new ProtoException("Unable to resolve type: " + typeName + " (you can use the TypeModel.DynamicTypeFormatting event to provide a custom mapping)");
                        }
                        key = source.GetTypeKey(ref type);
                        if(key < 0) throw new InvalidOperationException("Dynamic type is not a contract-type: " + type.Name);
                        break;
                    case FieldObject:
                        bool isString = type == typeof(string);
                        bool lateSet = value == null && isString;
                        if (value == null && !lateSet)
                        {
                            try
                            {
                                value = ((options & NetObjectOptions.UseConstructor) == 0)
                                            ? BclHelpers.GetUninitializedObject(type)
											: (type.IsArray || type.IsInterface ? null : Activator.CreateInstance(type, true));
                            } catch (Exception ex)
                            {
                                throw new ProtoException("Unable to create type " + (type == null ? "<null>" : type.FullName) + ": " + ex.Message, ex);
                            }
                        }
                        if (newObjectKey >= 0 && !lateSet)
                        {
                            source.NetCache.SetKeyedObject(newObjectKey, value);
                            if (newTypeKey >= 0) source.NetCache.SetKeyedObject(newTypeKey, type);
                        }
                        object oldValue = value;
                        if (isString)
                        {
                            value = source.ReadString();
                        }
                        else
                        {
                            value = ProtoReader.ReadTypedObject(oldValue, key, source, type);
                        }
                        
                        if (newObjectKey >= 0 && lateSet)
                        {
                            source.NetCache.SetKeyedObject(newObjectKey, value);
                            if (newTypeKey >= 0) source.NetCache.SetKeyedObject(newTypeKey, type);
                        }
						if (newObjectKey >= 0 && !lateSet && !ReferenceEquals(oldValue, value) && type.FullName.StartsWith("System.Collections.Generic.Dictionary`2"))
                        {
                            throw new ProtoException("A reference-tracked object changed reference during deserialization");
                        }
                        if (newObjectKey < 0 && newTypeKey >= 0)
                        {  // have a new type, but not a new object
                            source.NetCache.SetKeyedObject(newTypeKey, type);
                        }
                        break;
                    default:
                        source.SkipField();
                        break;
                }
            }
            if(newObjectKey >= 0 && (options & NetObjectOptions.AsReference) == 0)
            {
                throw new ProtoException("Object key in input stream, but reference-tracking was not expected");
            }
            ProtoReader.EndSubItem(token, source);

            return value;
        }
Example #3
0
        /// <summary>
        /// Reads an *implementation specific* bundled .NET object, including (as options) type-metadata, identity/re-use, etc.
        /// </summary>
        public static object ReadNetObject(object value, ProtoReader source, int key, Type type, NetObjectOptions options)
        {
#if FEAT_IKVM
            throw new NotSupportedException();
#else
            SubItemToken token = ProtoReader.StartSubItem(source);
            int fieldNumber;
            int newObjectKey = -1, newTypeKey = -1, tmp;
            while ((fieldNumber = source.ReadFieldHeader()) > 0)
            {
                switch (fieldNumber)
                {
                    case FieldExistingObjectKey:
                        tmp = source.ReadInt32();
                        value = source.NetCache.GetKeyedObject(tmp);
                        break;
                    case FieldNewObjectKey:
                        newObjectKey = source.ReadInt32();
                        break;
                    case FieldExistingTypeKey:
                        tmp = source.ReadInt32();
                        type = (Type)source.NetCache.GetKeyedObject(tmp);
                        key = source.GetTypeKey(ref type);
                        break;
                    case FieldNewTypeKey:
                        newTypeKey = source.ReadInt32();
                        break;
                    case FieldTypeName:
                        string typeName = source.ReadString();
                        type = source.DeserializeType(typeName);
                        if(type == null)
                        {
                            throw new ProtoException("Unable to resolve type: " + typeName + " (you can use the TypeModel.DynamicTypeFormatting event to provide a custom mapping)");
                        }
                        if (type == typeof(string))
                        {
                            key = -1;
                        }
                        else
                        {
                            key = source.GetTypeKey(ref type);
                            if (key < 0)
                                throw new InvalidOperationException("Dynamic type is not a contract-type: " + type.Name);
                        }
                        break;
                    case FieldObject:
                        bool isString = type == typeof(string);
                        bool wasNull = value == null;
                        bool lateSet = wasNull && (isString || ((options & NetObjectOptions.LateSet) != 0));
                        
                        if (newObjectKey >= 0 && !lateSet)
                        {
                            if (value == null)
                            {
                                source.TrapNextObject(newObjectKey);
                            }
                            else
                            {
                                source.NetCache.SetKeyedObject(newObjectKey, value);
                            }
                            if (newTypeKey >= 0) source.NetCache.SetKeyedObject(newTypeKey, type);
                        }
                        object oldValue = value;
                        if (isString)
                        {
                            value = source.ReadString();
                        }
                        else
                        {
                            value = ProtoReader.ReadTypedObject(oldValue, key, source, type);
                        }
                        
                        if (newObjectKey >= 0)
                        {
                            if(wasNull && !lateSet)
                            { // this both ensures (via exception) that it *was* set, and makes sure we don't shout
                                // about changed references
                                oldValue = source.NetCache.GetKeyedObject(newObjectKey);
                            }
                            if (lateSet)
                            {
                                source.NetCache.SetKeyedObject(newObjectKey, value);
                                if (newTypeKey >= 0) source.NetCache.SetKeyedObject(newTypeKey, type);
                            }
                        }
                        if (newObjectKey >= 0 && !lateSet && !ReferenceEquals(oldValue, value))
                        {
                            throw new ProtoException("A reference-tracked object changed reference during deserialization");
                        }
                        if (newObjectKey < 0 && newTypeKey >= 0)
                        {  // have a new type, but not a new object
                            source.NetCache.SetKeyedObject(newTypeKey, type);
                        }
                        break;
                    default:
                        source.SkipField();
                        break;
                }
            }
            if(newObjectKey >= 0 && (options & NetObjectOptions.AsReference) == 0)
            {
                throw new ProtoException("Object key in input stream, but reference-tracking was not expected");
            }
            ProtoReader.EndSubItem(token, source);

            return value;
#endif
        }
Example #4
0
        /// <summary>
        /// Reads an *implementation specific* bundled .NET object, including (as options) type-metadata, identity/re-use, etc.
        /// </summary>
        public static object ReadNetObject(object value, ProtoReader source, int key, Type type, NetObjectOptions options)
        {
            SubItemToken token = ProtoReader.StartSubItem(source);
            int fieldNumber;
            int newObjectKey = -1, newTypeKey = -1, tmp;
            while ((fieldNumber = source.ReadFieldHeader()) > 0)
            {
                switch (fieldNumber)
                {
                    case FieldExistingObjectKey:
                        tmp = source.ReadInt32();
                        value = source.NetCache.GetKeyedObject(tmp);
                        break;
                    case FieldNewObjectKey:
                        newObjectKey = source.ReadInt32();
                        break;
                    case FieldExistingTypeKey:
                        tmp = source.ReadInt32();
                        type = (Type)source.NetCache.GetKeyedObject(tmp);
                        key = source.GetTypeKey(ref type);
                        break;
                    case FieldNewTypeKey:
                        newTypeKey = source.ReadInt32();
                        break;
                    case FieldTypeName:
                        type = source.DeserializeType(source.ReadString());
                        key = source.GetTypeKey(ref type);
                        break;
                    case FieldObject:
                        bool isString = type == typeof(string);
                        bool lateSet = value == null && isString;
                        if (value == null && !lateSet)
                        {
                            value = ((options & NetObjectOptions.UseConstructor) == 0) ? BclHelpers.GetUninitializedObject(type) : Activator.CreateInstance(type);
                        }
                        if (newObjectKey >= 0 && !lateSet)
                        {
                            source.NetCache.SetKeyedObject(newObjectKey, value);
                            if (newTypeKey >= 0) source.NetCache.SetKeyedObject(newTypeKey, type);
                        }
                        object oldValue = value;
                        if (isString)
                        {
                            value = source.ReadString();
                        }
                        else
                        {
                            value = ProtoReader.ReadTypedObject(oldValue, key, source, type);
                        }

                        if (newObjectKey >= 0 && lateSet)
                        {
                            source.NetCache.SetKeyedObject(newObjectKey, value);
                            if (newTypeKey >= 0) source.NetCache.SetKeyedObject(newTypeKey, type);
                        }
                        if (!lateSet && !ReferenceEquals(oldValue, value))
                        {
                            throw new ProtoException("A reference-tracked object changed reference during deserialization");
                        }
                        break;
                    default:
                        source.SkipField();
                        break;
                }
            }
            ProtoReader.EndSubItem(token, source);

            return value;
        }
Example #5
0
        /// <summary>
        /// Writes an *implementation specific* bundled .NET object, including (as options) type-metadata, identity/re-use, etc.
        /// </summary>
        public static void WriteNetObject(object value, ProtoWriter dest, int key, NetObjectOptions options)
        {
            Helpers.DebugAssert(value != null);
            bool dynamicType = (options & NetObjectOptions.DynamicType) != 0,
                 asReference = (options & NetObjectOptions.AsReference) != 0;
            WireType wireType = dest.WireType;
            SubItemToken token = ProtoWriter.StartSubItem(null, dest);
            bool writeObject = true;
            if (asReference)
            {
                bool existing;
                int objectKey = dest.NetCache.AddObjectKey(value, out existing);
                ProtoWriter.WriteFieldHeader(existing ? FieldExistingObjectKey : FieldNewObjectKey, WireType.Variant, dest);
                ProtoWriter.WriteInt32(objectKey, dest);
                if (existing)
                {
                    writeObject = false;
                }
            }

            if (writeObject)
            {
                if (dynamicType)
                {
                    bool existing;
                    Type type = value.GetType();
                    key = dest.GetTypeKey(ref type);
                    int typeKey = dest.NetCache.AddObjectKey(type, out existing);
                    ProtoWriter.WriteFieldHeader(existing ? FieldExistingTypeKey : FieldNewTypeKey, WireType.Variant, dest);
                    ProtoWriter.WriteInt32(typeKey, dest);
                    if (!existing)
                    {
                        ProtoWriter.WriteFieldHeader(FieldTypeName, WireType.String, dest);
                        ProtoWriter.WriteString(dest.SerializeType(type), dest);
                    }
                    
                }
                ProtoWriter.WriteFieldHeader(FieldObject, wireType, dest);
                if (value is string)
                {
                    ProtoWriter.WriteString((string)value, dest);
                }
                else { 
                    ProtoWriter.WriteObject(value, key, dest);
                }
            }
            ProtoWriter.EndSubItem(token, dest);
        }
Example #6
0
        /// <summary>
        /// Reads an *implementation specific* bundled .NET object, including (as options) type-metadata, identity/re-use, etc.
        /// </summary>
        public static object ReadNetObject(object value, ProtoReader source, int key, Type type, NetObjectOptions options)
        {
            SubItemToken token = ProtoReader.StartSubItem(source);
            int          fieldNumber;
            int          newObjectKey = -1, newTypeKey = -1, tmp;

            while ((fieldNumber = source.ReadFieldHeader()) > 0)
            {
                switch (fieldNumber)
                {
                case FieldExistingObjectKey:
                    tmp   = source.ReadInt32();
                    value = source.NetCache.GetKeyedObject(tmp);
                    break;

                case FieldNewObjectKey:
                    newObjectKey = source.ReadInt32();
                    break;

                case FieldExistingTypeKey:
                    tmp  = source.ReadInt32();
                    type = (Type)source.NetCache.GetKeyedObject(tmp);
                    key  = source.GetTypeKey(ref type);
                    break;

                case FieldNewTypeKey:
                    newTypeKey = source.ReadInt32();
                    break;

                case FieldTypeName:
                    type = source.DeserializeType(source.ReadString());
                    key  = source.GetTypeKey(ref type);
                    break;

                case FieldObject:
                    bool isString = type == typeof(string);
                    bool lateSet  = value == null && isString;
                    if (value == null && !lateSet)
                    {
                        value = ((options & NetObjectOptions.UseConstructor) == 0) ? BclHelpers.GetUninitializedObject(type) : Activator.CreateInstance(type);
                    }
                    if (newObjectKey >= 0 && !lateSet)
                    {
                        source.NetCache.SetKeyedObject(newObjectKey, value);
                        if (newTypeKey >= 0)
                        {
                            source.NetCache.SetKeyedObject(newTypeKey, type);
                        }
                    }
                    object oldValue = value;
                    if (isString)
                    {
                        value = source.ReadString();
                    }
                    else
                    {
                        value = ProtoReader.ReadTypedObject(oldValue, key, source, type);
                    }

                    if (newObjectKey >= 0 && lateSet)
                    {
                        source.NetCache.SetKeyedObject(newObjectKey, value);
                        if (newTypeKey >= 0)
                        {
                            source.NetCache.SetKeyedObject(newTypeKey, type);
                        }
                    }
                    if (!lateSet && !ReferenceEquals(oldValue, value))
                    {
                        throw new ProtoException("A reference-tracked object changed reference during deserialization");
                    }
                    break;

                default:
                    source.SkipField();
                    break;
                }
            }
            ProtoReader.EndSubItem(token, source);

            return(value);
        }
Example #7
0
        /// <summary>
        /// Writes an *implementation specific* bundled .NET object, including (as options) type-metadata, identity/re-use, etc.
        /// </summary>
        public static void WriteNetObject(object value, ProtoWriter dest, int key, NetObjectOptions options)
        {
#if FEAT_IKVM
            throw new NotSupportedException();
#else
            if (dest == null)
            {
                throw new ArgumentNullException("dest");
            }
            bool dynamicType         = (options & NetObjectOptions.DynamicType) != 0,
                 asReference         = (options & NetObjectOptions.AsReference) != 0;
            WireType     wireType    = dest.WireType;
            SubItemToken token       = ProtoWriter.StartSubItem(null, dest);
            bool         writeObject = true;
            if (asReference)
            {
                bool existing;
                int  objectKey = dest.NetCache.AddObjectKey(value, out existing);
                ProtoWriter.WriteFieldHeader(existing ? FieldExistingObjectKey : FieldNewObjectKey, WireType.Variant, dest);
                ProtoWriter.WriteInt32(objectKey, dest);
                if (existing)
                {
                    writeObject = false;
                }
            }

            if (writeObject)
            {
                if (dynamicType)
                {
                    bool existing;
                    Type type = value.GetType();

                    if (!(value is string))
                    {
                        key = dest.GetTypeKey(ref type);
                        if (key < 0)
                        {
                            throw new InvalidOperationException("Dynamic type is not a contract-type: " + type.Name);
                        }
                    }
                    int typeKey = dest.NetCache.AddObjectKey(type, out existing);
                    ProtoWriter.WriteFieldHeader(existing ? FieldExistingTypeKey : FieldNewTypeKey, WireType.Variant, dest);
                    ProtoWriter.WriteInt32(typeKey, dest);
                    if (!existing)
                    {
                        ProtoWriter.WriteFieldHeader(FieldTypeName, WireType.String, dest);
                        ProtoWriter.WriteString(dest.SerializeType(type), dest);
                    }
                }
                ProtoWriter.WriteFieldHeader(FieldObject, wireType, dest);
                if (value is string)
                {
                    ProtoWriter.WriteString((string)value, dest);
                }
                else
                {
                    ProtoWriter.WriteObject(value, key, dest);
                }
            }
            ProtoWriter.EndSubItem(token, dest);
#endif
        }
Example #8
0
        /// <summary>
        /// Reads an *implementation specific* bundled .NET object, including (as options) type-metadata, identity/re-use, etc.
        /// </summary>
        public static object ReadNetObject(object value, ProtoReader source, int key, Type type, NetObjectOptions options)
        {
#if FEAT_IKVM
            throw new NotSupportedException();
#else
            SubItemToken token = ProtoReader.StartSubItem(source);
            int          fieldNumber;
            int          newObjectKey = -1, newTypeKey = -1, tmp;
            while ((fieldNumber = source.ReadFieldHeader()) > 0)
            {
                switch (fieldNumber)
                {
                case FieldExistingObjectKey:
                    tmp   = source.ReadInt32();
                    value = source.NetCache.GetKeyedObject(tmp);
                    break;

                case FieldNewObjectKey:
                    newObjectKey = source.ReadInt32();
                    break;

                case FieldExistingTypeKey:
                    tmp  = source.ReadInt32();
                    type = (Type)source.NetCache.GetKeyedObject(tmp);
                    key  = source.GetTypeKey(ref type);
                    break;

                case FieldNewTypeKey:
                    newTypeKey = source.ReadInt32();
                    break;

                case FieldTypeName:
                    string typeName = source.ReadString();
                    type = source.DeserializeType(typeName);
                    if (type == null)
                    {
                        throw new ProtoException("Unable to resolve type: " + typeName + " (you can use the TypeModel.DynamicTypeFormatting event to provide a custom mapping)");
                    }
                    if (type == typeof(string))
                    {
                        key = -1;
                    }
                    else
                    {
                        key = source.GetTypeKey(ref type);
                        if (key < 0)
                        {
                            throw new InvalidOperationException("Dynamic type is not a contract-type: " + type.Name);
                        }
                    }
                    break;

                case FieldObject:
                    bool isString = type == typeof(string);
                    bool wasNull  = value == null;
                    bool lateSet  = wasNull && (isString || ((options & NetObjectOptions.LateSet) != 0));

                    if (newObjectKey >= 0 && !lateSet)
                    {
                        if (value == null)
                        {
                            source.TrapNextObject(newObjectKey);
                        }
                        else
                        {
                            source.NetCache.SetKeyedObject(newObjectKey, value);
                        }
                        if (newTypeKey >= 0)
                        {
                            source.NetCache.SetKeyedObject(newTypeKey, type);
                        }
                    }
                    object oldValue = value;
                    if (isString)
                    {
                        value = source.ReadString();
                    }
                    else
                    {
                        value = ProtoReader.ReadTypedObject(oldValue, key, source, type);
                    }

                    if (newObjectKey >= 0)
                    {
                        if (wasNull && !lateSet)
                        {     // this both ensures (via exception) that it *was* set, and makes sure we don't shout
                            // about changed references
                            oldValue = source.NetCache.GetKeyedObject(newObjectKey);
                        }
                        if (lateSet)
                        {
                            source.NetCache.SetKeyedObject(newObjectKey, value);
                            if (newTypeKey >= 0)
                            {
                                source.NetCache.SetKeyedObject(newTypeKey, type);
                            }
                        }
                    }
                    if (newObjectKey >= 0 && !lateSet && !ReferenceEquals(oldValue, value))
                    {
                        throw new ProtoException("A reference-tracked object changed reference during deserialization");
                    }
                    if (newObjectKey < 0 && newTypeKey >= 0)
                    {      // have a new type, but not a new object
                        source.NetCache.SetKeyedObject(newTypeKey, type);
                    }
                    break;

                default:
                    source.SkipField();
                    break;
                }
            }
            if (newObjectKey >= 0 && (options & NetObjectOptions.AsReference) == 0)
            {
                throw new ProtoException("Object key in input stream, but reference-tracking was not expected");
            }
            ProtoReader.EndSubItem(token, source);

            return(value);
#endif
        }
Example #9
0
        public static object ReadNetObject(object value, ProtoReader source, int key, Type type, NetObjectOptions options)
        {
            SubItemToken token = ProtoReader.StartSubItem(source);
            int          num   = -1;
            int          num2  = -1;
            int          num3;

            while ((num3 = source.ReadFieldHeader()) > 0)
            {
                switch (num3)
                {
                case 1:
                {
                    int key2 = source.ReadInt32();
                    value = source.NetCache.GetKeyedObject(key2);
                    break;
                }

                case 2:
                    num = source.ReadInt32();
                    break;

                case 3:
                {
                    int key2 = source.ReadInt32();
                    type = (Type)source.NetCache.GetKeyedObject(key2);
                    key  = source.GetTypeKey(ref type);
                    break;
                }

                case 4:
                    num2 = source.ReadInt32();
                    break;

                case 8:
                {
                    string text = source.ReadString();
                    type = source.DeserializeType(text);
                    if (type == null)
                    {
                        throw new ProtoException("Unable to resolve type: " + text + " (you can use the TypeModel.DynamicTypeFormatting event to provide a custom mapping)");
                    }
                    if (type == typeof(string))
                    {
                        key = -1;
                        break;
                    }
                    key = source.GetTypeKey(ref type);
                    if (key >= 0)
                    {
                        break;
                    }
                    throw new InvalidOperationException("Dynamic type is not a contract-type: " + type.Name);
                }

                case 10:
                {
                    bool flag  = type == typeof(string);
                    bool flag2 = value == null;
                    bool flag3 = flag2 && (flag || (options & NetObjectOptions.LateSet) != NetObjectOptions.None);
                    if (num >= 0 && !flag3)
                    {
                        if (value == null)
                        {
                            source.TrapNextObject(num);
                        }
                        else
                        {
                            source.NetCache.SetKeyedObject(num, value);
                        }
                        if (num2 >= 0)
                        {
                            source.NetCache.SetKeyedObject(num2, type);
                        }
                    }
                    object obj = value;
                    value = ((!flag) ? ProtoReader.ReadTypedObject(obj, key, source, type) : source.ReadString());
                    if (num >= 0)
                    {
                        if (flag2 && !flag3)
                        {
                            obj = source.NetCache.GetKeyedObject(num);
                        }
                        if (flag3)
                        {
                            source.NetCache.SetKeyedObject(num, value);
                            if (num2 >= 0)
                            {
                                source.NetCache.SetKeyedObject(num2, type);
                            }
                        }
                    }
                    if (num >= 0 && !flag3 && obj != value)
                    {
                        throw new ProtoException("A reference-tracked object changed reference during deserialization");
                    }
                    if (num < 0 && num2 >= 0)
                    {
                        source.NetCache.SetKeyedObject(num2, type);
                    }
                    break;
                }

                default:
                    source.SkipField();
                    break;
                }
            }
            if (num >= 0 && (options & NetObjectOptions.AsReference) == NetObjectOptions.None)
            {
                throw new ProtoException("Object key in input stream, but reference-tracking was not expected");
            }
            ProtoReader.EndSubItem(token, source);
            return(value);
        }
Example #10
0
        public static object ReadNetObject(object value, ProtoReader source, int key, Type type, NetObjectOptions options)
        {
            int          num;
            SubItemToken token        = ProtoReader.StartSubItem(source);
            int          newObjectKey = -1;
            int          num3         = -1;

            while ((num = source.ReadFieldHeader()) > 0)
            {
                int    num4;
                bool   flag;
                bool   flag2;
                bool   flag3;
                object keyedObject;
                switch (num)
                {
                case 1:
                {
                    num4  = source.ReadInt32();
                    value = source.NetCache.GetKeyedObject(num4);
                    continue;
                }

                case 2:
                {
                    newObjectKey = source.ReadInt32();
                    continue;
                }

                case 3:
                {
                    num4 = source.ReadInt32();
                    type = (Type)source.NetCache.GetKeyedObject(num4);
                    key  = source.GetTypeKey(ref type);
                    continue;
                }

                case 4:
                {
                    num3 = source.ReadInt32();
                    continue;
                }

                case 8:
                {
                    string str = source.ReadString();
                    type = source.DeserializeType(str);
                    if (type == null)
                    {
                        throw new ProtoException("Unable to resolve type: " + str + " (you can use the TypeModel.DynamicTypeFormatting event to provide a custom mapping)");
                    }
                    break;
                }

                case 10:
                    flag  = type == typeof(string);
                    flag2 = value == null;
                    flag3 = flag2 && (flag || (((byte)(options & NetObjectOptions.LateSet)) != 0));
                    if ((newObjectKey < 0) || flag3)
                    {
                        goto Label_0180;
                    }
                    if (value != null)
                    {
                        goto Label_0162;
                    }
                    source.TrapNextObject(newObjectKey);
                    goto Label_016F;

                default:
                    goto Label_020D;
                }
                if (type == typeof(string))
                {
                    key = -1;
                    continue;
                }
                key = source.GetTypeKey(ref type);
                if (key >= 0)
                {
                    continue;
                }
                throw new InvalidOperationException("Dynamic type is not a contract-type: " + type.Name);
Label_0162:
                source.NetCache.SetKeyedObject(newObjectKey, value);
Label_016F:
                if (num3 >= 0)
                {
                    source.NetCache.SetKeyedObject(num3, type);
                }
Label_0180:
                keyedObject = value;
                if (flag)
                {
                    value = source.ReadString();
                }
                else
                {
                    value = ProtoReader.ReadTypedObject(keyedObject, key, source, type);
                }
                if (newObjectKey >= 0)
                {
                    if (flag2 && !flag3)
                    {
                        keyedObject = source.NetCache.GetKeyedObject(newObjectKey);
                    }
                    if (flag3)
                    {
                        source.NetCache.SetKeyedObject(newObjectKey, value);
                        if (num3 >= 0)
                        {
                            source.NetCache.SetKeyedObject(num3, type);
                        }
                    }
                }
                if (((newObjectKey >= 0) && !flag3) && !object.ReferenceEquals(keyedObject, value))
                {
                    throw new ProtoException("A reference-tracked object changed reference during deserialization");
                }
                if ((newObjectKey < 0) && (num3 >= 0))
                {
                    source.NetCache.SetKeyedObject(num3, type);
                }
                continue;
Label_020D:
                source.SkipField();
            }
            if ((newObjectKey >= 0) && (((byte)(options & NetObjectOptions.AsReference)) == 0))
            {
                throw new ProtoException("Object key in input stream, but reference-tracking was not expected");
            }
            ProtoReader.EndSubItem(token, source);
            return(value);
        }