Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 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.bindings.Struct.DataHeader; | |
| 8 | |
| 9 import java.nio.ByteBuffer; | |
| 10 | |
| 11 /** | |
| 12 * Header information for a message. | |
| 13 */ | |
| 14 public class MessageHeader { | |
| 15 | |
| 16 private static final int SIMPLE_MESSAGE_SIZE = 16; | |
| 17 private static final int SIMPLE_MESSAGE_NUM_FIELDS = 2; | |
| 18 private static final DataHeader SIMPLE_MESSAGE_STRUCT_INFO = | |
| 19 new DataHeader(SIMPLE_MESSAGE_SIZE, SIMPLE_MESSAGE_NUM_FIELDS); | |
| 20 | |
| 21 private static final int MESSAGE_WITH_REQUEST_ID_SIZE = 24; | |
| 22 private static final int MESSAGE_WITH_REQUEST_ID_NUM_FIELDS = 3; | |
| 23 private static final DataHeader MESSAGE_WITH_REQUEST_ID_STRUCT_INFO = | |
| 24 new DataHeader(MESSAGE_WITH_REQUEST_ID_SIZE, MESSAGE_WITH_REQUEST_ID _NUM_FIELDS); | |
| 25 | |
| 26 private static final int TYPE_OFFSET = 8; | |
| 27 private static final int FLAGS_OFFSET = 12; | |
| 28 private static final int REQUEST_ID_OFFSET = 16; | |
| 29 | |
| 30 /** | |
| 31 * Flag for a header of a message that expected a response. | |
| 32 */ | |
| 33 public static final int MESSAGE_EXPECTS_RESPONSE_FLAG = 1 << 0; | |
| 34 | |
| 35 /** | |
| 36 * Flag for a header of a message that is a response. | |
| 37 */ | |
| 38 public static final int MESSAGE_IS_RESPONSE_FLAG = 1 << 1; | |
| 39 | |
| 40 private final DataHeader mDataHeader; | |
| 41 private final int mType; | |
| 42 private final int mFlags; | |
| 43 private long mRequestId; | |
| 44 | |
| 45 /** | |
| 46 * Constructor for the header of a message which does not have a response. | |
| 47 */ | |
| 48 public MessageHeader(int type, int flags) { | |
|
rmcilroy
2014/07/16 15:06:44
I think the flags should are always be zero here -
qsr
2014/07/16 15:58:38
Done.
| |
| 49 assert !mustHaveRequestId(flags); | |
| 50 mDataHeader = SIMPLE_MESSAGE_STRUCT_INFO; | |
| 51 mType = type; | |
| 52 mFlags = flags; | |
| 53 mRequestId = 0; | |
| 54 } | |
| 55 | |
| 56 /** | |
| 57 * Constructor for the header of a message which have a response or being it self a response. | |
| 58 */ | |
| 59 public MessageHeader(int type, int flags, long requestId) { | |
| 60 assert mustHaveRequestId(flags); | |
| 61 mDataHeader = MESSAGE_WITH_REQUEST_ID_STRUCT_INFO; | |
| 62 mType = type; | |
| 63 mFlags = flags; | |
| 64 mRequestId = requestId; | |
| 65 } | |
| 66 | |
| 67 /** | |
| 68 * Constructor, parsing the header from a message. Should only be used by {@ link Message} | |
| 69 * itself. | |
| 70 */ | |
| 71 MessageHeader(Message message) { | |
| 72 Decoder decoder = new Decoder(message); | |
| 73 mDataHeader = decoder.readDataHeader(); | |
| 74 validateDataHeader(mDataHeader); | |
| 75 mType = decoder.readInt(TYPE_OFFSET); | |
| 76 mFlags = decoder.readInt(FLAGS_OFFSET); | |
| 77 if (mustHaveRequestId(mFlags)) { | |
| 78 if (mDataHeader.size < MESSAGE_WITH_REQUEST_ID_SIZE) { | |
| 79 throw new DeserializationException("Incorrect message size, expe cting at least " | |
| 80 + MESSAGE_WITH_REQUEST_ID_SIZE | |
| 81 + " for a message with a request identifier, but got: " + mDataHeader.size); | |
| 82 | |
| 83 } | |
| 84 mRequestId = decoder.readLong(REQUEST_ID_OFFSET); | |
| 85 } else { | |
| 86 mRequestId = 0; | |
| 87 } | |
| 88 } | |
| 89 | |
| 90 public int getSize() { | |
|
rmcilroy
2014/07/16 15:06:44
javadoc
qsr
2014/07/16 15:58:38
Done.
| |
| 91 return mDataHeader.size; | |
| 92 } | |
| 93 | |
| 94 /** | |
| 95 * Returns the type of the message. | |
| 96 */ | |
| 97 public int getType() { | |
| 98 return mType; | |
| 99 } | |
| 100 | |
| 101 /** | |
| 102 * Returns the flags associated to the message. | |
| 103 */ | |
| 104 public int getFlags() { | |
| 105 return mFlags; | |
| 106 } | |
| 107 | |
| 108 /** | |
| 109 * Returns if the message has the given flag. | |
| 110 */ | |
| 111 public boolean hasFlag(int flag) { | |
| 112 return (mFlags & flag) == flag; | |
| 113 } | |
| 114 | |
| 115 /** | |
| 116 * Returns if the message has a request id. | |
| 117 */ | |
| 118 public boolean hasRequestId() { | |
| 119 return mustHaveRequestId(mFlags); | |
| 120 } | |
| 121 | |
| 122 /** | |
| 123 * Return the request id for the message. Must only be called if the message has a request id. | |
| 124 */ | |
| 125 public long getRequestId() { | |
| 126 assert hasRequestId(); | |
| 127 return mRequestId; | |
| 128 } | |
| 129 | |
| 130 /** | |
| 131 * Encode the header. | |
| 132 */ | |
| 133 public void encode(Encoder encoder) { | |
| 134 encoder.encode(mDataHeader); | |
| 135 encoder.encode(getType(), TYPE_OFFSET); | |
| 136 encoder.encode(getFlags(), FLAGS_OFFSET); | |
| 137 if (hasRequestId()) { | |
| 138 encoder.encode(getRequestId(), REQUEST_ID_OFFSET); | |
| 139 } | |
| 140 } | |
| 141 | |
| 142 /** | |
| 143 * Returns true if the header has the expected flags. Only considers flags t his class knows | |
| 144 * about in order to allow this class to work with future version of the hea der format. | |
| 145 */ | |
| 146 public boolean validateHeader(int expectedFlags) { | |
| 147 int knownFlags = getFlags() & (MESSAGE_EXPECTS_RESPONSE_FLAG | MESSAGE_I S_RESPONSE_FLAG); | |
| 148 return knownFlags == expectedFlags; | |
| 149 } | |
| 150 | |
| 151 /** | |
| 152 * Returns true if the header has the expected type and flags. Only consider flags this class | |
| 153 * knows about in order to allow this class to work with future version of t he header format. | |
| 154 */ | |
| 155 public boolean validateHeader(int expectedType, int expectedFlags) { | |
| 156 return getType() == expectedType && validateHeader(expectedFlags); | |
| 157 } | |
| 158 | |
| 159 /** | |
| 160 * @see Object#hashCode() | |
| 161 */ | |
| 162 @Override | |
| 163 public int hashCode() { | |
| 164 final int prime = 31; | |
| 165 int result = 1; | |
| 166 result = prime * result + ((mDataHeader == null) ? 0 : mDataHeader.hashC ode()); | |
| 167 result = prime * result + mFlags; | |
| 168 result = prime * result + (int) (mRequestId ^ (mRequestId >>> 32)); | |
| 169 result = prime * result + mType; | |
| 170 return result; | |
| 171 } | |
| 172 | |
| 173 /** | |
| 174 * @see Object#equals(Object) | |
| 175 */ | |
| 176 @Override | |
| 177 public boolean equals(Object object) { | |
| 178 if (this == object) | |
| 179 return true; | |
| 180 if (object == null) | |
| 181 return false; | |
| 182 if (getClass() != object.getClass()) | |
| 183 return false; | |
| 184 MessageHeader other = (MessageHeader) object; | |
| 185 if (mDataHeader == null) { | |
| 186 if (other.mDataHeader != null) | |
| 187 return false; | |
| 188 } else if (!mDataHeader.equals(other.mDataHeader)) | |
| 189 return false; | |
| 190 if (mFlags != other.mFlags) | |
| 191 return false; | |
| 192 if (mRequestId != other.mRequestId) | |
| 193 return false; | |
| 194 if (mType != other.mType) | |
| 195 return false; | |
| 196 return true; | |
|
rmcilroy
2014/07/16 15:06:44
nit - I think this would be cleaner as:
if (objec
qsr
2014/07/16 15:58:38
Didn't remove the new line, because my auto-format
rmcilroy
2014/07/16 16:50:01
In that case you can do:
Objects.equals(mDataHea
qsr
2014/07/17 07:56:52
Done.
| |
| 197 } | |
| 198 | |
| 199 /** | |
| 200 * Set the request id on the message contained in the given buffer. | |
| 201 */ | |
| 202 void setRequestId(ByteBuffer buffer, long requestId) { | |
| 203 assert mustHaveRequestId(buffer.getInt(FLAGS_OFFSET)); | |
| 204 buffer.putLong(REQUEST_ID_OFFSET, requestId); | |
| 205 mRequestId = requestId; | |
| 206 } | |
| 207 | |
| 208 /** | |
| 209 * Returns whether a message with the given flags must have a request Id. | |
| 210 */ | |
| 211 private static boolean mustHaveRequestId(int flags) { | |
| 212 return (flags & (MESSAGE_EXPECTS_RESPONSE_FLAG | MESSAGE_IS_RESPONSE_FLA G)) != 0; | |
| 213 } | |
| 214 | |
| 215 /** | |
| 216 * Validate that the given {@link DataHeader} can be the data header of a me ssage header. | |
| 217 */ | |
| 218 private static void validateDataHeader(DataHeader dataHeader) { | |
| 219 if (dataHeader.numFields < SIMPLE_MESSAGE_NUM_FIELDS) { | |
| 220 throw new DeserializationException( | |
| 221 "Incorrect number of fields, expecting at least " + SIMPLE_M ESSAGE_NUM_FIELDS | |
| 222 + ", but got: " + dataHeader.numFields); | |
| 223 } | |
| 224 if (dataHeader.size < SIMPLE_MESSAGE_SIZE) { | |
| 225 throw new DeserializationException( | |
| 226 "Incorrect message size, expecting at least " + SIMPLE_MESSA GE_SIZE | |
| 227 + ", but got: " + dataHeader.size); | |
| 228 } | |
| 229 if (dataHeader.numFields == SIMPLE_MESSAGE_NUM_FIELDS | |
| 230 && dataHeader.size != SIMPLE_MESSAGE_SIZE) { | |
| 231 throw new DeserializationException( | |
| 232 "Incorrect message size for a message with " + SIMPLE_MESSAG E_NUM_FIELDS | |
| 233 + " fields, expecting " + SIMPLE_MESSAGE_SIZE + ", but got: " | |
| 234 + dataHeader.size); | |
| 235 } | |
| 236 if (dataHeader.numFields == MESSAGE_WITH_REQUEST_ID_NUM_FIELDS | |
| 237 && dataHeader.size != MESSAGE_WITH_REQUEST_ID_SIZE) { | |
| 238 throw new DeserializationException( | |
| 239 "Incorrect message size for a message with " | |
| 240 + MESSAGE_WITH_REQUEST_ID_NUM_FIELDS + " fields, expecting " | |
| 241 + MESSAGE_WITH_REQUEST_ID_SIZE + ", but got: " + dataHeader. size); | |
| 242 } | |
| 243 } | |
| 244 | |
| 245 } | |
| OLD | NEW |