1/// Licensed to the Apache Software Foundation (ASF) under one
2/// or more contributor license agreements. See the NOTICE file
3/// distributed with this work for additional information
4/// regarding copyright ownership. The ASF licenses this file
5/// to you under the Apache License, Version 2.0 (the
6/// "License"); you may not use this file except in compliance
7/// with the License. You may obtain a copy of the License at
8///
9/// http://www.apache.org/licenses/LICENSE-2.0
10///
11/// Unless required by applicable law or agreed to in writing,
12/// software distributed under the License is distributed on an
13/// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14/// KIND, either express or implied. See the License for the
15/// specific language governing permissions and limitations
16/// under the License.
17
18part of thrift;
19
20/// Buffered implementation of [TTransport].
21class TBufferedTransport extends TTransport {
22  final List<int> _writeBuffer = [];
23  Iterator<int> _readIterator;
24
25  Uint8List consumeWriteBuffer() {
26    Uint8List buffer = new Uint8List.fromList(_writeBuffer);
27    _writeBuffer.clear();
28    return buffer;
29  }
30
31  void _setReadBuffer(Uint8List readBuffer) {
32    _readIterator = readBuffer != null ? readBuffer.iterator : null;
33  }
34
35  void _reset({bool isOpen: false}) {
36    _isOpen = isOpen;
37    _writeBuffer.clear();
38    _readIterator = null;
39  }
40
41  bool get hasReadData => _readIterator != null;
42
43  bool _isOpen;
44  bool get isOpen => _isOpen;
45
46  Future open() async {
47    _reset(isOpen: true);
48  }
49
50  Future close() async {
51    _reset(isOpen: false);
52  }
53
54  int read(Uint8List buffer, int offset, int length) {
55    if (buffer == null) {
56      throw new ArgumentError.notNull("buffer");
57    }
58
59    if (offset + length > buffer.length) {
60      throw new ArgumentError("The range exceeds the buffer length");
61    }
62
63    if (_readIterator == null || length <= 0) {
64      return 0;
65    }
66
67    int i = 0;
68    while (i < length && _readIterator.moveNext()) {
69      buffer[offset + i] = _readIterator.current;
70      i++;
71    }
72
73    // cleanup iterator when we've reached the end
74    if (_readIterator.current == null) {
75      _readIterator = null;
76    }
77
78    return i;
79  }
80
81  void write(Uint8List buffer, int offset, int length) {
82    if (buffer == null) {
83      throw new ArgumentError.notNull("buffer");
84    }
85
86    if (offset + length > buffer.length) {
87      throw new ArgumentError("The range exceeds the buffer length");
88    }
89
90    _writeBuffer.addAll(buffer.sublist(offset, offset + length));
91  }
92
93  Future flush() {
94    _readIterator = consumeWriteBuffer().iterator;
95
96    return new Future.value();
97  }
98}
99