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