15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef PPAPI_PROXY_SERIALIZED_VAR_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PPAPI_PROXY_SERIALIZED_VAR_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
149ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/memory/shared_memory.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/c/pp_instance.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_var.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/ppapi_proxy_export.h"
18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ppapi/proxy/raw_var_data.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/proxy/serialized_handle.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/proxy/serialized_structs.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/var_serialization_rules.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PickleIterator;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace IPC {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Message;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ppapi {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace proxy {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Dispatcher;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class VarSerializationRules;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This class encapsulates a var so that we can serialize and deserialize it.
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The problem is that for strings, serialization and deserialization requires
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// knowledge from outside about how to get at or create a string. So this
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// object groups the var with a dispatcher so that string values can be set or
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// gotten.
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Declare IPC messages as using this type, but don't use it directly (it has
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// no useful public methods). Instead, instantiate one of the helper classes
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// below which are conveniently named for each use case to prevent screwups.
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Design background
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// -----------------
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is sadly super complicated. The IPC system needs a consistent type to
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// use for sending and receiving vars (this is a SerializedVar). But there are
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// different combinations of reference counting for sending and receiving
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// objects and for dealing with strings
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This makes SerializedVar complicated and easy to mess up. To make it
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// reasonable to use, all functions are protected and there are use-specific
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// classes that each encapsulate exactly one type of use in a way that typically
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// won't compile if you do the wrong thing.
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The IPC system is designed to pass things around and will make copies in
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// some cases, so our system must be designed so that this stuff will work.
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is challenging when the SerializedVar must do some cleanup after the
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// message is sent. To work around this, we create an inner class using a
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// linked_ptr so all copies of a SerializedVar can share and we can guarantee
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that the actual data will get cleaned up on shutdown.
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Constness
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ---------
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SerializedVar basically doesn't support const. Everything is mutable and
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// most functions are declared const. This unfortunateness is because of the
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// way the IPC system works. When deserializing, it will have a const
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SerializedVar in a Tuple and this will be given to the function. We kind of
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// want to modify that to convert strings and do refcounting.
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The helper classes used for accessing the SerializedVar have more reasonable
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// behavior and will enforce that you don't do stupid things.
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PPAPI_PROXY_EXPORT SerializedVar {
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SerializedVar();
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~SerializedVar();
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Backend implementation for IPC::ParamTraits<SerializedVar>.
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void WriteToMessage(IPC::Message* m) const {
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    inner_->WriteToMessage(m);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // If ReadFromMessage has been called, WriteDataToMessage will write the var
847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // that has been read from ReadFromMessage back to a message. This is used
857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // when converting handles for use in NaCl.
867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void WriteDataToMessage(IPC::Message* m,
877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                          const HandleWriter& handle_writer) const {
887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    inner_->WriteDataToMessage(m, handle_writer);
897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool ReadFromMessage(const IPC::Message* m, PickleIterator* iter) {
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return inner_->ReadFromMessage(m, iter);
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool is_valid_var() const {
957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return inner_->is_valid_var();
967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Returns the shared memory handles associated with this SerializedVar.
997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  std::vector<SerializedHandle*> GetHandles() const {
1007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return inner_->GetHandles();
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class SerializedVarReceiveInput;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class SerializedVarReturnValue;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class SerializedVarOutParam;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class SerializedVarSendInput;
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  friend class SerializedVarSendInputShmem;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class SerializedVarTestConstructor;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class SerializedVarVectorReceiveInput;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class PPAPI_PROXY_EXPORT Inner : public base::RefCounted<Inner> {
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   public:
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Inner();
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Inner(VarSerializationRules* serialization_rules);
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ~Inner();
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    VarSerializationRules* serialization_rules() {
119868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return serialization_rules_.get();
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void set_serialization_rules(VarSerializationRules* serialization_rules) {
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      serialization_rules_ = serialization_rules;
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    bool is_valid_var() const {
1267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return is_valid_var_;
1277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
1287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    std::vector<SerializedHandle*> GetHandles() {
1307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return (raw_var_data_ ? raw_var_data_->GetHandles() :
1317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          std::vector<SerializedHandle*>());
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // See outer class's declarations above.
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PP_Var GetVar();
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void SetVar(PP_Var var);
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    void SetInstance(PP_Instance instance);
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // For the SerializedVarTestConstructor, this writes the Var value as if
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // it was just received off the wire, without any serialization rules.
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void ForceSetVarValueForTest(PP_Var value);
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void WriteToMessage(IPC::Message* m) const;
1447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    void WriteDataToMessage(IPC::Message* m,
1457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                            const HandleWriter& handle_writer) const;
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool ReadFromMessage(const IPC::Message* m, PickleIterator* iter);
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Sets the cleanup mode. See the CleanupMode enum below.
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void SetCleanupModeToEndSendPassRef();
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void SetCleanupModeToEndReceiveCallerOwned();
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   private:
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    enum CleanupMode {
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // The serialized var won't do anything special in the destructor
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // (default).
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CLEANUP_NONE,
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // The serialized var will call EndSendPassRef in the destructor.
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      END_SEND_PASS_REF,
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // The serialized var will call EndReceiveCallerOwned in the destructor.
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      END_RECEIVE_CALLER_OWNED
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Rules for serializing and deserializing vars for this process type.
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This may be NULL, but must be set before trying to serialize to IPC when
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // sending, or before converting back to a PP_Var when receiving.
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<VarSerializationRules> serialization_rules_;
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If this is set to VARTYPE_STRING and the 'value.id' is 0, then the
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // string_from_ipc_ holds the string. This means that the caller hasn't
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // called Deserialize with a valid Dispatcher yet, which is how we can
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // convert the serialized string value to a PP_Var string ID.
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This var may not be complete until the serialization rules are set when
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // reading from IPC since we'll need that to convert the string_value to
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // a string ID. Before this, the as_id will be 0 for VARTYPE_STRING.
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PP_Var var_;
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PP_Instance instance_;
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CleanupMode cleanup_mode_;
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // If the var is not properly serialized, this will be false.
1857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    bool is_valid_var_;
1867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NDEBUG
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // When being sent or received over IPC, we should only be serialized or
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // deserialized once. These flags help us assert this is true.
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mutable bool has_been_serialized_;
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mutable bool has_been_deserialized_;
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // ReadFromMessage() may be called on the I/O thread, e.g., when reading the
195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // reply to a sync message. We cannot use the var tracker on the I/O thread,
196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // which means we cannot create some types of PP_Var
197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // (e.g. PP_VARTYPE_STRING). The data is stored in |raw_var_data_| and the
198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // PP_Var is constructed when |GetVar()| is called.
199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scoped_ptr<RawVarDataGraph> raw_var_data_;
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DISALLOW_COPY_AND_ASSIGN(Inner);
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SerializedVar(VarSerializationRules* serialization_rules);
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mutable scoped_refptr<Inner> inner_;
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Helpers for message sending side --------------------------------------------
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// For sending a value to the remote side.
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Example for API:
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   void MyFunction(PP_Var)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// IPC message:
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   IPC_MESSAGE_ROUTED1(MyFunction, SerializedVar);
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Sender would be:
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   void MyFunctionProxy(PP_Var param) {
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     Send(new MyFunctionMsg(SerializedVarSendInput(dispatcher, param));
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   }
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PPAPI_PROXY_EXPORT SerializedVarSendInput : public SerializedVar {
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SerializedVarSendInput(Dispatcher* dispatcher, const PP_Var& var);
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Helper function for serializing a vector of input vars for serialization.
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void ConvertVector(Dispatcher* dispatcher,
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const PP_Var* input,
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            size_t input_count,
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            std::vector<SerializedVar>* output);
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Disallow the empty constructor, but keep the default copy constructor
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // which is required to send the object to the IPC system.
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SerializedVarSendInput();
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Specialization for optionally sending over shared memory.
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class PPAPI_PROXY_EXPORT SerializedVarSendInputShmem : public SerializedVar {
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SerializedVarSendInputShmem(Dispatcher* dispatcher, const PP_Var& var,
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              const PP_Instance& instance);
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Disallow the empty constructor, but keep the default copy constructor
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // which is required to send the object to the IPC system.
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SerializedVarSendInputShmem();
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// For the calling side of a function returning a var. The sending side uses
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SerializedVarReturnValue.
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Example for API:
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   PP_Var MyFunction()
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// IPC message:
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   IPC_SYNC_MESSAGE_ROUTED0_1(MyFunction, SerializedVar);
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Message handler would be:
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   PP_Var MyFunctionProxy() {
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     ReceiveSerializedVarReturnValue result;
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     Send(new MyFunctionMsg(&result));
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     return result.Return(dispatcher());
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   }
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(yzshen): Move the dispatcher parameter to the constructor and store a
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// VarSerializationRules reference instead, in case the dispatcher is destroyed
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// while waiting for reply to the sync message.
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PPAPI_PROXY_EXPORT ReceiveSerializedVarReturnValue
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : public SerializedVar {
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note that we can't set the dispatcher in the constructor because the
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // data will be overridden when the return value is set. This constructor is
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // normally used in the pattern above (operator= will be implicitly invoked
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // when the sync message writes the output values).
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ReceiveSerializedVarReturnValue();
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This constructor can be used when deserializing manually. This is useful
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // when you're getting strings "returned" via a struct and need to manually
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // get the PP_Vars out. In this case just do:
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   ReceiveSerializedVarReturnValue(serialized).Return(dispatcher);
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit ReceiveSerializedVarReturnValue(const SerializedVar& serialized);
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PP_Var Return(Dispatcher* dispatcher);
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ReceiveSerializedVarReturnValue);
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Example for API:
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   "void MyFunction(PP_Var* exception);"
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// IPC message:
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   IPC_SYNC_MESSAGE_ROUTED0_1(MyFunction, SerializedVar);
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Message handler would be:
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   void OnMsgMyFunction(PP_Var* exception) {
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     ReceiveSerializedException se(dispatcher(), exception)
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     Send(new PpapiHostMsg_Foo(&se));
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   }
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PPAPI_PROXY_EXPORT ReceiveSerializedException : public SerializedVar {
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ReceiveSerializedException(Dispatcher* dispatcher, PP_Var* exception);
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~ReceiveSerializedException();
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if the exception passed in the constructor is set. Check
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // this before actually issuing the IPC.
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool IsThrown() const;
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The input/output exception we're wrapping. May be NULL.
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PP_Var* exception_;
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_IMPLICIT_CONSTRUCTORS(ReceiveSerializedException);
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Helper class for when we're returning a vector of Vars. When it goes out
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// of scope it will automatically convert the vector filled by the IPC layer
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// into the array specified by the constructor params.
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Example for API:
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   "void MyFunction(uint32_t* count, PP_Var** vars);"
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// IPC message:
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   IPC_SYNC_MESSAGE_ROUTED0_1(MyFunction, std::vector<SerializedVar>);
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Proxy function:
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   void MyFunction(uint32_t* count, PP_Var** vars) {
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     ReceiveSerializedVarVectorOutParam vect(dispatcher, count, vars);
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     Send(new MyMsg(vect.OutParam()));
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   }
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PPAPI_PROXY_EXPORT ReceiveSerializedVarVectorOutParam {
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ReceiveSerializedVarVectorOutParam(Dispatcher* dispatcher,
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     uint32_t* output_count,
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     PP_Var** output);
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~ReceiveSerializedVarVectorOutParam();
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<SerializedVar>* OutParam();
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Dispatcher* dispatcher_;
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint32_t* output_count_;
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PP_Var** output_;
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<SerializedVar> vector_;
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_IMPLICIT_CONSTRUCTORS(ReceiveSerializedVarVectorOutParam);
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Helpers for message receiving side ------------------------------------------
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// For receiving a value from the remote side.
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Example for API:
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   void MyFunction(PP_Var)
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// IPC message:
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   IPC_MESSAGE_ROUTED1(MyFunction, SerializedVar);
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Message handler would be:
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   void OnMsgMyFunction(SerializedVarReceiveInput param) {
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     MyFunction(param.Get());
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   }
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PPAPI_PROXY_EXPORT SerializedVarReceiveInput {
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We rely on the implicit constructor here since the IPC layer will call
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // us with a SerializedVar. Pass this object by value, the copy constructor
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // will pass along the pointer (as cheap as passing a pointer arg).
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SerializedVarReceiveInput(const SerializedVar& serialized);
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~SerializedVarReceiveInput();
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PP_Var Get(Dispatcher* dispatcher);
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PP_Var GetForInstance(Dispatcher* dispatcher, PP_Instance instance);
3677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool is_valid_var() { return serialized_.is_valid_var(); }
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const SerializedVar& serialized_;
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// For receiving an input vector of vars from the remote side.
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Example:
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   OnMsgMyFunction(SerializedVarVectorReceiveInput vector) {
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     uint32_t size;
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     PP_Var* array = vector.Get(dispatcher, &size);
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     MyFunction(size, array);
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   }
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PPAPI_PROXY_EXPORT SerializedVarVectorReceiveInput {
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SerializedVarVectorReceiveInput(const std::vector<SerializedVar>& serialized);
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~SerializedVarVectorReceiveInput();
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Only call Get() once. It will return a pointer to the converted array and
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // place the array size in the out param. Will return NULL when the array is
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // empty.
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PP_Var* Get(Dispatcher* dispatcher, uint32_t* array_size);
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::vector<SerializedVar>& serialized_;
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Filled by Get().
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<PP_Var> deserialized_;
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// For the receiving side of a function returning a var. The calling side uses
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ReceiveSerializedVarReturnValue.
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Example for API:
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   PP_Var MyFunction()
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// IPC message:
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   IPC_SYNC_MESSAGE_ROUTED0_1(MyFunction, SerializedVar);
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Message handler would be:
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   void OnMsgMyFunction(SerializedVarReturnValue result) {
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     result.Return(dispatcher(), MyFunction());
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   }
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PPAPI_PROXY_EXPORT SerializedVarReturnValue {
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We rely on the implicit constructor here since the IPC layer will call
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // us with a SerializedVar*. Pass this object by value, the copy constructor
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // will pass along the pointer (as cheap as passing a pointer arg).
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SerializedVarReturnValue(SerializedVar* serialized);
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Return(Dispatcher* dispatcher, const PP_Var& var);
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Helper function for code that doesn't use the pattern above, but gets
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a return value from the remote side via a struct. You can pass in the
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SerializedVar and a PP_Var will be created with return value semantics.
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static SerializedVar Convert(Dispatcher* dispatcher, const PP_Var& var);
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SerializedVar* serialized_;
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// For writing an out param to the remote side.
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Example for API:
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   "void MyFunction(PP_Var* out);"
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// IPC message:
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   IPC_SYNC_MESSAGE_ROUTED0_1(MyFunction, SerializedVar);
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Message handler would be:
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   void OnMsgMyFunction(SerializedVarOutParam out_param) {
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     MyFunction(out_param.OutParam(dispatcher()));
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   }
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PPAPI_PROXY_EXPORT SerializedVarOutParam {
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We rely on the implicit constructor here since the IPC layer will call
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // us with a SerializedVar*. Pass this object by value, the copy constructor
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // will pass along the pointer (as cheap as passing a pointer arg).
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SerializedVarOutParam(SerializedVar* serialized);
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~SerializedVarOutParam();
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Call this function only once. The caller should write its result to the
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // returned var pointer before this class goes out of scope. The var's
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // initial value will be VARTYPE_UNDEFINED.
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PP_Var* OutParam(Dispatcher* dispatcher);
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SerializedVar* serialized_;
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This is the value actually written by the code and returned by OutParam.
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We'll write this into serialized_ in our destructor.
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PP_Var writable_var_;
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Dispatcher* dispatcher_;
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// For returning an array of PP_Vars to the other side and transferring
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ownership.
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PPAPI_PROXY_EXPORT SerializedVarVectorOutParam {
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SerializedVarVectorOutParam(std::vector<SerializedVar>* serialized);
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~SerializedVarVectorOutParam();
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint32_t* CountOutParam() { return &count_; }
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PP_Var** ArrayOutParam(Dispatcher* dispatcher);
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Dispatcher* dispatcher_;
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<SerializedVar>* serialized_;
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint32_t count_;
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PP_Var* array_;
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// For tests that just want to construct a SerializedVar for giving it to one
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// of the other classes. This emulates a SerializedVar just received over the
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// wire from another process.
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PPAPI_PROXY_EXPORT SerializedVarTestConstructor : public SerializedVar {
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For POD-types and objects.
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit SerializedVarTestConstructor(const PP_Var& pod_var);
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For strings.
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit SerializedVarTestConstructor(const std::string& str);
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// For tests that want to read what's in a SerializedVar.
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PPAPI_PROXY_EXPORT SerializedVarTestReader : public SerializedVar {
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit SerializedVarTestReader(const SerializedVar& var);
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PP_Var GetVar() const { return inner_->GetVar(); }
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace proxy
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace ppapi
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // PPAPI_PROXY_SERIALIZED_VAR_H_
503