Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(106)

Side by Side Diff: mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl

Issue 917333003: Mojo C++ bindings templates: use the same templates for user-defined structs and method params. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 {# TODO(yzshen): Consider merging the template code for user-defined and 1 {# TODO(yzshen): Make these templates more readable. #}
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 (!object->{{name}}.offset) {
14 ReportValidationError(
15 mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
16 "null {{name}} field in {{struct.name}} struct");
17 return false;
18 }
19 {%- endif %}
20 if (!mojo::internal::ValidateEncodedPointer(&object->{{name}}.offset)) {
21 ReportValidationError(mojo::internal::VALIDATION_ERROR_ILLEGAL_POINTER);
22 return false;
23 }
24 {%- if kind|is_array_kind or kind|is_string_kind %}
25 if (!{{wrapper_type}}::Data_::Validate<
26 {{kind|get_array_validate_params|indent(10)}}>(
27 mojo::internal::DecodePointerRaw(&object->{{name}}.offset),
28 bounds_checker)) {
29 {%- elif kind|is_map_kind %}
30 if (!{{wrapper_type}}::Data_::Validate<
31 {{kind.value_kind|get_map_validate_params|indent(10)}}>(
32 mojo::internal::DecodePointerRaw(&object->{{name}}.offset),
33 bounds_checker)) {
34 {%- elif kind|is_struct_kind %}
35 if (!{{kind|get_name_for_kind}}::Data_::Validate(
36 mojo::internal::DecodePointerRaw(&object->{{name}}.offset),
37 bounds_checker)) {
38 {%- else %}
39 if (!{{wrapper_type}}::Data_::Validate(
40 mojo::internal::DecodePointerRaw(&object->{{name}}.offset),
41 bounds_checker)) {
42 {%- endif %}
43 return false;
44 }
45 {%- endmacro %}
46
47 {# Validates the specified struct field, which is supposed to be a handle.
48 This macro is expanded by the validate() macro. #}
49 {%- macro _validate_handle(struct, packed_field) %}
50 {%- set name = packed_field.field.name %}
51 {%- set kind = packed_field.field.kind %}
52 {%- if not kind|is_nullable_kind %}
53 if (object->{{name}}.value() == mojo::internal::kEncodedInvalidHandleValue) {
54 ReportValidationError(
55 mojo::internal::VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE,
56 "invalid {{name}} field in {{struct.name}} struct");
57 return false;
58 }
59 {%- endif %}
60 if (!bounds_checker->ClaimHandle(object->{{name}})) {
61 ReportValidationError(mojo::internal::VALIDATION_ERROR_ILLEGAL_HANDLE);
62 return false;
63 }
64 {%- endmacro %}
65
66 {# Validates the specified struct.
67 This macro is expanded as the body of {{struct.name}}_Data::Validate(). #}
68 {%- macro validate(struct) %}
69 if (!data)
70 return true;
71
72 if (!ValidateStructHeaderAndClaimMemory(data, bounds_checker))
73 return false;
74
75 // NOTE: The memory backing |object| may be smaller than |sizeof(*object)| if
76 // the message comes from an older version.
77 const {{struct.name}}_Data* object = static_cast<const {{struct.name}}_Data*>( data);
78
79 static const uint32_t kVersionSizePairs[{{struct.versions|length}}][2] = {
80 {%- for version in struct.versions -%}
81 { {{version.version}}, {{version.num_bytes}} }{% if not loop.last %}, {% end if -%}
82 {%- endfor -%}
83 };
84
85 if (object->header_.version <= {{struct.versions[-1].version}}) {
86 for (size_t i = 0; i < {{struct.versions|length}}; ++i) {
87 if (object->header_.version <= kVersionSizePairs[i][0]) {
88 if (object->header_.num_bytes == kVersionSizePairs[i][1])
89 break;
90
91 ReportValidationError(
92 mojo::internal::VALIDATION_ERROR_UNEXPECTED_STRUCT_HEADER);
93 return false;
94 }
95 }
96 } else if (object->header_.num_bytes < {{struct.versions[-1].num_bytes}}) {
97 ReportValidationError(
98 mojo::internal::VALIDATION_ERROR_UNEXPECTED_STRUCT_HEADER);
99 return false;
100 }
101
102 {#- Before validating fields introduced at a certain version, we need to add
103 a version check, which makes sure we skip further validation if |object|
104 is from an earlier version. |last_checked_version| records the last
105 version that we have added such version check. #}
106 {%- set last_checked_version = 0 %}
107 {%- for packed_field in struct.packed.packed_fields_in_ordinal_order %}
108 {%- set kind = packed_field.field.kind %}
109 {%- if kind|is_object_kind or kind|is_any_handle_kind %}
110 {%- if packed_field.min_version > last_checked_version %}
111 {%- set last_checked_version = packed_field.min_version %}
112 if (object->header_.version < {{packed_field.min_version}})
113 return true;
114 {%- endif %}
115 {%- if kind|is_object_kind %}
116 {{_validate_object(struct, packed_field)}}
117 {%- elif kind|is_any_handle_kind %}
118 {{_validate_handle(struct, packed_field)}}
119 {%- endif %}
120 {%- endif %}
121 {%- endfor %}
122
123 return true;
124 {%- endmacro %}
125
126 {# Declares a data member for the specified struct field.
127 This macro is expanded by the fields() macro. #}
128 {%- macro _field_line(field) %}
129 {%- set type = field.kind|cpp_field_type %}
130 {%- set name = field.name -%}
131 {%- if field.kind.spec == 'b' -%}
132 uint8_t {{name}} : 1;
133 {%- elif field.kind|is_enum_kind -%}
134 int32_t {{name}};
135 {%- else -%}
136 {{type}} {{name}};
137 {%- endif %}
138 {%- endmacro %}
139
140 {# Declares data members for the specified struct.
141 This macro is expanded in the {{struct.name}}_Data class declaration. #}
142 {%- macro fields(struct) %}
143 {%- for packed_field in struct.packed.packed_fields %}
144 {{_field_line(packed_field.field)}}
145 {%- if not loop.last %}
146 {%- set next_pf = struct.packed.packed_fields[loop.index0 + 1] %}
147 {%- set pad = next_pf.offset - (packed_field.offset + packed_field.size) % }
148 {%- if pad > 0 %}
149 uint8_t pad{{loop.index0}}_[{{pad}}];
150 {%- endif %}
151 {%- endif %}
152 {%- endfor -%}
153
154 {%- set num_fields = struct.packed.packed_fields|length %}
155 {%- if num_fields > 0 %}
156 {%- set last_field = struct.packed.packed_fields[num_fields - 1] %}
157 {%- set offset = last_field.offset + last_field.size %}
158 {%- set pad = offset|get_pad(8) -%}
159 {%- if pad > 0 %}
160 uint8_t padfinal_[{{pad}}];
161 {%- endif %}
162 {%- endif %}
163 {%- endmacro %}
164
165 {# Encodes the specified struct.
166 Expands as the body of {{struct.name}}_Data::EncodePointersAndHandles(). #}
167 {%- macro encodes(struct) -%}
168 MOJO_CHECK(header_.version == {{struct.versions[-1].version}});
169 {%- for pf in struct.packed.packed_fields_in_ordinal_order %}
170 {%- if pf.field.kind|is_object_kind %}
171 mojo::internal::Encode(&{{pf.field.name}}, handles);
172 {%- elif pf.field.kind|is_any_handle_kind %}
173 mojo::internal::EncodeHandle(&{{pf.field.name}}, handles);
174 {%- endif %}
175 {%- endfor %}
176 {%- endmacro -%}
177
178 {# Decodes the specified struct.
179 This macro is expanded as the body of
180 {{struct.name}}_Data:DecodePointersAndHandles(). #}
181 {%- macro decodes(struct) -%}
182 // NOTE: The memory backing |this| may has be smaller than |sizeof(*this)|, if
183 // the message comes from an older version.
184 {#- Before decoding fields introduced at a certain version, we need to add
185 a version check, which makes sure we skip further decoding if |this|
186 is from an earlier version. |last_checked_version| records the last
187 version that we have added such version check. #}
188 {%- set last_checked_version = 0 %}
189 {%- for pf in struct.packed.packed_fields_in_ordinal_order %}
190 {%- set name = pf.field.name %}
191 {%- set kind = pf.field.kind %}
192 {%- if kind|is_object_kind or kind|is_any_handle_kind %}
193 {%- if pf.min_version > last_checked_version %}
194 {%- set last_checked_version = pf.min_version %}
195 if (header_.version < {{pf.min_version}})
196 return;
197 {%- endif %}
198 {%- if kind|is_object_kind %}
199 mojo::internal::Decode(&{{name}}, handles);
200 {%- else %}
201 mojo::internal::DecodeHandle(&{{name}}, handles);
202 {%- endif %}
203 {%- endif %}
204 {%- endfor %}
205 {%- endmacro -%}
206 2
207 {# Computes the serialized size for the specified struct. 3 {# Computes the serialized size for the specified struct.
208 |struct| is the struct definition. 4 |struct| is the struct definition.
209 |input_field_pattern| should be a pattern that contains one string 5 |input_field_pattern| should be a pattern that contains one string
210 placeholder, for example, "input->%s", "p_%s". The placeholder will be 6 placeholder, for example, "input->%s", "p_%s". The placeholder will be
211 substituted with struct field names to refer to the input fields. 7 substituted with struct field names to refer to the input fields.
212 This macro is expanded to compute seriailized size for both: 8 This macro is expanded to compute seriailized size for both:
213 - user-defined structs: the input is an instance of the corresponding struct 9 - user-defined structs: the input is an instance of the corresponding struct
214 wrapper class. 10 wrapper class.
215 - method parameters/response parameters: the input is a list of 11 - method parameters/response parameters: the input is a list of
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
313 {%- elif kind|is_any_handle_kind %} 109 {%- elif kind|is_any_handle_kind %}
314 {{output_field}}.reset(mojo::internal::FetchAndReset(&{{input}}->{{name}})); 110 {{output_field}}.reset(mojo::internal::FetchAndReset(&{{input}}->{{name}}));
315 {%- elif kind|is_enum_kind %} 111 {%- elif kind|is_enum_kind %}
316 {{output_field}} = static_cast<{{kind|cpp_wrapper_type}}>({{input}}->{{name} }); 112 {{output_field}} = static_cast<{{kind|cpp_wrapper_type}}>({{input}}->{{name} });
317 {%- else %} 113 {%- else %}
318 {{output_field}} = {{input}}->{{name}}; 114 {{output_field}} = {{input}}->{{name}};
319 {%- endif %} 115 {%- endif %}
320 {%- endfor %} 116 {%- endfor %}
321 } while (false); 117 } while (false);
322 {%- endmacro %} 118 {%- endmacro %}
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698