FilteredInputStream
implements the
- * DataInput
interface that provides method for reading primitive
- * Java data types from a stream.
- *
- * @see DataInput
- *
- * @version 0.0
- *
- * @author Warren Levy DataInputStream
- * to read from the specified subordinate stream.
- *
- * @param in The subordinate InputStream
to read from
- */
- public DataInputStream(InputStream in)
- {
- super(in);
- }
-
- /**
- * This method reads bytes from the underlying stream into the specified
- * byte array buffer. It will attempt to fill the buffer completely, but
- * may return a short count if there is insufficient data remaining to be
- * read to fill the buffer.
- *
- * @param b The buffer into which bytes will be read.
- *
- * @return The actual number of bytes read, or -1 if end of stream reached
- * before reading any bytes.
- *
- * @exception IOException If an error occurs.
- */
- public final int read(byte[] b) throws IOException
- {
- return in.read(b, 0, b.length);
- }
-
- /**
- * This method reads bytes from the underlying stream into the specified
- * byte array buffer. It will attempt to read len
bytes and
- * will start storing them at position off
into the buffer.
- * This method can return a short count if there is insufficient data
- * remaining to be read to complete the desired read length.
- *
- * @param b The buffer into which bytes will be read.
- * @param off The offset into the buffer to start storing bytes.
- * @param len The requested number of bytes to read.
- *
- * @return The actual number of bytes read, or -1 if end of stream reached
- * before reading any bytes.
- *
- * @exception IOException If an error occurs.
- */
- public final int read(byte[] b, int off, int len) throws IOException
- {
- return in.read(b, off, len);
- }
-
- /**
- * This method reads a Java boolean value from an input stream. It does
- * so by reading a single byte of data. If that byte is zero, then the
- * value returned is false
. If the byte is non-zero, then
- * the value returned is true
.
- *
- * This method can read a boolean
written by an object
- * implementing the writeBoolean()
method in the
- * DataOutput
interface.
- *
- * @return The boolean
value read
- *
- * @exception EOFException If end of file is reached before reading
- * the boolean
- * @exception IOException If any other error occurs
- */
- public final boolean readBoolean() throws IOException
- {
- return convertToBoolean(in.read());
- }
-
- /**
- * This method reads a Java byte value from an input stream. The value
- * is in the range of -128 to 127.
- *
- * This method can read a byte
written by an object
- * implementing the writeByte()
method in the
- * DataOutput
interface.
- *
- * @return The byte
value read
- *
- * @exception EOFException If end of file is reached before reading the byte
- * @exception IOException If any other error occurs
- *
- * @see DataOutput
- */
- public final byte readByte() throws IOException
- {
- return convertToByte(in.read());
- }
-
- /**
- * This method reads a Java char
value from an input stream.
- * It operates by reading two bytes from the stream and converting them to
- * a single 16-bit Java char
. The two bytes are stored most
- * significant byte first (i.e., "big endian") regardless of the native
- * host byte ordering.
- *
- * As an example, if byte1
and byte2
- * represent the first and second byte read from the stream
- * respectively, they will be transformed to a char
in
- * the following manner:
- *
- * (char)(((byte1 & 0xFF) << 8) | (byte2 & 0xFF)
- *
- * This method can read a char
written by an object
- * implementing the writeChar()
method in the
- * DataOutput
interface.
- *
- * @return The char
value read
- *
- * @exception EOFException If end of file is reached before reading the char
- * @exception IOException If any other error occurs
- *
- * @see DataOutput
- */
- public final char readChar() throws IOException
- {
- readFully (buf, 0, 2);
- return convertToChar(buf);
- }
-
- /**
- * This method reads a Java double value from an input stream. It operates
- * by first reading a long
value from the stream by calling the
- * readLong()
method in this interface, then converts
- * that long
to a double
using the
- * longBitsToDouble
method in the class
- * java.lang.Double
- *
- * This method can read a double
written by an object
- * implementing the writeDouble()
method in the
- * DataOutput
interface.
- *
- * @return The double
value read
- *
- * @exception EOFException If end of file is reached before reading
- * the double
- * @exception IOException If any other error occurs
- *
- * @see java.lang.Double
- * @see DataOutput
- */
- public final double readDouble() throws IOException
- {
- return Double.longBitsToDouble(readLong());
- }
-
- /**
- * This method reads a Java float value from an input stream. It
- * operates by first reading an int
value from the
- * stream by calling the readInt()
method in this
- * interface, then converts that int
to a
- * float
using the intBitsToFloat
method
- * in the class java.lang.Float
- *
- * This method can read a float
written by an object
- * implementing the * writeFloat()
method in the
- * DataOutput
interface.
- *
- * @return The float
value read
- *
- * @exception EOFException If end of file is reached before reading the float
- * @exception IOException If any other error occurs
- *
- * @see java.lang.Float
- * @see DataOutput */
- public final float readFloat() throws IOException
- {
- return Float.intBitsToFloat(readInt());
- }
-
- /**
- * This method reads raw bytes into the passed array until the array is
- * full. Note that this method blocks until the data is available and
- * throws an exception if there is not enough data left in the stream to
- * fill the buffer
- *
- * @param b The buffer into which to read the data
- *
- * @exception EOFException If end of file is reached before filling
- * the buffer
- * @exception IOException If any other error occurs */
- public final void readFully(byte[] b) throws IOException
- {
- readFully(b, 0, b.length);
- }
-
- /**
- * This method reads raw bytes into the passed array
- * buf
starting offset
bytes into the
- * buffer. The number of bytes read will be exactly
- * len
Note that this method blocks until the data is
- * available and * throws an exception if there is not enough data
- * left in the stream to read len
bytes.
- *
- * @param buf The buffer into which to read the data
- * @param offset The offset into the buffer to start storing data
- * @param len The number of bytes to read into the buffer
- *
- * @exception EOFException If end of file is reached before filling
- * the buffer
- * @exception IOException If any other error occurs
- */
- public final void readFully(byte[] b, int off, int len) throws IOException
- {
- while (len > 0)
- {
- // in.read will block until some data is available.
- int numread = in.read(b, off, len);
- if (numread < 0)
- throw new EOFException();
- len -= numread;
- off += numread;
- }
- }
-
- /**
- * This method reads a Java int
value from an input
- * stream It operates by reading four bytes from the stream and
- * converting them to a single Java int
The bytes are
- * stored most significant byte first (i.e., "big endian")
- * regardless of the native host byte ordering.
- *
- * As an example, if byte1
through byte4
- * represent the first four bytes read from the stream, they will be
- * transformed to an int
in the following manner:
- *
- * (int)(((byte1 & 0xFF) << 24) + ((byte2 & 0xFF) << 16) +
- * ((byte3 & 0xFF) << 8) + (byte4 & 0xFF)))
- *
- * The value returned is in the range of 0 to 65535. - *
- * This method can read an int
written by an object
- * implementing the writeInt()
method in the
- * DataOutput
interface.
- *
- * @return The int
value read
- *
- * @exception EOFException If end of file is reached before reading the int
- * @exception IOException If any other error occurs
- *
- * @see DataOutput
- */
- public final int readInt() throws IOException
- {
- readFully (buf, 0, 4);
- return convertToInt(buf);
- }
-
- /**
- * This method reads the next line of text data from an input
- * stream. It operates by reading bytes and converting those bytes
- * to char
values by treating the byte read as the low
- * eight bits of the char
and using 0 as the high eight
- * bits. Because of this, it does not support the full 16-bit
- * Unicode character set.
- *
- * The reading of bytes ends when either the end of file or a line
- * terminator is encountered. The bytes read are then returned as a
- * String
A line terminator is a byte sequence
- * consisting of either \r
, \n
or
- * \r\n
. These termination charaters are discarded and
- * are not returned as part of the string.
- *
- * This method can read data that was written by an object implementing the
- * writeLine()
method in DataOutput
.
- *
- * @return The line read as a String
- *
- * @exception IOException If an error occurs
- *
- * @see DataOutput
- *
- * @deprecated
- */
- public final String readLine() throws IOException
- {
- StringBuffer strb = new StringBuffer();
-
- readloop: while (true)
- {
- int c = 0;
- char ch = ' ';
- boolean getnext = true;
- while (getnext)
- {
- getnext = false;
- c = in.read();
- if (c < 0) // got an EOF
- return strb.length() > 0 ? strb.toString() : null;
- ch = (char) c;
- if ((ch &= 0xFF) == '\n')
- // hack to correctly handle '\r\n' sequences
- if (ignoreInitialNewline)
- {
- ignoreInitialNewline = false;
- getnext = true;
- }
- else
- break readloop;
- }
-
- if (ch == '\r')
- {
- // FIXME: The following code tries to adjust the stream back one
- // character if the next char read is '\n'. As a last resort,
- // it tries to mark the position before reading but the bottom
- // line is that it is possible that this method will not properly
- // deal with a '\r' '\n' combination thus not fulfilling the
- // DataInput contract for readLine. It's not a particularly
- // safe approach threadwise since it is unsynchronized and
- // since it might mark an input stream behind the users back.
- // Along the same vein it could try the same thing for
- // ByteArrayInputStream and PushbackInputStream, but that is
- // probably overkill since this is deprecated & BufferedInputStream
- // is the most likely type of input stream.
- //
- // The alternative is to somehow push back the next byte if it
- // isn't a '\n' or to have the reading methods of this class
- // keep track of whether the last byte read was '\r' by readLine
- // and then skip the very next byte if it is '\n'. Either way,
- // this would increase the complexity of the non-deprecated methods
- // and since it is undesirable to make non-deprecated methods
- // less efficient, the following seems like the most reasonable
- // approach.
- int next_c = 0;
- char next_ch = ' ';
- if (in instanceof BufferedInputStream)
- {
- next_c = in.read();
- next_ch = (char) (next_c & 0xFF);
- if ((next_ch != '\n') && (next_c >= 0))
- {
- BufferedInputStream bin = (BufferedInputStream) in;
- if (bin.pos > 0)
- bin.pos--;
- }
- }
- else if (markSupported())
- {
- next_c = in.read();
- next_ch = (char) (next_c & 0xFF);
- if ((next_ch != '\n') && (next_c >= 0))
- {
- mark(1);
- if ((in.read() & 0xFF) != '\n')
- reset();
- }
- }
- // In order to catch cases where 'in' isn't a BufferedInputStream
- // and doesn't support mark() (such as reading from a Socket), set
- // a flag that instructs readLine() to ignore the first character
- // it sees _if_ that character is a '\n'.
- else ignoreInitialNewline = true;
- break;
- }
- strb.append(ch);
- }
-
- return strb.length() > 0 ? strb.toString() : "";
- }
-
- /**
- * This method reads a Java long value from an input stream
- * It operates by reading eight bytes from the stream and converting them to
- * a single Java long
The bytes are stored most
- * significant byte first (i.e., "big endian") regardless of the native
- * host byte ordering.
- *
- * As an example, if byte1
through byte8
- * represent the first eight bytes read from the stream, they will
- * be transformed to an long
in the following manner:
- *
- * (long)((((long)byte1 & 0xFF) << 56) + (((long)byte2 & 0xFF) << 48) +
- * (((long)byte3 & 0xFF) << 40) + (((long)byte4 & 0xFF) << 32) +
- * (((long)byte5 & 0xFF) << 24) + (((long)byte6 & 0xFF) << 16) +
- * (((long)byte7 & 0xFF) << 8) + ((long)byte9 & 0xFF)))
- *
- * The value returned is in the range of 0 to 65535. - *
- * This method can read an long
written by an object
- * implementing the writeLong()
method in the
- * DataOutput
interface.
- *
- * @return The long
value read
- *
- * @exception EOFException If end of file is reached before reading the long
- * @exception IOException If any other error occurs
- *
- * @see DataOutput
- */
- public final long readLong() throws IOException
- {
- readFully (buf, 0, 8);
- return convertToLong(buf);
- }
-
- /**
- * This method reads a signed 16-bit value into a Java in from the
- * stream. It operates by reading two bytes from the stream and
- * converting them to a single 16-bit Java short
. The
- * two bytes are stored most significant byte first (i.e., "big
- * endian") regardless of the native host byte ordering.
- *
- * As an example, if byte1
and byte2
- * represent the first and second byte read from the stream
- * respectively, they will be transformed to a short
. in
- * the following manner:
- *
- * (short)(((byte1 & 0xFF) << 8) | (byte2 & 0xFF)
- *
- * The value returned is in the range of -32768 to 32767. - *
- * This method can read a short
written by an object
- * implementing the writeShort()
method in the
- * DataOutput
interface.
- *
- * @return The short
value read
- *
- * @exception EOFException If end of file is reached before reading the value
- * @exception IOException If any other error occurs
- *
- * @see DataOutput
- */
- public final short readShort() throws IOException
- {
- readFully (buf, 0, 2);
- return convertToShort(buf);
- }
-
- /**
- * This method reads 8 unsigned bits into a Java int
- * value from the stream. The value returned is in the range of 0 to
- * 255.
- *
- * This method can read an unsigned byte written by an object
- * implementing the writeUnsignedByte()
method in the
- * DataOutput
interface.
- *
- * @return The unsigned bytes value read as a Java int
.
- *
- * @exception EOFException If end of file is reached before reading the value
- * @exception IOException If any other error occurs
- *
- * @see DataOutput
- */
- public final int readUnsignedByte() throws IOException
- {
- return convertToUnsignedByte(in.read());
- }
-
- /**
- * This method reads 16 unsigned bits into a Java int value from the stream.
- * It operates by reading two bytes from the stream and converting them to
- * a single Java int
The two bytes are stored most
- * significant byte first (i.e., "big endian") regardless of the native
- * host byte ordering.
- *
- * As an example, if byte1
and byte2
- * represent the first and second byte read from the stream
- * respectively, they will be transformed to an int
in
- * the following manner:
- *
- * (int)(((byte1 & 0xFF) << 8) + (byte2 & 0xFF))
- *
- * The value returned is in the range of 0 to 65535. - *
- * This method can read an unsigned short written by an object
- * implementing the writeUnsignedShort()
method in the
- * DataOutput
interface.
- *
- * @return The unsigned short value read as a Java int
- *
- * @exception EOFException If end of file is reached before reading the value
- * @exception IOException If any other error occurs
- */
- public final int readUnsignedShort() throws IOException
- {
- readFully (buf, 0, 2);
- return convertToUnsignedShort(buf);
- }
-
- /**
- * This method reads a String
from an input stream that
- * is encoded in a modified UTF-8 format. This format has a leading
- * two byte sequence that contains the remaining number of bytes to
- * read. This two byte sequence is read using the
- * readUnsignedShort()
method of this interface.
- *
- * After the number of remaining bytes have been determined, these
- * bytes are read an transformed into char
values.
- * These char
values are encoded in the stream using
- * either a one, two, or three byte format. The particular format
- * in use can be determined by examining the first byte read.
- *
- * If the first byte has a high order bit of 0, then that character
- * consists on only one byte. This character value consists of
- * seven bits that are at positions 0 through 6 of the byte. As an
- * example, if byte1
is the byte read from the stream,
- * it would be converted to a char
like so:
- *
- * (char)byte1
- *
- * If the first byte has 110 as its high order bits, then the - * character consists of two bytes. The bits that make up the character - * value are in positions 0 through 4 of the first byte and bit positions - * 0 through 5 of the second byte. (The second byte should have - * 10 as its high order bits). These values are in most significant - * byte first (i.e., "big endian") order. - *
- * As an example, if byte1
and byte2
are
- * the first two bytes read respectively, and the high order bits of
- * them match the patterns which indicate a two byte character
- * encoding, then they would be converted to a Java
- * char
like so:
- *
- * (char)(((byte1 & 0x1F) << 6) | (byte2 & 0x3F))
- *
- * If the first byte has a 1110 as its high order bits, then the - * character consists of three bytes. The bits that make up the character - * value are in positions 0 through 3 of the first byte and bit positions - * 0 through 5 of the other two bytes. (The second and third bytes should - * have 10 as their high order bits). These values are in most - * significant byte first (i.e., "big endian") order. - *
- * As an example, if byte1
byte2
and
- * byte3
are the three bytes read, and the high order
- * bits of them match the patterns which indicate a three byte
- * character encoding, then they would be converted to a Java
- * char
like so:
- *
- * (char)(((byte1 & 0x0F) << 12) | ((byte2 & 0x3F) << 6) | (byte3 & 0x3F))
- *
- * Note that all characters are encoded in the method that requires
- * the fewest number of bytes with the exception of the character
- * with the value of \u0000
which is encoded as two
- * bytes. This is a modification of the UTF standard used to
- * prevent C language style NUL
values from appearing
- * in the byte stream.
- *
- * This method can read data that was written by an object implementing the
- * writeUTF()
method in DataOutput
- *
- * @returns The String
read
- *
- * @exception EOFException If end of file is reached before reading
- * the String
- * @exception UTFDataFormatException If the data is not in UTF-8 format
- * @exception IOException If any other error occurs
- *
- * @see DataOutput
- */
- public final String readUTF() throws IOException
- {
- return readUTF(this);
- }
-
- /**
- * This method reads a String encoded in UTF-8 format from the
- * specified DataInput
source.
- *
- * @param in The DataInput
source to read from
- *
- * @return The String read from the source
- *
- * @exception IOException If an error occurs
- */
- public final static String readUTF(DataInput in) throws IOException
- {
- final int UTFlen = in.readUnsignedShort();
- byte[] buf = new byte[UTFlen];
-
- // This blocks until the entire string is available rather than
- // doing partial processing on the bytes that are available and then
- // blocking. An advantage of the latter is that Exceptions
- // could be thrown earlier. The former is a bit cleaner.
- in.readFully(buf, 0, UTFlen);
-
- return convertFromUTF(buf);
- }
-
- /**
- * This method attempts to skip and discard the specified number of bytes
- * in the input stream. It may actually skip fewer bytes than requested.
- * This method will not skip any bytes if passed a negative number of bytes
- * to skip.
- *
- * @param n The requested number of bytes to skip.
- * @return The requested number of bytes to skip.
- * @exception IOException If an error occurs.
- * @specnote The JDK docs claim that this returns the number of bytes
- * actually skipped. The JCL claims that this method can throw an
- * EOFException. Neither of these appear to be true in the JDK 1.3's
- * implementation. This tries to implement the actual JDK behaviour.
- */
- public final int skipBytes(int n) throws IOException
- {
- if (n <= 0)
- return 0;
- try
- {
- return (int) in.skip(n);
- }
- catch (EOFException x)
- {
- // do nothing.
- }
- return n;
- }
-
- static boolean convertToBoolean(int b) throws EOFException
- {
- if (b < 0)
- throw new EOFException();
- return (b != 0);
- }
-
- static byte convertToByte(int i) throws EOFException
- {
- if (i < 0)
- throw new EOFException();
- return (byte) i;
- }
-
- static int convertToUnsignedByte(int i) throws EOFException
- {
- if (i < 0)
- throw new EOFException();
- return (i & 0xFF);
- }
-
- static char convertToChar(byte[] buf)
- {
- return (char) ((buf[0] << 8) | (buf[1] & 0xff));
- }
-
- static short convertToShort(byte[] buf)
- {
- return (short) ((buf[0] << 8) | (buf[1] & 0xff));
- }
-
- static int convertToUnsignedShort(byte[] buf)
- {
- return (((buf[0] & 0xff) << 8) | (buf[1] & 0xff));
- }
-
- static int convertToInt(byte[] buf)
- {
- return (((buf[0] & 0xff) << 24) | ((buf[1] & 0xff) << 16) |
- ((buf[2] & 0xff) << 8) | (buf[3] & 0xff));
- }
-
- static long convertToLong(byte[] buf)
- {
- return (((long)(buf[0] & 0xff) << 56) |
- ((long)(buf[1] & 0xff) << 48) |
- ((long)(buf[2] & 0xff) << 40) |
- ((long)(buf[3] & 0xff) << 32) |
- ((long)(buf[4] & 0xff) << 24) |
- ((long)(buf[5] & 0xff) << 16) |
- ((long)(buf[6] & 0xff) << 8) |
- ((long)(buf[7] & 0xff)));
- }
-
- static String convertFromUTF(byte[] buf)
- throws EOFException, UTFDataFormatException
- {
- StringBuffer strbuf = new StringBuffer();
-
- for (int i = 0; i < buf.length; )
- {
- if ((buf[i] & 0x80) == 0) // bit pattern 0xxxxxxx
- strbuf.append((char) (buf[i++] & 0xFF));
- else if ((buf[i] & 0xE0) == 0xC0) // bit pattern 110xxxxx
- {
- if (i + 1 >= buf.length || (buf[i+1] & 0xC0) != 0x80)
- throw new UTFDataFormatException();
-
- strbuf.append((char) (((buf[i++] & 0x1F) << 6) |
- (buf[i++] & 0x3F)));
- }
- else if ((buf[i] & 0xF0) == 0xE0) // bit pattern 1110xxxx
- {
- if (i + 2 >= buf.length ||
- (buf[i+1] & 0xC0) != 0x80 || (buf[i+2] & 0xC0) != 0x80)
- throw new UTFDataFormatException();
-
- strbuf.append((char) (((buf[i++] & 0x0F) << 12) |
- ((buf[i++] & 0x3F) << 6) |
- (buf[i++] & 0x3F)));
- }
- else // must be ((buf[i] & 0xF0) == 0xF0 || (buf[i] & 0xC0) == 0x80)
- throw new UTFDataFormatException(); // bit patterns 1111xxxx or
- // 10xxxxxx
- }
-
- return strbuf.toString();
- }
-}