15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef PPAPI_PROXY_PROXY_ARRAY_OUTPUT_H_ 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PPAPI_PROXY_PROXY_ARRAY_OUTPUT_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_array_output.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Like ppapi/cpp/array_output.h file in the C++ wrappers but for use in the 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// proxy where we can't link to the C++ wrappers. This also adds a refcounted 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// version. 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use ArrayOutputAdapter when calling a function that synchronously returns 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// an array of data. Use RefCountedArrayOutputAdapterWithStorage for 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// asynchronous returns: 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// void OnCallbackComplete( 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// int32_t result, 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// scoped_refptr<RefCountedArrayOutputAdapter<PP_Resource> > output) { 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// // Vector is in output->output(). 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// } 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// void ScheduleCallback() { 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// base::scoped_refptr<RefCountedArrayOutputAdapter<PP_Resource> > output; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// callback = factory.NewOptionalCallback(&OnCallbackComplete, output); 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DoSomethingAsynchronously(output->pp_array_output(), 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// callback.pp_completion_callback()); 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ... 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ppapi { 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace proxy { 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Non-templatized base class for the array output conversion. It provides the 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// C implementation of a PP_ArrayOutput whose callback function is implemented 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// as a virtual call on a derived class. Do not use directly, use one of the 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// derived classes below. 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ArrayOutputAdapterBase { 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayOutputAdapterBase() { 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp_array_output_.GetDataBuffer = 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &ArrayOutputAdapterBase::GetDataBufferThunk; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp_array_output_.user_data = this; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~ArrayOutputAdapterBase() {} 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PP_ArrayOutput& pp_array_output() { return pp_array_output_; } 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void* GetDataBuffer(uint32_t element_count, 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t element_size) = 0; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void* GetDataBufferThunk(void* user_data, 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t element_count, 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t element_size); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_ArrayOutput pp_array_output_; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Disallow copying and assignment. This will do the wrong thing for most 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // subclasses. 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayOutputAdapterBase(const ArrayOutputAdapterBase&); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayOutputAdapterBase& operator=(const ArrayOutputAdapterBase&); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This adapter provides functionality for implementing a PP_ArrayOutput 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// structure as writing to a given vector object. 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is generally used internally in the C++ wrapper objects to 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// write into an output parameter supplied by the plugin. If the element size 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that the browser is writing does not match the size of the type we're using 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// this will assert and return NULL (which will cause the browser to fail the 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// call). 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Example that allows the browser to write into a given vector: 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// void DoFoo(std::vector<int>* results) { 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ArrayOutputAdapter<int> adapter(results); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ppb_foo->DoFoo(adapter.pp_array_output()); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// } 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename T> 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ArrayOutputAdapter : public ArrayOutputAdapterBase { 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayOutputAdapter(std::vector<T>* output) : output_(output) {} 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Two-step init for the "with storage" version below. 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayOutputAdapter() : output_(NULL) {} 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void set_output(std::vector<T>* output) { output_ = output; } 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ArrayOutputAdapterBase implementation. 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void* GetDataBuffer(uint32_t element_count, uint32_t element_size) { 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(element_size == sizeof(T)); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (element_count == 0 || element_size != sizeof(T)) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_->resize(element_count); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return &(*output_)[0]; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<T>* output_; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename T> 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ArrayOutputAdapterWithStorage : public ArrayOutputAdapter<T> { 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayOutputAdapterWithStorage() { 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note: "this->" is required due to two-phase name lookup where it isn't 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // allowed to look in the base class during parsing. 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this->set_output(&output_storage_); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<T>& output() { return output_storage_; } 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<T> output_storage_; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A reference counted version of ArrayOutputAdapterWithStorage. Since it 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// doesn't make much sense to heap-allocate one without storage, we don't 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// call it "with storage" to keep the name length under control. 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename T> 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class RefCountedArrayOutputAdapter 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : public ArrayOutputAdapterWithStorage<T>, 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public base::RefCounted<RefCountedArrayOutputAdapter<T> > { 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RefCountedArrayOutputAdapter() 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : ArrayOutputAdapterWithStorage<T>() { 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace proxy 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace ppapi 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // PPAPI_PROXY_PROXY_ARRAY_OUTPUT_H_ 139