示例#1
0
 public static TypeTag GetTypeTag(Type type)
 {
     if (type == typeof(string))
     {
         return(TypeTag.String);
     }
     else if (BinaryCommon.IsPrimitive(type))
     {
         return(TypeTag.PrimitiveType);
     }
     else if (type == typeof(object))
     {
         return(TypeTag.ObjectType);
     }
     else if (type.IsArray && type.GetArrayRank() == 1 && type.GetElementType() == typeof(object))
     {
         return(TypeTag.ArrayOfObject);
     }
     else if (type.IsArray && type.GetArrayRank() == 1 && type.GetElementType() == typeof(string))
     {
         return(TypeTag.ArrayOfString);
     }
     else if (type.IsArray && type.GetArrayRank() == 1 && BinaryCommon.IsPrimitive(type.GetElementType()))
     {
         return(TypeTag.ArrayOfPrimitiveType);
     }
     else if (type.Assembly == CorlibAssembly)
     {
         return(TypeTag.RuntimeType);
     }
     else
     {
         return(TypeTag.GenericType);
     }
 }
示例#2
0
        private static void EmitWriteTypeSpec(ILGenerator gen, Type type, string member)
        {
            switch (ObjectWriter.GetTypeTag(type))
            {
            case TypeTag.PrimitiveType:
                gen.Emit(OpCodes.Ldarg_2);
                gen.Emit(OpCodes.Ldc_I4_S, BinaryCommon.GetTypeCode(type));
                CodeGenerator.EmitWrite(gen, typeof(byte));
                break;

            case TypeTag.RuntimeType:
                gen.Emit(OpCodes.Ldarg_2);
                gen.Emit(OpCodes.Ldstr, type.FullName);
                CodeGenerator.EmitWrite(gen, typeof(string));
                break;

            case TypeTag.GenericType:
                gen.Emit(OpCodes.Ldarg_2);
                gen.Emit(OpCodes.Ldstr, type.FullName);
                CodeGenerator.EmitWrite(gen, typeof(string));
                gen.Emit(OpCodes.Ldarg_2);
                gen.Emit(OpCodes.Ldarg_1);
                CodeGenerator.EmitLoadTypeAssembly(gen, type, member);
                gen.EmitCall(OpCodes.Callvirt, typeof(ObjectWriter).GetMethod("GetAssemblyId"), null);
                gen.Emit(OpCodes.Conv_I4);
                CodeGenerator.EmitWrite(gen, typeof(int));
                break;

            case TypeTag.ArrayOfPrimitiveType:
                gen.Emit(OpCodes.Ldarg_2);
                gen.Emit(OpCodes.Ldc_I4_S, BinaryCommon.GetTypeCode(type.GetElementType()));
                CodeGenerator.EmitWrite(gen, typeof(byte));
                break;
            }
        }
示例#3
0
        private void WriteArray(BinaryWriter writer, long id, Array array)
        {
            // There are 4 ways of serializing arrays:
            // The element GenericArray (7) can be used for all arrays.
            // The element ArrayOfPrimitiveType (15) can be used for single-dimensional
            // arrays of primitive types
            // The element ArrayOfObject (16) can be used for single-dimensional Object arrays
            // The element ArrayOfString (17) can be used for single-dimensional string arrays

            Type elementType = array.GetType().GetElementType();

            if (elementType == typeof(object) && array.Rank == 1)
            {
                WriteObjectArray(writer, id, array);
            }
            else if (elementType == typeof(string) && array.Rank == 1)
            {
                WriteStringArray(writer, id, array);
            }
            else if (BinaryCommon.IsPrimitive(elementType) && array.Rank == 1)
            {
                WritePrimitiveTypeArray(writer, id, array);
            }
            else
            {
                WriteGenericArray(writer, id, array);
            }
        }
示例#4
0
        private void BlockWrite(BinaryWriter writer, Array array, int dataSize)
        {
            int totalSize = Buffer.ByteLength(array);

            if (arrayBuffer == null || (totalSize > arrayBuffer.Length && arrayBuffer.Length != ArrayBufferLength))
            {
                arrayBuffer = new byte [totalSize <= ArrayBufferLength ? totalSize : ArrayBufferLength];
            }

            int pos = 0;

            while (totalSize > 0)
            {
                int size = totalSize < arrayBuffer.Length ? totalSize : arrayBuffer.Length;
                Buffer.BlockCopy(array, pos, arrayBuffer, 0, size);

                if (!BitConverter.IsLittleEndian && dataSize > 1)
                {
                    BinaryCommon.SwapBytes(arrayBuffer, size, dataSize);
                }

                writer.Write(arrayBuffer, 0, size);
                totalSize -= size;
                pos       += size;
            }
        }
示例#5
0
        private void BlockRead(BinaryReader reader, Array array, int dataSize)
        {
            int i = Buffer.ByteLength(array);

            if (this.arrayBuffer == null || (i > this.arrayBuffer.Length && this.arrayBuffer.Length != this.ArrayBufferLength))
            {
                this.arrayBuffer = new byte[(i > this.ArrayBufferLength) ? this.ArrayBufferLength : i];
            }
            int num = 0;

            while (i > 0)
            {
                int num2 = (i >= this.arrayBuffer.Length) ? this.arrayBuffer.Length : i;
                int num3 = 0;
                do
                {
                    int num4 = reader.Read(this.arrayBuffer, num3, num2 - num3);
                    if (num4 == 0)
                    {
                        break;
                    }
                    num3 += num4;
                }while (num3 < num2);
IL_A6:
                if (!BitConverter.IsLittleEndian && dataSize > 1)
                {
                    BinaryCommon.SwapBytes(this.arrayBuffer, num2, dataSize);
                }
                Buffer.BlockCopy(this.arrayBuffer, 0, array, num, num2);
                i   -= num2;
                num += num2;
                continue;
                goto IL_A6;
            }
        }
示例#6
0
        public Type ReadType(BinaryReader reader, TypeTag code)
        {
            switch (code)
            {
            case TypeTag.PrimitiveType:
                return(BinaryCommon.GetTypeFromCode(reader.ReadByte()));

            case TypeTag.String:
                return(typeof(string));

            case TypeTag.ObjectType:
                return(typeof(object));

            case TypeTag.RuntimeType:
            {
                string name = reader.ReadString();
#if NET_2_0
                // map MS.NET's System.RuntimeType to System.MonoType
                if (_context.State == StreamingContextStates.Remoting)
                {
                    if (name == "System.RuntimeType")
                    {
                        return(typeof(MonoType));
                    }
                    else if (name == "System.RuntimeType[]")
                    {
                        return(typeof(MonoType[]));
                    }
                }
#endif
                Type t = Type.GetType(name);
                if (t != null)
                {
                    return(t);
                }

                throw new SerializationException(String.Format("Could not find type '{0}'.", name));
            }

            case TypeTag.GenericType:
            {
                string name  = reader.ReadString();
                long   asmid = (long)reader.ReadUInt32();
                return(GetDeserializationType(asmid, name));
            }

            case TypeTag.ArrayOfObject:
                return(typeof(object[]));

            case TypeTag.ArrayOfString:
                return(typeof(string[]));

            case TypeTag.ArrayOfPrimitiveType:
                Type elementType = BinaryCommon.GetTypeFromCode(reader.ReadByte());
                return(Type.GetType(elementType.FullName + "[]"));

            default:
                throw new NotSupportedException("Unknow type tag");
            }
        }
示例#7
0
        private void BlockRead(BinaryReader reader, Array array, int dataSize)
        {
            int totalSize = Buffer.ByteLength(array);

            if (arrayBuffer == null || (totalSize > arrayBuffer.Length && arrayBuffer.Length != ArrayBufferLength))
            {
                arrayBuffer = new byte [totalSize <= ArrayBufferLength ? totalSize : ArrayBufferLength];
            }

            int pos = 0;

            while (totalSize > 0)
            {
                int size = totalSize < arrayBuffer.Length ? totalSize : arrayBuffer.Length;
                int ap   = 0;
                do
                {
                    int nr = reader.Read(arrayBuffer, ap, size - ap);
                    if (nr == 0)
                    {
                        break;
                    }
                    ap += nr;
                } while (ap < size);

                if (!BitConverter.IsLittleEndian && dataSize > 1)
                {
                    BinaryCommon.SwapBytes(arrayBuffer, size, dataSize);
                }

                Buffer.BlockCopy(arrayBuffer, 0, array, pos, size);
                totalSize -= size;
                pos       += size;
            }
        }
示例#8
0
        public Type ReadType(BinaryReader reader, TypeTag code)
        {
            switch (code)
            {
            case TypeTag.PrimitiveType:
                return(BinaryCommon.GetTypeFromCode((int)reader.ReadByte()));

            case TypeTag.String:
                return(typeof(string));

            case TypeTag.ObjectType:
                return(typeof(object));

            case TypeTag.RuntimeType:
            {
                string text = reader.ReadString();
                if (this._context.State == StreamingContextStates.Remoting)
                {
                    if (text == "System.RuntimeType")
                    {
                        return(typeof(MonoType));
                    }
                    if (text == "System.RuntimeType[]")
                    {
                        return(typeof(MonoType[]));
                    }
                }
                Type type = Type.GetType(text);
                if (type != null)
                {
                    return(type);
                }
                throw new SerializationException(string.Format("Could not find type '{0}'.", text));
            }

            case TypeTag.GenericType:
            {
                string className  = reader.ReadString();
                long   assemblyId = (long)((ulong)reader.ReadUInt32());
                return(this.GetDeserializationType(assemblyId, className));
            }

            case TypeTag.ArrayOfObject:
                return(typeof(object[]));

            case TypeTag.ArrayOfString:
                return(typeof(string[]));

            case TypeTag.ArrayOfPrimitiveType:
            {
                Type typeFromCode = BinaryCommon.GetTypeFromCode((int)reader.ReadByte());
                return(Type.GetType(typeFromCode.FullName + "[]"));
            }

            default:
                throw new NotSupportedException("Unknow type tag");
            }
        }
