| OLD | NEW |
| (Empty) |
| 1 {# TODO(yzshen): Make these templates more readable. #} | |
| 2 | |
| 3 {# Computes the serialized size for the specified struct. | |
| 4 |struct| is the struct definition. | |
| 5 |input_field_pattern| should be a pattern that contains one string | |
| 6 placeholder, for example, "input->%s", "p_%s". The placeholder will be | |
| 7 substituted with struct field names to refer to the input fields. | |
| 8 This macro is expanded to compute seriailized size for both: | |
| 9 - user-defined structs: the input is an instance of the corresponding struct | |
| 10 wrapper class. | |
| 11 - method parameters/response parameters: the input is a list of | |
| 12 arguments. | |
| 13 It declares |size| of type size_t to store the resulting size. #} | |
| 14 {%- macro get_serialized_size(struct, input_field_pattern) -%} | |
| 15 size_t size = sizeof(internal::{{struct.name}}_Data); | |
| 16 {%- for pf in struct.packed.packed_fields_in_ordinal_order if pf.field.kind|is
_object_kind %} | |
| 17 {%- if pf.field.kind|is_union_kind %} | |
| 18 size += GetSerializedSize_({{input_field_pattern|format(pf.field.name)}}); | |
| 19 {%- elif pf.field.kind|is_struct_kind %} | |
| 20 size += {{input_field_pattern|format(pf.field.name)}}.is_null() | |
| 21 ? 0 | |
| 22 : GetSerializedSize_(*{{input_field_pattern|format(pf.field.name)}
}); | |
| 23 {%- else %} | |
| 24 size += GetSerializedSize_({{input_field_pattern|format(pf.field.name)}}); | |
| 25 {%- endif %} | |
| 26 {%- endfor %} | |
| 27 {%- endmacro -%} | |
| 28 | |
| 29 {# A private macro that prints the C++ log-and-report serialization errors | |
| 30 macro, and conditionally returns if |should_return_errors| #} | |
| 31 {%- macro _validation_check_macro(condition, error_code, error_msg, should_retur
n_errors=false) -%} | |
| 32 if ({{condition}}) { | |
| 33 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING({{error_code}}, "{{error_msg}}"); | |
| 34 {%- if should_return_errors %} | |
| 35 return {{error_code}}; | |
| 36 {%- endif %} | |
| 37 } | |
| 38 {%- endmacro -%} | |
| 39 | |
| 40 {# The following 4 macros call |SerializeArray_|, |SerializeMap_|, | |
| 41 |SerializeUnion_| and |Serialize_| respectively. If |should_return_error| | |
| 42 is true, these macros do the extra work of propagating non-successful error | |
| 43 codes. #} | |
| 44 {%- macro call_serialize_array(name, kind, input, buffer, output, | |
| 45 should_return_errors, indent_size) -%} | |
| 46 { | |
| 47 const mojo::internal::ArrayValidateParams {{name}}_validate_params( | |
| 48 {{kind|get_array_validate_params_ctor_args|indent(indent_size)}}); | |
| 49 {%- if should_return_errors -%} | |
| 50 auto retval = | |
| 51 {%- endif -%} | |
| 52 mojo::SerializeArray_({{input}}, {{buffer}}, {{output}}, | |
| 53 &{{name}}_validate_params); | |
| 54 {%- if should_return_errors %} | |
| 55 if (retval != mojo::internal::ValidationError::NONE) | |
| 56 return retval; | |
| 57 {%- endif %} | |
| 58 } | |
| 59 {%- endmacro -%} | |
| 60 | |
| 61 {%- macro call_serialize_map(name, kind, input, buffer, output, | |
| 62 should_return_errors, indent_size) -%} | |
| 63 { | |
| 64 const mojo::internal::ArrayValidateParams {{name}}_validate_params( | |
| 65 {{kind.value_kind|get_map_validate_params_ctor_args|indent(indent_size)}
}); | |
| 66 {%- if should_return_errors -%} | |
| 67 auto retval = | |
| 68 {%- endif -%} | |
| 69 mojo::SerializeMap_( | |
| 70 {{input}}, {{buffer}}, {{output}}, | |
| 71 &{{name}}_validate_params); | |
| 72 {%- if should_return_errors %} | |
| 73 if (retval != mojo::internal::ValidationError::NONE) | |
| 74 return retval; | |
| 75 {%- endif %} | |
| 76 } | |
| 77 {%- endmacro -%} | |
| 78 | |
| 79 {%- macro call_serialize_union(input, buffer, output, should_return_errors) -%}
| |
| 80 { | |
| 81 {%- if should_return_errors %} | |
| 82 auto retval = | |
| 83 {%- endif %} | |
| 84 SerializeUnion_({{input}}, | |
| 85 {{buffer}}, | |
| 86 {{output}}); | |
| 87 {%- if should_return_errors %} | |
| 88 if (retval != mojo::internal::ValidationError::NONE) | |
| 89 return retval; | |
| 90 {%- endif %} | |
| 91 } | |
| 92 {%- endmacro -%} | |
| 93 | |
| 94 {%- macro call_serialize_struct(input, buffer, output, should_return_errors) -%}
| |
| 95 { | |
| 96 {%- if should_return_errors -%} | |
| 97 auto retval = | |
| 98 {%- endif -%} | |
| 99 Serialize_({{input}}, | |
| 100 {{buffer}}, | |
| 101 {{output}}); | |
| 102 {%- if should_return_errors %} | |
| 103 if (retval != mojo::internal::ValidationError::NONE) | |
| 104 return retval; | |
| 105 {%- endif %} | |
| 106 } | |
| 107 {%- endmacro -%} | |
| 108 | |
| 109 {# Serializes the specified struct. | |
| 110 |struct| is the struct definition. | |
| 111 |struct_display_name| is the display name for the struct that can be showed | |
| 112 in error/log messages, for example, "FooStruct", "FooMethod request". | |
| 113 |input_field_pattern| should be a pattern that contains one string | |
| 114 placeholder, for example, "input->%s", "p_%s". The placeholder will be | |
| 115 substituted with struct field names to refer to the input fields. | |
| 116 |output| is the name of the output struct instance. | |
| 117 |buffer| is the name of the Buffer instance used. | |
| 118 |should_return_errors| is true if validation errors need to be return'd. | |
| 119 This is needed when serializing interface parameters, where you cannot | |
| 120 return. | |
| 121 | |
| 122 This macro is expanded to do serialization for both: | |
| 123 - user-defined structs: the input is an instance of the corresponding struct | |
| 124 wrapper class. | |
| 125 - method parameters/response parameters: the input is a list of | |
| 126 arguments. | |
| 127 This macro is expanded within the C++ struct serialization methods #} | |
| 128 {%- macro serialize(struct, struct_display_name, input_field_pattern, | |
| 129 output, buffer, should_return_errors=false) -%} | |
| 130 internal::{{struct.name}}_Data* {{output}} = | |
| 131 internal::{{struct.name}}_Data::New({{buffer}}); | |
| 132 {%- for pf in struct.packed.packed_fields_in_ordinal_order %} | |
| 133 {%- set input_field = input_field_pattern|format(pf.field.name) %} | |
| 134 {%- set name = pf.field.name %} | |
| 135 {%- set kind = pf.field.kind %} | |
| 136 {%- if kind|is_object_kind %} | |
| 137 {%- if kind|is_array_kind %} | |
| 138 {{call_serialize_array(name = name, | |
| 139 kind = kind, | |
| 140 input = '&' ~ input_field, | |
| 141 buffer = buffer, | |
| 142 output = "&%s->%s.ptr"|format(output,name), | |
| 143 should_return_errors = should_return_errors, | |
| 144 indent_size = 10)}} | |
| 145 {%- elif kind|is_map_kind %} | |
| 146 {{call_serialize_map(name = name, | |
| 147 kind = kind, | |
| 148 input = '&' ~ input_field, | |
| 149 buffer = buffer, | |
| 150 output = '&%s->%s.ptr'|format(output,name), | |
| 151 should_return_errors = should_return_errors, | |
| 152 indent_size = 10)}} | |
| 153 {%- elif kind|is_union_kind %} | |
| 154 internal::{{kind.name}}_Data* {{name}}_ptr = &{{output}}->{{name}}; | |
| 155 {{call_serialize_union(input = input_field ~ ".get()", | |
| 156 buffer = buffer, | |
| 157 output = "&%s_ptr"|format(name), | |
| 158 should_return_errors = should_return_errors)}} | |
| 159 {%- elif kind|is_string_kind %} | |
| 160 SerializeString_({{input_field}}, {{buffer}}, &{{output}}->{{name}}.ptr); | |
| 161 {%- else %} | |
| 162 {{call_serialize_struct(input = input_field ~ ".get()", | |
| 163 buffer = buffer, | |
| 164 output = "&%s->%s.ptr"|format(output,name), | |
| 165 should_return_errors = should_return_errors)}} | |
| 166 {%- endif %} | |
| 167 {%- if not kind|is_nullable_kind %} | |
| 168 {%- if kind|is_union_kind %} | |
| 169 {%- set condition = "%s->%s.is_null()" | format(output, name) %} | |
| 170 {%- else %} | |
| 171 {%- set condition = "!%s->%s.ptr" | format(output,name) %} | |
| 172 {%- endif %} | |
| 173 {{_validation_check_macro( | |
| 174 condition = condition, | |
| 175 error_code = "mojo::internal::ValidationError::UNEXPECTED_NULL_POINTER", | |
| 176 error_msg = "null %s in %s" | format(name, struct_display_name), | |
| 177 should_return_errors = should_return_errors)}} | |
| 178 {%- endif %} | |
| 179 {%- elif kind|is_any_handle_kind or kind|is_interface_kind %} | |
| 180 {%- if kind|is_interface_kind %} | |
| 181 mojo::internal::InterfaceHandleToData({{input_field}}.Pass(), | |
| 182 &{{output}}->{{name}}); | |
| 183 {%- elif kind|is_interface_request_kind %} | |
| 184 {{output}}->{{name}} = {{input_field}}.PassMessagePipe().release(); | |
| 185 {%- else %} | |
| 186 {{output}}->{{name}} = {{input_field}}.release(); | |
| 187 {%- endif %} | |
| 188 {%- if not kind|is_nullable_kind %} | |
| 189 {%- if kind|is_interface_kind %} | |
| 190 {%- set condition = "!%s->%s.handle.is_valid()" | format(output, name) %
} | |
| 191 {%- else %} | |
| 192 {%- set condition = "!%s->%s.is_valid()" | format(output,name) %} | |
| 193 {%- endif %} | |
| 194 {{_validation_check_macro( | |
| 195 condition = condition, | |
| 196 error_code = "mojo::internal::ValidationError::UNEXPECTED_INVALID_HANDLE", | |
| 197 error_msg = "invalid %s in %s" | format(name, struct_display_name), | |
| 198 should_return_errors = should_return_errors)}} | |
| 199 {%- endif %} | |
| 200 {%- elif kind|is_enum_kind %} | |
| 201 {{output}}->{{name}} = | |
| 202 static_cast<int32_t>({{input_field}}); | |
| 203 {%- else %} | |
| 204 {{output}}->{{name}} = {{input_field}}; | |
| 205 {%- endif %} | |
| 206 {%- endfor %} | |
| 207 {%- endmacro -%} | |
| 208 | |
| 209 {# Deserializes the specified struct. | |
| 210 |struct| is the struct definition. | |
| 211 |input| is the name of the input struct instance. | |
| 212 |output_field_pattern| should be a pattern that contains one string | |
| 213 placeholder, for example, "result->%s", "p_%s". The placeholder will be | |
| 214 substituted with struct field names to refer to the output fields. | |
| 215 This macro is expanded to do deserialization for both: | |
| 216 - user-defined structs: the output is an instance of the corresponding | |
| 217 struct wrapper class. | |
| 218 - method parameters/response parameters: the output is a list of | |
| 219 arguments. #} | |
| 220 {%- macro deserialize(struct, input, output_field_pattern) -%} | |
| 221 do { | |
| 222 // NOTE: The memory backing |{{input}}| may has be smaller than | |
| 223 // |sizeof(*{{input}})| if the message comes from an older version. | |
| 224 {#- Before deserialize fields introduced at a certain version, we need to add | |
| 225 a version check, which makes sure we skip further deserialization if | |
| 226 |input| is from an earlier version. |last_checked_version| records the | |
| 227 last version that we have added such version check. #} | |
| 228 {%- set last_checked_version = 0 %} | |
| 229 {%- for pf in struct.packed.packed_fields_in_ordinal_order %} | |
| 230 {%- set output_field = output_field_pattern|format(pf.field.name) %} | |
| 231 {%- set name = pf.field.name %} | |
| 232 {%- set kind = pf.field.kind %} | |
| 233 {%- if pf.min_version > last_checked_version %} | |
| 234 {%- set last_checked_version = pf.min_version %} | |
| 235 if ({{input}}->header_.version < {{pf.min_version}}) | |
| 236 break; | |
| 237 {%- endif %} | |
| 238 {%- if kind|is_object_kind %} | |
| 239 {%- if kind|is_union_kind %} | |
| 240 if (!{{input}}->{{name}}.is_null()) { | |
| 241 {{output_field}} = {{kind|get_name_for_kind}}::New(); | |
| 242 Deserialize_(&{{input}}->{{name}}, {{output_field}}.get()); | |
| 243 } | |
| 244 {%- elif kind|is_struct_kind %} | |
| 245 if ({{input}}->{{name}}.ptr) { | |
| 246 {{output_field}} = {{kind|get_name_for_kind}}::New(); | |
| 247 Deserialize_({{input}}->{{name}}.ptr, {{output_field}}.get()); | |
| 248 } | |
| 249 {%- else %} | |
| 250 {#- Arrays and Maps #} | |
| 251 Deserialize_({{input}}->{{name}}.ptr, &{{output_field}}); | |
| 252 {%- endif %} | |
| 253 {%- elif kind|is_interface_kind %} | |
| 254 mojo::internal::InterfaceDataToHandle(&{{input}}->{{name}}, &{{output_field}
}); | |
| 255 {%- elif kind|is_interface_request_kind %} | |
| 256 {{output_field}}.Bind(mojo::MakeScopedHandle(mojo::internal::FetchAndReset(&
{{input}}->{{name}}))); | |
| 257 {%- elif kind|is_any_handle_kind %} | |
| 258 {{output_field}}.reset(mojo::internal::FetchAndReset(&{{input}}->{{name}})); | |
| 259 {%- elif kind|is_enum_kind %} | |
| 260 {{output_field}} = static_cast<{{kind|cpp_wrapper_type}}>({{input}}->{{name}
}); | |
| 261 {%- else %} | |
| 262 {{output_field}} = {{input}}->{{name}}; | |
| 263 {%- endif %} | |
| 264 {%- endfor %} | |
| 265 } while (false); | |
| 266 {%- endmacro %} | |
| 267 | |
| 268 {# Forward declares |struct|, and typedefs the appropriate Ptr wrapper | |
| 269 (|mojo::StructPtr| or |mojo::InlinedStructPtr|). This macro is expanded for | |
| 270 all generated structs: | |
| 271 - user-defined mojo structs | |
| 272 - interface method params/response params #} | |
| 273 {%- macro structptr_forward_decl(struct) -%} | |
| 274 class {{struct.name}}; | |
| 275 {% if struct|should_inline %} | |
| 276 using {{struct.name}}Ptr = mojo::InlinedStructPtr<{{struct.name}}>; | |
| 277 {% else %} | |
| 278 using {{struct.name}}Ptr = mojo::StructPtr<{{struct.name}}>; | |
| 279 {% endif %} | |
| 280 {% endmacro %} | |
| OLD | NEW |