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)#include "ppapi/proxy/serialized_var.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_message_utils.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/c/pp_instance.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/dispatcher.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/interface_proxy.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/ppapi_param_traits.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/proxy/ppb_buffer_proxy.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/shared_impl/ppapi_globals.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/shared_impl/var.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/thunk/enter.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ppapi {
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace proxy {
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)namespace {
227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void DefaultHandleWriter(IPC::Message* m, const SerializedHandle& handle) {
237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  IPC::ParamTraits<SerializedHandle>::Write(m, handle);
247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}  // namespace
267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SerializedVar::Inner --------------------------------------------------------
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SerializedVar::Inner::Inner()
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : serialization_rules_(NULL),
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      var_(PP_MakeUndefined()),
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      instance_(0),
337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      cleanup_mode_(CLEANUP_NONE),
347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      is_valid_var_(true) {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NDEBUG
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  has_been_serialized_ = false;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  has_been_deserialized_ = false;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SerializedVar::Inner::Inner(VarSerializationRules* serialization_rules)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : serialization_rules_(serialization_rules),
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      var_(PP_MakeUndefined()),
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      instance_(0),
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cleanup_mode_(CLEANUP_NONE) {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NDEBUG
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  has_been_serialized_ = false;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  has_been_deserialized_ = false;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SerializedVar::Inner::~Inner() {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (cleanup_mode_) {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case END_SEND_PASS_REF:
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      serialization_rules_->EndSendPassRef(var_);
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case END_RECEIVE_CALLER_OWNED:
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      serialization_rules_->EndReceiveCallerOwned(var_);
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Var SerializedVar::Inner::GetVar() {
66868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(serialization_rules_.get());
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(NACL_WIN64)
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  NOTREACHED();
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return PP_MakeUndefined();
7123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#else
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (raw_var_data_.get()) {
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    var_ = raw_var_data_->CreatePPVar(instance_);
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    raw_var_data_.reset(NULL);
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return var_;
7823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#endif
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SerializedVar::Inner::SetVar(PP_Var var) {
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sanity check, when updating the var we should have received a
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // serialization rules pointer already.
84868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(serialization_rules_.get());
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var_ = var;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  raw_var_data_.reset(NULL);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SerializedVar::Inner::SetInstance(PP_Instance instance) {
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  instance_ = instance;
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SerializedVar::Inner::ForceSetVarValueForTest(PP_Var value) {
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var_ = value;
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  raw_var_data_.reset(NULL);
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SerializedVar::Inner::WriteToMessage(IPC::Message* m) const {
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // When writing to the IPC messages, a serialization rules handler should
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // always have been set.
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // When sending a message, it should be difficult to trigger this if you're
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // using the SerializedVarSendInput class and giving a non-NULL dispatcher.
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure you're using the proper "Send" helper class.
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // It should be more common to see this when handling an incoming message
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // that returns a var. This means the message handler didn't write to the
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // output parameter, or possibly you used the wrong helper class
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (normally SerializedVarReturnValue).
110868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(serialization_rules_.get());
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NDEBUG
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should only be serializing something once.
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!has_been_serialized_);
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  has_been_serialized_ = true;
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<RawVarDataGraph> data = RawVarDataGraph::Create(var_, instance_);
1187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (data) {
1197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    m->WriteBool(true);  // Success.
1207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    data->Write(m, base::Bind(&DefaultHandleWriter));
1217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  } else {
1227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    m->WriteBool(false);  // Failure.
1237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
1247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
1257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void SerializedVar::Inner::WriteDataToMessage(
1277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    IPC::Message* m,
1287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const HandleWriter& handle_writer) const {
1297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (raw_var_data_) {
1307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    m->WriteBool(true);  // Success.
1317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    raw_var_data_->Write(m, handle_writer);
1327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  } else {
1337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    m->WriteBool(false);  // Failure.
1347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SerializedVar::Inner::ReadFromMessage(const IPC::Message* m,
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           PickleIterator* iter) {
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NDEBUG
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should only deserialize something once or will end up with leaked
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // references.
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // One place this has happened in the past is using
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // std::vector<SerializedVar>.resize(). If you're doing this manually instead
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // of using the helper classes for handling in/out vectors of vars, be
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // sure you use the same pattern as the SerializedVarVector classes.
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!has_been_deserialized_);
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  has_been_deserialized_ = true;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // When reading, the dispatcher should be set when we get a Deserialize
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // call (which will supply a dispatcher).
1527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!m->ReadBool(iter, &is_valid_var_))
1537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return false;
1547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (is_valid_var_) {
1557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    raw_var_data_ = RawVarDataGraph::Read(m, iter);
1567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (!raw_var_data_)
1577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return false;
1587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
1597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return true;
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SerializedVar::Inner::SetCleanupModeToEndSendPassRef() {
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cleanup_mode_ = END_SEND_PASS_REF;
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SerializedVar::Inner::SetCleanupModeToEndReceiveCallerOwned() {
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cleanup_mode_ = END_RECEIVE_CALLER_OWNED;
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SerializedVar ---------------------------------------------------------------
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SerializedVar::SerializedVar() : inner_(new Inner) {
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SerializedVar::SerializedVar(VarSerializationRules* serialization_rules)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : inner_(new Inner(serialization_rules)) {
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SerializedVar::~SerializedVar() {
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SerializedVarSendInput ------------------------------------------------------
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SerializedVarSendInput::SerializedVarSendInput(Dispatcher* dispatcher,
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               const PP_Var& var)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : SerializedVar(dispatcher->serialization_rules()) {
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inner_->SetVar(dispatcher->serialization_rules()->SendCallerOwned(var));
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SerializedVarSendInput::ConvertVector(Dispatcher* dispatcher,
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           const PP_Var* input,
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           size_t input_count,
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           std::vector<SerializedVar>* output) {
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  output->reserve(input_count);
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < input_count; i++)
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    output->push_back(SerializedVarSendInput(dispatcher, input[i]));
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// SerializedVarSendInputShmem -------------------------------------------------
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SerializedVarSendInputShmem::SerializedVarSendInputShmem(
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Dispatcher* dispatcher,
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const PP_Var& var,
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const PP_Instance& instance)
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : SerializedVar(dispatcher->serialization_rules()) {
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  inner_->SetVar(dispatcher->serialization_rules()->SendCallerOwned(var));
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  inner_->SetInstance(instance);
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ReceiveSerializedVarReturnValue ---------------------------------------------
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ReceiveSerializedVarReturnValue::ReceiveSerializedVarReturnValue() {
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ReceiveSerializedVarReturnValue::ReceiveSerializedVarReturnValue(
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const SerializedVar& serialized)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : SerializedVar(serialized) {
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Var ReceiveSerializedVarReturnValue::Return(Dispatcher* dispatcher) {
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inner_->set_serialization_rules(dispatcher->serialization_rules());
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inner_->SetVar(inner_->serialization_rules()->ReceivePassRef(
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      inner_->GetVar()));
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return inner_->GetVar();
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ReceiveSerializedException --------------------------------------------------
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ReceiveSerializedException::ReceiveSerializedException(Dispatcher* dispatcher,
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                       PP_Var* exception)
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : SerializedVar(dispatcher->serialization_rules()),
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      exception_(exception) {
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ReceiveSerializedException::~ReceiveSerializedException() {
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (exception_) {
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // When an output exception is specified, it will take ownership of the
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // reference.
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    inner_->SetVar(
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        inner_->serialization_rules()->ReceivePassRef(inner_->GetVar()));
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *exception_ = inner_->GetVar();
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // When no output exception is specified, the browser thinks we have a ref
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // to an object that we don't want (this will happen only in the plugin
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // since the browser will always specify an out exception for the plugin to
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // write into).
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Strings don't need this handling since we can just avoid creating a
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Var from the std::string in the first place.
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (inner_->GetVar().type == PP_VARTYPE_OBJECT)
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      inner_->serialization_rules()->ReleaseObjectRef(inner_->GetVar());
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ReceiveSerializedException::IsThrown() const {
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return exception_ && exception_->type != PP_VARTYPE_UNDEFINED;
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ReceiveSerializedVarVectorOutParam ------------------------------------------
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ReceiveSerializedVarVectorOutParam::ReceiveSerializedVarVectorOutParam(
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Dispatcher* dispatcher,
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint32_t* output_count,
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PP_Var** output)
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : dispatcher_(dispatcher),
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      output_count_(output_count),
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      output_(output) {
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ReceiveSerializedVarVectorOutParam::~ReceiveSerializedVarVectorOutParam() {
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *output_count_ = static_cast<uint32_t>(vector_.size());
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!vector_.size()) {
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *output_ = NULL;
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *output_ = static_cast<PP_Var*>(malloc(vector_.size() * sizeof(PP_Var)));
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < vector_.size(); i++) {
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Here we just mimic what happens when returning a value.
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ReceiveSerializedVarReturnValue converted;
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SerializedVar* serialized = &converted;
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *serialized = vector_[i];
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (*output_)[i] = converted.Return(dispatcher_);
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::vector<SerializedVar>* ReceiveSerializedVarVectorOutParam::OutParam() {
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return &vector_;
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SerializedVarReceiveInput ---------------------------------------------------
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SerializedVarReceiveInput::SerializedVarReceiveInput(
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const SerializedVar& serialized)
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : serialized_(serialized) {
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SerializedVarReceiveInput::~SerializedVarReceiveInput() {
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Var SerializedVarReceiveInput::Get(Dispatcher* dispatcher) {
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  serialized_.inner_->set_serialization_rules(
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dispatcher->serialization_rules());
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that when the serialized var goes out of scope it cleans up the
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // stuff we're making in BeginReceiveCallerOwned.
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  serialized_.inner_->SetCleanupModeToEndReceiveCallerOwned();
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  serialized_.inner_->SetVar(
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      serialized_.inner_->serialization_rules()->BeginReceiveCallerOwned(
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          serialized_.inner_->GetVar()));
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return serialized_.inner_->GetVar();
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PP_Var SerializedVarReceiveInput::GetForInstance(Dispatcher* dispatcher,
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                 PP_Instance instance) {
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  serialized_.inner_->SetInstance(instance);
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return Get(dispatcher);
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SerializedVarVectorReceiveInput ---------------------------------------------
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SerializedVarVectorReceiveInput::SerializedVarVectorReceiveInput(
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::vector<SerializedVar>& serialized)
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : serialized_(serialized) {
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SerializedVarVectorReceiveInput::~SerializedVarVectorReceiveInput() {
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < deserialized_.size(); i++) {
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    serialized_[i].inner_->serialization_rules()->EndReceiveCallerOwned(
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        deserialized_[i]);
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Var* SerializedVarVectorReceiveInput::Get(Dispatcher* dispatcher,
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             uint32_t* array_size) {
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  deserialized_.resize(serialized_.size());
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < serialized_.size(); i++) {
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The vectors must be able to clean themselves up after this call is
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // torn down.
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    serialized_[i].inner_->set_serialization_rules(
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dispatcher->serialization_rules());
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    serialized_[i].inner_->SetVar(
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        serialized_[i].inner_->serialization_rules()->BeginReceiveCallerOwned(
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            serialized_[i].inner_->GetVar()));
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    deserialized_[i] = serialized_[i].inner_->GetVar();
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *array_size = static_cast<uint32_t>(serialized_.size());
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return deserialized_.empty() ? NULL : &deserialized_[0];
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SerializedVarReturnValue ----------------------------------------------------
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SerializedVarReturnValue::SerializedVarReturnValue(SerializedVar* serialized)
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : serialized_(serialized) {
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SerializedVarReturnValue::Return(Dispatcher* dispatcher,
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      const PP_Var& var) {
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  serialized_->inner_->set_serialization_rules(
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dispatcher->serialization_rules());
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Var must clean up after our BeginSendPassRef call.
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  serialized_->inner_->SetCleanupModeToEndSendPassRef();
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  serialized_->inner_->SetVar(
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dispatcher->serialization_rules()->BeginSendPassRef(var));
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SerializedVar SerializedVarReturnValue::Convert(Dispatcher* dispatcher,
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                const PP_Var& var) {
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Mimic what happens in the normal case.
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SerializedVar result;
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SerializedVarReturnValue retvalue(&result);
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  retvalue.Return(dispatcher, var);
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SerializedVarOutParam -------------------------------------------------------
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SerializedVarOutParam::SerializedVarOutParam(SerializedVar* serialized)
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : serialized_(serialized),
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      writable_var_(PP_MakeUndefined()),
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dispatcher_(NULL) {
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SerializedVarOutParam::~SerializedVarOutParam() {
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (serialized_->inner_->serialization_rules()) {
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // When unset, OutParam wasn't called. We'll just leave the var untouched
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // in that case.
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    serialized_->inner_->SetVar(
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        serialized_->inner_->serialization_rules()->BeginSendPassRef(
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            writable_var_));
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Normally the current object will be created on the stack to wrap a
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // SerializedVar and won't have a scope around the actual IPC send. So we
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // need to tell the SerializedVar to do the begin/end send pass ref calls.
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    serialized_->inner_->SetCleanupModeToEndSendPassRef();
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Var* SerializedVarOutParam::OutParam(Dispatcher* dispatcher) {
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dispatcher_ = dispatcher;
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  serialized_->inner_->set_serialization_rules(
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dispatcher->serialization_rules());
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return &writable_var_;
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SerializedVarVectorOutParam -------------------------------------------------
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SerializedVarVectorOutParam::SerializedVarVectorOutParam(
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<SerializedVar>* serialized)
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : dispatcher_(NULL),
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      serialized_(serialized),
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      count_(0),
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      array_(NULL) {
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SerializedVarVectorOutParam::~SerializedVarVectorOutParam() {
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(dispatcher_);
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Convert the array written by the pepper code to the serialized structure.
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note we can't use resize here, we have to allocate a new SerializedVar
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // for each serialized item. See ParamTraits<vector<SerializedVar>>::Read.
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  serialized_->reserve(count_);
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (uint32_t i = 0; i < count_; i++) {
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Just mimic what we do for regular OutParams.
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SerializedVar var;
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SerializedVarOutParam out(&var);
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *out.OutParam(dispatcher_) = array_[i];
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    serialized_->push_back(var);
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // When returning arrays, the pepper code expects the caller to take
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ownership of the array.
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  free(array_);
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Var** SerializedVarVectorOutParam::ArrayOutParam(Dispatcher* dispatcher) {
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!dispatcher_);  // Should only be called once.
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dispatcher_ = dispatcher;
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return &array_;
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SerializedVarTestConstructor::SerializedVarTestConstructor(
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const PP_Var& pod_var) {
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(pod_var.type != PP_VARTYPE_STRING);
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inner_->ForceSetVarValueForTest(pod_var);
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SerializedVarTestConstructor::SerializedVarTestConstructor(
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& str) {
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inner_->ForceSetVarValueForTest(StringVar::StringToPPVar(str));
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SerializedVarTestReader::SerializedVarTestReader(const SerializedVar& var)
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : SerializedVar(var) {
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace proxy
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace ppapi
468