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