// Spludlow Software // Copyright © Samuel P. Ludlow 2020 All Rights Reserved // Distributed under the terms of the GNU General Public License version 3 // Distributed WITHOUT ANY WARRANTY; without implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE // https://www.spludlow.co.uk/LICENCE.TXT // The Spludlow logo is a registered trademark of Samuel P. Ludlow and may not be used without permission // v1.14 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.IO; namespace Spludlow { [Serializable] public class CallMethod { public string Host; // H public string Queue; // Q public string Assembly; // A T M public string Type; public string Method; public string[][] Parameters; // P0 public string[][] ConstructorArguments; // C0 public Spludlow.CallFlags Flags; // F public int PrevResultParamIndex; // I public string[] Result; public string PickUpQueue; public string ManagedResultsAddress; public string ManagedResultsKey; public int ManagedResultsIndex; public CallMethod() { } public CallMethod( string address, string assembly, string type, string method) { this.Construct(address, assembly, type, method, null, null, Spludlow.CallFlags.None, -1); } public CallMethod( string address, string assembly, string type, string method, object[] parameters) { this.Construct(address, assembly, type, method, parameters, null, Spludlow.CallFlags.None, -1); } public CallMethod( string address, string assembly, string type, string method, object[] parameters, Spludlow.CallFlags flags) { this.Construct(address, assembly, type, method, parameters, null, flags, -1); } public CallMethod( string address, string assembly, string type, string method, object[] parameters, Spludlow.CallFlags flags, int prevResultParamIndex) { this.Construct(address, assembly, type, method, parameters, null, flags, prevResultParamIndex); } public CallMethod( string address, string assembly, string type, string method, object[] parameters, object[] constructorArguments, Spludlow.CallFlags flags, int prevResultParamIndex) { this.Construct(address, assembly, type, method, parameters, constructorArguments, flags, prevResultParamIndex); } public string Address { get { if (this.Queue == null) return this.Host; return this.Host + ":" + this.Queue; } } public CallMethod(Dictionary> arguments) { if (arguments.ContainsKey("") == true) { if (arguments.Keys.Count > 1) throw new ApplicationException("Can not mix shorthand ATM with specified arguments."); List words = arguments[""]; if (words.Count < 3) throw new ApplicationException("Must specify at least A T M."); CallText.Read(this, words.ToArray(), 0, null); } else { this.Host = Arguments.LastValue(arguments, "host"); this.Queue = Arguments.LastValue(arguments, "queue"); this.Assembly = Arguments.LastValue(arguments, "assembly"); this.Type = Arguments.LastValue(arguments, "type"); this.Method = Arguments.LastValue(arguments, "method"); this.Flags = CallFlag.Parse(Arguments.LastValue(arguments, "flags")); this.PrevResultParamIndex = -1; string arg = Arguments.LastValue(arguments, "index"); if (arg != null) this.PrevResultParamIndex = Int32.Parse(arg); this.Parameters = EncodeParameters("parameters", arguments); this.ConstructorArguments = EncodeParameters("constructor", arguments); } this.Result = null; } public string[][] EncodeParameters(string prefix, Dictionary> arguments) { Dictionary parameters = new Dictionary(); if (arguments.ContainsKey(prefix) == true) { for (int index = 0; index < arguments[prefix].Count; ++index) { string text = arguments[prefix][index]; Type type = Spludlow.SimpleEncoding.Guess(text); object data = Spludlow.SimpleEncoding.Decode(text, type.Name); parameters.Add(index, Spludlow.Parameters.EncodeParameter(data, false, false)); } } foreach (string key in arguments.Keys) { if (key.StartsWith(prefix) == false || key.Length == prefix.Length) continue; StringBuilder textData = new StringBuilder(); for (int arrayIndex = 0; arrayIndex < arguments[key].Count; ++arrayIndex) { if (textData.Length > 0) textData.Append("\t"); textData.Append(arguments[key][arrayIndex]); } int typeIndex = -1; for (int keyIndex = prefix.Length; keyIndex < key.Length; ++keyIndex) { if (Char.IsDigit(key[keyIndex]) == false) { typeIndex = keyIndex; break; } } string text = textData.ToString(); int index; string typeName; if (typeIndex == -1) { index = Int32.Parse(key.Substring(prefix.Length)); Type type = Spludlow.SimpleEncoding.Guess(text); typeName = type.Name; } else { index = Int32.Parse(key.Substring(prefix.Length, typeIndex - prefix.Length)); typeName = key.Substring(typeIndex); } object data = Spludlow.SimpleEncoding.Decode(text, typeName); parameters.Add(index, Spludlow.Parameters.EncodeParameter(data, false, false)); } return Spludlow.CallText.MakeArray(parameters); } public void SetAddress(string address) { string[] hostQueue = Spludlow.Call.SplitAddress(address); this.Host = hostQueue[0]; this.Queue = hostQueue[1]; } private void Construct( string address, string assembly, string type, string method, object[] parameters, object[] constructorArguments, Spludlow.CallFlags flags, int prevResultParamIndex) { if (address != null) this.SetAddress(address); this.Assembly = assembly; this.Type = type; this.Method = method; bool large = flags.HasFlag(Spludlow.CallFlags.LargeParameters); bool store = flags.HasFlag(Spludlow.CallFlags.StoreParameters); string uploadHost = null; if (this.Host != null && this.Queue == null) uploadHost = this.Host; this.Parameters = Spludlow.Parameters.EncodeParameters(parameters, large, store); this.ConstructorArguments = Spludlow.Parameters.EncodeParameters(constructorArguments, large, store); this.Flags = flags; this.PrevResultParamIndex = prevResultParamIndex; this.Result = null; } } }