1 // Copyright 2014 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_BINDINGS_MESSAGE_H_ 6 #define MOJO_PUBLIC_CPP_BINDINGS_MESSAGE_H_ 7 8 #include <stddef.h> 9 #include <stdint.h> 10 11 #include <limits> 12 #include <memory> 13 #include <string> 14 #include <vector> 15 16 #include "base/logging.h" 17 #include "mojo/public/cpp/bindings/lib/message_buffer.h" 18 #include "mojo/public/cpp/bindings/lib/message_internal.h" 19 #include "mojo/public/cpp/system/message.h" 20 21 namespace mojo { 22 23 // Message is a holder for the data and handles to be sent over a MessagePipe. 24 // Message owns its data and handles, but a consumer of Message is free to 25 // mutate the data and handles. The message's data is comprised of a header 26 // followed by payload. 27 class Message { 28 public: 29 static const uint32_t kFlagExpectsResponse = 1 << 0; 30 static const uint32_t kFlagIsResponse = 1 << 1; 31 static const uint32_t kFlagIsSync = 1 << 2; 32 33 Message(); 34 ~Message(); 35 36 // Initializes a Message with enough space for |capacity| bytes. 37 void Initialize(size_t capacity, bool zero_initialized); 38 39 // Initializes a Message from an existing Mojo MessageHandle. 40 void InitializeFromMojoMessage(ScopedMessageHandle message, 41 uint32_t num_bytes, 42 std::vector<Handle>* handles); 43 44 // Transfers data and handles to |destination|. 45 void MoveTo(Message* destination); 46 data_num_bytes()47 uint32_t data_num_bytes() const { return buffer_->data_num_bytes(); } 48 49 // Access the raw bytes of the message. data()50 const uint8_t* data() const { 51 return static_cast<const uint8_t*>(buffer_->data()); 52 } 53 mutable_data()54 uint8_t* mutable_data() { return static_cast<uint8_t*>(buffer_->data()); } 55 56 // Access the header. header()57 const internal::MessageHeader* header() const { 58 return static_cast<const internal::MessageHeader*>(buffer_->data()); 59 } 60 header()61 internal::MessageHeader* header() { 62 return const_cast<internal::MessageHeader*>( 63 static_cast<const Message*>(this)->header()); 64 } 65 interface_id()66 uint32_t interface_id() const { return header()->interface_id; } set_interface_id(uint32_t id)67 void set_interface_id(uint32_t id) { header()->interface_id = id; } 68 name()69 uint32_t name() const { return header()->name; } has_flag(uint32_t flag)70 bool has_flag(uint32_t flag) const { return !!(header()->flags & flag); } 71 72 // Access the request_id field (if present). has_request_id()73 bool has_request_id() const { return header()->version >= 1; } request_id()74 uint64_t request_id() const { 75 DCHECK(has_request_id()); 76 return static_cast<const internal::MessageHeaderWithRequestID*>( 77 header())->request_id; 78 } set_request_id(uint64_t request_id)79 void set_request_id(uint64_t request_id) { 80 DCHECK(has_request_id()); 81 static_cast<internal::MessageHeaderWithRequestID*>(header()) 82 ->request_id = request_id; 83 } 84 85 // Access the payload. payload()86 const uint8_t* payload() const { return data() + header()->num_bytes; } mutable_payload()87 uint8_t* mutable_payload() { return const_cast<uint8_t*>(payload()); } payload_num_bytes()88 uint32_t payload_num_bytes() const { 89 DCHECK(buffer_->data_num_bytes() >= header()->num_bytes); 90 size_t num_bytes = buffer_->data_num_bytes() - header()->num_bytes; 91 DCHECK(num_bytes <= std::numeric_limits<uint32_t>::max()); 92 return static_cast<uint32_t>(num_bytes); 93 } 94 95 // Access the handles. handles()96 const std::vector<Handle>* handles() const { return &handles_; } mutable_handles()97 std::vector<Handle>* mutable_handles() { return &handles_; } 98 99 // Access the underlying Buffer interface. buffer()100 internal::Buffer* buffer() { return buffer_.get(); } 101 102 // Takes a scoped MessageHandle which may be passed to |WriteMessageNew()| for 103 // transmission. Note that this invalidates this Message object, taking 104 // ownership of its internal storage and any attached handles. 105 ScopedMessageHandle TakeMojoMessage(); 106 107 // Notifies the system that this message is "bad," in this case meaning it was 108 // rejected by bindings validation code. 109 void NotifyBadMessage(const std::string& error); 110 111 private: 112 void CloseHandles(); 113 114 std::unique_ptr<internal::MessageBuffer> buffer_; 115 std::vector<Handle> handles_; 116 117 DISALLOW_COPY_AND_ASSIGN(Message); 118 }; 119 120 class MessageReceiver { 121 public: ~MessageReceiver()122 virtual ~MessageReceiver() {} 123 124 // The receiver may mutate the given message. Returns true if the message 125 // was accepted and false otherwise, indicating that the message was invalid 126 // or malformed. 127 virtual bool Accept(Message* message) WARN_UNUSED_RESULT = 0; 128 }; 129 130 class MessageReceiverWithResponder : public MessageReceiver { 131 public: ~MessageReceiverWithResponder()132 ~MessageReceiverWithResponder() override {} 133 134 // A variant on Accept that registers a MessageReceiver (known as the 135 // responder) to handle the response message generated from the given 136 // message. The responder's Accept method may be called during 137 // AcceptWithResponder or some time after its return. 138 // 139 // NOTE: Upon returning true, AcceptWithResponder assumes ownership of 140 // |responder| and will delete it after calling |responder->Accept| or upon 141 // its own destruction. 142 // 143 // TODO(yzshen): consider changing |responder| to 144 // std::unique_ptr<MessageReceiver>. 145 virtual bool AcceptWithResponder(Message* message, MessageReceiver* responder) 146 WARN_UNUSED_RESULT = 0; 147 }; 148 149 // A MessageReceiver that is also able to provide status about the state 150 // of the underlying MessagePipe to which it will be forwarding messages 151 // received via the |Accept()| call. 152 class MessageReceiverWithStatus : public MessageReceiver { 153 public: ~MessageReceiverWithStatus()154 ~MessageReceiverWithStatus() override {} 155 156 // Returns |true| if this MessageReceiver is currently bound to a MessagePipe, 157 // the pipe has not been closed, and the pipe has not encountered an error. 158 virtual bool IsValid() = 0; 159 160 // DCHECKs if this MessageReceiver is currently bound to a MessagePipe, the 161 // pipe has not been closed, and the pipe has not encountered an error. 162 // This function may be called on any thread. 163 virtual void DCheckInvalid(const std::string& message) = 0; 164 }; 165 166 // An alternative to MessageReceiverWithResponder for cases in which it 167 // is necessary for the implementor of this interface to know about the status 168 // of the MessagePipe which will carry the responses. 169 class MessageReceiverWithResponderStatus : public MessageReceiver { 170 public: ~MessageReceiverWithResponderStatus()171 ~MessageReceiverWithResponderStatus() override {} 172 173 // A variant on Accept that registers a MessageReceiverWithStatus (known as 174 // the responder) to handle the response message generated from the given 175 // message. Any of the responder's methods (Accept or IsValid) may be called 176 // during AcceptWithResponder or some time after its return. 177 // 178 // NOTE: Upon returning true, AcceptWithResponder assumes ownership of 179 // |responder| and will delete it after calling |responder->Accept| or upon 180 // its own destruction. 181 // 182 // TODO(yzshen): consider changing |responder| to 183 // std::unique_ptr<MessageReceiver>. 184 virtual bool AcceptWithResponder(Message* message, 185 MessageReceiverWithStatus* responder) 186 WARN_UNUSED_RESULT = 0; 187 }; 188 189 // Read a single message from the pipe. The caller should have created the 190 // Message, but not called Initialize(). Returns MOJO_RESULT_SHOULD_WAIT if 191 // the caller should wait on the handle to become readable. Returns 192 // MOJO_RESULT_OK if the message was read successfully and should be 193 // dispatched, otherwise returns an error code if something went wrong. 194 // 195 // NOTE: The message hasn't been validated and may be malformed! 196 MojoResult ReadMessage(MessagePipeHandle handle, Message* message); 197 198 } // namespace mojo 199 200 #endif // MOJO_PUBLIC_CPP_BINDINGS_MESSAGE_H_ 201