/// <summary> /// Performs the substitutions specified in the template and writes it to the stream. /// </summary> public bool WriteTemplate(GeneratorContext context) { // ensure context is not null. if (context == null) { context = new GeneratorContext(); } var skipping = true; var written = false; // build list of tokens. var count = 0; var tokens = new string[Replacements.Count]; foreach (var token in Replacements.Keys) { tokens[count++] = token; } // read first line. var line = _reader.ReadLine(); while (line != null) { // if skipping lines look for the template start tag. if (skipping) { if (line.IndexOf(TemplateStartTag, StringComparison.Ordinal) != -1) { skipping = false; } line = _reader.ReadLine(); continue; } // if writing lines look for the template end tag. else { if (line.IndexOf(TemplateEndAppendNewLineTag, StringComparison.Ordinal) != -1) { Write(NewLine); break; } if (line.IndexOf(TemplateEndTag, StringComparison.Ordinal) != -1) { break; } } // process empty lines. if (line.Length == 0) { if (written) { Write(NewLine); } written = true; line = _reader.ReadLine(); continue; } var found = false; for (var index = 0; index < line.Length; index++) { // check for a token at the current position. string token = null; for (var ii = 0; ii < tokens.Length; ii++) { if (StrCmp(line, index, tokens[ii])) { token = tokens[ii]; break; } } // nothing found. if (token == null) { continue; } // check if a template substitution is required. if (Templates.ContainsKey(token)) { // skip the token if no items to write. var definition = Templates[token]; if (definition == null || definition.Targets == null || definition.Targets.Count == 0) { found = true; line = line.Substring(index + token.Length); index = -1; continue; } // write multi-line template. var result = WriteTemplate( context.Target, token, context.Prefix + line.Substring(0, index)); if (result) { written = true; } line = string.Empty; continue; } // only process tokens if a value is provided. if (Replacements[token] != null) { written = WriteToken( context.Target, context, !found, line.Substring(0, index), token); found = true; } line = line.Substring(index + token.Length); index = -1; } // write line if no token found. if (line.Length > 0) { if (!found) { // ensure that an empty line does not get inserted at the start of a file. if (written || context.Target != null) { Write(NewLine); } Write(context.Prefix); written = true; } Write(line); } // read next line. line = _reader.ReadLine(); } return(written); }
/// <summary> /// Writes the code to defined a identifier for a type. /// </summary> private bool WriteTemplate_BinaryType(Template template, GeneratorContext context) { if (context.Target is ModelDesign model) { if (_model.TargetNamespace == DefaultNamespace) { template.WriteNextLine(string.Empty); return(template.WriteTemplate(context)); } return(false); } if (!(context.Target is DataTypeDesign dataType)) { return(false); } if (context.FirstInList) { template.WriteNextLine(string.Empty); } template.AddReplacement("_TypeName_", dataType.SymbolicName.Name); if (dataType.BasicDataType == BasicDataType.UserDefined) { template.AddReplacement("_BaseType_", GetBinaryDataType(dataType.BaseTypeNode as DataTypeDesign)); } var fields = new List <Parameter>(); var parents = new Stack <DataTypeDesign>(); for (var parent = dataType as DataTypeDesign; parent != null; parent = parent.BaseTypeNode as DataTypeDesign) { if (parent.Fields != null) { parents.Push(parent); } } while (parents.Count > 0) { var parent = parents.Pop(); foreach (var field in parent.Fields) { if (ReferenceEquals(dataType, parent)) { fields.Add(field); continue; } fields.Add(new Parameter { DataType = field.DataType, DataTypeNode = field.DataTypeNode, Description = field.Description, Identifier = field.Identifier, IdentifierInName = field.IdentifierInName, IdentifierSpecified = field.IdentifierSpecified, IsInherited = true, Name = field.Name, Parent = field.Parent, ValueRank = field.ValueRank }); } } if (dataType.BasicDataType == BasicDataType.Enumeration) { uint lengthInBits = 32; var isOptionSet = false; if (dataType.IsOptionSet) { isOptionSet = true; switch (dataType.BaseType.Name) { case "SByte": { lengthInBits = 8; break; } case "Byte": { lengthInBits = 8; break; } case "Int16": { lengthInBits = 16; break; } case "UInt16": { lengthInBits = 16; break; } case "Int32": { lengthInBits = 32; break; } case "UInt32": { lengthInBits = 32; break; } case "Int64": { lengthInBits = 64; break; } case "UInt64": { lengthInBits = 64; break; } } fields.Insert(0, new Parameter { Name = "None", Identifier = 0, IdentifierSpecified = true, DataType = fields[0].DataType, DataTypeNode = fields[0].DataTypeNode, Parent = fields[0].Parent }); } template.AddReplacement("_LengthInBits_", lengthInBits); template.AddReplacement("_IsOptionSet_", isOptionSet ? " IsOptionSet=\"true\"" : ""); } AddTemplate( template, "<!-- Documentation -->", null, new DataTypeDesign[] { dataType }, new LoadTemplateEventHandler(LoadTemplate_BinaryDocumentation), null); AddTemplate( template, "<!-- ListOfFields -->", null, fields, new LoadTemplateEventHandler(LoadTemplate_BinaryTypeFields), null); return(template.WriteTemplate(context)); }