diff options
Diffstat (limited to 'chromium/ppapi/proxy/proxy_array_output.h')
-rw-r--r-- | chromium/ppapi/proxy/proxy_array_output.h | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/chromium/ppapi/proxy/proxy_array_output.h b/chromium/ppapi/proxy/proxy_array_output.h new file mode 100644 index 00000000000..6d15e0b8358 --- /dev/null +++ b/chromium/ppapi/proxy/proxy_array_output.h @@ -0,0 +1,138 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// 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 <vector> + +#include "base/logging.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_ |