OSDN Git Service

original
[gb-231r1-is01/Gingerbread_2.3.3_r1_IS01.git] / libcore / luni / src / main / java / java / io / DataInputStream.java
1 /*
2  *  Licensed to the Apache Software Foundation (ASF) under one or more
3  *  contributor license agreements.  See the NOTICE file distributed with
4  *  this work for additional information regarding copyright ownership.
5  *  The ASF licenses this file to You under the Apache License, Version 2.0
6  *  (the "License"); you may not use this file except in compliance with
7  *  the License.  You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  */
17
18 package java.io;
19
20 import java.nio.charset.ModifiedUtf8;
21
22 /**
23  * Wraps an existing {@link InputStream} and reads typed data from it.
24  * Typically, this stream has been written by a DataOutputStream. Types that can
25  * be read include byte, 16-bit short, 32-bit int, 32-bit float, 64-bit long,
26  * 64-bit double, byte strings, and strings encoded in
27  * {@link DataInput modified UTF-8}.
28  *
29  * @see DataOutputStream
30  */
31 public class DataInputStream extends FilterInputStream implements DataInput {
32
33     byte[] buff;
34
35     /**
36      * Constructs a new DataInputStream on the InputStream {@code in}. All
37      * reads are then filtered through this stream. Note that data read by this
38      * stream is not in a human readable format and was most likely created by a
39      * DataOutputStream.
40      *
41      * <p><strong>Warning:</strong> passing a null source creates an invalid
42      * {@code DataInputStream}. All operations on such a stream will fail.
43      *
44      * @param in
45      *            the source InputStream the filter reads from.
46      * @see DataOutputStream
47      * @see RandomAccessFile
48      */
49     public DataInputStream(InputStream in) {
50         super(in);
51         buff = new byte[8];
52     }
53
54     /**
55      * Reads bytes from this stream into the byte array {@code buffer}. Returns
56      * the number of bytes that have been read.
57      *
58      * @param buffer
59      *            the buffer to read bytes into.
60      * @return the number of bytes that have been read or -1 if the end of the
61      *         stream has been reached.
62      * @throws IOException
63      *             if a problem occurs while reading from this stream.
64      * @see DataOutput#write(byte[])
65      * @see DataOutput#write(byte[], int, int)
66      */
67     @Override
68     public final int read(byte[] buffer) throws IOException {
69         return in.read(buffer, 0, buffer.length);
70     }
71
72     /**
73      * Reads at most {@code length} bytes from this stream and stores them in
74      * the byte array {@code buffer} starting at {@code offset}. Returns the
75      * number of bytes that have been read or -1 if no bytes have been read and
76      * the end of the stream has been reached.
77      *
78      * @param buffer
79      *            the byte array in which to store the bytes read.
80      * @param offset
81      *            the initial position in {@code buffer} to store the bytes
82      *            read from this stream.
83      * @param length
84      *            the maximum number of bytes to store in {@code buffer}.
85      * @return the number of bytes that have been read or -1 if the end of the
86      *         stream has been reached.
87      * @throws IOException
88      *             if a problem occurs while reading from this stream.
89      * @see DataOutput#write(byte[])
90      * @see DataOutput#write(byte[], int, int)
91      */
92     @Override
93     public final int read(byte[] buffer, int offset, int length)
94             throws IOException {
95         return in.read(buffer, offset, length);
96     }
97
98     /**
99      * Reads a boolean from this stream.
100      *
101      * @return the next boolean value from the source stream.
102      * @throws EOFException
103      *             if the end of the filtered stream is reached before one byte
104      *             has been read.
105      * @throws IOException
106      *             if a problem occurs while reading from this stream.
107      * @see DataOutput#writeBoolean(boolean)
108      */
109     public final boolean readBoolean() throws IOException {
110         int temp = in.read();
111         if (temp < 0) {
112             throw new EOFException();
113         }
114         return temp != 0;
115     }
116
117     /**
118      * Reads an 8-bit byte value from this stream.
119      *
120      * @return the next byte value from the source stream.
121      * @throws EOFException
122      *             if the end of the filtered stream is reached before one byte
123      *             has been read.
124      * @throws IOException
125      *             if a problem occurs while reading from this stream.
126      * @see DataOutput#writeByte(int)
127      */
128     public final byte readByte() throws IOException {
129         int temp = in.read();
130         if (temp < 0) {
131             throw new EOFException();
132         }
133         return (byte) temp;
134     }
135
136     /**
137      * Reads a 16-bit character value from this stream.
138      *
139      * @return the next char value from the source stream.
140      * @throws EOFException
141      *             if the end of the filtered stream is reached before two bytes
142      *             have been read.
143      * @throws IOException
144      *             if a problem occurs while reading from this stream.
145      * @see DataOutput#writeChar(int)
146      */
147     public final char readChar() throws IOException {
148         if (readToBuff(2) < 0){
149             throw new EOFException();
150         }
151         return (char) (((buff[0] & 0xff) << 8) | (buff[1] & 0xff));
152
153     }
154
155     private int readToBuff(int count) throws IOException {
156         int offset = 0;
157
158         while(offset < count) {
159             int bytesRead = in.read(buff, offset, count - offset);
160             if(bytesRead == -1) return bytesRead;
161             offset += bytesRead;
162         }
163         return offset;
164     }
165
166     /**
167      * Reads a 64-bit double value from this stream.
168      *
169      * @return the next double value from the source stream.
170      * @throws EOFException
171      *             if the end of the filtered stream is reached before eight
172      *             bytes have been read.
173      * @throws IOException
174      *             if a problem occurs while reading from this stream.
175      * @see DataOutput#writeDouble(double)
176      */
177     public final double readDouble() throws IOException {
178         return Double.longBitsToDouble(readLong());
179     }
180
181     /**
182      * Reads a 32-bit float value from this stream.
183      *
184      * @return the next float value from the source stream.
185      * @throws EOFException
186      *             if the end of the filtered stream is reached before four
187      *             bytes have been read.
188      * @throws IOException
189      *             if a problem occurs while reading from this stream.
190      * @see DataOutput#writeFloat(float)
191      */
192     public final float readFloat() throws IOException {
193         return Float.intBitsToFloat(readInt());
194     }
195
196     /**
197      * Reads bytes from this stream into the byte array {@code buffer}. This
198      * method will block until {@code buffer.length} number of bytes have been
199      * read.
200      *
201      * @param buffer
202      *            to read bytes into.
203      * @throws EOFException
204      *             if the end of the source stream is reached before enough
205      *             bytes have been read.
206      * @throws IOException
207      *             if a problem occurs while reading from this stream.
208      * @see DataOutput#write(byte[])
209      * @see DataOutput#write(byte[], int, int)
210      */
211     public final void readFully(byte[] buffer) throws IOException {
212         readFully(buffer, 0, buffer.length);
213     }
214
215     /**
216      * Reads bytes from this stream and stores them in the byte array {@code
217      * buffer} starting at the position {@code offset}. This method blocks until
218      * {@code length} bytes have been read. If {@code length} is zero, then this
219      * method returns without reading any bytes.
220      *
221      * @param buffer
222      *            the byte array into which the data is read.
223      * @param offset
224      *            the offset in {@code buffer} from where to store the bytes
225      *            read.
226      * @param length
227      *            the maximum number of bytes to read.
228      * @throws EOFException
229      *             if the end of the source stream is reached before enough
230      *             bytes have been read.
231      * @throws IndexOutOfBoundsException
232      *             if {@code offset < 0} or {@code length < 0}, or if {@code
233      *             offset + length} is greater than the size of {@code buffer}.
234      * @throws IOException
235      *             if a problem occurs while reading from this stream.
236      * @throws NullPointerException
237      *             if {@code buffer} or the source stream are null.
238      * @see java.io.DataInput#readFully(byte[], int, int)
239      */
240     public final void readFully(byte[] buffer, int offset, int length) throws IOException {
241         // BEGIN android-removed
242         // if (length < 0) {
243         //     throw new IndexOutOfBoundsException();
244         // }
245         // END android-removed
246         if (length == 0) {
247             return;
248         }
249         if (in == null) {
250             throw new NullPointerException("in == null");
251         }
252         if (buffer == null) {
253             throw new NullPointerException("buffer == null");
254         }
255         // BEGIN android-changed
256         // Exception priorities (in case of multiple errors) differ from
257         // RI, but are spec-compliant.
258         // used (offset | length) < 0 instead of separate (offset < 0) and
259         // (length < 0) check to safe one operation
260         if ((offset | length) < 0 || offset > buffer.length - length) {
261             throw new IndexOutOfBoundsException();
262         }
263         // END android-changed
264         while (length > 0) {
265             int result = in.read(buffer, offset, length);
266             if (result < 0) {
267                 throw new EOFException();
268             }
269             offset += result;
270             length -= result;
271         }
272     }
273
274     /**
275      * Reads a 32-bit integer value from this stream.
276      *
277      * @return the next int value from the source stream.
278      * @throws EOFException
279      *             if the end of the filtered stream is reached before four
280      *             bytes have been read.
281      * @throws IOException
282      *             if a problem occurs while reading from this stream.
283      * @see DataOutput#writeInt(int)
284      */
285     public final int readInt() throws IOException {
286         if (readToBuff(4) < 0){
287             throw new EOFException();
288         }
289         return ((buff[0] & 0xff) << 24) | ((buff[1] & 0xff) << 16) |
290             ((buff[2] & 0xff) << 8) | (buff[3] & 0xff);
291     }
292
293     /**
294      * Returns a string that contains the next line of text available from the
295      * source stream. A line is represented by zero or more characters followed
296      * by {@code '\n'}, {@code '\r'}, {@code "\r\n"} or the end of the stream.
297      * The string does not include the newline sequence.
298      *
299      * @return the contents of the line or {@code null} if no characters were
300      *         read before the end of the source stream has been reached.
301      * @throws IOException
302      *             if a problem occurs while reading from this stream.
303      * @deprecated Use {@link BufferedReader}
304      */
305     @Deprecated
306     public final String readLine() throws IOException {
307         StringBuilder line = new StringBuilder(80); // Typical line length
308         boolean foundTerminator = false;
309         while (true) {
310             int nextByte = in.read();
311             switch (nextByte) {
312                 case -1:
313                     if (line.length() == 0 && !foundTerminator) {
314                         return null;
315                     }
316                     return line.toString();
317                 case (byte) '\r':
318                     if (foundTerminator) {
319                         ((PushbackInputStream) in).unread(nextByte);
320                         return line.toString();
321                     }
322                     foundTerminator = true;
323                     /* Have to be able to peek ahead one byte */
324                     if (!(in.getClass() == PushbackInputStream.class)) {
325                         in = new PushbackInputStream(in);
326                     }
327                     break;
328                 case (byte) '\n':
329                     return line.toString();
330                 default:
331                     if (foundTerminator) {
332                         ((PushbackInputStream) in).unread(nextByte);
333                         return line.toString();
334                     }
335                     line.append((char) nextByte);
336             }
337         }
338     }
339
340     /**
341      * Reads a 64-bit long value from this stream.
342      *
343      * @return the next long value from the source stream.
344      * @throws EOFException
345      *             if the end of the filtered stream is reached before eight
346      *             bytes have been read.
347      * @throws IOException
348      *             if a problem occurs while reading from this stream.
349      * @see DataOutput#writeLong(long)
350      */
351     public final long readLong() throws IOException {
352         if (readToBuff(8) < 0){
353             throw new EOFException();
354         }
355         int i1 = ((buff[0] & 0xff) << 24) | ((buff[1] & 0xff) << 16) |
356             ((buff[2] & 0xff) << 8) | (buff[3] & 0xff);
357         int i2 = ((buff[4] & 0xff) << 24) | ((buff[5] & 0xff) << 16) |
358             ((buff[6] & 0xff) << 8) | (buff[7] & 0xff);
359
360         return ((i1 & 0xffffffffL) << 32) | (i2 & 0xffffffffL);
361     }
362
363     /**
364      * Reads a 16-bit short value from this stream.
365      *
366      * @return the next short value from the source stream.
367      * @throws EOFException
368      *             if the end of the filtered stream is reached before two bytes
369      *             have been read.
370      * @throws IOException
371      *             if a problem occurs while reading from this stream.
372      * @see DataOutput#writeShort(int)
373      */
374     public final short readShort() throws IOException {
375         if (readToBuff(2) < 0){
376             throw new EOFException();
377         }
378         return (short) (((buff[0] & 0xff) << 8) | (buff[1] & 0xff));
379     }
380
381     /**
382      * Reads an unsigned 8-bit byte value from this stream and returns it as an
383      * int.
384      *
385      * @return the next unsigned byte value from the source stream.
386      * @throws EOFException
387      *             if the end of the filtered stream has been reached before one
388      *             byte has been read.
389      * @throws IOException
390      *             if a problem occurs while reading from this stream.
391      * @see DataOutput#writeByte(int)
392      */
393     public final int readUnsignedByte() throws IOException {
394         int temp = in.read();
395         if (temp < 0) {
396             throw new EOFException();
397         }
398         return temp;
399     }
400
401     /**
402      * Reads a 16-bit unsigned short value from this stream and returns it as an
403      * int.
404      *
405      * @return the next unsigned short value from the source stream.
406      * @throws EOFException
407      *             if the end of the filtered stream is reached before two bytes
408      *             have been read.
409      * @throws IOException
410      *             if a problem occurs while reading from this stream.
411      * @see DataOutput#writeShort(int)
412      */
413     public final int readUnsignedShort() throws IOException {
414         if (readToBuff(2) < 0){
415             throw new EOFException();
416         }
417         return (char) (((buff[0] & 0xff) << 8) | (buff[1] & 0xff));
418     }
419
420     /**
421      * Reads an string encoded in {@link DataInput modified UTF-8} from this
422      * stream.
423      *
424      * @return the next {@link DataInput MUTF-8} encoded string read from the
425      *         source stream.
426      * @throws EOFException if the end of the input is reached before the read
427      *         request can be satisfied.
428      * @throws IOException
429      *             if a problem occurs while reading from this stream.
430      * @see DataOutput#writeUTF(java.lang.String)
431      */
432     public final String readUTF() throws IOException {
433         return decodeUTF(readUnsignedShort());
434     }
435
436
437     String decodeUTF(int utfSize) throws IOException {
438         return decodeUTF(utfSize, this);
439     }
440
441     private static String decodeUTF(int utfSize, DataInput in) throws IOException {
442         byte[] buf = new byte[utfSize];
443         in.readFully(buf, 0, utfSize);
444         return ModifiedUtf8.decode(buf, new char[utfSize], 0, utfSize);
445     }
446
447     /**
448      * Reads a string encoded in {@link DataInput modified UTF-8} from the
449      * {@code DataInput} stream {@code in}.
450      *
451      * @param in
452      *            the input stream to read from.
453      * @return the next {@link DataInput MUTF-8} encoded string from the source
454      *         stream.
455      * @throws IOException
456      *             if a problem occurs while reading from this stream.
457      * @see DataOutputStream#writeUTF(java.lang.String)
458      */
459     public static final String readUTF(DataInput in) throws IOException {
460         return decodeUTF(in.readUnsignedShort(), in);
461     }
462
463     /**
464      * Skips {@code count} number of bytes in this stream. Subsequent {@code
465      * read()}s will not return these bytes unless {@code reset()} is used.
466      *
467      * This method will not throw an {@link EOFException} if the end of the
468      * input is reached before {@code count} bytes where skipped.
469      *
470      * @param count
471      *            the number of bytes to skip.
472      * @return the number of bytes actually skipped.
473      * @throws IOException
474      *             if a problem occurs during skipping.
475      * @see #mark(int)
476      * @see #reset()
477      */
478     public final int skipBytes(int count) throws IOException {
479         int skipped = 0;
480         long skip;
481         while (skipped < count && (skip = in.skip(count - skipped)) != 0) {
482             skipped += skip;
483         }
484         // BEGIN android-removed
485         // if (skipped < 0) {
486         //     throw new EOFException();
487         // }
488         // END android-removed
489         return skipped;
490     }
491 }