示例#9
0
        public void WriteValue(BinaryWriter writer, Type valueType, object val)
        {
            if (val == null)
            {
                BinaryCommon.CheckSerializable(valueType, _surrogateSelector, _context);
                writer.Write((byte)BinaryElement.NullValue);
            }
            else if (BinaryCommon.IsPrimitive(val.GetType()))
            {
                if (!BinaryCommon.IsPrimitive(valueType))
                {
                    // It is a boxed primitive type value
                    writer.Write((byte)BinaryElement.BoxedPrimitiveTypeValue);
                    WriteTypeSpec(writer, val.GetType());
                }
                WritePrimitiveValue(writer, val);
            }
            else if (valueType.IsValueType)
            {
                // Value types are written embedded in the containing object
                WriteObjectInstance(writer, val, true);
            }
            else if (val is string)
            {
                // Strings are written embedded, unless already registered
                bool firstTime;
                long id = _idGenerator.GetId(val, out firstTime);

                if (firstTime)
                {
                    WriteObjectInstance(writer, val, false);
                }
                else
                {
                    WriteObjectReference(writer, id);
                }
            }
            else
            {
                // It is a reference type. Write a forward reference and queue the
                // object to the pending object list (unless already written).

                bool firstTime;
                long id = _idGenerator.GetId(val, out firstTime);

                if (firstTime)
                {
                    _pendingObjects.Enqueue(val);
                }
                WriteObjectReference(writer, id);
            }
        }
示例#10
0
        public static void EmitWriteTypeSpec(ILGenerator gen, Type type, string member)
        {
            // WARNING Keep in sync with WriteTypeSpec

            switch (ObjectWriter.GetTypeTag(type))
            {
            case TypeTag.PrimitiveType:
                // EMIT writer.Write (BinaryCommon.GetTypeCode (type));
                gen.Emit(OpCodes.Ldarg_2);
                gen.Emit(OpCodes.Ldc_I4_S, (byte)BinaryCommon.GetTypeCode(type));
                EmitWrite(gen, typeof(byte));
                break;

            case TypeTag.RuntimeType:
                // EMIT writer.Write (type.FullName);
                gen.Emit(OpCodes.Ldarg_2);
                gen.Emit(OpCodes.Ldstr, type.FullName);
                EmitWrite(gen, typeof(string));
                break;

            case TypeTag.GenericType:
                // EMIT writer.Write (type.FullName);
                gen.Emit(OpCodes.Ldarg_2);
                gen.Emit(OpCodes.Ldstr, type.FullName);
                EmitWrite(gen, typeof(string));

                // EMIT writer.Write ((int)ow.GetAssemblyId (type.Assembly));
                gen.Emit(OpCodes.Ldarg_2);
                gen.Emit(OpCodes.Ldarg_1);
                EmitLoadTypeAssembly(gen, type, member);
                gen.EmitCall(OpCodes.Callvirt, typeof(ObjectWriter).GetMethod("GetAssemblyId"), null);
                gen.Emit(OpCodes.Conv_I4);
                EmitWrite(gen, typeof(int));
                break;

            case TypeTag.ArrayOfPrimitiveType:
                // EMIT writer.Write (BinaryCommon.GetTypeCode (type.GetElementType()));
                gen.Emit(OpCodes.Ldarg_2);
                gen.Emit(OpCodes.Ldc_I4_S, (byte)BinaryCommon.GetTypeCode(type.GetElementType()));
                EmitWrite(gen, typeof(byte));
                break;

            default:
                // Type spec not needed
                break;
            }
        }
示例#11
0
        public void WriteTypeSpec(BinaryWriter writer, Type type)
        {
            // WARNING Keep in sync with EmitWriteTypeSpec

            switch (GetTypeTag(type))
            {
            case TypeTag.PrimitiveType:
                writer.Write(BinaryCommon.GetTypeCode(type));
                break;

            case TypeTag.RuntimeType:
                string fullName = type.FullName;
#if NET_2_0
                // Map System.MonoType to MS.NET's System.RuntimeType,
                // when called in remoting context.
                // Note that this code does not need to be in sync with
                // EmitWriteTypeSpec because serializing a MethodCall
                // won't trigger the CodeGenerator.
                if (_context.State == StreamingContextStates.Remoting)
                {
                    if (type == typeof(System.MonoType))
                    {
                        fullName = "System.RuntimeType";
                    }
                    else if (type == typeof(System.MonoType[]))
                    {
                        fullName = "System.RuntimeType[]";
                    }
                }
#endif
                writer.Write(fullName);
                break;

            case TypeTag.GenericType:
                writer.Write(type.FullName);
                writer.Write((int)GetAssemblyId(type.Assembly));
                break;

            case TypeTag.ArrayOfPrimitiveType:
                writer.Write(BinaryCommon.GetTypeCode(type.GetElementType()));
                break;

            default:
                // Type spec not needed
                break;
            }
        }
示例#12
0
        private void ReadValue(BinaryReader reader, object parentObject, long parentObjectId, SerializationInfo info, Type valueType, string fieldName, MemberInfo memberInfo, int[] indices)
        {
            object obj;

            if (BinaryCommon.IsPrimitive(valueType))
            {
                obj = ObjectReader.ReadPrimitiveTypeValue(reader, valueType);
                this.SetObjectValue(parentObject, fieldName, memberInfo, info, obj, valueType, indices);
                return;
            }
            BinaryElement binaryElement = (BinaryElement)reader.ReadByte();

            if (binaryElement == BinaryElement.ObjectReference)
            {
                long childObjectId = (long)((ulong)reader.ReadUInt32());
                this.RecordFixup(parentObjectId, childObjectId, parentObject, info, fieldName, memberInfo, indices);
                return;
            }
            long num;
            SerializationInfo info2;

            this.ReadObject(binaryElement, reader, out num, out obj, out info2);
            bool flag = false;

            if (num != 0L)
            {
                if (obj.GetType().IsValueType)
                {
                    this.RecordFixup(parentObjectId, num, parentObject, info, fieldName, memberInfo, indices);
                    flag = true;
                }
                if (info == null && !(parentObject is Array))
                {
                    this.RegisterObject(num, obj, info2, parentObjectId, memberInfo, null);
                }
                else
                {
                    this.RegisterObject(num, obj, info2, parentObjectId, null, indices);
                }
            }
            if (!flag)
            {
                this.SetObjectValue(parentObject, fieldName, memberInfo, info, obj, valueType, indices);
            }
        }
示例#13
0
 public void WriteValue(BinaryWriter writer, Type valueType, object val)
 {
     if (val == null)
     {
         BinaryCommon.CheckSerializable(valueType, this._surrogateSelector, this._context);
         writer.Write(10);
     }
     else if (BinaryCommon.IsPrimitive(val.GetType()))
     {
         if (!BinaryCommon.IsPrimitive(valueType))
         {
             writer.Write(8);
             this.WriteTypeSpec(writer, val.GetType());
         }
         ObjectWriter.WritePrimitiveValue(writer, val);
     }
     else if (valueType.IsValueType)
     {
         this.WriteObjectInstance(writer, val, true);
     }
     else if (val is string)
     {
         bool flag;
         long id = this._idGenerator.GetId(val, out flag);
         if (flag)
         {
             this.WriteObjectInstance(writer, val, false);
         }
         else
         {
             this.WriteObjectReference(writer, id);
         }
     }
     else
     {
         bool flag2;
         long id2 = this._idGenerator.GetId(val, out flag2);
         if (flag2)
         {
             this._pendingObjects.Enqueue(val);
         }
         this.WriteObjectReference(writer, id2);
     }
 }
示例#14
0
        private void ReadObjectContent(BinaryReader reader, TypeMetadata metadata, long objectId, out object objectInstance, out SerializationInfo info)
        {
            if (_filterLevel == TypeFilterLevel.Low)
            {
                objectInstance = FormatterServices.GetSafeUninitializedObject(metadata.Type);
            }
            else
            {
                objectInstance = FormatterServices.GetUninitializedObject(metadata.Type);
            }
            _manager.RaiseOnDeserializingEvent(objectInstance);

            info = metadata.NeedsSerializationInfo ? new SerializationInfo(metadata.Type, new FormatterConverter()) : null;

            if (metadata.MemberNames != null)
            {
                for (int n = 0; n < metadata.FieldCount; n++)
                {
                    ReadValue(reader, objectInstance, objectId, info, metadata.MemberTypes[n], metadata.MemberNames[n], null, null);
                }
            }
            else
            {
                for (int n = 0; n < metadata.FieldCount; n++)
                {
                    if (metadata.MemberInfos [n] != null)
                    {
                        ReadValue(reader, objectInstance, objectId, info, metadata.MemberTypes[n], metadata.MemberInfos[n].Name, metadata.MemberInfos[n], null);
                    }
                    else if (BinaryCommon.IsPrimitive(metadata.MemberTypes[n]))
                    {
                        // Since the member info is null, the type in this
                        // domain does not have this type. Even though we
                        // are not going to store the value, we will read
                        // it from the stream so that we can advance to the
                        // next block.
                        ReadPrimitiveTypeValue(reader, metadata.MemberTypes[n]);
                    }
                }
            }
        }
