proxy_array_output.h revision 5821806d5e7f356e8fa4b058a389a808ea183019
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//   ...
35namespace ppapi {
36namespace 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.
42class ArrayOutputAdapterBase {
43 public:
44  ArrayOutputAdapterBase() {
45    pp_array_output_.GetDataBuffer =
46        &ArrayOutputAdapterBase::GetDataBufferThunk;
47    pp_array_output_.user_data = this;
48  }
49  virtual ~ArrayOutputAdapterBase() {}
50
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//   }
84template<typename T>
85class ArrayOutputAdapter : public ArrayOutputAdapterBase {
86 public:
87  ArrayOutputAdapter(std::vector<T>* output) : output_(output) {}
88
89 protected:
90  // Two-step init for the "with storage" version below.
91  ArrayOutputAdapter() : output_(NULL) {}
92  void set_output(std::vector<T>* output) { output_ = output; }
93
94  // ArrayOutputAdapterBase implementation.
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
107template<typename T>
108class ArrayOutputAdapterWithStorage : public ArrayOutputAdapter<T> {
109 public:
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
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.
125template<typename T>
126class RefCountedArrayOutputAdapter
127    : public ArrayOutputAdapterWithStorage<T>,
128      public base::RefCounted<RefCountedArrayOutputAdapter<T> > {
129 public:
130  RefCountedArrayOutputAdapter()
131      : ArrayOutputAdapterWithStorage<T>() {
132  }
133};
134
135}  // namespace proxy
136}  // namespace ppapi
137
138#endif  // PPAPI_PROXY_PROXY_ARRAY_OUTPUT_H_
139