예제 #1
0
        private void WriteOptionalProperty(IndentedTextWriter writer, ClassDefinition.Property p, int index, bool parentHasOptionalFields)
        {
            WritePropertyDocumentation(writer, p, isUnion: false);

            var type  = RenderType(p, isOptional: true);
            var field = GetFieldName(p.SymbolicName);

            writer.WriteLine($"public {type} {p.SymbolicName}");
            writer.Begin("{");
            writer.WriteLine($"get => {field};");
            writer.WriteLine("set");
            writer.Begin("{");
            if (parentHasOptionalFields)
            {
                writer.WriteLine($"uint flag = 1u << ({index} + base.OptionalFieldCount);");
            }
            else
            {
                writer.WriteLine($"uint flag = 1u << {index};");
            }
            writer.WriteLine();
            writer.WriteLine($"{field} = value;");
            writer.WriteLine("EncodingMask = value is null");
            writer.Indent++;
            writer.WriteLine("? EncodingMask & ~flag");
            writer.WriteLine(": EncodingMask | flag;");
            writer.Indent--;
            writer.End("}");
            writer.End("}");
            writer.WriteLine($"private {type} {field};");
        }
예제 #2
0
        /*
         * Enumeration
         */
        private void WriteEnumeration(IndentedTextWriter writer, EnumDefinition e)
        {
            WriteDocumentation(writer, e);

            if (_typeSet.TryGetExpandedNodeId(e.DataTypeId, out var eId))
            {
                var idString = ToStringLiteral(eId.ToString());
                writer.WriteLine($"[Workstation.ServiceModel.Ua.DataTypeId({idString})]");
            }
            else
            {
                throw new InvalidDataException($"No data type id for enum {e.SymbolicName}.");
            }

            writer.WriteLine($"public enum {e.SymbolicName}");
            writer.Begin("{");

            foreach (var item in e.Items)
            {
                if (item.Description != null)
                {
                    writer.WriteLine("/// <summary>");
                    foreach (var line in item.Description.WordWrap(76 - 4 * writer.Indent))
                    {
                        writer.WriteLine($"/// {line}");
                    }
                    writer.WriteLine("/// </summary>");
                }
                writer.WriteLine($"{item.SymbolicName} = {item.Value},");
            }

            writer.End("}");
        }
예제 #3
0
        /*
         * Union
         */
        private void WriteUnion(IndentedTextWriter writer, ClassDefinition c, string name, IEnumerable <NestedType> nestedTypes)
        {
            WriteDocumentation(writer, c, isUnion: true);
            WriteAttributes(writer, c);

            WriteUnionHeader(writer, c, name);

            writer.Begin("{");

            if (nestedTypes.Any())
            {
                WriteNestedTypes(writer, nestedTypes);
            }

            WriteUnionEnum(writer, c);
            writer.WriteLine();
            WriteUnionFields(writer);

            writer.WriteLine();
            foreach (var p in c.Properties)
            {
                WriteUnionProperty(writer, p);
                writer.WriteLine();
            }

            WriteUnionEncodeMethod(writer, c);
            writer.WriteLine();
            WriteUnionDecodeMethod(writer, c);

            writer.End("}");
        }
예제 #4
0
        /*
         * Static class
         */
        private void WriteStaticClass(IndentedTextWriter writer, string name, IEnumerable <NestedType> nestedTypes)
        {
            writer.WriteLine($"public static class {name}");
            writer.Begin("{");

            WriteNestedTypes(writer, nestedTypes);

            writer.End("}");
        }
