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); } }
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; } }
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); } }
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; } }
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; } }
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"); } }
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; } }
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"); } }
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); } }
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; } }
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; } }
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); } }
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); } }
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]); } } } }
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); } }
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; } }
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); } }
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); }
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()); }
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()); }
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); } }
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); }