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_OUTPUT_TRAITS_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PPAPI_CPP_OUTPUT_TRAITS_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <vector>
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_resource.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/array_output.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/cpp/resource.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// @file
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// This file defines internal templates for defining how data is passed to the
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// browser via output parameters and how to convert that data to the
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// corresponding C++ object types.
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// It is used by the callback system, it should not be necessary for end-users
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// to use these templates directly.
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct PP_Var;
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace pp {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Var;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace internal {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This goop is a trick used to implement a template that can be used to
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// determine if a given class is the base class of another given class. It is
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// used in the resource object partial specialization below.
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename, typename> struct IsSame {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool const value = false;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename A> struct IsSame<A, A> {
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool const value = true;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename Base, typename Derived> struct IsBaseOf {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This class doesn't work correctly with forward declarations.
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Because sizeof cannot be applied to incomplete types, this line prevents us
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // from passing in forward declarations.
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef char (*EnsureTypesAreComplete)[sizeof(Base) + sizeof(Derived)];
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static Derived* CreateDerived();
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static char (&Check(Base*))[1];
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static char (&Check(...))[2];
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool const value = sizeof Check(CreateDerived()) == 1 &&
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            !IsSame<Base const, void const>::value;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Template to optionally derive from a given base class T if the given
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// predicate P is true.
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class T, bool P> struct InheritIf {};
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class T> struct InheritIf<T, true> : public T {};
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Single output parameters ----------------------------------------------------
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Output traits for all "plain old data" (POD) types. It is implemented to
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// pass a pointer to the browser as an output parameter.
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is used as a base class for the general CallbackOutputTraits below in
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the case where T is not a resource.
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename T>
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct GenericCallbackOutputTraits {
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The type passed to the PPAPI C API for this parameter. For normal out
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // params, we pass a pointer to the object so the browser can write into it.
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef T* APIArgType;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The type used to store the value. This is used internally in asynchronous
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // callbacks by the CompletionCallbackFactory to have the browser write into
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a temporary value associated with the callback, which is passed to the
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // plugin code when the callback is issued.
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef T StorageType;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Converts a "storage type" to a value that can be passed to the browser as
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // an output parameter. This just takes the address to convert the value to
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a pointer.
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static inline APIArgType StorageToAPIArg(StorageType& t) { return &t; }
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Converts the "storage type" to the value we pass to the plugin for
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // callbacks. This doesn't actually need to do anything in this case,
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // it's needed for some of more complex template specializations below.
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static inline T& StorageToPluginArg(StorageType& t) { return t; }
887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Initializes the "storage type" to a default value, if necessary. Here,
907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // we do nothing, assuming that the default constructor for T suffices.
917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  static inline void Initialize(StorageType* /* t */) {}
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Output traits for all resource types. It is implemented to pass a
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// PP_Resource* as an output parameter to the browser, and convert to the
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// given resource object type T when passing to the plugin.
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Note that this class is parameterized by the resource object, for example
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ResourceCallbackOutputTraits<pp::FileRef>. This is used as a base class for
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// CallbackOutputTraits below for the case where T is a derived class of
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// pp::Resource.
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename T>
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ResourceCallbackOutputTraits {
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // To call the browser, we just pass a PP_Resource pointer as the out param.
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef PP_Resource* APIArgType;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef PP_Resource StorageType;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static inline APIArgType StorageToAPIArg(StorageType& t) {
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return &t;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Converts the PP_Resource to a pp::* object, passing any reference counted
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // object along with it. This must only be called once since there will only
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be one reference that the browser has assigned to us for the out param!
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // When calling into the plugin, convert the PP_Resource into the requested
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // resource object type.
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static inline T StorageToPluginArg(StorageType& t) {
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return T(PASS_REF, t);
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  static inline void Initialize(StorageType* t) {
1227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    *t = 0;
1237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The general templatized base class for all CallbackOutputTraits. This class
127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// covers both resources and POD (ints, structs, etc.) by inheriting from the
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// appropriate base class depending on whether the given type derives from
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// pp::Resource. This trick allows us to do this once rather than writing
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// specializations for every resource object type.
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename T>
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct CallbackOutputTraits
133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : public InheritIf<GenericCallbackOutputTraits<T>,
134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       !IsBaseOf<Resource, T>::value>,
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      public InheritIf<ResourceCallbackOutputTraits<T>,
136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       IsBaseOf<Resource, T>::value> {
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A specialization of CallbackOutputTraits for pp::Var output parameters.
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// It passes a PP_Var* to the browser and converts to a pp::Var when passing
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to the plugin.
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<>
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct CallbackOutputTraits<Var> {
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // To call the browser, we just pass a PP_Var* as an output param.
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef PP_Var* APIArgType;
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef PP_Var StorageType;
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static inline APIArgType StorageToAPIArg(StorageType& t) {
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return &t;
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Converts the PP_Var to a pp::Var object, passing any reference counted
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // object along with it. This must only be called once since there will only
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be one reference that the browser has assigned to us for the out param!
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static inline pp::Var StorageToPluginArg(StorageType& t) {
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return Var(PASS_REF, t);
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  static inline void Initialize(StorageType* t) {
1607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    *t = PP_MakeUndefined();
1617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
164d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// A specialization of CallbackOutputTraits for bool output parameters.
165d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// It passes a PP_Bool* to the browser and converts to a bool when passing
166d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// to the plugin.
167d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)template<>
168d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)struct CallbackOutputTraits<bool> {
169d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // To call the browser, we just pass a PP_Bool* as an output param.
170d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  typedef PP_Bool* APIArgType;
171d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  typedef PP_Bool StorageType;
172d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
173d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  static inline APIArgType StorageToAPIArg(StorageType& t) {
174d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return &t;
175d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
176d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
177d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Converts the PP_Bool to a bool object.
178d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  static inline bool StorageToPluginArg(StorageType& t) {
179d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return PP_ToBool(t);
180d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
181d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
182d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  static inline void Initialize(StorageType* t) {
183d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    *t = PP_FALSE;
184d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
185d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)};
186d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Array output parameters -----------------------------------------------------
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Output traits for vectors of all "plain old data" (POD) types. It is
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// implemented to pass a pointer to the browser as an output parameter.
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is used as a base class for the general vector CallbackOutputTraits
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// below in the case where T is not a resource.
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename T>
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct GenericVectorCallbackOutputTraits {
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // All arrays are output via a PP_ArrayOutput type.
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef PP_ArrayOutput APIArgType;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We store the array as this adapter which combines the PP_ArrayOutput
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // structure with the underlying std::vector that it will write into.
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef ArrayOutputAdapterWithStorage<T> StorageType;
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Retrieves the PP_ArrayOutput interface for our vector object that the
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // browser will use to write into our code.
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static inline APIArgType StorageToAPIArg(StorageType& t) {
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return t.pp_array_output();
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Retrieves the underlying vector that can be passed to the plugin.
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static inline std::vector<T>& StorageToPluginArg(StorageType& t) {
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return t.output();
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  static inline void Initialize(StorageType* /* t */) {}
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Output traits for all vectors of resource types. It is implemented to pass
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a PP_ArrayOutput parameter to the browser, and convert the returned resources
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to a vector of the given resource object type T when passing to the plugin.
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Note that this class is parameterized by the resource object, for example
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ResourceVectorCallbackOutputTraits<pp::FileRef>. This is used as a base
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// class for CallbackOutputTraits below for the case where T is a derived
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// class of pp::Resource.
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename T>
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ResourceVectorCallbackOutputTraits {
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef PP_ArrayOutput APIArgType;
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef ResourceArrayOutputAdapterWithStorage<T> StorageType;
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static inline APIArgType StorageToAPIArg(StorageType& t) {
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return t.pp_array_output();
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static inline std::vector<T>& StorageToPluginArg(StorageType& t) {
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return t.output();
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  static inline void Initialize(StorageType* /* t */) {}
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Specialization of CallbackOutputTraits for vectors. This struct covers both
241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// arrays of resources and arrays of POD (ints, structs, etc.) by inheriting
242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// from the appropriate base class depending on whether the given type derives
243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// from pp::Resource. This trick allows us to do this once rather than writing
244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// specializations for every resource object type.
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename T>
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct CallbackOutputTraits< std::vector<T> >
247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : public InheritIf<GenericVectorCallbackOutputTraits<T>,
248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       !IsBaseOf<Resource, T>::value>,
249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      public InheritIf<ResourceVectorCallbackOutputTraits<T>,
250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       IsBaseOf<Resource, T>::value> {
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A specialization of CallbackOutputTraits to provide the callback system
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the information on how to handle vectors of pp::Var. Vectors of resources
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and plain data are handled separately. See the above definition for more.
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<>
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct CallbackOutputTraits< std::vector<pp::Var> > {
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // All arrays are output via a PP_ArrayOutput type.
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef PP_ArrayOutput APIArgType;
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We store the array as this adapter which combines the PP_ArrayOutput
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // structure with the underlying std::vector that it will write into.
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef VarArrayOutputAdapterWithStorage StorageType;
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Retrieves the PP_ArrayOutput interface for our vector object that the
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // browser will use to write into our code.
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static inline APIArgType StorageToAPIArg(StorageType& t) {
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return t.pp_array_output();
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Retrieves the underlying vector that can be passed to the plugin.
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static inline std::vector<pp::Var>& StorageToPluginArg(StorageType& t) {
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return t.output();
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  static inline void Initialize(StorageType* /* t */) {}
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace internal
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace pp
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // PPAPI_CPP_OUTPUT_TRAITS_H_
283