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); }