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 CodedBufferReader { | 7 class CodedBufferReader { |
8 static const int DEFAULT_RECURSION_LIMIT = 64; | 8 static const int DEFAULT_RECURSION_LIMIT = 64; |
9 static const int DEFAULT_SIZE_LIMIT = 64 << 20; | 9 static const int DEFAULT_SIZE_LIMIT = 64 << 20; |
10 | 10 |
11 final Uint8List _buffer; | 11 final Uint8List _buffer; |
12 int _bufferPos = 0; | 12 int _bufferPos = 0; |
13 int _currentLimit = -1; | 13 int _currentLimit = -1; |
14 int _lastTag = 0; | 14 int _lastTag = 0; |
15 int _recursionDepth = 0; | 15 int _recursionDepth = 0; |
16 final int _recursionLimit; | 16 final int _recursionLimit; |
17 final int _sizeLimit; | 17 final int _sizeLimit; |
18 | 18 |
19 CodedBufferReader( | 19 CodedBufferReader(List<int> buffer, |
20 List<int> buffer, | |
21 {int recursionLimit: DEFAULT_RECURSION_LIMIT, | 20 {int recursionLimit: DEFAULT_RECURSION_LIMIT, |
22 int sizeLimit: DEFAULT_SIZE_LIMIT}) : | 21 int sizeLimit: DEFAULT_SIZE_LIMIT}) |
23 _buffer = | 22 : _buffer = buffer is Uint8List ? buffer : new Uint8List(buffer.length) |
24 buffer is Uint8List | 23 ..setRange(0, buffer.length, buffer), |
25 ? buffer | 24 _recursionLimit = recursionLimit, |
26 : new Uint8List(buffer.length)..setRange(0, buffer.length, buffer), | 25 _sizeLimit = math.min(sizeLimit, buffer.length) { |
27 _recursionLimit = recursionLimit, | |
28 _sizeLimit = math.min(sizeLimit, buffer.length) { | |
29 _currentLimit = _sizeLimit; | 26 _currentLimit = _sizeLimit; |
30 } | 27 } |
31 | 28 |
32 void checkLastTagWas(int value) { | 29 void checkLastTagWas(int value) { |
33 if (_lastTag != value) { | 30 if (_lastTag != value) { |
34 throw new InvalidProtocolBufferException.invalidEndTag(); | 31 throw new InvalidProtocolBufferException.invalidEndTag(); |
35 } | 32 } |
36 } | 33 } |
37 | 34 |
38 bool isAtEnd() => _bufferPos >= _currentLimit; | 35 bool isAtEnd() => _bufferPos >= _currentLimit; |
(...skipping 16 matching lines...) Expand all Loading... |
55 | 52 |
56 void _checkLimit(int increment) { | 53 void _checkLimit(int increment) { |
57 assert(_currentLimit != -1); | 54 assert(_currentLimit != -1); |
58 _bufferPos += increment; | 55 _bufferPos += increment; |
59 if (_bufferPos > _currentLimit) { | 56 if (_bufferPos > _currentLimit) { |
60 throw new InvalidProtocolBufferException.truncatedMessage(); | 57 throw new InvalidProtocolBufferException.truncatedMessage(); |
61 } | 58 } |
62 } | 59 } |
63 | 60 |
64 void readGroup(int fieldNumber, GeneratedMessage message, | 61 void readGroup(int fieldNumber, GeneratedMessage message, |
65 ExtensionRegistry extensionRegistry) { | 62 ExtensionRegistry extensionRegistry) { |
66 if (_recursionDepth >= _recursionLimit) { | 63 if (_recursionDepth >= _recursionLimit) { |
67 throw new InvalidProtocolBufferException.recursionLimitExceeded(); | 64 throw new InvalidProtocolBufferException.recursionLimitExceeded(); |
68 } | 65 } |
69 ++_recursionDepth; | 66 ++_recursionDepth; |
70 message.mergeFromCodedBufferReader(this, extensionRegistry); | 67 message.mergeFromCodedBufferReader(this, extensionRegistry); |
71 checkLastTagWas(makeTag(fieldNumber, WIRETYPE_END_GROUP)); | 68 checkLastTagWas(makeTag(fieldNumber, WIRETYPE_END_GROUP)); |
72 --_recursionDepth; | 69 --_recursionDepth; |
73 } | 70 } |
74 | 71 |
75 UnknownFieldSet readUnknownFieldSetGroup(int fieldNumber) { | 72 UnknownFieldSet readUnknownFieldSetGroup(int fieldNumber) { |
76 if (_recursionDepth >= _recursionLimit) { | 73 if (_recursionDepth >= _recursionLimit) { |
77 throw new InvalidProtocolBufferException.recursionLimitExceeded(); | 74 throw new InvalidProtocolBufferException.recursionLimitExceeded(); |
78 } | 75 } |
79 ++_recursionDepth; | 76 ++_recursionDepth; |
80 UnknownFieldSet unknownFieldSet = new UnknownFieldSet(); | 77 UnknownFieldSet unknownFieldSet = new UnknownFieldSet(); |
81 unknownFieldSet.mergeFromCodedBufferReader(this); | 78 unknownFieldSet.mergeFromCodedBufferReader(this); |
82 checkLastTagWas(makeTag(fieldNumber, WIRETYPE_END_GROUP)); | 79 checkLastTagWas(makeTag(fieldNumber, WIRETYPE_END_GROUP)); |
83 --_recursionDepth; | 80 --_recursionDepth; |
84 return unknownFieldSet; | 81 return unknownFieldSet; |
85 } | 82 } |
86 | 83 |
87 void readMessage(GeneratedMessage message, | 84 void readMessage( |
88 ExtensionRegistry extensionRegistry) { | 85 GeneratedMessage message, ExtensionRegistry extensionRegistry) { |
89 int length = readInt32(); | 86 int length = readInt32(); |
90 if (_recursionDepth >= _recursionLimit) { | 87 if (_recursionDepth >= _recursionLimit) { |
91 throw new InvalidProtocolBufferException.recursionLimitExceeded(); | 88 throw new InvalidProtocolBufferException.recursionLimitExceeded(); |
92 } | 89 } |
93 if (length < 0) { | 90 if (length < 0) { |
94 throw new ArgumentError( | 91 throw new ArgumentError( |
95 'CodedBufferReader encountered an embedded string or message' | 92 'CodedBufferReader encountered an embedded string or message' |
96 ' which claimed to have negative size.'); | 93 ' which claimed to have negative size.'); |
97 } | 94 } |
98 | 95 |
(...skipping 17 matching lines...) Expand all Loading... |
116 int readSint32() => _decodeZigZag32(readUint32()); | 113 int readSint32() => _decodeZigZag32(readUint32()); |
117 Int64 readSint64() => _decodeZigZag64(readUint64()); | 114 Int64 readSint64() => _decodeZigZag64(readUint64()); |
118 int readFixed32() => _readByteData(4).getUint32(0, Endianness.LITTLE_ENDIAN); | 115 int readFixed32() => _readByteData(4).getUint32(0, Endianness.LITTLE_ENDIAN); |
119 Int64 readFixed64() => readSfixed64(); | 116 Int64 readFixed64() => readSfixed64(); |
120 int readSfixed32() => _readByteData(4).getInt32(0, Endianness.LITTLE_ENDIAN); | 117 int readSfixed32() => _readByteData(4).getInt32(0, Endianness.LITTLE_ENDIAN); |
121 Int64 readSfixed64() { | 118 Int64 readSfixed64() { |
122 var data = _readByteData(8); | 119 var data = _readByteData(8); |
123 var view = new Uint8List.view(data.buffer, data.offsetInBytes, 8); | 120 var view = new Uint8List.view(data.buffer, data.offsetInBytes, 8); |
124 return new Int64.fromBytes(view); | 121 return new Int64.fromBytes(view); |
125 } | 122 } |
| 123 |
126 bool readBool() => _readRawVarint32() != 0; | 124 bool readBool() => _readRawVarint32() != 0; |
127 List<int> readBytes() { | 125 List<int> readBytes() { |
128 int length = readInt32(); | 126 int length = readInt32(); |
129 _checkLimit(length); | 127 _checkLimit(length); |
130 return new Uint8List.view(_buffer.buffer, | 128 return new Uint8List.view( |
131 _buffer.offsetInBytes + _bufferPos - length, length); | 129 _buffer.buffer, _buffer.offsetInBytes + _bufferPos - length, length); |
132 } | 130 } |
| 131 |
133 String readString() => _UTF8.decode(readBytes()); | 132 String readString() => _UTF8.decode(readBytes()); |
134 double readFloat() => | 133 double readFloat() => |
135 _readByteData(4).getFloat32(0, Endianness.LITTLE_ENDIAN); | 134 _readByteData(4).getFloat32(0, Endianness.LITTLE_ENDIAN); |
136 double readDouble() => | 135 double readDouble() => |
137 _readByteData(8).getFloat64(0, Endianness.LITTLE_ENDIAN); | 136 _readByteData(8).getFloat64(0, Endianness.LITTLE_ENDIAN); |
138 | 137 |
139 int readTag() { | 138 int readTag() { |
140 if (isAtEnd()) { | 139 if (isAtEnd()) { |
141 _lastTag = 0; | 140 _lastTag = 0; |
142 return 0; | 141 return 0; |
143 } | 142 } |
144 | 143 |
145 _lastTag = readInt32(); | 144 _lastTag = readInt32(); |
146 if (getTagFieldNumber(_lastTag) == 0) { | 145 if (getTagFieldNumber(_lastTag) == 0) { |
147 throw new InvalidProtocolBufferException.invalidTag(); | 146 throw new InvalidProtocolBufferException.invalidTag(); |
148 } | 147 } |
149 return _lastTag; | 148 return _lastTag; |
150 } | 149 } |
151 | 150 |
152 static int _decodeZigZag32(int value) { | 151 static int _decodeZigZag32(int value) { |
153 if ((value & 0x1) == 1) value = -value; | 152 if ((value & 0x1) == 1) { |
154 return value >> 1; | 153 return -(value >> 1) - 1; |
| 154 } else { |
| 155 return value >> 1; |
| 156 } |
155 } | 157 } |
156 | 158 |
157 static Int64 _decodeZigZag64(Int64 value) { | 159 static Int64 _decodeZigZag64(Int64 value) { |
158 if ((value & 0x1) == 1) value = -value; | 160 if ((value & 0x1) == 1) value = -value; |
159 return value >> 1; | 161 return value >> 1; |
160 } | 162 } |
161 | 163 |
162 int _readRawVarintByte() { | 164 int _readRawVarintByte() { |
163 _checkLimit(1); | 165 _checkLimit(1); |
164 return _buffer[_bufferPos - 1]; | 166 return _buffer[_bufferPos - 1]; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
208 } | 210 } |
209 throw new InvalidProtocolBufferException.malformedVarint(); | 211 throw new InvalidProtocolBufferException.malformedVarint(); |
210 } | 212 } |
211 | 213 |
212 ByteData _readByteData(int sizeInBytes) { | 214 ByteData _readByteData(int sizeInBytes) { |
213 _checkLimit(sizeInBytes); | 215 _checkLimit(sizeInBytes); |
214 return new ByteData.view(_buffer.buffer, | 216 return new ByteData.view(_buffer.buffer, |
215 _buffer.offsetInBytes + _bufferPos - sizeInBytes, sizeInBytes); | 217 _buffer.offsetInBytes + _bufferPos - sizeInBytes, sizeInBytes); |
216 } | 218 } |
217 } | 219 } |
OLD | NEW |