1645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Copyright 2014 The Chromium Authors. All rights reserved.
2645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Use of this source code is governed by a BSD-style license that can be
3645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// found in the LICENSE file.
4645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
5645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#ifndef MOJO_PUBLIC_CPP_BINDINGS_MESSAGE_H_
6645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#define MOJO_PUBLIC_CPP_BINDINGS_MESSAGE_H_
7645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
8645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include <stddef.h>
9645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include <stdint.h>
10645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
11645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include <limits>
12645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include <memory>
13645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include <string>
14645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include <vector>
15645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
16645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "base/logging.h"
17645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "mojo/public/cpp/bindings/lib/message_buffer.h"
18645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "mojo/public/cpp/bindings/lib/message_internal.h"
19645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "mojo/public/cpp/system/message.h"
20645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
21645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chaveznamespace mojo {
22645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
23645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Message is a holder for the data and handles to be sent over a MessagePipe.
24645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Message owns its data and handles, but a consumer of Message is free to
25645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// mutate the data and handles. The message's data is comprised of a header
26645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// followed by payload.
27645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezclass Message {
28645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez public:
29645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  static const uint32_t kFlagExpectsResponse = 1 << 0;
30645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  static const uint32_t kFlagIsResponse = 1 << 1;
31645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  static const uint32_t kFlagIsSync = 1 << 2;
32645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
33645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  Message();
34645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ~Message();
35645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
36645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Initializes a Message with enough space for |capacity| bytes.
37645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  void Initialize(size_t capacity, bool zero_initialized);
38645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
39645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Initializes a Message from an existing Mojo MessageHandle.
40645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  void InitializeFromMojoMessage(ScopedMessageHandle message,
41645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                 uint32_t num_bytes,
42645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                 std::vector<Handle>* handles);
43645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
44645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Transfers data and handles to |destination|.
45645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  void MoveTo(Message* destination);
46645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
47645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  uint32_t data_num_bytes() const { return buffer_->data_num_bytes(); }
48645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
49645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Access the raw bytes of the message.
50645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  const uint8_t* data() const {
51645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    return static_cast<const uint8_t*>(buffer_->data());
52645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  }
53645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
54645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  uint8_t* mutable_data() { return static_cast<uint8_t*>(buffer_->data()); }
55645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
56645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Access the header.
57645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  const internal::MessageHeader* header() const {
58645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    return static_cast<const internal::MessageHeader*>(buffer_->data());
59645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  }
60645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
61645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  internal::MessageHeader* header() {
62645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    return const_cast<internal::MessageHeader*>(
63645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        static_cast<const Message*>(this)->header());
64645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  }
65645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
66645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  uint32_t interface_id() const { return header()->interface_id; }
67645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  void set_interface_id(uint32_t id) { header()->interface_id = id; }
68645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
69645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  uint32_t name() const { return header()->name; }
70645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  bool has_flag(uint32_t flag) const { return !!(header()->flags & flag); }
71645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
72645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Access the request_id field (if present).
73645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  bool has_request_id() const { return header()->version >= 1; }
74645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  uint64_t request_id() const {
75645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    DCHECK(has_request_id());
76645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    return static_cast<const internal::MessageHeaderWithRequestID*>(
77645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez               header())->request_id;
78645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  }
79645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  void set_request_id(uint64_t request_id) {
80645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    DCHECK(has_request_id());
81645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    static_cast<internal::MessageHeaderWithRequestID*>(header())
82645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        ->request_id = request_id;
83645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  }
84645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
85645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Access the payload.
86645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  const uint8_t* payload() const { return data() + header()->num_bytes; }
87645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  uint8_t* mutable_payload() { return const_cast<uint8_t*>(payload()); }
88645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  uint32_t payload_num_bytes() const {
89645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    DCHECK(buffer_->data_num_bytes() >= header()->num_bytes);
90645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    size_t num_bytes = buffer_->data_num_bytes() - header()->num_bytes;
91645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    DCHECK(num_bytes <= std::numeric_limits<uint32_t>::max());
92645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    return static_cast<uint32_t>(num_bytes);
93645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  }
94645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
95645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Access the handles.
96645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  const std::vector<Handle>* handles() const { return &handles_; }
97645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  std::vector<Handle>* mutable_handles() { return &handles_; }
98645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
99645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Access the underlying Buffer interface.
100645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  internal::Buffer* buffer() { return buffer_.get(); }
101645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
102645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Takes a scoped MessageHandle which may be passed to |WriteMessageNew()| for
103645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // transmission. Note that this invalidates this Message object, taking
104645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // ownership of its internal storage and any attached handles.
105645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ScopedMessageHandle TakeMojoMessage();
106645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
107645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Notifies the system that this message is "bad," in this case meaning it was
108645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // rejected by bindings validation code.
109645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  void NotifyBadMessage(const std::string& error);
110645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
111645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez private:
112645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  void CloseHandles();
113645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
114645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  std::unique_ptr<internal::MessageBuffer> buffer_;
115645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  std::vector<Handle> handles_;
116645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
117645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  DISALLOW_COPY_AND_ASSIGN(Message);
118645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez};
119645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
120645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezclass MessageReceiver {
121645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez public:
122645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  virtual ~MessageReceiver() {}
123645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
124645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // The receiver may mutate the given message.  Returns true if the message
125645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // was accepted and false otherwise, indicating that the message was invalid
126645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // or malformed.
127645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  virtual bool Accept(Message* message) WARN_UNUSED_RESULT = 0;
128645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez};
129645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
130645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezclass MessageReceiverWithResponder : public MessageReceiver {
131645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez public:
132645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ~MessageReceiverWithResponder() override {}
133645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
134645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // A variant on Accept that registers a MessageReceiver (known as the
135645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // responder) to handle the response message generated from the given
136645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // message. The responder's Accept method may be called during
137645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // AcceptWithResponder or some time after its return.
138645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  //
139645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // NOTE: Upon returning true, AcceptWithResponder assumes ownership of
140645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // |responder| and will delete it after calling |responder->Accept| or upon
141645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // its own destruction.
142645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  //
143645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // TODO(yzshen): consider changing |responder| to
144645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // std::unique_ptr<MessageReceiver>.
145645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  virtual bool AcceptWithResponder(Message* message, MessageReceiver* responder)
146645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      WARN_UNUSED_RESULT = 0;
147645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez};
148645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
149645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// A MessageReceiver that is also able to provide status about the state
150645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// of the underlying MessagePipe to which it will be forwarding messages
151645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// received via the |Accept()| call.
152645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezclass MessageReceiverWithStatus : public MessageReceiver {
153645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez public:
154645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ~MessageReceiverWithStatus() override {}
155645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
156645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Returns |true| if this MessageReceiver is currently bound to a MessagePipe,
157645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // the pipe has not been closed, and the pipe has not encountered an error.
158645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  virtual bool IsValid() = 0;
159645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
160645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // DCHECKs if this MessageReceiver is currently bound to a MessagePipe, the
161645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // pipe has not been closed, and the pipe has not encountered an error.
162645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // This function may be called on any thread.
163645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  virtual void DCheckInvalid(const std::string& message) = 0;
164645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez};
165645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
166645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// An alternative to MessageReceiverWithResponder for cases in which it
167645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// is necessary for the implementor of this interface to know about the status
168645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// of the MessagePipe which will carry the responses.
169645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezclass MessageReceiverWithResponderStatus : public MessageReceiver {
170645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez public:
171645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ~MessageReceiverWithResponderStatus() override {}
172645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
173645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // A variant on Accept that registers a MessageReceiverWithStatus (known as
174645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // the responder) to handle the response message generated from the given
175645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // message. Any of the responder's methods (Accept or IsValid) may be called
176645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // during  AcceptWithResponder or some time after its return.
177645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  //
178645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // NOTE: Upon returning true, AcceptWithResponder assumes ownership of
179645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // |responder| and will delete it after calling |responder->Accept| or upon
180645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // its own destruction.
181645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  //
182645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // TODO(yzshen): consider changing |responder| to
183645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // std::unique_ptr<MessageReceiver>.
184645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  virtual bool AcceptWithResponder(Message* message,
185645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                   MessageReceiverWithStatus* responder)
186645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      WARN_UNUSED_RESULT = 0;
187645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez};
188645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
189645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Read a single message from the pipe. The caller should have created the
190645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Message, but not called Initialize(). Returns MOJO_RESULT_SHOULD_WAIT if
191645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// the caller should wait on the handle to become readable. Returns
192645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// MOJO_RESULT_OK if the message was read successfully and should be
193645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// dispatched, otherwise returns an error code if something went wrong.
194645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez//
195645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// NOTE: The message hasn't been validated and may be malformed!
196645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector ChavezMojoResult ReadMessage(MessagePipeHandle handle, Message* message);
197645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
198645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}  // namespace mojo
199645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
200645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#endif  // MOJO_PUBLIC_CPP_BINDINGS_MESSAGE_H_
201