static string CreateCSharpName(IUavcanType t) { var name = t.Meta.Name; name = Capitalize(name); return(name); }
public static void ResolveNestedTypes(IUavcanType type, IUavcanTypeResolver typeResolver) { if (type == null) { throw new ArgumentNullException(nameof(type)); } if (typeResolver == null) { throw new ArgumentNullException(nameof(typeResolver)); } switch (type) { case MessageType t: ResolveNestedTypesCore(t.UnderlyingCompositeDsdlType, typeResolver); break; case ServiceType t: ResolveNestedTypesCore(t.Request, typeResolver); ResolveNestedTypesCore(t.Response, typeResolver); break; default: throw new ArgumentOutOfRangeException(nameof(type)); } }
static DsdlType CastNestedType(IUavcanType nestedType) { switch (nestedType) { case ServiceType _: throw new Exception("A service type can not be nested into another compound type."); case MessageType messageType: return(messageType); default: throw new InvalidOperationException($"Unknown DSDL type: '{nestedType}'."); } }
static string BuildType(IUavcanType t, string csharpName) { var builder = new StringBuilder(); switch (t) { case MessageType mt: builder.AppendLine($" [DataContract(Name = \"{t.Meta.Name}\", Namespace = \"{t.Meta.Namespace}\")]"); builder.AppendLine($" sealed class {csharpName}"); builder.AppendLine(" {"); foreach (var i in BuildCSharpMembers(mt)) { builder.AppendLine(" " + i); } builder.AppendLine(" }"); builder.AppendLine(); break; case ServiceType st: builder.AppendLine($" [DataContract(Name = \"{t.Meta.Name}.Request\", Namespace = \"{t.Meta.Namespace}\")]"); builder.AppendLine($" sealed class {csharpName}_Request"); builder.AppendLine(" {"); foreach (var i in BuildCSharpMembers(st.Request)) { builder.AppendLine(" " + i); } builder.AppendLine(" }"); builder.AppendLine(); builder.AppendLine($" [DataContract(Name = \"{t.Meta.Name}.Response\", Namespace = \"{t.Meta.Namespace}\")]"); builder.AppendLine($" sealed class {csharpName}_Response"); builder.AppendLine(" {"); foreach (var i in BuildCSharpMembers(st.Response)) { builder.AppendLine(" " + i); } builder.AppendLine(" }"); builder.AppendLine(); break; default: throw new InvalidOperationException(); } return(builder.ToString()); }
static void ValidateDTID(IUavcanType type) { if (type.Meta.DefaultDTID == null) { return; } if (type.Meta.DefaultDTID < 0) { throw new Exception("Invalid data type ID."); } switch (type) { case MessageType _ when(type.Meta.DefaultDTID > MESSAGE_DATA_TYPE_ID_MAX): case ServiceType _ when(type.Meta.DefaultDTID > SERVICE_DATA_TYPE_ID_MAX): throw new Exception("Invalid data type ID."); } }
static void ValidateUnion(IUavcanType type) { if (type == null) { throw new ArgumentNullException(nameof(type)); } void ValidateUnionCore(CompositeDsdlTypeBase ct) { if (ct.IsUnion) { if (ct.Fields == null || ct.Fields.Count < 2) { throw new Exception("Union contains less than 2 fields."); } if (ct.Fields.OfType <VoidDsdlType>().Any()) { throw new Exception("Union must not contain void fields."); } } } switch (type) { case MessageType mt: ValidateUnionCore(mt); break; case ServiceType st: ValidateUnionCore(st.Request); ValidateUnionCore(st.Response); break; default: throw new ArgumentException(); } }
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); }