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

Side by Side Diff: pkg/dev_compiler/tool/input_sdk/lib/convert/string_conversion.dart

Issue 2698353003: unfork DDC's copy of most SDK libraries (Closed)
Patch Set: revert core_patch Created 3 years, 9 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
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 provides an interface for converters to
9 * efficiently transmit String data.
10 *
11 * Instead of limiting the interface to one non-chunked String it accepts
12 * partial strings or can be transformed into a byte sink that
13 * accepts UTF-8 code units.
14 *
15 * This abstract class will likely get more methods over time. Implementers are
16 * urged to extend [StringConversionSinkBase] or to mix in
17 * [StringConversionSinkMixin], to ensure that their class covers the newly
18 * added methods.
19 */
20 abstract class StringConversionSink extends ChunkedConversionSink<String> {
21 StringConversionSink();
22 factory StringConversionSink.withCallback(void callback(String accumulated))
23 = _StringCallbackSink;
24 factory StringConversionSink.from(Sink<String> sink)
25 = _StringAdapterSink;
26
27 /**
28 * Creates a new instance wrapping the given [sink].
29 *
30 * Every string that is added to the returned instance is forwarded to
31 * the [sink]. The instance is allowed to buffer and is not required to
32 * forward immediately.
33 */
34 factory StringConversionSink.fromStringSink(StringSink sink) =
35 _StringSinkConversionSink;
36
37 /**
38 * Adds the next [chunk] to `this`.
39 *
40 * Adds the substring defined by [start] and [end]-exclusive to `this`.
41 *
42 * If [isLast] is `true` closes `this`.
43 */
44 void addSlice(String chunk, int start, int end, bool isLast);
45
46 /**
47 * Returns `this` as a sink that accepts UTF-8 input.
48 *
49 * If used, this method must be the first and only call to `this`. It
50 * invalidates `this`. All further operations must be performed on the result.
51 */
52 ByteConversionSink asUtf8Sink(bool allowMalformed);
53 // - asRuneSink
54 // - asCodeUnitsSink
55
56 /**
57 * Returns `this` as a [ClosableStringSink].
58 *
59 * If used, this method must be the first and only call to `this`. It
60 * invalidates `this`. All further operations must be performed on the result.
61 */
62 ClosableStringSink asStringSink();
63 }
64
65 /**
66 * A [ClosableStringSink] extends the [StringSink] interface by adding a
67 * `close` method.
68 */
69 abstract class ClosableStringSink extends StringSink {
70 /**
71 * Creates a new instance combining a [StringSink] [sink] and a callback
72 * [onClose] which is invoked when the returned instance is closed.
73 */
74 factory ClosableStringSink.fromStringSink(StringSink sink, void onClose())
75 = _ClosableStringSink;
76
77 /**
78 * Closes `this` and flushes any outstanding data.
79 */
80 void close();
81 }
82
83 typedef void _StringSinkCloseCallback();
84
85 /**
86 * This class wraps an existing [StringSink] and invokes a
87 * closure when [close] is invoked.
88 */
89 class _ClosableStringSink implements ClosableStringSink {
90 final _StringSinkCloseCallback _callback;
91 final StringSink _sink;
92
93 _ClosableStringSink(this._sink, this._callback);
94
95 void close() { _callback(); }
96
97 void writeCharCode(int charCode) { _sink.writeCharCode(charCode); }
98 void write(Object o) { _sink.write(o); }
99 void writeln([Object o = ""]) { _sink.writeln(o); }
100 void writeAll(Iterable objects, [String separator = ""]) {
101 _sink.writeAll(objects, separator);
102 }
103 }
104
105 /**
106 * This class wraps an existing [StringConversionSink] and exposes a
107 * [ClosableStringSink] interface. The wrapped sink only needs to implement
108 * `add` and `close`.
109 */
110 // TODO(floitsch): make this class public?
111 class _StringConversionSinkAsStringSinkAdapter implements ClosableStringSink {
112 static const _MIN_STRING_SIZE = 16;
113
114 StringBuffer _buffer;
115 StringConversionSink _chunkedSink;
116
117 _StringConversionSinkAsStringSinkAdapter(this._chunkedSink)
118 : _buffer = new StringBuffer();
119
120 void close() {
121 if (_buffer.isNotEmpty) _flush();
122 _chunkedSink.close();
123 }
124
125 void writeCharCode(int charCode) {
126 _buffer.writeCharCode(charCode);
127 if (_buffer.length > _MIN_STRING_SIZE) _flush();
128 }
129
130 void write(Object o) {
131 if (_buffer.isNotEmpty) _flush();
132 _chunkedSink.add(o.toString());
133 }
134
135 void writeln([Object o = ""]) {
136 _buffer.writeln(o);
137 if (_buffer.length > _MIN_STRING_SIZE) _flush();
138 }
139
140 void writeAll(Iterable objects, [String separator = ""]) {
141 if (_buffer.isNotEmpty) _flush();
142 Iterator iterator = objects.iterator;
143 if (!iterator.moveNext()) return;
144 if (separator.isEmpty) {
145 do {
146 _chunkedSink.add(iterator.current.toString());
147 } while (iterator.moveNext());
148 } else {
149 _chunkedSink.add(iterator.current.toString());
150 while (iterator.moveNext()) {
151 write(separator);
152 _chunkedSink.add(iterator.current.toString());
153 }
154 }
155 }
156
157 void _flush() {
158 String accumulated = _buffer.toString();
159 _buffer.clear();
160 _chunkedSink.add(accumulated);
161 }
162 }
163
164 /**
165 * This class provides a base-class for converters that need to accept String
166 * inputs.
167 */
168 abstract class StringConversionSinkBase extends StringConversionSinkMixin {
169 }
170
171 /**
172 * This class provides a mixin for converters that need to accept String
173 * inputs.
174 */
175 abstract class StringConversionSinkMixin implements StringConversionSink {
176
177 void addSlice(String str, int start, int end, bool isLast);
178 void close();
179
180 void add(String str) { addSlice(str, 0, str.length, false); }
181
182 ByteConversionSink asUtf8Sink(bool allowMalformed) {
183 return new _Utf8ConversionSink(this, allowMalformed);
184 }
185
186 ClosableStringSink asStringSink() {
187 return new _StringConversionSinkAsStringSinkAdapter(this);
188 }
189 }
190
191 /**
192 * This class is a [StringConversionSink] that wraps a [StringSink].
193 */
194 class _StringSinkConversionSink extends StringConversionSinkBase {
195 StringSink _stringSink;
196 _StringSinkConversionSink(StringSink this._stringSink);
197
198 void close() {}
199 void addSlice(String str, int start, int end, bool isLast) {
200 if (start != 0 || end != str.length) {
201 for (int i = start; i < end; i++) {
202 _stringSink.writeCharCode(str.codeUnitAt(i));
203 }
204 } else {
205 _stringSink.write(str);
206 }
207 if (isLast) close();
208 }
209
210 void add(String str) { _stringSink.write(str); }
211
212 ByteConversionSink asUtf8Sink(bool allowMalformed) {
213 return new _Utf8StringSinkAdapter(this, _stringSink, allowMalformed);
214 }
215
216 ClosableStringSink asStringSink() {
217 return new ClosableStringSink.fromStringSink(_stringSink, this.close);
218 }
219 }
220
221 /**
222 * This class accumulates all chunks into one string
223 * and invokes a callback when the sink is closed.
224 *
225 * This class can be used to terminate a chunked conversion.
226 */
227 class _StringCallbackSink extends _StringSinkConversionSink {
228 final _ChunkedConversionCallback<String> _callback;
229 _StringCallbackSink(this._callback) : super(new StringBuffer());
230
231 void close() {
232 StringBuffer buffer = _stringSink;
233 String accumulated = buffer.toString();
234 buffer.clear();
235 _callback(accumulated);
236 }
237
238 ByteConversionSink asUtf8Sink(bool allowMalformed) {
239 return new _Utf8StringSinkAdapter(
240 this, _stringSink, allowMalformed);
241 }
242 }
243
244 /**
245 * This class adapts a simple [ChunkedConversionSink] to a
246 * [StringConversionSink].
247 *
248 * All additional methods of the [StringConversionSink] (compared to the
249 * ChunkedConversionSink) are redirected to the `add` method.
250 */
251 class _StringAdapterSink extends StringConversionSinkBase {
252 final Sink<String> _sink;
253
254 _StringAdapterSink(this._sink);
255
256 void add(String str) { _sink.add(str); }
257
258 void addSlice(String str, int start, int end, bool isLast) {
259 if (start == 0 && end == str.length) {
260 add(str);
261 } else {
262 add(str.substring(start, end));
263 }
264 if (isLast) close();
265 }
266
267 void close() { _sink.close(); }
268 }
269
270
271 /**
272 * Decodes UTF-8 code units and stores them in a [StringSink].
273 */
274 class _Utf8StringSinkAdapter extends ByteConversionSink {
275 final _Utf8Decoder _decoder;
276 final Sink _sink;
277
278 _Utf8StringSinkAdapter(this._sink,
279 StringSink stringSink, bool allowMalformed)
280 : _decoder = new _Utf8Decoder(stringSink, allowMalformed);
281
282 void close() {
283 _decoder.close();
284 if(_sink != null) _sink.close();
285 }
286
287 void add(List<int> chunk) {
288 addSlice(chunk, 0, chunk.length, false);
289 }
290
291 void addSlice(List<int> codeUnits, int startIndex, int endIndex,
292 bool isLast) {
293 _decoder.convert(codeUnits, startIndex, endIndex);
294 if (isLast) close();
295 }
296 }
297
298 /**
299 * Decodes UTF-8 code units.
300 *
301 * Forwards the decoded strings to the given [StringConversionSink].
302 */
303 // TODO(floitsch): make this class public?
304 class _Utf8ConversionSink extends ByteConversionSink {
305
306 final _Utf8Decoder _decoder;
307 final StringConversionSink _chunkedSink;
308 final StringBuffer _buffer;
309 _Utf8ConversionSink(StringConversionSink sink, bool allowMalformed)
310 : this._(sink, new StringBuffer(), allowMalformed);
311
312 _Utf8ConversionSink._(this._chunkedSink, StringBuffer stringBuffer,
313 bool allowMalformed)
314 : _decoder = new _Utf8Decoder(stringBuffer, allowMalformed),
315 _buffer = stringBuffer;
316
317 void close() {
318 _decoder.close();
319 if (_buffer.isNotEmpty) {
320 String accumulated = _buffer.toString();
321 _buffer.clear();
322 _chunkedSink.addSlice(accumulated, 0, accumulated.length, true);
323 } else {
324 _chunkedSink.close();
325 }
326 }
327
328 void add(List<int> chunk) {
329 addSlice(chunk, 0, chunk.length, false);
330 }
331
332 void addSlice(List<int> chunk, int startIndex, int endIndex, bool isLast) {
333 _decoder.convert(chunk, startIndex, endIndex);
334 if (_buffer.isNotEmpty) {
335 String accumulated = _buffer.toString();
336 _chunkedSink.addSlice(accumulated, 0, accumulated.length, isLast);
337 _buffer.clear();
338 return;
339 }
340 if (isLast) close();
341 }
342 }
OLDNEW
« no previous file with comments | « pkg/dev_compiler/tool/input_sdk/lib/convert/line_splitter.dart ('k') | pkg/dev_compiler/tool/input_sdk/lib/convert/utf.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698