Upstream version 10.38.222.0
[platform/framework/web/crosswalk.git] / src / mojo / public / java / bindings / src / org / chromium / mojo / bindings / MessageWithHeader.java
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 package org.chromium.mojo.bindings;
6
7 import org.chromium.mojo.system.MessagePipeHandle;
8 import org.chromium.mojo.system.MessagePipeHandle.ReadMessageResult;
9 import org.chromium.mojo.system.MojoResult;
10
11 import java.nio.ByteBuffer;
12 import java.nio.ByteOrder;
13
14 /**
15  * Represents a {@link Message} which contains a {@link MessageHeader}. Deals with parsing the
16  * {@link MessageHeader} for a message.
17  */
18 public class MessageWithHeader {
19
20     private final Message mBaseMessage;
21     private final MessageHeader mHeader;
22     private Message mPayload;
23
24     /**
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.
27      */
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;
32     }
33
34     /**
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.
37      */
38     public MessageWithHeader(Message baseMessage) {
39         this(baseMessage, new org.chromium.mojo.bindings.MessageHeader(baseMessage));
40     }
41
42     /**
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.
45      */
46     public MessageHeader getHeader() {
47         return mHeader;
48     }
49
50     /**
51      * Returns the payload of the message.
52      */
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);
59         }
60         return mPayload;
61     }
62
63     /**
64      * Returns the raw message.
65      */
66     public Message getMessage() {
67         return mBaseMessage;
68     }
69
70     /**
71      * Set the request identifier on the message.
72      */
73     void setRequestId(long requestId) {
74         mHeader.setRequestId(mBaseMessage.buffer, requestId);
75     }
76
77     /**
78      * Read a message, and pass it to the given |MessageReceiver| if not null. If the
79      * |MessageReceiver| is null, the message is lost.
80      *
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.
83      */
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();
89         }
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())));
95         }
96         return result.getMojoResult();
97     }
98 }