root/ppapi/cpp/extensions/ext_output_traits.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


// Copyright (c) 2013 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_CPP_EXTENSIONS_OUTPUT_TRAITS_H_
#define PPAPI_CPP_EXTENSIONS_OUTPUT_TRAITS_H_

#include <vector>

#include "ppapi/c/pp_var.h"
#include "ppapi/cpp/extensions/from_var_converter.h"
#include "ppapi/cpp/logging.h"
#include "ppapi/cpp/pass_ref.h"
#include "ppapi/cpp/var.h"
#include "ppapi/cpp/var_array.h"

namespace pp {
namespace ext {
namespace internal {

template <class T>
class VarOutputAdapterWithStorage {
 public:
  VarOutputAdapterWithStorage() : pp_var_(PP_MakeUndefined()) {
  }

  ~VarOutputAdapterWithStorage() {
    PP_DCHECK(pp_var_.type == PP_VARTYPE_UNDEFINED);
  }

  PP_Var& pp_var() { return pp_var_; }

  T& output() {
    Var auto_release(PASS_REF, pp_var_);
    converter_.Set(pp_var_);
    pp_var_ = PP_MakeUndefined();
    return converter_.value();
  }

 private:
  PP_Var pp_var_;
  FromVarConverter<T> converter_;

  // Disallow copying and assignment.
  VarOutputAdapterWithStorage(const VarOutputAdapterWithStorage<T>&);
  VarOutputAdapterWithStorage<T>& operator=(
      const VarOutputAdapterWithStorage<T>&);
};

// ExtCallbackOutputTraits is used with ExtCompletionCallbackWithOutput. Unlike
// pp::internal::CallbackOutputTraits, it always uses PP_Var* as output
// parameter type to interact with the browser.
//
// For example, CompletionCallbackWithOutput<double> (using
// pp::internal::CallbackOutputTraits) uses double* as the output parameter
// type; while ExtCompletionCallbackWithOutput<double> uses PP_Var*.
template <class T>
struct ExtCallbackOutputTraits {
  typedef PP_Var* APIArgType;
  typedef VarOutputAdapterWithStorage<T> StorageType;

  static inline APIArgType StorageToAPIArg(StorageType& t) {
    return &t.pp_var();
  }

  // This must be called exactly once to consume the one PP_Var reference
  // assigned to us by the browser.
  static inline T& StorageToPluginArg(StorageType& t) {
    return t.output();
  }

  static inline void Initialize(StorageType* /* t */) {}
};

// This class provides storage for a PP_Var and a vector of objects which are
// of type T. The PP_Var is used as an output parameter to receive an array var
// from the browser. Each element in the array var is converted to a T object,
// using FromVarConverter, and stores in the vector.
template <class T>
class ArrayVarOutputAdapterWithStorage {
 public:
  ArrayVarOutputAdapterWithStorage() : pp_var_(PP_MakeUndefined()) {
  }

  ~ArrayVarOutputAdapterWithStorage() {
    PP_DCHECK(pp_var_.type == PP_VARTYPE_UNDEFINED);
  }

  PP_Var& pp_var() { return pp_var_; }

  std::vector<T>& output() {
    PP_DCHECK(output_storage_.empty());

    Var var(PASS_REF, pp_var_);
    pp_var_ = PP_MakeUndefined();
    if (var.is_array()) {
      VarArray array(var);

      uint32_t length = array.GetLength();
      output_storage_.reserve(length);
      for (uint32_t i = 0; i < length; ++i) {
        FromVarConverter<T> converter(array.Get(i).pp_var());
        output_storage_.push_back(converter.value());
      }
    }

    return output_storage_;
  }

 private:
  PP_Var pp_var_;
  std::vector<T> output_storage_;

  // Disallow copying and assignment.
  ArrayVarOutputAdapterWithStorage(const ArrayVarOutputAdapterWithStorage<T>&);
  ArrayVarOutputAdapterWithStorage<T>& operator=(
      const ArrayVarOutputAdapterWithStorage<T>&);
};

template <class T>
struct ExtCallbackOutputTraits< std::vector<T> > {
  typedef PP_Var* APIArgType;
  typedef ArrayVarOutputAdapterWithStorage<T> StorageType;

  static inline APIArgType StorageToAPIArg(StorageType& t) {
    return &t.pp_var();
  }

  // This must be called exactly once to consume the one PP_Var reference
  // assigned to us by the browser.
  static inline std::vector<T>& StorageToPluginArg(StorageType& t) {
    return t.output();
  }

  static inline void Initialize(StorageType* /* t */) {}
};

}  // namespace internal
}  // namespace ext
}  // namespace pp

#endif  // PPAPI_CPP_EXTENSIONS_OUTPUT_TRAITS_H_

/* [<][>][^][v][top][bottom][index][help] */