// 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 "ipc/ipc_message_utils.h"

#include <stddef.h>
#include <stdint.h>

#include "base/files/file_path.h"
#include "base/json/json_writer.h"
#include "base/memory/ptr_util.h"
#include "base/strings/nullable_string16.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "base/unguessable_token.h"
#include "base/values.h"
#include "build/build_config.h"
#include "ipc/ipc_channel_handle.h"
#include "ipc/ipc_message_attachment.h"
#include "ipc/ipc_message_attachment_set.h"
#include "ipc/ipc_mojo_param_traits.h"

#if defined(OS_MACOSX) && !defined(OS_IOS)
#include "ipc/mach_port_mac.h"
#endif

#if defined(OS_WIN)
#include <tchar.h>
#include "ipc/handle_win.h"
#include "ipc/ipc_platform_file.h"
#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
#include "base/file_descriptor_posix.h"
#include "ipc/ipc_platform_file_attachment_posix.h"
#endif

#if defined(OS_FUCHSIA)
#include "ipc/handle_fuchsia.h"
#endif

#if defined(OS_ANDROID)
#include "base/android/scoped_hardware_buffer_handle.h"
#include "ipc/ipc_mojo_handle_attachment.h"
#include "mojo/public/cpp/system/message_pipe.h"
#include "mojo/public/cpp/system/scope_to_message_pipe.h"
#endif

namespace IPC {

namespace {

const int kMaxRecursionDepth = 200;

template<typename CharType>
void LogBytes(const std::vector<CharType>& data, std::string* out) {
#if defined(OS_WIN)
  // Windows has a GUI for logging, which can handle arbitrary binary data.
  for (size_t i = 0; i < data.size(); ++i)
    out->push_back(data[i]);
#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
  // On POSIX, we log to stdout, which we assume can display ASCII.
  static const size_t kMaxBytesToLog = 100;
  for (size_t i = 0; i < std::min(data.size(), kMaxBytesToLog); ++i) {
    if (isprint(data[i]))
      out->push_back(data[i]);
    else
      out->append(
          base::StringPrintf("[%02X]", static_cast<unsigned char>(data[i])));
  }
  if (data.size() > kMaxBytesToLog) {
    out->append(base::StringPrintf(
        " and %u more bytes",
        static_cast<unsigned>(data.size() - kMaxBytesToLog)));
  }
#endif
}

bool ReadValue(const base::Pickle* m,
               base::PickleIterator* iter,
               std::unique_ptr<base::Value>* value,
               int recursion);

void WriteValue(base::Pickle* m, const base::Value* value, int recursion) {
  bool result;
  if (recursion > kMaxRecursionDepth) {
    LOG(ERROR) << "Max recursion depth hit in WriteValue.";
    return;
  }

  m->WriteInt(static_cast<int>(value->type()));

  switch (value->type()) {
    case base::Value::Type::NONE:
      break;
    case base::Value::Type::BOOLEAN: {
      bool val;
      result = value->GetAsBoolean(&val);
      DCHECK(result);
      WriteParam(m, val);
      break;
    }
    case base::Value::Type::INTEGER: {
      int val;
      result = value->GetAsInteger(&val);
      DCHECK(result);
      WriteParam(m, val);
      break;
    }
    case base::Value::Type::DOUBLE: {
      double val;
      result = value->GetAsDouble(&val);
      DCHECK(result);
      WriteParam(m, val);
      break;
    }
    case base::Value::Type::STRING: {
      std::string val;
      result = value->GetAsString(&val);
      DCHECK(result);
      WriteParam(m, val);
      break;
    }
    case base::Value::Type::BINARY: {
      m->WriteData(reinterpret_cast<const char*>(value->GetBlob().data()),
                   base::checked_cast<int>(value->GetBlob().size()));
      break;
    }
    case base::Value::Type::DICTIONARY: {
      const base::DictionaryValue* dict =
          static_cast<const base::DictionaryValue*>(value);

      WriteParam(m, base::checked_cast<int>(dict->size()));

      for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd();
           it.Advance()) {
        WriteParam(m, it.key());
        WriteValue(m, &it.value(), recursion + 1);
      }
      break;
    }
    case base::Value::Type::LIST: {
      const base::ListValue* list = static_cast<const base::ListValue*>(value);
      WriteParam(m, base::checked_cast<int>(list->GetSize()));
      for (const auto& entry : *list) {
        WriteValue(m, &entry, recursion + 1);
      }
      break;
    }

    // TODO(crbug.com/859477): Remove after root cause is found.
    default:
      CHECK(false);
      break;
  }
}

// Helper for ReadValue that reads a DictionaryValue into a pre-allocated
// object.
bool ReadDictionaryValue(const base::Pickle* m,
                         base::PickleIterator* iter,
                         base::DictionaryValue* value,
                         int recursion) {
  int size;
  if (!ReadParam(m, iter, &size))
    return false;

  for (int i = 0; i < size; ++i) {
    std::string key;
    std::unique_ptr<base::Value> subval;
    if (!ReadParam(m, iter, &key) ||
        !ReadValue(m, iter, &subval, recursion + 1))
      return false;
    value->SetWithoutPathExpansion(key, std::move(subval));
  }

  return true;
}

// Helper for ReadValue that reads a ReadListValue into a pre-allocated
// object.
bool ReadListValue(const base::Pickle* m,
                   base::PickleIterator* iter,
                   base::ListValue* value,
                   int recursion) {
  int size;
  if (!ReadParam(m, iter, &size))
    return false;

  for (int i = 0; i < size; ++i) {
    std::unique_ptr<base::Value> subval;
    if (!ReadValue(m, iter, &subval, recursion + 1))
      return false;
    value->Set(i, std::move(subval));
  }

  return true;
}

bool ReadValue(const base::Pickle* m,
               base::PickleIterator* iter,
               std::unique_ptr<base::Value>* value,
               int recursion) {
  if (recursion > kMaxRecursionDepth) {
    LOG(ERROR) << "Max recursion depth hit in ReadValue.";
    return false;
  }

  int type;
  if (!ReadParam(m, iter, &type))
    return false;

  switch (static_cast<base::Value::Type>(type)) {
    case base::Value::Type::NONE:
      *value = std::make_unique<base::Value>();
      break;
    case base::Value::Type::BOOLEAN: {
      bool val;
      if (!ReadParam(m, iter, &val))
        return false;
      *value = std::make_unique<base::Value>(val);
      break;
    }
    case base::Value::Type::INTEGER: {
      int val;
      if (!ReadParam(m, iter, &val))
        return false;
      *value = std::make_unique<base::Value>(val);
      break;
    }
    case base::Value::Type::DOUBLE: {
      double val;
      if (!ReadParam(m, iter, &val))
        return false;
      *value = std::make_unique<base::Value>(val);
      break;
    }
    case base::Value::Type::STRING: {
      std::string val;
      if (!ReadParam(m, iter, &val))
        return false;
      *value = std::make_unique<base::Value>(std::move(val));
      break;
    }
    case base::Value::Type::BINARY: {
      const char* data;
      int length;
      if (!iter->ReadData(&data, &length))
        return false;
      *value = base::Value::CreateWithCopiedBuffer(data, length);
      break;
    }
    case base::Value::Type::DICTIONARY: {
      base::DictionaryValue val;
      if (!ReadDictionaryValue(m, iter, &val, recursion))
        return false;
      *value = std::make_unique<base::Value>(std::move(val));
      break;
    }
    case base::Value::Type::LIST: {
      base::ListValue val;
      if (!ReadListValue(m, iter, &val, recursion))
        return false;
      *value = std::make_unique<base::Value>(std::move(val));
      break;
    }
    default:
      // TODO(crbug.com/859477): Remove after root cause is found.
      CHECK(false);
      return false;
  }

  return true;
}

}  // namespace

