OLD | NEW |
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 part of protobuf; | 5 part of protobuf; |
6 | 6 |
7 class CodedBufferWriter { | 7 class CodedBufferWriter { |
8 | 8 |
9 final List<TypedData> _output = <TypedData>[]; | 9 final List<TypedData> _output = <TypedData>[]; |
10 int _runningSizeInBytes = 0; | 10 int _runningSizeInBytes = 0; |
11 | 11 |
12 static final _WRITE_FUNCTION_MAP = _makeWriteFunctionMap(); | 12 static final _WRITE_FUNCTION_MAP = _makeWriteFunctionMap(); |
13 | 13 |
14 static ByteData _toVarint32(int value) { | 14 static ByteData _toVarint32(int value) { |
15 // Varint encoding always fits into 5 bytes. | 15 // Varint encoding always fits into 5 bytes. |
16 Uint8List result = new Uint8List(5); | 16 Uint8List result = new Uint8List(5); |
17 int i = 0; | 17 int i = 0; |
18 while (value >= 0x80) { | 18 while (value >= 0x80) { |
19 result[i++] = 0x80 | (value & 0x7f); | 19 result[i++] = 0x80 | (value & 0x7f); |
20 value >>= 7; | 20 value >>= 7; |
21 } | 21 } |
22 result[i++] = value; | 22 result[i++] = value; |
23 | 23 |
24 return new ByteData.view(result.buffer, 0, i); | 24 return new ByteData.view(result.buffer, 0, i); |
25 } | 25 } |
26 | 26 |
27 static ByteData _toVarint64(ByteData value) { | 27 static ByteData _toVarint64(Int64 value) { |
28 // Varint encoding always fits into 10 bytes. | 28 // Varint encoding always fits into 10 bytes. |
29 Uint8List result = new Uint8List(10); | 29 Uint8List result = new Uint8List(10); |
30 int i = 0; | 30 int i = 0; |
31 int lo = value.getUint32(0, Endianness.LITTLE_ENDIAN); | 31 ByteData bytes = |
32 int hi = value.getUint32(4, Endianness.LITTLE_ENDIAN); | 32 new ByteData.view(new Uint8List.fromList(value.toBytes()).buffer, 0, 8); |
| 33 int lo = bytes.getUint32(0, Endianness.LITTLE_ENDIAN); |
| 34 int hi = bytes.getUint32(4, Endianness.LITTLE_ENDIAN); |
33 while (hi > 0 || lo >= 0x80) { | 35 while (hi > 0 || lo >= 0x80) { |
34 result[i++] = 0x80 | (lo & 0x7f); | 36 result[i++] = 0x80 | (lo & 0x7f); |
35 lo = (lo >> 7) | ((hi & 0x7f) << 25); | 37 lo = (lo >> 7) | ((hi & 0x7f) << 25); |
36 hi >>= 7; | 38 hi >>= 7; |
37 } | 39 } |
38 result[i++] = lo; | 40 result[i++] = lo; |
39 | 41 |
40 return new ByteData.view(result.buffer, 0, i); | 42 return new ByteData.view(result.buffer, 0, i); |
41 } | 43 } |
42 | 44 |
43 static ByteData _int32ToBytes(int value) => _toVarint32(value & 0xffffffff); | 45 static ByteData _int32ToBytes(int value) => _toVarint32(value & 0xffffffff); |
44 | 46 |
45 static _makeWriteFunctionMap() { | 47 static _makeWriteFunctionMap() { |
46 writeBytesNoTag(output, List<int> value) { | 48 writeBytesNoTag(output, List<int> value) { |
47 output.writeInt32NoTag(value.length); | 49 output.writeInt32NoTag(value.length); |
48 output.writeRawBytes( | 50 output.writeRawBytes( |
49 new Uint8List(value.length)..setRange(0, value.length, value)); | 51 new Uint8List(value.length)..setRange(0, value.length, value)); |
50 } | 52 } |
51 | 53 |
52 makeWriter(convertor) => ((output, value) { | 54 makeWriter(convertor) => ((output, value) { |
53 output.writeRawBytes(convertor(value)); | 55 output.writeRawBytes(convertor(value)); |
54 }); | 56 }); |
55 | 57 |
56 int _encodeZigZag32(int value) => (value << 1) ^ (value >> 31); | 58 int _encodeZigZag32(int value) => (value << 1) ^ (value >> 31); |
57 | 59 |
58 ByteData _encodeZigZag64(ByteData value) { | 60 Int64 _encodeZigZag64(Int64 value) => (value << 1) ^ (value >> 63); |
59 int lo = value.getUint32(0, Endianness.LITTLE_ENDIAN); | 61 |
60 int hi = value.getUint32(4, Endianness.LITTLE_ENDIAN); | 62 ByteData makeByteData32(int value) => |
61 int newHi = (hi << 1) | (lo >> 31); | 63 new ByteData(4)..setUint32(0, value, Endianness.LITTLE_ENDIAN); |
62 int newLo = (lo << 1); | 64 |
63 if ((hi >> 31) == 1) { | 65 ByteData makeByteData64(Int64 value) { |
64 newHi ^= 0xffffffff; | 66 var data = new Uint8List.fromList(value.toBytes()); |
65 newLo ^= 0xffffffff; | 67 return new ByteData.view(data.buffer, 0, 8); |
66 } | |
67 return new ByteData(8) | |
68 ..setUint32(0, newLo, Endianness.LITTLE_ENDIAN) | |
69 ..setUint32(4, newHi, Endianness.LITTLE_ENDIAN); | |
70 } | 68 } |
71 | 69 |
72 | |
73 makeByteData32(int value) => | |
74 new ByteData(4)..setUint32(0, value, Endianness.LITTLE_ENDIAN); | |
75 | |
76 return new Map<int, dynamic>() | 70 return new Map<int, dynamic>() |
77 ..[GeneratedMessage._BOOL_BIT] = makeWriter( | 71 ..[GeneratedMessage._BOOL_BIT] = makeWriter( |
78 (value) => _int32ToBytes(value ? 1 : 0)) | 72 (value) => _int32ToBytes(value ? 1 : 0)) |
79 ..[GeneratedMessage._BYTES_BIT] = writeBytesNoTag | 73 ..[GeneratedMessage._BYTES_BIT] = writeBytesNoTag |
80 ..[GeneratedMessage._STRING_BIT] = (output, value) { | 74 ..[GeneratedMessage._STRING_BIT] = (output, value) { |
81 writeBytesNoTag(output, encodeUtf8(value)); | 75 writeBytesNoTag(output, encodeUtf8(value)); |
82 } | 76 } |
83 ..[GeneratedMessage._DOUBLE_BIT] = makeWriter((double value) { | 77 ..[GeneratedMessage._DOUBLE_BIT] = makeWriter((double value) { |
84 if (value.isNaN) return new ByteData(8) | 78 if (value.isNaN) return new ByteData(8) |
85 ..setUint32(0, 0x00000000, Endianness.LITTLE_ENDIAN) | 79 ..setUint32(0, 0x00000000, Endianness.LITTLE_ENDIAN) |
(...skipping 20 matching lines...) Expand all Loading... |
106 (value) => _int32ToBytes(value.value)) | 100 (value) => _int32ToBytes(value.value)) |
107 ..[GeneratedMessage._GROUP_BIT] = (output, value) { | 101 ..[GeneratedMessage._GROUP_BIT] = (output, value) { |
108 value.writeToCodedBufferWriter(output); | 102 value.writeToCodedBufferWriter(output); |
109 } | 103 } |
110 ..[GeneratedMessage._INT32_BIT] = makeWriter(_int32ToBytes) | 104 ..[GeneratedMessage._INT32_BIT] = makeWriter(_int32ToBytes) |
111 ..[GeneratedMessage._INT64_BIT] = makeWriter( | 105 ..[GeneratedMessage._INT64_BIT] = makeWriter( |
112 (value) => _toVarint64(value)) | 106 (value) => _toVarint64(value)) |
113 ..[GeneratedMessage._SINT32_BIT] = makeWriter( | 107 ..[GeneratedMessage._SINT32_BIT] = makeWriter( |
114 (int value) => _int32ToBytes(_encodeZigZag32(value))) | 108 (int value) => _int32ToBytes(_encodeZigZag32(value))) |
115 ..[GeneratedMessage._SINT64_BIT] = makeWriter( | 109 ..[GeneratedMessage._SINT64_BIT] = makeWriter( |
116 (ByteData value) => _toVarint64(_encodeZigZag64(value))) | 110 (Int64 value) => _toVarint64(_encodeZigZag64(value))) |
117 ..[GeneratedMessage._UINT32_BIT] = makeWriter(_toVarint32) | 111 ..[GeneratedMessage._UINT32_BIT] = makeWriter(_toVarint32) |
118 ..[GeneratedMessage._UINT64_BIT] = makeWriter(_toVarint64) | 112 ..[GeneratedMessage._UINT64_BIT] = makeWriter(_toVarint64) |
119 ..[GeneratedMessage._FIXED32_BIT] = makeWriter(makeByteData32) | 113 ..[GeneratedMessage._FIXED32_BIT] = makeWriter(makeByteData32) |
120 ..[GeneratedMessage._FIXED64_BIT] = makeWriter((x) => x) | 114 ..[GeneratedMessage._FIXED64_BIT] = makeWriter(makeByteData64) |
121 ..[GeneratedMessage._SFIXED32_BIT] = makeWriter(makeByteData32) | 115 ..[GeneratedMessage._SFIXED32_BIT] = makeWriter(makeByteData32) |
122 ..[GeneratedMessage._SFIXED64_BIT] = makeWriter((x) => x) | 116 ..[GeneratedMessage._SFIXED64_BIT] = makeWriter(makeByteData64) |
123 ..[GeneratedMessage._MESSAGE_BIT] = (output, value) { | 117 ..[GeneratedMessage._MESSAGE_BIT] = (output, value) { |
124 output._withDeferredSizeCalculation(() { | 118 output._withDeferredSizeCalculation(() { |
125 value.writeToCodedBufferWriter(output); | 119 value.writeToCodedBufferWriter(output); |
126 }); | 120 }); |
127 }; | 121 }; |
128 } | 122 } |
129 | 123 |
130 static final _OPEN_TAG_MAP = _makeOpenTagMap(); | 124 static final _OPEN_TAG_MAP = _makeOpenTagMap(); |
131 | 125 |
132 static _makeOpenTagMap() { | 126 static _makeOpenTagMap() { |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
213 int position = 0; | 207 int position = 0; |
214 for (var typedData in _output) { | 208 for (var typedData in _output) { |
215 Uint8List asBytes = new Uint8List.view( | 209 Uint8List asBytes = new Uint8List.view( |
216 typedData.buffer, typedData.offsetInBytes, typedData.lengthInBytes); | 210 typedData.buffer, typedData.offsetInBytes, typedData.lengthInBytes); |
217 result.setRange(position, position + typedData.lengthInBytes, asBytes); | 211 result.setRange(position, position + typedData.lengthInBytes, asBytes); |
218 position += typedData.lengthInBytes; | 212 position += typedData.lengthInBytes; |
219 } | 213 } |
220 return result; | 214 return result; |
221 } | 215 } |
222 } | 216 } |
OLD | NEW |