/// <summary> /// Creates a message class for a single message defined in text form. /// </summary> /// <param name="package">The name of the package. Leave this as null if the package name is included in <see cref="messageName"/>.</param> /// <param name="messageName">The name of the message. If this is a fully qualified name (e.g., std_msgs/Header instead of just Header), leave <see cref="package"/> as null.</param> /// <param name="messageDefinition">The definition of the message, as would be found in a .msg file.</param> /// <param name="forceStruct">Whether to construct this message as a struct instead of a class. You should probably leave this as false.</param> public ClassInfo(string?package, string messageName, string messageDefinition, bool forceStruct = false) { if (messageName == null) { throw new ArgumentNullException(nameof(messageName)); } int lastSlash = messageName.LastIndexOf('/'); if (lastSlash != -1) { if (!string.IsNullOrEmpty(package)) { throw new ArgumentException( "messageName contains a package, but package is not null. Only one of both must be set!"); } package = messageName.Substring(0, lastSlash); messageName = messageName.Substring(lastSlash + 1); } if (string.IsNullOrWhiteSpace(package)) { throw new InvalidOperationException("Could not find the package this message belongs to"); } RosPackage = package !; CsPackage = MsgParser.CsIfy(package !); Name = messageName; fullMessageText = messageDefinition.Replace("\r\n", "\n"); var lines = fullMessageText.Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries); elements = MsgParser.ParseFile(lines, Name).ToArray(); Elements = new ReadOnlyCollection <IElement>(elements); variables = elements.OfType <VariableElement>().ToArray(); if (forceStruct || IsClassForceStruct($"{RosPackage}/{Name}")) { ForceStruct = true; } isBlittable = ForceStruct && variables.All(variable => IsVariableBlittable(RosPackage, variable)); }
public ServiceInfo(string package, string path) { if (package == null) { throw new ArgumentNullException(nameof(package)); } if (path == null) { throw new ArgumentNullException(nameof(path)); } if (!File.Exists(path)) { throw new ArgumentException($"File {path} does not exist."); } Console.WriteLine($"-- Parsing '{path}'"); RosPackage = package; CsPackage = MsgParser.CsIfy(package); Name = Path.GetFileNameWithoutExtension(path); string[] lines = File.ReadAllLines(path); //File.ReadAllText(path); List <IElement> elements = MsgParser.ParseFile(lines, Name); int serviceSeparator = elements.FindIndex(x => x.Type == ElementType.ServiceSeparator); if (serviceSeparator == -1) { throw new MessageParseException("Service file has no separator"); } elementsReq = elements.GetRange(0, serviceSeparator).ToArray(); elementsResp = elements.GetRange(serviceSeparator + 1, elements.Count - serviceSeparator - 1).ToArray(); variablesReq = elementsReq.OfType <VariableElement>().ToArray(); variablesResp = elementsResp.OfType <VariableElement>().ToArray(); }
public static ClassInfo[]? GenerateFor(string package, string path) { string[] lines = File.ReadAllLines(path); string actionName = Path.GetFileNameWithoutExtension(path); List <IElement> elements = MsgParser.ParseFile(lines, actionName); List <int> separatorIndices = new List <int>(); for (int i = 0; i < elements.Count; i++) { if (elements[i].Type == ElementType.ServiceSeparator) { separatorIndices.Add(i); } } if (separatorIndices.Count != 2) { Console.WriteLine("EE Action for file '" + path + "' does not have the expected two --- separators"); return(null); } List <IElement> goalElements = elements.GetRange(0, separatorIndices[0]); List <IElement> resultElements = elements.GetRange(separatorIndices[0] + 1, separatorIndices[1] - separatorIndices[0] - 1); List <IElement> feedbackElements = elements.GetRange(separatorIndices[1] + 1, elements.Count - separatorIndices[1] - 1); ClassInfo goalInfo = new ClassInfo(package, $"{actionName}Goal", goalElements, actionName, ActionMessageType.Goal); ClassInfo resultInfo = new ClassInfo(package, $"{actionName}Result", resultElements, actionName, ActionMessageType.Result); ClassInfo feedbackInfo = new ClassInfo(package, $"{actionName}Feedback", feedbackElements, actionName, ActionMessageType.Feedback); IElement[] actionGoalElements = { new VariableElement("", "Header", "header", serializeAsProperty: true), new VariableElement("", "actionlib_msgs/GoalID", "goal_id", serializeAsProperty: true), new VariableElement("", $"{actionName}Goal", "goal", null, goalInfo,serializeAsProperty: true), }; ClassInfo actionGoalInfo = new ClassInfo(package, $"{actionName}ActionGoal", actionGoalElements, actionName, ActionMessageType.ActionGoal); IElement[] actionResultElements = { new VariableElement("", "Header", "header", serializeAsProperty: true), new VariableElement("", "actionlib_msgs/GoalStatus", "status", serializeAsProperty: true), new VariableElement("", $"{actionName}Result", "result", null, resultInfo,serializeAsProperty: true), }; ClassInfo actionResultInfo = new ClassInfo(package, $"{actionName}ActionResult", actionResultElements, actionName, ActionMessageType.ActionResult); IElement[] actionFeedbackElements = { new VariableElement("", "Header", "header", serializeAsProperty: true), new VariableElement("", "actionlib_msgs/GoalStatus", "status", serializeAsProperty: true), new VariableElement("", $"{actionName}Feedback", "feedback", null, feedbackInfo, serializeAsProperty: true), }; ClassInfo actionFeedbackInfo = new ClassInfo(package, $"{actionName}ActionFeedback", actionFeedbackElements, actionName, ActionMessageType.ActionFeedback); IElement[] actionElements = { new VariableElement("", $"{actionName}ActionGoal", "action_goal", serializeAsProperty: true), new VariableElement("", $"{actionName}ActionResult", "action_result", serializeAsProperty: true), new VariableElement("", $"{actionName}ActionFeedback", "action_feedback", serializeAsProperty: true), }; ClassInfo actionInfo = new ClassInfo(package, $"{actionName}Action", actionElements, actionName, ActionMessageType.Action); return(new[] { goalInfo, feedbackInfo, resultInfo, actionGoalInfo, actionFeedbackInfo, actionResultInfo, actionInfo }); }