// -----------------------------------------------------------------------------

LogData::LogData()
    : routing_id(0),
      type(0),
      sent(0),
      receive(0),
      dispatch(0) {
}

LogData::LogData(const LogData& other) = default;

LogData::~LogData() = default;

void ParamTraits<bool>::Log(const param_type& p, std::string* l) {
  l->append(p ? "true" : "false");
}

void ParamTraits<signed char>::Write(base::Pickle* m, const param_type& p) {
  m->WriteBytes(&p, sizeof(param_type));
}

bool ParamTraits<signed char>::Read(const base::Pickle* m,
                                    base::PickleIterator* iter,
                                    param_type* r) {
  const char* data;
  if (!iter->ReadBytes(&data, sizeof(param_type)))
    return false;
  memcpy(r, data, sizeof(param_type));
  return true;
}

void ParamTraits<signed char>::Log(const param_type& p, std::string* l) {
  l->append(base::NumberToString(p));
}

void ParamTraits<unsigned char>::Write(base::Pickle* m, const param_type& p) {
  m->WriteBytes(&p, sizeof(param_type));
}

bool ParamTraits<unsigned char>::Read(const base::Pickle* m,
                                      base::PickleIterator* iter,
                                      param_type* r) {
  const char* data;
  if (!iter->ReadBytes(&data, sizeof(param_type)))
    return false;
  memcpy(r, data, sizeof(param_type));
  return true;
}

void ParamTraits<unsigned char>::Log(const param_type& p, std::string* l) {
  l->append(base::NumberToString(p));
}

void ParamTraits<unsigned short>::Write(base::Pickle* m, const param_type& p) {
  m->WriteBytes(&p, sizeof(param_type));
}

bool ParamTraits<unsigned short>::Read(const base::Pickle* m,
                                       base::PickleIterator* iter,
                                       param_type* r) {
  const char* data;
  if (!iter->ReadBytes(&data, sizeof(param_type)))
    return false;
  memcpy(r, data, sizeof(param_type));
  return true;
}

void ParamTraits<unsigned short>::Log(const param_type& p, std::string* l) {
  l->append(base::NumberToString(p));
}

void ParamTraits<int>::Log(const param_type& p, std::string* l) {
  l->append(base::NumberToString(p));
}

void ParamTraits<unsigned int>::Log(const param_type& p, std::string* l) {
  l->append(base::NumberToString(p));
}

#if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_FUCHSIA) || \
    (defined(OS_ANDROID) && defined(ARCH_CPU_64_BITS))
void ParamTraits<long>::Log(const param_type& p, std::string* l) {
  l->append(base::NumberToString(p));
}

void ParamTraits<unsigned long>::Log(const param_type& p, std::string* l) {
  l->append(base::NumberToString(p));
}
#endif

void ParamTraits<long long>::Log(const param_type& p, std::string* l) {
  l->append(base::NumberToString(p));
}

void ParamTraits<unsigned long long>::Log(const param_type& p, std::string* l) {
  l->append(base::NumberToString(p));
}

void ParamTraits<float>::Log(const param_type& p, std::string* l) {
  l->append(base::StringPrintf("%e", p));
}

void ParamTraits<double>::Write(base::Pickle* m, const param_type& p) {
  m->WriteBytes(reinterpret_cast<const char*>(&p), sizeof(param_type));
}

bool ParamTraits<double>::Read(const base::Pickle* m,
                               base::PickleIterator* iter,
                               param_type* r) {
  const char *data;
  if (!iter->ReadBytes(&data, sizeof(*r))) {
    NOTREACHED();
    return false;
  }
  memcpy(r, data, sizeof(param_type));
  return true;
}

void ParamTraits<double>::Log(const param_type& p, std::string* l) {
  l->append(base::StringPrintf("%e", p));
}


void ParamTraits<std::string>::Log(const param_type& p, std::string* l) {
  l->append(p);
}

void ParamTraits<base::string16>::Log(const param_type& p, std::string* l) {
  l->append(base::UTF16ToUTF8(p));
}

void ParamTraits<std::vector<char>>::Write(base::Pickle* m,
                                           const param_type& p) {
  if (p.empty()) {
    m->WriteData(NULL, 0);
  } else {
    m->WriteData(&p.front(), base::checked_cast<int>(p.size()));
  }
}

bool ParamTraits<std::vector<char>>::Read(const base::Pickle* m,
                                          base::PickleIterator* iter,
                                          param_type* r) {
  const char *data;
  int data_size = 0;
  if (!iter->ReadData(&data, &data_size) || data_size < 0)
    return false;
  r->resize(data_size);
  if (data_size)
    memcpy(&r->front(), data, data_size);
  return true;
}

void ParamTraits<std::vector<char> >::Log(const param_type& p, std::string* l) {
  LogBytes(p, l);
}

