1 /*
2  * Hunt - A refined core library for D programming language.
3  *
4  * Copyright (C) 2018-2019 HuntLabs
5  *
6  * Website: https://www.huntlabs.net/
7  *
8  * Licensed under the Apache-2.0 License.
9  *
10  */
11 
12 module hunt.io.Common;
13 
14 import hunt.collection.ByteBuffer;
15 import hunt.Exceptions;
16 import hunt.util.Common;
17 import hunt.logging;
18 import hunt.concurrency.CountingCallback;
19 
20 import std.algorithm;
21 
22 
23 /**
24  * Serializability of a class is enabled by the class implementing the
25  * java.io.Serializable interface.
26  *
27  * <p><strong>Warning: Deserialization of untrusted data is inherently dangerous
28  * and should be avoided. Untrusted data should be carefully validated according to the
29  * "Serialization and Deserialization" section of the
30  * {@extLink secure_coding_guidelines_javase Secure Coding Guidelines for Java SE}.
31  * {@extLink serialization_filter_guide Serialization Filtering} describes best
32  * practices for defensive use of serial filters.
33  * </strong></p>
34  *
35  * Classes that do not implement this
36  * interface will not have any of their state serialized or
37  * deserialized.  All subtypes of a serializable class are themselves
38  * serializable.  The serialization interface has no methods or fields
39  * and serves only to identify the semantics of being serializable. <p>
40  *
41  * To allow subtypes of non-serializable classes to be serialized, the
42  * subtype may assume responsibility for saving and restoring the
43  * state of the supertype's public, protected, and (if accessible)
44  * package fields.  The subtype may assume this responsibility only if
45  * the class it extends has an accessible no-arg constructor to
46  * initialize the class's state.  It is an error to declare a class
47  * Serializable if this is not the case.  The error will be detected at
48  * runtime. <p>
49  *
50  * During deserialization, the fields of non-serializable classes will
51  * be initialized using the public or protected no-arg constructor of
52  * the class.  A no-arg constructor must be accessible to the subclass
53  * that is serializable.  The fields of serializable subclasses will
54  * be restored from the stream. <p>
55  *
56  * When traversing a graph, an object may be encountered that does not
57  * support the Serializable interface. In this case the
58  * NotSerializableException will be thrown and will identify the class
59  * of the non-serializable object. <p>
60  *
61  * Classes that require special handling during the serialization and
62  * deserialization process must implement special methods with these exact
63  * signatures:
64  *
65  * <PRE>
66  * private void writeObject(java.io.ObjectOutputStream out)
67  *     throws IOException
68  * private void readObject(java.io.ObjectInputStream in)
69  *     throws IOException, ClassNotFoundException;
70  * private void readObjectNoData()
71  *     throws ObjectStreamException;
72  * </PRE>
73  *
74  * <p>The writeObject method is responsible for writing the state of the
75  * object for its particular class so that the corresponding
76  * readObject method can restore it.  The default mechanism for saving
77  * the Object's fields can be invoked by calling
78  * out.defaultWriteObject. The method does not need to concern
79  * itself with the state belonging to its superclasses or subclasses.
80  * State is saved by writing the individual fields to the
81  * ObjectOutputStream using the writeObject method or by using the
82  * methods for primitive data types supported by DataOutput.
83  *
84  * <p>The readObject method is responsible for reading from the stream and
85  * restoring the classes fields. It may call in.defaultReadObject to invoke
86  * the default mechanism for restoring the object's non-static and
87  * non-transient fields.  The defaultReadObject method uses information in
88  * the stream to assign the fields of the object saved in the stream with the
89  * correspondingly named fields in the current object.  This handles the case
90  * when the class has evolved to add new fields. The method does not need to
91  * concern itself with the state belonging to its superclasses or subclasses.
92  * State is restored by reading data from the ObjectInputStream for
93  * the individual fields and making assignments to the appropriate fields
94  * of the object. Reading primitive data types is supported by DataInput.
95  *
96  * <p>The readObjectNoData method is responsible for initializing the state of
97  * the object for its particular class in the event that the serialization
98  * stream does not list the given class as a superclass of the object being
99  * deserialized.  This may occur in cases where the receiving party uses a
100  * different version of the deserialized instance's class than the sending
101  * party, and the receiver's version extends classes that are not extended by
102  * the sender's version.  This may also occur if the serialization stream has
103  * been tampered; hence, readObjectNoData is useful for initializing
104  * deserialized objects properly despite a "hostile" or incomplete source
105  * stream.
106  *
107  * <p>Serializable classes that need to designate an alternative object to be
108  * used when writing an object to the stream should implement this
109  * special method with the exact signature:
110  *
111  * <PRE>
112  * ANY-ACCESS-MODIFIER Object writeReplace() throws ObjectStreamException;
113  * </PRE><p>
114  *
115  * This writeReplace method is invoked by serialization if the method
116  * exists and it would be accessible from a method defined within the
117  * class of the object being serialized. Thus, the method can have private,
118  * protected and package-private access. Subclass access to this method
119  * follows java accessibility rules. <p>
120  *
121  * Classes that need to designate a replacement when an instance of it
122  * is read from the stream should implement this special method with the
123  * exact signature.
124  *
125  * <PRE>
126  * ANY-ACCESS-MODIFIER Object readResolve() throws ObjectStreamException;
127  * </PRE><p>
128  *
129  * This readResolve method follows the same invocation rules and
130  * accessibility rules as writeReplace.<p>
131  *
132  * The serialization runtime associates with each serializable class a version
133  * number, called a serialVersionUID, which is used during deserialization to
134  * verify that the sender and receiver of a serialized object have loaded
135  * classes for that object that are compatible with respect to serialization.
136  * If the receiver has loaded a class for the object that has a different
137  * serialVersionUID than that of the corresponding sender's class, then
138  * deserialization will result in an {@link InvalidClassException}.  A
139  * serializable class can declare its own serialVersionUID explicitly by
140  * declaring a field named <code>"serialVersionUID"</code> that must be static,
141  * final, and of type <code>long</code>:
142  *
143  * <PRE>
144  * ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L;
145  * </PRE>
146  *
147  * If a serializable class does not explicitly declare a serialVersionUID, then
148  * the serialization runtime will calculate a default serialVersionUID value
149  * for that class based on various aspects of the class, as described in the
150  * Java(TM) Object Serialization Specification.  However, it is <em>strongly
151  * recommended</em> that all serializable classes explicitly declare
152  * serialVersionUID values, since the default serialVersionUID computation is
153  * highly sensitive to class details that may vary depending on compiler
154  * implementations, and can thus result in unexpected
155  * <code>InvalidClassException</code>s during deserialization.  Therefore, to
156  * guarantee a consistent serialVersionUID value across different java compiler
157  * implementations, a serializable class must declare an explicit
158  * serialVersionUID value.  It is also strongly advised that explicit
159  * serialVersionUID declarations use the <code>private</code> modifier where
160  * possible, since such declarations apply only to the immediately declaring
161  * class--serialVersionUID fields are not useful as inherited members. Array
162  * classes cannot declare an explicit serialVersionUID, so they always have
163  * the default computed value, but the requirement for matching
164  * serialVersionUID values is waived for array classes.
165  *
166  */
167 interface Serializable {
168 
169 }
170 
171 /**
172  * This abstract class is the superclass of all classes representing
173  * an input stream of bytes.
174  *
175  * <p> Applications that need to define a subclass of <code>InputStream</code>
176  * must always provide a method that returns the next byte of input.
177  *
178  * @author  Arthur van Hoff
179  * @see     java.io.BufferedInputStream
180  * @see     java.io.ByteArrayInputStream
181  * @see     java.io.DataInputStream
182  * @see     java.io.FilterInputStream
183  * @see     java.io.InputStream#read()
184  * @see     java.io.OutputStream
185  * @see     java.io.PushbackInputStream
186  * @since   JDK1.0
187  */
188 abstract class InputStream : Closeable {
189 
190     // MAX_SKIP_BUFFER_SIZE is used to determine the maximum buffer size to
191     // use when skipping.
192     private enum int MAX_SKIP_BUFFER_SIZE = 2048;
193 
194     /**
195      * Reads the next byte of data from the input stream. The value byte is
196      * returned as an <code>int</code> in the range <code>0</code> to
197      * <code>255</code>. If no byte is available because the end of the stream
198      * has been reached, the value <code>-1</code> is returned. This method
199      * blocks until input data is available, the end of the stream is detected,
200      * or an exception is thrown.
201      *
202      * <p> A subclass must provide an implementation of this method.
203      *
204      * @return     the next byte of data, or <code>-1</code> if the end of the
205      *             stream is reached.
206      * @exception  IOException  if an I/O error occurs.
207      */
208     abstract int read();
209 
210     /**
211      * Reads some number of bytes from the input stream and stores them into
212      * the buffer array <code>b</code>. The number of bytes actually read is
213      * returned as an integer.  This method blocks until input data is
214      * available, end of file is detected, or an exception is thrown.
215      *
216      * <p> If the length of <code>b</code> is zero, then no bytes are read and
217      * <code>0</code> is returned; otherwise, there is an attempt to read at
218      * least one byte. If no byte is available because the stream is at the
219      * end of the file, the value <code>-1</code> is returned; otherwise, at
220      * least one byte is read and stored into <code>b</code>.
221      *
222      * <p> The first byte read is stored into element <code>b[0]</code>, the
223      * next one into <code>b[1]</code>, and so on. The number of bytes read is,
224      * at most, equal to the length of <code>b</code>. Let <i>k</i> be the
225      * number of bytes actually read; these bytes will be stored in elements
226      * <code>b[0]</code> through <code>b[</code><i>k</i><code>-1]</code>,
227      * leaving elements <code>b[</code><i>k</i><code>]</code> through
228      * <code>b[b.length-1]</code> unaffected.
229      *
230      * <p> The <code>read(b)</code> method for class <code>InputStream</code>
231      * has the same effect as: <pre><code> read(b, 0, b.length) </code></pre>
232      *
233      * @param      b   the buffer into which the data is read.
234      * @return     the total number of bytes read into the buffer, or
235      *             <code>-1</code> if there is no more data because the end of
236      *             the stream has been reached.
237      * @exception  IOException  If the first byte cannot be read for any reason
238      * other than the end of the file, if the input stream has been closed, or
239      * if some other I/O error occurs.
240      * @exception  NullPointerException  if <code>b</code> is <code>null</code>.
241      * @see        java.io.InputStream#read(byte[], int, int)
242      */
243     int read(byte[] b) {
244         return read(b, 0, cast(int)b.length);
245     }
246 
247     /**
248      * Reads up to <code>len</code> bytes of data from the input stream into
249      * an array of bytes.  An attempt is made to read as many as
250      * <code>len</code> bytes, but a smaller number may be read.
251      * The number of bytes actually read is returned as an integer.
252      *
253      * <p> This method blocks until input data is available, end of file is
254      * detected, or an exception is thrown.
255      *
256      * <p> If <code>len</code> is zero, then no bytes are read and
257      * <code>0</code> is returned; otherwise, there is an attempt to read at
258      * least one byte. If no byte is available because the stream is at end of
259      * file, the value <code>-1</code> is returned; otherwise, at least one
260      * byte is read and stored into <code>b</code>.
261      *
262      * <p> The first byte read is stored into element <code>b[off]</code>, the
263      * next one into <code>b[off+1]</code>, and so on. The number of bytes read
264      * is, at most, equal to <code>len</code>. Let <i>k</i> be the number of
265      * bytes actually read; these bytes will be stored in elements
266      * <code>b[off]</code> through <code>b[off+</code><i>k</i><code>-1]</code>,
267      * leaving elements <code>b[off+</code><i>k</i><code>]</code> through
268      * <code>b[off+len-1]</code> unaffected.
269      *
270      * <p> In every case, elements <code>b[0]</code> through
271      * <code>b[off]</code> and elements <code>b[off+len]</code> through
272      * <code>b[b.length-1]</code> are unaffected.
273      *
274      * <p> The <code>read(b,</code> <code>off,</code> <code>len)</code> method
275      * for class <code>InputStream</code> simply calls the method
276      * <code>read()</code> repeatedly. If the first such call results in an
277      * <code>IOException</code>, that exception is returned from the call to
278      * the <code>read(b,</code> <code>off,</code> <code>len)</code> method.  If
279      * any subsequent call to <code>read()</code> results in a
280      * <code>IOException</code>, the exception is caught and treated as if it
281      * were end of file; the bytes read up to that point are stored into
282      * <code>b</code> and the number of bytes read before the exception
283      * occurred is returned. The default implementation of this method blocks
284      * until the requested amount of input data <code>len</code> has been read,
285      * end of file is detected, or an exception is thrown. Subclasses are encouraged
286      * to provide a more efficient implementation of this method.
287      *
288      * @param      b     the buffer into which the data is read.
289      * @param      off   the start offset in array <code>b</code>
290      *                   at which the data is written.
291      * @param      len   the maximum number of bytes to read.
292      * @return     the total number of bytes read into the buffer, or
293      *             <code>-1</code> if there is no more data because the end of
294      *             the stream has been reached.
295      * @exception  IOException If the first byte cannot be read for any reason
296      * other than end of file, or if the input stream has been closed, or if
297      * some other I/O error occurs.
298      * @exception  NullPointerException If <code>b</code> is <code>null</code>.
299      * @exception  IndexOutOfBoundsException If <code>off</code> is negative,
300      * <code>len</code> is negative, or <code>len</code> is greater than
301      * <code>b.length - off</code>
302      * @see        java.io.InputStream#read()
303      */
304     int read(byte[] b, int off, int len) {
305         if (b is null) {
306             throw new NullPointerException("");
307         } else if (off < 0 || len < 0 || len > b.length - off) {
308             throw new IndexOutOfBoundsException("");
309         } else if (len == 0) {
310             return 0;
311         }
312 
313         int c = read();
314         if (c == -1) {
315             return -1;
316         }
317         b[off] = cast(byte)c;
318 
319         int i = 1;
320         try {
321             for (; i < len ; i++) {
322                 c = read();
323                 if (c == -1) {
324                     break;
325                 }
326                 b[off + i] = cast(byte)c;
327             }
328         } catch (IOException ee) {
329         }
330         return i;
331     }
332 
333     /**
334      * Skips over and discards <code>n</code> bytes of data from this input
335      * stream. The <code>skip</code> method may, for a variety of reasons, end
336      * up skipping over some smaller number of bytes, possibly <code>0</code>.
337      * This may result from any of a number of conditions; reaching end of file
338      * before <code>n</code> bytes have been skipped is only one possibility.
339      * The actual number of bytes skipped is returned. If {@code n} is
340      * negative, the {@code skip} method for class {@code InputStream} always
341      * returns 0, and no bytes are skipped. Subclasses may handle the negative
342      * value differently.
343      *
344      * <p> The <code>skip</code> method of this class creates a
345      * byte array and then repeatedly reads into it until <code>n</code> bytes
346      * have been read or the end of the stream has been reached. Subclasses are
347      * encouraged to provide a more efficient implementation of this method.
348      * For instance, the implementation may depend on the ability to seek.
349      *
350      * @param      n   the number of bytes to be skipped.
351      * @return     the actual number of bytes skipped.
352      * @exception  IOException  if the stream does not support seek,
353      *                          or if some other I/O error occurs.
354      */
355     long skip(long n) {
356         long remaining = n;
357         int nr;
358 
359         if (n <= 0) {
360             return 0;
361         }
362 
363         int size = cast(int)min(MAX_SKIP_BUFFER_SIZE, remaining);
364         byte[] skipBuffer = new byte[size];
365         while (remaining > 0) {
366             nr = read(skipBuffer, 0, cast(int)min(size, remaining));
367             if (nr < 0) {
368                 break;
369             }
370             remaining -= nr;
371         }
372 
373         return n - remaining;
374     }
375 
376     /**
377      * Returns an estimate of the number of bytes that can be read (or
378      * skipped over) from this input stream without blocking by the next
379      * invocation of a method for this input stream. The next invocation
380      * might be the same thread or another thread.  A single read or skip of this
381      * many bytes will not block, but may read or skip fewer bytes.
382      *
383      * <p> Note that while some implementations of {@code InputStream} will return
384      * the total number of bytes in the stream, many will not.  It is
385      * never correct to use the return value of this method to allocate
386      * a buffer intended to hold all data in this stream.
387      *
388      * <p> A subclass' implementation of this method may choose to throw an
389      * {@link IOException} if this input stream has been closed by
390      * invoking the {@link #close()} method.
391      *
392      * <p> The {@code available} method for class {@code InputStream} always
393      * returns {@code 0}.
394      *
395      * <p> This method should be overridden by subclasses.
396      *
397      * @return     an estimate of the number of bytes that can be read (or skipped
398      *             over) from this input stream without blocking or {@code 0} when
399      *             it reaches the end of the input stream.
400      * @exception  IOException if an I/O error occurs.
401      */
402     int available() { // @trusted nothrow 
403         return 0;
404     }
405 
406     /**
407      * Closes this input stream and releases any system resources associated
408      * with the stream.
409      *
410      * <p> The <code>close</code> method of <code>InputStream</code> does
411      * nothing.
412      *
413      * @exception  IOException  if an I/O error occurs.
414      */
415     void close() {}
416 
417     /**
418      * Marks the current position in this input stream. A subsequent call to
419      * the <code>reset</code> method repositions this stream at the last marked
420      * position so that subsequent reads re-read the same bytes.
421      *
422      * <p> The <code>readlimit</code> arguments tells this input stream to
423      * allow that many bytes to be read before the mark position gets
424      * invalidated.
425      *
426      * <p> The general contract of <code>mark</code> is that, if the method
427      * <code>markSupported</code> returns <code>true</code>, the stream somehow
428      * remembers all the bytes read after the call to <code>mark</code> and
429      * stands ready to supply those same bytes again if and whenever the method
430      * <code>reset</code> is called.  However, the stream is not required to
431      * remember any data at all if more than <code>readlimit</code> bytes are
432      * read from the stream before <code>reset</code> is called.
433      *
434      * <p> Marking a closed stream should not have any effect on the stream.
435      *
436      * <p> The <code>mark</code> method of <code>InputStream</code> does
437      * nothing.
438      *
439      * @param   readlimit   the maximum limit of bytes that can be read before
440      *                      the mark position becomes invalid.
441      * @see     java.io.InputStream#reset()
442      */
443     void mark(int readlimit) {}
444 
445     /**
446      * Repositions this stream to the position at the time the
447      * <code>mark</code> method was last called on this input stream.
448      *
449      * <p> The general contract of <code>reset</code> is:
450      *
451      * <ul>
452      * <li> If the method <code>markSupported</code> returns
453      * <code>true</code>, then:
454      *
455      *     <ul><li> If the method <code>mark</code> has not been called since
456      *     the stream was created, or the number of bytes read from the stream
457      *     since <code>mark</code> was last called is larger than the argument
458      *     to <code>mark</code> at that last call, then an
459      *     <code>IOException</code> might be thrown.
460      *
461      *     <li> If such an <code>IOException</code> is not thrown, then the
462      *     stream is reset to a state such that all the bytes read since the
463      *     most recent call to <code>mark</code> (or since the start of the
464      *     file, if <code>mark</code> has not been called) will be resupplied
465      *     to subsequent callers of the <code>read</code> method, followed by
466      *     any bytes that otherwise would have been the next input data as of
467      *     the time of the call to <code>reset</code>. </ul>
468      *
469      * <li> If the method <code>markSupported</code> returns
470      * <code>false</code>, then:
471      *
472      *     <ul><li> The call to <code>reset</code> may throw an
473      *     <code>IOException</code>.
474      *
475      *     <li> If an <code>IOException</code> is not thrown, then the stream
476      *     is reset to a fixed state that depends on the particular type of the
477      *     input stream and how it was created. The bytes that will be supplied
478      *     to subsequent callers of the <code>read</code> method depend on the
479      *     particular type of the input stream. </ul></ul>
480      *
481      * <p>The method <code>reset</code> for class <code>InputStream</code>
482      * does nothing except throw an <code>IOException</code>.
483      *
484      * @exception  IOException  if this stream has not been marked or if the
485      *               mark has been invalidated.
486      * @see     java.io.InputStream#mark(int)
487      * @see     java.io.IOException
488      */
489     void reset() {
490         throw new IOException("mark/reset not supported");
491     }
492 
493     /**
494      * Tests if this input stream supports the <code>mark</code> and
495      * <code>reset</code> methods. Whether or not <code>mark</code> and
496      * <code>reset</code> are supported is an invariant property of a
497      * particular input stream instance. The <code>markSupported</code> method
498      * of <code>InputStream</code> returns <code>false</code>.
499      *
500      * @return  <code>true</code> if this stream instance supports the mark
501      *          and reset methods; <code>false</code> otherwise.
502      * @see     java.io.InputStream#mark(int)
503      * @see     java.io.InputStream#reset()
504      */
505     bool markSupported() {
506         return false;
507     }
508 
509 }
510 
511 
512 /**
513  * This abstract class is the superclass of all classes representing
514  * an output stream of bytes. An output stream accepts output bytes
515  * and sends them to some sink.
516  * <p>
517  * Applications that need to define a subclass of
518  * <code>OutputStream</code> must always provide at least a method
519  * that writes one byte of output.
520  *
521  * @author  Arthur van Hoff
522  * @see     java.io.BufferedOutputStream
523  * @see     java.io.ByteArrayOutputStream
524  * @see     java.io.DataOutputStream
525  * @see     java.io.FilterOutputStream
526  * @see     java.io.InputStream
527  * @see     java.io.OutputStream#write(int)
528  * @since   JDK1.0
529  */
530 abstract class OutputStream : Closeable  { // implements  Flushable
531     /**
532      * Writes the specified byte to this output stream. The general
533      * contract for <code>write</code> is that one byte is written
534      * to the output stream. The byte to be written is the eight
535      * low-order bits of the argument <code>b</code>. The 24
536      * high-order bits of <code>b</code> are ignored.
537      * <p>
538      * Subclasses of <code>OutputStream</code> must provide an
539      * implementation for this method.
540      *
541      * @param      b   the <code>byte</code>.
542      * @exception  IOException  if an I/O error occurs. In particular,
543      *             an <code>IOException</code> may be thrown if the
544      *             output stream has been closed.
545      */
546     abstract void write(int b) ;
547 
548     void write(string b) {
549         write(cast(byte[])b, 0, cast(int)b.length);
550     }
551 
552     /**
553      * Writes <code>b.length</code> bytes from the specified byte array
554      * to this output stream. The general contract for <code>write(b)</code>
555      * is that it should have exactly the same effect as the call
556      * <code>write(b, 0, b.length)</code>.
557      *
558      * @param      b   the data.
559      * @exception  IOException  if an I/O error occurs.
560      * @see        java.io.OutputStream#write(byte[], int, int)
561      */
562     void write(byte[] b)  {
563         write(b, 0, cast(int)b.length);
564     }
565 
566     /**
567      * Writes <code>len</code> bytes from the specified byte array
568      * starting at offset <code>off</code> to this output stream.
569      * The general contract for <code>write(b, off, len)</code> is that
570      * some of the bytes in the array <code>b</code> are written to the
571      * output stream in order; element <code>b[off]</code> is the first
572      * byte written and <code>b[off+len-1]</code> is the last byte written
573      * by this operation.
574      * <p>
575      * The <code>write</code> method of <code>OutputStream</code> calls
576      * the write method of one argument on each of the bytes to be
577      * written out. Subclasses are encouraged to override this method and
578      * provide a more efficient implementation.
579      * <p>
580      * If <code>b</code> is <code>null</code>, a
581      * <code>NullPointerException</code> is thrown.
582      * <p>
583      * If <code>off</code> is negative, or <code>len</code> is negative, or
584      * <code>off+len</code> is greater than the length of the array
585      * <code>b</code>, then an <tt>IndexOutOfBoundsException</tt> is thrown.
586      *
587      * @param      b     the data.
588      * @param      off   the start offset in the data.
589      * @param      len   the number of bytes to write.
590      * @exception  IOException  if an I/O error occurs. In particular,
591      *             an <code>IOException</code> is thrown if the output
592      *             stream is closed.
593      */
594     void write(byte[] b, int off, int len) {
595         int bufferSize = cast(int)b.length;
596         if (b is null) {
597             throw new NullPointerException("");
598         } else if ((off < 0) || (off > bufferSize) || (len < 0) ||
599                    ((off + len) > bufferSize) || ((off + len) < 0)) {
600             import std.format;
601             string msg = format("buffer error, size: %d, offset: %d, length: %d",
602                 bufferSize, off, len);
603             throw new IndexOutOfBoundsException(msg);
604         } else if (len == 0) {
605             return;
606         }
607         for (int i = 0 ; i < len ; i++) {
608             write(b[off + i]);
609         }
610     }
611 
612     /**
613      * Flushes this output stream and forces any buffered output bytes
614      * to be written out. The general contract of <code>flush</code> is
615      * that calling it is an indication that, if any bytes previously
616      * written have been buffered by the implementation of the output
617      * stream, such bytes should immediately be written to their
618      * intended destination.
619      * <p>
620      * If the intended destination of this stream is an abstraction provided by
621      * the underlying operating system, for example a file, then flushing the
622      * stream guarantees only that bytes previously written to the stream are
623      * passed to the operating system for writing; it does not guarantee that
624      * they are actually written to a physical device such as a disk drive.
625      * <p>
626      * The <code>flush</code> method of <code>OutputStream</code> does nothing.
627      *
628      * @exception  IOException  if an I/O error occurs.
629      */
630     void flush()  {
631     }
632 
633     /**
634      * Closes this output stream and releases any system resources
635      * associated with this stream. The general contract of <code>close</code>
636      * is that it closes the output stream. A closed stream cannot perform
637      * output operations and cannot be reopened.
638      * <p>
639      * The <code>close</code> method of <code>OutputStream</code> does nothing.
640      *
641      * @exception  IOException  if an I/O error occurs.
642      */
643     void close()  {
644     }
645 
646 }
647 
648 /**
649  * IO Utilities. Provides stream handling utilities in singleton Threadpool
650  * implementation accessed by static members.
651  */
652 // class IO {
653 
654 // 	enum string CRLF = "\015\012";
655 
656 // 	enum byte[] CRLF_BYTES = [ '\015', '\012' ];
657 
658 // 	enum int bufferSize = 64 * 1024;
659 
660 //     /**
661 // 	 * Closes an arbitrary closable, and logs exceptions at ignore level
662 // 	 *
663 // 	 * @param closeable
664 // 	 *            the closeable to close
665 // 	 */
666 // 	static void close(Closeable closeable) {
667 // 		try {
668 // 			if (closeable !is null)
669 // 				closeable.close();
670 // 		} catch (IOException ignore) {
671 // 		}
672 // 	}
673 // }
674 
675 
676 interface BufferReaderHandler {
677 	void readBuffer(ByteBuffer buf, CountingCallback countingCallback, long count);
678 }