示例#15
0
        private void WriteArray(BinaryWriter writer, long id, Array array)
        {
            Type elementType = array.GetType().GetElementType();

            if (elementType == typeof(object) && array.Rank == 1)
            {
                this.WriteObjectArray(writer, id, array);
            }
            else if (elementType == typeof(string) && array.Rank == 1)
            {
                this.WriteStringArray(writer, id, array);
            }
            else if (BinaryCommon.IsPrimitive(elementType) && array.Rank == 1)
            {
                this.WritePrimitiveTypeArray(writer, id, array);
            }
            else
            {
                this.WriteGenericArray(writer, id, array);
            }
        }
示例#16
0
        private void BlockWrite(BinaryWriter writer, Array array, int dataSize)
        {
            int i = Buffer.ByteLength(array);

            if (this.arrayBuffer == null || (i > this.arrayBuffer.Length && this.arrayBuffer.Length != this.ArrayBufferLength))
            {
                this.arrayBuffer = new byte[(i > this.ArrayBufferLength) ? this.ArrayBufferLength : i];
            }
            int num = 0;

            while (i > 0)
            {
                int num2 = (i >= this.arrayBuffer.Length) ? this.arrayBuffer.Length : i;
                Buffer.BlockCopy(array, num, this.arrayBuffer, 0, num2);
                if (!BitConverter.IsLittleEndian && dataSize > 1)
                {
                    BinaryCommon.SwapBytes(this.arrayBuffer, num2, dataSize);
                }
                writer.Write(this.arrayBuffer, 0, num2);
                i   -= num2;
                num += num2;
            }
        }
示例#17
0
        public void WriteTypeSpec(BinaryWriter writer, Type type)
        {
            switch (ObjectWriter.GetTypeTag(type))
            {
            case TypeTag.PrimitiveType:
                writer.Write(BinaryCommon.GetTypeCode(type));
                break;

            case TypeTag.RuntimeType:
            {
                string value = type.FullName;
                if (this._context.State == StreamingContextStates.Remoting)
                {
                    if (type == typeof(MonoType))
                    {
                        value = "System.RuntimeType";
                    }
                    else if (type == typeof(MonoType[]))
                    {
                        value = "System.RuntimeType[]";
                    }
                }
                writer.Write(value);
                break;
            }

            case TypeTag.GenericType:
                writer.Write(type.FullName);
                writer.Write(this.GetAssemblyId(type.Assembly));
                break;

            case TypeTag.ArrayOfPrimitiveType:
                writer.Write(BinaryCommon.GetTypeCode(type.GetElementType()));
                break;
            }
        }
        public static void WriteMethodResponse(BinaryWriter writer, object obj, Header[] headers, BinaryFormatter formatter)
        {
            IMethodReturnMessage resp = (IMethodReturnMessage)obj;

            writer.Write((byte)BinaryElement.MethodResponse);

            string[] internalProperties = MethodReturnDictionary.InternalReturnKeys;

            int    infoArrayLength = 0;
            object info            = null;

            object[] extraProperties = null;

            // Type of return value

            ReturnTypeTag returnTypeTag;
            MethodFlags   contextFlag = MethodFlags.ExcludeLogicalCallContext;

            if (resp.Exception != null)
            {
                returnTypeTag      = ReturnTypeTag.Exception | ReturnTypeTag.Null;
                internalProperties = MethodReturnDictionary.InternalExceptionKeys;
                infoArrayLength    = 1;
            }
            else if (resp.ReturnValue == null)
            {
                returnTypeTag = ReturnTypeTag.Null;
            }
            else if (IsMethodPrimitive(resp.ReturnValue.GetType()))
            {
                returnTypeTag = ReturnTypeTag.PrimitiveType;
            }
            else
            {
                returnTypeTag = ReturnTypeTag.ObjectType;
                infoArrayLength++;
            }

            // Message flags

            MethodFlags formatFlag;

            if ((resp.LogicalCallContext != null) && resp.LogicalCallContext.HasInfo)
            {
                contextFlag = MethodFlags.IncludesLogicalCallContext;
                infoArrayLength++;
            }

            if (resp.Properties.Count > internalProperties.Length && ((returnTypeTag & ReturnTypeTag.Exception) == 0))
            {
                extraProperties = GetExtraProperties(resp.Properties, internalProperties);
                infoArrayLength++;
            }

            if (resp.OutArgCount == 0)
            {
                formatFlag = MethodFlags.NoArguments;
            }
            else
            {
                if (AllTypesArePrimitive(resp.Args))
                {
                    formatFlag = MethodFlags.PrimitiveArguments;
                }
                else
                {
                    if (infoArrayLength == 0)
                    {
                        formatFlag = MethodFlags.ArgumentsInSimpleArray;
                    }
                    else
                    {
                        formatFlag = MethodFlags.ArgumentsInMultiArray;
                        infoArrayLength++;
                    }
                }
            }

            writer.Write((byte)(contextFlag | formatFlag));
            writer.Write((byte)returnTypeTag);

            // FIXME: what are the following 2 bytes for?
            writer.Write((byte)0);
            writer.Write((byte)0);

            // Arguments

            if (returnTypeTag == ReturnTypeTag.PrimitiveType)
            {
                writer.Write(BinaryCommon.GetTypeCode(resp.ReturnValue.GetType()));
                ObjectWriter.WritePrimitiveValue(writer, resp.ReturnValue);
            }

            if (formatFlag == MethodFlags.PrimitiveArguments)
            {
                writer.Write((uint)resp.ArgCount);
                for (int n = 0; n < resp.ArgCount; n++)
                {
                    object val = resp.GetArg(n);
                    if (val != null)
                    {
                        writer.Write(BinaryCommon.GetTypeCode(val.GetType()));
                        ObjectWriter.WritePrimitiveValue(writer, val);
                    }
                    else
                    {
                        writer.Write((byte)BinaryTypeCode.Null);
                    }
                }
            }

            if (infoArrayLength > 0)
            {
                object[] infoArray = new object[infoArrayLength];
                int      n         = 0;

                if ((returnTypeTag & ReturnTypeTag.Exception) != 0)
                {
                    infoArray[n++] = resp.Exception;
                }

                if (formatFlag == MethodFlags.ArgumentsInMultiArray)
                {
                    infoArray[n++] = resp.Args;
                }

                if (returnTypeTag == ReturnTypeTag.ObjectType)
                {
                    infoArray[n++] = resp.ReturnValue;
                }

                if (contextFlag == MethodFlags.IncludesLogicalCallContext)
                {
                    infoArray[n++] = resp.LogicalCallContext;
                }

                if (extraProperties != null)
                {
                    infoArray[n++] = extraProperties;
                }

                info = infoArray;
            }
            else if ((formatFlag & MethodFlags.ArgumentsInSimpleArray) > 0)
            {
                info = resp.Args;
            }

            if (info != null)
            {
                ObjectWriter objectWriter = new ObjectWriter(formatter);
                objectWriter.WriteObjectGraph(writer, info, headers);
            }
            else
            {
                writer.Write((byte)BinaryElement.End);
            }
        }