void ParamTraits<std::vector<unsigned char>>::Write(base::Pickle* m,
                                                    const param_type& p) {
  if (p.empty()) {
    m->WriteData(NULL, 0);
  } else {
    m->WriteData(reinterpret_cast<const char*>(&p.front()),
                 base::checked_cast<int>(p.size()));
  }
}

bool ParamTraits<std::vector<unsigned char>>::Read(const base::Pickle* m,
                                                   base::PickleIterator* iter,
                                                   param_type* r) {
  const char *data;
  int data_size = 0;
  if (!iter->ReadData(&data, &data_size) || data_size < 0)
    return false;
  r->resize(data_size);
  if (data_size)
    memcpy(&r->front(), data, data_size);
  return true;
}

void ParamTraits<std::vector<unsigned char> >::Log(const param_type& p,
                                                   std::string* l) {
  LogBytes(p, l);
}

void ParamTraits<std::vector<bool>>::Write(base::Pickle* m,
                                           const param_type& p) {
  WriteParam(m, base::checked_cast<int>(p.size()));
  // Cast to bool below is required because libc++'s
  // vector<bool>::const_reference is different from bool, and we want to avoid
  // writing an extra specialization of ParamTraits for it.
  for (size_t i = 0; i < p.size(); i++)
    WriteParam(m, static_cast<bool>(p[i]));
}

bool ParamTraits<std::vector<bool>>::Read(const base::Pickle* m,
                                          base::PickleIterator* iter,
                                          param_type* r) {
  int size;
  // ReadLength() checks for < 0 itself.
  if (!iter->ReadLength(&size))
    return false;
  r->resize(size);
  for (int i = 0; i < size; i++) {
    bool value;
    if (!ReadParam(m, iter, &value))
      return false;
    (*r)[i] = value;
  }
  return true;
}

void ParamTraits<std::vector<bool> >::Log(const param_type& p, std::string* l) {
  for (size_t i = 0; i < p.size(); ++i) {
    if (i != 0)
      l->push_back(' ');
    LogParam(static_cast<bool>(p[i]), l);
  }
}

void ParamTraits<base::DictionaryValue>::Write(base::Pickle* m,
                                               const param_type& p) {
  WriteValue(m, &p, 0);
}

bool ParamTraits<base::DictionaryValue>::Read(const base::Pickle* m,
                                              base::PickleIterator* iter,
                                              param_type* r) {
  int type;
  if (!ReadParam(m, iter, &type) ||
      type != static_cast<int>(base::Value::Type::DICTIONARY))
    return false;

  return ReadDictionaryValue(m, iter, r, 0);
}

void ParamTraits<base::DictionaryValue>::Log(const param_type& p,
                                             std::string* l) {
  std::string json;
  base::JSONWriter::Write(p, &json);
  l->append(json);
}

#if defined(OS_POSIX) || defined(OS_FUCHSIA)
void ParamTraits<base::FileDescriptor>::Write(base::Pickle* m,
                                              const param_type& p) {
  // This serialization must be kept in sync with
  // nacl_message_scanner.cc:WriteHandle().
  const bool valid = p.fd >= 0;
  WriteParam(m, valid);

  if (!valid)
    return;

  if (p.auto_close) {
    if (!m->WriteAttachment(
            new internal::PlatformFileAttachment(base::ScopedFD(p.fd))))
      NOTREACHED();
  } else {
    if (!m->WriteAttachment(new internal::PlatformFileAttachment(p.fd)))
      NOTREACHED();
  }
}

bool ParamTraits<base::FileDescriptor>::Read(const base::Pickle* m,
                                             base::PickleIterator* iter,
                                             param_type* r) {
  *r = base::FileDescriptor();

  bool valid;
  if (!ReadParam(m, iter, &valid))
    return false;

  if (!valid)
    return true;

  scoped_refptr<base::Pickle::Attachment> attachment;
  if (!m->ReadAttachment(iter, &attachment))
    return false;

  if (static_cast<MessageAttachment*>(attachment.get())->GetType() !=
      MessageAttachment::Type::PLATFORM_FILE) {
    return false;
  }

  *r = base::FileDescriptor(
      static_cast<internal::PlatformFileAttachment*>(attachment.get())
          ->TakePlatformFile(),
      true);
  return true;
}

void ParamTraits<base::FileDescriptor>::Log(const param_type& p,
                                            std::string* l) {
  if (p.auto_close) {
    l->append(base::StringPrintf("FD(%d auto-close)", p.fd));
  } else {
    l->append(base::StringPrintf("FD(%d)", p.fd));
  }
}

void ParamTraits<base::ScopedFD>::Write(base::Pickle* m, const param_type& p) {
  // This serialization must be kept in sync with
  // nacl_message_scanner.cc:WriteHandle().
  const bool valid = p.is_valid();
  WriteParam(m, valid);

  if (!valid)
    return;

  if (!m->WriteAttachment(new internal::PlatformFileAttachment(
          std::move(const_cast<param_type&>(p))))) {
    NOTREACHED();
  }
}

bool ParamTraits<base::ScopedFD>::Read(const base::Pickle* m,
                                       base::PickleIterator* iter,
                                       param_type* r) {
  r->reset();

  bool valid;
  if (!ReadParam(m, iter, &valid))
    return false;

  if (!valid)
    return true;

  scoped_refptr<base::Pickle::Attachment> attachment;
  if (!m->ReadAttachment(iter, &attachment))
    return false;

  if (static_cast<MessageAttachment*>(attachment.get())->GetType() !=
      MessageAttachment::Type::PLATFORM_FILE) {
    return false;
  }

  *r = base::ScopedFD(
      static_cast<internal::PlatformFileAttachment*>(attachment.get())
          ->TakePlatformFile());
  return true;
}

void ParamTraits<base::ScopedFD>::Log(const param_type& p, std::string* l) {
  l->append(base::StringPrintf("ScopedFD(%d)", p.get()));
}
#endif  // defined(OS_POSIX) || defined(OS_FUCHSIA)

