Convert TestOldCompletionCallback in WebSocketJobTest.
[chromium-blink-merge.git] / ppapi / proxy / serialized_var.h
blobe75f48088b365ff95085f8d0c9fdad8bd0f8f640
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef PPAPI_PROXY_SERIALIZED_VAR_H_
6 #define PPAPI_PROXY_SERIALIZED_VAR_H_
8 #include <string>
9 #include <vector>
11 #include "base/basictypes.h"
12 #include "base/memory/ref_counted.h"
13 #include "ppapi/c/pp_var.h"
14 #include "ppapi/proxy/ppapi_proxy_export.h"
16 namespace IPC {
17 class Message;
20 namespace ppapi {
21 namespace proxy {
23 class Dispatcher;
24 class VarSerializationRules;
26 // This class encapsulates a var so that we can serialize and deserialize it.
27 // The problem is that for strings, serialization and deserialization requires
28 // knowledge from outside about how to get at or create a string. So this
29 // object groups the var with a dispatcher so that string values can be set or
30 // gotten.
32 // Declare IPC messages as using this type, but don't use it directly (it has
33 // no useful public methods). Instead, instantiate one of the helper classes
34 // below which are conveniently named for each use case to prevent screwups.
36 // Design background
37 // -----------------
38 // This is sadly super complicated. The IPC system needs a consistent type to
39 // use for sending and receiving vars (this is a SerializedVar). But there are
40 // different combinations of reference counting for sending and receiving
41 // objects and for dealing with strings
43 // This makes SerializedVar complicated and easy to mess up. To make it
44 // reasonable to use, all functions are protected and there are use-specific
45 // classes that each encapsulate exactly one type of use in a way that typically
46 // won't compile if you do the wrong thing.
48 // The IPC system is designed to pass things around and will make copies in
49 // some cases, so our system must be designed so that this stuff will work.
50 // This is challenging when the SerializedVar must do some cleanup after the
51 // message is sent. To work around this, we create an inner class using a
52 // linked_ptr so all copies of a SerializedVar can share and we can guarantee
53 // that the actual data will get cleaned up on shutdown.
55 // Constness
56 // ---------
57 // SerializedVar basically doesn't support const. Everything is mutable and
58 // most functions are declared const. This unfortunateness is because of the
59 // way the IPC system works. When deserializing, it will have a const
60 // SerializedVar in a Tuple and this will be given to the function. We kind of
61 // want to modify that to convert strings and do refcounting.
63 // The helper classes used for accessing the SerializedVar have more reasonable
64 // behavior and will enforce that you don't do stupid things.
65 class PPAPI_PROXY_EXPORT SerializedVar {
66 public:
67 SerializedVar();
68 ~SerializedVar();
70 // Backend implementation for IPC::ParamTraits<SerializedVar>.
71 void WriteToMessage(IPC::Message* m) const {
72 inner_->WriteToMessage(m);
74 bool ReadFromMessage(const IPC::Message* m, void** iter) {
75 return inner_->ReadFromMessage(m, iter);
78 protected:
79 friend class SerializedVarReceiveInput;
80 friend class SerializedVarReturnValue;
81 friend class SerializedVarOutParam;
82 friend class SerializedVarSendInput;
83 friend class SerializedVarTestConstructor;
84 friend class SerializedVarVectorReceiveInput;
86 class PPAPI_PROXY_EXPORT Inner : public base::RefCounted<Inner> {
87 public:
88 Inner();
89 Inner(VarSerializationRules* serialization_rules);
90 Inner(VarSerializationRules* serialization_rules, const PP_Var& var);
91 ~Inner();
93 VarSerializationRules* serialization_rules() {
94 return serialization_rules_;
96 void set_serialization_rules(VarSerializationRules* serialization_rules) {
97 serialization_rules_ = serialization_rules;
100 // See outer class's declarations above.
101 PP_Var GetVar() const;
102 PP_Var GetIncompleteVar() const;
103 void SetVar(PP_Var var);
104 const std::string& GetString() const;
105 std::string* GetStringPtr();
107 // For the SerializedVarTestConstructor, this writes the Var value as if
108 // it was just received off the wire, without any serialization rules.
109 void ForceSetVarValueForTest(PP_Var value);
110 void ForceSetStringValueForTest(const std::string& str);
112 void WriteToMessage(IPC::Message* m) const;
113 bool ReadFromMessage(const IPC::Message* m, void** iter);
115 // Sets the cleanup mode. See the CleanupMode enum below. These functions
116 // are not just a simple setter in order to require that the appropriate
117 // data is set along with the corresponding mode.
118 void SetCleanupModeToEndSendPassRef(Dispatcher* dispatcher);
119 void SetCleanupModeToEndReceiveCallerOwned();
121 private:
122 enum CleanupMode {
123 // The serialized var won't do anything special in the destructor
124 // (default).
125 CLEANUP_NONE,
127 // The serialized var will call EndSendPassRef in the destructor.
128 END_SEND_PASS_REF,
130 // The serialized var will call EndReceiveCallerOwned in the destructor.
131 END_RECEIVE_CALLER_OWNED
134 // Rules for serializing and deserializing vars for this process type.
135 // This may be NULL, but must be set before trying to serialize to IPC when
136 // sending, or before converting back to a PP_Var when receiving.
137 VarSerializationRules* serialization_rules_;
139 // If this is set to VARTYPE_STRING and the 'value.id' is 0, then the
140 // string_value_ contains the string. This means that the caller hasn't
141 // called Deserialize with a valid Dispatcher yet, which is how we can
142 // convert the serialized string value to a PP_Var string ID.
144 // This var may not be complete until the serialization rules are set when
145 // reading from IPC since we'll need that to convert the string_value to
146 // a string ID. Before this, the as_id will be 0 for VARTYPE_STRING.
147 PP_Var var_;
149 // Holds the literal string value to/from IPC. This will be valid if the
150 // var_ is VARTYPE_STRING.
151 std::string string_value_;
153 CleanupMode cleanup_mode_;
155 // The dispatcher saved for the call to EndSendPassRef for the cleanup.
156 // This is only valid when cleanup_mode == END_SEND_PASS_REF.
157 Dispatcher* dispatcher_for_end_send_pass_ref_;
159 #ifndef NDEBUG
160 // When being sent or received over IPC, we should only be serialized or
161 // deserialized once. These flags help us assert this is true.
162 mutable bool has_been_serialized_;
163 mutable bool has_been_deserialized_;
164 #endif
166 DISALLOW_COPY_AND_ASSIGN(Inner);
169 SerializedVar(VarSerializationRules* serialization_rules);
170 SerializedVar(VarSerializationRules* serialization, const PP_Var& var);
172 mutable scoped_refptr<Inner> inner_;
175 // Helpers for message sending side --------------------------------------------
177 // For sending a value to the remote side.
179 // Example for API:
180 // void MyFunction(PP_Var)
181 // IPC message:
182 // IPC_MESSAGE_ROUTED1(MyFunction, SerializedVar);
183 // Sender would be:
184 // void MyFunctionProxy(PP_Var param) {
185 // Send(new MyFunctionMsg(SerializedVarSendInput(dispatcher, param));
186 // }
187 class SerializedVarSendInput : public SerializedVar {
188 public:
189 SerializedVarSendInput(Dispatcher* dispatcher, const PP_Var& var);
191 // Helper function for serializing a vector of input vars for serialization.
192 static void ConvertVector(Dispatcher* dispatcher,
193 const PP_Var* input,
194 size_t input_count,
195 std::vector<SerializedVar>* output);
197 private:
198 // Disallow the empty constructor, but keep the default copy constructor
199 // which is required to send the object to the IPC system.
200 SerializedVarSendInput();
203 // For the calling side of a function returning a var. The sending side uses
204 // SerializedVarReturnValue.
206 // Example for API:
207 // PP_Var MyFunction()
208 // IPC message:
209 // IPC_SYNC_MESSAGE_ROUTED0_1(MyFunction, SerializedVar);
210 // Message handler would be:
211 // PP_Var MyFunctionProxy() {
212 // ReceiveSerializedVarReturnValue result;
213 // Send(new MyFunctionMsg(&result));
214 // return result.Return(dispatcher());
215 // }
216 class PPAPI_PROXY_EXPORT ReceiveSerializedVarReturnValue
217 : public SerializedVar {
218 public:
219 // Note that we can't set the dispatcher in the constructor because the
220 // data will be overridden when the return value is set. This constructor is
221 // normally used in the pattern above (operator= will be implicitly invoked
222 // when the sync message writes the output values).
223 ReceiveSerializedVarReturnValue();
225 // This constructor can be used when deserializing manually. This is useful
226 // when you're getting strings "returned" via a struct and need to manually
227 // get the PP_Vars out. In this case just do:
228 // ReceiveSerializedVarReturnValue(serialized).Return(dispatcher);
229 explicit ReceiveSerializedVarReturnValue(const SerializedVar& serialized);
231 PP_Var Return(Dispatcher* dispatcher);
233 private:
234 DISALLOW_COPY_AND_ASSIGN(ReceiveSerializedVarReturnValue);
237 // Example for API:
238 // "void MyFunction(PP_Var* exception);"
239 // IPC message:
240 // IPC_SYNC_MESSAGE_ROUTED0_1(MyFunction, SerializedVar);
241 // Message handler would be:
242 // void OnMsgMyFunction(PP_Var* exception) {
243 // ReceiveSerializedException se(dispatcher(), exception)
244 // Send(new PpapiHostMsg_Foo(&se));
245 // }
246 class ReceiveSerializedException : public SerializedVar {
247 public:
248 ReceiveSerializedException(Dispatcher* dispatcher, PP_Var* exception);
249 ~ReceiveSerializedException();
251 // Returns true if the exception passed in the constructor is set. Check
252 // this before actually issuing the IPC.
253 bool IsThrown() const;
255 private:
256 Dispatcher* dispatcher_;
258 // The input/output exception we're wrapping. May be NULL.
259 PP_Var* exception_;
261 DISALLOW_IMPLICIT_CONSTRUCTORS(ReceiveSerializedException);
264 // Helper class for when we're returning a vector of Vars. When it goes out
265 // of scope it will automatically convert the vector filled by the IPC layer
266 // into the array specified by the constructor params.
268 // Example for API:
269 // "void MyFunction(uint32_t* count, PP_Var** vars);"
270 // IPC message:
271 // IPC_SYNC_MESSAGE_ROUTED0_1(MyFunction, std::vector<SerializedVar>);
272 // Proxy function:
273 // void MyFunction(uint32_t* count, PP_Var** vars) {
274 // ReceiveSerializedVarVectorOutParam vect(dispatcher, count, vars);
275 // Send(new MyMsg(vect.OutParam()));
276 // }
277 class ReceiveSerializedVarVectorOutParam {
278 public:
279 ReceiveSerializedVarVectorOutParam(Dispatcher* dispatcher,
280 uint32_t* output_count,
281 PP_Var** output);
282 ~ReceiveSerializedVarVectorOutParam();
284 std::vector<SerializedVar>* OutParam();
286 private:
287 Dispatcher* dispatcher_;
288 uint32_t* output_count_;
289 PP_Var** output_;
291 std::vector<SerializedVar> vector_;
293 DISALLOW_IMPLICIT_CONSTRUCTORS(ReceiveSerializedVarVectorOutParam);
296 // Helpers for message receiving side ------------------------------------------
298 // For receiving a value from the remote side.
300 // Example for API:
301 // void MyFunction(PP_Var)
302 // IPC message:
303 // IPC_MESSAGE_ROUTED1(MyFunction, SerializedVar);
304 // Message handler would be:
305 // void OnMsgMyFunction(SerializedVarReceiveInput param) {
306 // MyFunction(param.Get());
307 // }
308 class PPAPI_PROXY_EXPORT SerializedVarReceiveInput {
309 public:
310 // We rely on the implicit constructor here since the IPC layer will call
311 // us with a SerializedVar. Pass this object by value, the copy constructor
312 // will pass along the pointer (as cheap as passing a pointer arg).
313 SerializedVarReceiveInput(const SerializedVar& serialized);
314 ~SerializedVarReceiveInput();
316 PP_Var Get(Dispatcher* dispatcher);
318 private:
319 const SerializedVar& serialized_;
321 // Since the SerializedVar is const, we can't set its dispatcher (which is
322 // OK since we don't need to). But since we need it for our own uses, we
323 // track it here. Will be NULL before Get() is called.
324 Dispatcher* dispatcher_;
325 PP_Var var_;
328 // For receiving an input vector of vars from the remote side.
330 // Example:
331 // OnMsgMyFunction(SerializedVarVectorReceiveInput vector) {
332 // uint32_t size;
333 // PP_Var* array = vector.Get(dispatcher, &size);
334 // MyFunction(size, array);
335 // }
336 class SerializedVarVectorReceiveInput {
337 public:
338 SerializedVarVectorReceiveInput(const std::vector<SerializedVar>& serialized);
339 ~SerializedVarVectorReceiveInput();
341 // Only call Get() once. It will return a pointer to the converted array and
342 // place the array size in the out param. Will return NULL when the array is
343 // empty.
344 PP_Var* Get(Dispatcher* dispatcher, uint32_t* array_size);
346 private:
347 const std::vector<SerializedVar>& serialized_;
349 // Filled by Get().
350 std::vector<PP_Var> deserialized_;
353 // For the receiving side of a function returning a var. The calling side uses
354 // ReceiveSerializedVarReturnValue.
356 // Example for API:
357 // PP_Var MyFunction()
358 // IPC message:
359 // IPC_SYNC_MESSAGE_ROUTED0_1(MyFunction, SerializedVar);
360 // Message handler would be:
361 // void OnMsgMyFunction(SerializedVarReturnValue result) {
362 // result.Return(dispatcher(), MyFunction());
363 // }
364 class PPAPI_PROXY_EXPORT SerializedVarReturnValue {
365 public:
366 // We rely on the implicit constructor here since the IPC layer will call
367 // us with a SerializedVar*. Pass this object by value, the copy constructor
368 // will pass along the pointer (as cheap as passing a pointer arg).
369 SerializedVarReturnValue(SerializedVar* serialized);
371 void Return(Dispatcher* dispatcher, const PP_Var& var);
373 // Helper function for code that doesn't use the pattern above, but gets
374 // a return value from the remote side via a struct. You can pass in the
375 // SerializedVar and a PP_Var will be created with return value semantics.
376 static SerializedVar Convert(Dispatcher* dispatcher, const PP_Var& var);
378 private:
379 SerializedVar* serialized_;
382 // For writing an out param to the remote side.
384 // Example for API:
385 // "void MyFunction(PP_Var* out);"
386 // IPC message:
387 // IPC_SYNC_MESSAGE_ROUTED0_1(MyFunction, SerializedVar);
388 // Message handler would be:
389 // void OnMsgMyFunction(SerializedVarOutParam out_param) {
390 // MyFunction(out_param.OutParam(dispatcher()));
391 // }
392 class PPAPI_PROXY_EXPORT SerializedVarOutParam {
393 public:
394 // We rely on the implicit constructor here since the IPC layer will call
395 // us with a SerializedVar*. Pass this object by value, the copy constructor
396 // will pass along the pointer (as cheap as passing a pointer arg).
397 SerializedVarOutParam(SerializedVar* serialized);
398 ~SerializedVarOutParam();
400 // Call this function only once. The caller should write its result to the
401 // returned var pointer before this class goes out of scope. The var's
402 // initial value will be VARTYPE_UNDEFINED.
403 PP_Var* OutParam(Dispatcher* dispatcher);
405 private:
406 SerializedVar* serialized_;
408 // This is the value actually written by the code and returned by OutParam.
409 // We'll write this into serialized_ in our destructor.
410 PP_Var writable_var_;
412 Dispatcher* dispatcher_;
415 // For returning an array of PP_Vars to the other side and transferring
416 // ownership.
418 class SerializedVarVectorOutParam {
419 public:
420 SerializedVarVectorOutParam(std::vector<SerializedVar>* serialized);
421 ~SerializedVarVectorOutParam();
423 uint32_t* CountOutParam() { return &count_; }
424 PP_Var** ArrayOutParam(Dispatcher* dispatcher);
426 private:
427 Dispatcher* dispatcher_;
428 std::vector<SerializedVar>* serialized_;
430 uint32_t count_;
431 PP_Var* array_;
434 // For tests that just want to construct a SerializedVar for giving it to one
435 // of the other classes. This emulates a SerializedVar just received over the
436 // wire from another process.
437 class PPAPI_PROXY_EXPORT SerializedVarTestConstructor : public SerializedVar {
438 public:
439 // For POD-types and objects.
440 explicit SerializedVarTestConstructor(const PP_Var& pod_var);
442 // For strings.
443 explicit SerializedVarTestConstructor(const std::string& str);
446 // For tests that want to read what's in a SerializedVar.
447 class PPAPI_PROXY_EXPORT SerializedVarTestReader : public SerializedVar {
448 public:
449 explicit SerializedVarTestReader(const SerializedVar& var);
451 // The "incomplete" var is the one sent over the wire. Strings and object
452 // IDs have not yet been converted, so this is the thing that tests will
453 // actually want to check.
454 PP_Var GetIncompleteVar() const { return inner_->GetIncompleteVar(); }
456 const std::string& GetString() const { return inner_->GetString(); }
459 } // namespace proxy
460 } // namespace ppapi
462 #endif // PPAPI_PROXY_SERIALIZED_VAR_H_