1 /*
2  * Copyright (c) 1994, 2006, 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   JDK1.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</code>
157      * method of <code>DataInput</code>.
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      * @exception  EOFException  if this input stream reaches the end before
165      *             reading all the bytes.
166      * @exception  IOException   the stream has been closed and the contained
167      *             input stream does not support reading after close, or
168      *             another I/O error occurs.
169      * @see        java.io.FilterInputStream#in
170      */
readFully(byte b[])171     public final void readFully(byte b[]) throws IOException {
172         readFully(b, 0, b.length);
173     }
174 
175     /**
176      * See the general contract of the <code>readFully</code>
177      * method of <code>DataInput</code>.
178      * <p>
179      * Bytes
180      * for this operation are read from the contained
181      * input stream.
182      *
183      * @param      b     the buffer into which the data is read.
184      * @param      off   the start offset of the data.
185      * @param      len   the number of bytes to read.
186      * @exception  EOFException  if this input stream reaches the end before
187      *               reading all the bytes.
188      * @exception  IOException   the stream has been closed and the contained
189      *             input stream does not support reading after close, or
190      *             another I/O error occurs.
191      * @see        java.io.FilterInputStream#in
192      */
readFully(byte b[], int off, int len)193     public final void readFully(byte b[], int off, int len) throws IOException {
194         if (len < 0)
195             throw new IndexOutOfBoundsException();
196         int n = 0;
197         while (n < len) {
198             int count = in.read(b, off + n, len - n);
199             if (count < 0)
200                 throw new EOFException();
201             n += count;
202         }
203     }
204 
205     /**
206      * See the general contract of the <code>skipBytes</code>
207      * method of <code>DataInput</code>.
208      * <p>
209      * Bytes for this operation are read from the contained
210      * input stream.
211      *
212      * @param      n   the number of bytes to be skipped.
213      * @return     the actual number of bytes skipped.
214      * @exception  IOException  if the contained input stream does not support
215      *             seek, or the stream has been closed and
216      *             the contained input stream does not support
217      *             reading after close, or another I/O error occurs.
218      */
skipBytes(int n)219     public final int skipBytes(int n) throws IOException {
220         int total = 0;
221         int cur = 0;
222 
223         while ((total<n) && ((cur = (int) in.skip(n-total)) > 0)) {
224             total += cur;
225         }
226 
227         return total;
228     }
229 
230     /**
231      * See the general contract of the <code>readBoolean</code>
232      * method of <code>DataInput</code>.
233      * <p>
234      * Bytes for this operation are read from the contained
235      * input stream.
236      *
237      * @return     the <code>boolean</code> value read.
238      * @exception  EOFException  if this input stream has reached the end.
239      * @exception  IOException   the stream has been closed and the contained
240      *             input stream does not support reading after close, or
241      *             another I/O error occurs.
242      * @see        java.io.FilterInputStream#in
243      */
readBoolean()244     public final boolean readBoolean() throws IOException {
245         int ch = in.read();
246         if (ch < 0)
247             throw new EOFException();
248         return (ch != 0);
249     }
250 
251     /**
252      * See the general contract of the <code>readByte</code>
253      * method of <code>DataInput</code>.
254      * <p>
255      * Bytes
256      * for this operation are read from the contained
257      * input stream.
258      *
259      * @return     the next byte of this input stream as a signed 8-bit
260      *             <code>byte</code>.
261      * @exception  EOFException  if this input stream has reached the end.
262      * @exception  IOException   the stream has been closed and the contained
263      *             input stream does not support reading after close, or
264      *             another I/O error occurs.
265      * @see        java.io.FilterInputStream#in
266      */
readByte()267     public final byte readByte() throws IOException {
268         int ch = in.read();
269         if (ch < 0)
270             throw new EOFException();
271         return (byte)(ch);
272     }
273 
274     /**
275      * See the general contract of the <code>readUnsignedByte</code>
276      * method of <code>DataInput</code>.
277      * <p>
278      * Bytes
279      * for this operation are read from the contained
280      * input stream.
281      *
282      * @return     the next byte of this input stream, interpreted as an
283      *             unsigned 8-bit number.
284      * @exception  EOFException  if this input stream has reached the end.
285      * @exception  IOException   the stream has been closed and the contained
286      *             input stream does not support reading after close, or
287      *             another I/O error occurs.
288      * @see         java.io.FilterInputStream#in
289      */
readUnsignedByte()290     public final int readUnsignedByte() throws IOException {
291         int ch = in.read();
292         if (ch < 0)
293             throw new EOFException();
294         return ch;
295     }
296 
297     /**
298      * See the general contract of the <code>readShort</code>
299      * method of <code>DataInput</code>.
300      * <p>
301      * Bytes
302      * for this operation are read from the contained
303      * input stream.
304      *
305      * @return     the next two bytes of this input stream, interpreted as a
306      *             signed 16-bit number.
307      * @exception  EOFException  if this input stream reaches the end before
308      *               reading two bytes.
309      * @exception  IOException   the stream has been closed and the contained
310      *             input stream does not support reading after close, or
311      *             another I/O error occurs.
312      * @see        java.io.FilterInputStream#in
313      */
readShort()314     public final short readShort() throws IOException {
315         // b/30268192
316         // Android-changed: Use read(byte[], int, int) instead of read().
317         readFully(readBuffer, 0, 2);
318         return Memory.peekShort(readBuffer, 0, ByteOrder.BIG_ENDIAN);
319     }
320 
321     /**
322      * See the general contract of the <code>readUnsignedShort</code>
323      * method of <code>DataInput</code>.
324      * <p>
325      * Bytes
326      * for this operation are read from the contained
327      * input stream.
328      *
329      * @return     the next two bytes of this input stream, interpreted as an
330      *             unsigned 16-bit integer.
331      * @exception  EOFException  if this input stream reaches the end before
332      *             reading two bytes.
333      * @exception  IOException   the stream has been closed and the contained
334      *             input stream does not support reading after close, or
335      *             another I/O error occurs.
336      * @see        java.io.FilterInputStream#in
337      */
readUnsignedShort()338     public final int readUnsignedShort() throws IOException {
339         // b/30268192
340         // Android-changed: Use read(byte[], int, int) instead of read().
341         readFully(readBuffer, 0, 2);
342         return Memory.peekShort(readBuffer, 0, ByteOrder.BIG_ENDIAN) & 0xffff;
343     }
344 
345     /**
346      * See the general contract of the <code>readChar</code>
347      * method of <code>DataInput</code>.
348      * <p>
349      * Bytes
350      * for this operation are read from the contained
351      * input stream.
352      *
353      * @return     the next two bytes of this input stream, interpreted as a
354      *             <code>char</code>.
355      * @exception  EOFException  if this input stream reaches the end before
356      *               reading two bytes.
357      * @exception  IOException   the stream has been closed and the contained
358      *             input stream does not support reading after close, or
359      *             another I/O error occurs.
360      * @see        java.io.FilterInputStream#in
361      */
readChar()362     public final char readChar() throws IOException {
363         // b/30268192
364         // Android-changed: Use read(byte[], int, int) instead of read().
365         readFully(readBuffer, 0, 2);
366         return (char)Memory.peekShort(readBuffer, 0, ByteOrder.BIG_ENDIAN);
367     }
368 
369     /**
370      * See the general contract of the <code>readInt</code>
371      * method of <code>DataInput</code>.
372      * <p>
373      * Bytes
374      * for this operation are read from the contained
375      * input stream.
376      *
377      * @return     the next four bytes of this input stream, interpreted as an
378      *             <code>int</code>.
379      * @exception  EOFException  if this input stream reaches the end before
380      *               reading four bytes.
381      * @exception  IOException   the stream has been closed and the contained
382      *             input stream does not support reading after close, or
383      *             another I/O error occurs.
384      * @see        java.io.FilterInputStream#in
385      */
readInt()386     public final int readInt() throws IOException {
387         // b/30268192
388         // Android-changed: Use read(byte[], int, int) instead of read().
389         readFully(readBuffer, 0, 4);
390         return Memory.peekInt(readBuffer, 0, ByteOrder.BIG_ENDIAN);
391     }
392 
393     private byte readBuffer[] = new byte[8];
394 
395     /**
396      * See the general contract of the <code>readLong</code>
397      * method of <code>DataInput</code>.
398      * <p>
399      * Bytes
400      * for this operation are read from the contained
401      * input stream.
402      *
403      * @return     the next eight bytes of this input stream, interpreted as a
404      *             <code>long</code>.
405      * @exception  EOFException  if this input stream reaches the end before
406      *               reading eight bytes.
407      * @exception  IOException   the stream has been closed and the contained
408      *             input stream does not support reading after close, or
409      *             another I/O error occurs.
410      * @see        java.io.FilterInputStream#in
411      */
readLong()412     public final long readLong() throws IOException {
413         readFully(readBuffer, 0, 8);
414         return (((long)readBuffer[0] << 56) +
415                 ((long)(readBuffer[1] & 255) << 48) +
416                 ((long)(readBuffer[2] & 255) << 40) +
417                 ((long)(readBuffer[3] & 255) << 32) +
418                 ((long)(readBuffer[4] & 255) << 24) +
419                 ((readBuffer[5] & 255) << 16) +
420                 ((readBuffer[6] & 255) <<  8) +
421                 ((readBuffer[7] & 255) <<  0));
422     }
423 
424     /**
425      * See the general contract of the <code>readFloat</code>
426      * method of <code>DataInput</code>.
427      * <p>
428      * Bytes
429      * for this operation are read from the contained
430      * input stream.
431      *
432      * @return     the next four bytes of this input stream, interpreted as a
433      *             <code>float</code>.
434      * @exception  EOFException  if this input stream reaches the end before
435      *               reading four bytes.
436      * @exception  IOException   the stream has been closed and the contained
437      *             input stream does not support reading after close, or
438      *             another I/O error occurs.
439      * @see        java.io.DataInputStream#readInt()
440      * @see        java.lang.Float#intBitsToFloat(int)
441      */
readFloat()442     public final float readFloat() throws IOException {
443         return Float.intBitsToFloat(readInt());
444     }
445 
446     /**
447      * See the general contract of the <code>readDouble</code>
448      * method of <code>DataInput</code>.
449      * <p>
450      * Bytes
451      * for this operation are read from the contained
452      * input stream.
453      *
454      * @return     the next eight bytes of this input stream, interpreted as a
455      *             <code>double</code>.
456      * @exception  EOFException  if this input stream reaches the end before
457      *               reading eight bytes.
458      * @exception  IOException   the stream has been closed and the contained
459      *             input stream does not support reading after close, or
460      *             another I/O error occurs.
461      * @see        java.io.DataInputStream#readLong()
462      * @see        java.lang.Double#longBitsToDouble(long)
463      */
readDouble()464     public final double readDouble() throws IOException {
465         return Double.longBitsToDouble(readLong());
466     }
467 
468     private char lineBuffer[];
469 
470     /**
471      * See the general contract of the <code>readLine</code>
472      * method of <code>DataInput</code>.
473      * <p>
474      * Bytes
475      * for this operation are read from the contained
476      * input stream.
477      *
478      * @deprecated This method does not properly convert bytes to characters.
479      * As of JDK&nbsp;1.1, the preferred way to read lines of text is via the
480      * <code>BufferedReader.readLine()</code> method.  Programs that use the
481      * <code>DataInputStream</code> class to read lines can be converted to use
482      * the <code>BufferedReader</code> class by replacing code of the form:
483      * <blockquote><pre>
484      *     DataInputStream d =&nbsp;new&nbsp;DataInputStream(in);
485      * </pre></blockquote>
486      * with:
487      * <blockquote><pre>
488      *     BufferedReader d
489      *          =&nbsp;new&nbsp;BufferedReader(new&nbsp;InputStreamReader(in));
490      * </pre></blockquote>
491      *
492      * @return     the next line of text from this input stream.
493      * @exception  IOException  if an I/O error occurs.
494      * @see        java.io.BufferedReader#readLine()
495      * @see        java.io.FilterInputStream#in
496      */
497     @Deprecated
readLine()498     public final String readLine() throws IOException {
499         char buf[] = lineBuffer;
500 
501         if (buf == null) {
502             buf = lineBuffer = new char[128];
503         }
504 
505         int room = buf.length;
506         int offset = 0;
507         int c;
508 
509 loop:   while (true) {
510             switch (c = in.read()) {
511               case -1:
512               case '\n':
513                 break loop;
514 
515               case '\r':
516                 int c2 = in.read();
517                 if ((c2 != '\n') && (c2 != -1)) {
518                     if (!(in instanceof PushbackInputStream)) {
519                         this.in = new PushbackInputStream(in);
520                     }
521                     ((PushbackInputStream)in).unread(c2);
522                 }
523                 break loop;
524 
525               default:
526                 if (--room < 0) {
527                     buf = new char[offset + 128];
528                     room = buf.length - offset - 1;
529                     System.arraycopy(lineBuffer, 0, buf, 0, offset);
530                     lineBuffer = buf;
531                 }
532                 buf[offset++] = (char) c;
533                 break;
534             }
535         }
536         if ((c == -1) && (offset == 0)) {
537             return null;
538         }
539         return String.copyValueOf(buf, 0, offset);
540     }
541 
542     /**
543      * See the general contract of the <code>readUTF</code>
544      * method of <code>DataInput</code>.
545      * <p>
546      * Bytes
547      * for this operation are read from the contained
548      * input stream.
549      *
550      * @return     a Unicode string.
551      * @exception  EOFException  if this input stream reaches the end before
552      *               reading all the bytes.
553      * @exception  IOException   the stream has been closed and the contained
554      *             input stream does not support reading after close, or
555      *             another I/O error occurs.
556      * @exception  UTFDataFormatException if the bytes do not represent a valid
557      *             modified UTF-8 encoding of a string.
558      * @see        java.io.DataInputStream#readUTF(java.io.DataInput)
559      */
readUTF()560     public final String readUTF() throws IOException {
561         return readUTF(this);
562     }
563 
564     /**
565      * Reads from the
566      * stream <code>in</code> a representation
567      * of a Unicode  character string encoded in
568      * <a href="DataInput.html#modified-utf-8">modified UTF-8</a> format;
569      * this string of characters is then returned as a <code>String</code>.
570      * The details of the modified UTF-8 representation
571      * are  exactly the same as for the <code>readUTF</code>
572      * method of <code>DataInput</code>.
573      *
574      * @param      in   a data input stream.
575      * @return     a Unicode string.
576      * @exception  EOFException            if the input stream reaches the end
577      *               before all the bytes.
578      * @exception  IOException   the stream has been closed and the contained
579      *             input stream does not support reading after close, or
580      *             another I/O error occurs.
581      * @exception  UTFDataFormatException  if the bytes do not represent a
582      *               valid modified UTF-8 encoding of a Unicode string.
583      * @see        java.io.DataInputStream#readUnsignedShort()
584      */
readUTF(DataInput in)585     public final static String readUTF(DataInput in) throws IOException {
586         int utflen = in.readUnsignedShort();
587         byte[] bytearr = null;
588         char[] chararr = null;
589         if (in instanceof DataInputStream) {
590             DataInputStream dis = (DataInputStream)in;
591             if (dis.bytearr.length < utflen){
592                 dis.bytearr = new byte[utflen*2];
593                 dis.chararr = new char[utflen*2];
594             }
595             chararr = dis.chararr;
596             bytearr = dis.bytearr;
597         } else {
598             bytearr = new byte[utflen];
599             chararr = new char[utflen];
600         }
601 
602         int c, char2, char3;
603         int count = 0;
604         int chararr_count=0;
605 
606         in.readFully(bytearr, 0, utflen);
607 
608         while (count < utflen) {
609             c = (int) bytearr[count] & 0xff;
610             if (c > 127) break;
611             count++;
612             chararr[chararr_count++]=(char)c;
613         }
614 
615         while (count < utflen) {
616             c = (int) bytearr[count] & 0xff;
617             switch (c >> 4) {
618                 case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
619                     /* 0xxxxxxx*/
620                     count++;
621                     chararr[chararr_count++]=(char)c;
622                     break;
623                 case 12: case 13:
624                     /* 110x xxxx   10xx xxxx*/
625                     count += 2;
626                     if (count > utflen)
627                         throw new UTFDataFormatException(
628                             "malformed input: partial character at end");
629                     char2 = (int) bytearr[count-1];
630                     if ((char2 & 0xC0) != 0x80)
631                         throw new UTFDataFormatException(
632                             "malformed input around byte " + count);
633                     chararr[chararr_count++]=(char)(((c & 0x1F) << 6) |
634                                                     (char2 & 0x3F));
635                     break;
636                 case 14:
637                     /* 1110 xxxx  10xx xxxx  10xx xxxx */
638                     count += 3;
639                     if (count > utflen)
640                         throw new UTFDataFormatException(
641                             "malformed input: partial character at end");
642                     char2 = (int) bytearr[count-2];
643                     char3 = (int) bytearr[count-1];
644                     if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80))
645                         throw new UTFDataFormatException(
646                             "malformed input around byte " + (count-1));
647                     chararr[chararr_count++]=(char)(((c     & 0x0F) << 12) |
648                                                     ((char2 & 0x3F) << 6)  |
649                                                     ((char3 & 0x3F) << 0));
650                     break;
651                 default:
652                     /* 10xx xxxx,  1111 xxxx */
653                     throw new UTFDataFormatException(
654                         "malformed input around byte " + count);
655             }
656         }
657         // The number of chars produced may be less than utflen
658         return new String(chararr, 0, chararr_count);
659     }
660 }
661