#if defined(OS_ANDROID)
void ParamTraits<base::android::ScopedHardwareBufferHandle>::Write(
    base::Pickle* m,
    const param_type& p) {
  const bool is_valid = p.is_valid();
  WriteParam(m, is_valid);
  if (!is_valid)
    return;

  // We must keep a ref to the AHardwareBuffer alive until the receiver has
  // acquired its own reference. We do this by sending a message pipe handle
  // along with the buffer. When the receiver deserializes (or even if they
  // die without ever reading the message) their end of the pipe will be
  // closed. We will eventually detect this and release the AHB reference.
  mojo::MessagePipe tracking_pipe;
  m->WriteAttachment(new internal::MojoHandleAttachment(
      mojo::ScopedHandle::From(std::move(tracking_pipe.handle0))));
  WriteParam(m, base::FileDescriptor(p.SerializeAsFileDescriptor().release(),
                                     true /* auto_close */));

  // Pass ownership of the input handle to our tracking pipe to keep the AHB
  // alive long enough to be deserialized by the receiver.
  mojo::ScopeToMessagePipe(std::move(const_cast<param_type&>(p)),
                           std::move(tracking_pipe.handle1));
}

bool ParamTraits<base::android::ScopedHardwareBufferHandle>::Read(
    const base::Pickle* m,
    base::PickleIterator* iter,
    param_type* r) {
  *r = base::android::ScopedHardwareBufferHandle();

  bool is_valid;
  if (!ReadParam(m, iter, &is_valid))
    return false;
  if (!is_valid)
    return true;

  scoped_refptr<base::Pickle::Attachment> tracking_pipe_attachment;
  if (!m->ReadAttachment(iter, &tracking_pipe_attachment))
    return false;

  // We keep this alive until the AHB is safely deserialized below. When this
  // goes out of scope, the sender holding the other end of this pipe will treat
  // this handle closure as a signal that it's safe to release their AHB
  // keepalive ref.
  mojo::ScopedHandle tracking_pipe =
      static_cast<MessageAttachment*>(tracking_pipe_attachment.get())
          ->TakeMojoHandle();

  base::FileDescriptor descriptor;
  if (!ReadParam(m, iter, &descriptor))
    return false;

  // NOTE: It is valid to deserialize an invalid FileDescriptor, so the success
  // of |ReadParam()| above does not imply that |descriptor| is valid.
  base::ScopedFD scoped_fd(descriptor.fd);
  if (!scoped_fd.is_valid())
    return false;

  *r = base::android::ScopedHardwareBufferHandle::DeserializeFromFileDescriptor(
      std::move(scoped_fd));
  return true;
}

void ParamTraits<base::android::ScopedHardwareBufferHandle>::Log(
    const param_type& p,
    std::string* l) {
  l->append(base::StringPrintf("base::android::ScopedHardwareBufferHandle(%p)",
                               p.get()));
}
#endif  // defined(OS_ANDROID)

void ParamTraits<base::SharedMemoryHandle>::Write(base::Pickle* m,
                                                  const param_type& p) {
  // This serialization must be kept in sync with
  // nacl_message_scanner.cc:WriteHandle().
  const bool valid = p.IsValid();
  WriteParam(m, valid);

  if (!valid)
    return;

#if defined(OS_WIN)
  HandleWin handle_win(p.GetHandle());
  WriteParam(m, handle_win);
#elif defined(OS_FUCHSIA)
  HandleFuchsia handle_fuchsia(p.GetHandle());
  WriteParam(m, handle_fuchsia);
#elif defined(OS_MACOSX) && !defined(OS_IOS)
  MachPortMac mach_port_mac(p.GetMemoryObject());
  WriteParam(m, mach_port_mac);
#elif defined(OS_POSIX)
#if defined(OS_ANDROID)
  WriteParam(m, p.IsReadOnly());

  // Ensure the region is read-only before sending it through IPC.
  if (p.IsReadOnly()) {
    if (!p.IsRegionReadOnly()) {
      LOG(ERROR) << "Sending unsealed read-only region through IPC";
      p.SetRegionReadOnly();
    }
  }
#endif
  if (p.OwnershipPassesToIPC()) {
    if (!m->WriteAttachment(new internal::PlatformFileAttachment(
            base::ScopedFD(p.GetHandle()))))
      NOTREACHED();
  } else {
    if (!m->WriteAttachment(
            new internal::PlatformFileAttachment(p.GetHandle())))
      NOTREACHED();
  }
#endif

#if (defined(OS_MACOSX) && !defined(OS_IOS)) || defined(OS_WIN)
  // If the caller intended to pass ownership to the IPC stack, release a
  // reference.
  if (p.OwnershipPassesToIPC())
    p.Close();
#endif

  DCHECK(!p.GetGUID().is_empty());
  WriteParam(m, p.GetGUID());
  WriteParam(m, static_cast<uint64_t>(p.GetSize()));
}

bool ParamTraits<base::SharedMemoryHandle>::Read(const base::Pickle* m,
                                                 base::PickleIterator* iter,
                                                 param_type* r) {
  *r = base::SharedMemoryHandle();

  bool valid;
  if (!ReadParam(m, iter, &valid))
    return false;
  if (!valid)
    return true;

#if defined(OS_WIN)
  HandleWin handle_win;
  if (!ReadParam(m, iter, &handle_win))
    return false;
#elif defined(OS_FUCHSIA)
  HandleFuchsia handle_fuchsia;
  if (!ReadParam(m, iter, &handle_fuchsia))
    return false;
#elif defined(OS_MACOSX) && !defined(OS_IOS)
  MachPortMac mach_port_mac;
  if (!ReadParam(m, iter, &mach_port_mac))
    return false;
#elif defined(OS_POSIX)
#if defined(OS_ANDROID)
  bool is_read_only = false;
  if (!ReadParam(m, iter, &is_read_only))
    return false;
#endif
  scoped_refptr<base::Pickle::Attachment> attachment;
  if (!m->ReadAttachment(iter, &attachment))
    return false;

  if (static_cast<MessageAttachment*>(attachment.get())->GetType() !=
      MessageAttachment::Type::PLATFORM_FILE) {
    return false;
  }
#endif

  base::UnguessableToken guid;
  uint64_t size;
  if (!ReadParam(m, iter, &guid) || !ReadParam(m, iter, &size) ||
      !base::IsValueInRangeForNumericType<size_t>(size)) {
    return false;
  }

#if defined(OS_WIN)
  *r = base::SharedMemoryHandle(handle_win.get_handle(),
                                static_cast<size_t>(size), guid);
#elif defined(OS_FUCHSIA)
  *r = base::SharedMemoryHandle(handle_fuchsia.get_handle(),
                                static_cast<size_t>(size), guid);
#elif defined(OS_MACOSX) && !defined(OS_IOS)
  *r = base::SharedMemoryHandle(mach_port_mac.get_mach_port(),
                                static_cast<size_t>(size), guid);
#elif defined(OS_POSIX)
  *r = base::SharedMemoryHandle(
      base::FileDescriptor(
          static_cast<internal::PlatformFileAttachment*>(attachment.get())
              ->TakePlatformFile(),
          true),
      static_cast<size_t>(size), guid);
#endif

#if defined(OS_ANDROID)
  if (is_read_only)
    r->SetReadOnly();
#endif

  return true;
}

