diff -r d441042e6c11 -r 05224402145d emul/mini/src/main/java/java/io/DataInputStream.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/emul/mini/src/main/java/java/io/DataInputStream.java Wed Jan 23 20:39:23 2013 +0100 @@ -0,0 +1,704 @@ +/* + * Copyright (c) 1994, 2006, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.io; + +import org.apidesign.bck2brwsr.core.JavaScriptBody; + +/** + * A data input stream lets an application read primitive Java data + * types from an underlying input stream in a machine-independent + * way. An application uses a data output stream to write data that + * can later be read by a data input stream. + *

+ * DataInputStream is not necessarily safe for multithreaded access. + * Thread safety is optional and is the responsibility of users of + * methods in this class. + * + * @author Arthur van Hoff + * @see java.io.DataOutputStream + * @since JDK1.0 + */ +public +class DataInputStream extends FilterInputStream implements DataInput { + + /** + * Creates a DataInputStream that uses the specified + * underlying InputStream. + * + * @param in the specified input stream + */ + public DataInputStream(InputStream in) { + super(in); + } + + /** + * working arrays initialized on demand by readUTF + */ + private byte bytearr[] = new byte[80]; + private char chararr[] = new char[80]; + + /** + * Reads some number of bytes from the contained input stream and + * stores them into the buffer array b. The number of + * bytes actually read is returned as an integer. This method blocks + * until input data is available, end of file is detected, or an + * exception is thrown. + * + *

If b is null, a NullPointerException is + * thrown. If the length of b is zero, then no bytes are + * read and 0 is returned; otherwise, there is an attempt + * to read at least one byte. If no byte is available because the + * stream is at end of file, the value -1 is returned; + * otherwise, at least one byte is read and stored into b. + * + *

The first byte read is stored into element b[0], the + * next one into b[1], and so on. The number of bytes read + * is, at most, equal to the length of b. Let k + * be the number of bytes actually read; these bytes will be stored in + * elements b[0] through b[k-1], leaving + * elements b[k] through b[b.length-1] + * unaffected. + * + *

The read(b) method has the same effect as: + *

+     * read(b, 0, b.length)
+     * 
+ * + * @param b the buffer into which the data is read. + * @return the total number of bytes read into the buffer, or + * -1 if there is no more data because the end + * of the stream has been reached. + * @exception IOException if the first byte cannot be read for any reason + * other than end of file, the stream has been closed and the underlying + * input stream does not support reading after close, or another I/O + * error occurs. + * @see java.io.FilterInputStream#in + * @see java.io.InputStream#read(byte[], int, int) + */ + public final int read(byte b[]) throws IOException { + return in.read(b, 0, b.length); + } + + /** + * Reads up to len bytes of data from the contained + * input stream into an array of bytes. An attempt is made to read + * as many as len bytes, but a smaller number may be read, + * possibly zero. The number of bytes actually read is returned as an + * integer. + * + *

This method blocks until input data is available, end of file is + * detected, or an exception is thrown. + * + *

If len is zero, then no bytes are read and + * 0 is returned; otherwise, there is an attempt to read at + * least one byte. If no byte is available because the stream is at end of + * file, the value -1 is returned; otherwise, at least one + * byte is read and stored into b. + * + *

The first byte read is stored into element b[off], the + * next one into b[off+1], and so on. The number of bytes read + * is, at most, equal to len. Let k be the number of + * bytes actually read; these bytes will be stored in elements + * b[off] through b[off+k-1], + * leaving elements b[off+k] through + * b[off+len-1] unaffected. + * + *

In every case, elements b[0] through + * b[off] and elements b[off+len] through + * b[b.length-1] are unaffected. + * + * @param b the buffer into which the data is read. + * @param off the start offset in the destination array b + * @param len the maximum number of bytes read. + * @return the total number of bytes read into the buffer, or + * -1 if there is no more data because the end + * of the stream has been reached. + * @exception NullPointerException If b is null. + * @exception IndexOutOfBoundsException If off is negative, + * len is negative, or len is greater than + * b.length - off + * @exception IOException if the first byte cannot be read for any reason + * other than end of file, the stream has been closed and the underlying + * input stream does not support reading after close, or another I/O + * error occurs. + * @see java.io.FilterInputStream#in + * @see java.io.InputStream#read(byte[], int, int) + */ + public final int read(byte b[], int off, int len) throws IOException { + return in.read(b, off, len); + } + + /** + * See the general contract of the readFully + * method of DataInput. + *

+ * Bytes + * for this operation are read from the contained + * input stream. + * + * @param b the buffer into which the data is read. + * @exception EOFException if this input stream reaches the end before + * reading all the bytes. + * @exception IOException the stream has been closed and the contained + * input stream does not support reading after close, or + * another I/O error occurs. + * @see java.io.FilterInputStream#in + */ + public final void readFully(byte b[]) throws IOException { + readFully(b, 0, b.length); + } + + /** + * See the general contract of the readFully + * method of DataInput. + *

+ * Bytes + * for this operation are read from the contained + * input stream. + * + * @param b the buffer into which the data is read. + * @param off the start offset of the data. + * @param len the number of bytes to read. + * @exception EOFException if this input stream reaches the end before + * reading all the bytes. + * @exception IOException the stream has been closed and the contained + * input stream does not support reading after close, or + * another I/O error occurs. + * @see java.io.FilterInputStream#in + */ + public final void readFully(byte b[], int off, int len) throws IOException { + if (len < 0) + throw new IndexOutOfBoundsException(); + int n = 0; + while (n < len) { + int count = in.read(b, off + n, len - n); + if (count < 0) + throw new EOFException(); + n += count; + } + } + + /** + * See the general contract of the skipBytes + * method of DataInput. + *

+ * Bytes for this operation are read from the contained + * input stream. + * + * @param n the number of bytes to be skipped. + * @return the actual number of bytes skipped. + * @exception IOException if the contained input stream does not support + * seek, or the stream has been closed and + * the contained input stream does not support + * reading after close, or another I/O error occurs. + */ + public final int skipBytes(int n) throws IOException { + int total = 0; + int cur = 0; + + while ((total 0)) { + total += cur; + } + + return total; + } + + /** + * See the general contract of the readBoolean + * method of DataInput. + *

+ * Bytes for this operation are read from the contained + * input stream. + * + * @return the boolean value read. + * @exception EOFException if this input stream has reached the end. + * @exception IOException the stream has been closed and the contained + * input stream does not support reading after close, or + * another I/O error occurs. + * @see java.io.FilterInputStream#in + */ + public final boolean readBoolean() throws IOException { + int ch = in.read(); + if (ch < 0) + throw new EOFException(); + return (ch != 0); + } + + /** + * See the general contract of the readByte + * method of DataInput. + *

+ * Bytes + * for this operation are read from the contained + * input stream. + * + * @return the next byte of this input stream as a signed 8-bit + * byte. + * @exception EOFException if this input stream has reached the end. + * @exception IOException the stream has been closed and the contained + * input stream does not support reading after close, or + * another I/O error occurs. + * @see java.io.FilterInputStream#in + */ + public final byte readByte() throws IOException { + int ch = in.read(); + if (ch < 0) + throw new EOFException(); + return (byte)(ch); + } + + /** + * See the general contract of the readUnsignedByte + * method of DataInput. + *

+ * Bytes + * for this operation are read from the contained + * input stream. + * + * @return the next byte of this input stream, interpreted as an + * unsigned 8-bit number. + * @exception EOFException if this input stream has reached the end. + * @exception IOException the stream has been closed and the contained + * input stream does not support reading after close, or + * another I/O error occurs. + * @see java.io.FilterInputStream#in + */ + public final int readUnsignedByte() throws IOException { + int ch = in.read(); + if (ch < 0) + throw new EOFException(); + return ch; + } + + /** + * See the general contract of the readShort + * method of DataInput. + *

+ * Bytes + * for this operation are read from the contained + * input stream. + * + * @return the next two bytes of this input stream, interpreted as a + * signed 16-bit number. + * @exception EOFException if this input stream reaches the end before + * reading two bytes. + * @exception IOException the stream has been closed and the contained + * input stream does not support reading after close, or + * another I/O error occurs. + * @see java.io.FilterInputStream#in + */ + public final short readShort() throws IOException { + int ch1 = in.read(); + int ch2 = in.read(); + if ((ch1 | ch2) < 0) + throw new EOFException(); + return (short)((ch1 << 8) + (ch2 << 0)); + } + + /** + * See the general contract of the readUnsignedShort + * method of DataInput. + *

+ * Bytes + * for this operation are read from the contained + * input stream. + * + * @return the next two bytes of this input stream, interpreted as an + * unsigned 16-bit integer. + * @exception EOFException if this input stream reaches the end before + * reading two bytes. + * @exception IOException the stream has been closed and the contained + * input stream does not support reading after close, or + * another I/O error occurs. + * @see java.io.FilterInputStream#in + */ + public final int readUnsignedShort() throws IOException { + int ch1 = in.read(); + int ch2 = in.read(); + if ((ch1 | ch2) < 0) + throw new EOFException(); + return (ch1 << 8) + (ch2 << 0); + } + + /** + * See the general contract of the readChar + * method of DataInput. + *

+ * Bytes + * for this operation are read from the contained + * input stream. + * + * @return the next two bytes of this input stream, interpreted as a + * char. + * @exception EOFException if this input stream reaches the end before + * reading two bytes. + * @exception IOException the stream has been closed and the contained + * input stream does not support reading after close, or + * another I/O error occurs. + * @see java.io.FilterInputStream#in + */ + public final char readChar() throws IOException { + int ch1 = in.read(); + int ch2 = in.read(); + if ((ch1 | ch2) < 0) + throw new EOFException(); + return (char)((ch1 << 8) + (ch2 << 0)); + } + + /** + * See the general contract of the readInt + * method of DataInput. + *

+ * Bytes + * for this operation are read from the contained + * input stream. + * + * @return the next four bytes of this input stream, interpreted as an + * int. + * @exception EOFException if this input stream reaches the end before + * reading four bytes. + * @exception IOException the stream has been closed and the contained + * input stream does not support reading after close, or + * another I/O error occurs. + * @see java.io.FilterInputStream#in + */ + public final int readInt() throws IOException { + int ch1 = in.read(); + int ch2 = in.read(); + int ch3 = in.read(); + int ch4 = in.read(); + if ((ch1 | ch2 | ch3 | ch4) < 0) + throw new EOFException(); + return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0)); + } + + private byte readBuffer[] = new byte[8]; + + /** + * See the general contract of the readLong + * method of DataInput. + *

+ * Bytes + * for this operation are read from the contained + * input stream. + * + * @return the next eight bytes of this input stream, interpreted as a + * long. + * @exception EOFException if this input stream reaches the end before + * reading eight bytes. + * @exception IOException the stream has been closed and the contained + * input stream does not support reading after close, or + * another I/O error occurs. + * @see java.io.FilterInputStream#in + */ + public final long readLong() throws IOException { + readFully(readBuffer, 0, 8); + return (((long)readBuffer[0] << 56) + + ((long)(readBuffer[1] & 255) << 48) + + ((long)(readBuffer[2] & 255) << 40) + + ((long)(readBuffer[3] & 255) << 32) + + ((long)(readBuffer[4] & 255) << 24) + + ((readBuffer[5] & 255) << 16) + + ((readBuffer[6] & 255) << 8) + + ((readBuffer[7] & 255) << 0)); + } + + /** + * See the general contract of the readFloat + * method of DataInput. + *

+ * Bytes + * for this operation are read from the contained + * input stream. + * + * @return the next four bytes of this input stream, interpreted as a + * float. + * @exception EOFException if this input stream reaches the end before + * reading four bytes. + * @exception IOException the stream has been closed and the contained + * input stream does not support reading after close, or + * another I/O error occurs. + * @see java.io.DataInputStream#readInt() + * @see java.lang.Float#intBitsToFloat(int) + */ + public final float readFloat() throws IOException { + return Float.intBitsToFloat(readInt()); + } + + /** + * See the general contract of the readDouble + * method of DataInput. + *

+ * Bytes + * for this operation are read from the contained + * input stream. + * + * @return the next eight bytes of this input stream, interpreted as a + * double. + * @exception EOFException if this input stream reaches the end before + * reading eight bytes. + * @exception IOException the stream has been closed and the contained + * input stream does not support reading after close, or + * another I/O error occurs. + * @see java.io.DataInputStream#readLong() + * @see java.lang.Double#longBitsToDouble(long) + */ + public final double readDouble() throws IOException { + int hi = readInt(); + int low = readInt(); + return toDouble(hi, low); + } + + @JavaScriptBody(args={ "hi", "low" }, + body= + "if (low == 0) {\n" + + " if (hi === 0x7ff00000) return Number.POSITIVE_INFINITY;\n" + + " if (hi === 0xfff00000) return Number.NEGATIVE_INFINITY;\n" + + "}\n" + + "if (hi >= 0x7ff00000 && hi <= 0x7fffffff) return Number.NaN;\n" + + "if (hi >= 0xfff00000 && hi <= 0xffffffff) return Number.NaN;\n" + + "var s = (hi & 0x80000000) === 0 ? 1 : -1;\n" + + "var e = (hi >> 20) & 0x7ff;\n" + + "var to32 = low >> 0;\n" + + "if (e === 0) {\n" + + " if (to32 & 0x80000000) {\n" + + " hi = hi << 1 + 1; low = low << 1;\n" + + " } else {\n" + + " hi = hi << 1; low = low << 1;\n" + + " }\n" + + "} else {\n" + + " hi = (hi & 0xfffff) | 0x100000;\n" + + "}\n" + + "to32 = low >> 0;\n" + + "var m = Math.pow(2.0, 32) * hi + to32;\n" + + "var r = s * m * Math.pow(2.0, e - 1075);\n" + + "//throw 'exp: ' + e + ' sign: ' + s + ' hi:' + hi + ' low: ' + low + ' m: ' + m + ' r: ' + r;\n" + + "return r;\n" + ) + private static double toDouble(int hi, int low) { + long both = hi; + both = (both << 32) & low; + return Double.doubleToLongBits(both); + } + + private char lineBuffer[]; + + /** + * See the general contract of the readLine + * method of DataInput. + *

+ * Bytes + * for this operation are read from the contained + * input stream. + * + * @deprecated This method does not properly convert bytes to characters. + * As of JDK 1.1, the preferred way to read lines of text is via the + * BufferedReader.readLine() method. Programs that use the + * DataInputStream class to read lines can be converted to use + * the BufferedReader class by replacing code of the form: + *

+     *     DataInputStream d = new DataInputStream(in);
+     * 
+ * with: + *
+     *     BufferedReader d
+     *          = new BufferedReader(new InputStreamReader(in));
+     * 
+ * + * @return the next line of text from this input stream. + * @exception IOException if an I/O error occurs. + * @see java.io.BufferedReader#readLine() + * @see java.io.FilterInputStream#in + */ + @Deprecated + public final String readLine() throws IOException { + char buf[] = lineBuffer; + + if (buf == null) { + buf = lineBuffer = new char[128]; + } + + int room = buf.length; + int offset = 0; + int c; + +loop: while (true) { + switch (c = in.read()) { + case -1: + case '\n': + break loop; + + case '\r': + int c2 = in.read(); + if ((c2 != '\n') && (c2 != -1)) { + if (!(in instanceof PushbackInputStream)) { + this.in = new PushbackInputStream(in); + } + ((PushbackInputStream)in).unread(c2); + } + break loop; + + default: + if (--room < 0) { + buf = new char[offset + 128]; + room = buf.length - offset - 1; + arraycopy(lineBuffer, 0, buf, 0, offset); + lineBuffer = buf; + } + buf[offset++] = (char) c; + break; + } + } + if ((c == -1) && (offset == 0)) { + return null; + } + return String.copyValueOf(buf, 0, offset); + } + + /** + * See the general contract of the readUTF + * method of DataInput. + *

+ * Bytes + * for this operation are read from the contained + * input stream. + * + * @return a Unicode string. + * @exception EOFException if this input stream reaches the end before + * reading all the bytes. + * @exception IOException the stream has been closed and the contained + * input stream does not support reading after close, or + * another I/O error occurs. + * @exception UTFDataFormatException if the bytes do not represent a valid + * modified UTF-8 encoding of a string. + * @see java.io.DataInputStream#readUTF(java.io.DataInput) + */ + public final String readUTF() throws IOException { + return readUTF(this); + } + + /** + * Reads from the + * stream in a representation + * of a Unicode character string encoded in + * modified UTF-8 format; + * this string of characters is then returned as a String. + * The details of the modified UTF-8 representation + * are exactly the same as for the readUTF + * method of DataInput. + * + * @param in a data input stream. + * @return a Unicode string. + * @exception EOFException if the input stream reaches the end + * before all the bytes. + * @exception IOException the stream has been closed and the contained + * input stream does not support reading after close, or + * another I/O error occurs. + * @exception UTFDataFormatException if the bytes do not represent a + * valid modified UTF-8 encoding of a Unicode string. + * @see java.io.DataInputStream#readUnsignedShort() + */ + public final static String readUTF(DataInput in) throws IOException { + int utflen = in.readUnsignedShort(); + byte[] bytearr = null; + char[] chararr = null; + if (in instanceof DataInputStream) { + DataInputStream dis = (DataInputStream)in; + if (dis.bytearr.length < utflen){ + dis.bytearr = new byte[utflen*2]; + dis.chararr = new char[utflen*2]; + } + chararr = dis.chararr; + bytearr = dis.bytearr; + } else { + bytearr = new byte[utflen]; + chararr = new char[utflen]; + } + + int c, char2, char3; + int count = 0; + int chararr_count=0; + + in.readFully(bytearr, 0, utflen); + + while (count < utflen) { + c = (int) bytearr[count] & 0xff; + if (c > 127) break; + count++; + chararr[chararr_count++]=(char)c; + } + + while (count < utflen) { + c = (int) bytearr[count] & 0xff; + switch (c >> 4) { + case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: + /* 0xxxxxxx*/ + count++; + chararr[chararr_count++]=(char)c; + break; + case 12: case 13: + /* 110x xxxx 10xx xxxx*/ + count += 2; + if (count > utflen) + throw new UTFDataFormatException( + "malformed input: partial character at end"); + char2 = (int) bytearr[count-1]; + if ((char2 & 0xC0) != 0x80) + throw new UTFDataFormatException( + "malformed input around byte " + count); + chararr[chararr_count++]=(char)(((c & 0x1F) << 6) | + (char2 & 0x3F)); + break; + case 14: + /* 1110 xxxx 10xx xxxx 10xx xxxx */ + count += 3; + if (count > utflen) + throw new UTFDataFormatException( + "malformed input: partial character at end"); + char2 = (int) bytearr[count-2]; + char3 = (int) bytearr[count-1]; + if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80)) + throw new UTFDataFormatException( + "malformed input around byte " + (count-1)); + chararr[chararr_count++]=(char)(((c & 0x0F) << 12) | + ((char2 & 0x3F) << 6) | + ((char3 & 0x3F) << 0)); + break; + default: + /* 10xx xxxx, 1111 xxxx */ + throw new UTFDataFormatException( + "malformed input around byte " + count); + } + } + // The number of chars produced may be less than utflen + return new String(chararr, 0, chararr_count); + } + static void arraycopy(char[] value, int srcBegin, char[] dst, int dstBegin, int count) { + while (count-- > 0) { + dst[dstBegin++] = value[srcBegin++]; + } + } +}