예제 #5
0
        private void WriteEncodeMethod(IndentedTextWriter writer, ClassDefinition c, bool isDerived, bool parentIsStructure, bool parentHasOptionalFields)
        {
            var hasOptionalFields = c.OptionalPropertyCount != 0;
            var modifier          = isDerived ? "override" : "virtual";

            WriteInheritDoc(writer);
            writer.WriteLine($"public {modifier} void Encode(Workstation.ServiceModel.Ua.IEncoder encoder)");
            writer.Begin("{");
            if (isDerived && !parentIsStructure)
            {
                writer.WriteLine("base.Encode(encoder);");
            }

            writer.WriteLine($"encoder.PushNamespace({ToStringLiteral(c.Namespace)});");
            writer.WriteLine();
            if (hasOptionalFields && !parentHasOptionalFields)
            {
                writer.WriteLine("encoder.WriteUInt32(\"EncodingMask\", EncodingMask);");
            }

            var index = 0;

            foreach (var p in c.Properties)
            {
                var netType = _typeSet.GetNetType(p.DataTypeId);
                var suffix  = RenderMethodSuffix(netType, p.Rank);

                if (p.IsOptional)
                {
                    writer.WriteLine($"if ({p.SymbolicName} is {{}} opt{index})");
                    writer.Begin("{");
                    writer.WriteLine($"encoder.Write{suffix}({ToStringLiteral(p.OpcUaName)}, opt{index});");
                    writer.End("}");
                    index++;
                }
                else
                {
                    writer.WriteLine($"encoder.Write{suffix}({ToStringLiteral(p.OpcUaName)}, {p.SymbolicName});");
                }
            }
            writer.WriteLine();
            writer.WriteLine("encoder.PopNamespace();");
            writer.End("}");
        }
예제 #6
0
        private void WriteUnionProperty(IndentedTextWriter writer, ClassDefinition.Property p)
        {
            WritePropertyDocumentation(writer, p, isUnion: true);
            var netType = _typeSet.GetNetType(p.DataTypeId);
            var r       = p.Rank switch
            {
                2 => "[,]",
                1 => "[]",
                _ => ""
            };
            var type = $"{netType.TypeName}{r}";

            writer.WriteLine($"public {type} {p.SymbolicName}");
            writer.Begin("{");
            writer.WriteLine($"get => ({type})_field;");
            writer.WriteLine("set");
            writer.Begin("{");
            writer.WriteLine($"SwitchField = UnionField.{p.SymbolicName};");
            writer.WriteLine($"_field = value;");
            writer.End("}");
            writer.End("}");
        }
예제 #7
0
        /*
         * Class and unions
         */
        private void WriteClass(IndentedTextWriter writer, ClassDefinition c, string name, IEnumerable <NestedType> nestedTypes)
        {
            bool isDerived         = c.ParentDataTypeId != null;
            bool parentIsStructure = c.ParentDataTypeId == NodeId.Parse(DataTypeIds.Structure);

            WriteDocumentation(writer, c, isUnion: false);
            WriteAttributes(writer, c);

            var hasOptionalFields       = c.OptionalPropertyCount != 0;
            var parentHasOptionalFields = _typeSet.ParentHasOptionalProperties(c);

            WriteClassHeader(writer, c, name, parentHasOptionalFields);

            writer.Begin("{");

            if (nestedTypes.Any())
            {
                WriteNestedTypes(writer, nestedTypes);
            }

            if (hasOptionalFields)
            {
                WriteOptionalFieldsImplementation(writer, c, parentHasOptionalFields);
            }

            var optional = 0;

            foreach (var p in c.Properties)
            {
                if (p.IsOptional)
                {
                    WriteOptionalProperty(writer, p, optional, parentHasOptionalFields);
                    optional++;
                }
                else
                {
                    WriteProperty(writer, p);
                }
                writer.WriteLine();
            }

            bool hasParentMethods = isDerived && !parentIsStructure;

            if (c.Properties.Any() || !hasParentMethods)
            {
                WriteEncodeMethod(writer, c, isDerived, parentIsStructure, parentHasOptionalFields);
                writer.WriteLine();
                WriteDecodeMethod(writer, c, isDerived, parentIsStructure, parentHasOptionalFields);
            }
            writer.End("}");
        }
예제 #8
0
        private void WriteUnionEnum(IndentedTextWriter writer, ClassDefinition c)
        {
            writer.WriteLine("public enum UnionField");
            writer.Begin("{");
            writer.WriteLine("Null = 0,");
            var i = 1;

            foreach (var p in c.Properties)
            {
                writer.WriteLine($"{p.SymbolicName} = {i},");
                i++;
            }
            writer.End("}");
        }
예제 #9
0
        public void Write(IndentedTextWriter writer)
        {
            WriteFileHeader(writer);

            writer.WriteLine("[assembly: Workstation.ServiceModel.Ua.TypeLibrary]");
            writer.WriteLine($"namespace {_netNamespace}");
            writer.Begin("{");

            WriteCommonTypes(writer);

            WriteDefinitions(writer);

            writer.End("}");
        }
