1/*
2 * Copyright (c) 1994, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package java.io;
27
28/**
29 * A data input stream lets an application read primitive Java data
30 * types from an underlying input stream in a machine-independent
31 * way. An application uses a data output stream to write data that
32 * can later be read by a data input stream.
33 * <p>
34 * DataInputStream is not necessarily safe for multithreaded access.
35 * Thread safety is optional and is the responsibility of users of
36 * methods in this class.
37 *
38 * @author  Arthur van Hoff
39 * @see     java.io.DataOutputStream
40 * @since   1.0
41 */
42public
43class DataInputStream extends FilterInputStream implements DataInput {
44
45    /**
46     * Creates a DataInputStream that uses the specified
47     * underlying InputStream.
48     *
49     * @param  in   the specified input stream
50     */
51    public DataInputStream(InputStream in) {
52        super(in);
53    }
54
55    /**
56     * working arrays initialized on demand by readUTF
57     */
58    private byte bytearr[] = new byte[80];
59    private char chararr[] = new char[80];
60
61    /**
62     * Reads some number of bytes from the contained input stream and
63     * stores them into the buffer array <code>b</code>. The number of
64     * bytes actually read is returned as an integer. This method blocks
65     * until input data is available, end of file is detected, or an
66     * exception is thrown.
67     *
68     * <p>If <code>b</code> is null, a <code>NullPointerException</code> is
69     * thrown. If the length of <code>b</code> is zero, then no bytes are
70     * read and <code>0</code> is returned; otherwise, there is an attempt
71     * to read at least one byte. If no byte is available because the
72     * stream is at end of file, the value <code>-1</code> is returned;
73     * otherwise, at least one byte is read and stored into <code>b</code>.
74     *
75     * <p>The first byte read is stored into element <code>b[0]</code>, the
76     * next one into <code>b[1]</code>, and so on. The number of bytes read
77     * is, at most, equal to the length of <code>b</code>. Let <code>k</code>
78     * be the number of bytes actually read; these bytes will be stored in
79     * elements <code>b[0]</code> through <code>b[k-1]</code>, leaving
80     * elements <code>b[k]</code> through <code>b[b.length-1]</code>
81     * unaffected.
82     *
83     * <p>The <code>read(b)</code> method has the same effect as:
84     * <blockquote><pre>
85     * read(b, 0, b.length)
86     * </pre></blockquote>
87     *
88     * @param      b   the buffer into which the data is read.
89     * @return     the total number of bytes read into the buffer, or
90     *             <code>-1</code> if there is no more data because the end
91     *             of the stream has been reached.
92     * @exception  IOException if the first byte cannot be read for any reason
93     * other than end of file, the stream has been closed and the underlying
94     * input stream does not support reading after close, or another I/O
95     * error occurs.
96     * @see        java.io.FilterInputStream#in
97     * @see        java.io.InputStream#read(byte[], int, int)
98     */
99    public final int read(byte b[]) throws IOException {
100        return in.read(b, 0, b.length);
101    }
102
103    /**
104     * Reads up to <code>len</code> bytes of data from the contained
105     * input stream into an array of bytes.  An attempt is made to read
106     * as many as <code>len</code> bytes, but a smaller number may be read,
107     * possibly zero. The number of bytes actually read is returned as an
108     * integer.
109     *
110     * <p> This method blocks until input data is available, end of file is
111     * detected, or an exception is thrown.
112     *
113     * <p> If <code>len</code> is zero, then no bytes are read and
114     * <code>0</code> is returned; otherwise, there is an attempt to read at
115     * least one byte. If no byte is available because the stream is at end of
116     * file, the value <code>-1</code> is returned; otherwise, at least one
117     * byte is read and stored into <code>b</code>.
118     *
119     * <p> The first byte read is stored into element <code>b[off]</code>, the
120     * next one into <code>b[off+1]</code>, and so on. The number of bytes read
121     * is, at most, equal to <code>len</code>. Let <i>k</i> be the number of
122     * bytes actually read; these bytes will be stored in elements
123     * <code>b[off]</code> through <code>b[off+</code><i>k</i><code>-1]</code>,
124     * leaving elements <code>b[off+</code><i>k</i><code>]</code> through
125     * <code>b[off+len-1]</code> unaffected.
126     *
127     * <p> In every case, elements <code>b[0]</code> through
128     * <code>b[off]</code> and elements <code>b[off+len]</code> through
129     * <code>b[b.length-1]</code> are unaffected.
130     *
131     * @param      b     the buffer into which the data is read.
132     * @param off the start offset in the destination array <code>b</code>
133     * @param      len   the maximum number of bytes read.
134     * @return     the total number of bytes read into the buffer, or
135     *             <code>-1</code> if there is no more data because the end
136     *             of the stream has been reached.
137     * @exception  NullPointerException If <code>b</code> is <code>null</code>.
138     * @exception  IndexOutOfBoundsException If <code>off</code> is negative,
139     * <code>len</code> is negative, or <code>len</code> is greater than
140     * <code>b.length - off</code>
141     * @exception  IOException if the first byte cannot be read for any reason
142     * other than end of file, the stream has been closed and the underlying
143     * input stream does not support reading after close, or another I/O
144     * error occurs.
145     * @see        java.io.FilterInputStream#in
146     * @see        java.io.InputStream#read(byte[], int, int)
147     */
148    public final int read(byte b[], int off, int len) throws IOException {
149        return in.read(b, off, len);
150    }
151
152    /**
153     * See the general contract of the {@code readFully}
154     * method of {@code DataInput}.
155     * <p>
156     * Bytes
157     * for this operation are read from the contained
158     * input stream.
159     *
160     * @param   b   the buffer into which the data is read.
161     * @throws  NullPointerException if {@code b} is {@code null}.
162     * @throws  EOFException  if this input stream reaches the end before
163     *          reading all the bytes.
164     * @throws  IOException   the stream has been closed and the contained
165     *          input stream does not support reading after close, or
166     *          another I/O error occurs.
167     * @see     java.io.FilterInputStream#in
168     */
169    public final void readFully(byte b[]) throws IOException {
170        readFully(b, 0, b.length);
171    }
172
173    /**
174     * See the general contract of the {@code readFully}
175     * method of {@code DataInput}.
176     * <p>
177     * Bytes
178     * for this operation are read from the contained
179     * input stream.
180     *
181     * @param      b     the buffer into which the data is read.
182     * @param      off   the start offset in the data array {@code b}.
183     * @param      len   the number of bytes to read.
184     * @exception  NullPointerException if {@code b} is {@code null}.
185     * @exception  IndexOutOfBoundsException if {@code off} is negative,
186     *             {@code len} is negative, or {@code len} is greater than
187     *             {@code b.length - off}.
188     * @exception  EOFException  if this input stream reaches the end before
189     *             reading all the bytes.
190     * @exception  IOException   the stream has been closed and the contained
191     *             input stream does not support reading after close, or
192     *             another I/O error occurs.
193     * @see        java.io.FilterInputStream#in
194     */
195    public final void readFully(byte b[], int off, int len) throws IOException {
196        if (len < 0)
197            throw new IndexOutOfBoundsException();
198        int n = 0;
199        while (n < len) {
200            int count = in.read(b, off + n, len - n);
201            if (count < 0)
202                throw new EOFException();
203            n += count;
204        }
205    }
206
207    /**
208     * See the general contract of the <code>skipBytes</code>
209     * method of <code>DataInput</code>.
210     * <p>
211     * Bytes for this operation are read from the contained
212     * input stream.
213     *
214     * @param      n   the number of bytes to be skipped.
215     * @return     the actual number of bytes skipped.
216     * @exception  IOException  if the contained input stream does not support
217     *             seek, or the stream has been closed and
218     *             the contained input stream does not support
219     *             reading after close, or another I/O error occurs.
220     */
221    public final int skipBytes(int n) throws IOException {
222        int total = 0;
223        int cur = 0;
224
225        while ((total<n) && ((cur = (int) in.skip(n-total)) > 0)) {
226            total += cur;
227        }
228
229        return total;
230    }
231
232    /**
233     * See the general contract of the <code>readBoolean</code>
234     * method of <code>DataInput</code>.
235     * <p>
236     * Bytes for this operation are read from the contained
237     * input stream.
238     *
239     * @return     the <code>boolean</code> value read.
240     * @exception  EOFException  if this input stream has reached the end.
241     * @exception  IOException   the stream has been closed and the contained
242     *             input stream does not support reading after close, or
243     *             another I/O error occurs.
244     * @see        java.io.FilterInputStream#in
245     */
246    public final boolean readBoolean() throws IOException {
247        int ch = in.read();
248        if (ch < 0)
249            throw new EOFException();
250        return (ch != 0);
251    }
252
253    /**
254     * See the general contract of the <code>readByte</code>
255     * method of <code>DataInput</code>.
256     * <p>
257     * Bytes
258     * for this operation are read from the contained
259     * input stream.
260     *
261     * @return     the next byte of this input stream as a signed 8-bit
262     *             <code>byte</code>.
263     * @exception  EOFException  if this input stream has reached the end.
264     * @exception  IOException   the stream has been closed and the contained
265     *             input stream does not support reading after close, or
266     *             another I/O error occurs.
267     * @see        java.io.FilterInputStream#in
268     */
269    public final byte readByte() throws IOException {
270        int ch = in.read();
271        if (ch < 0)
272            throw new EOFException();
273        return (byte)(ch);
274    }
275
276    /**
277     * See the general contract of the <code>readUnsignedByte</code>
278     * method of <code>DataInput</code>.
279     * <p>
280     * Bytes
281     * for this operation are read from the contained
282     * input stream.
283     *
284     * @return     the next byte of this input stream, interpreted as an
285     *             unsigned 8-bit number.
286     * @exception  EOFException  if this input stream has reached the end.
287     * @exception  IOException   the stream has been closed and the contained
288     *             input stream does not support reading after close, or
289     *             another I/O error occurs.
290     * @see         java.io.FilterInputStream#in
291     */
292    public final int readUnsignedByte() throws IOException {
293        int ch = in.read();
294        if (ch < 0)
295            throw new EOFException();
296        return ch;
297    }
298
299    /**
300     * See the general contract of the <code>readShort</code>
301     * method of <code>DataInput</code>.
302     * <p>
303     * Bytes
304     * for this operation are read from the contained
305     * input stream.
306     *
307     * @return     the next two bytes of this input stream, interpreted as a
308     *             signed 16-bit number.
309     * @exception  EOFException  if this input stream reaches the end before
310     *               reading two bytes.
311     * @exception  IOException   the stream has been closed and the contained
312     *             input stream does not support reading after close, or
313     *             another I/O error occurs.
314     * @see        java.io.FilterInputStream#in
315     */
316    public final short readShort() throws IOException {
317        int ch1 = in.read();
318        int ch2 = in.read();
319        if ((ch1 | ch2) < 0)
320            throw new EOFException();
321        return (short)((ch1 << 8) + (ch2 << 0));
322    }
323
324    /**
325     * See the general contract of the <code>readUnsignedShort</code>
326     * method of <code>DataInput</code>.
327     * <p>
328     * Bytes
329     * for this operation are read from the contained
330     * input stream.
331     *
332     * @return     the next two bytes of this input stream, interpreted as an
333     *             unsigned 16-bit integer.
334     * @exception  EOFException  if this input stream reaches the end before
335     *             reading two bytes.
336     * @exception  IOException   the stream has been closed and the contained
337     *             input stream does not support reading after close, or
338     *             another I/O error occurs.
339     * @see        java.io.FilterInputStream#in
340     */
341    public final int readUnsignedShort() throws IOException {
342        int ch1 = in.read();
343        int ch2 = in.read();
344        if ((ch1 | ch2) < 0)
345            throw new EOFException();
346        return (ch1 << 8) + (ch2 << 0);
347    }
348
349    /**
350     * See the general contract of the <code>readChar</code>
351     * method of <code>DataInput</code>.
352     * <p>
353     * Bytes
354     * for this operation are read from the contained
355     * input stream.
356     *
357     * @return     the next two bytes of this input stream, interpreted as a
358     *             <code>char</code>.
359     * @exception  EOFException  if this input stream reaches the end before
360     *               reading two bytes.
361     * @exception  IOException   the stream has been closed and the contained
362     *             input stream does not support reading after close, or
363     *             another I/O error occurs.
364     * @see        java.io.FilterInputStream#in
365     */
366    public final char readChar() throws IOException {
367        int ch1 = in.read();
368        int ch2 = in.read();
369        if ((ch1 | ch2) < 0)
370            throw new EOFException();
371        return (char)((ch1 << 8) + (ch2 << 0));
372    }
373
374    /**
375     * See the general contract of the <code>readInt</code>
376     * method of <code>DataInput</code>.
377     * <p>
378     * Bytes
379     * for this operation are read from the contained
380     * input stream.
381     *
382     * @return     the next four bytes of this input stream, interpreted as an
383     *             <code>int</code>.
384     * @exception  EOFException  if this input stream reaches the end before
385     *               reading four bytes.
386     * @exception  IOException   the stream has been closed and the contained
387     *             input stream does not support reading after close, or
388     *             another I/O error occurs.
389     * @see        java.io.FilterInputStream#in
390     */
391    public final int readInt() throws IOException {
392        int ch1 = in.read();
393        int ch2 = in.read();
394        int ch3 = in.read();
395        int ch4 = in.read();
396        if ((ch1 | ch2 | ch3 | ch4) < 0)
397            throw new EOFException();
398        return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
399    }
400
401    private byte readBuffer[] = new byte[8];
402
403    /**
404     * See the general contract of the <code>readLong</code>
405     * method of <code>DataInput</code>.
406     * <p>
407     * Bytes
408     * for this operation are read from the contained
409     * input stream.
410     *
411     * @return     the next eight bytes of this input stream, interpreted as a
412     *             <code>long</code>.
413     * @exception  EOFException  if this input stream reaches the end before
414     *               reading eight bytes.
415     * @exception  IOException   the stream has been closed and the contained
416     *             input stream does not support reading after close, or
417     *             another I/O error occurs.
418     * @see        java.io.FilterInputStream#in
419     */
420    public final long readLong() throws IOException {
421        readFully(readBuffer, 0, 8);
422        return (((long)readBuffer[0] << 56) +
423                ((long)(readBuffer[1] & 255) << 48) +
424                ((long)(readBuffer[2] & 255) << 40) +
425                ((long)(readBuffer[3] & 255) << 32) +
426                ((long)(readBuffer[4] & 255) << 24) +
427                ((readBuffer[5] & 255) << 16) +
428                ((readBuffer[6] & 255) <<  8) +
429                ((readBuffer[7] & 255) <<  0));
430    }
431
432    /**
433     * See the general contract of the <code>readFloat</code>
434     * method of <code>DataInput</code>.
435     * <p>
436     * Bytes
437     * for this operation are read from the contained
438     * input stream.
439     *
440     * @return     the next four bytes of this input stream, interpreted as a
441     *             <code>float</code>.
442     * @exception  EOFException  if this input stream reaches the end before
443     *               reading four bytes.
444     * @exception  IOException   the stream has been closed and the contained
445     *             input stream does not support reading after close, or
446     *             another I/O error occurs.
447     * @see        java.io.DataInputStream#readInt()
448     * @see        java.lang.Float#intBitsToFloat(int)
449     */
450    public final float readFloat() throws IOException {
451        return Float.intBitsToFloat(readInt());
452    }
453
454    /**
455     * See the general contract of the <code>readDouble</code>
456     * method of <code>DataInput</code>.
457     * <p>
458     * Bytes
459     * for this operation are read from the contained
460     * input stream.
461     *
462     * @return     the next eight bytes of this input stream, interpreted as a
463     *             <code>double</code>.
464     * @exception  EOFException  if this input stream reaches the end before
465     *               reading eight bytes.
466     * @exception  IOException   the stream has been closed and the contained
467     *             input stream does not support reading after close, or
468     *             another I/O error occurs.
469     * @see        java.io.DataInputStream#readLong()
470     * @see        java.lang.Double#longBitsToDouble(long)
471     */
472    public final double readDouble() throws IOException {
473        return Double.longBitsToDouble(readLong());
474    }
475
476    private char lineBuffer[];
477
478    /**
479     * See the general contract of the <code>readLine</code>
480     * method of <code>DataInput</code>.
481     * <p>
482     * Bytes
483     * for this operation are read from the contained
484     * input stream.
485     *
486     * @deprecated This method does not properly convert bytes to characters.
487     * As of JDK&nbsp;1.1, the preferred way to read lines of text is via the
488     * <code>BufferedReader.readLine()</code> method.  Programs that use the
489     * <code>DataInputStream</code> class to read lines can be converted to use
490     * the <code>BufferedReader</code> class by replacing code of the form:
491     * <blockquote><pre>
492     *     DataInputStream d =&nbsp;new&nbsp;DataInputStream(in);
493     * </pre></blockquote>
494     * with:
495     * <blockquote><pre>
496     *     BufferedReader d
497     *          =&nbsp;new&nbsp;BufferedReader(new&nbsp;InputStreamReader(in));
498     * </pre></blockquote>
499     *
500     * @return     the next line of text from this input stream.
501     * @exception  IOException  if an I/O error occurs.
502     * @see        java.io.BufferedReader#readLine()
503     * @see        java.io.FilterInputStream#in
504     */
505    @Deprecated
506    public final String readLine() throws IOException {
507        char buf[] = lineBuffer;
508
509        if (buf == null) {
510            buf = lineBuffer = new char[128];
511        }
512
513        int room = buf.length;
514        int offset = 0;
515        int c;
516
517loop:   while (true) {
518            switch (c = in.read()) {
519              case -1:
520              case '\n':
521                break loop;
522
523              case '\r':
524                int c2 = in.read();
525                if ((c2 != '\n') && (c2 != -1)) {
526                    if (!(in instanceof PushbackInputStream)) {
527                        this.in = new PushbackInputStream(in);
528                    }
529                    ((PushbackInputStream)in).unread(c2);
530                }
531                break loop;
532
533              default:
534                if (--room < 0) {
535                    buf = new char[offset + 128];
536                    room = buf.length - offset - 1;
537                    System.arraycopy(lineBuffer, 0, buf, 0, offset);
538                    lineBuffer = buf;
539                }
540                buf[offset++] = (char) c;
541                break;
542            }
543        }
544        if ((c == -1) && (offset == 0)) {
545            return null;
546        }
547        return String.copyValueOf(buf, 0, offset);
548    }
549
550    /**
551     * See the general contract of the <code>readUTF</code>
552     * method of <code>DataInput</code>.
553     * <p>
554     * Bytes
555     * for this operation are read from the contained
556     * input stream.
557     *
558     * @return     a Unicode string.
559     * @exception  EOFException  if this input stream reaches the end before
560     *               reading all the bytes.
561     * @exception  IOException   the stream has been closed and the contained
562     *             input stream does not support reading after close, or
563     *             another I/O error occurs.
564     * @exception  UTFDataFormatException if the bytes do not represent a valid
565     *             modified UTF-8 encoding of a string.
566     * @see        java.io.DataInputStream#readUTF(java.io.DataInput)
567     */
568    public final String readUTF() throws IOException {
569        return readUTF(this);
570    }
571
572    /**
573     * Reads from the
574     * stream <code>in</code> a representation
575     * of a Unicode  character string encoded in
576     * <a href="DataInput.html#modified-utf-8">modified UTF-8</a> format;
577     * this string of characters is then returned as a <code>String</code>.
578     * The details of the modified UTF-8 representation
579     * are  exactly the same as for the <code>readUTF</code>
580     * method of <code>DataInput</code>.
581     *
582     * @param      in   a data input stream.
583     * @return     a Unicode string.
584     * @exception  EOFException            if the input stream reaches the end
585     *               before all the bytes.
586     * @exception  IOException   the stream has been closed and the contained
587     *             input stream does not support reading after close, or
588     *             another I/O error occurs.
589     * @exception  UTFDataFormatException  if the bytes do not represent a
590     *               valid modified UTF-8 encoding of a Unicode string.
591     * @see        java.io.DataInputStream#readUnsignedShort()
592     */
593    public static final String readUTF(DataInput in) throws IOException {
594        int utflen = in.readUnsignedShort();
595        byte[] bytearr = null;
596        char[] chararr = null;
597        if (in instanceof DataInputStream) {
598            DataInputStream dis = (DataInputStream)in;
599            if (dis.bytearr.length < utflen){
600                dis.bytearr = new byte[utflen*2];
601                dis.chararr = new char[utflen*2];
602            }
603            chararr = dis.chararr;
604            bytearr = dis.bytearr;
605        } else {
606            bytearr = new byte[utflen];
607            chararr = new char[utflen];
608        }
609
610        int c, char2, char3;
611        int count = 0;
612        int chararr_count=0;
613
614        in.readFully(bytearr, 0, utflen);
615
616        while (count < utflen) {
617            c = (int) bytearr[count] & 0xff;
618            if (c > 127) break;
619            count++;
620            chararr[chararr_count++]=(char)c;
621        }
622
623        while (count < utflen) {
624            c = (int) bytearr[count] & 0xff;
625            switch (c >> 4) {
626                case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
627                    /* 0xxxxxxx*/
628                    count++;
629                    chararr[chararr_count++]=(char)c;
630                    break;
631                case 12: case 13:
632                    /* 110x xxxx   10xx xxxx*/
633                    count += 2;
634                    if (count > utflen)
635                        throw new UTFDataFormatException(
636                            "malformed input: partial character at end");
637                    char2 = (int) bytearr[count-1];
638                    if ((char2 & 0xC0) != 0x80)
639                        throw new UTFDataFormatException(
640                            "malformed input around byte " + count);
641                    chararr[chararr_count++]=(char)(((c & 0x1F) << 6) |
642                                                    (char2 & 0x3F));
643                    break;
644                case 14:
645                    /* 1110 xxxx  10xx xxxx  10xx xxxx */
646                    count += 3;
647                    if (count > utflen)
648                        throw new UTFDataFormatException(
649                            "malformed input: partial character at end");
650                    char2 = (int) bytearr[count-2];
651                    char3 = (int) bytearr[count-1];
652                    if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80))
653                        throw new UTFDataFormatException(
654                            "malformed input around byte " + (count-1));
655                    chararr[chararr_count++]=(char)(((c     & 0x0F) << 12) |
656                                                    ((char2 & 0x3F) << 6)  |
657                                                    ((char3 & 0x3F) << 0));
658                    break;
659                default:
660                    /* 10xx xxxx,  1111 xxxx */
661                    throw new UTFDataFormatException(
662                        "malformed input around byte " + count);
663            }
664        }
665        // The number of chars produced may be less than utflen
666        return new String(chararr, 0, chararr_count);
667    }
668}
669