OLD | NEW |
---|---|
1 {# TODO(yzshen): Make these templates more readable. #} | 1 {# TODO(yzshen): Consider merging the template code for user-defined and |
2 parameter data structs. That way we can eliminate validate(), fields(), | |
3 encodes() and decodes(). #} | |
4 | |
5 {# Validates the specified struct field, which is supposed to be an object | |
6 (struct/array/string/map/union). | |
7 This macro is expanded by the validate() macro. #} | |
8 {%- macro _validate_object(struct, packed_field) %} | |
9 {%- set name = packed_field.field.name %} | |
10 {%- set kind = packed_field.field.kind %} | |
11 {%- set wrapper_type = kind|cpp_wrapper_type %} | |
12 {%- if not kind|is_nullable_kind %} | |
13 {%- if kind|is_union_kind %} | |
14 if (object->{{name}}.is_null()) { | |
15 {%- else %} | |
16 if (!object->{{name}}.offset) { | |
17 {%- endif %} | |
18 ReportValidationError( | |
19 mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER, | |
20 "null {{name}} field in {{struct.name}} struct"); | |
21 return false; | |
22 } | |
23 {%- endif %} | |
24 {%- if not kind|is_union_kind %} | |
25 if (!mojo::internal::ValidateEncodedPointer(&object->{{name}}.offset)) { | |
26 ReportValidationError(mojo::internal::VALIDATION_ERROR_ILLEGAL_POINTER); | |
27 return false; | |
28 } | |
29 {%- endif %} | |
30 {%- if kind|is_array_kind or kind|is_string_kind %} | |
31 if (!{{wrapper_type}}::Data_::Validate< | |
32 {{kind|get_array_validate_params|indent(10)}}>( | |
33 mojo::internal::DecodePointerRaw(&object->{{name}}.offset), | |
34 bounds_checker)) { | |
35 {%- elif kind|is_map_kind %} | |
36 if (!{{wrapper_type}}::Data_::Validate< | |
37 {{kind.value_kind|get_map_validate_params|indent(10)}}>( | |
38 mojo::internal::DecodePointerRaw(&object->{{name}}.offset), | |
39 bounds_checker)) { | |
40 {%- elif kind|is_struct_kind %} | |
41 if (!{{kind|get_name_for_kind}}::Data_::Validate( | |
42 mojo::internal::DecodePointerRaw(&object->{{name}}.offset), | |
43 bounds_checker)) { | |
44 {%- elif kind|is_union_kind %} | |
45 // We already claimed the union's memory as part of the struct, so we don't | |
46 // try to claim the union's memory when validating the union. | |
47 if (!{{kind.name}}::Data_::Validate(&object->{{name}}, bounds_checker, true)) { | |
48 {%- else %} | |
49 if (!{{wrapper_type}}::Data_::Validate( | |
50 mojo::internal::DecodePointerRaw(&object->{{name}}.offset), | |
51 bounds_checker)) { | |
52 {%- endif %} | |
53 return false; | |
54 } | |
55 {%- endmacro %} | |
56 | |
57 {# Validates the specified struct field, which is supposed to be a handle. | |
58 This macro is expanded by the validate() macro. #} | |
59 {%- macro _validate_handle(struct, packed_field) %} | |
60 {%- set name = packed_field.field.name %} | |
61 {%- set kind = packed_field.field.kind %} | |
62 {%- if not kind|is_nullable_kind %} | |
63 if (object->{{name}}.value() == mojo::internal::kEncodedInvalidHandleValue) { | |
64 ReportValidationError( | |
65 mojo::internal::VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE, | |
66 "invalid {{name}} field in {{struct.name}} struct"); | |
67 return false; | |
68 } | |
69 {%- endif %} | |
70 if (!bounds_checker->ClaimHandle(object->{{name}})) { | |
71 ReportValidationError(mojo::internal::VALIDATION_ERROR_ILLEGAL_HANDLE); | |
72 return false; | |
73 } | |
74 {%- endmacro %} | |
75 | |
76 {# Validates the specified struct. | |
77 This macro is expanded as the body of {{struct.name}}_Data::Validate(). #} | |
78 {%- macro validate(struct) %} | |
79 if (!data) | |
80 return true; | |
81 | |
82 if (!ValidateStructHeaderAndClaimMemory(data, bounds_checker)) | |
83 return false; | |
84 | |
85 // NOTE: The memory backing |object| may be smaller than |sizeof(*object)| if | |
86 // the message comes from an older version. | |
87 const {{struct.name}}_Data* object = static_cast<const {{struct.name}}_Data*>( data); | |
88 | |
89 static const uint32_t kVersionSizePairs[{{struct.versions|length}}][2] = { | |
90 {%- for version in struct.versions -%} | |
91 { {{version.version}}, {{version.num_bytes}} }{% if not loop.last %}, {% end if -%} | |
92 {%- endfor -%} | |
93 }; | |
94 | |
95 if (object->header_.version <= {{struct.versions[-1].version}}) { | |
96 for (size_t i = 0; i < {{struct.versions|length}}; ++i) { | |
97 if (object->header_.version <= kVersionSizePairs[i][0]) { | |
98 if (object->header_.num_bytes == kVersionSizePairs[i][1]) | |
99 break; | |
100 | |
101 ReportValidationError( | |
102 mojo::internal::VALIDATION_ERROR_UNEXPECTED_STRUCT_HEADER); | |
103 return false; | |
104 } | |
105 } | |
106 } else if (object->header_.num_bytes < {{struct.versions[-1].num_bytes}}) { | |
107 ReportValidationError( | |
108 mojo::internal::VALIDATION_ERROR_UNEXPECTED_STRUCT_HEADER); | |
109 return false; | |
110 } | |
111 | |
112 {#- Before validating fields introduced at a certain version, we need to add | |
113 a version check, which makes sure we skip further validation if |object| | |
114 is from an earlier version. |last_checked_version| records the last | |
115 version that we have added such version check. #} | |
116 {%- set last_checked_version = 0 %} | |
117 {%- for packed_field in struct.packed.packed_fields_in_ordinal_order %} | |
118 {%- set kind = packed_field.field.kind %} | |
119 {%- if kind|is_object_kind or kind|is_any_handle_kind %} | |
120 {%- if packed_field.min_version > last_checked_version %} | |
121 {%- set last_checked_version = packed_field.min_version %} | |
122 if (object->header_.version < {{packed_field.min_version}}) | |
123 return true; | |
124 {%- endif %} | |
125 {%- if kind|is_object_kind %} | |
126 {{_validate_object(struct, packed_field)}} | |
127 {%- elif kind|is_any_handle_kind %} | |
128 {{_validate_handle(struct, packed_field)}} | |
129 {%- endif %} | |
130 {%- endif %} | |
131 {%- endfor %} | |
132 | |
133 return true; | |
134 {%- endmacro %} | |
135 | |
136 {# Declares a data member for the specified struct field. | |
137 This macro is expanded by the fields() macro. #} | |
138 {%- macro _field_line(field) %} | |
139 {%- set type = field.kind|cpp_field_type %} | |
140 {%- set name = field.name -%} | |
141 {%- if field.kind.spec == 'b' -%} | |
142 uint8_t {{name}} : 1; | |
143 {%- elif field.kind|is_enum_kind -%} | |
144 int32_t {{name}}; | |
145 {%- else -%} | |
146 {{type}} {{name}}; | |
147 {%- endif %} | |
148 {%- endmacro %} | |
149 | |
150 {# Declares data members for the specified struct. | |
151 This macro is expanded in the {{struct.name}}_Data class declaration. #} | |
152 {%- macro fields(struct) %} | |
153 {%- for packed_field in struct.packed.packed_fields %} | |
154 {{_field_line(packed_field.field)}} | |
155 {%- if not loop.last %} | |
156 {%- set next_pf = struct.packed.packed_fields[loop.index0 + 1] %} | |
157 {%- set pad = next_pf.offset - (packed_field.offset + packed_field.size) % } | |
158 {%- if pad > 0 %} | |
159 uint8_t pad{{loop.index0}}_[{{pad}}]; | |
160 {%- endif %} | |
161 {%- endif %} | |
162 {%- endfor -%} | |
163 | |
164 {%- set num_fields = struct.packed.packed_fields|length %} | |
165 {%- if num_fields > 0 %} | |
166 {%- set last_field = struct.packed.packed_fields[num_fields - 1] %} | |
167 {%- set offset = last_field.offset + last_field.size %} | |
168 {%- set pad = offset|get_pad(8) -%} | |
169 {%- if pad > 0 %} | |
170 uint8_t padfinal_[{{pad}}]; | |
171 {%- endif %} | |
172 {%- endif %} | |
173 {%- endmacro %} | |
174 | |
175 {# Encodes the specified struct. | |
176 Expands as the body of {{struct.name}}_Data::EncodePointersAndHandles(). #} | |
177 {%- macro encodes(struct) -%} | |
178 MOJO_CHECK(header_.version == {{struct.versions[-1].version}}); | |
179 {%- for pf in struct.packed.packed_fields_in_ordinal_order %} | |
180 {%- if pf.field.kind|is_object_kind %} | |
yzshen1
2015/03/26 07:30:15
This macro (and some others) are gone.
There migh
azani
2015/03/26 22:27:39
Done.
| |
181 {%- if pf.field.kind|is_union_kind %} | |
182 // TODO(azani): Encode pointers and handles. | |
183 {%- else %} | |
184 mojo::internal::Encode(&{{pf.field.name}}, handles); | |
185 {%- endif %} | |
186 {%- elif pf.field.kind|is_any_handle_kind %} | |
187 mojo::internal::EncodeHandle(&{{pf.field.name}}, handles); | |
188 {%- endif %} | |
189 {%- endfor %} | |
190 {%- endmacro -%} | |
191 | |
192 {# Decodes the specified struct. | |
193 This macro is expanded as the body of | |
194 {{struct.name}}_Data:DecodePointersAndHandles(). #} | |
195 {%- macro decodes(struct) -%} | |
196 // NOTE: The memory backing |this| may has be smaller than |sizeof(*this)|, if | |
197 // the message comes from an older version. | |
198 {#- Before decoding fields introduced at a certain version, we need to add | |
199 a version check, which makes sure we skip further decoding if |this| | |
200 is from an earlier version. |last_checked_version| records the last | |
201 version that we have added such version check. #} | |
202 {%- set last_checked_version = 0 %} | |
203 {%- for pf in struct.packed.packed_fields_in_ordinal_order %} | |
204 {%- set name = pf.field.name %} | |
205 {%- set kind = pf.field.kind %} | |
206 {%- if kind|is_object_kind or kind|is_any_handle_kind %} | |
207 {%- if pf.min_version > last_checked_version %} | |
208 {%- set last_checked_version = pf.min_version %} | |
209 if (header_.version < {{pf.min_version}}) | |
210 return; | |
211 {%- endif %} | |
212 {%- if kind|is_object_kind %} | |
213 {%- if pf.field.kind|is_union_kind %} | |
214 // TODO(azani): Decode pointers and handles. | |
215 {%- else %} | |
216 mojo::internal::Decode(&{{name}}, handles); | |
217 {%- endif %} | |
218 {%- else %} | |
219 mojo::internal::DecodeHandle(&{{name}}, handles); | |
220 {%- endif %} | |
221 {%- endif %} | |
222 {%- endfor %} | |
223 {%- endmacro -%} | |
2 | 224 |
3 {# Computes the serialized size for the specified struct. | 225 {# Computes the serialized size for the specified struct. |
4 |struct| is the struct definition. | 226 |struct| is the struct definition. |
5 |input_field_pattern| should be a pattern that contains one string | 227 |input_field_pattern| should be a pattern that contains one string |
6 placeholder, for example, "input->%s", "p_%s". The placeholder will be | 228 placeholder, for example, "input->%s", "p_%s". The placeholder will be |
7 substituted with struct field names to refer to the input fields. | 229 substituted with struct field names to refer to the input fields. |
8 This macro is expanded to compute seriailized size for both: | 230 This macro is expanded to compute seriailized size for both: |
9 - user-defined structs: the input is an instance of the corresponding struct | 231 - user-defined structs: the input is an instance of the corresponding struct |
10 wrapper class. | 232 wrapper class. |
11 - method parameters/response parameters: the input is a list of | 233 - method parameters/response parameters: the input is a list of |
(...skipping 27 matching lines...) Expand all Loading... | |
39 {%- set input_field = input_field_pattern|format(pf.field.name) %} | 261 {%- set input_field = input_field_pattern|format(pf.field.name) %} |
40 {%- set name = pf.field.name %} | 262 {%- set name = pf.field.name %} |
41 {%- set kind = pf.field.kind %} | 263 {%- set kind = pf.field.kind %} |
42 {%- if kind|is_object_kind %} | 264 {%- if kind|is_object_kind %} |
43 {%- if kind|is_array_kind %} | 265 {%- if kind|is_array_kind %} |
44 mojo::SerializeArray_<{{kind|get_array_validate_params|indent(24)}}>( | 266 mojo::SerializeArray_<{{kind|get_array_validate_params|indent(24)}}>( |
45 mojo::internal::Forward({{input_field}}), {{buffer}}, &{{output}}->{{name} }.ptr); | 267 mojo::internal::Forward({{input_field}}), {{buffer}}, &{{output}}->{{name} }.ptr); |
46 {%- elif kind|is_map_kind %} | 268 {%- elif kind|is_map_kind %} |
47 mojo::SerializeMap_<{{kind.value_kind|get_map_validate_params|indent(24)}}>( | 269 mojo::SerializeMap_<{{kind.value_kind|get_map_validate_params|indent(24)}}>( |
48 mojo::internal::Forward({{input_field}}), {{buffer}}, &{{output}}->{{name} }.ptr); | 270 mojo::internal::Forward({{input_field}}), {{buffer}}, &{{output}}->{{name} }.ptr); |
271 {%- elif kind|is_union_kind %} | |
272 internal::{{kind.name}}_Data* {{name}}_ptr = &{{output}}->{{name}}; | |
273 SerializeUnion_(mojo::internal::Forward({{input_field}}), {{buffer}}, &{{name} }_ptr, true); | |
49 {%- else %} | 274 {%- else %} |
50 Serialize_(mojo::internal::Forward({{input_field}}), {{buffer}}, &{{output}}-> {{name}}.ptr); | 275 Serialize_(mojo::internal::Forward({{input_field}}), {{buffer}}, &{{output}}-> {{name}}.ptr); |
51 {%- endif %} | 276 {%- endif %} |
52 {%- if not kind|is_nullable_kind %} | 277 {%- if not kind|is_nullable_kind %} |
53 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( | 278 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( |
279 {%- if kind|is_union_kind %} | |
280 {{output}}->{{name}}.is_null(), | |
281 {%- else %} | |
54 !{{output}}->{{name}}.ptr, | 282 !{{output}}->{{name}}.ptr, |
283 {%- endif %} | |
55 mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER, | 284 mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER, |
56 "null {{name}} in {{struct_display_name}}"); | 285 "null {{name}} in {{struct_display_name}}"); |
57 {%- endif %} | 286 {%- endif %} |
58 {%- elif kind|is_any_handle_kind %} | 287 {%- elif kind|is_any_handle_kind %} |
59 {%- if kind|is_interface_kind or kind|is_interface_request_kind %} | 288 {%- if kind|is_interface_kind or kind|is_interface_request_kind %} |
60 {{output}}->{{name}} = {{input_field}}.PassMessagePipe().release(); | 289 {{output}}->{{name}} = {{input_field}}.PassMessagePipe().release(); |
61 {%- else %} | 290 {%- else %} |
62 {{output}}->{{name}} = {{input_field}}.release(); | 291 {{output}}->{{name}} = {{input_field}}.release(); |
63 {%- endif %} | 292 {%- endif %} |
64 {%- if not kind|is_nullable_kind %} | 293 {%- if not kind|is_nullable_kind %} |
(...skipping 30 matching lines...) Expand all Loading... | |
95 {%- set last_checked_version = 0 %} | 324 {%- set last_checked_version = 0 %} |
96 {%- for pf in struct.packed.packed_fields_in_ordinal_order %} | 325 {%- for pf in struct.packed.packed_fields_in_ordinal_order %} |
97 {%- set output_field = output_field_pattern|format(pf.field.name) %} | 326 {%- set output_field = output_field_pattern|format(pf.field.name) %} |
98 {%- set name = pf.field.name %} | 327 {%- set name = pf.field.name %} |
99 {%- set kind = pf.field.kind %} | 328 {%- set kind = pf.field.kind %} |
100 {%- if pf.min_version > last_checked_version %} | 329 {%- if pf.min_version > last_checked_version %} |
101 {%- set last_checked_version = pf.min_version %} | 330 {%- set last_checked_version = pf.min_version %} |
102 if ({{input}}->header_.version < {{pf.min_version}}) | 331 if ({{input}}->header_.version < {{pf.min_version}}) |
103 break; | 332 break; |
104 {%- endif %} | 333 {%- endif %} |
105 {%- if kind|is_object_kind %} | 334 {%- if kind|is_union_kind %} |
yzshen1
2015/03/26 07:30:15
Please move this if into the if for "is_object_kin
azani
2015/03/26 22:27:40
Done.
| |
335 Deserialize_(&input->{{pf.field.name}}, &result->{{pf.field.name}}); | |
yzshen1
2015/03/26 07:30:15
Please use {{output_field}}, {{input}}.
Besides,
azani
2015/03/26 22:27:39
Done.
| |
336 {%- elif kind|is_object_kind %} | |
106 Deserialize_({{input}}->{{name}}.ptr, &{{output_field}}); | 337 Deserialize_({{input}}->{{name}}.ptr, &{{output_field}}); |
107 {%- elif kind|is_interface_kind or kind|is_interface_request_kind %} | 338 {%- elif kind|is_interface_kind or kind|is_interface_request_kind %} |
108 {{output_field}}.Bind(mojo::MakeScopedHandle(mojo::internal::FetchAndReset(& {{input}}->{{name}}))); | 339 {{output_field}}.Bind(mojo::MakeScopedHandle(mojo::internal::FetchAndReset(& {{input}}->{{name}}))); |
109 {%- elif kind|is_any_handle_kind %} | 340 {%- elif kind|is_any_handle_kind %} |
110 {{output_field}}.reset(mojo::internal::FetchAndReset(&{{input}}->{{name}})); | 341 {{output_field}}.reset(mojo::internal::FetchAndReset(&{{input}}->{{name}})); |
111 {%- elif kind|is_enum_kind %} | 342 {%- elif kind|is_enum_kind %} |
112 {{output_field}} = static_cast<{{kind|cpp_wrapper_type}}>({{input}}->{{name} }); | 343 {{output_field}} = static_cast<{{kind|cpp_wrapper_type}}>({{input}}->{{name} }); |
113 {%- else %} | 344 {%- else %} |
114 {{output_field}} = {{input}}->{{name}}; | 345 {{output_field}} = {{input}}->{{name}}; |
115 {%- endif %} | 346 {%- endif %} |
116 {%- endfor %} | 347 {%- endfor %} |
117 } while (false); | 348 } while (false); |
118 {%- endmacro %} | 349 {%- endmacro %} |
OLD | NEW |