예제 #10
0
        private void WriteUnionDecodeMethod(IndentedTextWriter writer, ClassDefinition c)
        {
            WriteInheritDoc(writer);
            writer.WriteLine($"public override void Decode(Workstation.ServiceModel.Ua.IDecoder decoder)");
            writer.Begin("{");

            writer.WriteLine($"decoder.PushNamespace({ToStringLiteral(c.Namespace)});");
            writer.WriteLine();
            writer.WriteLine($"var switchField = (UnionField)decoder.ReadUInt32(null);");
            writer.WriteLine($"switch (switchField)");
            writer.Begin("{");
            writer.WriteLine("case UnionField.Null:");
            writer.Indent++;
            writer.WriteLine("_field = null;");
            writer.WriteLine("break;");
            writer.Indent--;
            foreach (var p in c.Properties)
            {
                var netType = _typeSet.GetNetType(p.DataTypeId);
                var suffix  = RenderMethodSuffix(netType, p.Rank);

                writer.WriteLine($"case UnionField.{p.SymbolicName}:");
                writer.Indent++;
                writer.WriteLine($"{p.SymbolicName} = decoder.Read{suffix}({ToStringLiteral(p.OpcUaName)});");
                writer.WriteLine("break;");
                writer.Indent--;
            }
            writer.WriteLine("default:");
            writer.Indent++;
            writer.WriteLine("throw new Workstation.ServiceModel.Ua.ServiceResultException(Workstation.ServiceModel.Ua.StatusCodes.BadEncodingError);");
            writer.Indent--;

            writer.End("}");

            writer.WriteLine("decoder.PopNamespace();");
            writer.End("}");
        }
예제 #11
0
        private void WriteDecodeMethod(IndentedTextWriter writer, ClassDefinition c, bool isDerived, bool parentIsStructure, bool parentHasOptionalFields)
        {
            var hasOptionalFields = c.OptionalPropertyCount != 0;
            var modifier          = isDerived ? "override" : "virtual";

            WriteInheritDoc(writer);
            writer.WriteLine($"public {modifier} void Decode(Workstation.ServiceModel.Ua.IDecoder decoder)");
            writer.Begin("{");
            if (hasOptionalFields && parentHasOptionalFields)
            {
                writer.WriteLine("int offset = base.OptionalFieldCount;");
                writer.WriteLine();
            }
            if (isDerived && !parentIsStructure)
            {
                writer.WriteLine("base.Decode(decoder);");
            }

            writer.WriteLine($"decoder.PushNamespace({ToStringLiteral(c.Namespace)});");
            writer.WriteLine();
            if (hasOptionalFields)
            {
                if (!parentHasOptionalFields)
                {
                    writer.WriteLine("var encodingMask = decoder.ReadUInt32(null);");
                    writer.WriteLine("EncodingMask = encodingMask;");
                }
                else
                {
                    writer.WriteLine("var encodingMask = EncodingMask;");
                }
                writer.WriteLine();
            }

            var index = 0;

            foreach (var p in c.Properties)
            {
                var netType = _typeSet.GetNetType(p.DataTypeId);
                var suffix  = RenderMethodSuffix(netType, p.Rank);
                var type    = RenderType(p, isOptional: true);

                if (p.IsOptional)
                {
                    if (parentHasOptionalFields)
                    {
                        writer.WriteLine($"{p.SymbolicName} = (encodingMask & (1u << ({index} + offset))) != 0");
                    }
                    else
                    {
                        writer.WriteLine($"{p.SymbolicName} = (encodingMask & (1u << {index})) != 0");
                    }
                    writer.Indent++;
                    writer.WriteLine($"? decoder.Read{suffix}({ToStringLiteral(p.OpcUaName)})");
                    writer.WriteLine($": default({type});");
                    writer.Indent--;
                    index++;
                }
                else
                {
                    writer.WriteLine($"{p.SymbolicName} = decoder.Read{suffix}({ToStringLiteral(p.OpcUaName)});");
                }
            }
            writer.WriteLine();
            writer.WriteLine("decoder.PopNamespace();");
            writer.End("}");
        }