Pepper_56_C++_interfaces
Pepper_56_C++_interfaces
 All Classes Namespaces Files Functions Typedefs Enumerations Macros Groups
array_output.h
1 // Copyright (c) 2012 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_ARRAY_OUTPUT_H_
6 #define PPAPI_CPP_ARRAY_OUTPUT_H_
7 
8 #include <stddef.h>
9 #include <stdint.h>
10 
11 #include <vector>
12 
13 #include "ppapi/c/pp_array_output.h"
14 #include "ppapi/c/pp_resource.h"
15 #include "ppapi/cpp/logging.h"
16 #include "ppapi/cpp/pass_ref.h"
17 #include "ppapi/cpp/var.h"
18 
19 namespace pp {
20 
21 // Converts the given array of PP_Resources into an array of the requested
22 // C++ resource types, passing ownership of a reference in the process.
23 //
24 // This is used to convert output arrays of resources that the browser has
25 // generated into the more convenient C++ wrappers for those resources. The
26 // initial "PassRef" parameter is there to emphasize what happens to the
27 // reference count of the input resource and to match the resource constructors
28 // that look the same.
29 template<typename ResourceObjectType>
30 inline void ConvertPPResourceArrayToObjects(
31  PassRef,
32  const std::vector<PP_Resource>& input,
33  std::vector<ResourceObjectType>* output) {
34  output->resize(0);
35  output->reserve(input.size());
36  for (size_t i = 0; i < input.size(); i++)
37  output->push_back(ResourceObjectType(PASS_REF, input[i]));
38 }
39 
40 // Non-templatized base class for the array output conversion. It provides the
41 // C implementation of a PP_ArrayOutput whose callback function is implemented
42 // as a virtual call on a derived class. Do not use directly, use one of the
43 // derived classes below.
45  public:
47  pp_array_output_.GetDataBuffer =
48  &ArrayOutputAdapterBase::GetDataBufferThunk;
49  pp_array_output_.user_data = this;
50  }
51  virtual ~ArrayOutputAdapterBase() {}
52 
53  const PP_ArrayOutput& pp_array_output() { return pp_array_output_; }
54 
55  protected:
56  virtual void* GetDataBuffer(uint32_t element_count,
57  uint32_t element_size) = 0;
58 
59  private:
60  static void* GetDataBufferThunk(void* user_data,
61  uint32_t element_count,
62  uint32_t element_size);
63 
64  PP_ArrayOutput pp_array_output_;
65 
66  // Disallow copying and assignment. This will do the wrong thing for most
67  // subclasses.
70 };
71 
72 // This adapter provides functionality for implementing a PP_ArrayOutput
73 // structure as writing to a given vector object.
74 //
75 // This is generally used internally in the C++ wrapper objects to
76 // write into an output parameter supplied by the plugin. If the element size
77 // that the browser is writing does not match the size of the type we're using
78 // this will assert and return NULL (which will cause the browser to fail the
79 // call).
80 //
81 // Example that allows the browser to write into a given vector:
82 // void DoFoo(std::vector<int>* results) {
83 // ArrayOutputAdapter<int> adapter(results);
84 // ppb_foo->DoFoo(adapter.pp_array_output());
85 // }
86 template<typename T>
88  public:
89  ArrayOutputAdapter(std::vector<T>* output) : output_(output) {}
90 
91  protected:
92  // Two-step init for the "with storage" version below.
93  ArrayOutputAdapter() : output_(NULL) {}
94  void set_output(std::vector<T>* output) { output_ = output; }
95 
96  // ArrayOutputAdapterBase implementation.
97  virtual void* GetDataBuffer(uint32_t element_count, uint32_t element_size) {
98  if (element_count == 0)
99  return NULL;
100  PP_DCHECK(element_size == sizeof(T));
101  if (element_size != sizeof(T))
102  return NULL;
103  output_->resize(element_count);
104  return &(*output_)[0];
105  }
106 
107  private:
108  std::vector<T>* output_;
109 };
110 
111 // This adapter provides functionality for implementing a PP_ArrayOutput
112 // structure as writing resources to a given vector object.
113 //
114 // When returning an array of resources, the browser will write PP_Resources
115 // via a PP_ArrayOutput. This code will automatically convert the PP_Resources
116 // to the given wrapper type, (as long as that wrapper type supports the
117 // correct constructor). The ownership of the resources that the browser passed
118 // to us will be transferred to the C++ wrapper object.
119 //
120 // Conversion of the PP_Resources to the C++ wrapper object occurs in the
121 // destructor. This object is intended to be used on the stack in a C++ wrapper
122 // object for a call.
123 //
124 // Example:
125 // void GetFiles(std::vector<pp::FileRef>* results) {
126 // ResourceArrayOutputAdapter<pp::FileRef> adapter(results);
127 // ppb_foo->DoFoo(adapter.pp_array_output());
128 // }
129 template<typename T>
131  public:
132  explicit ResourceArrayOutputAdapter(std::vector<T>* output)
133  : output_(output) {
134  output_->resize(0);
135  }
136  virtual ~ResourceArrayOutputAdapter() {
137  ConvertPPResourceArrayToObjects(PASS_REF, intermediate_output_, output_);
138  }
139 
140  protected:
141  // Two-step init for the "with storage" version below.
142  ResourceArrayOutputAdapter() : output_(NULL) {}
143  void set_output(T* output) { output_ = output; }
144 
145  // ArrayOutputAdapterBase implementation.
146  virtual void* GetDataBuffer(uint32_t element_count,
147  uint32_t element_size) {
148  if (element_count == 0)
149  return NULL;
150  PP_DCHECK(element_size == sizeof(PP_Resource));
151  if (element_size != sizeof(PP_Resource))
152  return NULL;
153  intermediate_output_.resize(element_count);
154  return &intermediate_output_[0];
155  }
156 
157  private:
158  std::vector<PP_Resource> intermediate_output_;
159  std::vector<T>* output_;
160 };
161 
162 // This adapter is like the ArrayOutputAdapter except that it also contains
163 // the underlying std::vector that will be populated (rather than writing it to
164 // an object passed into the constructor).
165 //
166 // This is used by the CompletionCallbackFactory system to collect the output
167 // parameters from an async function call. The collected data is then passed to
168 // the plugins callback function.
169 //
170 // You can also use it directly if you want to have an array output and aren't
171 // using the CompletionCallbackFactory. For example, if you're calling a
172 // PPAPI function DoFoo that takes a PP_OutputArray that is supposed to be
173 // writing integers, do this:
174 //
175 // ArrayOutputAdapterWithStorage<int> adapter;
176 // ppb_foo->DoFoo(adapter.pp_output_array());
177 // const std::vector<int>& result = adapter.output();
178 template<typename T>
180  public:
182  this->set_output(&output_storage_);
183  }
184 
185  std::vector<T>& output() { return output_storage_; }
186 
187  private:
188  std::vector<T> output_storage_;
189 };
190 
191 // This adapter is like the ArrayOutputAdapterWithStorage except this
192 // additionally converts PP_Var structs to pp::Var objects.
193 //
194 // You can also use it directly if you want to have an array output and aren't
195 // using the CompletionCallbackFactory. For example, if you're calling a
196 // PPAPI function GetVars that takes a PP_OutputArray that is supposed to be
197 // writing PP_Vars, do this:
198 //
199 // VarArrayOutputAdapterWithStorage adapter;
200 // ppb_foo->GetVars(adapter.pp_output_array());
201 // const std::vector<pp::Var>& result = adapter.output().
202 //
203 // This one is non-inline since it's not templatized.
205  public:
208 
209  // Returns the final array of resource objects, converting the PP_Vars
210  // written by the browser to pp::Var objects.
211  //
212  // This function should only be called once or we would end up converting
213  // the array more than once, which would mess up the refcounting.
214  std::vector<Var>& output();
215 
216  private:
217  // The browser will write the PP_Vars into this array.
218  std::vector<PP_Var> temp_storage_;
219 
220  // When asked for the output, the resources above will be converted to the
221  // C++ resource objects in this array for passing to the calling code.
222  std::vector<Var> output_storage_;
223 };
224 
225 // This adapter is like the ArrayOutputAdapterWithStorage except this
226 // additionally converts PP_Resources to C++ wrapper objects of the given type.
227 //
228 // You can also use it directly if you want to have an array output and aren't
229 // using the CompletionCallbackFactory. For example, if you're calling a
230 // PPAPI function GetFiles that takes a PP_OutputArray that is supposed to be
231 // writing PP_Resources cooresponding to FileRefs, do this:
232 //
233 // ResourceArrayOutputAdapterWithStorage<FileRef> adapter;
234 // ppb_foo->GetFiles(adapter.pp_output_array());
235 // std::vector<FileRef> result = adapter.output().
236 template<typename T>
238  : public ArrayOutputAdapter<PP_Resource> {
239  public:
241  set_output(&temp_storage_);
242  }
243 
245  if (!temp_storage_.empty()) {
246  // An easy way to release the resource references held by this object.
247  output();
248  }
249  }
250 
251  // Returns the final array of resource objects, converting the PP_Resources
252  // written by the browser to resource objects.
253  //
254  // This function should only be called once or we would end up converting
255  // the array more than once, which would mess up the refcounting.
256  std::vector<T>& output() {
257  PP_DCHECK(output_storage_.empty());
258 
259  ConvertPPResourceArrayToObjects(PASS_REF, temp_storage_, &output_storage_);
260  temp_storage_.clear();
261  return output_storage_;
262  }
263 
264  private:
265  // The browser will write the PP_Resources into this array.
266  std::vector<PP_Resource> temp_storage_;
267 
268  // When asked for the output, the resources above will be converted to the
269  // C++ resource objects in this array for passing to the calling code.
270  std::vector<T> output_storage_;
271 };
272 
273 } // namespace pp
274 
275 #endif // PPAPI_CPP_ARRAY_OUTPUT_H_
Definition: array_output.h:237
#define PP_DCHECK(a)
Definition: logging.h:16
Definition: array_output.h:44
Definition: array_output.h:87
Definition: array_output.h:204
PassRef
Definition: pass_ref.h:17
Definition: array_output.h:130
Definition: array_output.h:179