void ParamTraits<base::SharedMemoryHandle>::Log(const param_type& p,
                                                std::string* l) {
#if defined(OS_WIN)
  l->append("HANDLE: ");
  LogParam(p.GetHandle(), l);
#elif defined(OS_MACOSX) && !defined(OS_IOS)
  l->append("Mach port: ");
  LogParam(p.GetMemoryObject(), l);
#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
  l->append("FD: ");
  LogParam(p.GetHandle(), l);
#endif

  l->append("GUID: ");
  LogParam(p.GetGUID(), l);
  l->append("size: ");
  LogParam(static_cast<uint64_t>(p.GetSize()), l);
#if defined(OS_ANDROID)
  l->append("read-only: ");
  LogParam(p.IsReadOnly(), l);
#endif
}

void ParamTraits<base::ReadOnlySharedMemoryRegion>::Write(base::Pickle* m,
                                                          const param_type& p) {
  base::subtle::PlatformSharedMemoryRegion handle =
      base::ReadOnlySharedMemoryRegion::TakeHandleForSerialization(
          std::move(const_cast<param_type&>(p)));
  WriteParam(m, std::move(handle));
}

bool ParamTraits<base::ReadOnlySharedMemoryRegion>::Read(
    const base::Pickle* m,
    base::PickleIterator* iter,
    param_type* r) {
  base::subtle::PlatformSharedMemoryRegion handle;
  if (!ReadParam(m, iter, &handle))
    return false;

  *r = base::ReadOnlySharedMemoryRegion::Deserialize(std::move(handle));
  return true;
}

void ParamTraits<base::ReadOnlySharedMemoryRegion>::Log(const param_type& p,
                                                        std::string* l) {
  *l = "<base::ReadOnlySharedMemoryRegion>";
  // TODO(alexilin): currently there is no way to access underlying handle
  // without destructing a ReadOnlySharedMemoryRegion instance.
}

void ParamTraits<base::WritableSharedMemoryRegion>::Write(base::Pickle* m,
                                                          const param_type& p) {
  base::subtle::PlatformSharedMemoryRegion handle =
      base::WritableSharedMemoryRegion::TakeHandleForSerialization(
          std::move(const_cast<param_type&>(p)));
  WriteParam(m, std::move(handle));
}

bool ParamTraits<base::WritableSharedMemoryRegion>::Read(
    const base::Pickle* m,
    base::PickleIterator* iter,
    param_type* r) {
  base::subtle::PlatformSharedMemoryRegion handle;
  if (!ReadParam(m, iter, &handle))
    return false;

  *r = base::WritableSharedMemoryRegion::Deserialize(std::move(handle));
  return true;
}

void ParamTraits<base::WritableSharedMemoryRegion>::Log(const param_type& p,
                                                        std::string* l) {
  *l = "<base::WritableSharedMemoryRegion>";
  // TODO(alexilin): currently there is no way to access underlying handle
  // without destructing a ReadOnlySharedMemoryRegion instance.
}

void ParamTraits<base::UnsafeSharedMemoryRegion>::Write(base::Pickle* m,
                                                        const param_type& p) {
  base::subtle::PlatformSharedMemoryRegion handle =
      base::UnsafeSharedMemoryRegion::TakeHandleForSerialization(
          std::move(const_cast<param_type&>(p)));
  WriteParam(m, std::move(handle));
}

bool ParamTraits<base::UnsafeSharedMemoryRegion>::Read(
    const base::Pickle* m,
    base::PickleIterator* iter,
    param_type* r) {
  base::subtle::PlatformSharedMemoryRegion handle;
  if (!ReadParam(m, iter, &handle))
    return false;

  *r = base::UnsafeSharedMemoryRegion::Deserialize(std::move(handle));
  return true;
}

void ParamTraits<base::UnsafeSharedMemoryRegion>::Log(const param_type& p,
                                                      std::string* l) {
  *l = "<base::UnsafeSharedMemoryRegion>";
  // TODO(alexilin): currently there is no way to access underlying handle
  // without destructing a ReadOnlySharedMemoryRegion instance.
}

void ParamTraits<base::subtle::PlatformSharedMemoryRegion>::Write(
    base::Pickle* m,
    const param_type& p) {
  // This serialization must be kept in sync with
  // nacl_message_scanner.cc::WriteHandle().
  const bool valid = p.IsValid();
  WriteParam(m, valid);

  if (!valid)
    return;

  WriteParam(m, p.GetMode());
  WriteParam(m, static_cast<uint64_t>(p.GetSize()));
  WriteParam(m, p.GetGUID());

#if defined(OS_WIN)
  base::win::ScopedHandle h = const_cast<param_type&>(p).PassPlatformHandle();
  HandleWin handle_win(h.Get());
  WriteParam(m, handle_win);
#elif defined(OS_FUCHSIA)
  zx::handle h = const_cast<param_type&>(p).PassPlatformHandle();
  HandleFuchsia handle_fuchsia(h.get());
  WriteParam(m, handle_fuchsia);
#elif defined(OS_MACOSX) && !defined(OS_IOS)
  base::mac::ScopedMachSendRight h =
      const_cast<param_type&>(p).PassPlatformHandle();
  MachPortMac mach_port_mac(h.get());
  WriteParam(m, mach_port_mac);
#elif defined(OS_ANDROID)
  m->WriteAttachment(new internal::PlatformFileAttachment(
      base::ScopedFD(const_cast<param_type&>(p).PassPlatformHandle())));
#elif defined(OS_POSIX)
  base::subtle::ScopedFDPair h =
      const_cast<param_type&>(p).PassPlatformHandle();
  m->WriteAttachment(new internal::PlatformFileAttachment(std::move(h.fd)));
  if (p.GetMode() ==
      base::subtle::PlatformSharedMemoryRegion::Mode::kWritable) {
    m->WriteAttachment(
        new internal::PlatformFileAttachment(std::move(h.readonly_fd)));
  }
#endif
}

