OLD | NEW |
| (Empty) |
1 {%- import "interface_macros.tmpl" as interface_macros %} | |
2 {%- set class_name = interface.name %} | |
3 {%- set proxy_name = interface.name ~ "Proxy" %} | |
4 {%- set namespace_as_string = "%s"|format(namespace|replace(".","::")) %} | |
5 | |
6 {%- macro alloc_params(parameters) %} | |
7 {%- for param in parameters %} | |
8 {%- if param.kind|is_object_kind %} | |
9 {{param.kind|cpp_result_type}} p{{loop.index}}; | |
10 Deserialize_(params->{{param.name}}.ptr, &p{{loop.index}}); | |
11 {% endif -%} | |
12 {%- endfor %} | |
13 {%- endmacro %} | |
14 | |
15 {%- macro pass_params(parameters) %} | |
16 {%- for param in parameters %} | |
17 {%- if param.kind|is_string_kind -%} | |
18 p{{loop.index}} | |
19 {%- elif param.kind|is_object_kind -%} | |
20 p{{loop.index}}.Pass() | |
21 {%- elif param.kind|is_interface_kind -%} | |
22 mojo::MakeProxy<{{param.kind|get_name_for_kind}}>(mojo::MakeScopedHandle(mojo::i
nternal::FetchAndReset(¶ms->{{param.name}}))) | |
23 {%- elif param.kind|is_interface_request_kind -%} | |
24 mojo::MakeRequest<{{param.kind.kind|get_name_for_kind}}>(mojo::MakeScopedHandle(
mojo::internal::FetchAndReset(¶ms->{{param.name}}))) | |
25 {%- elif param.kind|is_any_handle_kind -%} | |
26 mojo::MakeScopedHandle(mojo::internal::FetchAndReset(¶ms->{{param.name}})) | |
27 {%- elif param.kind|is_enum_kind -%} | |
28 static_cast<{{param.kind|cpp_wrapper_type}}>(params->{{param.name}}) | |
29 {%- else -%} | |
30 params->{{param.name}} | |
31 {%- endif -%} | |
32 {%- if not loop.last %}, {% endif %} | |
33 {%- endfor %} | |
34 {%- endmacro %} | |
35 | |
36 {%- macro compute_payload_size(params_name, parameters) -%} | |
37 size_t payload_size = | |
38 mojo::internal::Align(sizeof({{params_name}})); | |
39 {#--- Computes #} | |
40 {%- for param in parameters %} | |
41 {%- if param.kind|is_object_kind %} | |
42 payload_size += GetSerializedSize_(in_{{param.name}}); | |
43 {%- endif %} | |
44 {%- endfor %} | |
45 {%- endmacro %} | |
46 | |
47 {%- macro build_message(params_name, parameters, params_description) -%} | |
48 {# TODO(yzshen): Consider refactoring to share code with | |
49 struct_serialization_definition.tmpl #} | |
50 {{params_name}}* params = | |
51 {{params_name}}::New(builder.buffer()); | |
52 {#--- Sets #} | |
53 {% for param in parameters %} | |
54 {%- if param.kind|is_object_kind %} | |
55 {%- if param.kind|is_array_kind %} | |
56 mojo::SerializeArray_<{{param.kind|get_array_validate_params|indent(24)}}>( | |
57 mojo::internal::Forward(in_{{param.name}}), builder.buffer(), ¶ms->{{p
aram.name}}.ptr); | |
58 {%- elif param.kind|is_map_kind %} | |
59 mojo::SerializeMap_<{{param.kind.value_kind|get_map_validate_params|indent(24)
}}>( | |
60 mojo::internal::Forward(in_{{param.name}}), builder.buffer(), ¶ms->{{p
aram.name}}.ptr); | |
61 {%- else %} | |
62 Serialize_(mojo::internal::Forward(in_{{param.name}}), builder.buffer(), ¶
ms->{{param.name}}.ptr); | |
63 {%- endif %} | |
64 {%- if not param.kind|is_nullable_kind %} | |
65 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( | |
66 !params->{{param.name}}.ptr, | |
67 mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER, | |
68 "null {{param.name}} argument in {{params_description}}"); | |
69 {%- endif %} | |
70 {%- elif param.kind|is_any_handle_kind %} | |
71 {%- if param.kind|is_interface_kind or | |
72 param.kind|is_interface_request_kind %} | |
73 // Delegate handle. | |
74 params->{{param.name}} = in_{{param.name}}.PassMessagePipe().release(); | |
75 {%- else %} | |
76 params->{{param.name}} = in_{{param.name}}.release(); | |
77 {%- endif %} | |
78 {%- if not param.kind|is_nullable_kind %} | |
79 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( | |
80 !params->{{param.name}}.is_valid(), | |
81 mojo::internal::VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE, | |
82 "invalid {{param.name}} argument in {{params_description}}"); | |
83 {%- endif %} | |
84 {%- else %} | |
85 params->{{param.name}} = in_{{param.name}}; | |
86 {%- endif %} | |
87 {%- endfor %} | |
88 mojo::Message message; | |
89 params->EncodePointersAndHandles(message.mutable_handles()); | |
90 builder.Finish(&message); | |
91 {%- endmacro %} | |
92 | |
93 {#--- Begin #} | |
94 const char* {{class_name}}::Name_ = "{{namespace_as_string}}::{{class_name}}"; | |
95 {#--- Constants #} | |
96 {% for constant in interface.constants %} | |
97 const {{constant.kind|cpp_pod_type}} {{interface.name}}::{{constant.name}} = {{c
onstant|constant_value}}; | |
98 {%- endfor %} | |
99 | |
100 {#--- ForwardToCallback definition #} | |
101 {%- for method in interface.methods -%} | |
102 {%- if method.response_parameters != None %} | |
103 class {{class_name}}_{{method.name}}_ForwardToCallback | |
104 : public mojo::MessageReceiver { | |
105 public: | |
106 {{class_name}}_{{method.name}}_ForwardToCallback( | |
107 const {{interface_macros.declare_callback(method)}}& callback) | |
108 : callback_(callback) { | |
109 } | |
110 virtual bool Accept(mojo::Message* message) override; | |
111 private: | |
112 {{interface_macros.declare_callback(method)}} callback_; | |
113 MOJO_DISALLOW_COPY_AND_ASSIGN({{class_name}}_{{method.name}}_ForwardToCallback
); | |
114 }; | |
115 bool {{class_name}}_{{method.name}}_ForwardToCallback::Accept( | |
116 mojo::Message* message) { | |
117 internal::{{class_name}}_{{method.name}}_ResponseParams_Data* params = | |
118 reinterpret_cast<internal::{{class_name}}_{{method.name}}_ResponseParams_D
ata*>( | |
119 message->mutable_payload()); | |
120 | |
121 params->DecodePointersAndHandles(message->mutable_handles()); | |
122 {{alloc_params(method.response_parameters)|indent(2)}} | |
123 callback_.Run({{pass_params(method.response_parameters)}}); | |
124 return true; | |
125 } | |
126 {%- endif %} | |
127 {%- endfor %} | |
128 | |
129 {{proxy_name}}::{{proxy_name}}(mojo::MessageReceiverWithResponder* receiver) | |
130 : receiver_(receiver) { | |
131 } | |
132 | |
133 {#--- Proxy definitions #} | |
134 | |
135 {%- for method in interface.methods %} | |
136 {%- set message_name = | |
137 "internal::k%s_%s_Name"|format(interface.name, method.name) %} | |
138 {%- set params_name = | |
139 "internal::%s_%s_Params_Data"|format(interface.name, method.name) %} | |
140 {%- set params_description = | |
141 "%s.%s request"|format(interface.name, method.name) %} | |
142 void {{proxy_name}}::{{method.name}}( | |
143 {{interface_macros.declare_request_params("in_", method)}}) { | |
144 {{compute_payload_size(params_name, method.parameters)}} | |
145 | |
146 {%- if method.response_parameters != None %} | |
147 mojo::internal::RequestMessageBuilder builder({{message_name}}, payload_size); | |
148 {%- else %} | |
149 mojo::internal::MessageBuilder builder({{message_name}}, payload_size); | |
150 {%- endif %} | |
151 | |
152 {{build_message(params_name, method.parameters, params_description)}} | |
153 | |
154 {%- if method.response_parameters != None %} | |
155 mojo::MessageReceiver* responder = | |
156 new {{class_name}}_{{method.name}}_ForwardToCallback(callback); | |
157 if (!receiver_->AcceptWithResponder(&message, responder)) | |
158 delete responder; | |
159 {%- else %} | |
160 bool ok = receiver_->Accept(&message); | |
161 // This return value may be ignored as !ok implies the Connector has | |
162 // encountered an error, which will be visible through other means. | |
163 MOJO_ALLOW_UNUSED_LOCAL(ok); | |
164 {%- endif %} | |
165 } | |
166 {%- endfor %} | |
167 | |
168 {#--- ProxyToResponder definition #} | |
169 {%- for method in interface.methods -%} | |
170 {%- if method.response_parameters != None %} | |
171 {%- set message_name = | |
172 "internal::k%s_%s_Name"|format(interface.name, method.name) %} | |
173 {%- set params_name = | |
174 "internal::%s_%s_ResponseParams_Data"|format(interface.name, method.
name) %} | |
175 {%- set params_description = | |
176 "%s.%s response"|format(interface.name, method.name) %} | |
177 class {{class_name}}_{{method.name}}_ProxyToResponder | |
178 : public {{interface_macros.declare_callback(method)}}::Runnable { | |
179 public: | |
180 virtual ~{{class_name}}_{{method.name}}_ProxyToResponder() { | |
181 delete responder_; | |
182 } | |
183 | |
184 {{class_name}}_{{method.name}}_ProxyToResponder( | |
185 uint64_t request_id, | |
186 mojo::MessageReceiver* responder) | |
187 : request_id_(request_id), | |
188 responder_(responder) { | |
189 } | |
190 | |
191 virtual void Run({{interface_macros.declare_params("in_", method.response_para
meters)}}) const override; | |
192 | |
193 private: | |
194 uint64_t request_id_; | |
195 mutable mojo::MessageReceiver* responder_; | |
196 MOJO_DISALLOW_COPY_AND_ASSIGN({{class_name}}_{{method.name}}_ProxyToResponder)
; | |
197 }; | |
198 void {{class_name}}_{{method.name}}_ProxyToResponder::Run( | |
199 {{interface_macros.declare_params("in_", method.response_parameters)}}) cons
t { | |
200 {{compute_payload_size(params_name, method.response_parameters)}} | |
201 mojo::internal::ResponseMessageBuilder builder( | |
202 {{message_name}}, payload_size, request_id_); | |
203 {{build_message(params_name, method.response_parameters, params_description)}} | |
204 bool ok = responder_->Accept(&message); | |
205 MOJO_ALLOW_UNUSED_LOCAL(ok); | |
206 // TODO(darin): !ok returned here indicates a malformed message, and that may | |
207 // be good reason to close the connection. However, we don't have a way to do | |
208 // that from here. We should add a way. | |
209 delete responder_; | |
210 responder_ = nullptr; | |
211 } | |
212 {%- endif -%} | |
213 {%- endfor %} | |
214 | |
215 {{class_name}}Stub::{{class_name}}Stub() | |
216 : sink_(nullptr) { | |
217 } | |
218 | |
219 {#--- Stub definition #} | |
220 | |
221 bool {{class_name}}Stub::Accept(mojo::Message* message) { | |
222 {%- if interface.methods %} | |
223 switch (message->header()->name) { | |
224 {%- for method in interface.methods %} | |
225 case internal::k{{class_name}}_{{method.name}}_Name: { | |
226 {%- if method.response_parameters == None %} | |
227 internal::{{class_name}}_{{method.name}}_Params_Data* params = | |
228 reinterpret_cast<internal::{{class_name}}_{{method.name}}_Params_Data*
>( | |
229 message->mutable_payload()); | |
230 | |
231 params->DecodePointersAndHandles(message->mutable_handles()); | |
232 {{alloc_params(method.parameters)|indent(6)}} | |
233 // A null |sink_| typically means there is a missing call to | |
234 // InterfacePtr::set_client(). | |
235 assert(sink_); | |
236 sink_->{{method.name}}({{pass_params(method.parameters)}}); | |
237 return true; | |
238 {%- else %} | |
239 break; | |
240 {%- endif %} | |
241 } | |
242 {%- endfor %} | |
243 } | |
244 {%- endif %} | |
245 return false; | |
246 } | |
247 | |
248 bool {{class_name}}Stub::AcceptWithResponder( | |
249 mojo::Message* message, mojo::MessageReceiver* responder) { | |
250 {%- if interface.methods %} | |
251 switch (message->header()->name) { | |
252 {%- for method in interface.methods %} | |
253 case internal::k{{class_name}}_{{method.name}}_Name: { | |
254 {%- if method.response_parameters != None %} | |
255 internal::{{class_name}}_{{method.name}}_Params_Data* params = | |
256 reinterpret_cast<internal::{{class_name}}_{{method.name}}_Params_Data*
>( | |
257 message->mutable_payload()); | |
258 | |
259 params->DecodePointersAndHandles(message->mutable_handles()); | |
260 {{interface_macros.declare_callback(method)}}::Runnable* runnable = | |
261 new {{class_name}}_{{method.name}}_ProxyToResponder( | |
262 message->request_id(), responder); | |
263 {{interface_macros.declare_callback(method)}} callback(runnable); | |
264 {{alloc_params(method.parameters)|indent(6)}} | |
265 // A null |sink_| typically means there is a missing call to | |
266 // InterfacePtr::set_client(). | |
267 assert(sink_); | |
268 sink_->{{method.name}}( | |
269 {%- if method.parameters -%}{{pass_params(method.parameters)}}, {% endif -%}call
back); | |
270 return true; | |
271 {%- else %} | |
272 break; | |
273 {%- endif %} | |
274 } | |
275 {%- endfor %} | |
276 } | |
277 {%- endif %} | |
278 return false; | |
279 } | |
280 | |
281 {#--- Request validator definitions #} | |
282 | |
283 {{class_name}}RequestValidator::{{class_name}}RequestValidator( | |
284 mojo::MessageReceiver* sink) : MessageFilter(sink) { | |
285 } | |
286 | |
287 bool {{class_name}}RequestValidator::Accept(mojo::Message* message) { | |
288 {%- if interface.methods %} | |
289 switch (message->header()->name) { | |
290 {%- for method in interface.methods %} | |
291 case internal::k{{class_name}}_{{method.name}}_Name: { | |
292 {%- if method.response_parameters != None %} | |
293 if (!message->has_flag(mojo::internal::kMessageExpectsResponse)) | |
294 break; | |
295 {%- else %} | |
296 if (message->has_flag(mojo::internal::kMessageExpectsResponse) || | |
297 message->has_flag(mojo::internal::kMessageIsResponse)) { | |
298 break; | |
299 } | |
300 {%- endif %} | |
301 mojo::internal::BoundsChecker bounds_checker( | |
302 message->payload(), message->payload_num_bytes(), | |
303 message->handles()->size()); | |
304 if (!internal::{{class_name}}_{{method.name}}_Params_Data::Validate( | |
305 message->payload(), &bounds_checker)) { | |
306 return false; | |
307 } | |
308 break; | |
309 } | |
310 {%- endfor %} | |
311 } | |
312 {%- endif %} | |
313 | |
314 // A null |sink_| typically means there is a missing call to | |
315 // InterfacePtr::set_client(). | |
316 assert(sink_); | |
317 return sink_->Accept(message); | |
318 } | |
319 | |
320 {#--- Response validator definitions #} | |
321 {% if interface|has_callbacks %} | |
322 {{class_name}}ResponseValidator::{{class_name}}ResponseValidator( | |
323 mojo::MessageReceiver* sink) : MessageFilter(sink) { | |
324 } | |
325 | |
326 bool {{class_name}}ResponseValidator::Accept(mojo::Message* message) { | |
327 {%- if interface.methods %} | |
328 switch (message->header()->name) { | |
329 {%- for method in interface.methods if method.response_parameters != None %} | |
330 case internal::k{{class_name}}_{{method.name}}_Name: { | |
331 if (!message->has_flag(mojo::internal::kMessageIsResponse)) | |
332 break; | |
333 mojo::internal::BoundsChecker bounds_checker( | |
334 message->payload(), message->payload_num_bytes(), | |
335 message->handles()->size()); | |
336 if (!internal::{{class_name}}_{{method.name}}_ResponseParams_Data::Validat
e( | |
337 message->payload(), &bounds_checker)) { | |
338 return false; | |
339 } | |
340 break; | |
341 } | |
342 {%- endfor %} | |
343 } | |
344 {%- endif %} | |
345 | |
346 // A null |sink_| typically means there is a missing call to | |
347 // InterfacePtr::set_client(). | |
348 assert(sink_); | |
349 return sink_->Accept(message); | |
350 } | |
351 {%- endif -%} | |
OLD | NEW |