/// <summary> /// TCP调用 /// </summary> /// <param name="commandInfo">命令信息</param> /// <returns>返回值类型</returns> public unsafe TcpServer.ReturnType Call(TcpServer.CommandInfoBase commandInfo) { TcpServer.ReturnType returnType = TcpServer.ReturnType.ClientDisposed; SocketError socketError; bool isError = false; Monitor.Enter(SocketLock); try { if (IsDisposed == 0) { if (getSocket()) { byte[] buffer = Buffer.Buffer; fixed(byte *dataFixed = buffer) { byte *start = dataFixed + Buffer.StartIndex; *(uint *)start = (uint)commandInfo.Command | (uint)TcpServer.CommandFlags.NullData | (uint)commandInfo.CommandFlags; isError = true; int size = Socket.Send(buffer, Buffer.StartIndex, sizeof(uint), SocketFlags.None, out socketError); ++SendCount; if (size == sizeof(uint)) { size = Socket.Receive(buffer, Buffer.StartIndex, sizeof(int), SocketFlags.None, out socketError); ++ReceiveCount; if (size == sizeof(uint)) { returnType = (TcpServer.ReturnType)(*start); isError = false; } else { returnType = TcpServer.ReturnType.ClientReceiveError; } } else { returnType = TcpServer.ReturnType.ClientSendError; } } } else { returnType = TcpServer.ReturnType.ClientException; } } } finally { isCheck = 0; if (isError) { closeSocket(); } Monitor.Exit(SocketLock); } return(returnType); }
/// <summary> /// TCP调用 /// </summary> /// <typeparam name="inputParameterType">输入参数类型</typeparam> /// <param name="commandInfo">命令信息</param> /// <param name="inputParameter">输入参数</param> /// <returns>返回值类型</returns> public unsafe TcpServer.ReturnType Call <inputParameterType>(TcpServer.CommandInfoBase commandInfo, ref inputParameterType inputParameter) where inputParameterType : struct { ClientBuffer clientBuffer = default(ClientBuffer); Monitor.Enter(SocketLock); try { if (IsDisposed == 0) { if (commandInfo.IsVerifyMethod || getSocket()) { fixed(byte *dataFixed = Buffer.GetFixedBuffer()) { outputStream.Reset(dataFixed + Buffer.StartIndex, Buffer.Length); build(commandInfo, ref inputParameter, ref clientBuffer); } if (clientBuffer.Send(this)) { int size = Socket.Receive(Buffer.Buffer, Buffer.StartIndex, sizeof(int), SocketFlags.None, out clientBuffer.SocketError); ++ReceiveCount; if (size == sizeof(uint)) { clientBuffer.SetReturnType((TcpServer.ReturnType)Buffer.Buffer[Buffer.StartIndex]); } else { clientBuffer.ReturnType = TcpServer.ReturnType.ClientReceiveError; } } } else { clientBuffer.ReturnType = TcpServer.ReturnType.ClientException; } } } finally { isCheck = 0; if (clientBuffer.IsError) { closeSocket(); } Monitor.Exit(SocketLock); clientBuffer.Free(); } return(clientBuffer.ReturnType); }
/// <summary> /// TCP调用并返回参数值 /// </summary> /// <typeparam name="outputParameterType">输出参数类型</typeparam> /// <param name="commandInfo">命令信息</param> /// <param name="outputParameter">输出参数</param> /// <returns>返回值类型</returns> public unsafe TcpServer.ReturnType Get <outputParameterType>(TcpServer.CommandInfoBase commandInfo, ref outputParameterType outputParameter) where outputParameterType : struct { ClientBuffer clientBuffer = default(ClientBuffer); Monitor.Enter(SocketLock); try { if (IsDisposed == 0) { if (getSocket()) { fixed(byte *dataFixed = Buffer.GetFixedBuffer()) { *(uint *)(dataFixed + Buffer.StartIndex) = (uint)commandInfo.Command | (uint)TcpServer.CommandFlags.NullData | (uint)commandInfo.CommandFlags; clientBuffer.IsError = true; int size = Socket.Send(Buffer.Buffer, Buffer.StartIndex, sizeof(uint), SocketFlags.None, out clientBuffer.SocketError); ++SendCount; if (size == sizeof(uint)) { receive(commandInfo, ref outputParameter, ref clientBuffer); } else { clientBuffer.ReturnType = TcpServer.ReturnType.ClientSendError; } } } else { clientBuffer.ReturnType = TcpServer.ReturnType.ClientException; } } } finally { isCheck = 0; if (clientBuffer.IsError) { closeSocket(); } Monitor.Exit(SocketLock); clientBuffer.Free(); } return(clientBuffer.ReturnType); }
/// <summary> /// 数据反序列化 /// </summary> /// <typeparam name="outputParameterType"></typeparam> /// <param name="commandInfo"></param> /// <param name="outputParameter"></param> /// <param name="clientBuffer"></param> private unsafe void deSerialize <outputParameterType>(TcpServer.CommandInfoBase commandInfo, ref outputParameterType outputParameter, ref ClientBuffer clientBuffer) where outputParameterType : struct { if ((commandInfo.CommandFlags & TcpServer.CommandFlags.JsonSerialize) == 0) { if (commandInfo.SimpleSerializeOutputParamter == 0) { if (receiveDeSerializer == null) { receiveDeSerializer = AutoCSer.BinaryDeSerializer.YieldPool.Default.Pop() ?? new AutoCSer.BinaryDeSerializer(); receiveDeSerializer.SetTcpServer(AutoCSer.BinaryDeSerializer.DefaultConfig, null); } if (receiveDeSerializer.DeSerializeTcpServer(ref clientBuffer.Data, ref outputParameter)) { clientBuffer.ReturnType = TcpServer.ReturnType.Success; return; } } else { fixed(byte *dataFixed = clientBuffer.Data.GetFixedBuffer()) { byte *start = dataFixed + clientBuffer.Data.Start, end = start + clientBuffer.Data.Length; if (SimpleSerialize.TypeDeSerializer <outputParameterType> .DeSerialize(start, ref outputParameter, end) == end) { clientBuffer.ReturnType = TcpServer.ReturnType.Success; return; } } } } else { if (receiveJsonParser == null) { receiveJsonParser = AutoCSer.JsonDeSerializer.YieldPool.Default.Pop() ?? new AutoCSer.JsonDeSerializer(); receiveJsonParser.SetTcpServer(); } if (receiveJsonParser.DeSerializeTcpServer(ref clientBuffer.Data, ref outputParameter)) { clientBuffer.ReturnType = TcpServer.ReturnType.Success; return; } } clientBuffer.ReturnType = TcpServer.ReturnType.ClientDeSerializeError; }
public static unsafe TcpServer.ReturnType Call(Client client, TcpServer.CommandInfoBase commandInfo) { return(client.Call(commandInfo)); }
public static unsafe TcpServer.ReturnType Call <inputParameterType>(Client client, TcpServer.CommandInfoBase commandInfo, ref inputParameterType inputParameter) where inputParameterType : struct { return(client.Call(commandInfo, ref inputParameter)); }
public static unsafe TcpServer.ReturnType Get <outputParameterType>(Client client, TcpServer.CommandInfoBase commandInfo, ref outputParameterType outputParameter) where outputParameterType : struct { return(client.Get(commandInfo, ref outputParameter)); }
/// <summary> /// TCP调用并返回参数值 /// </summary> /// <typeparam name="inputParameterType">输入参数类型</typeparam> /// <typeparam name="outputParameterType">输出参数类型</typeparam> /// <param name="commandInfo">命令信息</param> /// <param name="inputParameter">输入参数</param> /// <param name="outputParameter">输出参数</param> /// <returns>返回值类型</returns> public unsafe TcpServer.ReturnType Get <inputParameterType, outputParameterType>(TcpServer.CommandInfoBase commandInfo, ref inputParameterType inputParameter, ref outputParameterType outputParameter) where inputParameterType : struct where outputParameterType : struct { ClientBuffer clientBuffer = default(ClientBuffer); Monitor.Enter(SocketLock); try { if (IsDisposed == 0) { if (commandInfo.IsVerifyMethod || getSocket()) { fixed(byte *dataFixed = Buffer.GetFixedBuffer()) { outputStream.Reset(dataFixed + Buffer.StartIndex, Buffer.Length); build(commandInfo, ref inputParameter, ref clientBuffer); } if (clientBuffer.Send(this)) { clientBuffer.Free(); receive(commandInfo, ref outputParameter, ref clientBuffer); } } else { clientBuffer.ReturnType = TcpServer.ReturnType.ClientException; } } } finally { isCheck = 0; if (clientBuffer.IsError) { closeSocket(); } Monitor.Exit(SocketLock); clientBuffer.Free(); } return(clientBuffer.ReturnType); }
/// <summary> /// 接收数据 /// </summary> /// <typeparam name="outputParameterType"></typeparam> /// <param name="commandInfo"></param> /// <param name="outputParameter"></param> /// <param name="clientBuffer"></param> private unsafe void receive <outputParameterType>(TcpServer.CommandInfoBase commandInfo, ref outputParameterType outputParameter, ref ClientBuffer clientBuffer) where outputParameterType : struct { int compressionDataSize, dataSize = 0, nextSize, receiveSize = Socket.Receive(Buffer.Buffer, Buffer.StartIndex, Buffer.Length, SocketFlags.None, out clientBuffer.SocketError); ++ReceiveCount; if (receiveSize >= sizeof(int) * 2) { fixed(byte *bufferFixed = Buffer.GetFixedBuffer()) { byte *start = bufferFixed + Buffer.StartIndex; if ((compressionDataSize = *(int *)start) > 0) { if ((nextSize = compressionDataSize + sizeof(int) - receiveSize) == 0) { clientBuffer.IsError = false; if (ReceiveMarkData != 0) { Mark(Buffer.Buffer, ReceiveMarkData, Buffer.StartIndex + sizeof(int), compressionDataSize); } clientBuffer.SetReceiveData(ref Buffer, compressionDataSize); deSerialize(commandInfo, ref outputParameter, ref clientBuffer); return; } if (nextSize > 0 && clientBuffer.SocketError == SocketError.Success) { if (nextSize <= Buffer.Length) { goto RECEIVE; } else { goto BIGBUFFER; } } } else if (compressionDataSize < 0) { if ((compressionDataSize = -compressionDataSize) <= (dataSize = *(int *)(start + sizeof(int)))) { if ((nextSize = compressionDataSize + sizeof(int) * 2 - receiveSize) == 0) { clientBuffer.IsError = false; if (ReceiveMarkData != 0) { Mark(Buffer.Buffer, ReceiveMarkData, Buffer.StartIndex + sizeof(int) * 2, compressionDataSize); } if (clientBuffer.DeCompressReceiveData(ref Buffer, compressionDataSize, dataSize)) { deSerialize(commandInfo, ref outputParameter, ref clientBuffer); } return; } if (nextSize > 0) { if (nextSize <= Buffer.Length) { goto RECEIVE; } else { goto BIGBUFFER; } } } } else if (receiveSize == sizeof(int) * 2) { clientBuffer.ReturnType = (TcpServer.ReturnType)(*(start + sizeof(int))); return; } } } clientBuffer.ReturnType = TcpServer.ReturnType.ClientReceiveError; return; BIGBUFFER: clientBuffer.CopyBufferData(ref Buffer, receiveSize + nextSize, receiveSize); if (clientBuffer.CopyBuffer.Length > SendBufferMaxSize) { do { int count = Socket.Receive(Buffer.Buffer, Buffer.StartIndex + receiveSize, nextSize, SocketFlags.None, out clientBuffer.SocketError); ++ReceiveCount; if ((nextSize -= count) == 0) { clientBuffer.IsError = false; if (dataSize == 0) { if (ReceiveMarkData != 0) { Mark(clientBuffer.CopyBuffer.Buffer, ReceiveMarkData, clientBuffer.CopyBuffer.StartIndex + sizeof(int), compressionDataSize); } clientBuffer.SetReceiveData(compressionDataSize); deSerialize(commandInfo, ref outputParameter, ref clientBuffer); } else { if (ReceiveMarkData != 0) { Mark(clientBuffer.CopyBuffer.Buffer, ReceiveMarkData, clientBuffer.CopyBuffer.StartIndex + sizeof(int) * 2, compressionDataSize); } if (clientBuffer.DeCompressReceiveData(compressionDataSize, dataSize)) { deSerialize(commandInfo, ref outputParameter, ref clientBuffer); } } return; } if (count <= 0 || clientBuffer.SocketError != SocketError.Success) { clientBuffer.ReturnType = TcpServer.ReturnType.ClientReceiveError; return; } receiveSize += count; }while (true); } Buffer.Free(); clientBuffer.CopyBuffer.CopyToClear(ref Buffer); RECEIVE: do { int count = Socket.Receive(Buffer.Buffer, Buffer.StartIndex + receiveSize, nextSize, SocketFlags.None, out clientBuffer.SocketError); ++ReceiveCount; if ((nextSize -= count) == 0) { clientBuffer.IsError = false; if (dataSize == 0) { if (ReceiveMarkData != 0) { Mark(Buffer.Buffer, ReceiveMarkData, Buffer.StartIndex + sizeof(int), compressionDataSize); } clientBuffer.SetReceiveData(ref Buffer, compressionDataSize); deSerialize(commandInfo, ref outputParameter, ref clientBuffer); } else { if (ReceiveMarkData != 0) { Mark(Buffer.Buffer, ReceiveMarkData, Buffer.StartIndex + sizeof(int) * 2, compressionDataSize); } if (clientBuffer.DeCompressReceiveData(ref Buffer, compressionDataSize, dataSize)) { deSerialize(commandInfo, ref outputParameter, ref clientBuffer); } } return; } if (count <= 0 || clientBuffer.SocketError != SocketError.Success) { clientBuffer.ReturnType = TcpServer.ReturnType.ClientReceiveError; return; } receiveSize += count; }while (true); }
/// <summary> /// 创建命令输入数据 /// </summary> /// <typeparam name="inputParameterType"></typeparam> /// <param name="commandInfo"></param> /// <param name="inputParameter"></param> /// <param name="clientBuffer"></param> private unsafe void build <inputParameterType>(TcpServer.CommandInfoBase commandInfo, ref inputParameterType inputParameter, ref ClientBuffer clientBuffer) where inputParameterType : struct { byte *start = outputStream.Data.Byte; outputStream.Data.CurrentIndex = sizeof(uint) + sizeof(int); if ((commandInfo.CommandFlags & TcpServer.CommandFlags.JsonSerialize) == 0) { if (commandInfo.SimpleSerializeInputParamter == 0) { int parameterIndex = commandInfo.InputParameterIndex; if (serializeParameterIndex == parameterIndex) { outputSerializer.SerializeTcpServerNext(ref inputParameter); } else { outputSerializer.SerializeTcpServer(ref inputParameter); serializeParameterIndex = parameterIndex; } } else { SimpleSerialize.TypeSerializer <inputParameterType> .Serializer(outputStream, ref inputParameter); } } else { if (outputJsonSerializer == null) { outputJsonSerializer = AutoCSer.JsonSerializer.YieldPool.Default.Pop() ?? new AutoCSer.JsonSerializer(); outputJsonSerializer.SetTcpServer(); } outputJsonSerializer.SerializeTcpServer(ref inputParameter, outputSerializer.Stream); } int dataLength = outputStream.Data.CurrentIndex - (sizeof(uint) + sizeof(int)); if (dataLength <= maxInputSize) { byte *write = outputStream.Data.Byte; *(uint *)write = (uint)commandInfo.Command | (uint)commandInfo.CommandFlags; *(int *)(write + sizeof(uint)) = dataLength; if (outputStream.Data.CurrentIndex <= Buffer.Length) { if (start != write) { AutoCSer.Memory.Common.CopyNotNull(write, start, outputStream.Data.CurrentIndex); } clientBuffer.Data.Set(Buffer.Buffer, Buffer.StartIndex, outputStream.Data.CurrentIndex); } else { outputStream.Data.GetSubBuffer(ref clientBuffer.CopyBuffer); clientBuffer.SetSendDataCopyBuffer(outputStream.Data.CurrentIndex); if (clientBuffer.CopyBuffer.Length <= SendBufferMaxSize) { Buffer.Free(); clientBuffer.CopyBuffer.CopyToClear(ref Buffer); } } if (dataLength < MinCompressSize || !clientBuffer.CompressSendData(dataLength, SendMarkData)) { if (SendMarkData == 0) { clientBuffer.IsError = true; } else { clientBuffer.MarkSendData(dataLength, SendMarkData); } } } }
/// <summary> /// 创建 TCP 客户端 /// </summary> /// <param name="type"></param> /// <param name="attribute"></param> /// <param name="methods"></param> /// <param name="getCommandMethod"></param> /// <returns></returns> internal Type Build(Type type, TcpServer.ServerBaseAttribute attribute, Method <attributeType, methodAttributeType, serverSocketType>[] methods, MethodInfo getCommandMethod) { TypeBuilder typeBuilder = AutoCSer.Emit.Builder.Module.Builder.DefineType(Metadata.ClientTypeName + ".Emit." + type.FullName, TypeAttributes.Class | TypeAttributes.Sealed, Metadata.MethodClientType, new Type[] { type }); typeBuilder.DefineDefaultConstructor(MethodAttributes.Public); ConstructorBuilder staticConstructorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, null); ILGenerator staticConstructorGenerator = staticConstructorBuilder.GetILGenerator(); Commands = new TcpServer.CommandInfoBase[methods.Length]; int parameterIndex; foreach (Method <attributeType, methodAttributeType, serverSocketType> nextMethod in methods) { if (nextMethod != null) { Method <attributeType, methodAttributeType, serverSocketType> method = nextMethod; METHOD: FieldBuilder commandInfoFieldBuilder; if (method.Attribute.IsExpired) { commandInfoFieldBuilder = null; } else { commandInfoFieldBuilder = typeBuilder.DefineField("_c" + method.Attribute.CommandIdentity.toString(), typeof(TcpServer.CommandInfoBase), FieldAttributes.Private | FieldAttributes.InitOnly | FieldAttributes.Static); TcpServer.CommandInfoBase commandInfo = new TcpServer.CommandInfoBase { Command = method.Attribute.CommandIdentity + TcpServer.Server.CommandStartIndex, IsVerifyMethod = method.Attribute.IsVerifyMethod }; Commands[method.Attribute.CommandIdentity] = commandInfo; if (method.IsJsonSerialize) { commandInfo.CommandFlags = TcpServer.CommandFlags.JsonSerialize; } if (method.ParameterType != null) { commandInfo.InputParameterIndex = method.ParameterType.Index; if (attribute.IsSimpleSerialize) { commandInfo.IsSimpleSerializeInputParamter = method.ParameterType.IsSimpleSerialize; } } if (attribute.IsSimpleSerialize && method.OutputParameterType != null) { commandInfo.IsSimpleSerializeOutputParamter = method.OutputParameterType.IsSimpleSerialize && SimpleSerialize.Serializer.IsType(method.ReturnType); } #region private static readonly AutoCSer.Net.TcpServer.CommandInfoBase @MethodIdentityCommand = AutoCSer.Net.TcpInternalSimpleServer.Emit.Client<interfaceType>.commands[method.Attribute.CommandIdentity]; staticConstructorGenerator.int32(method.Attribute.CommandIdentity); staticConstructorGenerator.call(getCommandMethod); staticConstructorGenerator.Emit(OpCodes.Stsfld, commandInfoFieldBuilder); #endregion } if (method.PropertyInfo == null) { ParameterInfo[] parameters = method.MethodInfo.GetParameters(); MethodBuilder methodBuilder = typeBuilder.DefineMethod(method.MethodInfo.Name, MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final, method.MethodInfo.ReturnType, parameters.getArray(parameter => parameter.ParameterType)); typeBuilder.DefineMethodOverride(methodBuilder, method.MethodInfo); ILGenerator methodGenerator = methodBuilder.GetILGenerator(); if (method.Attribute.IsExpired) { if (method.ReturnValueType == null) { #region throw new Exception(AutoCSer.Net.TcpServer.ReturnType.VersionExpired.ToString()); methodGenerator.throwString(AutoCSer.Net.TcpServer.ReturnType.VersionExpired.ToString()); #endregion } else { #region @ParameterName = default(@ParameterType.FullName); parameterIndex = 0; foreach (ParameterInfo parameter in parameters) { ++parameterIndex; if (parameter.IsOut) { methodGenerator.outParameterDefault(parameter, parameterIndex, method.Attribute.IsInitobj); } } #endregion #region return new AutoCSer.Net.TcpServer.ReturnValue<@MethodReturnType.FullName> { Type = AutoCSer.Net.TcpServer.ReturnType.VersionExpired }; LocalBuilder returnReturnValueLocalBuilder = methodGenerator.DeclareLocal(method.ReturnValueType); if (method.ReturnType != typeof(void) && (method.Attribute.IsInitobj || method.ReturnType.isInitobj())) { methodGenerator.Emit(OpCodes.Ldloca_S, returnReturnValueLocalBuilder); methodGenerator.Emit(OpCodes.Initobj, method.ReturnValueType); } methodGenerator.Emit(OpCodes.Ldloca_S, returnReturnValueLocalBuilder); methodGenerator.int32((byte)AutoCSer.Net.TcpServer.ReturnType.VersionExpired); methodGenerator.Emit(OpCodes.Stfld, method.ReturnType == typeof(void) ? TcpServer.Emit.ClientMetadata.ReturnValueTypeField : method.ReturnValueType.GetField(TcpServer.Emit.ClientMetadata.ReturnValueTypeField.Name, BindingFlags.Instance | BindingFlags.Public)); methodGenerator.Emit(OpCodes.Ldloc_S, returnReturnValueLocalBuilder); methodGenerator.Emit(OpCodes.Ret); #endregion } } else { Label clientExceptionLabel = methodGenerator.DefineLabel(); #region if (_isDisposed_ == 0) methodGenerator.Emit(OpCodes.Ldarg_0); methodGenerator.call(TcpSimpleServer.Emit.ClientMetadata.MethodClientGetIsDisposedMethod); methodGenerator.Emit(method.ParameterType == null && method.OutputParameterType == null ? OpCodes.Brtrue_S : OpCodes.Brtrue, clientExceptionLabel); #endregion LocalBuilder inputParameterLocalBuilder; if (method.ParameterType == null) { inputParameterLocalBuilder = null; } else { #region TcpInternalSimpleServer.@InputParameterTypeName _inputParameter_ = new TcpInternalSimpleServer.@InputParameterTypeName { @ParameterName = @ParameterName }; inputParameterLocalBuilder = methodGenerator.DeclareLocal(method.ParameterType.Type); LocalBuilder newInputParameterLocalBuilder = methodGenerator.DeclareLocal(method.ParameterType.Type); if (method.Attribute.IsInitobj || method.ParameterType.IsInitobj) { methodGenerator.Emit(OpCodes.Ldloca_S, newInputParameterLocalBuilder); methodGenerator.Emit(OpCodes.Initobj, method.ParameterType.Type); } parameterIndex = 0; foreach (ParameterInfo parameter in parameters) { ++parameterIndex; if (SimpleParameterType.IsInputParameter(parameter)) { methodGenerator.parameterToStructField(parameter, parameterIndex, newInputParameterLocalBuilder, method.ParameterType.GetField(parameter.Name)); } } methodGenerator.Emit(OpCodes.Ldloc_S, newInputParameterLocalBuilder); methodGenerator.Emit(OpCodes.Stloc_S, inputParameterLocalBuilder); #endregion } if (method.OutputParameterType == null) { #region AutoCSer.Net.TcpServer.ReturnType _returnType_ = _TcpClient_.Call(@MethodIdentityCommand, ref _inputParameter_); LocalBuilder returnTypeLocalBuilder = methodGenerator.DeclareLocal(typeof(AutoCSer.Net.TcpServer.ReturnType)); methodGenerator.Emit(OpCodes.Ldarg_0); methodGenerator.call(Metadata.MethodClientGetTcpClientMethod); methodGenerator.Emit(OpCodes.Ldsfld, commandInfoFieldBuilder); if (method.ParameterType == null) { methodGenerator.call(Metadata.ClientCallMethod); } else { methodGenerator.Emit(OpCodes.Ldloca_S, inputParameterLocalBuilder); //methodGenerator.call(Metadata.ClientCallInputMethod.MakeGenericMethod(method.ParameterType.Type)); methodGenerator.call(Metadata.GetParameterGenericType(method.ParameterType.Type).ClientCallMethod); } methodGenerator.Emit(OpCodes.Stloc_S, returnTypeLocalBuilder); #endregion if (method.ReturnValueType == null) { Label throwReturnTypeLabel = methodGenerator.DefineLabel(); #region if (_returnType_ == AutoCSer.Net.TcpServer.ReturnType.Success) return; methodGenerator.Emit(OpCodes.Ldloc_S, returnTypeLocalBuilder); methodGenerator.int32((byte)AutoCSer.Net.TcpServer.ReturnType.Success); methodGenerator.Emit(OpCodes.Bne_Un_S, throwReturnTypeLabel); methodGenerator.Emit(OpCodes.Ret); #endregion methodGenerator.MarkLabel(throwReturnTypeLabel); #region throw new Exception(AutoCSer.Net.TcpInternalServer.Emit.Client.ReturnTypeStrings[(byte)_returnType_]); methodGenerator.Emit(OpCodes.Ldsfld, TcpServer.Emit.ClientMetadata.ReturnTypeStringsField); methodGenerator.Emit(OpCodes.Ldloc_S, returnTypeLocalBuilder); methodGenerator.Emit(OpCodes.Ldelem_Ref); methodGenerator.call(AutoCSer.Extensions.EmitGenerator.NewExceptionStringMethodInfo); methodGenerator.Emit(OpCodes.Throw); #endregion } else { #region return new AutoCSer.Net.TcpServer.ReturnValue { Type = _returnType_ }; LocalBuilder returnReturnValueLocalBuilder = methodGenerator.DeclareLocal(method.ReturnValueType); //methodGenerator.Emit(OpCodes.Ldloca_S, returnReturnValueLocalBuilder); //methodGenerator.Emit(OpCodes.Initobj, method.ReturnValueType); methodGenerator.Emit(OpCodes.Ldloca_S, returnReturnValueLocalBuilder); methodGenerator.Emit(OpCodes.Ldloc_S, returnTypeLocalBuilder); methodGenerator.Emit(OpCodes.Stfld, TcpServer.Emit.ClientMetadata.ReturnValueTypeField); methodGenerator.Emit(OpCodes.Ldloc_S, returnReturnValueLocalBuilder); methodGenerator.Emit(OpCodes.Ret); #endregion } } else { #region TcpInternalSimpleServer.@OutputParameterTypeName _outputParameter_ = new TcpInternalSimpleServer.@OutputParameterTypeName { @ParameterName = @ParameterName }; LocalBuilder outputParameterLocalBuilder = methodGenerator.DeclareLocal(method.OutputParameterType.Type); if (method.Attribute.IsInitobj || method.OutputParameterType.IsInitobj) { methodGenerator.Emit(OpCodes.Ldloca_S, outputParameterLocalBuilder); methodGenerator.Emit(OpCodes.Initobj, method.OutputParameterType.Type); } parameterIndex = 0; foreach (ParameterInfo parameter in parameters) { ++parameterIndex; if (parameter.ParameterType.IsByRef) { methodGenerator.parameterToStructField(parameter, parameterIndex, outputParameterLocalBuilder, method.OutputParameterType.GetField(parameter.Name)); } } //if (method.ReturnInputParameter != null) //{ //} #endregion #region AutoCSer.Net.TcpServer.ReturnType _returnType_ = _TcpClient_.Get<TcpInternalSimpleServer.@InputParameterTypeName, TcpInternalSimpleServer.@OutputParameterTypeName>(@MethodIdentityCommand, ref _inputParameter_, ref _outputParameter_); LocalBuilder returnTypeLocalBuilder = methodGenerator.DeclareLocal(typeof(AutoCSer.Net.TcpServer.ReturnType)); methodGenerator.Emit(OpCodes.Ldarg_0); methodGenerator.call(Metadata.MethodClientGetTcpClientMethod); methodGenerator.Emit(OpCodes.Ldsfld, commandInfoFieldBuilder); if (method.ParameterType == null) { methodGenerator.Emit(OpCodes.Ldloca_S, outputParameterLocalBuilder); //methodGenerator.call(Metadata.ClientGetMethod.MakeGenericMethod(method.OutputParameterType.Type)); methodGenerator.call(Metadata.GetParameterGenericType(method.OutputParameterType.Type).ClientGetMethod); } else { methodGenerator.Emit(OpCodes.Ldloca_S, inputParameterLocalBuilder); methodGenerator.Emit(OpCodes.Ldloca_S, outputParameterLocalBuilder); //methodGenerator.call(Metadata.ClientGetInputMethod.MakeGenericMethod(method.ParameterType.Type, method.OutputParameterType.Type)); methodGenerator.call(Metadata.GetParameterGenericType2(method.ParameterType.Type, method.OutputParameterType.Type).ClientGetMethod); } methodGenerator.Emit(OpCodes.Stloc_S, returnTypeLocalBuilder); #endregion if (method.ReturnValueType == null) { Label throwReturnTypeLabel = methodGenerator.DefineLabel(); #region if (_returnType_ == AutoCSer.Net.TcpServer.ReturnType.Success) methodGenerator.Emit(OpCodes.Ldloc_S, returnTypeLocalBuilder); methodGenerator.int32((byte)AutoCSer.Net.TcpServer.ReturnType.Success); methodGenerator.Emit(OpCodes.Bne_Un, throwReturnTypeLabel); #endregion #region @ParameterName = _outputParameter_.@ParameterName; parameterIndex = 0; foreach (ParameterInfo parameter in parameters) { ++parameterIndex; if (parameter.ParameterType.IsByRef) { methodGenerator.outParameterFromValueField(parameter, parameterIndex, outputParameterLocalBuilder, method.OutputParameterType.GetField(parameter.Name)); } } #endregion if (method.ReturnType == typeof(void)) { #region return; methodGenerator.Emit(OpCodes.Ret); #endregion } else { #region return _outputParameter_.Ret; methodGenerator.Emit(OpCodes.Ldloca_S, outputParameterLocalBuilder); methodGenerator.Emit(OpCodes.Ldfld, method.OutputParameterType.GetField(TcpServer.ReturnValue.RetParameterName)); //methodGenerator.Emit(OpCodes.Stloc_S, returnValueLocalBuilder); //methodGenerator.Emit(OpCodes.Ldloc_S, returnValueLocalBuilder); methodGenerator.Emit(OpCodes.Ret); #endregion } methodGenerator.MarkLabel(throwReturnTypeLabel); #region throw new Exception(AutoCSer.Net.TcpServer.Emit.Client.ReturnTypeStrings[(byte)_returnType_]); methodGenerator.Emit(OpCodes.Ldsfld, TcpServer.Emit.ClientMetadata.ReturnTypeStringsField); methodGenerator.Emit(OpCodes.Ldloc_S, returnTypeLocalBuilder); methodGenerator.Emit(OpCodes.Ldelem_Ref); methodGenerator.call(AutoCSer.Extensions.EmitGenerator.NewExceptionStringMethodInfo); methodGenerator.Emit(OpCodes.Throw); #endregion } else { #region @ParameterName = _outputParameter_.@ParameterName; parameterIndex = 0; foreach (ParameterInfo parameter in parameters) { ++parameterIndex; if (parameter.ParameterType.IsByRef) { methodGenerator.outParameterFromValueField(parameter, parameterIndex, outputParameterLocalBuilder, method.OutputParameterType.GetField(parameter.Name)); } } #endregion #region return new AutoCSer.Net.TcpServer.ReturnValue<@MethodReturnType.FullName> { Type = _returnType_, Value = _outputParameter_.Return }; LocalBuilder returnReturnValueLocalBuilder = methodGenerator.DeclareLocal(method.ReturnValueType); if (method.ReturnType == typeof(void)) { methodGenerator.Emit(OpCodes.Ldloca_S, returnReturnValueLocalBuilder); methodGenerator.Emit(OpCodes.Ldloc_S, returnTypeLocalBuilder); methodGenerator.Emit(OpCodes.Stfld, TcpServer.Emit.ClientMetadata.ReturnValueTypeField); } else { if (method.Attribute.IsInitobj || method.ReturnType.isInitobj()) { methodGenerator.Emit(OpCodes.Ldloca_S, returnReturnValueLocalBuilder); methodGenerator.Emit(OpCodes.Initobj, method.ReturnValueType); } methodGenerator.Emit(OpCodes.Ldloca_S, returnReturnValueLocalBuilder); methodGenerator.Emit(OpCodes.Ldloc_S, returnTypeLocalBuilder); methodGenerator.Emit(OpCodes.Stfld, method.ReturnValueType.GetField(TcpServer.Emit.ClientMetadata.ReturnValueTypeField.Name, BindingFlags.Instance | BindingFlags.Public)); methodGenerator.Emit(OpCodes.Ldloca_S, returnReturnValueLocalBuilder); methodGenerator.Emit(OpCodes.Ldloca_S, outputParameterLocalBuilder); methodGenerator.Emit(OpCodes.Ldfld, method.OutputParameterType.GetField(TcpServer.ReturnValue.RetParameterName)); methodGenerator.Emit(OpCodes.Stfld, method.ReturnValueType.GetField("Value", BindingFlags.Instance | BindingFlags.Public)); } methodGenerator.Emit(OpCodes.Ldloc_S, returnReturnValueLocalBuilder); methodGenerator.Emit(OpCodes.Ret); #endregion } } methodGenerator.MarkLabel(clientExceptionLabel); if (method.ReturnValueType == null) { #region throw new Exception(AutoCSer.Net.TcpServer.ReturnType.ClientException.ToString()); methodGenerator.throwString(AutoCSer.Net.TcpServer.ReturnType.ClientException.ToString()); #endregion } else { #region @ParameterName = default(@ParameterType.FullName); parameterIndex = 0; foreach (ParameterInfo parameter in parameters) { ++parameterIndex; if (parameter.IsOut) { methodGenerator.outParameterDefault(parameter, parameterIndex, method.Attribute.IsInitobj); } } #endregion #region return new AutoCSer.Net.TcpServer.ReturnValue<@MethodReturnType.FullName> { Type = AutoCSer.Net.TcpServer.ReturnType.ClientException }; LocalBuilder returnReturnValueLocalBuilder = methodGenerator.DeclareLocal(method.ReturnValueType); if (method.ReturnType != typeof(void) && method.ReturnType.isInitobj()) { methodGenerator.Emit(OpCodes.Ldloca_S, returnReturnValueLocalBuilder); methodGenerator.Emit(OpCodes.Initobj, method.ReturnValueType); } methodGenerator.Emit(OpCodes.Ldloca_S, returnReturnValueLocalBuilder); methodGenerator.int32((byte)AutoCSer.Net.TcpServer.ReturnType.ClientException); methodGenerator.Emit(OpCodes.Stfld, method.ReturnType == typeof(void) ? TcpServer.Emit.ClientMetadata.ReturnValueTypeField : method.ReturnValueType.GetField(TcpServer.Emit.ClientMetadata.ReturnValueTypeField.Name, BindingFlags.Instance | BindingFlags.Public)); methodGenerator.Emit(OpCodes.Ldloc_S, returnReturnValueLocalBuilder); methodGenerator.Emit(OpCodes.Ret); #endregion } } } else if (method.IsPropertySetMethod) { if (method.PropertyBuilder != null || method.PropertyGetMethod == null) { ParameterInfo[] parameters = method.MethodInfo.GetParameters(); PropertyBuilder propertyBuilder = method.PropertyBuilder ?? typeBuilder.DefineProperty(method.PropertyInfo.Name, PropertyAttributes.HasDefault, parameters[parameters.Length - 1].ParameterType, new LeftArray <ParameterInfo> { Array = parameters, Length = parameters.Length - 1 }.GetArray(parameter => parameter.ParameterType)); MethodBuilder setMethodBuilder = typeBuilder.DefineMethod(method.MethodInfo.Name, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig | MethodAttributes.Virtual, method.MethodInfo.ReturnType, parameters.getArray(parameter => parameter.ParameterType)); ILGenerator methodGenerator = setMethodBuilder.GetILGenerator(); //XXX propertyBuilder.SetSetMethod(setMethodBuilder); method.PropertyBuilder = null; } } else { Type[] parameterTypes = method.MethodInfo.GetParameters().getArray(parameter => parameter.ParameterType); PropertyBuilder propertyBuilder = typeBuilder.DefineProperty(method.PropertyInfo.Name, PropertyAttributes.HasDefault, method.MethodInfo.ReturnType, parameterTypes); MethodBuilder getMethodBuilder = typeBuilder.DefineMethod(method.MethodInfo.Name, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig | MethodAttributes.Virtual, method.MethodInfo.ReturnType, parameterTypes); ILGenerator methodGenerator = getMethodBuilder.GetILGenerator(); //XXX propertyBuilder.SetGetMethod(getMethodBuilder); if (method.PropertySetMethod != null) { method = method.PropertySetMethod; method.PropertyBuilder = propertyBuilder; goto METHOD; } } } } staticConstructorGenerator.Emit(OpCodes.Ret); return(typeBuilder.CreateType()); }