bool ParamTraits<base::subtle::PlatformSharedMemoryRegion>::Read(
    const base::Pickle* m,
    base::PickleIterator* iter,
    param_type* r) {
  bool valid;
  if (!ReadParam(m, iter, &valid))
    return false;
  if (!valid) {
    *r = base::subtle::PlatformSharedMemoryRegion();
    return true;
  }

  base::subtle::PlatformSharedMemoryRegion::Mode mode;
  uint64_t shm_size;
  base::UnguessableToken guid;
  if (!ReadParam(m, iter, &mode) || !ReadParam(m, iter, &shm_size) ||
      !base::IsValueInRangeForNumericType<size_t>(shm_size) ||
      !ReadParam(m, iter, &guid)) {
    return false;
  }
  size_t size = static_cast<size_t>(shm_size);

#if defined(OS_WIN)
  HandleWin handle_win;
  if (!ReadParam(m, iter, &handle_win))
    return false;
  *r = base::subtle::PlatformSharedMemoryRegion::Take(
      base::win::ScopedHandle(handle_win.get_handle()), mode, size, guid);
#elif defined(OS_FUCHSIA)
  HandleFuchsia handle_fuchsia;
  if (!ReadParam(m, iter, &handle_fuchsia))
    return false;
  *r = base::subtle::PlatformSharedMemoryRegion::Take(
      zx::vmo(handle_fuchsia.get_handle()), mode, size, guid);
#elif defined(OS_MACOSX) && !defined(OS_IOS)
  MachPortMac mach_port_mac;
  if (!ReadParam(m, iter, &mach_port_mac))
    return false;
  *r = base::subtle::PlatformSharedMemoryRegion::Take(
      base::mac::ScopedMachSendRight(mach_port_mac.get_mach_port()), mode, size,
      guid);
#elif defined(OS_POSIX)
  scoped_refptr<base::Pickle::Attachment> attachment;
  if (!m->ReadAttachment(iter, &attachment))
    return false;
  if (static_cast<MessageAttachment*>(attachment.get())->GetType() !=
      MessageAttachment::Type::PLATFORM_FILE) {
    return false;
  }

#if defined(OS_ANDROID)
  *r = base::subtle::PlatformSharedMemoryRegion::Take(
      base::ScopedFD(
          static_cast<internal::PlatformFileAttachment*>(attachment.get())
              ->TakePlatformFile()),
      mode, size, guid);
#else
  scoped_refptr<base::Pickle::Attachment> readonly_attachment;
  if (mode == base::subtle::PlatformSharedMemoryRegion::Mode::kWritable) {
    if (!m->ReadAttachment(iter, &readonly_attachment))
      return false;

    if (static_cast<MessageAttachment*>(readonly_attachment.get())->GetType() !=
        MessageAttachment::Type::PLATFORM_FILE) {
      return false;
    }
  }
  *r = base::subtle::PlatformSharedMemoryRegion::Take(
      base::subtle::ScopedFDPair(
          base::ScopedFD(
              static_cast<internal::PlatformFileAttachment*>(attachment.get())
                  ->TakePlatformFile()),
          readonly_attachment
              ? base::ScopedFD(static_cast<internal::PlatformFileAttachment*>(
                                   readonly_attachment.get())
                                   ->TakePlatformFile())
              : base::ScopedFD()),
      mode, size, guid);
#endif  // defined(OS_ANDROID)

#endif

  return true;
}

void ParamTraits<base::subtle::PlatformSharedMemoryRegion>::Log(
    const param_type& p,
    std::string* l) {
#if defined(OS_FUCHSIA)
  l->append("Handle: ");
  LogParam(p.GetPlatformHandle()->get(), l);
#elif defined(OS_WIN)
  l->append("Handle: ");
  LogParam(p.GetPlatformHandle(), l);
#elif defined(OS_MACOSX) && !defined(OS_IOS)
  l->append("Mach port: ");
  LogParam(p.GetPlatformHandle(), l);
#elif defined(OS_ANDROID)
  l->append("FD: ");
  LogParam(p.GetPlatformHandle(), l);
#elif defined(OS_POSIX)
  base::subtle::FDPair h = p.GetPlatformHandle();
  l->append("FD: ");
  LogParam(h.fd, l);
  l->append("Read-only FD: ");
  LogParam(h.readonly_fd, l);
#endif

  l->append("Mode: ");
  LogParam(p.GetMode(), l);
  l->append("size: ");
  LogParam(static_cast<uint64_t>(p.GetSize()), l);
  l->append("GUID: ");
  LogParam(p.GetGUID(), l);
}

void ParamTraits<base::subtle::PlatformSharedMemoryRegion::Mode>::Write(
    base::Pickle* m,
    const param_type& value) {
  DCHECK(static_cast<int>(value) >= 0 &&
         static_cast<int>(value) <= static_cast<int>(param_type::kMaxValue));
  m->WriteInt(static_cast<int>(value));
}

bool ParamTraits<base::subtle::PlatformSharedMemoryRegion::Mode>::Read(
    const base::Pickle* m,
    base::PickleIterator* iter,
    param_type* p) {
  int value;
  if (!iter->ReadInt(&value))
    return false;
  if (!(static_cast<int>(value) >= 0 &&
        static_cast<int>(value) <= static_cast<int>(param_type::kMaxValue))) {
    return false;
  }
  *p = static_cast<param_type>(value);
  return true;
}

void ParamTraits<base::subtle::PlatformSharedMemoryRegion::Mode>::Log(
    const param_type& p,
    std::string* l) {
  LogParam(static_cast<int>(p), l);
}

#if defined(OS_WIN)
void ParamTraits<PlatformFileForTransit>::Write(base::Pickle* m,
                                                const param_type& p) {
  m->WriteBool(p.IsValid());
  if (p.IsValid()) {
    HandleWin handle_win(p.GetHandle());
    ParamTraits<HandleWin>::Write(m, handle_win);
    ::CloseHandle(p.GetHandle());
  }
}

