• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_PROXY_PROXY_ARRAY_OUTPUT_H_
6 #define PPAPI_PROXY_PROXY_ARRAY_OUTPUT_H_
7 
8 #include <vector>
9 
10 #include "base/logging.h"
11 #include "base/memory/ref_counted.h"
12 #include "ppapi/c/pp_array_output.h"
13 
14 // Like ppapi/cpp/array_output.h file in the C++ wrappers but for use in the
15 // proxy where we can't link to the C++ wrappers. This also adds a refcounted
16 // version.
17 //
18 // Use ArrayOutputAdapter when calling a function that synchronously returns
19 // an array of data. Use RefCountedArrayOutputAdapterWithStorage for
20 // asynchronous returns:
21 //
22 // void OnCallbackComplete(
23 //     int32_t result,
24 //     scoped_refptr<RefCountedArrayOutputAdapter<PP_Resource> > output) {
25 //   // Vector is in output->output().
26 // }
27 //
28 // void ScheduleCallback() {
29 //   base::scoped_refptr<RefCountedArrayOutputAdapter<PP_Resource> > output;
30 //
31 //   callback = factory.NewOptionalCallback(&OnCallbackComplete, output);
32 //   DoSomethingAsynchronously(output->pp_array_output(),
33 //                             callback.pp_completion_callback());
34 //   ...
35 namespace ppapi {
36 namespace proxy {
37 
38 // Non-templatized base class for the array output conversion. It provides the
39 // C implementation of a PP_ArrayOutput whose callback function is implemented
40 // as a virtual call on a derived class. Do not use directly, use one of the
41 // derived classes below.
42 class ArrayOutputAdapterBase {
43  public:
ArrayOutputAdapterBase()44   ArrayOutputAdapterBase() {
45     pp_array_output_.GetDataBuffer =
46         &ArrayOutputAdapterBase::GetDataBufferThunk;
47     pp_array_output_.user_data = this;
48   }
~ArrayOutputAdapterBase()49   virtual ~ArrayOutputAdapterBase() {}
50 
pp_array_output()51   const PP_ArrayOutput& pp_array_output() { return pp_array_output_; }
52 
53  protected:
54   virtual void* GetDataBuffer(uint32_t element_count,
55                               uint32_t element_size) = 0;
56 
57  private:
58   static void* GetDataBufferThunk(void* user_data,
59                                   uint32_t element_count,
60                                   uint32_t element_size);
61 
62   PP_ArrayOutput pp_array_output_;
63 
64   // Disallow copying and assignment. This will do the wrong thing for most
65   // subclasses.
66   ArrayOutputAdapterBase(const ArrayOutputAdapterBase&);
67   ArrayOutputAdapterBase& operator=(const ArrayOutputAdapterBase&);
68 };
69 
70 // This adapter provides functionality for implementing a PP_ArrayOutput
71 // structure as writing to a given vector object.
72 //
73 // This is generally used internally in the C++ wrapper objects to
74 // write into an output parameter supplied by the plugin. If the element size
75 // that the browser is writing does not match the size of the type we're using
76 // this will assert and return NULL (which will cause the browser to fail the
77 // call).
78 //
79 // Example that allows the browser to write into a given vector:
80 //   void DoFoo(std::vector<int>* results) {
81 //     ArrayOutputAdapter<int> adapter(results);
82 //     ppb_foo->DoFoo(adapter.pp_array_output());
83 //   }
84 template<typename T>
85 class ArrayOutputAdapter : public ArrayOutputAdapterBase {
86  public:
ArrayOutputAdapter(std::vector<T> * output)87   ArrayOutputAdapter(std::vector<T>* output) : output_(output) {}
88 
89  protected:
90   // Two-step init for the "with storage" version below.
ArrayOutputAdapter()91   ArrayOutputAdapter() : output_(NULL) {}
set_output(std::vector<T> * output)92   void set_output(std::vector<T>* output) { output_ = output; }
93 
94   // ArrayOutputAdapterBase implementation.
GetDataBuffer(uint32_t element_count,uint32_t element_size)95   virtual void* GetDataBuffer(uint32_t element_count, uint32_t element_size) {
96     DCHECK(element_size == sizeof(T));
97     if (element_count == 0 || element_size != sizeof(T))
98       return NULL;
99     output_->resize(element_count);
100     return &(*output_)[0];
101   }
102 
103  private:
104   std::vector<T>* output_;
105 };
106 
107 template<typename T>
108 class ArrayOutputAdapterWithStorage : public ArrayOutputAdapter<T> {
109  public:
ArrayOutputAdapterWithStorage()110   ArrayOutputAdapterWithStorage() {
111     // Note: "this->" is required due to two-phase name lookup where it isn't
112     // allowed to look in the base class during parsing.
113     this->set_output(&output_storage_);
114   }
115 
output()116   std::vector<T>& output() { return output_storage_; }
117 
118  private:
119   std::vector<T> output_storage_;
120 };
121 
122 // A reference counted version of ArrayOutputAdapterWithStorage. Since it
123 // doesn't make much sense to heap-allocate one without storage, we don't
124 // call it "with storage" to keep the name length under control.
125 template<typename T>
126 class RefCountedArrayOutputAdapter
127     : public ArrayOutputAdapterWithStorage<T>,
128       public base::RefCounted<RefCountedArrayOutputAdapter<T> > {
129  public:
RefCountedArrayOutputAdapter()130   RefCountedArrayOutputAdapter()
131       : ArrayOutputAdapterWithStorage<T>() {
132   }
133 };
134 
135 }  // namespace proxy
136 }  // namespace ppapi
137 
138 #endif  // PPAPI_PROXY_PROXY_ARRAY_OUTPUT_H_
139