summaryrefslogtreecommitdiffstats
path: root/ipc/chromium/src/chrome/common/ipc_message.cc
diff options
context:
space:
mode:
Diffstat (limited to 'ipc/chromium/src/chrome/common/ipc_message.cc')
-rw-r--r--ipc/chromium/src/chrome/common/ipc_message.cc218
1 files changed, 218 insertions, 0 deletions
diff --git a/ipc/chromium/src/chrome/common/ipc_message.cc b/ipc/chromium/src/chrome/common/ipc_message.cc
new file mode 100644
index 0000000000..5343c67fc0
--- /dev/null
+++ b/ipc/chromium/src/chrome/common/ipc_message.cc
@@ -0,0 +1,218 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+// Copyright (c) 2006-2008 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 "chrome/common/ipc_message.h"
+
+#include "base/logging.h"
+#include "build/build_config.h"
+#include "mojo/core/ports/event.h"
+
+#include <utility>
+
+#include "nsISupportsImpl.h"
+
+namespace IPC {
+
+//------------------------------------------------------------------------------
+
+const mojo::core::ports::UserMessage::TypeInfo Message::kUserMessageTypeInfo{};
+
+Message::~Message() { MOZ_COUNT_DTOR(IPC::Message); }
+
+Message::Message(int32_t routing_id, msgid_t type, uint32_t segment_capacity,
+ HeaderFlags flags)
+ : UserMessage(&kUserMessageTypeInfo),
+ Pickle(sizeof(Header), segment_capacity) {
+ MOZ_COUNT_CTOR(IPC::Message);
+ header()->routing = routing_id;
+ header()->type = type;
+ header()->flags = flags;
+ header()->num_handles = 0;
+ header()->txid = -1;
+ header()->seqno = 0;
+#if defined(OS_MACOSX)
+ header()->cookie = 0;
+ header()->num_send_rights = 0;
+#endif
+ header()->event_footer_size = 0;
+}
+
+Message::Message(const char* data, int data_len)
+ : UserMessage(&kUserMessageTypeInfo),
+ Pickle(sizeof(Header), data, data_len) {
+ MOZ_COUNT_CTOR(IPC::Message);
+}
+
+/*static*/ mozilla::UniquePtr<Message> Message::IPDLMessage(
+ int32_t routing_id, msgid_t type, uint32_t segment_capacity,
+ HeaderFlags flags) {
+ return mozilla::MakeUnique<Message>(routing_id, type, segment_capacity,
+ flags);
+}
+
+/*static*/ mozilla::UniquePtr<Message> Message::ForSyncDispatchError(
+ NestedLevel level) {
+ auto m = mozilla::MakeUnique<Message>(0, 0, 0, HeaderFlags(level));
+ auto& flags = m->header()->flags;
+ flags.SetSync();
+ flags.SetReply();
+ flags.SetReplyError();
+ return m;
+}
+
+void Message::WriteFooter(const void* data, uint32_t data_len) {
+ if (data_len == 0) {
+ return;
+ }
+
+ WriteBytes(data, data_len);
+}
+
+bool Message::ReadFooter(void* buffer, uint32_t buffer_len, bool truncate) {
+ if (buffer_len == 0) {
+ return true;
+ }
+
+ if (NS_WARN_IF(AlignInt(header()->payload_size) != header()->payload_size) ||
+ NS_WARN_IF(AlignInt(buffer_len) > header()->payload_size)) {
+ return false;
+ }
+
+ // Seek to the start of the footer, and read it in. We read in with a
+ // duplicate of the iterator so we can use it to truncate later.
+ uint32_t offset = header()->payload_size - AlignInt(buffer_len);
+ PickleIterator footer_iter(*this);
+ if (NS_WARN_IF(!IgnoreBytes(&footer_iter, offset))) {
+ return false;
+ }
+
+ PickleIterator read_iter(footer_iter);
+ bool ok = ReadBytesInto(&read_iter, buffer, buffer_len);
+
+ // If requested, truncate the buffer to the start of the footer.
+ if (truncate) {
+ Truncate(&footer_iter);
+ }
+ return ok;
+}
+
+bool Message::WriteFileHandle(mozilla::UniqueFileHandle handle) {
+ uint32_t handle_index = attached_handles_.Length();
+ WriteUInt32(handle_index);
+ if (handle_index == MAX_DESCRIPTORS_PER_MESSAGE) {
+ return false;
+ }
+ attached_handles_.AppendElement(std::move(handle));
+ return true;
+}
+
+bool Message::ConsumeFileHandle(PickleIterator* iter,
+ mozilla::UniqueFileHandle* handle) const {
+ uint32_t handle_index;
+ if (!ReadUInt32(iter, &handle_index)) {
+ return false;
+ }
+ if (handle_index >= attached_handles_.Length()) {
+ return false;
+ }
+ // NOTE: This mutates the underlying array, replacing the handle with an
+ // invalid handle.
+ *handle = std::exchange(attached_handles_[handle_index], nullptr);
+ return true;
+}
+
+void Message::SetAttachedFileHandles(
+ nsTArray<mozilla::UniqueFileHandle> handles) {
+ MOZ_DIAGNOSTIC_ASSERT(attached_handles_.IsEmpty());
+ attached_handles_ = std::move(handles);
+}
+
+uint32_t Message::num_handles() const { return attached_handles_.Length(); }
+
+void Message::WritePort(mozilla::ipc::ScopedPort port) {
+ uint32_t port_index = attached_ports_.Length();
+ WriteUInt32(port_index);
+ attached_ports_.AppendElement(std::move(port));
+}
+
+bool Message::ConsumePort(PickleIterator* iter,
+ mozilla::ipc::ScopedPort* port) const {
+ uint32_t port_index;
+ if (!ReadUInt32(iter, &port_index)) {
+ return false;
+ }
+ if (port_index >= attached_ports_.Length()) {
+ return false;
+ }
+ // NOTE: This mutates the underlying array, replacing the port with a consumed
+ // port.
+ *port = std::exchange(attached_ports_[port_index], {});
+ return true;
+}
+
+void Message::SetAttachedPorts(nsTArray<mozilla::ipc::ScopedPort> ports) {
+ MOZ_DIAGNOSTIC_ASSERT(attached_ports_.IsEmpty());
+ attached_ports_ = std::move(ports);
+}
+
+#if defined(OS_MACOSX)
+bool Message::WriteMachSendRight(mozilla::UniqueMachSendRight port) {
+ uint32_t index = attached_send_rights_.Length();
+ WriteUInt32(index);
+ if (index == MAX_DESCRIPTORS_PER_MESSAGE) {
+ return false;
+ }
+ attached_send_rights_.AppendElement(std::move(port));
+ return true;
+}
+
+bool Message::ConsumeMachSendRight(PickleIterator* iter,
+ mozilla::UniqueMachSendRight* port) const {
+ uint32_t index;
+ if (!ReadUInt32(iter, &index)) {
+ return false;
+ }
+ if (index >= attached_send_rights_.Length()) {
+ return false;
+ }
+ // NOTE: This mutates the underlying array, replacing the send right with a
+ // null right.
+ *port = std::exchange(attached_send_rights_[index], nullptr);
+ return true;
+}
+
+uint32_t Message::num_send_rights() const {
+ return attached_send_rights_.Length();
+}
+#endif
+
+bool Message::WillBeRoutedExternally(
+ mojo::core::ports::UserMessageEvent& event) {
+ if (!attached_ports_.IsEmpty()) {
+ // Explicitly attach any ports which were attached to this Message to this
+ // UserMessageEvent before we route it externally so that they can be
+ // transferred correctly. These ports will be recovered if needed in
+ // `GetMessage`.
+ MOZ_DIAGNOSTIC_ASSERT(
+ event.num_ports() == 0,
+ "Must not have previously attached ports to the UserMessageEvent");
+ event.ReservePorts(attached_ports_.Length());
+ for (size_t i = 0; i < event.num_ports(); ++i) {
+ event.ports()[i] = attached_ports_[i].Release().name();
+ }
+ attached_ports_.Clear();
+ }
+ return true;
+}
+
+void Message::AssertAsLargeAsHeader() const {
+ MOZ_DIAGNOSTIC_ASSERT(size() >= sizeof(Header));
+ MOZ_DIAGNOSTIC_ASSERT(CurrentSize() >= sizeof(Header));
+ // Our buffers should agree with what our header specifies.
+ MOZ_DIAGNOSTIC_ASSERT(size() == CurrentSize());
+}
+
+} // namespace IPC