Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(139)

Side by Side Diff: sdk/lib/convert/byte_conversion.dart

Issue 19883003: Add chunked conversion to converters. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Improve some typse. Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2013, 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 part of dart.convert;
6
7 /**
8 * This class represents the [ByteConversionSink] interface. It is
9 * accessed through [ByteConversionSink.INTERFACE] or as instance field
10 * `interface` from [ByteConversionSink]s.
11 */
12 class _ByteInterface extends ChunkedConversionInterface {
13 const _ByteInterface();
14
15 ByteConversionSink adapt(ChunkedConversionSink sink) {
16 if (sink.interface == _ByteInterface) return sink;
Søren Gjesse 2013/07/24 09:26:41 _ByteInterface => ByteConvertionSink.INTERFACE
floitsch 2013/07/24 18:31:15 Done.
17 // Common denominator is ChunkedConversionSink.
18 return new _ByteAdapterSink(sink);
19 }
20 }
21
22 /**
23 * The [ByteConversionSink] provides an interface for converters to
24 * efficiently transmit byte data.
25 *
26 * Instead of limiting the interface to one non-chunked list of bytes it
27 * accepts its input in chunks (themselves being lists of bytes).
28 */
29 abstract class ByteConversionSink
30 extends ChunkedConversionSink<List<int>, List<int>> {
31
32 /** The Interface that represents the [ByteConversionSink]. */
33 static const ChunkedConversionInterface INTERFACE = const _ByteInterface();
34
35 ByteConversionSink();
36 /**
37 * Creates a [ByteConversionSink] with a callback.
38 *
39 * The [callback] is invoked with the accumulated data when the sink is
40 * closed (which automatically happens when it receives data through
41 * [addNonChunked]).
42 */
43 factory ByteConversionSink.withCallback(void callback(List<int> list)) =
44 _ByteConversionCallbackSink;
Søren Gjesse 2013/07/24 09:26:41 How about also having a ByteConvertionSink.withFu
floitsch 2013/07/24 18:31:15 Removed that constructor during removal of addNonC
45
46 /**
47 * Adds the next [chunk] to `this`.
48 *
49 * Adds the substring defined by [start] and [end]-exclusive to `this`.
50 *
51 * If [isLast] is `true` closes `this`.
52 *
53 * The given [chunk] is not hold onto. Once the method returns, it is safe to
54 * overwrite the data in it.
55 */
56 void addSlice(List<int> chunk, int start, int end, bool isLast);
57
58 // TODO(floitsch): add more methods:
59 // - iterateBytes.
60
61 ChunkedConversionInterface get interface => INTERFACE;
62 }
63
64 /**
65 * The [StringConversionSinkBase] provides a base-class for converters that
66 * need to accept byte inputs.
67 */
68 abstract class ByteConversionSinkBase extends ByteConversionSink {
69
70 void add(List<int> chunk);
71 void close();
72
73 void addNonChunked(List<int> list) {
74 add(list);
75 close();
76 }
77
78 void addSlice(List<int> chunk, int start, int end, bool isLast) {
79 if (start != 0 || end != chunk.length) {
80 add(chunk.sublist(start, end));
81 } else {
82 add(chunk);
83 }
84 if (isLast) close();
85 }
86
87 ChunkedConversionInterface get interface => ByteConversionSink.INTERFACE;
88 }
89
90 /**
91 * A [ByteConversionSink] accumulates all chunks and gives it to
92 * the wrapped sink in one go (using `addNonChunked`).
93 *
94 * This class can be used to terminate a chunked conversion.
95 */
96 class _ByteAdapterSink extends ByteConversionSinkBase {
97 static const _INITIAL_BUFFER_SIZE = 1024;
98 final ChunkedConversionSink _otherSink;
99 // TODO(11971, floitsch): use Uint8List instead of normal lists.
100 final List<int> _buffer = new List<int>(_INITIAL_BUFFER_SIZE);
101 int _bufferIndex = 0;
102
103 _ByteAdapterSink(this._otherSink);
104
105 void add(Iterable<int> chunk) {
106 int freeCount = _buffer.length - _bufferIndex;
107 if (chunk.length > freeCount) {
108 // Grow the buffer.
109 int oldLength = _buffer.length;
110 int newLength = _roundToPowerOf2(chunk.length + oldLength) * 2;
111 // TODO(11971, floitsch): use Uint8List instead of normal lists.
112 List<int> grown = new List<int>(newLength);
113 grown.setRange(0, _buffer.length, _buffer);
114 }
115 _buffer.setRange(_bufferIndex, _bufferIndex + chunk.length, chunk);
116 _bufferIndex += chunk.length;
117 }
118
119 static int _roundToPowerOf2(int v) {
Søren Gjesse 2013/07/24 09:26:41 This is not the first time I have seen this code.
floitsch 2013/07/24 18:31:15 Filed http://dartbug.com/12008.
120 assert(v > 0);
121 v--;
122 v |= v >> 1;
123 v |= v >> 2;
124 v |= v >> 4;
125 v |= v >> 8;
126 v |= v >> 16;
127 v++;
128 return v;
129 }
130
131 void close() {
132 _otherSink.addNonChunked(_buffer.sublist(0, _bufferIndex));
133 }
134
135 void addNonChunked(List<int> list) => _otherSink.addNonChunked(list);
136 }
137
138 /**
139 * A [ByteConversionSink] accumulating all chunks and invoking a
140 * callback when the sink is closed.
141 */
142 class _ByteConversionCallbackSink extends ByteConversionSinkBase {
143 final _ChunkedConversionCallback<List<int>> _callback;
144 // TODO(floitsch): use typed lists.
145 final List<int> _accumulated = <int>[];
146
147 _ByteConversionCallbackSink(this._callback);
148
149 void add(Iterable<int> chunk) { _accumulated.addAll(chunk); }
150 void close() { _callback(_accumulated); }
151
152 void addNonChunked(List<int> list) => _callback(list);
153 }
OLDNEW
« no previous file with comments | « no previous file | sdk/lib/convert/chunked_conversion.dart » ('j') | sdk/lib/convert/chunked_conversion.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698