| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 part of bindings; | 5 part of bindings; |
| 6 | 6 |
| 7 class MessageHeader { | 7 class MessageHeader { |
| 8 static const int kSimpleMessageSize = 16; | 8 static const int kSimpleMessageSize = 16; |
| 9 // TODO(yzshen): In order to work with other bindings which still interprets | 9 // TODO(yzshen): In order to work with other bindings which still interprets |
| 10 // the |version| field as |num_fields|, set it to version 2 for now. | 10 // the |version| field as |num_fields|, set it to version 2 for now. |
| 11 static const int kSimpleMessageVersion = 2; | 11 static const int kSimpleMessageVersion = 2; |
| 12 static const int kMessageWithRequestIdSize = 24; | 12 static const int kMessageWithRequestIdSize = 24; |
| 13 // TODO(yzshen): In order to work with other bindings which still interprets | 13 // TODO(yzshen): In order to work with other bindings which still interprets |
| 14 // the |version| field as |num_fields|, set it to version 3 for now. | 14 // the |version| field as |num_fields|, set it to version 3 for now. |
| 15 static const int kMessageWithRequestIdVersion = 3; | 15 static const int kMessageWithRequestIdVersion = 3; |
| 16 static const int kMessageTypeOffset = StructDataHeader.kHeaderSize; | 16 static const int kMessageTypeOffset = StructDataHeader.kHeaderSize; |
| 17 static const int kMessageFlagsOffset = kMessageTypeOffset + 4; | 17 static const int kMessageFlagsOffset = kMessageTypeOffset + 4; |
| 18 static const int kMessageRequestIdOffset = kMessageFlagsOffset + 4; | 18 static const int kMessageRequestIdOffset = kMessageFlagsOffset + 4; |
| 19 static const int kMessageExpectsResponse = 1 << 0; | 19 static const int kMessageExpectsResponse = 1 << 0; |
| 20 static const int kMessageIsResponse = 1 << 1; | 20 static const int kMessageIsResponse = 1 << 1; |
| 21 | 21 |
| 22 StructDataHeader _header; | 22 StructDataHeader _header; |
| 23 int type; | 23 int type; |
| 24 int flags; | 24 int flags; |
| 25 int requestId; | 25 int requestId; |
| 26 | 26 |
| 27 static bool mustHaveRequestId(int flags) => | 27 static bool mustHaveRequestId(int flags) => |
| 28 (flags & (kMessageExpectsResponse | kMessageIsResponse)) != 0; | 28 (flags & (kMessageExpectsResponse | kMessageIsResponse)) != 0; |
| 29 | 29 |
| 30 MessageHeader(this.type) : | 30 MessageHeader(this.type) |
| 31 _header = new StructDataHeader(kSimpleMessageSize, kSimpleMessageVersion), | 31 : _header = new StructDataHeader( |
| 32 flags = 0, | 32 kSimpleMessageSize, kSimpleMessageVersion), |
| 33 requestId = 0; | 33 flags = 0, |
| 34 requestId = 0; |
| 34 | 35 |
| 35 MessageHeader.withRequestId(this.type, this.flags, this.requestId) : | 36 MessageHeader.withRequestId(this.type, this.flags, this.requestId) |
| 36 _header = new StructDataHeader( | 37 : _header = new StructDataHeader( |
| 37 kMessageWithRequestIdSize, kMessageWithRequestIdVersion); | 38 kMessageWithRequestIdSize, kMessageWithRequestIdVersion); |
| 38 | 39 |
| 39 MessageHeader.fromMessage(Message message) { | 40 MessageHeader.fromMessage(Message message) { |
| 40 var decoder = new Decoder(message); | 41 var decoder = new Decoder(message); |
| 41 _header = decoder.decodeStructDataHeader(); | 42 _header = decoder.decodeStructDataHeader(); |
| 42 if (_header.size < kSimpleMessageSize) { | 43 if (_header.size < kSimpleMessageSize) { |
| 43 throw new MojoCodecError( | 44 throw new MojoCodecError('Incorrect message size. Got: ${_header.size} ' |
| 44 'Incorrect message size. Got: ${_header.size} ' | |
| 45 'wanted $kSimpleMessageSize'); | 45 'wanted $kSimpleMessageSize'); |
| 46 } | 46 } |
| 47 type = decoder.decodeUint32(kMessageTypeOffset); | 47 type = decoder.decodeUint32(kMessageTypeOffset); |
| 48 flags = decoder.decodeUint32(kMessageFlagsOffset); | 48 flags = decoder.decodeUint32(kMessageFlagsOffset); |
| 49 if (mustHaveRequestId(flags)) { | 49 if (mustHaveRequestId(flags)) { |
| 50 if (_header.size < kMessageWithRequestIdSize) { | 50 if (_header.size < kMessageWithRequestIdSize) { |
| 51 throw new MojoCodecError( | 51 throw new MojoCodecError('Incorrect message size. Got: ${_header.size} ' |
| 52 'Incorrect message size. Got: ${_header.size} ' | |
| 53 'wanted $kMessageWithRequestIdSize'); | 52 'wanted $kMessageWithRequestIdSize'); |
| 54 } | 53 } |
| 55 requestId = decoder.decodeUint64(kMessageRequestIdOffset); | 54 requestId = decoder.decodeUint64(kMessageRequestIdOffset); |
| 56 } else { | 55 } else { |
| 57 requestId = 0; | 56 requestId = 0; |
| 58 } | 57 } |
| 59 } | 58 } |
| 60 | 59 |
| 61 int get size => _header.size; | 60 int get size => _header.size; |
| 62 bool get hasRequestId => mustHaveRequestId(flags); | 61 bool get hasRequestId => mustHaveRequestId(flags); |
| 63 | 62 |
| 64 void encode(Encoder encoder) { | 63 void encode(Encoder encoder) { |
| 65 encoder.encodeStructDataHeader(_header); | 64 encoder.encodeStructDataHeader(_header); |
| 66 encoder.encodeUint32(type, kMessageTypeOffset); | 65 encoder.encodeUint32(type, kMessageTypeOffset); |
| 67 encoder.encodeUint32(flags, kMessageFlagsOffset); | 66 encoder.encodeUint32(flags, kMessageFlagsOffset); |
| 68 if (hasRequestId) { | 67 if (hasRequestId) { |
| 69 encoder.encodeUint64(requestId, kMessageRequestIdOffset); | 68 encoder.encodeUint64(requestId, kMessageRequestIdOffset); |
| 70 } | 69 } |
| 71 } | 70 } |
| 72 | 71 |
| 73 ServiceMessage get serviceMessage => new ServiceMessage(this); | |
| 74 | |
| 75 String toString() => "MessageHeader($_header, $type, $flags, $requestId)"; | 72 String toString() => "MessageHeader($_header, $type, $flags, $requestId)"; |
| 76 | 73 |
| 77 bool validateHeaderFlags(expectedFlags) => | 74 bool validateHeaderFlags(expectedFlags) => |
| 78 (flags & (kMessageExpectsResponse | kMessageIsResponse)) == expectedFlags; | 75 (flags & (kMessageExpectsResponse | kMessageIsResponse)) == expectedFlags; |
| 79 | 76 |
| 80 bool validateHeader(int expectedType, int expectedFlags) => | 77 bool validateHeader(int expectedType, int expectedFlags) => |
| 81 (type == expectedType) && validateHeaderFlags(expectedFlags); | 78 (type == expectedType) && validateHeaderFlags(expectedFlags); |
| 82 | 79 |
| 83 static void _validateDataHeader(StructDataHeader dataHeader) { | 80 static void _validateDataHeader(StructDataHeader dataHeader) { |
| 84 if (dataHeader.version < kSimpleMessageVersion) { | 81 if (dataHeader.version < kSimpleMessageVersion) { |
| 85 throw 'Incorrect version, expecting at least ' | 82 throw 'Incorrect version, expecting at least ' |
| 86 '$kSimpleMessageVersion, but got: ${dataHeader.version}.'; | 83 '$kSimpleMessageVersion, but got: ${dataHeader.version}.'; |
| 87 } | 84 } |
| 88 if (dataHeader.size < kSimpleMessageSize) { | 85 if (dataHeader.size < kSimpleMessageSize) { |
| 89 throw 'Incorrect message size, expecting at least $kSimpleMessageSize, ' | 86 throw 'Incorrect message size, expecting at least $kSimpleMessageSize, ' |
| 90 'but got: ${dataHeader.size}'; | 87 'but got: ${dataHeader.size}'; |
| 91 } | 88 } |
| 92 if ((dataHeader.version == kSimpleMessageVersion) && | 89 if ((dataHeader.version == kSimpleMessageVersion) && |
| 93 (dataHeader.size != kSimpleMessageSize)) { | 90 (dataHeader.size != kSimpleMessageSize)) { |
| 94 throw 'Incorrect message size for a message of version ' | 91 throw 'Incorrect message size for a message of version ' |
| 95 '$kSimpleMessageVersion, expecting $kSimpleMessageSize, ' | 92 '$kSimpleMessageVersion, expecting $kSimpleMessageSize, ' |
| 96 'but got ${dataHeader.size}'; | 93 'but got ${dataHeader.size}'; |
| 97 } | 94 } |
| 98 if ((dataHeader.version == kMessageWithRequestIdVersion) && | 95 if ((dataHeader.version == kMessageWithRequestIdVersion) && |
| 99 (dataHeader.size != kMessageWithRequestIdSize)) { | 96 (dataHeader.size != kMessageWithRequestIdSize)) { |
| 100 throw 'Incorrect message size for a message of version ' | 97 throw 'Incorrect message size for a message of version ' |
| 101 '$kMessageWithRequestIdVersion, expecting ' | 98 '$kMessageWithRequestIdVersion, expecting ' |
| 102 '$kMessageWithRequestIdSize, but got ${dataHeader.size}'; | 99 '$kMessageWithRequestIdSize, but got ${dataHeader.size}'; |
| 103 } | 100 } |
| 104 } | 101 } |
| 105 } | 102 } |
| 106 | 103 |
| 107 | |
| 108 class Message { | 104 class Message { |
| 109 final ByteData buffer; | 105 final ByteData buffer; |
| 110 final List<core.MojoHandle> handles; | 106 final List<core.MojoHandle> handles; |
| 111 Message(this.buffer, this.handles); | 107 Message(this.buffer, this.handles); |
| 112 String toString() => | 108 String toString() => |
| 113 "Message(numBytes=${buffer.lengthInBytes}, numHandles=${handles.length})"; | 109 "Message(numBytes=${buffer.lengthInBytes}, numHandles=${handles.length})"; |
| 114 } | 110 } |
| 115 | 111 |
| 116 | |
| 117 class ServiceMessage extends Message { | 112 class ServiceMessage extends Message { |
| 118 final MessageHeader header; | 113 final MessageHeader header; |
| 119 Message _payload; | 114 Message _payload; |
| 120 | 115 |
| 121 ServiceMessage(Message message, this.header) | 116 ServiceMessage(Message message, this.header) |
| 122 : super(message.buffer, message.handles); | 117 : super(message.buffer, message.handles); |
| 123 | 118 |
| 124 ServiceMessage.fromMessage(Message message) | 119 ServiceMessage.fromMessage(Message message) |
| 125 : this(message, new MessageHeader.fromMessage(message)); | 120 : this(message, new MessageHeader.fromMessage(message)); |
| 126 | 121 |
| 127 Message get payload { | 122 Message get payload { |
| 128 if (_payload == null) { | 123 if (_payload == null) { |
| 129 var truncatedBuffer = new ByteData.view(buffer.buffer, header.size); | 124 var truncatedBuffer = new ByteData.view(buffer.buffer, header.size); |
| 130 _payload = new Message(truncatedBuffer, handles); | 125 _payload = new Message(truncatedBuffer, handles); |
| 131 } | 126 } |
| 132 return _payload; | 127 return _payload; |
| 133 } | 128 } |
| 134 | 129 |
| 135 String toString() => "ServiceMessage($header, $_payload)"; | 130 String toString() => "ServiceMessage($header, $_payload)"; |
| 136 } | 131 } |
| OLD | NEW |