// 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_CPP_ARRAY_OUTPUT_H_
#define PPAPI_CPP_ARRAY_OUTPUT_H_

#include <vector>

#include "ppapi/c/pp_array_output.h"
#include "ppapi/c/pp_resource.h"
#include "ppapi/cpp/logging.h"
#include "ppapi/cpp/pass_ref.h"
#include "ppapi/cpp/var.h"

namespace pp {

// Converts the given array of PP_Resources into an array of the requested
// C++ resource types, passing ownership of a reference in the process.
//
// This is used to convert output arrays of resources that the browser has
// generated into the more convenient C++ wrappers for those resources. The
// initial "PassRef" parameter is there to emphasize what happens to the
// reference count of the input resource and to match the resource constructors
// that look the same.
template<typename ResourceObjectType>
inline void ConvertPPResourceArrayToObjects(
    PassRef,
    const std::vector<PP_Resource>& input,
    std::vector<ResourceObjectType>* output) {
  output->resize(0);
  output->reserve(input.size());
  for (size_t i = 0; i < input.size(); i++)
    output->push_back(ResourceObjectType(PASS_REF, input[i]));
}

// 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) {
    if (element_count == 0)
      return NULL;
    PP_DCHECK(element_size == sizeof(T));
    if (element_size != sizeof(T))
      return NULL;
    output_->resize(element_count);
    return &(*output_)[0];
  }

 private:
  std::vector<T>* output_;
};

// This adapter provides functionality for implementing a PP_ArrayOutput
// structure as writing resources to a given vector object.
//
// When returning an array of resources, the browser will write PP_Resources
// via a PP_ArrayOutput. This code will automatically convert the PP_Resources
// to the given wrapper type, (as long as that wrapper type supports the
// correct constructor). The ownership of the resources that the browser passed
// to us will be transferred to the C++ wrapper object.
//
// Conversion of the PP_Resources to the C++ wrapper object occurs in the
// destructor. This object is intended to be used on the stack in a C++ wrapper
// object for a call.
//
// Example:
//   void GetFiles(std::vector<pp::FileRef>* results) {
//     ResourceArrayOutputAdapter<pp::FileRef> adapter(results);
//     ppb_foo->DoFoo(adapter.pp_array_output());
//   }
template<typename T>
class ResourceArrayOutputAdapter : public ArrayOutputAdapterBase {
 public:
  explicit ResourceArrayOutputAdapter(std::vector<T>* output)
      : output_(output) {
    output_->resize(0);
  }
  virtual ~ResourceArrayOutputAdapter() {
    ConvertPPResourceArrayToObjects(PASS_REF, intermediate_output_, output_);
  }

 protected:
  // Two-step init for the "with storage" version below.
  ResourceArrayOutputAdapter() : output_(NULL) {}
  void set_output(T* output) { output_ = output; }

  // ArrayOutputAdapterBase implementation.
  virtual void* GetDataBuffer(uint32_t element_count,
                              uint32_t element_size) {
    if (element_count == 0)
      return NULL;
    PP_DCHECK(element_size == sizeof(PP_Resource));
    if (element_size != sizeof(PP_Resource))
      return NULL;
    intermediate_output_.resize(element_count);
    return &intermediate_output_[0];
  }

 private:
  std::vector<PP_Resource> intermediate_output_;
  std::vector<T>* output_;
};

// This adapter is like the ArrayOutputAdapter except that it also contains
// the underlying std::vector that will be populated (rather than writing it to
// an object passed into the constructor).
//
// This is used by the CompletionCallbackFactory system to collect the output
// parameters from an async function call. The collected data is then passed to
// the plugins callback function.
//
// You can also use it directly if you want to have an array output and aren't
// using the CompletionCallbackFactory. For example, if you're calling a
// PPAPI function DoFoo that takes a PP_OutputArray that is supposed to be
// writing integers, do this:
//
//    ArrayOutputAdapterWithStorage<int> adapter;
//    ppb_foo->DoFoo(adapter.pp_output_array());
//    const std::vector<int>& result = adapter.output();
template<typename T>
class ArrayOutputAdapterWithStorage : public ArrayOutputAdapter<T> {
 public:
  ArrayOutputAdapterWithStorage() {
    this->set_output(&output_storage_);
  }

  std::vector<T>& output() { return output_storage_; }

 private:
  std::vector<T> output_storage_;
};

// This adapter is like the ArrayOutputAdapterWithStorage except this
// additionally converts PP_Var structs to pp::Var objects.
//
// You can also use it directly if you want to have an array output and aren't
// using the CompletionCallbackFactory. For example, if you're calling a
// PPAPI function GetVars that takes a PP_OutputArray that is supposed to be
// writing PP_Vars, do this:
//
//    VarArrayOutputAdapterWithStorage adapter;
//    ppb_foo->GetVars(adapter.pp_output_array());
//    const std::vector<pp::Var>& result = adapter.output().
//
// This one is non-inline since it's not templatized.
class VarArrayOutputAdapterWithStorage : public ArrayOutputAdapter<PP_Var> {
 public:
  VarArrayOutputAdapterWithStorage();
  virtual ~VarArrayOutputAdapterWithStorage();

  // Returns the final array of resource objects, converting the PP_Vars
  // written by the browser to pp::Var objects.
  //
  // This function should only be called once or we would end up converting
  // the array more than once, which would mess up the refcounting.
  std::vector<Var>& output();

 private:
  // The browser will write the PP_Vars into this array.
  std::vector<PP_Var> temp_storage_;

  // When asked for the output, the resources above will be converted to the
  // C++ resource objects in this array for passing to the calling code.
  std::vector<Var> output_storage_;
};

// This adapter is like the ArrayOutputAdapterWithStorage except this
// additionally converts PP_Resources to C++ wrapper objects of the given type.
//
// You can also use it directly if you want to have an array output and aren't
// using the CompletionCallbackFactory. For example, if you're calling a
// PPAPI function GetFiles that takes a PP_OutputArray that is supposed to be
// writing PP_Resources cooresponding to FileRefs, do this:
//
//    ResourceArrayOutputAdapterWithStorage<FileRef> adapter;
//    ppb_foo->GetFiles(adapter.pp_output_array());
//    std::vector<FileRef> result = adapter.output().
template<typename T>
class ResourceArrayOutputAdapterWithStorage
    : public ArrayOutputAdapter<PP_Resource> {
 public:
  ResourceArrayOutputAdapterWithStorage() {
    set_output(&temp_storage_);
  }

  virtual ~ResourceArrayOutputAdapterWithStorage() {
    if (!temp_storage_.empty()) {
      // An easy way to release the resource references held by this object.
      output();
    }
  }

  // Returns the final array of resource objects, converting the PP_Resources
  // written by the browser to resource objects.
  //
  // This function should only be called once or we would end up converting
  // the array more than once, which would mess up the refcounting.
  std::vector<T>& output() {
    PP_DCHECK(output_storage_.empty());

    ConvertPPResourceArrayToObjects(PASS_REF, temp_storage_, &output_storage_);
    temp_storage_.clear();
    return output_storage_;
  }

 private:
  // The browser will write the PP_Resources into this array.
  std::vector<PP_Resource> temp_storage_;

  // When asked for the output, the resources above will be converted to the
  // C++ resource objects in this array for passing to the calling code.
  std::vector<T> output_storage_;
};

}  // namespace pp

#endif  // PPAPI_CPP_ARRAY_OUTPUT_H_
