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_CPP_ARRAY_OUTPUT_H_ 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PPAPI_CPP_ARRAY_OUTPUT_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_array_output.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_resource.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/logging.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/pass_ref.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/var.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace pp { 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Converts the given array of PP_Resources into an array of the requested 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// C++ resource types, passing ownership of a reference in the process. 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is used to convert output arrays of resources that the browser has 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// generated into the more convenient C++ wrappers for those resources. The 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// initial "PassRef" parameter is there to emphasize what happens to the 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// reference count of the input resource and to match the resource constructors 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that look the same. 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename ResourceObjectType> 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline void ConvertPPResourceArrayToObjects( 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PassRef, 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<PP_Resource>& input, 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<ResourceObjectType>* output) { 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output->resize(0); 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output->reserve(input.size()); 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < input.size(); i++) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output->push_back(ResourceObjectType(PASS_REF, input[i])); 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Non-templatized base class for the array output conversion. It provides the 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// C implementation of a PP_ArrayOutput whose callback function is implemented 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// as a virtual call on a derived class. Do not use directly, use one of the 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// derived classes below. 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ArrayOutputAdapterBase { 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayOutputAdapterBase() { 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp_array_output_.GetDataBuffer = 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &ArrayOutputAdapterBase::GetDataBufferThunk; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp_array_output_.user_data = this; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~ArrayOutputAdapterBase() {} 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PP_ArrayOutput& pp_array_output() { return pp_array_output_; } 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void* GetDataBuffer(uint32_t element_count, 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t element_size) = 0; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void* GetDataBufferThunk(void* user_data, 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t element_count, 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t element_size); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_ArrayOutput pp_array_output_; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Disallow copying and assignment. This will do the wrong thing for most 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // subclasses. 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayOutputAdapterBase(const ArrayOutputAdapterBase&); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayOutputAdapterBase& operator=(const ArrayOutputAdapterBase&); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This adapter provides functionality for implementing a PP_ArrayOutput 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// structure as writing to a given vector object. 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is generally used internally in the C++ wrapper objects to 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// write into an output parameter supplied by the plugin. If the element size 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that the browser is writing does not match the size of the type we're using 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// this will assert and return NULL (which will cause the browser to fail the 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// call). 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Example that allows the browser to write into a given vector: 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// void DoFoo(std::vector<int>* results) { 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ArrayOutputAdapter<int> adapter(results); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ppb_foo->DoFoo(adapter.pp_array_output()); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// } 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename T> 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ArrayOutputAdapter : public ArrayOutputAdapterBase { 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayOutputAdapter(std::vector<T>* output) : output_(output) {} 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Two-step init for the "with storage" version below. 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayOutputAdapter() : output_(NULL) {} 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void set_output(std::vector<T>* output) { output_ = output; } 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ArrayOutputAdapterBase implementation. 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void* GetDataBuffer(uint32_t element_count, uint32_t element_size) { 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (element_count == 0) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_DCHECK(element_size == sizeof(T)); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (element_size != sizeof(T)) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_->resize(element_count); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return &(*output_)[0]; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<T>* output_; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This adapter provides functionality for implementing a PP_ArrayOutput 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// structure as writing resources to a given vector object. 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// When returning an array of resources, the browser will write PP_Resources 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// via a PP_ArrayOutput. This code will automatically convert the PP_Resources 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to the given wrapper type, (as long as that wrapper type supports the 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// correct constructor). The ownership of the resources that the browser passed 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to us will be transferred to the C++ wrapper object. 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Conversion of the PP_Resources to the C++ wrapper object occurs in the 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// destructor. This object is intended to be used on the stack in a C++ wrapper 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// object for a call. 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Example: 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// void GetFiles(std::vector<pp::FileRef>* results) { 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ResourceArrayOutputAdapter<pp::FileRef> adapter(results); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ppb_foo->DoFoo(adapter.pp_array_output()); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// } 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename T> 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ResourceArrayOutputAdapter : public ArrayOutputAdapterBase { 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit ResourceArrayOutputAdapter(std::vector<T>* output) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : output_(output) { 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_->resize(0); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~ResourceArrayOutputAdapter() { 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConvertPPResourceArrayToObjects(PASS_REF, intermediate_output_, output_); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Two-step init for the "with storage" version below. 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResourceArrayOutputAdapter() : output_(NULL) {} 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void set_output(T* output) { output_ = output; } 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ArrayOutputAdapterBase implementation. 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void* GetDataBuffer(uint32_t element_count, 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t element_size) { 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (element_count == 0) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_DCHECK(element_size == sizeof(PP_Resource)); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (element_size != sizeof(PP_Resource)) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) intermediate_output_.resize(element_count); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return &intermediate_output_[0]; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<PP_Resource> intermediate_output_; 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<T>* output_; 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This adapter is like the ArrayOutputAdapter except that it also contains 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the underlying std::vector that will be populated (rather than writing it to 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// an object passed into the constructor). 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is used by the CompletionCallbackFactory system to collect the output 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// parameters from an async function call. The collected data is then passed to 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the plugins callback function. 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// You can also use it directly if you want to have an array output and aren't 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// using the CompletionCallbackFactory. For example, if you're calling a 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// PPAPI function DoFoo that takes a PP_OutputArray that is supposed to be 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// writing integers, do this: 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ArrayOutputAdapterWithStorage<int> adapter; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ppb_foo->DoFoo(adapter.pp_output_array()); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// const std::vector<int>& result = adapter.output(); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename T> 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ArrayOutputAdapterWithStorage : public ArrayOutputAdapter<T> { 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayOutputAdapterWithStorage() { 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this->set_output(&output_storage_); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<T>& output() { return output_storage_; } 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<T> output_storage_; 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This adapter is like the ArrayOutputAdapterWithStorage except this 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// additionally converts PP_Var structs to pp::Var objects. 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// You can also use it directly if you want to have an array output and aren't 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// using the CompletionCallbackFactory. For example, if you're calling a 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// PPAPI function GetVars that takes a PP_OutputArray that is supposed to be 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// writing PP_Vars, do this: 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// VarArrayOutputAdapterWithStorage adapter; 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ppb_foo->GetVars(adapter.pp_output_array()); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// const std::vector<pp::Var>& result = adapter.output(). 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This one is non-inline since it's not templatized. 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class VarArrayOutputAdapterWithStorage : public ArrayOutputAdapter<PP_Var> { 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VarArrayOutputAdapterWithStorage(); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~VarArrayOutputAdapterWithStorage(); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the final array of resource objects, converting the PP_Vars 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // written by the browser to pp::Var objects. 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This function should only be called once or we would end up converting 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the array more than once, which would mess up the refcounting. 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<Var>& output(); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The browser will write the PP_Vars into this array. 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<PP_Var> temp_storage_; 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When asked for the output, the resources above will be converted to the 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // C++ resource objects in this array for passing to the calling code. 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<Var> output_storage_; 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This adapter is like the ArrayOutputAdapterWithStorage except this 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// additionally converts PP_Resources to C++ wrapper objects of the given type. 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// You can also use it directly if you want to have an array output and aren't 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// using the CompletionCallbackFactory. For example, if you're calling a 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// PPAPI function GetFiles that takes a PP_OutputArray that is supposed to be 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// writing PP_Resources cooresponding to FileRefs, do this: 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ResourceArrayOutputAdapterWithStorage<FileRef> adapter; 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ppb_foo->GetFiles(adapter.pp_output_array()); 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// std::vector<FileRef> result = adapter.output(). 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename T> 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ResourceArrayOutputAdapterWithStorage 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : public ArrayOutputAdapter<PP_Resource> { 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResourceArrayOutputAdapterWithStorage() { 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set_output(&temp_storage_); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~ResourceArrayOutputAdapterWithStorage() { 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!temp_storage_.empty()) { 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // An easy way to release the resource references held by this object. 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output(); 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the final array of resource objects, converting the PP_Resources 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // written by the browser to resource objects. 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This function should only be called once or we would end up converting 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the array more than once, which would mess up the refcounting. 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<T>& output() { 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_DCHECK(output_storage_.empty()); 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConvertPPResourceArrayToObjects(PASS_REF, temp_storage_, &output_storage_); 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) temp_storage_.clear(); 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return output_storage_; 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The browser will write the PP_Resources into this array. 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<PP_Resource> temp_storage_; 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When asked for the output, the resources above will be converted to the 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // C++ resource objects in this array for passing to the calling code. 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<T> output_storage_; 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace pp 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // PPAPI_CPP_ARRAY_OUTPUT_H_ 273