bool ParamTraits<PlatformFileForTransit>::Read(const base::Pickle* m,
                                               base::PickleIterator* iter,
                                               param_type* r) {
  bool is_valid;
  if (!iter->ReadBool(&is_valid))
    return false;
  if (!is_valid) {
    *r = PlatformFileForTransit();
    return true;
  }

  HandleWin handle_win;
  if (!ParamTraits<HandleWin>::Read(m, iter, &handle_win))
    return false;
  *r = PlatformFileForTransit(handle_win.get_handle());
  return true;
}

void ParamTraits<PlatformFileForTransit>::Log(const param_type& p,
                                              std::string* l) {
  LogParam(p.GetHandle(), l);
}
#endif  // defined(OS_WIN)

void ParamTraits<base::FilePath>::Write(base::Pickle* m, const param_type& p) {
  p.WriteToPickle(m);
}

bool ParamTraits<base::FilePath>::Read(const base::Pickle* m,
                                       base::PickleIterator* iter,
                                       param_type* r) {
  return r->ReadFromPickle(iter);
}

void ParamTraits<base::FilePath>::Log(const param_type& p, std::string* l) {
  ParamTraits<base::FilePath::StringType>::Log(p.value(), l);
}

void ParamTraits<base::ListValue>::Write(base::Pickle* m, const param_type& p) {
  WriteValue(m, &p, 0);
}

bool ParamTraits<base::ListValue>::Read(const base::Pickle* m,
                                        base::PickleIterator* iter,
                                        param_type* r) {
  int type;
  if (!ReadParam(m, iter, &type) ||
      type != static_cast<int>(base::Value::Type::LIST))
    return false;

  return ReadListValue(m, iter, r, 0);
}

void ParamTraits<base::ListValue>::Log(const param_type& p, std::string* l) {
  std::string json;
  base::JSONWriter::Write(p, &json);
  l->append(json);
}

void ParamTraits<base::NullableString16>::Write(base::Pickle* m,
                                                const param_type& p) {
  WriteParam(m, p.string());
  WriteParam(m, p.is_null());
}

bool ParamTraits<base::NullableString16>::Read(const base::Pickle* m,
                                               base::PickleIterator* iter,
                                               param_type* r) {
  base::string16 string;
  if (!ReadParam(m, iter, &string))
    return false;
  bool is_null;
  if (!ReadParam(m, iter, &is_null))
    return false;
  *r = base::NullableString16(string, is_null);
  return true;
}

void ParamTraits<base::NullableString16>::Log(const param_type& p,
                                              std::string* l) {
  l->append("(");
  LogParam(p.string(), l);
  l->append(", ");
  LogParam(p.is_null(), l);
  l->append(")");
}

void ParamTraits<base::File::Info>::Write(base::Pickle* m,
                                          const param_type& p) {
  WriteParam(m, p.size);
  WriteParam(m, p.is_directory);
  WriteParam(m, p.last_modified.ToDoubleT());
  WriteParam(m, p.last_accessed.ToDoubleT());
  WriteParam(m, p.creation_time.ToDoubleT());
}

bool ParamTraits<base::File::Info>::Read(const base::Pickle* m,
                                         base::PickleIterator* iter,
                                         param_type* p) {
  double last_modified, last_accessed, creation_time;
  if (!ReadParam(m, iter, &p->size) ||
      !ReadParam(m, iter, &p->is_directory) ||
      !ReadParam(m, iter, &last_modified) ||
      !ReadParam(m, iter, &last_accessed) ||
      !ReadParam(m, iter, &creation_time))
    return false;
  p->last_modified = base::Time::FromDoubleT(last_modified);
  p->last_accessed = base::Time::FromDoubleT(last_accessed);
  p->creation_time = base::Time::FromDoubleT(creation_time);
  return true;
}

void ParamTraits<base::File::Info>::Log(const param_type& p,
                                        std::string* l) {
  l->append("(");
  LogParam(p.size, l);
  l->append(",");
  LogParam(p.is_directory, l);
  l->append(",");
  LogParam(p.last_modified.ToDoubleT(), l);
  l->append(",");
  LogParam(p.last_accessed.ToDoubleT(), l);
  l->append(",");
  LogParam(p.creation_time.ToDoubleT(), l);
  l->append(")");
}

void ParamTraits<base::Time>::Write(base::Pickle* m, const param_type& p) {
  ParamTraits<int64_t>::Write(m, p.ToInternalValue());
}

bool ParamTraits<base::Time>::Read(const base::Pickle* m,
                                   base::PickleIterator* iter,
                                   param_type* r) {
  int64_t value;
  if (!ParamTraits<int64_t>::Read(m, iter, &value))
    return false;
  *r = base::Time::FromInternalValue(value);
  return true;
}

void ParamTraits<base::Time>::Log(const param_type& p, std::string* l) {
  ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
}

void ParamTraits<base::TimeDelta>::Write(base::Pickle* m, const param_type& p) {
  ParamTraits<int64_t>::Write(m, p.ToInternalValue());
}

bool ParamTraits<base::TimeDelta>::Read(const base::Pickle* m,
                                        base::PickleIterator* iter,
                                        param_type* r) {
  int64_t value;
  bool ret = ParamTraits<int64_t>::Read(m, iter, &value);
  if (ret)
    *r = base::TimeDelta::FromInternalValue(value);

  return ret;
}

void ParamTraits<base::TimeDelta>::Log(const param_type& p, std::string* l) {
  ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
}

void ParamTraits<base::TimeTicks>::Write(base::Pickle* m, const param_type& p) {
  ParamTraits<int64_t>::Write(m, p.ToInternalValue());
}

bool ParamTraits<base::TimeTicks>::Read(const base::Pickle* m,
                                        base::PickleIterator* iter,
                                        param_type* r) {
  int64_t value;
  bool ret = ParamTraits<int64_t>::Read(m, iter, &value);
  if (ret)
    *r = base::TimeTicks::FromInternalValue(value);

  return ret;
}

void ParamTraits<base::TimeTicks>::Log(const param_type& p, std::string* l) {
  ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
}

// If base::UnguessableToken is no longer 128 bits, the IPC serialization logic
// below should be updated.
static_assert(sizeof(base::UnguessableToken) == 2 * sizeof(uint64_t),
              "base::UnguessableToken should be of size 2 * sizeof(uint64_t).");

