ext_output_traits.h revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
1// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#ifndef PPAPI_CPP_EXTENSIONS_OUTPUT_TRAITS_H_ 6#define PPAPI_CPP_EXTENSIONS_OUTPUT_TRAITS_H_ 7 8#include <vector> 9 10#include "ppapi/c/pp_var.h" 11#include "ppapi/cpp/dev/var_array_dev.h" 12#include "ppapi/cpp/extensions/from_var_converter.h" 13#include "ppapi/cpp/logging.h" 14#include "ppapi/cpp/pass_ref.h" 15#include "ppapi/cpp/var.h" 16 17namespace pp { 18namespace ext { 19namespace internal { 20 21// Base class for all those types within the pp::ext namespace that are used 22// with CompletionCallbackWithOutput. This class doesn't do anything itself, 23// but it affects the behavior of CallbackOutputTraits for all its subclasses. 24// 25// TODO(yzshen): Within pp::ext, basic types such as std::string or double may 26// be used with CompletionCallbackWithOutput as well. This approach doesn't 27// work for them. One way is to refactor CallbackOutputTraits to consider not 28// only the output C++ object type, but also the output parameter type that the 29// C interface uses. And then we can remove this class. 30class OutputObjectBase { 31}; 32 33template <class T> 34class VarOutputAdapterWithStorage { 35 public: 36 VarOutputAdapterWithStorage() : pp_var_(PP_MakeUndefined()) { 37 } 38 39 ~VarOutputAdapterWithStorage() { 40 PP_DCHECK(pp_var_.type == PP_VARTYPE_UNDEFINED); 41 } 42 43 PP_Var& pp_var() { return pp_var_; } 44 45 T& output() { 46 Var auto_release(PASS_REF, pp_var_); 47 converter_.Set(pp_var_); 48 pp_var_ = PP_MakeUndefined(); 49 return converter_.value(); 50 } 51 52 private: 53 PP_Var pp_var_; 54 FromVarConverter<T> converter_; 55 56 // Disallow copying and assignment. 57 VarOutputAdapterWithStorage(const VarOutputAdapterWithStorage<T>&); 58 VarOutputAdapterWithStorage<T>& operator=( 59 const VarOutputAdapterWithStorage<T>&); 60}; 61 62template <class T> 63struct ExtensionsCallbackOutputTraits { 64 typedef PP_Var* APIArgType; 65 typedef VarOutputAdapterWithStorage<T> StorageType; 66 67 static inline APIArgType StorageToAPIArg(StorageType& t) { 68 return &t.pp_var(); 69 } 70 71 // This must be called exactly once to consume the one PP_Var reference 72 // assigned to us by the browser. 73 static inline T& StorageToPluginArg(StorageType& t) { 74 return t.output(); 75 } 76}; 77 78// This class provides storage for a PP_Var and a vector of objects which are 79// of type T. The PP_Var is used as an output parameter to recevie an array var 80// from the browser. Each element in the array var is converted to a T object, 81// using FromVarConverter, and stores in the vector. 82template <class T> 83class ArrayVarOutputAdapterWithStorage { 84 public: 85 ArrayVarOutputAdapterWithStorage() : pp_var_(PP_MakeUndefined()) { 86 } 87 88 ~ArrayVarOutputAdapterWithStorage() { 89 PP_DCHECK(pp_var_.type == PP_VARTYPE_UNDEFINED); 90 } 91 92 PP_Var& pp_var() { return pp_var_; } 93 94 std::vector<T>& output() { 95 PP_DCHECK(output_storage_.empty()); 96 97 Var var(PASS_REF, pp_var_); 98 pp_var_ = PP_MakeUndefined(); 99 if (var.is_array()) { 100 VarArray_Dev array(var); 101 102 uint32_t length = array.GetLength(); 103 output_storage_.reserve(length); 104 for (uint32_t i = 0; i < length; ++i) { 105 FromVarConverter<T> converter(array.Get(i).pp_var()); 106 output_storage_.push_back(converter.value()); 107 } 108 } 109 110 return output_storage_; 111 } 112 113 private: 114 PP_Var pp_var_; 115 std::vector<T> output_storage_; 116 117 // Disallow copying and assignment. 118 ArrayVarOutputAdapterWithStorage(const ArrayVarOutputAdapterWithStorage<T>&); 119 ArrayVarOutputAdapterWithStorage<T>& operator=( 120 const ArrayVarOutputAdapterWithStorage<T>&); 121}; 122 123template <class T> 124struct ExtensionsVectorCallbackOutputTraits { 125 typedef PP_Var* APIArgType; 126 typedef ArrayVarOutputAdapterWithStorage<T> StorageType; 127 128 static inline APIArgType StorageToAPIArg(StorageType& t) { 129 return &t.pp_var(); 130 } 131 132 // This must be called exactly once to consume the one PP_Var reference 133 // assigned to us by the browser. 134 static inline std::vector<T>& StorageToPluginArg(StorageType& t) { 135 return t.output(); 136 } 137}; 138 139} // namespace internal 140} // namespace ext 141} // namespace pp 142 143#endif // PPAPI_CPP_EXTENSIONS_OUTPUT_TRAITS_H_ 144