// Copyright 2016 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. #ifndef MOJO_PUBLIC_CPP_SYSTEM_MESSAGE_H_ #define MOJO_PUBLIC_CPP_SYSTEM_MESSAGE_H_ #include <limits> #include <vector> #include "base/macros.h" #include "base/numerics/safe_conversions.h" #include "base/strings/string_piece.h" #include "mojo/public/c/system/message_pipe.h" #include "mojo/public/cpp/system/handle.h" namespace mojo { const MojoMessageHandle kInvalidMessageHandleValue = MOJO_MESSAGE_HANDLE_INVALID; // Handle wrapper base class for a |MojoMessageHandle|. class MessageHandle { public: MessageHandle() : value_(kInvalidMessageHandleValue) {} explicit MessageHandle(MojoMessageHandle value) : value_(value) {} ~MessageHandle() {} void swap(MessageHandle& other) { MojoMessageHandle temp = value_; value_ = other.value_; other.value_ = temp; } bool is_valid() const { return value_ != kInvalidMessageHandleValue; } const MojoMessageHandle& value() const { return value_; } MojoMessageHandle* mutable_value() { return &value_; } void set_value(MojoMessageHandle value) { value_ = value; } void Close() { DCHECK(is_valid()); MojoResult result = MojoDestroyMessage(value_); ALLOW_UNUSED_LOCAL(result); DCHECK_EQ(MOJO_RESULT_OK, result); } private: MojoMessageHandle value_; }; using ScopedMessageHandle = ScopedHandleBase<MessageHandle>; inline MojoResult CreateMessage(ScopedMessageHandle* handle) { MojoMessageHandle raw_handle; MojoResult rv = MojoCreateMessage(nullptr, &raw_handle); if (rv != MOJO_RESULT_OK) return rv; handle->reset(MessageHandle(raw_handle)); return MOJO_RESULT_OK; } inline MojoResult GetMessageData(MessageHandle message, void** buffer, uint32_t* num_bytes, std::vector<ScopedHandle>* handles, MojoGetMessageDataFlags flags) { DCHECK(message.is_valid()); DCHECK(num_bytes); DCHECK(buffer); uint32_t num_handles = 0; MojoGetMessageDataOptions options; options.struct_size = sizeof(options); options.flags = flags; MojoResult rv = MojoGetMessageData(message.value(), &options, buffer, num_bytes, nullptr, &num_handles); if (rv != MOJO_RESULT_RESOURCE_EXHAUSTED) { if (handles) handles->clear(); return rv; } handles->resize(num_handles); return MojoGetMessageData(message.value(), &options, buffer, num_bytes, reinterpret_cast<MojoHandle*>(handles->data()), &num_handles); } inline MojoResult NotifyBadMessage(MessageHandle message, const base::StringPiece& error) { DCHECK(message.is_valid()); DCHECK(base::IsValueInRangeForNumericType<uint32_t>(error.size())); return MojoNotifyBadMessage(message.value(), error.data(), static_cast<uint32_t>(error.size()), nullptr); } } // namespace mojo #endif // MOJO_PUBLIC_CPP_SYSTEM_MESSAGE_H_