private static string ExecuteRequest(ArmaRequest request) { _inputBuffer = ""; if (!AvailableExtensions.ContainsKey(request.ExtensionName)) { throw new ArgumentException($"Extension is not valid: {request.ExtensionName}"); } var function = FunctionLoader.LoadFunction <CLibFuncDelegate>(AvailableExtensions[request.ExtensionName], request.ActionName); if (request.TaskId == -1) { return(ControlCharacter.STX + function(request.Data) + ControlCharacter.EOT); } var task = Task.Run(() => function(request.Data)); if (Tasks.ContainsKey(request.TaskId)) { Tasks.Remove(request.TaskId); } Tasks.Add(request.TaskId, task); return((ControlCharacter.ACK).ToString()); }
public static ArmaRequest Parse(string input) { int headerStart = input.IndexOf(ControlCharacter.SOH); int textStart = input.IndexOf(ControlCharacter.STX); int textEnd = input.IndexOf(ControlCharacter.ETX); string header = input.Substring(headerStart < 0 ? 0 : headerStart + 1, (textStart < 0 ? input.Length : textStart) - 1); string[] headerValues = header.Split(new [] { ControlCharacter.US }, 3); var request = new ArmaRequest(); int taskId; if (!int.TryParse(headerValues[0], out taskId)) { throw new ArgumentException($"Invalid task id: {headerValues[0]}"); } request.TaskId = taskId; request.ExtensionName = headerValues[1].Trim(); request.ActionName = headerValues[2].Trim(); request.Data = textStart < 0 ? "" : input.Substring(textStart + 1, textEnd - textStart - 1); return(request); }
public static void RVExtension(StringBuilder output, int outputSize, [MarshalAs(UnmanagedType.LPStr)] string input) { outputSize--; switch (input) { case "": return; case "debugger": Debugger.Toggle(); return; case "version": output.Append(DllEntry.GetVersion()); break; default: switch (input[0]) { case ControlCharacter.ACK: output.Append(DllEntry._outputBuffer); break; case ControlCharacter.ENQ: if (Tasks.Count == 0) { break; } try { var completedTasksIndices = new List <int>(); foreach (var taskEntry in Tasks) { if (!taskEntry.Value.IsCompleted) { continue; } try { output.Append(ControlCharacter.SOH + taskEntry.Key.ToString() + ControlCharacter.STX + taskEntry.Value.Result); } catch (Exception e) { output.Append(ControlCharacter.SOH + taskEntry.Key.ToString() + ControlCharacter.STX); if (e is AggregateException) { ((AggregateException)e).Handle(x => { output.Append(x.Message + "\n"); return(true); }); } else { output.Append(e.Message); } } Debugger.Log("Task result: " + taskEntry.Key); completedTasksIndices.Add(taskEntry.Key); } foreach (int index in completedTasksIndices) { Tasks.Remove(index); } output.Append(ControlCharacter.EOT); } catch (Exception e) { Debugger.Log(e); output.Append(e.Message); } break; default: try { _inputBuffer += input; if (_inputBuffer[_inputBuffer.Length - 1] == ControlCharacter.ETX) { output.Append(ExecuteRequest(ArmaRequest.Parse(_inputBuffer))); } else { output.Append(ControlCharacter.ACK); } } catch (Exception e) { output.Append(e.Message); } break; } break; } List <byte> outputBytes = Encoding.Default.GetBytes(output.ToString()).ToList(); if (outputBytes.Count <= outputSize) { return; } int outputSplitPosition = outputSize; while ((outputBytes[outputSplitPosition - 1] & 0xC0) == 0x80) { outputSplitPosition--; } DllEntry._outputBuffer = Encoding.Default.GetString(outputBytes.GetRange(outputSplitPosition, outputBytes.Count - outputSplitPosition).ToArray()); output = output.Remove(output.Length - DllEntry._outputBuffer.Length, DllEntry._outputBuffer.Length); }