|  | // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file | 
|  | // for details. All rights reserved. Use of this source code is governed by a | 
|  | // BSD-style license that can be found in the LICENSE file. | 
|  |  | 
|  | part of dart.io; | 
|  |  | 
|  | /** | 
|  | * Basic input stream which supplies binary data. | 
|  | * | 
|  | * Input streams are used to read data sequentially from some data | 
|  | * source. All input streams are non-blocking. They each have a number | 
|  | * of read calls which will always return without any IO related | 
|  | * blocking. If the requested data is not available a read call will | 
|  | * return `null`. All input streams have one or more handlers which | 
|  | * will trigger when data is available. | 
|  | * | 
|  | * The following example shows a data handler in an ordinary input | 
|  | * stream which will be called when some data is available and a call | 
|  | * to read will not return `null`. | 
|  | * | 
|  | *     InputStream input = ... | 
|  | *     input.onData = () { | 
|  | *       var data = input.read(); | 
|  | *       ... | 
|  | *     }; | 
|  | * | 
|  | * If for some reason the data from an input stream cannot be handled | 
|  | * by the application immediately setting the data handler to `null` | 
|  | * will avoid further callbacks until it is set to a function | 
|  | * again. While the data handler is not active system flow control | 
|  | * will be used to avoid buffering more data than needed. | 
|  | * | 
|  | * Always set up appropriate handlers when using input streams. | 
|  | * | 
|  | */ | 
|  | abstract class InputStream { | 
|  | /** | 
|  | * Reads data from the stream. Returns a system allocated buffer | 
|  | * with up to [len] bytes. If no value is passed for [len] all | 
|  | * available data will be returned. If no data is available null will | 
|  | * be returned. | 
|  | */ | 
|  | List<int> read([int len]); | 
|  |  | 
|  | /** | 
|  | * Reads up to [len] bytes into buffer [buffer] starting at offset | 
|  | * [offset]. Returns the number of bytes actually read which might | 
|  | * be zero. If [offset] is not specified 0 is used. If [len] is not | 
|  | * specified the length of [buffer] is used. | 
|  | */ | 
|  | int readInto(List<int> buffer, [int offset, int len]); | 
|  |  | 
|  | /** | 
|  | * Returns the number of bytes available for immediate reading. | 
|  | */ | 
|  | int available(); | 
|  |  | 
|  | /** | 
|  | * Pipe the content of this input stream directly to the output | 
|  | * stream [output]. The default behavior is to close the output when | 
|  | * all the data from the input stream have been written. Specifying | 
|  | * `false` for the optional argument [close] keeps the output | 
|  | * stream open after writing all data from the input stream. | 
|  | */ | 
|  | void pipe(OutputStream output, {bool close: true}); | 
|  |  | 
|  | /** | 
|  | * Close the underlying communication channel to avoid getting any | 
|  | * more data. In normal situations, where all data is read from the | 
|  | * stream until the close handler is called, calling [close] is not | 
|  | * required. When [close] is used the close handler will still be | 
|  | * called. | 
|  | */ | 
|  | void close(); | 
|  |  | 
|  | /** | 
|  | * Returns whether the stream is closed. There will be no more data | 
|  | * to read. | 
|  | */ | 
|  | bool get closed; | 
|  |  | 
|  | /** | 
|  | * Sets the handler that gets called when data is available. | 
|  | */ | 
|  | void set onData(void callback()); | 
|  |  | 
|  | /** | 
|  | * Sets the handler that gets called when there will be no more data | 
|  | * available in the stream. | 
|  | */ | 
|  | void set onClosed(void callback()); | 
|  |  | 
|  | /** | 
|  | * Sets the handler that gets called when the underlying | 
|  | * communication channel gets into some kind of error situation. | 
|  | */ | 
|  | void set onError(void callback(e)); | 
|  | } | 
|  |  | 
|  |  | 
|  | /** | 
|  | * String encodings. | 
|  | */ | 
|  | class Encoding { | 
|  | static const Encoding UTF_8 = const Encoding._internal("UTF-8"); | 
|  | static const Encoding ISO_8859_1 = const Encoding._internal("ISO-8859-1"); | 
|  | static const Encoding ASCII = const Encoding._internal("ASCII"); | 
|  | /** | 
|  | * SYSTEM encoding is the current code page on Windows and UTF-8 on | 
|  | * Linux and Mac. | 
|  | */ | 
|  | static const Encoding SYSTEM = const Encoding._internal("SYSTEM"); | 
|  | const Encoding._internal(String this.name); | 
|  | final String name; | 
|  | } | 
|  |  | 
|  |  | 
|  | /** | 
|  | * A string input stream wraps a basic input stream and supplies | 
|  | * string data. This data can be read either as string chunks or as | 
|  | * lines separated by line termination character sequences. | 
|  | */ | 
|  | abstract class StringInputStream { | 
|  | /** | 
|  | * Decodes a binary input stream into characters using the specified | 
|  | * encoding. | 
|  | */ | 
|  | factory StringInputStream(InputStream input, | 
|  | [Encoding encoding = Encoding.UTF_8]) { | 
|  | return new _StringInputStream(input, encoding); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Reads up to [len] characters from the stream. if [len] is not | 
|  | * specified reads as many characters as is available from the | 
|  | * stream. If no data is available null will be returned. | 
|  | */ | 
|  | String read([int len]); | 
|  |  | 
|  | /** | 
|  | * Reads the next line from the stream. The line ending characters | 
|  | * will not be part of the returned string. If a full line is not | 
|  | * available null will be returned. | 
|  | */ | 
|  | String readLine(); | 
|  |  | 
|  | /** | 
|  | * Returns the number of characters available for immediate | 
|  | * reading. Note that this includes all characters that will be in | 
|  | * the String returned from [read] this includes line breaking | 
|  | * characters. If [readLine] is used for reading one can observe | 
|  | * less characters being returned as the line breaking characters | 
|  | * are discarded. | 
|  | */ | 
|  | int available(); | 
|  |  | 
|  | /** | 
|  | * Returns whether the stream has been closed. There might still be | 
|  | * more data to read. | 
|  | */ | 
|  | bool get closed; | 
|  |  | 
|  | /** | 
|  | * Returns the encoding used to decode the binary data into characters. | 
|  | */ | 
|  | Encoding get encoding; | 
|  |  | 
|  | /** | 
|  | * Sets the handler that gets called when data is available. The two | 
|  | * handlers [onData] and [onLine] are mutually exclusive | 
|  | * and setting one will remove the other. | 
|  | */ | 
|  | void set onData(void callback()); | 
|  |  | 
|  | /** | 
|  | * Sets the handler that gets called when a line is available. The | 
|  | * two handlers [onData] and [onLine] are mutually | 
|  | * exclusive and setting one will remove the other. | 
|  | */ | 
|  | void set onLine(void callback()); | 
|  |  | 
|  | /** | 
|  | * Sets the handler that gets called when there will be no more data | 
|  | * available in the stream. | 
|  | */ | 
|  | void set onClosed(void callback()); | 
|  |  | 
|  | /** | 
|  | * Sets the handler that gets called when the underlying | 
|  | * communication channel gets into some kind of error situation. | 
|  | */ | 
|  | void set onError(void callback(e)); | 
|  | } | 
|  |  | 
|  |  | 
|  | /** | 
|  | * A chunked input stream wraps a basic input stream and supplies | 
|  | * binary data in configurable chunk sizes. | 
|  | */ | 
|  | abstract class ChunkedInputStream { | 
|  | /** | 
|  | * Adds buffering to an input stream and provide the ability to read | 
|  | * the data in known size chunks. | 
|  | */ | 
|  | factory ChunkedInputStream(InputStream input, [int chunkSize = 0]) { | 
|  | return new _ChunkedInputStream(input, chunkSize); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Reads [chunkSize] bytes from the stream. If [chunkSize] bytes are | 
|  | * not currently available null is returned. When the stream is | 
|  | * closed the last call can return with less than [chunkSize] bytes. | 
|  | */ | 
|  | List<int> read(); | 
|  |  | 
|  | /** | 
|  | * Returns whether the stream has been closed. There might still be | 
|  | * more data to read. | 
|  | */ | 
|  | bool get closed; | 
|  |  | 
|  | /** | 
|  | * Returns the chunk size used by this stream. | 
|  | */ | 
|  | int get chunkSize; | 
|  |  | 
|  | /** | 
|  | * Sets the chunk size used by this stream. | 
|  | */ | 
|  | void set chunkSize(int chunkSize); | 
|  |  | 
|  | /** | 
|  | * Sets the handler that gets called when at least [chunkSize] bytes | 
|  | * of data is available or the underlying stream has been closed and | 
|  | * there is still unread data. | 
|  | */ | 
|  | void set onData(void callback()); | 
|  |  | 
|  | /** | 
|  | * Sets the handler that gets called when there will be no more data | 
|  | * available in the stream. | 
|  | */ | 
|  | void set onClosed(void callback()); | 
|  |  | 
|  | /** | 
|  | * Sets the handler that gets called when the underlying | 
|  | * communication channel gets into some kind of error situation. | 
|  | */ | 
|  | void set onError(void callback(e)); | 
|  | } | 
|  |  | 
|  |  | 
|  | class StreamException implements Exception { | 
|  | const StreamException([String this.message = ""]); | 
|  | const StreamException.streamClosed() : message = "Stream closed"; | 
|  | String toString() => "StreamException: $message"; | 
|  | final String message; | 
|  | } |