public UavcanTypeMeta ParseMeta(string path) { var name = Path.GetFileName(path); var match = _fileNameRegex.Match(name); if (!match.Success) { throw new Exception($"Invalid file name [{path}]; expected pattern: [<default-dtid>.]<short-type-name>.[<major-version>.<minor-version>.]" + DsdlExtension); } var meta = new UavcanTypeMeta(); if (match.Groups["DTID"].Success) { meta.DefaultDTID = int.Parse(match.Groups["DTID"].Value); } if (match.Groups["VER"].Success) { meta.Version = Version.Parse(match.Groups["VER"].Value); } meta.Namespace = GetNamespace(path); meta.Name = match.Groups["NAME"].Value; return(meta); }
static void ProcessLineTokens(UavcanTypeMeta meta, CompositeDsdlType type, string[] tokens) { if (tokens.Length < 1) { throw new Exception("Invalid attribute definition."); } int offset = 0; var castMode = CastMode.Saturated; switch (tokens[0]) { case "saturated": offset++; break; case "truncated": offset++; castMode = CastMode.Truncated; break; } string attrTypeName, attrName; switch (tokens.Length - offset) { case 0: case 1 when(!tokens[0].StartsWith("void")): throw new Exception("Invalid attribute definition."); case 1: attrTypeName = tokens[offset]; attrName = null; offset += 1; break; default: attrTypeName = tokens[offset]; attrName = tokens[offset + 1]; offset += 2; break; } var attrType = ParseType(meta.Namespace, attrTypeName, castMode); switch (attrType) { case VoidDsdlType _: break; default: ValidateAttributeName(attrName); break; } switch (tokens.Length - offset) { case 0: var field = new DsdlField { Name = attrName, Type = attrType, }; type.AddMember(field); if (attrName != null) { type.Members.Add(attrName, field); } break; case 1: throw new Exception("Constant assignment expected."); default: if (tokens[offset] != "=") { throw new Exception("Constant assignment expected."); } var expression = string.Join(" ", tokens, offset + 1, tokens.Length - offset - 1); var constant = CreateConstant(attrType, attrName, expression); type.AddMember(constant); if (attrName != null) { type.Members.Add(attrName, constant); } break; } }
public static IUavcanType Parse(TextReader reader, UavcanTypeMeta meta) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } if (meta == null) { throw new ArgumentNullException(nameof(meta)); } ValidateTypeFullName(meta.FullName); IUavcanType result = null; var compoundType = new CompositeDsdlType(); int lineCounter = 0; string line; while ((line = reader.ReadLine()) != null) { lineCounter++; line = SkipComment(line).Trim(); if (string.IsNullOrEmpty(line)) { continue; } try { if (line == "---") { if (result != null) { throw new Exception("Duplicate response mark."); } result = new ServiceType { Meta = meta, Request = compoundType, }; compoundType = new CompositeDsdlType(); } else if (line == "@union") { if (compoundType.IsUnion) { throw new Exception("Data structure has already been declared as union."); } compoundType.SetIsUnion(true); } else { var tokens = line.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); ProcessLineTokens(meta, compoundType, tokens); } } catch (Exception ex) { throw new Exception($"Cannot parse line #{lineCounter}: '{line}'.", ex); } } if (result == null) { result = new MessageType(compoundType) { Meta = meta, }; } else if (result is ServiceType st) { st.Response = compoundType; } else { throw new InvalidOperationException(); } ValidateDTID(result); ValidateUnion(result); return(result); }