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

#include "mojo/edk/system/message_in_transit.h"

#include <string.h>

#include "base/compiler_specific.h"
#include "base/logging.h"
#include "mojo/edk/system/configuration.h"
#include "mojo/edk/system/transport_data.h"

namespace mojo {
namespace system {

STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Type
    MessageInTransit::kTypeEndpoint;
STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Type
    MessageInTransit::kTypeChannel;
STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Type
    MessageInTransit::kTypeRawChannel;
STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Subtype
    MessageInTransit::kSubtypeEndpointData;
STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Subtype
    MessageInTransit::kSubtypeChannelAttachAndRunEndpoint;
STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Subtype
    MessageInTransit::kSubtypeChannelRemoveEndpoint;
STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Subtype
    MessageInTransit::kSubtypeChannelRemoveEndpointAck;
STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Subtype
    MessageInTransit::kSubtypeRawChannelPosixExtraPlatformHandles;
STATIC_CONST_MEMBER_DEFINITION const size_t MessageInTransit::kMessageAlignment;

struct MessageInTransit::PrivateStructForCompileAsserts {
  // The size of |Header| must be a multiple of the alignment.
  static_assert(sizeof(Header) % kMessageAlignment == 0,
                "sizeof(MessageInTransit::Header) invalid");
};

MessageInTransit::View::View(size_t message_size, const void* buffer)
    : buffer_(buffer) {
  size_t next_message_size = 0;
  DCHECK(MessageInTransit::GetNextMessageSize(buffer_, message_size,
                                              &next_message_size));
  DCHECK_EQ(message_size, next_message_size);
  // This should be equivalent.
  DCHECK_EQ(message_size, total_size());
}

bool MessageInTransit::View::IsValid(size_t serialized_platform_handle_size,
                                     const char** error_message) const {
  size_t max_message_num_bytes = GetConfiguration().max_message_num_bytes;
  // Avoid dangerous situations, but making sure that the size of the "header" +
  // the size of the data fits into a 31-bit number.
  DCHECK_LE(static_cast<uint64_t>(sizeof(Header)) + max_message_num_bytes,
            0x7fffffffULL)
      << "GetConfiguration().max_message_num_bytes too big";

  // We assume (to avoid extra rounding code) that the maximum message (data)
  // size is a multiple of the alignment.
  DCHECK_EQ(max_message_num_bytes % kMessageAlignment, 0U)
      << "GetConfiguration().max_message_num_bytes not a multiple of alignment";

  // Note: This also implies a check on the |main_buffer_size()|, which is just
  // |RoundUpMessageAlignment(sizeof(Header) + num_bytes())|.
  if (num_bytes() > max_message_num_bytes) {
    *error_message = "Message data payload too large";
    return false;
  }

  if (transport_data_buffer_size() > 0) {
    const char* e = TransportData::ValidateBuffer(
        serialized_platform_handle_size, transport_data_buffer(),
        transport_data_buffer_size());
    if (e) {
      *error_message = e;
      return false;
    }
  }

  return true;
}

MessageInTransit::MessageInTransit(Type type,
                                   Subtype subtype,
                                   uint32_t num_bytes,
                                   const void* bytes)
    : main_buffer_size_(RoundUpMessageAlignment(sizeof(Header) + num_bytes)),
      main_buffer_(static_cast<char*>(
          base::AlignedAlloc(main_buffer_size_, kMessageAlignment))) {
  ConstructorHelper(type, subtype, num_bytes);
  if (bytes) {
    memcpy(MessageInTransit::bytes(), bytes, num_bytes);
    memset(static_cast<char*>(MessageInTransit::bytes()) + num_bytes, 0,
           main_buffer_size_ - sizeof(Header) - num_bytes);
  } else {
    memset(MessageInTransit::bytes(), 0, main_buffer_size_ - sizeof(Header));
  }
}

MessageInTransit::MessageInTransit(Type type,
                                   Subtype subtype,
                                   uint32_t num_bytes,
                                   UserPointer<const void> bytes)
    : main_buffer_size_(RoundUpMessageAlignment(sizeof(Header) + num_bytes)),
      main_buffer_(static_cast<char*>(
          base::AlignedAlloc(main_buffer_size_, kMessageAlignment))) {
  ConstructorHelper(type, subtype, num_bytes);
  bytes.GetArray(MessageInTransit::bytes(), num_bytes);
  memset(static_cast<char*>(MessageInTransit::bytes()) + num_bytes, 0,
         main_buffer_size_ - sizeof(Header) - num_bytes);
}

MessageInTransit::MessageInTransit(const View& message_view)
    : main_buffer_size_(message_view.main_buffer_size()),
      main_buffer_(static_cast<char*>(
          base::AlignedAlloc(main_buffer_size_, kMessageAlignment))) {
  DCHECK_GE(main_buffer_size_, sizeof(Header));
  DCHECK_EQ(main_buffer_size_ % kMessageAlignment, 0u);

  memcpy(main_buffer_.get(), message_view.main_buffer(), main_buffer_size_);
  DCHECK_EQ(main_buffer_size_,
            RoundUpMessageAlignment(sizeof(Header) + num_bytes()));
}

MessageInTransit::~MessageInTransit() {
  if (dispatchers_) {
    for (size_t i = 0; i < dispatchers_->size(); i++) {
      if (!(*dispatchers_)[i])
        continue;

      DCHECK((*dispatchers_)[i]->HasOneRef());
      (*dispatchers_)[i]->Close();
    }
  }
}

// static
bool MessageInTransit::GetNextMessageSize(const void* buffer,
                                          size_t buffer_size,
                                          size_t* next_message_size) {
  DCHECK(next_message_size);
  if (!buffer_size)
    return false;
  DCHECK(buffer);
  DCHECK_EQ(
      reinterpret_cast<uintptr_t>(buffer) % MessageInTransit::kMessageAlignment,
      0u);

  if (buffer_size < sizeof(Header))
    return false;

  const Header* header = static_cast<const Header*>(buffer);
  *next_message_size = header->total_size;
  DCHECK_EQ(*next_message_size % kMessageAlignment, 0u);
  return true;
}

void MessageInTransit::SetDispatchers(
    scoped_ptr<DispatcherVector> dispatchers) {
  DCHECK(dispatchers);
  DCHECK(!dispatchers_);
  DCHECK(!transport_data_);

  dispatchers_ = dispatchers.Pass();
#ifndef NDEBUG
  for (size_t i = 0; i < dispatchers_->size(); i++)
    DCHECK(!(*dispatchers_)[i] || (*dispatchers_)[i]->HasOneRef());
#endif
}

void MessageInTransit::SetTransportData(
    scoped_ptr<TransportData> transport_data) {
  DCHECK(transport_data);
  DCHECK(!transport_data_);
  DCHECK(!dispatchers_);

  transport_data_ = transport_data.Pass();
  UpdateTotalSize();
}

void MessageInTransit::SerializeAndCloseDispatchers(Channel* channel) {
  DCHECK(channel);
  DCHECK(!transport_data_);

  if (!dispatchers_ || !dispatchers_->size())
    return;

  transport_data_.reset(new TransportData(dispatchers_.Pass(), channel));

  // Update the sizes in the message header.
  UpdateTotalSize();
}

void MessageInTransit::ConstructorHelper(Type type,
                                         Subtype subtype,
                                         uint32_t num_bytes) {
  DCHECK_LE(num_bytes, GetConfiguration().max_message_num_bytes);

  // |total_size| is updated below, from the other values.
  header()->type = type;
  header()->subtype = subtype;
  header()->source_id = ChannelEndpointId();
  header()->destination_id = ChannelEndpointId();
  header()->num_bytes = num_bytes;
  header()->unused = 0;
  // Note: If dispatchers are subsequently attached, then |total_size| will have
  // to be adjusted.
  UpdateTotalSize();
}

void MessageInTransit::UpdateTotalSize() {
  DCHECK_EQ(main_buffer_size_ % kMessageAlignment, 0u);
  header()->total_size = static_cast<uint32_t>(main_buffer_size_);
  if (transport_data_) {
    header()->total_size +=
        static_cast<uint32_t>(transport_data_->buffer_size());
  }
}

}  // namespace system
}  // namespace mojo
