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
26 package 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  */

42 public
43 class 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[], intint)
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[], intint)
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
517 loop:   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