Separate Simple Backend creation from initialization.
[chromium-blink-merge.git] / ppapi / cpp / array_output.h
blob3a52190feac93d6bdba66fbdb49665b748812b31
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.
5 #ifndef PPAPI_CPP_ARRAY_OUTPUT_H_
6 #define PPAPI_CPP_ARRAY_OUTPUT_H_
8 #include <vector>
10 #include "ppapi/c/dev/ppb_directory_reader_dev.h"
11 #include "ppapi/c/pp_array_output.h"
12 #include "ppapi/c/pp_resource.h"
13 #include "ppapi/cpp/dev/directory_entry_dev.h"
14 #include "ppapi/cpp/logging.h"
15 #include "ppapi/cpp/pass_ref.h"
16 #include "ppapi/cpp/var.h"
18 namespace pp {
20 // Converts the given array of PP_Resources into an array of the requested
21 // C++ resource types, passing ownership of a reference in the process.
23 // This is used to convert output arrays of resources that the browser has
24 // generated into the more convenient C++ wrappers for those resources. The
25 // initial "PassRef" parameter is there to emphasize what happens to the
26 // reference count of the input resource and to match the resource constructors
27 // that look the same.
28 template<typename ResourceObjectType>
29 inline void ConvertPPResourceArrayToObjects(
30 PassRef,
31 const std::vector<PP_Resource>& input,
32 std::vector<ResourceObjectType>* output) {
33 output->resize(0);
34 output->reserve(input.size());
35 for (size_t i = 0; i < input.size(); i++)
36 output->push_back(ResourceObjectType(PASS_REF, input[i]));
39 // Non-templatized base class for the array output conversion. It provides the
40 // C implementation of a PP_ArrayOutput whose callback function is implemented
41 // as a virtual call on a derived class. Do not use directly, use one of the
42 // derived classes below.
43 class ArrayOutputAdapterBase {
44 public:
45 ArrayOutputAdapterBase() {
46 pp_array_output_.GetDataBuffer =
47 &ArrayOutputAdapterBase::GetDataBufferThunk;
48 pp_array_output_.user_data = this;
50 virtual ~ArrayOutputAdapterBase() {}
52 const PP_ArrayOutput& pp_array_output() { return pp_array_output_; }
54 protected:
55 virtual void* GetDataBuffer(uint32_t element_count,
56 uint32_t element_size) = 0;
58 private:
59 static void* GetDataBufferThunk(void* user_data,
60 uint32_t element_count,
61 uint32_t element_size);
63 PP_ArrayOutput pp_array_output_;
65 // Disallow copying and assignment. This will do the wrong thing for most
66 // subclasses.
67 ArrayOutputAdapterBase(const ArrayOutputAdapterBase&);
68 ArrayOutputAdapterBase& operator=(const ArrayOutputAdapterBase&);
71 // This adapter provides functionality for implementing a PP_ArrayOutput
72 // structure as writing to a given vector object.
74 // This is generally used internally in the C++ wrapper objects to
75 // write into an output parameter supplied by the plugin. If the element size
76 // that the browser is writing does not match the size of the type we're using
77 // this will assert and return NULL (which will cause the browser to fail the
78 // call).
80 // Example that allows the browser to write into a given vector:
81 // void DoFoo(std::vector<int>* results) {
82 // ArrayOutputAdapter<int> adapter(results);
83 // ppb_foo->DoFoo(adapter.pp_array_output());
84 // }
85 template<typename T>
86 class ArrayOutputAdapter : public ArrayOutputAdapterBase {
87 public:
88 ArrayOutputAdapter(std::vector<T>* output) : output_(output) {}
90 protected:
91 // Two-step init for the "with storage" version below.
92 ArrayOutputAdapter() : output_(NULL) {}
93 void set_output(std::vector<T>* output) { output_ = output; }
95 // ArrayOutputAdapterBase implementation.
96 virtual void* GetDataBuffer(uint32_t element_count, uint32_t element_size) {
97 if (element_count == 0)
98 return NULL;
99 PP_DCHECK(element_size == sizeof(T));
100 if (element_size != sizeof(T))
101 return NULL;
102 output_->resize(element_count);
103 return &(*output_)[0];
106 private:
107 std::vector<T>* output_;
110 // This adapter provides functionality for implementing a PP_ArrayOutput
111 // structure as writing resources to a given vector object.
113 // When returning an array of resources, the browser will write PP_Resources
114 // via a PP_ArrayOutput. This code will automatically convert the PP_Resources
115 // to the given wrapper type, (as long as that wrapper type supports the
116 // correct constructor). The ownership of the resources that the browser passed
117 // to us will be transferred to the C++ wrapper object.
119 // Conversion of the PP_Resources to the C++ wrapper object occurs in the
120 // destructor. This object is intended to be used on the stack in a C++ wrapper
121 // object for a call.
123 // Example:
124 // void GetFiles(std::vector<pp::FileRef>* results) {
125 // ResourceArrayOutputAdapter<pp::FileRef> adapter(results);
126 // ppb_foo->DoFoo(adapter.pp_array_output());
127 // }
128 template<typename T>
129 class ResourceArrayOutputAdapter : public ArrayOutputAdapterBase {
130 public:
131 explicit ResourceArrayOutputAdapter(std::vector<T>* output)
132 : output_(output) {
133 output_->resize(0);
135 virtual ~ResourceArrayOutputAdapter() {
136 ConvertPPResourceArrayToObjects(PASS_REF, intermediate_output_, output_);
139 protected:
140 // Two-step init for the "with storage" version below.
141 ResourceArrayOutputAdapter() : output_(NULL) {}
142 void set_output(T* output) { output_ = output; }
144 // ArrayOutputAdapterBase implementation.
145 virtual void* GetDataBuffer(uint32_t element_count,
146 uint32_t element_size) {
147 if (element_count == 0)
148 return NULL;
149 PP_DCHECK(element_size == sizeof(PP_Resource));
150 if (element_size != sizeof(PP_Resource))
151 return NULL;
152 intermediate_output_.resize(element_count);
153 return &intermediate_output_[0];
156 private:
157 std::vector<PP_Resource> intermediate_output_;
158 std::vector<T>* output_;
161 // This adapter is like the ArrayOutputAdapter except that it also contains
162 // the underlying std::vector that will be populated (rather than writing it to
163 // an object passed into the constructor).
165 // This is used by the CompletionCallbackFactory system to collect the output
166 // parameters from an async function call. The collected data is then passed to
167 // the plugins callback function.
169 // You can also use it directly if you want to have an array output and aren't
170 // using the CompletionCallbackFactory. For example, if you're calling a
171 // PPAPI function DoFoo that takes a PP_OutputArray that is supposed to be
172 // writing integers, do this:
174 // ArrayOutputAdapterWithStorage<int> adapter;
175 // ppb_foo->DoFoo(adapter.pp_output_array());
176 // const std::vector<int>& result = adapter.output();
177 template<typename T>
178 class ArrayOutputAdapterWithStorage : public ArrayOutputAdapter<T> {
179 public:
180 ArrayOutputAdapterWithStorage() {
181 this->set_output(&output_storage_);
184 std::vector<T>& output() { return output_storage_; }
186 private:
187 std::vector<T> output_storage_;
190 // This adapter is like the ArrayOutputAdapterWithStorage except this
191 // additionally converts PP_Var structs to pp::Var objects.
193 // You can also use it directly if you want to have an array output and aren't
194 // using the CompletionCallbackFactory. For example, if you're calling a
195 // PPAPI function GetVars that takes a PP_OutputArray that is supposed to be
196 // writing PP_Vars, do this:
198 // VarArrayOutputAdapterWithStorage adapter;
199 // ppb_foo->GetVars(adapter.pp_output_array());
200 // const std::vector<pp::Var>& result = adapter.output().
202 // This one is non-inline since it's not templatized.
203 class VarArrayOutputAdapterWithStorage : public ArrayOutputAdapter<PP_Var> {
204 public:
205 VarArrayOutputAdapterWithStorage();
206 virtual ~VarArrayOutputAdapterWithStorage();
208 // Returns the final array of resource objects, converting the PP_Vars
209 // written by the browser to pp::Var objects.
211 // This function should only be called once or we would end up converting
212 // the array more than once, which would mess up the refcounting.
213 std::vector<Var>& output();
215 private:
216 // The browser will write the PP_Vars into this array.
217 std::vector<PP_Var> temp_storage_;
219 // When asked for the output, the resources above will be converted to the
220 // C++ resource objects in this array for passing to the calling code.
221 std::vector<Var> output_storage_;
224 // This adapter is like the ArrayOutputAdapterWithStorage except this
225 // additionally converts PP_Resources to C++ wrapper objects of the given type.
227 // You can also use it directly if you want to have an array output and aren't
228 // using the CompletionCallbackFactory. For example, if you're calling a
229 // PPAPI function GetFiles that takes a PP_OutputArray that is supposed to be
230 // writing PP_Resources cooresponding to FileRefs, do this:
232 // ResourceArrayOutputAdapterWithStorage<FileRef> adapter;
233 // ppb_foo->GetFiles(adapter.pp_output_array());
234 // std::vector<FileRef> result = adapter.output().
235 template<typename T>
236 class ResourceArrayOutputAdapterWithStorage
237 : public ArrayOutputAdapter<PP_Resource> {
238 public:
239 ResourceArrayOutputAdapterWithStorage() {
240 set_output(&temp_storage_);
243 virtual ~ResourceArrayOutputAdapterWithStorage() {
244 if (!temp_storage_.empty()) {
245 // An easy way to release the resource references held by this object.
246 output();
250 // Returns the final array of resource objects, converting the PP_Resources
251 // written by the browser to resource objects.
253 // This function should only be called once or we would end up converting
254 // the array more than once, which would mess up the refcounting.
255 std::vector<T>& output() {
256 PP_DCHECK(output_storage_.empty());
258 ConvertPPResourceArrayToObjects(PASS_REF, temp_storage_, &output_storage_);
259 temp_storage_.clear();
260 return output_storage_;
263 private:
264 // The browser will write the PP_Resources into this array.
265 std::vector<PP_Resource> temp_storage_;
267 // When asked for the output, the resources above will be converted to the
268 // C++ resource objects in this array for passing to the calling code.
269 std::vector<T> output_storage_;
272 class DirectoryEntryArrayOutputAdapterWithStorage
273 : public ArrayOutputAdapter<PP_DirectoryEntry_Dev> {
274 public:
275 DirectoryEntryArrayOutputAdapterWithStorage() {
276 set_output(&temp_storage_);
279 virtual ~DirectoryEntryArrayOutputAdapterWithStorage() {
280 if (!temp_storage_.empty()) {
281 // An easy way to release the resource references held by |temp_storage_|.
282 // A destructor for PP_DirectoryEntry_Dev will release them.
283 output();
287 // Returns the final array of resource objects, converting the
288 // PP_DirectoryEntry_Dev written by the browser to pp::DirectoryEntry_Dev
289 // objects.
291 // This function should only be called once or we would end up converting
292 // the array more than once, which would mess up the refcounting.
293 std::vector<pp::DirectoryEntry_Dev>& output() {
294 PP_DCHECK(output_storage_.empty());
295 typedef std::vector<PP_DirectoryEntry_Dev> Entries;
296 for (Entries::iterator it = temp_storage_.begin();
297 it != temp_storage_.end(); ++it)
298 output_storage_.push_back(DirectoryEntry_Dev(PASS_REF, *it));
299 temp_storage_.clear();
300 return output_storage_;
303 private:
304 // The browser will write the PP_DirectoryEntry_Devs into this array.
305 std::vector<PP_DirectoryEntry_Dev> temp_storage_;
307 // When asked for the output, the PP_DirectoryEntry_Devs above will be
308 // converted to the pp::DirectoryEntry_Devs in this array for passing to the
309 // calling code.
310 std::vector<pp::DirectoryEntry_Dev> output_storage_;
313 } // namespace pp
315 #endif // PPAPI_CPP_ARRAY_OUTPUT_H_