// Copyright 2015 The Chromium OS 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 "libprotobinder/parcel.h"

#include <string.h>

#include "libprotobinder/binder_host.h"
#include "libprotobinder/binder_proxy.h"

#define PAD_SIZE(s) (((s) + 3) & ~3)

namespace protobinder {

Parcel::Parcel()
    : data_(nullptr),
      data_len_(0),
      data_capacity_(0),
      data_pos_(0),
      objects_(nullptr),
      objects_count_(0),
      objects_capacity_(0),
      owners_release_function_(nullptr) {
}

Parcel::~Parcel() {
  if (owners_release_function_) {
    owners_release_function_(this, data_, data_len_, objects_, objects_count_,
                             nullptr);
  } else {
    if (data_)
      free(data_);
    if (objects_)
      free(objects_);
  }
}

// ---- Public API ----

bool Parcel::WriteInt32(int32_t val) {
  return WriteAligned(val);
}

bool Parcel::WriteInt64(int64_t val) {
  return WriteAligned(val);
}

bool Parcel::WriteUInt32(uint32_t val) {
  return WriteAligned(val);
}

bool Parcel::WriteUInt64(uint64_t val) {
  return WriteAligned(val);
}

bool Parcel::WriteFloat(float val) {
  return WriteAligned(val);
}

bool Parcel::WriteDouble(double val) {
  return WriteAligned(val);
}

bool Parcel::WritePointer(uintptr_t val) {
  return WriteAligned<binder_uintptr_t>(val);
}

bool Parcel::ReadInt32(int32_t* val) {
  return ReadAligned(val);
}

bool Parcel::ReadInt64(int64_t* val) {
  return ReadAligned(val);
}

bool Parcel::ReadUInt32(uint32_t* val) {
  return ReadAligned(val);
}

bool Parcel::ReadUInt64(uint64_t* val) {
  return ReadAligned(val);
}

bool Parcel::ReadFloat(float* val) {
  return ReadAligned(val);
}

bool Parcel::ReadDouble(double* val) {
  return ReadAligned(val);
}

bool Parcel::ReadPointer(uintptr_t* val) {
  binder_uintptr_t pointer_val = 0;
  if (ReadAligned(&pointer_val)) {
    *val = pointer_val;
    return true;
  }
  return false;
}

bool Parcel::Write(const void* data, size_t len) {
  void* buf = AllocatePaddedBuffer(len);
  if (buf == nullptr)
    return false;
  memcpy(buf, data, len);
  return true;
}

bool Parcel::WriteString16(const uint16_t* str, size_t len) {
  // Only 32bit lengths are supported.
  if (static_cast<uint64_t>(len) >= 0x100000000)
    return false;
  size_t alloc_len = len * sizeof(uint16_t);
  if (alloc_len < len)
    return false;
  if (!WriteUInt32(len))
    return false;
  return Write(str, alloc_len);
}

bool Parcel::WriteString16(const std::string& str) {
  size_t len = str.size();
  // Only 32bit lengths are supported.
  if (static_cast<uint64_t>(len) >= 0x100000000)
    return false;
  // Android String16 Parcel code expects a NULL byte
  size_t alloc_len = (len + 1) * sizeof(uint16_t);
  if (alloc_len <= len)
    return false;
  if (!WriteUInt32(len))
    return false;
  uint16_t* buf = reinterpret_cast<uint16_t*>(AllocatePaddedBuffer(alloc_len));
  if (buf == nullptr)
    return false;
  for (size_t i = 0; i < len; i++)
    buf[i] = str[i];
  buf[len] = '\0';
  return true;
}

bool Parcel::WriteString(const std::string& str) {
  size_t len = str.size();
  // Only 32bit lengths are supported.
  if (static_cast<uint64_t>(len) >= 0x100000000)
    return false;
  if (!WriteUInt32(len))
    return false;
  // No need to store NULL
  return Write(str.c_str(), len);
}

bool Parcel::Read(void* data, size_t len) {
  if ((data_pos_ + PAD_SIZE(len)) >= data_pos_ &&
      (data_pos_ + PAD_SIZE(len)) <= data_len_ && len <= PAD_SIZE(len)) {
    memcpy(data, data_ + data_pos_, len);
    data_pos_ += PAD_SIZE(len);
    return true;
  }
  return false;
}

// TODO(leecam): Replace most of these nullptr checks with a DCHECK().
// http://brbug.com/599
bool Parcel::ReadString16(uint16_t* new_string, size_t* max_len) {
  if (new_string == nullptr || max_len == nullptr)
    return false;
  uint32_t len = 0;
  if (!ReadUInt32(&len))
    return false;
  if (len > *max_len)
    return false;
  size_t alloc_len = len * sizeof(uint16_t);
  if (alloc_len < len)
    return false;
  uint16_t* buf = reinterpret_cast<uint16_t*>(GetPaddedBuffer(alloc_len));
  if (buf == nullptr)
    return false;
  memcpy(new_string, buf, alloc_len);
  *max_len = len;
  return true;
}

bool Parcel::ReadString16(std::string* new_string) {
  if (new_string == nullptr)
    return false;
  uint32_t len = 0;
  if (!ReadUInt32(&len))
    return false;
  size_t alloc_len = (len + 1) * sizeof(uint16_t);
  if (alloc_len <= len)
    return false;
  uint16_t* buf = reinterpret_cast<uint16_t*>(GetPaddedBuffer(alloc_len));
  if (buf == nullptr)
    return false;
  new_string->clear();
  for (size_t i = 0; i < len; i++)
    new_string->push_back(buf[i]);
  return true;
}

bool Parcel::ReadString(std::string* new_string) {
  if (new_string == nullptr)
    return false;
  uint32_t len = 0;
  if (!ReadUInt32(&len))
    return false;
  char* buf = reinterpret_cast<char*>(GetPaddedBuffer(len));
  if (buf == nullptr)
    return false;
  new_string->clear();
  new_string->insert(0, buf, len);
  return true;
}

bool Parcel::WriteStrongBinder(const IBinder* binder) {
  flat_binder_object object;
  object.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
  if (binder != nullptr) {
    const IBinder* host = binder->GetBinderHost();
    if (host) {
      object.type = BINDER_TYPE_BINDER;
      object.binder = reinterpret_cast<uintptr_t>(host);
      object.cookie = reinterpret_cast<uintptr_t>(host);
    } else {
      object.type = BINDER_TYPE_HANDLE;
      object.binder = 0;
      object.cookie = 0;
      const BinderProxy* proxy = binder->GetBinderProxy();
      if (proxy == nullptr) {
        object.handle = 0;
      } else {
        object.handle = proxy->handle();
      }
    }
  } else {
    object.type = BINDER_TYPE_BINDER;
    object.binder = 0;
    object.cookie = 0;
  }
  return WriteObject(object);
}

bool Parcel::WriteFd(int fd) {
  struct flat_binder_object object;
  object.type = BINDER_TYPE_FD;
  object.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
  object.handle = fd;
  object.cookie = 0;
  return WriteObject(object);
}

bool Parcel::WriteRawHandle(uint32_t handle) {
  struct flat_binder_object object;
  object.type = BINDER_TYPE_HANDLE;
  object.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
  object.handle = handle;
  object.cookie = 0;
  return WriteObject(object);
}

bool Parcel::WriteRawBinder(const void* binder) {
  struct flat_binder_object object;
  object.type = BINDER_TYPE_BINDER;
  object.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
  object.binder = (binder_uintptr_t)binder;
  object.cookie = 0;
  return WriteObject(object);
}

bool Parcel::ReadStrongBinder(IBinder** binder) {
  if (binder == nullptr)
    return false;
  const flat_binder_object* flat_object = ReadObject();
  if (flat_object == nullptr)
    return false;

  switch (flat_object->type) {
    case BINDER_TYPE_BINDER:
      // TODO(leecam): Support this and return flat->cookie
      return false;
    case BINDER_TYPE_HANDLE:
      *binder = new BinderProxy(flat_object->handle);
      return true;
  }
  return false;
}

bool Parcel::ReadFd(int* fd) {
  if (fd == nullptr)
    return false;
  const flat_binder_object* flat_object = ReadObject();
  if (flat_object == nullptr)
    return false;
  if (flat_object->type != BINDER_TYPE_FD)
    return false;
  *fd = flat_object->handle;
  return true;
}

bool Parcel::ReadRawBinder(void** binder) {
  if (binder == nullptr)
    return false;
  const flat_binder_object* flat_object = ReadObject();
  if (flat_object == nullptr)
    return false;
  if (flat_object->type != BINDER_TYPE_BINDER)
    return false;
  *binder = reinterpret_cast<void*>(flat_object->binder);
  return true;
}

bool Parcel::ReadRawHandle(uint32_t* handle) {
  if (handle == nullptr)
    return false;
  const flat_binder_object* flat_object = ReadObject();
  if (flat_object == nullptr)
    return false;
  if (flat_object->type != BINDER_TYPE_HANDLE)
    return false;
  *handle = flat_object->handle;
  return true;
}

bool Parcel::WriteParcel(Parcel* parcel) {
  if (parcel == nullptr)
    return false;
  size_t required_object_count = objects_count_ + parcel->ObjectCount();
  if (required_object_count < objects_count_)
    return false;
  if (required_object_count >= objects_capacity_) {
    size_t new_capacity = required_object_count + 16;
    if (new_capacity < required_object_count)
      return false;
    binder_size_t* new_objects = reinterpret_cast<binder_size_t*>(
        realloc(objects_, new_capacity * sizeof(binder_size_t)));
    if (new_objects == nullptr)
      return false;
    objects_ = new_objects;
    objects_capacity_ = new_capacity;
  }
  size_t base = data_pos_;

  if (!Write(parcel->Data(), parcel->Len()))
    return false;

  for (size_t i = 0; i < parcel->ObjectCount(); i++) {
    objects_[objects_count_] = base + parcel->ObjectData()[i];
    objects_count_++;
  }
  return true;
}

bool Parcel::GetFdAtOffset(int* fd, size_t offset) {
  if (fd == nullptr)
    return false;
  const flat_binder_object* flat_object = GetObjectAtOffset(offset);
  if (flat_object == nullptr)
    return false;
  if (flat_object->type != BINDER_TYPE_FD)
    return false;
  *fd = flat_object->handle;
  return true;
}

bool Parcel::GetStrongBinderAtOffset(IBinder** binder, size_t offset) {
  if (binder == NULL)
    return false;
  const flat_binder_object* flat_object = GetObjectAtOffset(offset);
  if (flat_object == NULL)
    return false;

  switch (flat_object->type) {
    case BINDER_TYPE_BINDER:
      // TODO(leecam): Support this and return flat->cookie
      return false;
    case BINDER_TYPE_HANDLE:
      *binder = new BinderProxy(flat_object->handle);
      return true;
  }
  return false;
}

bool Parcel::InitFromBinderTransaction(void* data,
                                       size_t data_len,
                                       binder_size_t* objects,
                                       size_t objects_size,
                                       Parcel::release_func func) {
  if (data_ != nullptr) {
    // Already allocated.
    return false;
  }
  data_ = reinterpret_cast<uint8_t*>(data);
  data_len_ = data_len;
  objects_ = objects;
  objects_count_ = objects_size / sizeof(binder_size_t);
  owners_release_function_ = func;
  return true;
}

bool Parcel::SetCapacity(size_t capacity) {
  // Can't shink yet
  if (capacity < data_capacity_)
    return false;
  size_t new_capacity = PAD_SIZE(capacity);
  if (new_capacity < capacity)
    return false;
  uint8_t* new_data = reinterpret_cast<uint8_t*>(realloc(data_, new_capacity));
  if (new_data == nullptr)
    return false;
  data_ = new_data;
  data_capacity_ = new_capacity;
  return true;
}

bool Parcel::SetLen(size_t len) {
  if (len > data_capacity_)
    return false;
  data_len_ = len;
  return true;
}

bool Parcel::SetPos(size_t pos) {
  if (pos > data_len_)
    return false;
  data_pos_ = pos;
  return true;
}

// ---- Private API ----

template <class T>
bool Parcel::WriteAligned(T val) {
  // TODO(leecam): compile time check for alignment.
  if (data_pos_ + sizeof(val) < data_pos_)
    return false;
  if (data_pos_ + sizeof(val) > data_capacity_) {
    // Grow the backing buffer.
    if (!Grow(sizeof(val)))
      return false;
  }
  *reinterpret_cast<T*>(data_ + data_pos_) = val;
  AdvancePostion(sizeof(val));
  return true;
}

bool Parcel::WriteObject(const flat_binder_object& object) {
  if (data_pos_ + sizeof(object) < data_pos_)
    return false;
  if (data_pos_ + sizeof(object) > data_capacity_) {
    // Need to grow data
    if (!Grow(sizeof(object)))
      return false;
  }

  if (objects_count_ >= objects_capacity_) {
    // Need to grow objects.
    // TODO(leecam): Is this growth strategy any good?
    size_t new_capacity = objects_capacity_ + 16;
    if (new_capacity < objects_capacity_)
      return false;
    binder_size_t* new_objects = reinterpret_cast<binder_size_t*>(
        realloc(objects_, new_capacity * sizeof(binder_size_t)));
    if (new_objects == nullptr)
      return false;
    objects_ = new_objects;
    objects_capacity_ = new_capacity;
  }

  // Now have enough room to add the object.
  *reinterpret_cast<flat_binder_object*>(data_ + data_pos_) = object;

  objects_[objects_count_] = data_pos_;
  objects_count_++;

  AdvancePostion(sizeof(object));
  return true;
}

template <class T>
bool Parcel::ReadAligned(T* val) {
  // TODO(leecam): Compile time check for aligmment.
  if (data_pos_ + sizeof(T) < data_pos_)
    return false;
  if (val == nullptr)
    return false;
  if ((data_pos_ + sizeof(T)) <= data_len_) {
    const void* data = data_ + data_pos_;
    data_pos_ += sizeof(T);
    *val = *reinterpret_cast<const T*>(data);
    return true;
  }
  return false;
}

const flat_binder_object* Parcel::ReadObject() {
  if (data_pos_ + sizeof(flat_binder_object) < data_pos_)
    return nullptr;
  if ((data_pos_ + sizeof(flat_binder_object)) > data_len_)
    return nullptr;
  const flat_binder_object* obj =
      reinterpret_cast<const flat_binder_object*>(data_ + data_pos_);
  // TODO(leecam): Validate this object.
  data_pos_ += sizeof(flat_binder_object);
  return obj;
}

bool Parcel::Grow(size_t extra_required) {
  // Increase capacity by |extra_required| then add 50%
  // to save on repeated allocations.
  size_t new_capacity = PAD_SIZE(((data_capacity_ + extra_required) * 3) / 2);
  if (new_capacity < data_capacity_)
    return false;
  return SetCapacity(new_capacity);
}

void Parcel::AdvancePostion(size_t len) {
  // Overflow and capacity checks always done in caller.
  data_pos_ += len;
  if (data_pos_ > data_len_)
    data_len_ = data_pos_;
}

void* Parcel::AllocatePaddedBuffer(size_t len) {
  size_t padded_len = PAD_SIZE(len);
  if (padded_len < len || (data_pos_ + padded_len) < data_pos_)
    return nullptr;
  if (data_pos_ + padded_len >= data_capacity_) {
    if (!Grow(padded_len))
      return nullptr;
  }
  uint8_t* data = data_ + data_pos_;
  // If we have padding then zero the last word.
  if (padded_len > len) {
    *reinterpret_cast<uint32_t*>(data + padded_len - sizeof(uint32_t)) = 0;
  }
  AdvancePostion(padded_len);
  return data;
}

void* Parcel::GetPaddedBuffer(size_t len) {
  if ((data_pos_ + PAD_SIZE(len)) >= data_pos_ &&
      (data_pos_ + PAD_SIZE(len)) <= data_len_ && len <= PAD_SIZE(len)) {
    void* data = data_ + data_pos_;
    data_pos_ += PAD_SIZE(len);
    return data;
  }
  return nullptr;
}

const flat_binder_object* Parcel::GetObjectAtOffset(size_t offset) {
  size_t base = data_pos_ + (offset * sizeof(flat_binder_object));
  if (base < (offset * sizeof(flat_binder_object)))
    return nullptr;
  if (base + sizeof(flat_binder_object) < data_pos_)
    return nullptr;
  if ((base + sizeof(flat_binder_object)) > data_len_)
    return nullptr;
  const flat_binder_object* obj =
      reinterpret_cast<const flat_binder_object*>(data_ + base);
  // TODO(leecam): Validate this object
  return obj;
}

}  // namespace protobinder
