OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012, 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 /** | |
6 * Utility class that holds a number of byte buffers and can deliver | |
7 * the bytes either one by one or in chunks. | |
8 */ | |
9 class _BufferList { | |
10 _BufferList() { | |
11 clear(); | |
12 } | |
13 | |
14 /** | |
15 * Adds a new buffer to the list possibly with an offset of the | |
16 * first byte of interest. The offset can only be specified if the | |
17 * buffer list is empty. | |
18 */ | |
19 void add(List<int> buffer, [int offset = 0]) { | |
20 assert(offset == 0 || _buffers.isEmpty); | |
21 _buffers.addLast(buffer); | |
22 _length += buffer.length; | |
23 if (offset != 0) _index = offset; | |
24 } | |
25 | |
26 /** | |
27 * Returns the first buffer from the list. This returns the whole | |
28 * buffer and does not remove the buffer from the list. Use | |
29 * [index] to determine the index of the first byte in the buffer. | |
30 */ | |
31 List<int> get first => _buffers.first; | |
32 | |
33 /** | |
34 * Returns the current index of the next byte. This will always be | |
35 * an index into the first buffer as when the index is advanced past | |
36 * the end of a buffer it is removed from the list. | |
37 */ | |
38 int get index => _index; | |
39 | |
40 /** | |
41 * Peek at the next available byte. | |
42 */ | |
43 int peek() => _buffers.first[_index]; | |
44 | |
45 /** | |
46 * Returns the next available byte removing it from the buffers. | |
47 */ | |
48 int next() { | |
49 int value = _buffers.first[_index++]; | |
50 _length--; | |
51 if (_index == _buffers.first.length) { | |
52 _buffers.removeFirst(); | |
53 _index = 0; | |
54 } | |
55 return value; | |
56 } | |
57 | |
58 /** | |
59 * Read [count] bytes from the buffer list. If the number of bytes | |
60 * requested is not available null will be returned. | |
61 */ | |
62 List<int> readBytes(int count) { | |
63 List<int> result; | |
64 if (_length == 0 || _length < count) return null; | |
65 if (_index == 0 && _buffers.first.length == count) { | |
66 result = _buffers.first; | |
67 _buffers.removeFirst(); | |
68 _index = 0; | |
69 _length -= count; | |
70 return result; | |
71 } else { | |
72 int firstRemaining = _buffers.first.length - _index; | |
73 if (firstRemaining >= count) { | |
74 result = _buffers.first.getRange(_index, count); | |
75 _index += count; | |
76 _length -= count; | |
77 if (_index == _buffers.first.length) { | |
78 _buffers.removeFirst(); | |
79 _index = 0; | |
80 } | |
81 return result; | |
82 } else { | |
83 result = new Uint8List(count); | |
84 int remaining = count; | |
85 while (remaining > 0) { | |
86 int bytesInFirst = _buffers.first.length - _index; | |
87 if (bytesInFirst <= remaining) { | |
88 result.setRange(count - remaining, | |
89 bytesInFirst, | |
90 _buffers.first, | |
91 _index); | |
92 _buffers.removeFirst(); | |
93 _index = 0; | |
94 _length -= bytesInFirst; | |
95 remaining -= bytesInFirst; | |
96 } else { | |
97 result.setRange(count - remaining, | |
98 remaining, | |
99 _buffers.first, | |
100 _index); | |
101 _index = remaining; | |
102 _length -= remaining; | |
103 remaining = 0; | |
104 assert(_index < _buffers.first.length); | |
105 } | |
106 } | |
107 return result; | |
108 } | |
109 } | |
110 } | |
111 | |
112 /** | |
113 * Remove a number of bytes from the buffer list. Currently the | |
114 * number of bytes to remove must be confined to the first buffer. | |
115 */ | |
116 void removeBytes(int count) { | |
117 int firstRemaining = first.length - _index; | |
118 assert(count <= firstRemaining); | |
119 if (count == firstRemaining) { | |
120 _buffers.removeFirst(); | |
121 _index = 0; | |
122 } else { | |
123 _index += count; | |
124 } | |
125 _length -= count; | |
126 } | |
127 | |
128 | |
129 /** | |
130 * Returns the total number of bytes remaining in the buffers. | |
131 */ | |
132 int get length => _length; | |
133 | |
134 /** | |
135 * Returns whether the buffer list is empty that is has no bytes | |
136 * available. | |
137 */ | |
138 bool get isEmpty => _buffers.isEmpty; | |
139 | |
140 /** | |
141 * Clears the content of the buffer list. | |
142 */ | |
143 void clear() { | |
144 _index = 0; | |
145 _length = 0; | |
146 _buffers = new Queue(); | |
147 } | |
148 | |
149 int _length; // Total number of bytes remaining in the buffers. | |
150 Queue<List<int>> _buffers; // List of data buffers. | |
151 int _index; // Index of the next byte in the first buffer. | |
152 } | |
OLD | NEW |