public asapJson.JsonNode ReadMessage(Func <asapJson.JsonNode, bool> cond) { while (true) { SpinWait.SpinUntil(() => this.Messages.Count > 0); var temp = new List <asapJson.JsonNode>(); asapJson.JsonNode y = null; while (!this.Messages.IsEmpty) //Would be more efficient to use a ConcurrentSet { this.Messages.TryTake(out y); if (cond.Invoke(y)) { break; } temp.Add(y); } foreach (var item in temp) { this.Messages.Add(item); //Add back Items that didn't match } if (y != null) { return(y); } } }
public IEnumerable <Variable> GetVariables(EVariableNamespace scope, params string[] names) { var command = new asapJson.JsonNode(new Dictionary <string, asapJson.JsonNode>()); command.GetValue_Object()["command"] = new asapJson.JsonNode((int)ESendCommands.GetVariable); var data = command.GetValue_Object()["data"] = new asapJson.JsonNode(new Dictionary <string, asapJson.JsonNode>()); data.GetValue_Object()["name"] = new asapJson.JsonNode(names.Select(name => new asapJson.JsonNode(name))); data.GetValue_Object()["scope"] = new asapJson.JsonNode((int)scope); this.WriteMessage(command); var response = this.ReadMessage((node) => (int)(node.GetValue_Object()["command"].GetValue_Number()) == (int)ERecvCommands.VariablesList); var variables = response.GetValue_Object()["data"]; if (variables.GetValueType() == JsonNode.EJType.Array) //Might be null if no variables found { foreach (var variable in variables.GetValue_Array()) { var name = variable.GetValue_Object()["name"].GetValue_String(); var type = variable.GetValue_Object()["type"].GetValue_String(); var value = ""; switch (type) { case "void": yield return(new Variable() { Name = name, Value = value, VariableType = Variable.ValueType.ANY }); break; case "array": { value = VariableArrayToString(variable.GetValue_Object()["value"]); var ns = (EVariableNamespace)variable.GetValue_Object()["ns"].GetValue_Number(); //Namespace the variable comes from yield return(new Variable() { Name = name, Value = value, VariableType = Variable.ValueType.ARRAY, Namespace = ns }); } break; default: { value = variable.GetValue_Object()["value"].GetValue_String(); var ns = (EVariableNamespace)variable.GetValue_Object()["ns"].GetValue_Number(); //Namespace the variable comes from yield return(new Variable() { Name = name, Value = value, VariableType = Variable.ValueType.Parse(type), Namespace = ns }); } break; } } } }
public void UpdateBreakpoint(Breakpoint b) { { var command = new asapJson.JsonNode(new Dictionary <string, asapJson.JsonNode>()); command.GetValue_Object()["command"] = new asapJson.JsonNode((int)ESendCommands.AddBreakpoint); command.GetValue_Object()["data"] = b.Serialize(); this.WriteMessage(command); } }
public void WriteMessage(asapJson.JsonNode node) { var str = node.ToString(); Logger.Log(NLog.LogLevel.Info, string.Format("SEND {0}", str)); var bytes = ASCIIEncoding.UTF8.GetBytes(str); this.Pipe.Write(bytes, 0, bytes.Length); }
public static async Task <Profile> Fetch(string profileName, ApiProvider apiProvider) { string url = apiProvider.Api; url += "profile/info?name=" + WebUtility.UrlEncode(profileName); var response = await apiProvider.Client.GetAsync(new Uri(url)); asapJson.JsonNode responseNode = new asapJson.JsonNode(await response.Content.ReadAsStringAsync(), true); response.Dispose(); return(new Profile(responseNode)); }
public bool Attach() { if (this.Pipe != null && this.Pipe.IsConnected) { throw new InvalidOperationException(); } if (this.Pipe != null) { this.Pipe.Dispose(); } this.Pipe = new NamedPipeClientStream(".", @"ArmaDebugEnginePipeIface", PipeDirection.InOut, PipeOptions.Asynchronous, System.Security.Principal.TokenImpersonationLevel.None, System.IO.HandleInheritability.None); this.Breakpoints = new List <Breakpoint>(); try { this.Pipe.Connect(1000); this.Pipe.ReadMode = PipeTransmissionMode.Message; this.PipeReadThread = new Thread(Thread_ReadPipeMessage); this.PipeReadThread.Start(); } catch (TimeoutException ex) { this.LastError = ex.Message; this.Pipe = null; return(false); } var command = new asapJson.JsonNode(new Dictionary <string, asapJson.JsonNode>()); command.GetValue_Object()["command"] = new asapJson.JsonNode((int)ESendCommands.GetVersionInfo); this.WriteMessage(command); var response = this.ReadMessage((node) => (int)(node.GetValue_Object()["command"].GetValue_Number()) == (int)ERecvCommands.VersionInfo); if (response.GetValue_Object()["gameType"].GetValueType() == JsonNode.EJType.String) //Might be null if init failed or attached too soon { var gameType = response.GetValue_Object()["gameType"].GetValue_String(); } if (response.GetValue_Object()["gameVersion"].GetValueType() == JsonNode.EJType.String) //Might be null if init failed or attached too soon { var gameVersion = response.GetValue_Object()["gameVersion"].GetValue_String(); } var arch = response.GetValue_Object()["arch"].GetValue_String(); var build = response.GetValue_Object()["build"].GetValue_Number(); var version = response.GetValue_Object()["version"].GetValue_String(); if (build < MinimalDebuggerBuild) { this.LastError = "Unsupported Debugger build: " + build + " \nMinimal build required: " + MinimalDebuggerBuild; Detach(); return(false); } return(true); }
public bool Perform(EOperation op) { switch (op) { case EOperation.Continue: { var node = new asapJson.JsonNode(new Dictionary <string, asapJson.JsonNode>()); node.GetValue_Object()["command"] = new asapJson.JsonNode((int)ESendCommands.ContinueExecution); node.GetValue_Object()["data"] = new asapJson.JsonNode((int)EStepType.Continue); this.WriteMessage(node); return(true); } case EOperation.StepInto: { var node = new asapJson.JsonNode(new Dictionary <string, asapJson.JsonNode>()); node.GetValue_Object()["command"] = new asapJson.JsonNode((int)ESendCommands.ContinueExecution); node.GetValue_Object()["data"] = new asapJson.JsonNode((int)EStepType.StepInto); this.WriteMessage(node); return(true); } case EOperation.StepOver: { var node = new asapJson.JsonNode(new Dictionary <string, asapJson.JsonNode>()); node.GetValue_Object()["command"] = new asapJson.JsonNode((int)ESendCommands.ContinueExecution); node.GetValue_Object()["data"] = new asapJson.JsonNode((int)EStepType.StepOver); this.WriteMessage(node); return(true); } case EOperation.StepOut: { var node = new asapJson.JsonNode(new Dictionary <string, asapJson.JsonNode>()); node.GetValue_Object()["command"] = new asapJson.JsonNode((int)ESendCommands.ContinueExecution); node.GetValue_Object()["data"] = new asapJson.JsonNode((int)EStepType.StepOut); this.WriteMessage(node); return(true); } default: this.LastError = "Not Implemented"; return(false); } }
private void Thread_ReadPipeMessage() { try { var buffer = new byte[2048]; while (this.Pipe.IsConnected) { var builder = new StringBuilder(); do { var ammount = this.Pipe.Read(buffer, 0, buffer.Length); for (int i = 0; i < ammount; i++) { builder.Append((char)buffer[i]); } } while (!this.Pipe.IsMessageComplete); if (builder.Length > 0) { var node = new asapJson.JsonNode(builder.ToString(), true); Logger.Log(NLog.LogLevel.Info, string.Format("RECV {0}", node.ToString())); if (node.GetValue_Object().ContainsKey("exception")) { this.OnError?.Invoke(this, new OnErrorEventArgs() { Message = node.GetValue_Object()["exception"].GetValue_String() }); } else { switch ((ERecvCommands)node.GetValue_Object()["command"].GetValue_Number()) { case ERecvCommands.HaltBreakpoint: case ERecvCommands.HaltStep: { var callstack = this.LastCallstack = node.GetValue_Object()["callstack"]; var instruction = node.GetValue_Object()["instruction"]; var fileOffsetNode = instruction.GetValue_Object()["fileOffset"]; var line = (int)fileOffsetNode.GetValue_Array()[0].GetValue_Number(); var col = (int)fileOffsetNode.GetValue_Array()[2].GetValue_Number(); this.OnHalt?.Invoke(this, new OnHaltEventArgs() { DocumentPath = instruction.GetValue_Object()["filename"].GetValue_String(), Col = col, Line = line }); } break; case ERecvCommands.HaltError: { var callstack = this.LastCallstack = node.GetValue_Object()["callstack"]; var error = node.GetValue_Object()["error"]; var fileOffsetNode = error.GetValue_Object()["fileOffset"]; var errorMessage = error.GetValue_Object()["message"]; //ToDo: display to user var fileContent = error.GetValue_Object()["content"]; //File content in case we don't have that file var line = (int)fileOffsetNode.GetValue_Array()[0].GetValue_Number(); var col = (int)fileOffsetNode.GetValue_Array()[2].GetValue_Number(); this.OnHalt?.Invoke(this, new OnHaltEventArgs() { DocumentPath = error.GetValue_Object()["filename"].GetValue_String(), Col = col, Line = line }); } break; case ERecvCommands.HaltScriptAssert: case ERecvCommands.HaltScriptHalt: { var callstack = this.LastCallstack = node.GetValue_Object()["callstack"]; var error = node.GetValue_Object()["halt"]; var fileOffsetNode = error.GetValue_Object()["fileOffset"]; var fileContent = error.GetValue_Object()["content"]; //File content in case we don't have that file var line = (int)fileOffsetNode.GetValue_Array()[0].GetValue_Number(); var col = (int)fileOffsetNode.GetValue_Array()[2].GetValue_Number(); this.OnHalt?.Invoke(this, new OnHaltEventArgs() { DocumentPath = error.GetValue_Object()["filename"].GetValue_String(), Col = col, Line = line }); } break; case ERecvCommands.ContinueExecution: { this.OnContinue?.Invoke(this, new OnContinueEventArgs() { }); } break; default: this.Messages.Add(node); break; } } } Thread.Sleep(10); } } catch (ObjectDisposedException) { } }
private void readObject(System.IO.StreamReader sr) { int i; bool isOpen = false; bool hasLabel = false; bool getNextValue = false; bool getNextKeySet = false; string label = ""; char lastChar = '\0'; Dictionary<string, JsonNode> dict = new Dictionary<string, JsonNode>(); this.setValue(dict); while ((i = sr.Peek()) >= 0) { char c = (char)i; if (!(c == ' ' || c == '\t' || c == '\n' || c == '\r')) { if (isOpen) {//node is opened ('{' already got read) and ready to be parsed if (hasLabel) {//Label for current object item was already started and thus can be if (getNextKeySet) {//Next key set needs to be received (value already parsed) or the current object has to be closed if (c == ',') { hasLabel = false; getNextKeySet = false; getNextValue = false; hasLabel = false; } else if (c == '}') { c = (char)sr.Read(); lastChar = c; break; } else { throw new Exception("Parsing Object failed: Expected ',' or '}', got '" + c + '\''); } } else if (getNextValue) {//Next value of current label needs to get parsed JsonNode child = new JsonNode(); child.read(sr); dict.Add(label, child); getNextKeySet = true; lastChar = '\0'; continue; } else {//Separator for label and string expected if (c != ':') throw new Exception("Parsing Object failed: Expected '\"', got '" + c + '\''); getNextValue = true; } } else {//No label yet found --> get label of current item if (c != '"') throw new Exception("Parsing Object failed: Expected '\"', got '" + c + '\''); label = parseStringFromEncoded(sr); hasLabel = true; lastChar = '"'; continue; } } else {//node yet has to be opened if (c != '{') throw new Exception("Parsing Object failed: Expected '{', got '" + c + '\''); isOpen = true; } } c = (i = sr.Read()) > 0 ? (char)c : '\0'; lastChar = c; } if (lastChar != '}') throw new Exception("Parsing Object failed: Expected '}', got '" + lastChar + '\''); }
private void readArray(System.IO.StreamReader sr) { int i; List<JsonNode> array = new List<JsonNode>(); this.setValue(array); bool isOpen = false; bool allowNext = true; char lastChar = '\0'; while ((i = sr.Peek()) >= 0) { char c = (char)i; if (!(c == ' ' || c == '\t' || c == '\n' || c == '\r')) { if (isOpen) { if (c == ']') { c = (i = sr.Read()) > 0 ? (char)c : '\0'; lastChar = c; break; } else if (allowNext) { JsonNode node = new JsonNode(); node.read(sr); array.Add(node); allowNext = false; lastChar = '\0'; continue; } else if (c == ',') { allowNext = true; } else { throw new Exception("Parsing Object failed: Expected ',' or ']', got '" + c + '\''); } } else { if (c != '[') throw new Exception("Parsing Object failed: Expected '{', got '" + c + '\''); isOpen = true; allowNext = true; } } c = (i = sr.Read()) > 0 ? (char)c : '\0'; lastChar = c; } }
public void setAtPath(JsonNode node, string path, char delimeter = '/') { int index = path.LastIndexOf(delimeter); JsonNode lastNode; if (index > 0) { lastNode = getByPath(path.Substring(0, index), delimeter, true); ; } else { lastNode = this; } if (lastNode.Type == EJType.Object) { Dictionary<string, JsonNode> val; lastNode.getValue(out val); if (val == null) { val = new Dictionary<string, JsonNode>(); lastNode.setValue(val); } if (index > 0) { val.Add(path.Substring(index + 1), node); } else { val.Add(path, node); } } else { throw new Exception("Cannot set path to end. Parent node is not an object"); } }
public JsonNode getByPath(string path, char delimeter = '/', bool createIfNonExisting = false) { var pathArgs = path.Split(delimeter); JsonNode curNode = this; foreach (var next in pathArgs) { if (string.IsNullOrEmpty(next)) continue; if (curNode.Type == EJType.Object) { Dictionary<string, JsonNode> val; curNode.getValue(out val); if (val == null) { val = new Dictionary<string, JsonNode>(); curNode.setValue(val); } if (!val.TryGetValue(next, out curNode)) { if (createIfNonExisting) { curNode = new JsonNode(new Dictionary<string, JsonNode>()); val.Add(next, curNode); } else { throw new Exception("Cannot resolve path to end. No next node at '" + next + '\''); } } } else { throw new Exception("Cannot resolve path to end. No next node at '" + next + '\''); } } return curNode; }
private void ReadObject(System.IO.StreamReader sr) { int i; bool isOpen = false; bool hasLabel = false; bool getNextValue = false; bool getNextKeySet = false; string label = ""; char lastChar = '\0'; Dictionary <string, JsonNode> dict = new Dictionary <string, JsonNode>(); this.SetValue(dict); while ((i = sr.Peek()) >= 0) { char c = (char)i; if (!(c == ' ' || c == '\t' || c == '\n' || c == '\r')) { if (isOpen) { //node is opened ('{' already got read) and ready to be parsed if (hasLabel) { //Label for current object item was already started and thus can be if (getNextKeySet) { //Next key set needs to be received (value already parsed) or the current object has to be closed if (c == ',') { hasLabel = false; getNextKeySet = false; getNextValue = false; hasLabel = false; } else if (c == '}') { c = (char)sr.Read(); lastChar = c; break; } else { throw new Exception("Parsing Object failed: Expected ',' or '}', got '" + c + '\''); } } else if (getNextValue) {//Next value of current label needs to get parsed JsonNode child = new JsonNode(); child.Read(sr); dict.Add(label, child); getNextKeySet = true; lastChar = '\0'; continue; } else {//Separator for label and string expected if (c != ':') { throw new Exception("Parsing Object failed: Expected '\"', got '" + c + '\''); } getNextValue = true; } } else {//No label yet found --> get label of current item if (c != '"') { throw new Exception("Parsing Object failed: Expected '\"', got '" + c + '\''); } label = ParseStringFromEncoded(sr); hasLabel = true; lastChar = '"'; continue; } } else {//node yet has to be opened if (c != '{') { throw new Exception("Parsing Object failed: Expected '{', got '" + c + '\''); } isOpen = true; } } c = (i = sr.Read()) > 0 ? (char)c : '\0'; lastChar = c; } if (lastChar != '}') { throw new Exception("Parsing Object failed: Expected '}', got '" + lastChar + '\''); } }