private static void ProxyInvoke(CodeWriter w, Action<object[]> Transmit, MethodInfo ik, byte CLA, APDUInstructionAttribute INS) { var p = ik.GetParameters(); Func<Type, string> GetCleanName = t => { var prefix = t.Name + "_"; if (ik.Name.StartsWith(prefix)) return ik.Name.Substring(prefix.Length); return ik.Name; }; if (INS.InputParameterType != null) w.Block("partial class " + INS.InputParameterType.Name, delegate { var CleanName = GetCleanName(INS.InputParameterType); if (p.Length == 2 && p[1].ParameterType == typeof(short)) { var Pi8 = p[1]; if (INS.OutputParameterType != null) w.Block("public " + INS.OutputParameterType.Name + " " + CleanName + "(params byte[] data)", delegate { w.Statement("return FromBytes(this.Host, this.Host." + ik.Name + "(this.Token, data));"); } ); else { w.Block("public byte[] " + CleanName + "(params byte[] data)", delegate { w.Statement("return this.Host." + ik.Name + "(this.Token, data);"); } ); // jsc has a nasty bug for nested params method invocation... could cause out of stack error w.Block("public byte[] " + CleanName + "()", delegate { w.Statement("var data = new byte[0];"); w.Statement("return this.Host." + ik.Name + "(this.Token, data);"); } ); } } } ); if (INS.OutputParameterType != null) w.Block("partial class " + INS.OutputParameterType.Name, delegate { var CleanName = GetCleanName(INS.OutputParameterType); if (p.Length == 2 && p[1].ParameterType == typeof(short)) { var Pi8 = p[1]; if (INS.InputParameterType != null) w.Block("static public " + INS.OutputParameterType.Name + " " + CleanName + "(" + ik.DeclaringType.Name + "Proxy host, " + INS.InputParameterType.Name + " token, params byte[] data)", delegate { w.Statement("return " + CleanName + "(host, (short)token, data);"); } ); w.Block("static public " + INS.OutputParameterType.Name + " " + CleanName + "(" + ik.DeclaringType.Name + "Proxy host, short " + Pi8.Name + ", params byte[] data)", delegate { w.Statement("return FromBytes(host, host." + ik.Name + "(" + Pi8.Name + ", data));"); } ); } } ); if (p.Length == 1) { w.Statement("[System.Diagnostics.DebuggerNonUserCode]"); w.Block("public byte[] " + ik.Name + "(params byte[] data)", delegate { w.Statement("var c = new System.IO.MemoryStream();"); w.Statement("c.WriteByte(" + CLA.ToHexLiteral() + ");"); w.Statement("c.WriteByte(" + INS.INS.ToHexLiteral() + ");"); w.Statement("c.WriteByte(" + 0 + ");"); w.Statement("c.WriteByte(" + 0 + ");"); w.Statement("c.WriteByte((byte)data.Length);"); w.Statement("c.Write(data, 0, data.Length);"); w.Statement("return InternalTransmit(c.ToArray());"); } ); return; } if (p.Length == 2 && p[1].ParameterType == typeof(short)) { var Pi8 = p[1]; w.Statement("[System.Diagnostics.DebuggerNonUserCode]"); w.Block("public byte[] " + ik.Name + "(short " + Pi8.Name + ", params byte[] data)", delegate { w.Statement("var c = new System.IO.MemoryStream();"); w.Statement("c.WriteByte(" + CLA.ToHexLiteral() + ");"); w.Statement("c.WriteByte(" + INS.INS.ToHexLiteral() + ");"); w.Statement("c.WriteByte(" + "(byte)((" + Pi8.Name + " >> 8) & 0xff)" + ");"); w.Statement("c.WriteByte(" + "(byte)(" + Pi8.Name + " & 0xff)" + ");"); w.Block("if (data.Length > 0)", delegate { w.Statement("c.WriteByte((byte)data.Length);"); w.Statement("c.Write(data, 0, data.Length);"); } ); w.Block("if (this.IsLengthExpectedSpecified)", delegate { w.Statement("c.WriteByte(this.LengthExpected);"); } ); w.Statement("return InternalTransmit(c.ToArray());"); } ); return; } if (p.Length == 3 && (p[1].ParameterType == typeof(byte) || (p[1].ParameterType.IsEnum && Enum.GetUnderlyingType(p[1].ParameterType) == typeof(byte))) && (p[2].ParameterType == typeof(byte) || (p[2].ParameterType.IsEnum && Enum.GetUnderlyingType(p[2].ParameterType) == typeof(byte))) ) { var P1 = p[1]; var P2 = p[2]; var P1_HasDefault = (P1.Attributes & ParameterAttributes.HasDefault) == ParameterAttributes.HasDefault; var P2_HasDefault = (P2.Attributes & ParameterAttributes.HasDefault) == ParameterAttributes.HasDefault; var DataParameters = new ParameterInfo[0]; if (INS.DataParameters != null && INS.DataParameters.BaseType == typeof(MulticastDelegate)) { DataParameters = INS.DataParameters.GetMethod("Invoke").GetParameters(); } #region ParameterString var ParameterString = new StringBuilder(); ParameterString.Append("public byte[] " + ik.Name + "("); if (!P1_HasDefault) { ParameterString.Append(P1.ParameterType.ToPrimitiveName()); ParameterString.Append(" " + P1.Name + ", "); } if (!P2_HasDefault) { ParameterString.Append(P2.ParameterType.ToPrimitiveName()); ParameterString.Append(" " + P2.Name + ", "); } if (DataParameters.Length > 0) { for (int i = 0; i < DataParameters.Length; i++) { if (i > 0) ParameterString.Append(", "); ParameterString.Append(DataParameters[i].ParameterType.ToPrimitiveName()); ParameterString.Append(" "); ParameterString.Append(DataParameters[i].Name); } } else { ParameterString.Append("params byte[] data"); } ParameterString.Append(")"); #endregion w.Statement("[System.Diagnostics.DebuggerNonUserCode]"); w.Block(ParameterString.ToString(), delegate { #region datac if (DataParameters.Length > 0) w.Region("data", delegate { w.Statement("var datac = new System.IO.MemoryStream();"); foreach (var datap in DataParameters) { if (datap.ParameterType == typeof(string)) { w.Statement("foreach (var datap in " + datap.Name + ") datac.WriteByte((byte)datap);"); } } w.Statement("var data = datac.ToArray();"); } ); #endregion w.Statement("var c = new System.IO.MemoryStream();"); w.Statement("c.WriteByte(" + CLA.ToHexLiteral() + ");"); w.Statement("c.WriteByte(" + INS.INS.ToHexLiteral() + ");"); w.Statement("c.WriteByte((byte)" + (P1_HasDefault ? P1.DefaultValue : P1.Name) + ");"); w.Statement("c.WriteByte((byte)" + (P2_HasDefault ? P2.DefaultValue : P2.Name) + ");"); w.Block("if (data.Length > 0)", delegate { w.Statement("c.WriteByte((byte)data.Length);"); w.Statement("c.Write(data, 0, data.Length);"); } ); w.Block("if (this.IsLengthExpectedSpecified)", delegate { w.Statement("c.WriteByte(this.LengthExpected);"); } ); w.Statement("return InternalTransmit(c.ToArray());"); } ); return; } }
private static void ProxyInvoke(CodeWriter w, Action <object[]> Transmit, MethodInfo ik, byte CLA, APDUInstructionAttribute INS) { var p = ik.GetParameters(); Func <Type, string> GetCleanName = t => { var prefix = t.Name + "_"; if (ik.Name.StartsWith(prefix)) { return(ik.Name.Substring(prefix.Length)); } return(ik.Name); }; if (INS.InputParameterType != null) { w.Block("partial class " + INS.InputParameterType.Name, delegate { var CleanName = GetCleanName(INS.InputParameterType); if (p.Length == 2 && p[1].ParameterType == typeof(short)) { var Pi8 = p[1]; if (INS.OutputParameterType != null) { w.Block("public " + INS.OutputParameterType.Name + " " + CleanName + "(params byte[] data)", delegate { w.Statement("return FromBytes(this.Host, this.Host." + ik.Name + "(this.Token, data));"); } ); } else { w.Block("public byte[] " + CleanName + "(params byte[] data)", delegate { w.Statement("return this.Host." + ik.Name + "(this.Token, data);"); } ); // jsc has a nasty bug for nested params method invocation... could cause out of stack error w.Block("public byte[] " + CleanName + "()", delegate { w.Statement("var data = new byte[0];"); w.Statement("return this.Host." + ik.Name + "(this.Token, data);"); } ); } } } ); } if (INS.OutputParameterType != null) { w.Block("partial class " + INS.OutputParameterType.Name, delegate { var CleanName = GetCleanName(INS.OutputParameterType); if (p.Length == 2 && p[1].ParameterType == typeof(short)) { var Pi8 = p[1]; if (INS.InputParameterType != null) { w.Block("static public " + INS.OutputParameterType.Name + " " + CleanName + "(" + ik.DeclaringType.Name + "Proxy host, " + INS.InputParameterType.Name + " token, params byte[] data)", delegate { w.Statement("return " + CleanName + "(host, (short)token, data);"); } ); } w.Block("static public " + INS.OutputParameterType.Name + " " + CleanName + "(" + ik.DeclaringType.Name + "Proxy host, short " + Pi8.Name + ", params byte[] data)", delegate { w.Statement("return FromBytes(host, host." + ik.Name + "(" + Pi8.Name + ", data));"); } ); } } ); } if (p.Length == 1) { w.Statement("[System.Diagnostics.DebuggerNonUserCode]"); w.Block("public byte[] " + ik.Name + "(params byte[] data)", delegate { w.Statement("var c = new System.IO.MemoryStream();"); w.Statement("c.WriteByte(" + CLA.ToHexLiteral() + ");"); w.Statement("c.WriteByte(" + INS.INS.ToHexLiteral() + ");"); w.Statement("c.WriteByte(" + 0 + ");"); w.Statement("c.WriteByte(" + 0 + ");"); w.Statement("c.WriteByte((byte)data.Length);"); w.Statement("c.Write(data, 0, data.Length);"); w.Statement("return InternalTransmit(c.ToArray());"); } ); return; } if (p.Length == 2 && p[1].ParameterType == typeof(short)) { var Pi8 = p[1]; w.Statement("[System.Diagnostics.DebuggerNonUserCode]"); w.Block("public byte[] " + ik.Name + "(short " + Pi8.Name + ", params byte[] data)", delegate { w.Statement("var c = new System.IO.MemoryStream();"); w.Statement("c.WriteByte(" + CLA.ToHexLiteral() + ");"); w.Statement("c.WriteByte(" + INS.INS.ToHexLiteral() + ");"); w.Statement("c.WriteByte(" + "(byte)((" + Pi8.Name + " >> 8) & 0xff)" + ");"); w.Statement("c.WriteByte(" + "(byte)(" + Pi8.Name + " & 0xff)" + ");"); w.Block("if (data.Length > 0)", delegate { w.Statement("c.WriteByte((byte)data.Length);"); w.Statement("c.Write(data, 0, data.Length);"); } ); w.Block("if (this.IsLengthExpectedSpecified)", delegate { w.Statement("c.WriteByte(this.LengthExpected);"); } ); w.Statement("return InternalTransmit(c.ToArray());"); } ); return; } if (p.Length == 3 && (p[1].ParameterType == typeof(byte) || (p[1].ParameterType.IsEnum && Enum.GetUnderlyingType(p[1].ParameterType) == typeof(byte))) && (p[2].ParameterType == typeof(byte) || (p[2].ParameterType.IsEnum && Enum.GetUnderlyingType(p[2].ParameterType) == typeof(byte))) ) { var P1 = p[1]; var P2 = p[2]; var P1_HasDefault = (P1.Attributes & ParameterAttributes.HasDefault) == ParameterAttributes.HasDefault; var P2_HasDefault = (P2.Attributes & ParameterAttributes.HasDefault) == ParameterAttributes.HasDefault; var DataParameters = new ParameterInfo[0]; if (INS.DataParameters != null && INS.DataParameters.BaseType == typeof(MulticastDelegate)) { DataParameters = INS.DataParameters.GetMethod("Invoke").GetParameters(); } #region ParameterString var ParameterString = new StringBuilder(); ParameterString.Append("public byte[] " + ik.Name + "("); if (!P1_HasDefault) { ParameterString.Append(P1.ParameterType.ToPrimitiveName()); ParameterString.Append(" " + P1.Name + ", "); } if (!P2_HasDefault) { ParameterString.Append(P2.ParameterType.ToPrimitiveName()); ParameterString.Append(" " + P2.Name + ", "); } if (DataParameters.Length > 0) { for (int i = 0; i < DataParameters.Length; i++) { if (i > 0) { ParameterString.Append(", "); } ParameterString.Append(DataParameters[i].ParameterType.ToPrimitiveName()); ParameterString.Append(" "); ParameterString.Append(DataParameters[i].Name); } } else { ParameterString.Append("params byte[] data"); } ParameterString.Append(")"); #endregion w.Statement("[System.Diagnostics.DebuggerNonUserCode]"); w.Block(ParameterString.ToString(), delegate { #region datac if (DataParameters.Length > 0) { w.Region("data", delegate { w.Statement("var datac = new System.IO.MemoryStream();"); foreach (var datap in DataParameters) { if (datap.ParameterType == typeof(string)) { w.Statement("foreach (var datap in " + datap.Name + ") datac.WriteByte((byte)datap);"); } } w.Statement("var data = datac.ToArray();"); } ); } #endregion w.Statement("var c = new System.IO.MemoryStream();"); w.Statement("c.WriteByte(" + CLA.ToHexLiteral() + ");"); w.Statement("c.WriteByte(" + INS.INS.ToHexLiteral() + ");"); w.Statement("c.WriteByte((byte)" + (P1_HasDefault ? P1.DefaultValue : P1.Name) + ");"); w.Statement("c.WriteByte((byte)" + (P2_HasDefault ? P2.DefaultValue : P2.Name) + ");"); w.Block("if (data.Length > 0)", delegate { w.Statement("c.WriteByte((byte)data.Length);"); w.Statement("c.Write(data, 0, data.Length);"); } ); w.Block("if (this.IsLengthExpectedSpecified)", delegate { w.Statement("c.WriteByte(this.LengthExpected);"); } ); w.Statement("return InternalTransmit(c.ToArray());"); } ); return; } }