Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: mojo/public/dart/src/codec.dart

Issue 703273002: Update mojo sdk to rev 04a510fb37db10642e156957f9b2c11c2f6442ac (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix content/child -> mojo/common linking Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « mojo/public/dart/bindings.dart ('k') | mojo/public/js/BUILD.gn » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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 const int kAlignment = 8;
8 const int kArrayHeaderSize = 8;
9 const int kStructHeaderSize = 8;
10 const int kMessageHeaderSize = 16;
11 const int kMessageWithRequestIDHeaderSize = 24;
12 const int kMapStructPayloadSize = 16;
13 const int kStructHeaderNumBytesOffset = 0;
14 const int kStructHeaderNumFieldsOffset = 4;
15 const int kEncodedInvalidHandleValue = 0xffffffff;
16 const String kErrorUnsigned = "Passing negative value to unsigned encoder";
17
18
19 int align(int size) => size + (kAlignment - (size % kAlignment)) % kAlignment;
20 bool isAligned(offset) => (offset >= 0) && ((offset % kAlignment) == 0);
21
22
23 Uint8List utf8OfString(String s) =>
24 (new Uint8List.fromList((const Utf8Encoder()).convert(s)));
25
26
27 String stringOfUtf8(Uint8List bytes) =>
28 (const Utf8Decoder()).convert(bytes.toList());
29
30
31 // Given an argument that is either a Type or an instance:
32 // Invoke the static method "decode" of the Type, or the instance method
33 // "decode" of the instance, on the MojoDecoder.
34 Object _callDecode(Object typeOrInstance, MojoDecoder decoder) {
35 if (typeOrInstance is Type) {
36 return reflectClass(typeOrInstance).invoke(#decode, [decoder]).reflectee;
37 } else {
38 return typeOrInstance.decode(decoder);
39 }
40 }
41
42
43 // Given an argument that is either a Type or an instance:
44 // Invoke the static method "encode" of the Type, or the instance method
45 // "encode" of the instance, on the MojoEncoder and value to be encoded.
46 void _callEncode(Object typeOrInstance, MojoEncoder encoder, Object val) {
47 if (typeOrInstance is Type) {
48 reflectClass(typeOrInstance).invoke(#encode, [encoder, val]);
49 } else {
50 typeOrInstance.encode(encoder, val);
51 }
52 }
53
54
55 // Given an argument that is either a Type or an instance:
56 // Invoke the static getter "encodedSize" of the Type, or the instance getter
57 // "encodedSize" of the instance, and return the result.
58 int getEncodedSize(Object typeOrInstance) {
59 if (typeOrInstance is Type) {
60 return reflectClass(typeOrInstance).getField(#encodedSize).reflectee;
61 } else {
62 return typeOrInstance.encodedSize;
63 }
64 }
65
66
67 class MojoDecoder {
68 ByteData buffer;
69 List<int> handles;
70 int base;
71 int next;
72
73 MojoDecoder(this.buffer, this.handles, this.base) {
74 next = base;
75 }
76
77 void skip(int offset) {
78 next += offset;
79 }
80
81 int readInt8() {
82 int result = buffer.getInt8(next);
83 next += 1;
84 return result;
85 }
86
87 int readUint8() {
88 int result = buffer.getUint8(next);
89 next += 1;
90 return result;
91 }
92
93 int readInt16() {
94 int result = buffer.getInt16(next, Endianness.LITTLE_ENDIAN);
95 next += 2;
96 return result;
97 }
98
99 int readUint16() {
100 int result = buffer.getUint16(next, Endianness.LITTLE_ENDIAN);
101 next += 2;
102 return result;
103 }
104
105 int readInt32() {
106 int result = buffer.getInt32(next, Endianness.LITTLE_ENDIAN);
107 next += 4;
108 return result;
109 }
110
111 int readUint32() {
112 int result = buffer.getUint32(next, Endianness.LITTLE_ENDIAN);
113 next += 4;
114 return result;
115 }
116
117 int readInt64() {
118 int result = buffer.getInt64(next, Endianness.LITTLE_ENDIAN);
119 next += 8;
120 return result;
121 }
122
123 int readUint64() {
124 int result = buffer.getUint64(next, Endianness.LITTLE_ENDIAN);
125 next += 8;
126 return result;
127 }
128
129 double readFloat() {
130 double result = buffer.getFloat32(next,Endianness.LITTLE_ENDIAN);
131 next += 4;
132 return result;
133 }
134
135 double readDouble() {
136 double result = buffer.getFloat64(next, Endianness.LITTLE_ENDIAN);
137 next += 8;
138 return result;
139 }
140
141 int decodePointer() {
142 int offsetPointer = next;
143 int offset = readUint64();
144 if (offset == 0) {
145 return 0;
146 }
147 return offsetPointer + offset;
148 }
149
150 MojoDecoder decodeAndCreateDecoder(int offset) {
151 return new MojoDecoder(buffer, handles, offset);
152 }
153
154 int decodeHandle() {
155 return handles[readUint32()];
156 }
157
158 String decodeString() {
159 int numBytes = readUint32();
160 int numElements = readUint32();
161 int base = next;
162 next += numElements;
163 return stringOfUtf8(buffer.buffer.asUint8List(base, numElements));
164 }
165
166 List decodeArray(Object type) {
167 int numBytes = readUint32();
168 int numElements = readUint32();
169 if (type == PackedBool) {
170 int b;
171 List<bool> result = new List<bool>(numElements);
172 for (int i = 0; i < numElements; i++) {
173 if ((i % 8) == 0) {
174 b = readUint8();
175 }
176 result[i] = ((b & (1 << (i % 8)) != 0) ? true : false);
177 }
178 return result;
179 } else {
180 List result = new List(numElements);
181 for (int i = 0; i < numElements; i++) {
182 result[i] = _callDecode(type, this);
183 }
184 return result;
185 }
186 }
187
188 Object decodeStruct(Object t) {
189 return _callDecode(t, this);
190 }
191
192 Object decodeStructPointer(Object t) {
193 int pointer = decodePointer();
194 if (pointer == 0) {
195 return null;
196 }
197 return _callDecode(t, decodeAndCreateDecoder(pointer));
198 }
199
200 List decodeArrayPointer(Object type) {
201 int pointer = decodePointer();
202 if (pointer == 0) {
203 return null;
204 }
205 return decodeAndCreateDecoder(pointer).decodeArray(type);
206 }
207
208 String decodeStringPointer() {
209 int pointer = decodePointer();
210 if (pointer == 0) {
211 return null;
212 }
213 return decodeAndCreateDecoder(pointer).decodeString();
214 }
215
216 Map decodeMap(Object keyType, Object valType) {
217 skip(4); // number of bytes.
218 skip(4); // number of fields.
219 List keys = decodeArrayPointer(keyType);
220 List values = decodeArrayPointer(valType);
221 return new Map.fromIterables(keys, values);
222 }
223
224 Map decodeMapPointer(Object keyType, Object valType) {
225 int pointer = this.decodePointer();
226 if (pointer == 0) {
227 return null;
228 }
229 MojoDecoder decoder = decodeAndCreateDecoder(pointer);
230 return decoder.decodeMap(keyType, valType);
231 }
232 }
233
234
235 class MojoEncoder {
236 ByteData buffer;
237 List<int> handles;
238 int base;
239 int next;
240 int extent;
241
242 MojoEncoder(this.buffer, this.handles, this.base, this.extent) {
243 next = base;
244 }
245
246 void skip(int offset) {
247 next += offset;
248 }
249
250 void writeInt8(int val) {
251 buffer.setInt8(next, val);
252 next += 1;
253 }
254
255 void writeUint8(int val) {
256 if (val < 0) {
257 throw new ArgumentError("$kErrorUnsigned: $val");
258 }
259 buffer.setUint8(next, val);
260 next += 1;
261 }
262
263 void writeInt16(int val) {
264 buffer.setInt16(next, val, Endianness.LITTLE_ENDIAN);
265 next += 2;
266 }
267
268 void writeUint16(int val) {
269 if (val < 0) {
270 throw new ArgumentError("$kErrorUnsigned: $val");
271 }
272 buffer.setUint16(next, val, Endianness.LITTLE_ENDIAN);
273 next += 2;
274 }
275
276 void writeInt32(int val) {
277 buffer.setInt32(next, val, Endianness.LITTLE_ENDIAN);
278 next += 4;
279 }
280
281 void writeUint32(int val) {
282 if (val < 0) {
283 throw new ArgumentError("$kErrorUnsigned: $val");
284 }
285 buffer.setUint32(next, val, Endianness.LITTLE_ENDIAN);
286 next += 4;
287 }
288
289 void writeInt64(int val) {
290 buffer.setInt64(next, val, Endianness.LITTLE_ENDIAN);
291 next += 8;
292 }
293
294 void writeUint64(int val) {
295 if (val < 0) {
296 throw new ArgumentError("$kErrorUnsigned: $val");
297 }
298 buffer.setUint64(next, val, Endianness.LITTLE_ENDIAN);
299 next += 8;
300 }
301
302 void writeFloat(double val) {
303 buffer.setFloat32(next, val, Endianness.LITTLE_ENDIAN);
304 next += 4;
305 }
306
307 void writeDouble(double val) {
308 buffer.setFloat64(next, val, Endianness.LITTLE_ENDIAN);
309 next += 8;
310 }
311
312 void encodePointer(int pointer) {
313 if (pointer == null) {
314 writeUint64(0);
315 return;
316 }
317 int offset = pointer - next;
318 writeUint64(offset);
319 }
320
321 void grow(int new_size) {
322 Uint8List new_buffer = new Uint8List(new_size);
323 new_buffer.setRange(0, next, buffer.buffer.asUint8List());
324 buffer = new_buffer.buffer.asByteData();
325 }
326
327 int alloc(int size_request) {
328 int pointer = extent;
329 extent += size_request;
330 if (extent > buffer.lengthInBytes) {
331 int new_size = buffer.lengthInBytes + size_request;
332 new_size += new_size ~/ 2;
333 grow(new_size);
334 }
335 return pointer;
336 }
337
338 MojoEncoder createAndEncodeEncoder(int size) {
339 int pointer = alloc(align(size));
340 encodePointer(pointer);
341 return new MojoEncoder(buffer, handles, pointer, extent);
342 }
343
344 void encodeHandle(int handle) {
345 handles.add(handle);
346 writeUint32(handles.length - 1);
347 }
348
349 void encodeString(String val) {
350 Uint8List utf8string = utf8OfString(val);
351 int numElements = utf8string.lengthInBytes;
352 int numBytes = kArrayHeaderSize + numElements;
353 writeUint32(numBytes);
354 writeUint32(numElements);
355 buffer.buffer.asUint8List().setRange(next, next + numElements, utf8string);
356 next += numElements;
357 }
358
359 void encodeArray(Object t, List val, [int numElements, int encodedSize]) {
360 if (numElements == null) {
361 numElements = val.length;
362 }
363 if (encodedSize == null) {
364 encodedSize = kArrayHeaderSize + (getEncodedSize(t) * numElements);
365 }
366
367 writeUint32(encodedSize);
368 writeUint32(numElements);
369
370 if (t == PackedBool) {
371 int b = 0;
372 for (int i = 0; i < numElements; i++) {
373 if (val[i]) {
374 b |= (1 << (i % 8));
375 }
376 if (((i % 8) == 7) || (i == (numElements - 1))) {
377 Uint8.encode(this, b);
378 }
379 }
380 } else {
381 for (int i = 0; i < numElements; i++) {
382 _callEncode(t, this, val[i]);
383 }
384 }
385 }
386
387 void encodeStruct(Object t, Object val) {
388 _callEncode(t, this, val);
389 }
390
391 void encodeStructPointer(Object t, Object val) {
392 if (val == null) {
393 encodePointer(val);
394 return;
395 }
396 MojoEncoder encoder = createAndEncodeEncoder(getEncodedSize(t));
397 _callEncode(t, encoder, val);
398 extent = encoder.extent;
399 buffer = encoder.buffer;
400 }
401
402 void encodeArrayPointer(Object t, List val) {
403 if (val == null) {
404 encodePointer(val);
405 return;
406 }
407 int numElements = val.length;
408 int encodedSize = kArrayHeaderSize + ((t == PackedBool) ?
409 (numElements / 8).ceil() : (getEncodedSize(t) * numElements));
410 MojoEncoder encoder = createAndEncodeEncoder(encodedSize);
411 encoder.encodeArray(t, val, numElements, encodedSize);
412 extent = encoder.extent;
413 buffer = encoder.buffer;
414 }
415
416 void encodeStringPointer(String val) {
417 if (val == null) {
418 encodePointer(val);
419 return;
420 }
421 int encodedSize = kArrayHeaderSize + utf8OfString(val).lengthInBytes;
422 MojoEncoder encoder = createAndEncodeEncoder(encodedSize);
423 encoder.encodeString(val);
424 extent = encoder.extent;
425 buffer = encoder.buffer;
426 }
427
428 void encodeMap(Object keyType, Object valType, Map val) {
429 List keys = val.keys;
430 List vals = val.values;
431 writeUint32(kStructHeaderSize + kMapStructPayloadSize);
432 writeUint32(2);
433 encodeArrayPointer(keyType, keys);
434 encodeArrayPointer(valType, vals);
435 }
436
437 void encodeMapPointer(Object keyTYpe, Object valType, Map val) {
438 if (val == null) {
439 encodePointer(val);
440 return;
441 }
442 int encodedSize = kStructHeaderSize + kMapStructPayloadSize;
443 MojoEncoder encoder = createAndEncodeEncoder(encodedSize);
444 encoder.encodeMap(keyType, valType, val);
445 extent = encoder.extent;
446 buffer = encoder.buffer;
447 }
448 }
449
450
451 const int kMessageNameOffset = kStructHeaderSize;
452 const int kMessageFlagsOffset = kMessageNameOffset + 4;
453 const int kMessageRequestIDOffset = kMessageFlagsOffset + 4;
454 const int kMessageExpectsResponse = 1 << 0;
455 const int kMessageIsResponse = 1 << 1;
456
457 class Message {
458 ByteData buffer;
459 List<int> handles;
460
461 Message(this.buffer, this.handles);
462
463 int getHeaderNumBytes() => buffer.getUint32(kStructHeaderNumBytesOffset);
464 int getHeaderNumFields() => buffer.getUint32(kStructHeaderNumFieldsOffset);
465 int getName() => buffer.getUint32(kMessageNameOffset);
466 int getFlags() => buffer.getUint32(kMessageFlagsOffset);
467 bool isResponse() => (getFlags() & kMessageIsResponse) != 0;
468 bool expectsResponse() => (getFlags() & kMessageExpectsResponse) != 0;
469
470 void setRequestID(int id) {
471 buffer.setUint64(kMessageRequestIDOffset, id);
472 }
473 }
474
475
476 class MessageBuilder {
477 MojoEncoder encoder;
478 List<int> handles;
479
480 MessageBuilder(int name, int payloadSize) {
481 int numBytes = kMessageHeaderSize + payloadSize;
482 var buffer = new ByteData(numBytes);
483 handles = [];
484
485 encoder = new MojoEncoder(buffer, handles, 0, kMessageHeaderSize);
486 encoder.writeUint32(kMessageHeaderSize);
487 encoder.writeUint32(2); // num_fields;
488 encoder.writeUint32(name);
489 encoder.writeUint32(0); // flags.
490 }
491
492 MojoEncoder createEncoder(int size) {
493 encoder = new MojoEncoder(encoder.buffer,
494 handles,
495 encoder.next,
496 encoder.next + size);
497 return encoder;
498 }
499
500 void encodeStruct(Object t, Object val) {
501 encoder = createEncoder(getEncodedSize(t));
502 _callEncode(t, encoder, val);
503 }
504
505 ByteData _trimBuffer() {
506 return new ByteData.view(encoder.buffer.buffer, 0, encoder.extent);
507 }
508
509 Message finish() {
510 Message message = new Message(_trimBuffer(), handles);
511 encoder = null;
512 handles = null;
513 return message;
514 }
515 }
516
517
518 class MessageWithRequestIDBuilder extends MessageBuilder {
519 MessageWithRequestIDBuilder(
520 int name, int payloadSize, int flags, int requestID) {
521 int numBytes = kMessageWithRequestIDHeaderSize + payloadSize;
522 buffer = new ByteData(numBytes);
523 handles = [];
524 base = 0;
525
526 encoder = createEncoder(0, kMessageWithRequestIDHeaderSize);
527 encoder.writeUint32(kMessageWithRequestIDHeaderSize);
528 encoder.writeUint32(3); // num_fields.
529 encoder.writeUint32(name);
530 encoder.writeUint32(flags);
531 encoder.writeUint64(requestID);
532 base = encoder.next;
533 buffer = encoder.buffer;
534 }
535 }
536
537
538 class MessageReader {
539 MojoDecoder decoder;
540 int payloadSize;
541 int name;
542 int flags;
543 int requestID;
544
545 MessageReader(Message message) {
546 decoder = new MojoDecoder(message.buffer, message.handles, 0);
547
548 int messageHeaderSize = decoder.readUint32();
549 payloadSize = message.buffer.lengthInBytes - messageHeaderSize;
550
551 int num_fields = decoder.readUint32();
552 name = decoder.readUint32();
553 flags = decoder.readUint32();
554
555 if (num_fields >= 3) {
556 requestID = decoder.readUint64();
557 }
558 decoder.skip(messageHeaderSize - decoder.next);
559 }
560
561 Object decodeStruct(Object t) => _callDecode(t, decoder);
562 }
563
564
565 abstract class MojoType<T> {
566 static const int encodedSize = 0;
567 static T decode(MojoDecoder decoder) { return null }
568 static void encode(MojoEncoder encoder, T val) {}
569 }
570
571
572 class PackedBool {}
573
574
575 class Int8 implements MojoType<int> {
576 static const int encodedSize = 1;
577 static int decode(MojoDecoder decoder) => decoder.readInt8();
578 static void encode(MojoEncoder encoder, int val) {
579 encoder.writeInt8(val);
580 }
581 }
582
583
584 class Uint8 implements MojoType<int> {
585 static const int encodedSize = 1;
586 static int decode(MojoDecoder decoder) => decoder.readUint8();
587 static void encode(MojoEncoder encoder, int val) {
588 encoder.writeUint8(val);
589 }
590 }
591
592
593 class Int16 implements MojoType<int> {
594 static const int encodedSize = 2;
595 static int decode(MojoDecoder decoder) => decoder.readInt16();
596 static void encode(MojoEncoder encoder, int val) {
597 encoder.writeInt16(val);
598 }
599 }
600
601
602 class Uint16 implements MojoType<int> {
603 static const int encodedSize = 2;
604 static int decode(MojoDecoder decoder) => decoder.readUint16();
605 static void encode(MojoEncoder encoder, int val) {
606 encoder.writeUint16(val);
607 }
608 }
609
610
611 class Int32 implements MojoType<int> {
612 static const int encodedSize = 4;
613 static int decode(MojoDecoder decoder) => decoder.readInt32();
614 static void encode(MojoEncoder encoder, int val) {
615 encoder.writeInt32(val);
616 }
617 }
618
619
620 class Uint32 implements MojoType<int> {
621 static const int encodedSize = 4;
622 static int decode(MojoDecoder decoder) => decoder.readUint32();
623 static void encode(MojoEncoder encoder, int val) {
624 encoder.writeUint32(val);
625 }
626 }
627
628
629 class Int64 implements MojoType<int> {
630 static const int encodedSize = 8;
631 static int decode(MojoDecoder decoder) => decoder.readInt64();
632 static void encode(MojoEncoder encoder, int val) {
633 encoder.writeInt64(val);
634 }
635 }
636
637
638 class Uint64 implements MojoType<int> {
639 static const int encodedSize = 8;
640 static int decode(MojoDecoder decoder) => decoder.readUint64();
641 static void encode(MojoEncoder encoder, int val) {
642 encoder.writeUint64(val);
643 }
644 }
645
646
647 class MojoString implements MojoType<String> {
648 static const int encodedSize = 8;
649 static String decode(MojoDecoder decoder) => decoder.decodeStringPointer();
650 static void encode(MojoEncoder encoder, String val) {
651 encoder.encodeStringPointer(val);
652 }
653 }
654
655
656 class NullableMojoString implements MojoType<String> {
657 static const int encodedSize = MojoString.encodedSize;
658 static var decode = MojoString.decode;
659 static var encode = MojoString.encode;
660 }
661
662
663 class Float implements MojoType<double> {
664 static const int encodedSize = 4;
665 static double decode(MojoDecoder decoder) => decoder.readFloat();
666 static void encode(MojoEncoder encoder, double val) {
667 encoder.writeFloat(val);
668 }
669 }
670
671
672 class Double implements MojoType<double> {
673 static const int encodedSize = 8;
674 static double decode(MojoDecoder decoder) => decoder.readDouble();
675 static void encode(MojoEncoder encoder, double val) {
676 encoder.writeDouble(val);
677 }
678 }
679
680
681 class PointerTo {
682 Object val;
683
684 PointerTo(this.val);
685
686 int encodedSize = 8;
687 Object decode(MojoDecoder decoder) {
688 int pointer = decoder.decodePointer();
689 if (pointer == 0) {
690 return null;
691 }
692 return _callDecode(val, decoder.decodeAndCreateDecoder(pointer));
693 }
694 void encode(MojoEncoder encoder, Object val) {
695 if (val == null) {
696 encoder.encodePointer(val);
697 return;
698 }
699 MojoEncoder obj_encoder =
700 encoder.createAndEncodeEncoder(getEncodedSize(this.val));
701 _callEncode(this.val, obj_encoder, val);
702 }
703 }
704
705
706 class NullablePointerTo extends PointerTo {
707 static const int encodedSize = PointerTo.encodedSize;
708 }
709
710
711 class ArrayOf {
712 Object val;
713 int length;
714
715 ArrayOf(this.val, [this.length = 0]);
716
717 int dimensions() => [length].addAll((val is ArrayOf) ? val.dimensions() : []);
718
719 int encodedSize = 8;
720 List decode(MojoDecoder decoder) => decoder.decodeArrayPointer(val);
721 void encode(MojoEncoder encoder, List val) {
722 encoder.encodeArrayPointer(this.val, val);
723 }
724 }
725
726
727 class NullableArrayOf extends ArrayOf {
728 static const int encodedSize = ArrayOf.encodedSize;
729 }
730
731
732 class Handle implements MojoType<int> {
733 static const int encodedSize = 4;
734 static int decode(MojoDecoder decoder) => decoder.decodeHandle();
735 static void encode(MojoEncoder encoder, int val) {
736 encoder.encodeHandle(val);
737 }
738 }
739
740
741 class NullableHandle implements MojoType<int> {
742 static const int encodedSize = Handle.encodedSize;
743 static const decode = Handle.decode;
744 static const encode = Handle.encode;
745 }
OLDNEW
« no previous file with comments | « mojo/public/dart/bindings.dart ('k') | mojo/public/js/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698