Exemplo n.º 1
0
        private int GenerateComplexTypes(CodeNamespace ns)
        {
            int type_count = 0;

            // First populate the type cache.
            foreach (var complex_type in _server.ComplexTypes)
            {
                if (complex_type is NdrBaseStructureTypeReference struct_type)
                {
                    _type_descriptors[complex_type] = new RpcTypeDescriptor(complex_type.Name, true,
                                                                            "ReadStruct", true, "WriteStruct", complex_type, null, null);
                    type_count++;
                }
            }

            if (type_count == 0)
            {
                return(0);
            }

            bool create_constructor_properties         = HasFlag(RpcClientBuilderFlags.GenerateConstructorProperties);
            CodeTypeDeclaration constructor_type       = null;
            CodeTypeDeclaration array_constructor_type = null;

            if (create_constructor_properties)
            {
                constructor_type                = ns.AddType(CONSTRUCTOR_STRUCT_NAME);
                constructor_type.IsStruct       = true;
                array_constructor_type          = ns.AddType(ARRAY_CONSTRUCTOR_STRUCT_NAME);
                array_constructor_type.IsStruct = true;
            }

            // Now generate the complex types.
            foreach (var complex_type in _server.ComplexTypes)
            {
                if (!(complex_type is NdrBaseStructureTypeReference struct_type))
                {
                    ns.Comments.Add(new CodeCommentStatement($"Unsupported type {complex_type.GetType()} {complex_type.Name}"));
                    continue;
                }

                var s_type = ns.AddType(complex_type.Name);
                s_type.IsStruct = true;
                s_type.BaseTypes.Add(new CodeTypeReference(typeof(INdrStructure)));

                var marshal_method = s_type.AddMarshalMethod(MARSHAL_NAME);
                marshal_method.AddAlign(MARSHAL_NAME, struct_type.Alignment + 1);
                var unmarshal_method = s_type.AddUnmarshalMethod(UNMARSHAL_NAME);
                unmarshal_method.AddAlign(UNMARSHAL_NAME, struct_type.Alignment + 1);

                var offset_to_name =
                    struct_type.Members.Select(m => Tuple.Create(m.Offset, m.Name)).ToList();
                var default_initialize_expr = new Dictionary <string, CodeExpression>();
                var member_parameters       = new List <Tuple <CodeTypeReference, string> >();

                foreach (var member in struct_type.Members)
                {
                    var f_type = GetTypeDescriptor(member.MemberType);
                    s_type.AddField(f_type.GetStructureType(), member.Name, MemberAttributes.Public);
                    member_parameters.Add(Tuple.Create(f_type.GetParameterType(), member.Name));

                    List <RpcMarshalArgument> extra_marshal_args = new List <RpcMarshalArgument>();
                    if (f_type.VarianceDescriptor.IsValid)
                    {
                        extra_marshal_args.Add(f_type.VarianceDescriptor.CalculateCorrelationArgument(member.Offset, offset_to_name));
                    }

                    if (f_type.Pointer)
                    {
                        marshal_method.AddDeferredMarshalCall(f_type, MARSHAL_NAME, member.Name, extra_marshal_args.ToArray());
                        unmarshal_method.AddDeferredEmbeddedUnmarshalCall(f_type, UNMARSHAL_NAME, member.Name);
                    }
                    else
                    {
                        if (!f_type.ValueType)
                        {
                            marshal_method.AddNullCheck(MARSHAL_NAME, member.Name);
                        }

                        marshal_method.AddMarshalCall(f_type, MARSHAL_NAME, member.Name, extra_marshal_args.ToArray());
                        unmarshal_method.AddUnmarshalCall(f_type, UNMARSHAL_NAME, member.Name);
                    }

                    if (!f_type.Pointer || f_type.PointerType == RpcPointerType.Reference)
                    {
                        if (f_type.CodeType.ArrayRank > 0)
                        {
                            default_initialize_expr.Add(member.Name, new CodeArrayCreateExpression(f_type.CodeType, CodeGenUtils.GetPrimitive(f_type.FixedCount)));
                        }
                        else if (f_type.BuiltinType == typeof(string) && f_type.FixedCount > 0)
                        {
                            default_initialize_expr.Add(member.Name, new CodeObjectCreateExpression(f_type.CodeType, CodeGenUtils.GetPrimitive('\0'),
                                                                                                    CodeGenUtils.GetPrimitive(f_type.FixedCount)));
                        }
                    }
                }

                var p_type = _type_descriptors[complex_type];

                if (!create_constructor_properties)
                {
                    s_type.AddDefaultConstructorMethod("CreateDefault", MemberAttributes.Public | MemberAttributes.Static, p_type, default_initialize_expr);
                    s_type.AddConstructorMethod(p_type, member_parameters);
                }
                else
                {
                    constructor_type.AddDefaultConstructorMethod(complex_type.Name, MemberAttributes.Public | MemberAttributes.Final, p_type, default_initialize_expr);
                    constructor_type.AddConstructorMethod(complex_type.Name, p_type, member_parameters);
                    array_constructor_type.AddArrayConstructorMethod(complex_type.Name, p_type);
                }
            }

            return(type_count);
        }