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.
5 package org.chromium.mojo.bindings;
7 import org.chromium.mojo.system.MessagePipeHandle;
8 import org.chromium.mojo.system.MessagePipeHandle.ReadMessageResult;
9 import org.chromium.mojo.system.MojoResult;
11 import java.nio.ByteBuffer;
12 import java.nio.ByteOrder;
15 * Represents a {@link Message} which contains a {@link MessageHeader}. Deals with parsing the
16 * {@link MessageHeader} for a message.
18 public class MessageWithHeader {
20 private final Message mBaseMessage;
21 private final MessageHeader mHeader;
22 private Message mPayload;
25 * Reinterpret the given |message| as a message with the given |header|. The |message| must
26 * contain the |header| as the start of its raw data.
28 public MessageWithHeader(Message baseMessage, MessageHeader header) {
29 assert header.equals(new org.chromium.mojo.bindings.MessageHeader(baseMessage));
30 this.mBaseMessage = baseMessage;
31 this.mHeader = header;
35 * Reinterpret the given |message| as a message with a header. The |message| must contain a
36 * header as the start of it's raw data, which will be parsed by this constructor.
38 public MessageWithHeader(Message baseMessage) {
39 this(baseMessage, new org.chromium.mojo.bindings.MessageHeader(baseMessage));
43 * Returns the header of the given message. This will throw a {@link DeserializationException}
44 * if the start of the message is not a valid header.
46 public MessageHeader getHeader() {
51 * Returns the payload of the message.
53 public Message getPayload() {
54 if (mPayload == null) {
55 ByteBuffer truncatedBuffer = ((ByteBuffer) mBaseMessage.buffer.position(
56 getHeader().getSize())).slice();
57 truncatedBuffer.order(ByteOrder.nativeOrder());
58 mPayload = new Message(truncatedBuffer, mBaseMessage.handles);
64 * Returns the raw message.
66 public Message getMessage() {
71 * Set the request identifier on the message.
73 void setRequestId(long requestId) {
74 mHeader.setRequestId(mBaseMessage.buffer, requestId);
78 * Read a message, and pass it to the given |MessageReceiver| if not null. If the
79 * |MessageReceiver| is null, the message is lost.
81 * @param receiver The {@link MessageReceiver} that will receive the read {@link Message}. Can
82 * be <code>null</code>, in which case the message is discarded.
84 public static int readAndDispatchMessage(MessagePipeHandle handle, MessageReceiver receiver) {
85 // TODO(qsr) Allow usage of a pool of pre-allocated buffer for performance.
86 ReadMessageResult result = handle.readMessage(null, 0, MessagePipeHandle.ReadFlags.NONE);
87 if (result.getMojoResult() != MojoResult.RESOURCE_EXHAUSTED) {
88 return result.getMojoResult();
90 ByteBuffer buffer = ByteBuffer.allocateDirect(result.getMessageSize());
91 result = handle.readMessage(buffer, result.getHandlesCount(),
92 MessagePipeHandle.ReadFlags.NONE);
93 if (receiver != null && result.getMojoResult() == MojoResult.OK) {
94 receiver.accept(new MessageWithHeader(new Message(buffer, result.getHandles())));
96 return result.getMojoResult();