示例#1
0
        /// <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));
        }