Home | History | Annotate | Download | only in extensions
      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