// 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.

#include "ppapi/proxy/plugin_array_buffer_var.h"

#include <stdlib.h>

#include <limits>

#include "base/memory/shared_memory.h"
#include "ppapi/c/dev/ppb_buffer_dev.h"
#include "ppapi/proxy/plugin_dispatcher.h"
#include "ppapi/proxy/plugin_globals.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/proxy/serialized_structs.h"
#include "ppapi/shared_impl/host_resource.h"
#include "ppapi/shared_impl/resource.h"
#include "ppapi/thunk/enter.h"
#include "ppapi/thunk/ppb_buffer_api.h"

using base::SharedMemory;
using base::SharedMemoryHandle;
using ppapi::proxy::PluginGlobals;
using ppapi::proxy::PluginResourceTracker;

namespace ppapi {

PluginArrayBufferVar::PluginArrayBufferVar(uint32 size_in_bytes)
    : buffer_(size_in_bytes),
      plugin_handle_(base::SharedMemory::NULLHandle()),
      size_in_bytes_(size_in_bytes) {
}

PluginArrayBufferVar::PluginArrayBufferVar(uint32 size_in_bytes,
                                           SharedMemoryHandle plugin_handle)
    : plugin_handle_(plugin_handle),
      size_in_bytes_(size_in_bytes) {
}

PluginArrayBufferVar::~PluginArrayBufferVar() {
  Unmap();

  if (shmem_.get() == NULL) {
    // The SharedMemory destuctor can't close the handle for us.
    if (SharedMemory::IsHandleValid(plugin_handle_))
      SharedMemory::CloseHandle(plugin_handle_);
  } else {
    // Delete SharedMemory, if we have one.
    shmem_.reset();
  }
}

void* PluginArrayBufferVar::Map() {
  if (shmem_.get())
    return shmem_->memory();
  if (SharedMemory::IsHandleValid(plugin_handle_)) {
    shmem_.reset(new SharedMemory(plugin_handle_, false));
    if (!shmem_->Map(size_in_bytes_)) {
      shmem_.reset();
      return NULL;
    }
    return shmem_->memory();
  }
  if (buffer_.empty())
    return NULL;
  return &(buffer_[0]);
}

void PluginArrayBufferVar::Unmap() {
  if (shmem_.get())
    shmem_->Unmap();
}

uint32 PluginArrayBufferVar::ByteLength() {
  return size_in_bytes_;
}

bool PluginArrayBufferVar::CopyToNewShmem(
    PP_Instance instance,
    int* host_handle_id,
    SharedMemoryHandle* plugin_out_handle) {
  ppapi::proxy::PluginDispatcher* dispatcher =
      ppapi::proxy::PluginDispatcher::GetForInstance(instance);
  if (!dispatcher)
    return false;

  ppapi::proxy::SerializedHandle plugin_handle;
  dispatcher->Send(new PpapiHostMsg_SharedMemory_CreateSharedMemory(
      instance, ByteLength(), host_handle_id, &plugin_handle));
  if (!plugin_handle.IsHandleValid() || !plugin_handle.is_shmem() ||
      *host_handle_id == -1)
    return false;

  base::SharedMemoryHandle tmp_handle = plugin_handle.shmem();
  SharedMemory s(tmp_handle, false);
  if (!s.Map(ByteLength()))
    return false;
  memcpy(s.memory(), Map(), ByteLength());
  s.Unmap();

  // We don't need to keep the shared memory around on the plugin side;
  // we've already copied all our data into it. We'll make it invalid
  // just to be safe.
  *plugin_out_handle = base::SharedMemory::NULLHandle();

  return true;
}

}  // namespace ppapi
