1{# TODO(yzshen): Make these templates more readable. #} 2 3{# Serializes the specified struct. 4 |struct| is the struct definition. 5 |struct_display_name| is the display name for the struct that can be showed 6 in error/log messages, for example, "FooStruct", "FooMethod request". 7 |input_field_pattern| should be a pattern that contains one string 8 placeholder, for example, "input->%s", "p_%s". The placeholder will be 9 substituted with struct field names to refer to the input fields. 10 |writer| is the name of the BufferWriter to use for allocation and writing. 11 |buffer| is the name of the Buffer instance used. 12 |context| is the name of the serialization context. 13 |input_may_be_temp|: please see the comments of get_serialized_size. 14 This macro is expanded to do serialization for both: 15 - user-defined structs: the input is an instance of the corresponding struct 16 wrapper class. 17 - method parameters/response parameters: the input is a list of 18 arguments. #} 19{%- macro serialize(struct, struct_display_name, input_field_pattern, writer, 20 buffer, context, input_may_be_temp=False) -%} 21 {{writer}}.Allocate({{buffer}}); 22{%- for pf in struct.packed.packed_fields_in_ordinal_order %} 23{%- set input_field = input_field_pattern|format(pf.field.name) %} 24{%- set name = pf.field.name %} 25{%- set kind = pf.field.kind %} 26{%- set serializer_type = kind|unmapped_type_for_serializer %} 27 28{%- if kind|is_object_kind or kind|is_any_handle_or_interface_kind %} 29{%- set original_input_field = input_field_pattern|format(name) %} 30{%- set input_field = "in_%s"|format(name) if input_may_be_temp 31 else original_input_field %} 32{%- if input_may_be_temp %} 33 decltype({{original_input_field}}) in_{{name}} = {{original_input_field}}; 34{%- endif %} 35{%- endif %} 36 37{%- if kind|is_object_kind %} 38{%- if kind|is_array_kind or kind|is_map_kind %} 39 typename decltype({{writer}}->{{name}})::BaseType::BufferWriter 40 {{name}}_writer; 41 const mojo::internal::ContainerValidateParams {{name}}_validate_params( 42 {{kind|get_container_validate_params_ctor_args|indent(10)}}); 43 mojo::internal::Serialize<{{serializer_type}}>( 44 {{input_field}}, {{buffer}}, &{{name}}_writer, &{{name}}_validate_params, 45 {{context}}); 46 {{writer}}->{{name}}.Set( 47 {{name}}_writer.is_null() ? nullptr : {{name}}_writer.data()); 48{%- elif kind|is_union_kind %} 49 typename decltype({{writer}}->{{name}})::BufferWriter {{name}}_writer; 50 {{name}}_writer.AllocateInline({{buffer}}, &{{writer}}->{{name}}); 51 mojo::internal::Serialize<{{serializer_type}}>( 52 {{input_field}}, {{buffer}}, &{{name}}_writer, true, {{context}}); 53{%- else %} 54 typename decltype({{writer}}->{{name}})::BaseType::BufferWriter 55 {{name}}_writer; 56 mojo::internal::Serialize<{{serializer_type}}>( 57 {{input_field}}, {{buffer}}, &{{name}}_writer, {{context}}); 58 {{writer}}->{{name}}.Set( 59 {{name}}_writer.is_null() ? nullptr : {{name}}_writer.data()); 60{%- endif %} 61{%- if not kind|is_nullable_kind %} 62 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( 63 {{writer}}->{{name}}.is_null(), 64 mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER, 65 "null {{name}} in {{struct_display_name}}"); 66{%- endif %} 67 68{%- elif kind|is_any_handle_or_interface_kind %} 69 mojo::internal::Serialize<{{serializer_type}}>( 70 {{input_field}}, &{{writer}}->{{name}}, {{context}}); 71{%- if not kind|is_nullable_kind %} 72 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( 73 !mojo::internal::IsHandleOrInterfaceValid({{writer}}->{{name}}), 74{%- if kind|is_associated_kind %} 75 mojo::internal::VALIDATION_ERROR_UNEXPECTED_INVALID_INTERFACE_ID, 76{%- else %} 77 mojo::internal::VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE, 78{%- endif %} 79 "invalid {{name}} in {{struct_display_name}}"); 80{%- endif %} 81 82{%- elif kind|is_enum_kind %} 83 mojo::internal::Serialize<{{serializer_type}}>( 84 {{input_field}}, &{{writer}}->{{name}}); 85 86{%- else %} 87 {{writer}}->{{name}} = {{input_field}}; 88{%- endif %} 89{%- endfor %} 90{%- endmacro -%} 91 92{# Deserializes the specified struct. 93 |struct| is the struct definition. 94 |input| is the name of the input struct data view. It is expected to be 95 non-null. 96 |output_field_pattern| should be a pattern that contains one string 97 placeholder, for example, "result->%s", "p_%s". The placeholder will be 98 substituted with struct field names to refer to the output fields. 99 |context| is the name of the serialization context. 100 |success| is the name of a bool variable to track success of the operation. 101 This macro is expanded to do deserialization for both: 102 - user-defined structs: the output is an instance of the corresponding 103 struct wrapper class. 104 - method parameters/response parameters: the output is a list of 105 arguments. #} 106{%- macro deserialize(struct, input, output_field_pattern, success) -%} 107{%- for pf in struct.packed.packed_fields_in_ordinal_order %} 108{%- set output_field = output_field_pattern|format(pf.field.name) %} 109{%- set name = pf.field.name %} 110{%- set kind = pf.field.kind %} 111{%- if kind|is_object_kind or kind|is_enum_kind %} 112 if (!{{input}}.Read{{name|under_to_camel}}(&{{output_field}})) 113 {{success}} = false; 114{%- elif kind|is_any_handle_kind %} 115 {{output_field}} = {{input}}.Take{{name|under_to_camel}}(); 116{%- elif kind|is_any_interface_kind %} 117 {{output_field}} = 118 {{input}}.Take{{name|under_to_camel}}<decltype({{output_field}})>(); 119{%- else %} 120 {{output_field}} = {{input}}.{{name}}(); 121{%- endif %} 122{%- endfor %} 123{%- endmacro %} 124