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 <assert.h> 9 10 #include <vector> 11 12 #include "mojo/public/cpp/bindings/lib/message_internal.h" 13 14 namespace mojo { 15 16 // Message is a holder for the data and handles to be sent over a MessagePipe. 17 // Message owns its data and handles, but a consumer of Message is free to 18 // mutate the data and handles. The message's data is comprised of a header 19 // followed by payload. 20 class Message { 21 public: 22 Message(); 23 ~Message(); 24 25 // These may only be called on a newly created Message object. 26 void AllocUninitializedData(uint32_t num_bytes); 27 void AdoptData(uint32_t num_bytes, internal::MessageData* data); 28 29 // Swaps data and handles between this Message and another. 30 void Swap(Message* other); 31 32 uint32_t data_num_bytes() const { return data_num_bytes_; } 33 34 // Access the raw bytes of the message. 35 const uint8_t* data() const { return 36 reinterpret_cast<const uint8_t*>(data_); 37 } 38 uint8_t* mutable_data() { return reinterpret_cast<uint8_t*>(data_); } 39 40 // Access the header. 41 const internal::MessageHeader* header() const { return &data_->header; } 42 43 uint32_t name() const { return data_->header.name; } 44 bool has_flag(uint32_t flag) const { return !!(data_->header.flags & flag); } 45 46 // Access the request_id field (if present). 47 bool has_request_id() const { return data_->header.num_fields >= 3; } 48 uint64_t request_id() const { 49 assert(has_request_id()); 50 return static_cast<const internal::MessageHeaderWithRequestID*>( 51 &data_->header)->request_id; 52 } 53 void set_request_id(uint64_t request_id) { 54 assert(has_request_id()); 55 static_cast<internal::MessageHeaderWithRequestID*>(&data_->header)-> 56 request_id = request_id; 57 } 58 59 // Access the payload. 60 const uint8_t* payload() const { 61 return reinterpret_cast<const uint8_t*>(data_) + data_->header.num_bytes; 62 } 63 uint8_t* mutable_payload() { 64 return reinterpret_cast<uint8_t*>(data_) + data_->header.num_bytes; 65 } 66 uint32_t payload_num_bytes() const { 67 assert(data_num_bytes_ >= data_->header.num_bytes); 68 return data_num_bytes_ - data_->header.num_bytes; 69 } 70 71 // Access the handles. 72 const std::vector<Handle>* handles() const { return &handles_; } 73 std::vector<Handle>* mutable_handles() { return &handles_; } 74 75 private: 76 uint32_t data_num_bytes_; 77 internal::MessageData* data_; // Heap-allocated using malloc. 78 std::vector<Handle> handles_; 79 80 MOJO_DISALLOW_COPY_AND_ASSIGN(Message); 81 }; 82 83 class MessageReceiver { 84 public: 85 virtual ~MessageReceiver() {} 86 87 // The receiver may mutate the given message. Returns true if the message 88 // was accepted and false otherwise, indicating that the message was invalid 89 // or malformed. 90 virtual bool Accept(Message* message) MOJO_WARN_UNUSED_RESULT = 0; 91 }; 92 93 class MessageReceiverWithResponder : public MessageReceiver { 94 public: 95 virtual ~MessageReceiverWithResponder() {} 96 97 // A variant on Accept that registers a MessageReceiver (known as the 98 // responder) to handle the response message generated from the given 99 // message. The responder's Accept method may be called during 100 // AcceptWithResponder or some time after its return. 101 // 102 // NOTE: Upon returning true, AcceptWithResponder assumes ownership of 103 // |responder| and will delete it after calling |responder->Accept| or upon 104 // its own destruction. 105 // 106 virtual bool AcceptWithResponder( 107 Message* message, MessageReceiver* responder) MOJO_WARN_UNUSED_RESULT = 0; 108 }; 109 110 // Read a single message from the pipe and dispatch to the given receiver. The 111 // receiver may be null, in which case the message is simply discarded. 112 // Returns MOJO_RESULT_SHOULD_WAIT if the caller should wait on the handle to 113 // become readable. Returns MOJO_RESULT_OK if a message was dispatched and 114 // otherwise returns an error code if something went wrong. 115 // 116 // NOTE: The message hasn't been validated and may be malformed! 117 MojoResult ReadAndDispatchMessage(MessagePipeHandle handle, 118 MessageReceiver* receiver, 119 bool* receiver_result); 120 121 } // namespace mojo 122 123 #endif // MOJO_PUBLIC_CPP_BINDINGS_MESSAGE_H_ 124