示例#19
0
        private void GetObjectData(object obj, out TypeMetadata metadata, out object data)
        {
            Type instanceType = obj.GetType();

            // Check if the formatter has a surrogate selector, if it does,
            // check if the surrogate selector handles objects of the given type.

            if (_surrogateSelector != null)
            {
                ISurrogateSelector      selector;
                ISerializationSurrogate surrogate = _surrogateSelector.GetSurrogate(instanceType, _context, out selector);
                if (surrogate != null)
                {
                    SerializationInfo info = new SerializationInfo(instanceType, new FormatterConverter());
                    surrogate.GetObjectData(obj, info, _context);
                    metadata = new SerializableTypeMetadata(instanceType, info);
                    data     = info;
                    return;
                }
            }

            // Check if the object is marked with the Serializable attribute

            BinaryCommon.CheckSerializable(instanceType, _surrogateSelector, _context);

#if NET_2_0
            _manager.RegisterObject(obj);
#endif

            ISerializable ser = obj as ISerializable;

            if (ser != null)
            {
                SerializationInfo info = new SerializationInfo(instanceType, new FormatterConverter());
                ser.GetObjectData(info, _context);
                metadata = new SerializableTypeMetadata(instanceType, info);
                data     = info;
            }
            else
            {
                data = obj;
                if (_context.Context != null)
                {
                    // Don't cache metadata info when the Context property is not null sice
                    // we can't control the number of possible contexts in this case
                    metadata = new MemberTypeMetadata(instanceType, _context);
                    return;
                }

                Hashtable typesTable;
                bool      isNew = false;
                lock (_cachedTypes) {
                    typesTable = (Hashtable)_cachedTypes [_context.State];
                    if (typesTable == null)
                    {
                        typesTable = new Hashtable();
                        _cachedTypes [_context.State] = typesTable;
                        isNew = true;
                    }
                }

                metadata = null;
                lock (typesTable) {
                    if (!isNew)
                    {
                        metadata = (TypeMetadata)typesTable [instanceType];
                    }

                    if (metadata == null)
                    {
                        metadata = CreateMemberTypeMetadata(instanceType);
                    }

                    typesTable [instanceType] = metadata;
                }
            }
        }
        public static void WriteMethodCall(BinaryWriter writer, object obj, Header[] headers, ISurrogateSelector surrogateSelector, StreamingContext context, FormatterAssemblyStyle assemblyFormat, FormatterTypeStyle typeFormat)
        {
            IMethodCallMessage methodCallMessage = (IMethodCallMessage)obj;

            writer.Write(21);
            int    num  = 0;
            object obj2 = null;

            object[]    array = null;
            MethodFlags methodFlags;

            if (methodCallMessage.LogicalCallContext != null && methodCallMessage.LogicalCallContext.HasInfo)
            {
                methodFlags = MethodFlags.IncludesLogicalCallContext;
                num++;
            }
            else
            {
                methodFlags = MethodFlags.ExcludeLogicalCallContext;
            }
            if (RemotingServices.IsMethodOverloaded(methodCallMessage))
            {
                num++;
                methodFlags |= MethodFlags.IncludesSignature;
            }
            if (methodCallMessage.Properties.Count > MethodCallDictionary.InternalKeys.Length)
            {
                array = MessageFormatter.GetExtraProperties(methodCallMessage.Properties, MethodCallDictionary.InternalKeys);
                num++;
            }
            if (methodCallMessage.MethodBase.IsGenericMethod)
            {
                num++;
                methodFlags |= MethodFlags.GenericArguments;
            }
            if (methodCallMessage.ArgCount == 0)
            {
                methodFlags |= MethodFlags.NoArguments;
            }
            else if (MessageFormatter.AllTypesArePrimitive(methodCallMessage.Args))
            {
                methodFlags |= MethodFlags.PrimitiveArguments;
            }
            else if (num == 0)
            {
                methodFlags |= MethodFlags.ArgumentsInSimpleArray;
            }
            else
            {
                methodFlags |= MethodFlags.ArgumentsInMultiArray;
                num++;
            }
            writer.Write((int)methodFlags);
            writer.Write(18);
            writer.Write(methodCallMessage.MethodName);
            writer.Write(18);
            writer.Write(methodCallMessage.TypeName);
            if ((methodFlags & MethodFlags.PrimitiveArguments) > (MethodFlags)0)
            {
                writer.Write((uint)methodCallMessage.Args.Length);
                for (int i = 0; i < methodCallMessage.ArgCount; i++)
                {
                    object arg = methodCallMessage.GetArg(i);
                    if (arg != null)
                    {
                        writer.Write(BinaryCommon.GetTypeCode(arg.GetType()));
                        ObjectWriter.WritePrimitiveValue(writer, arg);
                    }
                    else
                    {
                        writer.Write(17);
                    }
                }
            }
            if (num > 0)
            {
                object[] array2 = new object[num];
                int      num2   = 0;
                if ((methodFlags & MethodFlags.ArgumentsInMultiArray) > (MethodFlags)0)
                {
                    array2[num2++] = methodCallMessage.Args;
                }
                if ((methodFlags & MethodFlags.GenericArguments) > (MethodFlags)0)
                {
                    array2[num2++] = methodCallMessage.MethodBase.GetGenericArguments();
                }
                if ((methodFlags & MethodFlags.IncludesSignature) > (MethodFlags)0)
                {
                    array2[num2++] = methodCallMessage.MethodSignature;
                }
                if ((methodFlags & MethodFlags.IncludesLogicalCallContext) > (MethodFlags)0)
                {
                    array2[num2++] = methodCallMessage.LogicalCallContext;
                }
                if (array != null)
                {
                    array2[num2++] = array;
                }
                obj2 = array2;
            }
            else if ((methodFlags & MethodFlags.ArgumentsInSimpleArray) > (MethodFlags)0)
            {
                obj2 = methodCallMessage.Args;
            }
            if (obj2 != null)
            {
                ObjectWriter objectWriter = new ObjectWriter(surrogateSelector, context, assemblyFormat, typeFormat);
                objectWriter.WriteObjectGraph(writer, obj2, headers);
            }
            else
            {
                writer.Write(11);
            }
        }
        public static void WriteMethodResponse(BinaryWriter writer, object obj, Header[] headers, ISurrogateSelector surrogateSelector, StreamingContext context, FormatterAssemblyStyle assemblyFormat, FormatterTypeStyle typeFormat)
        {
            IMethodReturnMessage methodReturnMessage = (IMethodReturnMessage)obj;

            writer.Write(22);
            string[] array = MethodReturnDictionary.InternalReturnKeys;
            int      num   = 0;
            object   obj2  = null;

            object[]      array2      = null;
            MethodFlags   methodFlags = MethodFlags.ExcludeLogicalCallContext;
            ReturnTypeTag returnTypeTag;

            if (methodReturnMessage.Exception != null)
            {
                returnTypeTag = (ReturnTypeTag)34;
                array         = MethodReturnDictionary.InternalExceptionKeys;
                num           = 1;
            }
            else if (methodReturnMessage.ReturnValue == null)
            {
                returnTypeTag = ReturnTypeTag.Null;
            }
            else if (MessageFormatter.IsMethodPrimitive(methodReturnMessage.ReturnValue.GetType()))
            {
                returnTypeTag = ReturnTypeTag.PrimitiveType;
            }
            else
            {
                returnTypeTag = ReturnTypeTag.ObjectType;
                num++;
            }
            if (methodReturnMessage.LogicalCallContext != null && methodReturnMessage.LogicalCallContext.HasInfo)
            {
                methodFlags = MethodFlags.IncludesLogicalCallContext;
                num++;
            }
            if (methodReturnMessage.Properties.Count > array.Length && (byte)(returnTypeTag & ReturnTypeTag.Exception) == 0)
            {
                array2 = MessageFormatter.GetExtraProperties(methodReturnMessage.Properties, array);
                num++;
            }
            MethodFlags methodFlags2;

            if (methodReturnMessage.OutArgCount == 0)
            {
                methodFlags2 = MethodFlags.NoArguments;
            }
            else if (MessageFormatter.AllTypesArePrimitive(methodReturnMessage.Args))
            {
                methodFlags2 = MethodFlags.PrimitiveArguments;
            }
            else if (num == 0)
            {
                methodFlags2 = MethodFlags.ArgumentsInSimpleArray;
            }
            else
            {
                methodFlags2 = MethodFlags.ArgumentsInMultiArray;
                num++;
            }
            writer.Write((byte)(methodFlags | methodFlags2));
            writer.Write((byte)returnTypeTag);
            writer.Write(0);
            writer.Write(0);
            if (returnTypeTag == ReturnTypeTag.PrimitiveType)
            {
                writer.Write(BinaryCommon.GetTypeCode(methodReturnMessage.ReturnValue.GetType()));
                ObjectWriter.WritePrimitiveValue(writer, methodReturnMessage.ReturnValue);
            }
            if (methodFlags2 == MethodFlags.PrimitiveArguments)
            {
                writer.Write((uint)methodReturnMessage.ArgCount);
                for (int i = 0; i < methodReturnMessage.ArgCount; i++)
                {
                    object arg = methodReturnMessage.GetArg(i);
                    if (arg != null)
                    {
                        writer.Write(BinaryCommon.GetTypeCode(arg.GetType()));
                        ObjectWriter.WritePrimitiveValue(writer, arg);
                    }
                    else
                    {
                        writer.Write(17);
                    }
                }
            }
            if (num > 0)
            {
                object[] array3 = new object[num];
                int      num2   = 0;
                if ((byte)(returnTypeTag & ReturnTypeTag.Exception) != 0)
                {
                    array3[num2++] = methodReturnMessage.Exception;
                }
                if (methodFlags2 == MethodFlags.ArgumentsInMultiArray)
                {
                    array3[num2++] = methodReturnMessage.Args;
                }
                if (returnTypeTag == ReturnTypeTag.ObjectType)
                {
                    array3[num2++] = methodReturnMessage.ReturnValue;
                }
                if (methodFlags == MethodFlags.IncludesLogicalCallContext)
                {
                    array3[num2++] = methodReturnMessage.LogicalCallContext;
                }
                if (array2 != null)
                {
                    array3[num2++] = array2;
                }
                obj2 = array3;
            }
            else if ((methodFlags2 & MethodFlags.ArgumentsInSimpleArray) > (MethodFlags)0)
            {
                obj2 = methodReturnMessage.Args;
            }
            if (obj2 != null)
            {
                ObjectWriter objectWriter = new ObjectWriter(surrogateSelector, context, assemblyFormat, typeFormat);
                objectWriter.WriteObjectGraph(writer, obj2, headers);
            }
            else
            {
                writer.Write(11);
            }
        }
        public static object ReadMethodResponse(BinaryElement elem, BinaryReader reader, bool hasHeaders, HeaderHandler headerHandler, IMethodCallMessage methodCallMessage, BinaryFormatter formatter)
        {
            if (elem != BinaryElement.MethodResponse)
            {
                throw new SerializationException("Invalid format. Expected BinaryElement.MethodResponse, found " + elem);
            }

            MethodFlags   flags          = (MethodFlags)reader.ReadByte();
            ReturnTypeTag typeTag        = (ReturnTypeTag)reader.ReadByte();
            bool          hasContextInfo = (flags & MethodFlags.IncludesLogicalCallContext) > 0;

            // FIXME: find a meaning for those 2 bytes
            reader.ReadByte();
            reader.ReadByte();

            object returnValue = null;

            object[]           outArgs     = null;
            LogicalCallContext callContext = null;
            Exception          exception   = null;

            object[] extraProperties = null;
            Header[] headers         = null;

            if ((typeTag & ReturnTypeTag.PrimitiveType) > 0)
            {
                Type type = BinaryCommon.GetTypeFromCode(reader.ReadByte());
                returnValue = ObjectReader.ReadPrimitiveTypeValue(reader, type);
            }

            if ((flags & MethodFlags.PrimitiveArguments) > 0)
            {
                uint count = reader.ReadUInt32();
                outArgs = new object[count];
                for (int n = 0; n < count; n++)
                {
                    Type type = BinaryCommon.GetTypeFromCode(reader.ReadByte());
                    outArgs[n] = ObjectReader.ReadPrimitiveTypeValue(reader, type);
                }
            }

            if (hasContextInfo || (typeTag & ReturnTypeTag.ObjectType) > 0 ||
                (typeTag & ReturnTypeTag.Exception) > 0 ||
                (flags & MethodFlags.ArgumentsInSimpleArray) > 0 ||
                (flags & MethodFlags.ArgumentsInMultiArray) > 0)
            {
                // There objects that need to be deserialized using an ObjectReader

                ObjectReader objectReader = new ObjectReader(formatter);
                object       result;
                objectReader.ReadObjectGraph(reader, hasHeaders, out result, out headers);
                object[] msgInfo = (object[])result;

                if ((typeTag & ReturnTypeTag.Exception) > 0)
                {
                    exception = (Exception)msgInfo[0];
                    if (hasContextInfo)
                    {
                        callContext = (LogicalCallContext)msgInfo[1];
                    }
                }
                else if ((flags & MethodFlags.NoArguments) > 0 || (flags & MethodFlags.PrimitiveArguments) > 0)
                {
                    int n = 0;
                    if ((typeTag & ReturnTypeTag.ObjectType) > 0)
                    {
                        returnValue = msgInfo [n++];
                    }
                    if (hasContextInfo)
                    {
                        callContext = (LogicalCallContext)msgInfo[n++];
                    }
                    if (n < msgInfo.Length)
                    {
                        extraProperties = (object[])msgInfo[n];
                    }
                }
                else if ((flags & MethodFlags.ArgumentsInSimpleArray) > 0)
                {
                    outArgs = msgInfo;
                }
                else
                {
                    int n = 0;
                    outArgs = (object[])msgInfo[n++];
                    if ((typeTag & ReturnTypeTag.ObjectType) > 0)
                    {
                        returnValue = msgInfo[n++];
                    }
                    if (hasContextInfo)
                    {
                        callContext = (LogicalCallContext)msgInfo[n++];
                    }
                    if (n < msgInfo.Length)
                    {
                        extraProperties = (object[])msgInfo[n];
                    }
                }
            }
            else
            {
                reader.ReadByte(); // Reads the stream ender
            }

            if (headerHandler != null)
            {
                headerHandler(headers);
            }

            if (exception != null)
            {
                return(new ReturnMessage(exception, methodCallMessage));
            }
            else
            {
                int           argCount = (outArgs != null) ? outArgs.Length : 0;
                ReturnMessage result   = new ReturnMessage(returnValue, outArgs, argCount, callContext, methodCallMessage);

                if (extraProperties != null)
                {
                    foreach (DictionaryEntry entry in extraProperties)
                    {
                        result.Properties [(string)entry.Key] = entry.Value;
                    }
                }

                return(result);
            }
        }
        public static object ReadMethodCall(BinaryElement elem, BinaryReader reader, bool hasHeaders, HeaderHandler headerHandler, BinaryFormatter formatter)
        {
            if (elem != BinaryElement.MethodCall)
            {
                throw new SerializationException("Invalid format. Expected BinaryElement.MethodCall, found " + elem);
            }
            MethodFlags methodFlags = (MethodFlags)reader.ReadInt32();

            if (reader.ReadByte() != 18)
            {
                throw new SerializationException("Invalid format");
            }
            string value = reader.ReadString();

            if (reader.ReadByte() != 18)
            {
                throw new SerializationException("Invalid format");
            }
            string value2 = reader.ReadString();

            object[] array  = null;
            object   value3 = null;
            object   value4 = null;

            object[] array2  = null;
            Header[] headers = null;
            Type[]   value5  = null;
            if ((methodFlags & MethodFlags.PrimitiveArguments) > (MethodFlags)0)
            {
                uint num = reader.ReadUInt32();
                array = new object[num];
                int num2 = 0;
                while ((long)num2 < (long)((ulong)num))
                {
                    Type typeFromCode = BinaryCommon.GetTypeFromCode((int)reader.ReadByte());
                    array[num2] = ObjectReader.ReadPrimitiveTypeValue(reader, typeFromCode);
                    num2++;
                }
            }
            if ((methodFlags & MethodFlags.NeedsInfoArrayMask) > (MethodFlags)0)
            {
                ObjectReader objectReader = new ObjectReader(formatter);
                object       obj;
                objectReader.ReadObjectGraph(reader, hasHeaders, out obj, out headers);
                object[] array3 = (object[])obj;
                if ((methodFlags & MethodFlags.ArgumentsInSimpleArray) > (MethodFlags)0)
                {
                    array = array3;
                }
                else
                {
                    int num3 = 0;
                    if ((methodFlags & MethodFlags.ArgumentsInMultiArray) > (MethodFlags)0)
                    {
                        if (array3.Length > 1)
                        {
                            array = (object[])array3[num3++];
                        }
                        else
                        {
                            array = new object[0];
                        }
                    }
                    if ((methodFlags & MethodFlags.GenericArguments) > (MethodFlags)0)
                    {
                        value5 = (Type[])array3[num3++];
                    }
                    if ((methodFlags & MethodFlags.IncludesSignature) > (MethodFlags)0)
                    {
                        value3 = array3[num3++];
                    }
                    if ((methodFlags & MethodFlags.IncludesLogicalCallContext) > (MethodFlags)0)
                    {
                        value4 = array3[num3++];
                    }
                    if (num3 < array3.Length)
                    {
                        array2 = (object[])array3[num3];
                    }
                }
            }
            else
            {
                reader.ReadByte();
            }
            if (array == null)
            {
                array = new object[0];
            }
            string value6 = null;

            if (headerHandler != null)
            {
                value6 = (headerHandler(headers) as string);
            }
            MethodCall methodCall = new MethodCall(new Header[]
            {
                new Header("__MethodName", value),
                new Header("__MethodSignature", value3),
                new Header("__TypeName", value2),
                new Header("__Args", array),
                new Header("__CallContext", value4),
                new Header("__Uri", value6),
                new Header("__GenericArguments", value5)
            });

            if (array2 != null)
            {
                foreach (DictionaryEntry dictionaryEntry in array2)
                {
                    methodCall.Properties[(string)dictionaryEntry.Key] = dictionaryEntry.Value;
                }
            }
            return(methodCall);
        }
