// 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 { public class CallText { public static string Write2(CallMethod callMethod, string[][] parameters, string[][] constructorArguments) { StringBuilder text = new StringBuilder(); if (callMethod.Host != null) { text.Append("Host\t"); text.AppendLine(callMethod.Host); } if (callMethod.Queue != null) { text.Append("Queue\t"); text.AppendLine(callMethod.Queue); } text.Append("Assembly\t"); text.AppendLine(callMethod.Assembly); text.Append("Type\t"); text.AppendLine(callMethod.Type); text.Append("Method\t"); text.AppendLine(callMethod.Method); if (callMethod.Flags != CallFlags.None) { text.Append("Flags\t"); text.AppendLine(callMethod.Flags.ToString().Replace(",", " |")); } WriteParameters(text, parameters, "P"); if (constructorArguments != null) WriteParameters(text, constructorArguments, "C"); return text.ToString(); } private static void WriteParameters(StringBuilder text, string[][] parameters, string prefix) { if (parameters == null) return; for (int index = 0; index < parameters.Length; ++index) { string parameterType = parameters[index][0]; string parameterData = parameters[index][1]; string parameterName = null; if (parameters[index].Length > 2) parameterName = parameters[index][2]; if (parameterType.StartsWith("@") == false && parameterType != "null") { Type type = Type.GetType(parameterType, true, false); if (Spludlow.SimpleEncoding.IsSimple(type) == true) { parameterType = type.Name; if (parameterData != null) { object data = Spludlow.Parameters.DecodeParameter(parameters[index]); parameterData = Spludlow.SimpleEncoding.Encode(data, type.Name); } } else { if (parameterData != null) { string filename = Spludlow.WebServices.CreateProgramDataTempFilename(".txt"); File.WriteAllText(filename, parameterData); parameterType = "@" + parameterType; parameterData = filename; } } } text.Append(prefix); text.Append(index.ToString("00")); text.Append("\t"); text.Append(parameterName); text.Append("\t"); text.Append(parameterType); text.Append("\t"); text.Append(parameterData); text.AppendLine(); } } public static CallMethod Read(string callText) { CallMethod callMethod = new CallMethod(); using (StringReader reader = new StringReader(callText)) Read(callMethod, new string[] { "@" }, 0, reader); return callMethod; } public static void Read(CallMethod callMethod, string[] words, int startIndex, TextReader reader) { bool hasBody = false; Dictionary parameters = new Dictionary(); Dictionary constructors = new Dictionary(); int lineParamIndex = 0; for (int index = startIndex; index < words.Length; ++index) { string word = words[index]; if (word == "@") { hasBody = true; break; } switch (index - startIndex) { case 0: callMethod.Assembly = word; break; case 1: callMethod.Type = word; break; case 2: callMethod.Method = word; break; default: int calclineParamIndex = index - startIndex - 3; if (calclineParamIndex != lineParamIndex) throw new ApplicationException("bas calc"); Type type = Spludlow.SimpleEncoding.Guess(word); object data = Spludlow.SimpleEncoding.Decode(word, type.Name); parameters.Add(lineParamIndex, Spludlow.Parameters.EncodeParameter(data, false, false)); ++lineParamIndex; break; } } if (hasBody == true) { if (reader == null) throw new ApplicationException("No body after @ in call text."); string line; while ((line = reader.ReadLine()) != null) { if (line.StartsWith("#") == true) continue; if (line.Length == 0) break; words = Spludlow.Text.Split(line, '\t', true); string firstWord = words[0].ToLower(); switch (firstWord) { case "host": callMethod.Host = words[1]; break; case "queue": callMethod.Queue = words[1]; break; case "assembly": callMethod.Assembly = words[1]; break; case "type": callMethod.Type = words[1]; break; case "method": callMethod.Method = words[1]; break; case "flags": callMethod.Flags = Spludlow.CallFlag.Parse(words[1]); break; default: if (firstWord.StartsWith("c") == false || firstWord.StartsWith("p") == false) { int index = 0; if (firstWord.Length > 1) index = Int32.Parse(firstWord.Substring(1)); string parameterName = words[1]; string parameterTypeName = words[2]; string[] pair; if (parameterTypeName.StartsWith("@") == true) { pair = new string[] { parameterTypeName, words[3] }; } else { object data = null; if (words.Length > 3) { StringBuilder dataText = new StringBuilder(); for (int arrayIndex = 3; arrayIndex < words.Length; ++arrayIndex) { if (dataText.Length > 0) dataText.Append("\t"); dataText.Append(words[arrayIndex]); } data = Spludlow.SimpleEncoding.Decode(dataText.ToString(), parameterTypeName); } pair = Spludlow.Parameters.EncodeParameter(data, false, false); } pair = new string[] { pair[0], pair[1], parameterName }; if (firstWord.StartsWith("c") == true) constructors.Add(index, pair); else parameters.Add(index, pair); } break; } } } callMethod.Parameters = MakeArray(parameters); callMethod.ConstructorArguments = MakeArray(constructors); } public static string[][] MakeArray(Dictionary dictionary) { int maxIndex = -1; foreach (int index in dictionary.Keys) maxIndex = Math.Max(maxIndex, index); if (maxIndex == -1) return null; List result = new List(); for (int index = 0; index <= maxIndex; ++index) { if (dictionary.ContainsKey(index) == true) result.Add(dictionary[index]); else result.Add(Spludlow.Parameters.EncodedNull); } return result.ToArray(); } } }