OLD | NEW |
(Empty) | |
| 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 |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 class CodedStreamReader extends CodedReader { |
| 6 PbInputStreamReader _input; |
| 7 |
| 8 CodedStreamReader(InputStream input, [ |
| 9 int recursionLimit = CodedReader.DEFAULT_RECURSION_LIMIT, |
| 10 int sizeLimit = CodedReader.DEFAULT_SIZE_LIMIT]) : |
| 11 super(recursionLimit, sizeLimit), |
| 12 _input = new PbInputStreamReader(input); |
| 13 |
| 14 bool isAtEnd() => (_currentLimit != -1 &&_bufferPos >= _currentLimit) || |
| 15 _input.closed; |
| 16 |
| 17 Future readGroup(int fieldNumber, Builder builder, |
| 18 ExtensionRegistry extensionRegistry) { |
| 19 if (_recursionDepth >= _recursionLimit) { |
| 20 throw InvalidProtocolBufferException.recursionLimitExceeded(); |
| 21 } |
| 22 ++_recursionDepth; |
| 23 return builder.mergeFromCodedStreamReader(this).transform((_) { |
| 24 checkLastTagWas(WireFormat.makeTag(fieldNumber, |
| 25 WireFormat.WIRETYPE_END_GROUP)); |
| 26 --_recursionDepth; |
| 27 }); |
| 28 } |
| 29 |
| 30 Future readUnknownFieldSetGroup(int fieldNumber, |
| 31 UnknownFieldSet_Builder builder, ExtensionRegistry extensionRegistry) { |
| 32 if (_recursionDepth >= _recursionLimit) { |
| 33 throw InvalidProtocolBufferException.recursionLimitExceeded(); |
| 34 } |
| 35 ++_recursionDepth; |
| 36 return builder.mergeFromCodedStreamReader(this).transform((_) { |
| 37 checkLastTagWas(WireFormat.makeTag(fieldNumber, |
| 38 WireFormat.WIRETYPE_END_GROUP)); |
| 39 --_recursionDepth; |
| 40 }); |
| 41 } |
| 42 |
| 43 Future readMessage(Builder builder, ExtensionRegistry extensionRegistry) { |
| 44 int oldLimit; |
| 45 return readInt32().chain((int length) { |
| 46 if(_recursionDepth >= _recursionLimit) { |
| 47 throw InvalidProtocolBufferException.recursionLimitExceeded(); |
| 48 } |
| 49 oldLimit = _pushLimit(length); |
| 50 ++_recursionDepth; |
| 51 return builder.mergeFromCodedStreamReader(this); |
| 52 }).transform((_){ |
| 53 checkLastTagWas(0); |
| 54 --_recursionDepth; |
| 55 _popLimit(oldLimit); |
| 56 return null; |
| 57 }); |
| 58 } |
| 59 |
| 60 Future<int> readEnum() => readInt32(); |
| 61 |
| 62 Future<int> readInt32() => |
| 63 readRawVarint().transform((v) => PbCodec.toInt32(v)); |
| 64 |
| 65 Future<int> readInt64() => |
| 66 readRawVarint().transform((v) => PbCodec.toInt64(v)); |
| 67 |
| 68 Future<int> readUint32() => |
| 69 readRawVarint().transform((v) => PbCodec.toUint32(v)); |
| 70 |
| 71 Future<int> readUint64() => |
| 72 readRawVarint().transform((v) => PbCodec.toUint64(v)); |
| 73 |
| 74 Future<int> readSint32() => |
| 75 readRawVarint().transform((v) => PbCodec.toSint32(v)); |
| 76 |
| 77 Future<int> readSint64() => |
| 78 readRawVarint().transform((v) => PbCodec.toSint64(v)); |
| 79 |
| 80 Future<int> readFixed32() => |
| 81 readRaw32().transform((v) => PbCodec.toFixed32(v)); |
| 82 |
| 83 Future<int> readFixed64() => |
| 84 readRaw64().transform((v) => PbCodec.toFixed64(v)); |
| 85 |
| 86 Future<int> readSfixed32() => |
| 87 readRaw32().transform((v) => PbCodec.toSfixed32(v)); |
| 88 |
| 89 Future<int> readSfixed64() => |
| 90 readRaw64().transform((v) => PbCodec.toSfixed64(v)); |
| 91 |
| 92 Future<bool> readBool() => |
| 93 readRawVarint().transform((v) => PbCodec.toBool(v)); |
| 94 |
| 95 Future<List<int>> readBytes() => readRawLengthDelimited(); |
| 96 |
| 97 Future<String> readString() => |
| 98 readRawLengthDelimited().transform((v) => decodeUtf8(v)); |
| 99 |
| 100 Future<double> readFloat() => |
| 101 readRaw32().transform((v) => PbCodec.toFloat(v)); |
| 102 |
| 103 Future<double> readDouble() => |
| 104 readRaw64().transform((v) => PbCodec.toDouble(v)); |
| 105 |
| 106 |
| 107 Future<int> readTag() { |
| 108 if (isAtEnd()) { |
| 109 _lastTag = 0; |
| 110 return new Future<int>.immediate(0); |
| 111 } |
| 112 return readInt32().transform((int value) { |
| 113 _lastTag = value; |
| 114 if (WireFormat.getTagFieldNumber(_lastTag) == 0) { |
| 115 throw InvalidProtocolBufferException.invalidTag(); |
| 116 } else { |
| 117 return _lastTag; |
| 118 } |
| 119 }); |
| 120 } |
| 121 |
| 122 Future<List<int>> readRawVarint() { |
| 123 List<int> rawBytes = []; |
| 124 Future completeVarint() { |
| 125 return _readRawByte().chain((int value) { |
| 126 if (value == null) { |
| 127 throw InvalidProtocolBufferException.truncatedMessage(); |
| 128 } |
| 129 rawBytes.add(value); |
| 130 if (rawBytes.length < 10 && (value & 0x80) != 0) { |
| 131 return completeVarint(); |
| 132 } else { |
| 133 return new Future.immediate(0); |
| 134 } |
| 135 }); |
| 136 } |
| 137 return completeVarint().transform((_) => rawBytes); |
| 138 } |
| 139 |
| 140 Future<List<int>> readRaw32() => _readRawBytes(4); |
| 141 Future<List<int>> readRaw64() => _readRawBytes(8); |
| 142 |
| 143 Future<List<int>> readRawLengthDelimited() => |
| 144 readInt32().chain((int length) => _readRawBytes(length)); |
| 145 |
| 146 Future<int> _readRawByte() { |
| 147 try { |
| 148 _bufferPos++; |
| 149 _checkLimit(); |
| 150 } catch (InvalidProtocolBufferException e) { |
| 151 // add a Future.immediateException() construct... |
| 152 Completer<int> c = new Completer<int>(); |
| 153 c.completeException(e); |
| 154 return c.future; |
| 155 } |
| 156 return _input.readByte().transform((int byte) { |
| 157 if (byte == null) { |
| 158 throw InvalidProtocolBufferException.truncatedMessage(); |
| 159 } |
| 160 return byte; |
| 161 }); |
| 162 } |
| 163 |
| 164 Future<List<int>> _readRawBytes(int size) { |
| 165 try { |
| 166 _bufferPos += size; |
| 167 _checkLimit(); |
| 168 } catch (InvalidProtocolBufferException e) { |
| 169 // add a Future.immediateException() construct... |
| 170 Completer<int> c = new Completer<int>(); |
| 171 c.completeException(e); |
| 172 return c.future; |
| 173 } |
| 174 return _input.readBytes(size); |
| 175 } |
| 176 |
| 177 Future skipField(int tag) { |
| 178 int number = tag >> 3; |
| 179 int wireType = tag & 0x7; |
| 180 switch (wireType) { |
| 181 case WireFormat.WIRETYPE_VARINT: |
| 182 return readRawVarint().transform((_) => null); |
| 183 case WireFormat.WIRETYPE_FIXED64: |
| 184 return readRaw64().transform((_) => null); |
| 185 case WireFormat.WIRETYPE_LENGTH_DELIMITED: |
| 186 return readRawLengthDelimited().transform((_) => null); |
| 187 case WireFormat.WIRETYPE_START_GROUP: |
| 188 UnknownFieldSet_Builder subBuilder = |
| 189 new UnknownFieldSet_Builder(); |
| 190 return readUnknownFieldSetGroup(number, subBuilder, |
| 191 ExtensionRegistry.EMPTY_REGISTRY).transform((_) => null); |
| 192 case WireFormat.WIRETYPE_END_GROUP: // should not happen, but ignore? |
| 193 return new Future.immediate(null); |
| 194 case WireFormat.WIRETYPE_FIXED32: |
| 195 return readRaw32().transform((_) => null); |
| 196 } |
| 197 } |
| 198 |
| 199 Future skipRawBytes(int number) { |
| 200 return _readRawBytes(number).transform((_) => null); |
| 201 } |
| 202 |
| 203 void _enableReadAhead(int numberOfBytes) { |
| 204 _input.setReadAhead(numberOfBytes); |
| 205 } |
| 206 } |
OLD | NEW |