1 // Copyright 2016 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef MOJO_PUBLIC_CPP_SYSTEM_MESSAGE_H_ 6 #define MOJO_PUBLIC_CPP_SYSTEM_MESSAGE_H_ 7 8 #include <limits> 9 #include <vector> 10 11 #include "base/macros.h" 12 #include "base/numerics/safe_conversions.h" 13 #include "base/strings/string_piece.h" 14 #include "mojo/public/c/system/message_pipe.h" 15 #include "mojo/public/cpp/system/handle.h" 16 17 namespace mojo { 18 19 const MojoMessageHandle kInvalidMessageHandleValue = 20 MOJO_MESSAGE_HANDLE_INVALID; 21 22 // Handle wrapper base class for a |MojoMessageHandle|. 23 class MessageHandle { 24 public: 25 MessageHandle() : value_(kInvalidMessageHandleValue) {} 26 explicit MessageHandle(MojoMessageHandle value) : value_(value) {} 27 ~MessageHandle() {} 28 29 void swap(MessageHandle& other) { 30 MojoMessageHandle temp = value_; 31 value_ = other.value_; 32 other.value_ = temp; 33 } 34 35 bool is_valid() const { return value_ != kInvalidMessageHandleValue; } 36 37 const MojoMessageHandle& value() const { return value_; } 38 MojoMessageHandle* mutable_value() { return &value_; } 39 void set_value(MojoMessageHandle value) { value_ = value; } 40 41 void Close() { 42 DCHECK(is_valid()); 43 MojoResult result = MojoDestroyMessage(value_); 44 ALLOW_UNUSED_LOCAL(result); 45 DCHECK_EQ(MOJO_RESULT_OK, result); 46 } 47 48 private: 49 MojoMessageHandle value_; 50 }; 51 52 using ScopedMessageHandle = ScopedHandleBase<MessageHandle>; 53 54 inline MojoResult CreateMessage(ScopedMessageHandle* handle) { 55 MojoMessageHandle raw_handle; 56 MojoResult rv = MojoCreateMessage(nullptr, &raw_handle); 57 if (rv != MOJO_RESULT_OK) 58 return rv; 59 60 handle->reset(MessageHandle(raw_handle)); 61 return MOJO_RESULT_OK; 62 } 63 64 inline MojoResult GetMessageData(MessageHandle message, 65 void** buffer, 66 uint32_t* num_bytes, 67 std::vector<ScopedHandle>* handles, 68 MojoGetMessageDataFlags flags) { 69 DCHECK(message.is_valid()); 70 DCHECK(num_bytes); 71 DCHECK(buffer); 72 uint32_t num_handles = 0; 73 74 MojoGetMessageDataOptions options; 75 options.struct_size = sizeof(options); 76 options.flags = flags; 77 MojoResult rv = MojoGetMessageData(message.value(), &options, buffer, 78 num_bytes, nullptr, &num_handles); 79 if (rv != MOJO_RESULT_RESOURCE_EXHAUSTED) { 80 if (handles) 81 handles->clear(); 82 return rv; 83 } 84 85 handles->resize(num_handles); 86 return MojoGetMessageData(message.value(), &options, buffer, num_bytes, 87 reinterpret_cast<MojoHandle*>(handles->data()), 88 &num_handles); 89 } 90 91 inline MojoResult NotifyBadMessage(MessageHandle message, 92 const base::StringPiece& error) { 93 DCHECK(message.is_valid()); 94 DCHECK(base::IsValueInRangeForNumericType<uint32_t>(error.size())); 95 return MojoNotifyBadMessage(message.value(), error.data(), 96 static_cast<uint32_t>(error.size()), nullptr); 97 } 98 99 } // namespace mojo 100 101 #endif // MOJO_PUBLIC_CPP_SYSTEM_MESSAGE_H_ 102