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