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