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/extensions/from_var_converter.h" 12 #include "ppapi/cpp/logging.h" 13 #include "ppapi/cpp/pass_ref.h" 14 #include "ppapi/cpp/var.h" 15 #include "ppapi/cpp/var_array.h" 16 17 namespace pp { 18 namespace ext { 19 namespace internal { 20 21 template <class T> 22 class VarOutputAdapterWithStorage { 23 public: 24 VarOutputAdapterWithStorage() : pp_var_(PP_MakeUndefined()) { 25 } 26 27 ~VarOutputAdapterWithStorage() { 28 PP_DCHECK(pp_var_.type == PP_VARTYPE_UNDEFINED); 29 } 30 31 PP_Var& pp_var() { return pp_var_; } 32 33 T& output() { 34 Var auto_release(PASS_REF, pp_var_); 35 converter_.Set(pp_var_); 36 pp_var_ = PP_MakeUndefined(); 37 return converter_.value(); 38 } 39 40 private: 41 PP_Var pp_var_; 42 FromVarConverter<T> converter_; 43 44 // Disallow copying and assignment. 45 VarOutputAdapterWithStorage(const VarOutputAdapterWithStorage<T>&); 46 VarOutputAdapterWithStorage<T>& operator=( 47 const VarOutputAdapterWithStorage<T>&); 48 }; 49 50 // ExtCallbackOutputTraits is used with ExtCompletionCallbackWithOutput. Unlike 51 // pp::internal::CallbackOutputTraits, it always uses PP_Var* as output 52 // parameter type to interact with the browser. 53 // 54 // For example, CompletionCallbackWithOutput<double> (using 55 // pp::internal::CallbackOutputTraits) uses double* as the output parameter 56 // type; while ExtCompletionCallbackWithOutput<double> uses PP_Var*. 57 template <class T> 58 struct ExtCallbackOutputTraits { 59 typedef PP_Var* APIArgType; 60 typedef VarOutputAdapterWithStorage<T> StorageType; 61 62 static inline APIArgType StorageToAPIArg(StorageType& t) { 63 return &t.pp_var(); 64 } 65 66 // This must be called exactly once to consume the one PP_Var reference 67 // assigned to us by the browser. 68 static inline T& StorageToPluginArg(StorageType& t) { 69 return t.output(); 70 } 71 72 static inline void Initialize(StorageType* /* t */) {} 73 }; 74 75 // This class provides storage for a PP_Var and a vector of objects which are 76 // of type T. The PP_Var is used as an output parameter to receive an array var 77 // from the browser. Each element in the array var is converted to a T object, 78 // using FromVarConverter, and stores in the vector. 79 template <class T> 80 class ArrayVarOutputAdapterWithStorage { 81 public: 82 ArrayVarOutputAdapterWithStorage() : pp_var_(PP_MakeUndefined()) { 83 } 84 85 ~ArrayVarOutputAdapterWithStorage() { 86 PP_DCHECK(pp_var_.type == PP_VARTYPE_UNDEFINED); 87 } 88 89 PP_Var& pp_var() { return pp_var_; } 90 91 std::vector<T>& output() { 92 PP_DCHECK(output_storage_.empty()); 93 94 Var var(PASS_REF, pp_var_); 95 pp_var_ = PP_MakeUndefined(); 96 if (var.is_array()) { 97 VarArray array(var); 98 99 uint32_t length = array.GetLength(); 100 output_storage_.reserve(length); 101 for (uint32_t i = 0; i < length; ++i) { 102 FromVarConverter<T> converter(array.Get(i).pp_var()); 103 output_storage_.push_back(converter.value()); 104 } 105 } 106 107 return output_storage_; 108 } 109 110 private: 111 PP_Var pp_var_; 112 std::vector<T> output_storage_; 113 114 // Disallow copying and assignment. 115 ArrayVarOutputAdapterWithStorage(const ArrayVarOutputAdapterWithStorage<T>&); 116 ArrayVarOutputAdapterWithStorage<T>& operator=( 117 const ArrayVarOutputAdapterWithStorage<T>&); 118 }; 119 120 template <class T> 121 struct ExtCallbackOutputTraits< std::vector<T> > { 122 typedef PP_Var* APIArgType; 123 typedef ArrayVarOutputAdapterWithStorage<T> StorageType; 124 125 static inline APIArgType StorageToAPIArg(StorageType& t) { 126 return &t.pp_var(); 127 } 128 129 // This must be called exactly once to consume the one PP_Var reference 130 // assigned to us by the browser. 131 static inline std::vector<T>& StorageToPluginArg(StorageType& t) { 132 return t.output(); 133 } 134 135 static inline void Initialize(StorageType* /* t */) {} 136 }; 137 138 } // namespace internal 139 } // namespace ext 140 } // namespace pp 141 142 #endif // PPAPI_CPP_EXTENSIONS_OUTPUT_TRAITS_H_ 143