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

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

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

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

The read(b) method has the same effect as: jtulach@146: *

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

This method blocks until input data is available, end of file is jtulach@146: * detected, or an exception is thrown. jtulach@146: * jtulach@146: *

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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