1 /* Copyright (C) 1998, 1999 Cygnus Solutions
3 This file is part of libgcj.
5 This software is copyrighted work licensed under the terms of the
6 Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
12 * @author Warren Levy <warrenl@cygnus.com>
13 * @date October 20, 1998.
16 /* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
17 * "The Java Language Specification", ISBN 0-201-63451-1
18 * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
19 * Status: Believed complete and correct.
22 public class DataInputStream extends FilterInputStream implements DataInput
24 // readLine() hack to ensure that an '\r' not followed by an '\n' is
25 // handled correctly. If set, readLine() will ignore the first char it sees
26 // if that char is a '\n'
27 boolean ignoreInitialNewline = false;
29 public DataInputStream(InputStream in)
34 public final int read(byte[] b) throws IOException
36 return super.read(b, 0, b.length);
39 public final int read(byte[] b, int off, int len) throws IOException
41 if (off < 0 || len < 0 || off + len > b.length)
42 throw new ArrayIndexOutOfBoundsException();
44 return super.read(b, off, len);
47 public final boolean readBoolean() throws IOException
49 return (readByte() != 0);
52 public final byte readByte() throws IOException
56 throw new EOFException();
61 public final char readChar() throws IOException
63 return (char) ((readByte() << 8) | readUnsignedByte());
66 public final double readDouble() throws IOException
68 return Double.longBitsToDouble(readLong());
71 public final float readFloat() throws IOException
73 return Float.intBitsToFloat(readInt());
76 public final void readFully(byte[] b) throws IOException
78 readFully(b, 0, b.length);
81 public final void readFully(byte[] b, int off, int len) throws IOException
83 if (off < 0 || len < 0 || off + len > b.length)
84 throw new ArrayIndexOutOfBoundsException();
88 // super.read will block until some data is available.
89 int numread = super.read(b, off, len);
91 throw new EOFException();
97 public final int readInt() throws IOException
100 for (int i = 0; i < 4; i++)
101 retval |= readUnsignedByte() << (24 - i * 8);
106 // Deprecated as of JDK 1.1
107 public final String readLine() throws IOException
109 StringBuffer strb = new StringBuffer();
111 readloop: while (true)
115 boolean getnext = true;
120 if (c < 0) // got an EOF
121 return strb.length() > 0 ? strb.toString() : null;
123 if ((ch &= 0xFF) == '\n')
124 // hack to correctly handle '\r\n' sequences
125 if (ignoreInitialNewline)
127 ignoreInitialNewline = false;
136 // FIXME: The following code tries to adjust the stream back one
137 // character if the next char read is '\n'. As a last resort,
138 // it tries to mark the position before reading but the bottom
139 // line is that it is possible that this method will not properly
140 // deal with a '\r' '\n' combination thus not fulfilling the
141 // DataInput contract for readLine. It's not a particularly
142 // safe approach threadwise since it is unsynchronized and
143 // since it might mark an input stream behind the users back.
144 // Along the same vein it could try the same thing for
145 // ByteArrayInputStream and PushbackInputStream, but that is
146 // probably overkill since this is deprecated & BufferedInputStream
147 // is the most likely type of input stream.
149 // The alternative is to somehow push back the next byte if it
150 // isn't a '\n' or to have the reading methods of this class
151 // keep track of whether the last byte read was '\r' by readLine
152 // and then skip the very next byte if it is '\n'. Either way,
153 // this would increase the complexity of the non-deprecated methods
154 // and since it is undesirable to make non-deprecated methods
155 // less efficient, the following seems like the most reasonable
159 if (in instanceof BufferedInputStream)
162 next_ch = (char) (next_c & 0xFF);
163 if ((next_ch != '\n') && (next_c >= 0))
165 BufferedInputStream bin = (BufferedInputStream) in;
170 else if (markSupported())
173 next_ch = (char) (next_c & 0xFF);
174 if ((next_ch != '\n') && (next_c >= 0))
177 if ((read() & 0xFF) != '\n')
181 // In order to catch cases where 'in' isn't a BufferedInputStream
182 // and doesn't support mark() (such as reading from a Socket), set
183 // a flag that instructs readLine() to ignore the first character
184 // it sees _if_ that character is a '\n'.
185 else ignoreInitialNewline = true;
191 return strb.length() > 0 ? strb.toString() : "";
194 public final long readLong() throws IOException
197 for (int i = 0; i < 8; i++)
198 retval |= (long) readUnsignedByte() << (56 - i * 8);
203 public final short readShort() throws IOException
205 return (short) ((readByte() << 8) | readUnsignedByte());
208 public final int readUnsignedByte() throws IOException
212 throw new EOFException();
217 public final int readUnsignedShort() throws IOException
219 return (readUnsignedByte() << 8) | readUnsignedByte();
222 public final String readUTF() throws IOException
224 return readUTF(this);
227 public final static String readUTF(DataInput in) throws IOException
229 final int UTFlen = in.readUnsignedShort();
230 byte[] buf = new byte[UTFlen];
231 StringBuffer strbuf = new StringBuffer();
233 // This blocks until the entire string is available rather than
234 // doing partial processing on the bytes that are available and then
235 // blocking. An advantage of the latter is that Exceptions
236 // could be thrown earlier. The former is a bit cleaner.
237 in.readFully(buf, 0, UTFlen);
238 for (int i = 0; i < UTFlen; )
240 if ((buf[i] & 0x80) == 0) // bit pattern 0xxxxxxx
241 strbuf.append((char) (buf[i++] & 0xFF));
242 else if ((buf[i] & 0xE0) == 0xC0) // bit pattern 110xxxxx
244 if (i + 1 >= UTFlen || (buf[i+1] & 0xC0) != 0x80)
245 throw new UTFDataFormatException();
247 strbuf.append((char) (((buf[i++] & 0x1F) << 6) |
250 else if ((buf[i] & 0xF0) == 0xE0) // bit pattern 1110xxxx
252 if (i + 2 >= UTFlen ||
253 (buf[i+1] & 0xC0) != 0x80 || (buf[i+2] & 0xC0) != 0x80)
254 throw new UTFDataFormatException();
256 strbuf.append((char) (((buf[i++] & 0x0F) << 12) |
257 ((buf[i++] & 0x3F) << 6) |
260 else // must be ((buf[i] & 0xF0) == 0xF0 || (buf[i] & 0xC0) == 0x80)
261 throw new UTFDataFormatException(); // bit patterns 1111xxxx or
265 return strbuf.toString();
268 public final int skipBytes(int n) throws IOException
270 // The contract in the Java Lang. Spec. says that this never
271 // throws an EOFException and infers that it doesn't block (since
272 // it may skip less than the requested number of bytes).
273 // BUT, the JCL book specifically says that this method blocks
274 // and can throw an EOFException. Finally, the Java 1.2 online
275 // doc simply refers to the general contract. As such, we will
276 // stick to the contract and assume for now that the JCL book
279 // Since we're only skipping at most an int number of bytes, the cast
280 // of return value to an int is fine.
283 n = Math.min(n, available());
284 return (int) super.skip((long) n);