blob: ed57be10d9841118d26225b46962c8ba909ab4a6 [file] [log] [blame]
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef PPAPI_CPP_EXTENSIONS_OUTPUT_TRAITS_H_
#define PPAPI_CPP_EXTENSIONS_OUTPUT_TRAITS_H_
#include <vector>
#include "ppapi/c/pp_var.h"
#include "ppapi/cpp/extensions/from_var_converter.h"
#include "ppapi/cpp/logging.h"
#include "ppapi/cpp/pass_ref.h"
#include "ppapi/cpp/var.h"
#include "ppapi/cpp/var_array.h"
namespace pp {
namespace ext {
namespace internal {
template <class T>
class VarOutputAdapterWithStorage {
public:
VarOutputAdapterWithStorage() : pp_var_(PP_MakeUndefined()) {
}
~VarOutputAdapterWithStorage() {
PP_DCHECK(pp_var_.type == PP_VARTYPE_UNDEFINED);
}
PP_Var& pp_var() { return pp_var_; }
T& output() {
Var auto_release(PASS_REF, pp_var_);
converter_.Set(pp_var_);
pp_var_ = PP_MakeUndefined();
return converter_.value();
}
private:
PP_Var pp_var_;
FromVarConverter<T> converter_;
// Disallow copying and assignment.
VarOutputAdapterWithStorage(const VarOutputAdapterWithStorage<T>&);
VarOutputAdapterWithStorage<T>& operator=(
const VarOutputAdapterWithStorage<T>&);
};
// ExtCallbackOutputTraits is used with ExtCompletionCallbackWithOutput. Unlike
// pp::internal::CallbackOutputTraits, it always uses PP_Var* as output
// parameter type to interact with the browser.
//
// For example, CompletionCallbackWithOutput<double> (using
// pp::internal::CallbackOutputTraits) uses double* as the output parameter
// type; while ExtCompletionCallbackWithOutput<double> uses PP_Var*.
template <class T>
struct ExtCallbackOutputTraits {
typedef PP_Var* APIArgType;
typedef VarOutputAdapterWithStorage<T> StorageType;
static inline APIArgType StorageToAPIArg(StorageType& t) {
return &t.pp_var();
}
// This must be called exactly once to consume the one PP_Var reference
// assigned to us by the browser.
static inline T& StorageToPluginArg(StorageType& t) {
return t.output();
}
static inline void Initialize(StorageType* /* t */) {}
};
// This class provides storage for a PP_Var and a vector of objects which are
// of type T. The PP_Var is used as an output parameter to receive an array var
// from the browser. Each element in the array var is converted to a T object,
// using FromVarConverter, and stores in the vector.
template <class T>
class ArrayVarOutputAdapterWithStorage {
public:
ArrayVarOutputAdapterWithStorage() : pp_var_(PP_MakeUndefined()) {
}
~ArrayVarOutputAdapterWithStorage() {
PP_DCHECK(pp_var_.type == PP_VARTYPE_UNDEFINED);
}
PP_Var& pp_var() { return pp_var_; }
std::vector<T>& output() {
PP_DCHECK(output_storage_.empty());
Var var(PASS_REF, pp_var_);
pp_var_ = PP_MakeUndefined();
if (var.is_array()) {
VarArray array(var);
uint32_t length = array.GetLength();
output_storage_.reserve(length);
for (uint32_t i = 0; i < length; ++i) {
FromVarConverter<T> converter(array.Get(i).pp_var());
output_storage_.push_back(converter.value());
}
}
return output_storage_;
}
private:
PP_Var pp_var_;
std::vector<T> output_storage_;
// Disallow copying and assignment.
ArrayVarOutputAdapterWithStorage(const ArrayVarOutputAdapterWithStorage<T>&);
ArrayVarOutputAdapterWithStorage<T>& operator=(
const ArrayVarOutputAdapterWithStorage<T>&);
};
template <class T>
struct ExtCallbackOutputTraits< std::vector<T> > {
typedef PP_Var* APIArgType;
typedef ArrayVarOutputAdapterWithStorage<T> StorageType;
static inline APIArgType StorageToAPIArg(StorageType& t) {
return &t.pp_var();
}
// This must be called exactly once to consume the one PP_Var reference
// assigned to us by the browser.
static inline std::vector<T>& StorageToPluginArg(StorageType& t) {
return t.output();
}
static inline void Initialize(StorageType* /* t */) {}
};
} // namespace internal
} // namespace ext
} // namespace pp
#endif // PPAPI_CPP_EXTENSIONS_OUTPUT_TRAITS_H_