示例#24
0
        public static Type GenerateMetadataTypeInternal(Type type, StreamingContext context)
        {
            string text = type.Name + "__TypeMetadata";
            string str  = string.Empty;
            int    num  = 0;

            while (CodeGenerator._module.GetType(text + str) != null)
            {
                int num2;
                num = (num2 = num + 1);
                str = num2.ToString();
            }
            text += str;
            MemberInfo[] serializableMembers = FormatterServices.GetSerializableMembers(type, context);
            TypeBuilder  typeBuilder         = CodeGenerator._module.DefineType(text, TypeAttributes.Public, typeof(ClrTypeMetadata));

            Type[]             parameterTypes     = Type.EmptyTypes;
            ConstructorBuilder constructorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, parameterTypes);
            ConstructorInfo    constructor        = typeof(ClrTypeMetadata).GetConstructor(new Type[]
            {
                typeof(Type)
            });
            ILGenerator ilgenerator = constructorBuilder.GetILGenerator();

            ilgenerator.Emit(OpCodes.Ldarg_0);
            ilgenerator.Emit(OpCodes.Ldtoken, type);
            ilgenerator.EmitCall(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle"), null);
            ilgenerator.Emit(OpCodes.Call, constructor);
            ilgenerator.Emit(OpCodes.Ret);
            parameterTypes = new Type[]
            {
                typeof(ObjectWriter),
                typeof(BinaryWriter)
            };
            MethodBuilder methodBuilder = typeBuilder.DefineMethod("WriteAssemblies", MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.Virtual, typeof(void), parameterTypes);

            ilgenerator = methodBuilder.GetILGenerator();
            foreach (FieldInfo fieldInfo in serializableMembers)
            {
                Type type2 = fieldInfo.FieldType;
                while (type2.IsArray)
                {
                    type2 = type2.GetElementType();
                }
                if (type2.Assembly != ObjectWriter.CorlibAssembly)
                {
                    ilgenerator.Emit(OpCodes.Ldarg_1);
                    ilgenerator.Emit(OpCodes.Ldarg_2);
                    CodeGenerator.EmitLoadTypeAssembly(ilgenerator, type2, fieldInfo.Name);
                    ilgenerator.EmitCall(OpCodes.Callvirt, typeof(ObjectWriter).GetMethod("WriteAssembly"), null);
                    ilgenerator.Emit(OpCodes.Pop);
                }
            }
            ilgenerator.Emit(OpCodes.Ret);
            typeBuilder.DefineMethodOverride(methodBuilder, typeof(TypeMetadata).GetMethod("WriteAssemblies"));
            parameterTypes = new Type[]
            {
                typeof(ObjectWriter),
                typeof(BinaryWriter),
                typeof(bool)
            };
            methodBuilder = typeBuilder.DefineMethod("WriteTypeData", MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.Virtual, typeof(void), parameterTypes);
            ilgenerator   = methodBuilder.GetILGenerator();
            ilgenerator.Emit(OpCodes.Ldarg_2);
            ilgenerator.Emit(OpCodes.Ldc_I4, serializableMembers.Length);
            CodeGenerator.EmitWrite(ilgenerator, typeof(int));
            foreach (FieldInfo fieldInfo2 in serializableMembers)
            {
                ilgenerator.Emit(OpCodes.Ldarg_2);
                ilgenerator.Emit(OpCodes.Ldstr, fieldInfo2.Name);
                CodeGenerator.EmitWrite(ilgenerator, typeof(string));
            }
            Label label = ilgenerator.DefineLabel();

            ilgenerator.Emit(OpCodes.Ldarg_3);
            ilgenerator.Emit(OpCodes.Brfalse, label);
            foreach (FieldInfo fieldInfo3 in serializableMembers)
            {
                ilgenerator.Emit(OpCodes.Ldarg_2);
                ilgenerator.Emit(OpCodes.Ldc_I4_S, (byte)ObjectWriter.GetTypeTag(fieldInfo3.FieldType));
                CodeGenerator.EmitWrite(ilgenerator, typeof(byte));
            }
            foreach (FieldInfo fieldInfo4 in serializableMembers)
            {
                CodeGenerator.EmitWriteTypeSpec(ilgenerator, fieldInfo4.FieldType, fieldInfo4.Name);
            }
            ilgenerator.MarkLabel(label);
            ilgenerator.Emit(OpCodes.Ret);
            typeBuilder.DefineMethodOverride(methodBuilder, typeof(TypeMetadata).GetMethod("WriteTypeData"));
            parameterTypes = new Type[]
            {
                typeof(ObjectWriter),
                typeof(BinaryWriter),
                typeof(object)
            };
            methodBuilder = typeBuilder.DefineMethod("WriteObjectData", MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.Virtual, typeof(void), parameterTypes);
            ilgenerator   = methodBuilder.GetILGenerator();
            LocalBuilder local  = ilgenerator.DeclareLocal(type);
            OpCode       opcode = OpCodes.Ldloc;

            ilgenerator.Emit(OpCodes.Ldarg_3);
            if (type.IsValueType)
            {
                ilgenerator.Emit(OpCodes.Unbox, type);
                CodeGenerator.LoadFromPtr(ilgenerator, type);
                opcode = OpCodes.Ldloca_S;
            }
            else
            {
                ilgenerator.Emit(OpCodes.Castclass, type);
            }
            ilgenerator.Emit(OpCodes.Stloc, local);
            foreach (FieldInfo fieldInfo5 in serializableMembers)
            {
                Type fieldType = fieldInfo5.FieldType;
                if (BinaryCommon.IsPrimitive(fieldType))
                {
                    ilgenerator.Emit(OpCodes.Ldarg_2);
                    ilgenerator.Emit(opcode, local);
                    if (fieldType == typeof(DateTime) || fieldType == typeof(TimeSpan) || fieldType == typeof(decimal))
                    {
                        ilgenerator.Emit(OpCodes.Ldflda, fieldInfo5);
                    }
                    else
                    {
                        ilgenerator.Emit(OpCodes.Ldfld, fieldInfo5);
                    }
                    CodeGenerator.EmitWritePrimitiveValue(ilgenerator, fieldType);
                }
                else
                {
                    ilgenerator.Emit(OpCodes.Ldarg_1);
                    ilgenerator.Emit(OpCodes.Ldarg_2);
                    ilgenerator.Emit(OpCodes.Ldtoken, fieldType);
                    ilgenerator.EmitCall(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle"), null);
                    ilgenerator.Emit(opcode, local);
                    ilgenerator.Emit(OpCodes.Ldfld, fieldInfo5);
                    if (fieldType.IsValueType)
                    {
                        ilgenerator.Emit(OpCodes.Box, fieldType);
                    }
                    ilgenerator.EmitCall(OpCodes.Call, typeof(ObjectWriter).GetMethod("WriteValue"), null);
                }
            }
            ilgenerator.Emit(OpCodes.Ret);
            typeBuilder.DefineMethodOverride(methodBuilder, typeof(TypeMetadata).GetMethod("WriteObjectData"));
            return(typeBuilder.CreateType());
        }
示例#25
0
        static public Type GenerateMetadataType(Type type, StreamingContext context)
        {
            string name  = type.Name + "__TypeMetadata";
            string sufix = "";
            int    n     = 0;

            while (_module.GetType(name + sufix) != null)
            {
                sufix = (++n).ToString();
            }

            name += sufix;

            MemberInfo[] members = FormatterServices.GetSerializableMembers(type, context);

            TypeBuilder typeBuilder = _module.DefineType(name, TypeAttributes.Public, typeof(ClrTypeMetadata));

            Type[]        parameters;
            MethodBuilder method;
            ILGenerator   gen;

            // *********************
            //  METHOD public constructor (Type t): base (t);

            parameters = new Type[0];

            ConstructorBuilder ctor     = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, parameters);
            ConstructorInfo    baseCtor = typeof(ClrTypeMetadata).GetConstructor(new Type[] { typeof(Type) });

            gen = ctor.GetILGenerator();

            gen.Emit(OpCodes.Ldarg_0);
            gen.Emit(OpCodes.Ldtoken, type);
            gen.EmitCall(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle"), null);
            gen.Emit(OpCodes.Call, baseCtor);
            gen.Emit(OpCodes.Ret);

            // *********************
            //  METHOD public override void WriteAssemblies (ObjectWriter ow, BinaryWriter writer);

            parameters = new Type[] { typeof(ObjectWriter), typeof(BinaryWriter) };
            method     = typeBuilder.DefineMethod("WriteAssemblies", MethodAttributes.Public | MethodAttributes.Virtual, typeof(void), parameters);
            gen        = method.GetILGenerator();

            foreach (FieldInfo field in members)
            {
                Type memberType = field.FieldType;
                while (memberType.IsArray)
                {
                    memberType = memberType.GetElementType();
                }

                if (memberType.Assembly != ObjectWriter.CorlibAssembly)
                {
                    // EMIT ow.WriteAssembly (writer, memberType.Assembly);
                    gen.Emit(OpCodes.Ldarg_1);
                    gen.Emit(OpCodes.Ldarg_2);
                    EmitLoadTypeAssembly(gen, memberType, field.Name);
                    gen.EmitCall(OpCodes.Callvirt, typeof(ObjectWriter).GetMethod("WriteAssembly"), null);
                    gen.Emit(OpCodes.Pop);
                }
            }
            gen.Emit(OpCodes.Ret);
            typeBuilder.DefineMethodOverride(method, typeof(TypeMetadata).GetMethod("WriteAssemblies"));

            // *********************
            // METHOD public override void WriteTypeData (ObjectWriter ow, BinaryWriter writer, bool writeTypes);

            parameters = new Type[] { typeof(ObjectWriter), typeof(BinaryWriter), typeof(bool) };
            method     = typeBuilder.DefineMethod("WriteTypeData", MethodAttributes.Public | MethodAttributes.Virtual, typeof(void), parameters);
            gen        = method.GetILGenerator();

            // EMIT writer.Write (members.Length);
            gen.Emit(OpCodes.Ldarg_2);
            gen.Emit(OpCodes.Ldc_I4, members.Length);
            EmitWrite(gen, typeof(int));

            // Names of fields
            foreach (FieldInfo field in members)
            {
                // EMIT writer.Write (name);
                gen.Emit(OpCodes.Ldarg_2);
                gen.Emit(OpCodes.Ldstr, field.Name);
                EmitWrite(gen, typeof(string));
            }

            Label falseLabel = gen.DefineLabel();

            gen.Emit(OpCodes.Ldarg_3);
            gen.Emit(OpCodes.Brfalse, falseLabel);

            // Types of fields
            foreach (FieldInfo field in members)
            {
                // EMIT writer.Write ((byte) ObjectWriter.GetTypeTag (type));
                gen.Emit(OpCodes.Ldarg_2);
                gen.Emit(OpCodes.Ldc_I4_S, (byte)ObjectWriter.GetTypeTag(field.FieldType));
                EmitWrite(gen, typeof(byte));
            }

            // Type specs of fields
            foreach (FieldInfo field in members)
            {
                // EMIT ow.WriteTypeSpec (writer, field.FieldType);
                EmitWriteTypeSpec(gen, field.FieldType, field.Name);
            }
            gen.MarkLabel(falseLabel);

            gen.Emit(OpCodes.Ret);
            typeBuilder.DefineMethodOverride(method, typeof(TypeMetadata).GetMethod("WriteTypeData"));

            // *********************
            // METHOD public override void WriteObjectData (ObjectWriter ow, BinaryWriter writer, object data)

            parameters = new Type[] { typeof(ObjectWriter), typeof(BinaryWriter), typeof(object) };
            method     = typeBuilder.DefineMethod("WriteObjectData", MethodAttributes.Public | MethodAttributes.Virtual, typeof(void), parameters);
            gen        = method.GetILGenerator();

            LocalBuilder localBuilder = gen.DeclareLocal(type);
            OpCode       lload        = OpCodes.Ldloc;

            gen.Emit(OpCodes.Ldarg_3);
            if (type.IsValueType)
            {
                gen.Emit(OpCodes.Unbox, type);
                LoadFromPtr(gen, type);
                lload = OpCodes.Ldloca_S;
            }
            else
            {
                gen.Emit(OpCodes.Castclass, type);
            }

            gen.Emit(OpCodes.Stloc, localBuilder);

            foreach (FieldInfo field in members)
            {
                // EMIT ow.WriteValue (writer, ((FieldInfo)members[n]).FieldType, values[n]);
                Type ftype = field.FieldType;
                if (BinaryCommon.IsPrimitive(ftype))
                {
                    gen.Emit(OpCodes.Ldarg_2);
                    gen.Emit(lload, localBuilder);
                    if (ftype == typeof(DateTime) || ftype == typeof(TimeSpan) || ftype == typeof(decimal))
                    {
                        gen.Emit(OpCodes.Ldflda, field);
                    }
                    else
                    {
                        gen.Emit(OpCodes.Ldfld, field);
                    }
                    EmitWritePrimitiveValue(gen, ftype);
                }
                else
                {
                    gen.Emit(OpCodes.Ldarg_1);
                    gen.Emit(OpCodes.Ldarg_2);
                    gen.Emit(OpCodes.Ldtoken, ftype);
                    gen.EmitCall(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle"), null);
                    gen.Emit(lload, localBuilder);
                    gen.Emit(OpCodes.Ldfld, field);
                    if (ftype.IsValueType)
                    {
                        gen.Emit(OpCodes.Box, ftype);
                    }
                    gen.EmitCall(OpCodes.Call, typeof(ObjectWriter).GetMethod("WriteValue"), null);
                }
            }

            gen.Emit(OpCodes.Ret);
            typeBuilder.DefineMethodOverride(method, typeof(TypeMetadata).GetMethod("WriteObjectData"));

            return(typeBuilder.CreateType());
        }
示例#26
0
        private void ReadValue(BinaryReader reader, object parentObject, long parentObjectId, SerializationInfo info, Type valueType, string fieldName, MemberInfo memberInfo, int[] indices)
        {
            // Reads a value from the stream and assigns it to the member of an object

            object val;

            if (BinaryCommon.IsPrimitive(valueType) && !IsGeneric(memberInfo))
            {
                val = ReadPrimitiveTypeValue(reader, valueType);
                SetObjectValue(parentObject, fieldName, memberInfo, info, val, valueType, indices);
                return;
            }

            // Gets the object

            BinaryElement element = (BinaryElement)reader.ReadByte();

            if (element == BinaryElement.ObjectReference)
            {
                // Just read the id of the referred object and record a fixup
                long childObjectId = (long)reader.ReadUInt32();
                RecordFixup(parentObjectId, childObjectId, parentObject, info, fieldName, memberInfo, indices);
                return;
            }

            long objectId;
            SerializationInfo objectInfo;

            ReadObject(element, reader, out objectId, out val, out objectInfo);

            // There are two cases where the object cannot be assigned to the parent
            // and a fixup must be used:
            //  1) When what has been read is not an object, but an id of an object that
            //     has not been read yet (an object reference). This is managed in the
            //     previous block of code.
            //  2) When the read object is a value type object. Value type fields hold
            //     copies of objects, not references. Thus, if the value object that
            //     has been read has pending fixups, those fixups would be made to the
            //     boxed copy in the ObjectManager, and not in the required object instance

            // First of all register the fixup, and then the object. ObjectManager is more
            // efficient if done in this order

            bool hasFixup = false;

            if (objectId != 0)
            {
                if (val.GetType().IsValueType)
                {
                    RecordFixup(parentObjectId, objectId, parentObject, info, fieldName, memberInfo, indices);
                    hasFixup = true;
                }

                // Register the value

                if (info == null && !(parentObject is Array))
                {
                    RegisterObject(objectId, val, objectInfo, parentObjectId, memberInfo, null);
                }
                else
                {
                    RegisterObject(objectId, val, objectInfo, parentObjectId, null, indices);
                }
            }
            // Assign the value to the parent object, unless there is a fixup

            if (!hasFixup)
            {
                SetObjectValue(parentObject, fieldName, memberInfo, info, val, valueType, indices);
            }
        }
        public static object ReadMethodCall(BinaryElement elem, BinaryReader reader, bool hasHeaders, HeaderHandler headerHandler, BinaryFormatter formatter)
        {
            if (elem != BinaryElement.MethodCall)
            {
                throw new SerializationException("Invalid format. Expected BinaryElement.MethodCall, found " + elem);
            }

            MethodFlags flags = (MethodFlags)reader.ReadInt32();

            if (((BinaryTypeCode)reader.ReadByte()) != BinaryTypeCode.String)
            {
                throw new SerializationException("Invalid format");
            }
            string methodName = reader.ReadString();

            if (((BinaryTypeCode)reader.ReadByte()) != BinaryTypeCode.String)
            {
                throw new SerializationException("Invalid format");
            }
            string className = reader.ReadString();

            //bool hasContextInfo = (flags & MethodFlags.IncludesLogicalCallContext) > 0;

            object[] arguments       = null;
            object   methodSignature = null;
            object   callContext     = null;

            object[] extraProperties  = null;
            Header[] headers          = null;
            Type[]   genericArguments = null;

            if ((flags & MethodFlags.PrimitiveArguments) > 0)
            {
                uint count = reader.ReadUInt32();
                arguments = new object[count];
                for (int n = 0; n < count; n++)
                {
                    Type type = BinaryCommon.GetTypeFromCode(reader.ReadByte());
                    arguments[n] = ObjectReader.ReadPrimitiveTypeValue(reader, type);
                }
            }

            if ((flags & MethodFlags.NeedsInfoArrayMask) > 0)
            {
                ObjectReader objectReader = new ObjectReader(formatter);

                object result;
                objectReader.ReadObjectGraph(reader, hasHeaders, out result, out headers);
                object[] msgInfo = (object[])result;

                if ((flags & MethodFlags.ArgumentsInSimpleArray) > 0)
                {
                    arguments = msgInfo;
                }
                else
                {
                    int n = 0;
                    if ((flags & MethodFlags.ArgumentsInMultiArray) > 0)
                    {
                        if (msgInfo.Length > 1)
                        {
                            arguments = (object[])msgInfo[n++];
                        }
                        else
                        {
                            arguments = new object[0];
                        }
                    }

                    if ((flags & MethodFlags.GenericArguments) > 0)
                    {
                        genericArguments = (Type[])msgInfo[n++];
                    }

                    if ((flags & MethodFlags.IncludesSignature) > 0)
                    {
                        methodSignature = msgInfo[n++];
                    }

                    if ((flags & MethodFlags.IncludesLogicalCallContext) > 0)
                    {
                        callContext = msgInfo[n++];
                    }

                    if (n < msgInfo.Length)
                    {
                        extraProperties = (object[])msgInfo[n];
                    }
                }
            }
            else
            {
                reader.ReadByte(); // Reads the stream ender
            }

            if (arguments == null)
            {
                arguments = new object[0];
            }

            string uri = null;

            if (headerHandler != null)
            {
                uri = headerHandler(headers) as string;
            }

            Header[] methodInfo = new Header[7];
            methodInfo[0] = new Header("__MethodName", methodName);
            methodInfo[1] = new Header("__MethodSignature", methodSignature);
            methodInfo[2] = new Header("__TypeName", className);
            methodInfo[3] = new Header("__Args", arguments);
            methodInfo[4] = new Header("__CallContext", callContext);
            methodInfo[5] = new Header("__Uri", uri);
            methodInfo[6] = new Header("__GenericArguments", genericArguments);

            MethodCall call = new MethodCall(methodInfo);

            if (extraProperties != null)
            {
                foreach (DictionaryEntry entry in extraProperties)
                {
                    call.Properties [(string)entry.Key] = entry.Value;
                }
            }

            return(call);
        }
        public static void WriteMethodCall(BinaryWriter writer, object obj, Header[] headers, BinaryFormatter formatter)
        {
            IMethodCallMessage call = (IMethodCallMessage)obj;

            writer.Write((byte)BinaryElement.MethodCall);

            MethodFlags methodFlags;
            int         infoArraySize = 0;
            object      info          = null;

            object[] extraProperties = null;

            if (call.LogicalCallContext != null && call.LogicalCallContext.HasInfo)
            {
                methodFlags = MethodFlags.IncludesLogicalCallContext;
                infoArraySize++;
            }
            else
            {
                methodFlags = MethodFlags.ExcludeLogicalCallContext;
            }

            if (RemotingServices.IsMethodOverloaded(call))
            {
                infoArraySize++;
                methodFlags |= MethodFlags.IncludesSignature;
            }

            if (call.Properties.Count > MethodCallDictionary.InternalKeys.Length)
            {
                extraProperties = GetExtraProperties(call.Properties, MethodCallDictionary.InternalKeys);
                infoArraySize++;
            }

            if (call.MethodBase.IsGenericMethod)
            {
                infoArraySize++;
                methodFlags |= MethodFlags.GenericArguments;
            }
            if (call.ArgCount == 0)
            {
                methodFlags |= MethodFlags.NoArguments;
            }
            else
            {
                if (AllTypesArePrimitive(call.Args))
                {
                    methodFlags |= MethodFlags.PrimitiveArguments;
                }
                else
                {
                    if (infoArraySize == 0)
                    {
                        methodFlags |= MethodFlags.ArgumentsInSimpleArray;
                    }
                    else
                    {
                        methodFlags |= MethodFlags.ArgumentsInMultiArray;
                        infoArraySize++;
                    }
                }
            }

            writer.Write((int)methodFlags);

            // Method name
            writer.Write((byte)BinaryTypeCode.String);
            writer.Write(call.MethodName);

            // Class name
            writer.Write((byte)BinaryTypeCode.String);
            writer.Write(call.TypeName);

            // Arguments

            if ((methodFlags & MethodFlags.PrimitiveArguments) > 0)
            {
                writer.Write((uint)call.Args.Length);
                for (int n = 0; n < call.ArgCount; n++)
                {
                    object arg = call.GetArg(n);
                    if (arg != null)
                    {
                        writer.Write(BinaryCommon.GetTypeCode(arg.GetType()));
                        ObjectWriter.WritePrimitiveValue(writer, arg);
                    }
                    else
                    {
                        writer.Write((byte)BinaryTypeCode.Null);
                    }
                }
            }

            if (infoArraySize > 0)
            {
                object[] ainfo = new object[infoArraySize];
                int      n     = 0;
                if ((methodFlags & MethodFlags.ArgumentsInMultiArray) > 0)
                {
                    ainfo[n++] = call.Args;
                }
                if ((methodFlags & MethodFlags.GenericArguments) > 0)
                {
                    ainfo[n++] = call.MethodBase.GetGenericArguments();
                }
                if ((methodFlags & MethodFlags.IncludesSignature) > 0)
                {
                    ainfo[n++] = call.MethodSignature;
                }
                if ((methodFlags & MethodFlags.IncludesLogicalCallContext) > 0)
                {
                    ainfo[n++] = call.LogicalCallContext;
                }
                if (extraProperties != null)
                {
                    ainfo[n++] = extraProperties;
                }
                info = ainfo;
            }
            else if ((methodFlags & MethodFlags.ArgumentsInSimpleArray) > 0)
            {
                info = call.Args;
            }

            if (info != null)
            {
                ObjectWriter objectWriter = new ObjectWriter(formatter);
                objectWriter.WriteObjectGraph(writer, info, headers);
            }
            else
            {
                writer.Write((byte)BinaryElement.End);
            }
        }
示例#29
0
        private void GetObjectData(object obj, out TypeMetadata metadata, out object data)
        {
            Type type = obj.GetType();

            if (this._surrogateSelector != null)
            {
                ISurrogateSelector      surrogateSelector;
                ISerializationSurrogate surrogate = this._surrogateSelector.GetSurrogate(type, this._context, out surrogateSelector);
                if (surrogate != null)
                {
                    SerializationInfo serializationInfo = new SerializationInfo(type, new FormatterConverter());
                    surrogate.GetObjectData(obj, serializationInfo, this._context);
                    metadata = new SerializableTypeMetadata(type, serializationInfo);
                    data     = serializationInfo;
                    return;
                }
            }
            BinaryCommon.CheckSerializable(type, this._surrogateSelector, this._context);
            this._manager.RegisterObject(obj);
            ISerializable serializable = obj as ISerializable;

            if (serializable != null)
            {
                SerializationInfo serializationInfo2 = new SerializationInfo(type, new FormatterConverter());
                serializable.GetObjectData(serializationInfo2, this._context);
                metadata = new SerializableTypeMetadata(type, serializationInfo2);
                data     = serializationInfo2;
            }
            else
            {
                data = obj;
                if (this._context.Context != null)
                {
                    metadata = new MemberTypeMetadata(type, this._context);
                    return;
                }
                bool      flag        = false;
                Hashtable cachedTypes = ObjectWriter._cachedTypes;
                Hashtable hashtable;
                lock (cachedTypes)
                {
                    hashtable = (Hashtable)ObjectWriter._cachedTypes[this._context.State];
                    if (hashtable == null)
                    {
                        hashtable = new Hashtable();
                        ObjectWriter._cachedTypes[this._context.State] = hashtable;
                        flag = true;
                    }
                }
                metadata = null;
                Hashtable obj2 = hashtable;
                lock (obj2)
                {
                    if (!flag)
                    {
                        metadata = (TypeMetadata)hashtable[type];
                    }
                    if (metadata == null)
                    {
                        metadata = this.CreateMemberTypeMetadata(type);
                    }
                    hashtable[type] = metadata;
                }
            }
        }
        public static object ReadMethodResponse(BinaryElement elem, BinaryReader reader, bool hasHeaders, HeaderHandler headerHandler, IMethodCallMessage methodCallMessage, BinaryFormatter formatter)
        {
            if (elem != BinaryElement.MethodResponse)
            {
                throw new SerializationException("Invalid format. Expected BinaryElement.MethodResponse, found " + elem);
            }
            MethodFlags   methodFlags   = (MethodFlags)reader.ReadByte();
            ReturnTypeTag returnTypeTag = (ReturnTypeTag)reader.ReadByte();
            bool          flag          = (methodFlags & MethodFlags.IncludesLogicalCallContext) > (MethodFlags)0;

            reader.ReadByte();
            reader.ReadByte();
            object ret = null;

            object[]           array   = null;
            LogicalCallContext callCtx = null;
            Exception          ex      = null;

            object[] array2  = null;
            Header[] headers = null;
            if ((byte)(returnTypeTag & ReturnTypeTag.PrimitiveType) > 0)
            {
                Type typeFromCode = BinaryCommon.GetTypeFromCode((int)reader.ReadByte());
                ret = ObjectReader.ReadPrimitiveTypeValue(reader, typeFromCode);
            }
            if ((methodFlags & MethodFlags.PrimitiveArguments) > (MethodFlags)0)
            {
                uint num = reader.ReadUInt32();
                array = new object[num];
                int num2 = 0;
                while ((long)num2 < (long)((ulong)num))
                {
                    Type typeFromCode2 = BinaryCommon.GetTypeFromCode((int)reader.ReadByte());
                    array[num2] = ObjectReader.ReadPrimitiveTypeValue(reader, typeFromCode2);
                    num2++;
                }
            }
            if (flag || (byte)(returnTypeTag & ReturnTypeTag.ObjectType) > 0 || (byte)(returnTypeTag & ReturnTypeTag.Exception) > 0 || (methodFlags & MethodFlags.ArgumentsInSimpleArray) > (MethodFlags)0 || (methodFlags & MethodFlags.ArgumentsInMultiArray) > (MethodFlags)0)
            {
                ObjectReader objectReader = new ObjectReader(formatter);
                object       obj;
                objectReader.ReadObjectGraph(reader, hasHeaders, out obj, out headers);
                object[] array3 = (object[])obj;
                if ((byte)(returnTypeTag & ReturnTypeTag.Exception) > 0)
                {
                    ex = (Exception)array3[0];
                    if (flag)
                    {
                        callCtx = (LogicalCallContext)array3[1];
                    }
                }
                else if ((methodFlags & MethodFlags.NoArguments) > (MethodFlags)0 || (methodFlags & MethodFlags.PrimitiveArguments) > (MethodFlags)0)
                {
                    int num3 = 0;
                    if ((byte)(returnTypeTag & ReturnTypeTag.ObjectType) > 0)
                    {
                        ret = array3[num3++];
                    }
                    if (flag)
                    {
                        callCtx = (LogicalCallContext)array3[num3++];
                    }
                    if (num3 < array3.Length)
                    {
                        array2 = (object[])array3[num3];
                    }
                }
                else if ((methodFlags & MethodFlags.ArgumentsInSimpleArray) > (MethodFlags)0)
                {
                    array = array3;
                }
                else
                {
                    int num4 = 0;
                    array = (object[])array3[num4++];
                    if ((byte)(returnTypeTag & ReturnTypeTag.ObjectType) > 0)
                    {
                        ret = array3[num4++];
                    }
                    if (flag)
                    {
                        callCtx = (LogicalCallContext)array3[num4++];
                    }
                    if (num4 < array3.Length)
                    {
                        array2 = (object[])array3[num4];
                    }
                }
            }
            else
            {
                reader.ReadByte();
            }
            if (headerHandler != null)
            {
                headerHandler(headers);
            }
            if (ex != null)
            {
                return(new ReturnMessage(ex, methodCallMessage));
            }
            int           outArgsCount  = (array == null) ? 0 : array.Length;
            ReturnMessage returnMessage = new ReturnMessage(ret, array, outArgsCount, callCtx, methodCallMessage);

            if (array2 != null)
            {
                foreach (DictionaryEntry dictionaryEntry in array2)
                {
                    returnMessage.Properties[(string)dictionaryEntry.Key] = dictionaryEntry.Value;
                }
            }
            return(returnMessage);
        }