This source file includes following definitions.
- DefaultHandleWriter
- is_valid_var_
- cleanup_mode_
- GetVar
- SetVar
- SetInstance
- ForceSetVarValueForTest
- WriteToMessage
- WriteDataToMessage
- ReadFromMessage
- SetCleanupModeToEndSendPassRef
- SetCleanupModeToEndReceiveCallerOwned
- ConvertVector
- exception_
- IsThrown
- output_
- Get
- GetForInstance
- Get
- Convert
- dispatcher_
- array_
- ArrayOutParam
#include "ppapi/proxy/serialized_var.h"
#include "base/logging.h"
#include "ipc/ipc_message_utils.h"
#include "ppapi/c/pp_instance.h"
#include "ppapi/proxy/dispatcher.h"
#include "ppapi/proxy/interface_proxy.h"
#include "ppapi/proxy/ppapi_param_traits.h"
#include "ppapi/proxy/ppb_buffer_proxy.h"
#include "ppapi/shared_impl/ppapi_globals.h"
#include "ppapi/shared_impl/var.h"
#include "ppapi/thunk/enter.h"
namespace ppapi {
namespace proxy {
namespace {
void DefaultHandleWriter(IPC::Message* m, const SerializedHandle& handle) {
IPC::ParamTraits<SerializedHandle>::Write(m, handle);
}
}
SerializedVar::Inner::Inner()
: serialization_rules_(NULL),
var_(PP_MakeUndefined()),
instance_(0),
cleanup_mode_(CLEANUP_NONE),
is_valid_var_(true) {
#ifndef NDEBUG
has_been_serialized_ = false;
has_been_deserialized_ = false;
#endif
}
SerializedVar::Inner::Inner(VarSerializationRules* serialization_rules)
: serialization_rules_(serialization_rules),
var_(PP_MakeUndefined()),
instance_(0),
cleanup_mode_(CLEANUP_NONE) {
#ifndef NDEBUG
has_been_serialized_ = false;
has_been_deserialized_ = false;
#endif
}
SerializedVar::Inner::~Inner() {
switch (cleanup_mode_) {
case END_SEND_PASS_REF:
serialization_rules_->EndSendPassRef(var_);
break;
case END_RECEIVE_CALLER_OWNED:
serialization_rules_->EndReceiveCallerOwned(var_);
break;
default:
break;
}
}
PP_Var SerializedVar::Inner::GetVar() {
DCHECK(serialization_rules_.get());
#if defined(NACL_WIN64)
NOTREACHED();
return PP_MakeUndefined();
#else
if (raw_var_data_.get()) {
var_ = raw_var_data_->CreatePPVar(instance_);
raw_var_data_.reset(NULL);
}
return var_;
#endif
}
void SerializedVar::Inner::SetVar(PP_Var var) {
DCHECK(serialization_rules_.get());
var_ = var;
raw_var_data_.reset(NULL);
}
void SerializedVar::Inner::SetInstance(PP_Instance instance) {
instance_ = instance;
}
void SerializedVar::Inner::ForceSetVarValueForTest(PP_Var value) {
var_ = value;
raw_var_data_.reset(NULL);
}
void SerializedVar::Inner::WriteToMessage(IPC::Message* m) const {
DCHECK(serialization_rules_.get());
#ifndef NDEBUG
DCHECK(!has_been_serialized_);
has_been_serialized_ = true;
#endif
scoped_ptr<RawVarDataGraph> data = RawVarDataGraph::Create(var_, instance_);
if (data) {
m->WriteBool(true);
data->Write(m, base::Bind(&DefaultHandleWriter));
} else {
m->WriteBool(false);
}
}
void SerializedVar::Inner::WriteDataToMessage(
IPC::Message* m,
const HandleWriter& handle_writer) const {
if (raw_var_data_) {
m->WriteBool(true);
raw_var_data_->Write(m, handle_writer);
} else {
m->WriteBool(false);
}
}
bool SerializedVar::Inner::ReadFromMessage(const IPC::Message* m,
PickleIterator* iter) {
#ifndef NDEBUG
DCHECK(!has_been_deserialized_);
has_been_deserialized_ = true;
#endif
if (!m->ReadBool(iter, &is_valid_var_))
return false;
if (is_valid_var_) {
raw_var_data_ = RawVarDataGraph::Read(m, iter);
if (!raw_var_data_)
return false;
}
return true;
}
void SerializedVar::Inner::SetCleanupModeToEndSendPassRef() {
cleanup_mode_ = END_SEND_PASS_REF;
}
void SerializedVar::Inner::SetCleanupModeToEndReceiveCallerOwned() {
cleanup_mode_ = END_RECEIVE_CALLER_OWNED;
}
SerializedVar::SerializedVar() : inner_(new Inner) {
}
SerializedVar::SerializedVar(VarSerializationRules* serialization_rules)
: inner_(new Inner(serialization_rules)) {
}
SerializedVar::~SerializedVar() {
}
SerializedVarSendInput::SerializedVarSendInput(Dispatcher* dispatcher,
const PP_Var& var)
: SerializedVar(dispatcher->serialization_rules()) {
inner_->SetVar(dispatcher->serialization_rules()->SendCallerOwned(var));
}
void SerializedVarSendInput::ConvertVector(Dispatcher* dispatcher,
const PP_Var* input,
size_t input_count,
std::vector<SerializedVar>* output) {
output->reserve(input_count);
for (size_t i = 0; i < input_count; i++)
output->push_back(SerializedVarSendInput(dispatcher, input[i]));
}
SerializedVarSendInputShmem::SerializedVarSendInputShmem(
Dispatcher* dispatcher,
const PP_Var& var,
const PP_Instance& instance)
: SerializedVar(dispatcher->serialization_rules()) {
inner_->SetVar(dispatcher->serialization_rules()->SendCallerOwned(var));
inner_->SetInstance(instance);
}
ReceiveSerializedVarReturnValue::ReceiveSerializedVarReturnValue() {
}
ReceiveSerializedVarReturnValue::ReceiveSerializedVarReturnValue(
const SerializedVar& serialized)
: SerializedVar(serialized) {
}
PP_Var ReceiveSerializedVarReturnValue::Return(Dispatcher* dispatcher) {
inner_->set_serialization_rules(dispatcher->serialization_rules());
inner_->SetVar(inner_->serialization_rules()->ReceivePassRef(
inner_->GetVar()));
return inner_->GetVar();
}
ReceiveSerializedException::ReceiveSerializedException(Dispatcher* dispatcher,
PP_Var* exception)
: SerializedVar(dispatcher->serialization_rules()),
exception_(exception) {
}
ReceiveSerializedException::~ReceiveSerializedException() {
if (exception_) {
inner_->SetVar(
inner_->serialization_rules()->ReceivePassRef(inner_->GetVar()));
*exception_ = inner_->GetVar();
} else {
if (inner_->GetVar().type == PP_VARTYPE_OBJECT)
inner_->serialization_rules()->ReleaseObjectRef(inner_->GetVar());
}
}
bool ReceiveSerializedException::IsThrown() const {
return exception_ && exception_->type != PP_VARTYPE_UNDEFINED;
}
ReceiveSerializedVarVectorOutParam::ReceiveSerializedVarVectorOutParam(
Dispatcher* dispatcher,
uint32_t* output_count,
PP_Var** output)
: dispatcher_(dispatcher),
output_count_(output_count),
output_(output) {
}
ReceiveSerializedVarVectorOutParam::~ReceiveSerializedVarVectorOutParam() {
*output_count_ = static_cast<uint32_t>(vector_.size());
if (!vector_.size()) {
*output_ = NULL;
return;
}
*output_ = static_cast<PP_Var*>(malloc(vector_.size() * sizeof(PP_Var)));
for (size_t i = 0; i < vector_.size(); i++) {
ReceiveSerializedVarReturnValue converted;
SerializedVar* serialized = &converted;
*serialized = vector_[i];
(*output_)[i] = converted.Return(dispatcher_);
}
}
std::vector<SerializedVar>* ReceiveSerializedVarVectorOutParam::OutParam() {
return &vector_;
}
SerializedVarReceiveInput::SerializedVarReceiveInput(
const SerializedVar& serialized)
: serialized_(serialized) {
}
SerializedVarReceiveInput::~SerializedVarReceiveInput() {
}
PP_Var SerializedVarReceiveInput::Get(Dispatcher* dispatcher) {
serialized_.inner_->set_serialization_rules(
dispatcher->serialization_rules());
serialized_.inner_->SetCleanupModeToEndReceiveCallerOwned();
serialized_.inner_->SetVar(
serialized_.inner_->serialization_rules()->BeginReceiveCallerOwned(
serialized_.inner_->GetVar()));
return serialized_.inner_->GetVar();
}
PP_Var SerializedVarReceiveInput::GetForInstance(Dispatcher* dispatcher,
PP_Instance instance) {
serialized_.inner_->SetInstance(instance);
return Get(dispatcher);
}
SerializedVarVectorReceiveInput::SerializedVarVectorReceiveInput(
const std::vector<SerializedVar>& serialized)
: serialized_(serialized) {
}
SerializedVarVectorReceiveInput::~SerializedVarVectorReceiveInput() {
for (size_t i = 0; i < deserialized_.size(); i++) {
serialized_[i].inner_->serialization_rules()->EndReceiveCallerOwned(
deserialized_[i]);
}
}
PP_Var* SerializedVarVectorReceiveInput::Get(Dispatcher* dispatcher,
uint32_t* array_size) {
deserialized_.resize(serialized_.size());
for (size_t i = 0; i < serialized_.size(); i++) {
serialized_[i].inner_->set_serialization_rules(
dispatcher->serialization_rules());
serialized_[i].inner_->SetVar(
serialized_[i].inner_->serialization_rules()->BeginReceiveCallerOwned(
serialized_[i].inner_->GetVar()));
deserialized_[i] = serialized_[i].inner_->GetVar();
}
*array_size = static_cast<uint32_t>(serialized_.size());
return deserialized_.empty() ? NULL : &deserialized_[0];
}
SerializedVarReturnValue::SerializedVarReturnValue(SerializedVar* serialized)
: serialized_(serialized) {
}
void SerializedVarReturnValue::Return(Dispatcher* dispatcher,
const PP_Var& var) {
serialized_->inner_->set_serialization_rules(
dispatcher->serialization_rules());
serialized_->inner_->SetCleanupModeToEndSendPassRef();
serialized_->inner_->SetVar(
dispatcher->serialization_rules()->BeginSendPassRef(var));
}
SerializedVar SerializedVarReturnValue::Convert(Dispatcher* dispatcher,
const PP_Var& var) {
SerializedVar result;
SerializedVarReturnValue retvalue(&result);
retvalue.Return(dispatcher, var);
return result;
}
SerializedVarOutParam::SerializedVarOutParam(SerializedVar* serialized)
: serialized_(serialized),
writable_var_(PP_MakeUndefined()),
dispatcher_(NULL) {
}
SerializedVarOutParam::~SerializedVarOutParam() {
if (serialized_->inner_->serialization_rules()) {
serialized_->inner_->SetVar(
serialized_->inner_->serialization_rules()->BeginSendPassRef(
writable_var_));
serialized_->inner_->SetCleanupModeToEndSendPassRef();
}
}
PP_Var* SerializedVarOutParam::OutParam(Dispatcher* dispatcher) {
dispatcher_ = dispatcher;
serialized_->inner_->set_serialization_rules(
dispatcher->serialization_rules());
return &writable_var_;
}
SerializedVarVectorOutParam::SerializedVarVectorOutParam(
std::vector<SerializedVar>* serialized)
: dispatcher_(NULL),
serialized_(serialized),
count_(0),
array_(NULL) {
}
SerializedVarVectorOutParam::~SerializedVarVectorOutParam() {
DCHECK(dispatcher_);
serialized_->reserve(count_);
for (uint32_t i = 0; i < count_; i++) {
SerializedVar var;
SerializedVarOutParam out(&var);
*out.OutParam(dispatcher_) = array_[i];
serialized_->push_back(var);
}
free(array_);
}
PP_Var** SerializedVarVectorOutParam::ArrayOutParam(Dispatcher* dispatcher) {
DCHECK(!dispatcher_);
dispatcher_ = dispatcher;
return &array_;
}
SerializedVarTestConstructor::SerializedVarTestConstructor(
const PP_Var& pod_var) {
DCHECK(pod_var.type != PP_VARTYPE_STRING);
inner_->ForceSetVarValueForTest(pod_var);
}
SerializedVarTestConstructor::SerializedVarTestConstructor(
const std::string& str) {
inner_->ForceSetVarValueForTest(StringVar::StringToPPVar(str));
}
SerializedVarTestReader::SerializedVarTestReader(const SerializedVar& var)
: SerializedVar(var) {
}
}
}