void ParamTraits<base::UnguessableToken>::Write(base::Pickle* m,
                                                const param_type& p) {
  DCHECK(!p.is_empty());

  ParamTraits<uint64_t>::Write(m, p.GetHighForSerialization());
  ParamTraits<uint64_t>::Write(m, p.GetLowForSerialization());
}

bool ParamTraits<base::UnguessableToken>::Read(const base::Pickle* m,
                                               base::PickleIterator* iter,
                                               param_type* r) {
  uint64_t high, low;
  if (!ParamTraits<uint64_t>::Read(m, iter, &high) ||
      !ParamTraits<uint64_t>::Read(m, iter, &low))
    return false;

  // Receiving a zeroed UnguessableToken is a security issue.
  if (high == 0 && low == 0)
    return false;

  *r = base::UnguessableToken::Deserialize(high, low);
  return true;
}

void ParamTraits<base::UnguessableToken>::Log(const param_type& p,
                                              std::string* l) {
  l->append(p.ToString());
}

void ParamTraits<IPC::ChannelHandle>::Write(base::Pickle* m,
                                            const param_type& p) {
#if defined(OS_NACL_SFI)
  WriteParam(m, p.socket);
#else
  WriteParam(m, p.mojo_handle);
#endif
}

bool ParamTraits<IPC::ChannelHandle>::Read(const base::Pickle* m,
                                           base::PickleIterator* iter,
                                           param_type* r) {
#if defined(OS_NACL_SFI)
  return ReadParam(m, iter, &r->socket);
#else
  return ReadParam(m, iter, &r->mojo_handle);
#endif
}

void ParamTraits<IPC::ChannelHandle>::Log(const param_type& p,
                                          std::string* l) {
  l->append("ChannelHandle(");
#if defined(OS_NACL_SFI)
  ParamTraits<base::FileDescriptor>::Log(p.socket, l);
#else
  LogParam(p.mojo_handle, l);
#endif
  l->append(")");
}

void ParamTraits<LogData>::Write(base::Pickle* m, const param_type& p) {
  WriteParam(m, p.channel);
  WriteParam(m, p.routing_id);
  WriteParam(m, p.type);
  WriteParam(m, p.flags);
  WriteParam(m, p.sent);
  WriteParam(m, p.receive);
  WriteParam(m, p.dispatch);
  WriteParam(m, p.message_name);
  WriteParam(m, p.params);
}

bool ParamTraits<LogData>::Read(const base::Pickle* m,
                                base::PickleIterator* iter,
                                param_type* r) {
  return
      ReadParam(m, iter, &r->channel) &&
      ReadParam(m, iter, &r->routing_id) &&
      ReadParam(m, iter, &r->type) &&
      ReadParam(m, iter, &r->flags) &&
      ReadParam(m, iter, &r->sent) &&
      ReadParam(m, iter, &r->receive) &&
      ReadParam(m, iter, &r->dispatch) &&
      ReadParam(m, iter, &r->message_name) &&
      ReadParam(m, iter, &r->params);
}

void ParamTraits<LogData>::Log(const param_type& p, std::string* l) {
  // Doesn't make sense to implement this!
}

void ParamTraits<Message>::Write(base::Pickle* m, const Message& p) {
#if defined(OS_POSIX) || defined(OS_FUCHSIA)
  // We don't serialize the file descriptors in the nested message, so there
  // better not be any.
  DCHECK(!p.HasAttachments());
#endif

  // Don't just write out the message. This is used to send messages between
  // NaCl (Posix environment) and the browser (could be on Windows). The message
  // header formats differ between these systems (so does handle sharing, but
  // we already asserted we don't have any handles). So just write out the
  // parts of the header we use.
  //
  // Be careful also to use only explicitly-sized types. The NaCl environment
  // could be 64-bit and the host browser could be 32-bits. The nested message
  // may or may not be safe to send between 32-bit and 64-bit systems, but we
  // leave that up to the code sending the message to ensure.
  m->WriteUInt32(static_cast<uint32_t>(p.routing_id()));
  m->WriteUInt32(p.type());
  m->WriteUInt32(p.flags());
  m->WriteData(p.payload(), static_cast<uint32_t>(p.payload_size()));
}

bool ParamTraits<Message>::Read(const base::Pickle* m,
                                base::PickleIterator* iter,
                                Message* r) {
  uint32_t routing_id, type, flags;
  if (!iter->ReadUInt32(&routing_id) ||
      !iter->ReadUInt32(&type) ||
      !iter->ReadUInt32(&flags))
    return false;

  int payload_size;
  const char* payload;
  if (!iter->ReadData(&payload, &payload_size))
    return false;

  r->SetHeaderValues(static_cast<int32_t>(routing_id), type, flags);
  r->WriteBytes(payload, payload_size);
  return true;
}

void ParamTraits<Message>::Log(const Message& p, std::string* l) {
  l->append("<IPC::Message>");
}

#if defined(OS_WIN)
// Note that HWNDs/HANDLE/HCURSOR/HACCEL etc are always 32 bits, even on 64
// bit systems. That's why we use the Windows macros to convert to 32 bits.
void ParamTraits<HANDLE>::Write(base::Pickle* m, const param_type& p) {
  m->WriteInt(HandleToLong(p));
}

bool ParamTraits<HANDLE>::Read(const base::Pickle* m,
                               base::PickleIterator* iter,
                               param_type* r) {
  int32_t temp;
  if (!iter->ReadInt(&temp))
    return false;
  *r = LongToHandle(temp);
  return true;
}

void ParamTraits<HANDLE>::Log(const param_type& p, std::string* l) {
  l->append(base::StringPrintf("0x%p", p));
}

void ParamTraits<MSG>::Write(base::Pickle* m, const param_type& p) {
  m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
}

bool ParamTraits<MSG>::Read(const base::Pickle* m,
                            base::PickleIterator* iter,
                            param_type* r) {
  const char *data;
  int data_size = 0;
  bool result = iter->ReadData(&data, &data_size);
  if (result && data_size == sizeof(MSG)) {
    memcpy(r, data, sizeof(MSG));
  } else {
    result = false;
    NOTREACHED();
  }

  return result;
}

void ParamTraits<MSG>::Log(const param_type& p, std::string* l) {
  l->append("<MSG>");
}

#endif  // OS_WIN

}  // namespace IPC
