mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			290 lines
		
	
	
		
			8.2 KiB
		
	
	
	
		
			Java
		
	
	
	
			
		
		
	
	
			290 lines
		
	
	
		
			8.2 KiB
		
	
	
	
		
			Java
		
	
	
	
| /* Copyright (C) 1998, 1999  Red Hat, Inc.
 | |
| 
 | |
|    This file is part of libgcj.
 | |
| 
 | |
| This software is copyrighted work licensed under the terms of the
 | |
| Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
 | |
| details.  */
 | |
|  
 | |
| package java.io;
 | |
| 
 | |
| /**
 | |
|  * @author Warren Levy <warrenl@cygnus.com>
 | |
|  * @date October 20, 1998.  
 | |
|  */
 | |
| 
 | |
| /* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
 | |
|  * "The Java Language Specification", ISBN 0-201-63451-1
 | |
|  * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
 | |
|  * Status:  Believed complete and correct.
 | |
|  */
 | |
|  
 | |
| public class DataInputStream extends FilterInputStream implements DataInput
 | |
| {
 | |
|   // readLine() hack to ensure that an '\r' not followed by an '\n' is
 | |
|   // handled correctly. If set, readLine() will ignore the first char it sees
 | |
|   // if that char is a '\n'
 | |
|   boolean ignoreInitialNewline = false;
 | |
|   
 | |
|   public DataInputStream(InputStream in)
 | |
|   {
 | |
|     super(in);
 | |
|   }
 | |
| 
 | |
|   public final int read(byte[] b) throws IOException
 | |
|   {
 | |
|     return super.read(b, 0, b.length);
 | |
|   }
 | |
| 
 | |
|   public final int read(byte[] b, int off, int len) throws IOException
 | |
|   {
 | |
|     if (off < 0 || len < 0 || off + len > b.length)
 | |
|       throw new ArrayIndexOutOfBoundsException();
 | |
| 
 | |
|     return super.read(b, off, len);
 | |
|   }
 | |
| 
 | |
|   public final boolean readBoolean() throws IOException
 | |
|   {
 | |
|     return (readByte() != 0);
 | |
|   }
 | |
| 
 | |
|   public final byte readByte() throws IOException
 | |
|   {
 | |
|     int i = read();
 | |
|     if (i < 0)
 | |
|       throw new EOFException();
 | |
| 
 | |
|     return (byte) i;
 | |
|   }
 | |
| 
 | |
|   public final char readChar() throws IOException
 | |
|   {
 | |
|     return (char) ((readByte() << 8) | readUnsignedByte());
 | |
|   }
 | |
| 
 | |
|   public final double readDouble() throws IOException
 | |
|   {
 | |
|     return Double.longBitsToDouble(readLong());
 | |
|   }
 | |
| 
 | |
|   public final float readFloat() throws IOException
 | |
|   {
 | |
|     return Float.intBitsToFloat(readInt());
 | |
|   }
 | |
| 
 | |
|   public final void readFully(byte[] b) throws IOException
 | |
|   {
 | |
|     readFully(b, 0, b.length);
 | |
|   }
 | |
| 
 | |
|   public final void readFully(byte[] b, int off, int len) throws IOException
 | |
|   {
 | |
|     if (off < 0 || len < 0 || off + len > b.length)
 | |
|       throw new ArrayIndexOutOfBoundsException();
 | |
| 
 | |
|     while (len > 0)
 | |
|       {
 | |
| 	// super.read will block until some data is available.
 | |
| 	int numread = super.read(b, off, len);
 | |
| 	if (numread < 0)
 | |
| 	  throw new EOFException();
 | |
| 	len -= numread;
 | |
| 	off += numread;
 | |
|       }
 | |
|   }
 | |
| 
 | |
|   public final int readInt() throws IOException
 | |
|   {
 | |
|     int retval = 0;
 | |
|     for (int i = 0; i < 4; i++)
 | |
|       retval |= readUnsignedByte() << (24 - i * 8);
 | |
| 
 | |
|     return retval;
 | |
|   }
 | |
| 
 | |
|   // Deprecated as of JDK 1.1
 | |
|   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 = 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 = 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 = read();
 | |
| 	        next_ch = (char) (next_c & 0xFF);
 | |
| 		if ((next_ch != '\n') && (next_c >= 0)) 
 | |
| 		  {
 | |
| 		    mark(1);
 | |
| 		    if ((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() : "";
 | |
|   }
 | |
| 
 | |
|   public final long readLong() throws IOException
 | |
|   {
 | |
|     long retval = 0L;
 | |
|     for (int i = 0; i < 8; i++)
 | |
|       retval |= (long) readUnsignedByte() << (56 - i * 8);
 | |
| 
 | |
|     return retval;
 | |
|   }
 | |
| 
 | |
|   public final short readShort() throws IOException
 | |
|   {
 | |
|     return (short) ((readByte() << 8) | readUnsignedByte());
 | |
|   }
 | |
| 
 | |
|   public final int readUnsignedByte() throws IOException
 | |
|   {
 | |
|     int i = read();
 | |
|     if (i < 0)
 | |
|       throw new EOFException();
 | |
| 
 | |
|     return (i & 0xFF);
 | |
|   }
 | |
| 
 | |
|   public final int readUnsignedShort() throws IOException
 | |
|   {
 | |
|     return (readUnsignedByte() << 8) | readUnsignedByte();
 | |
|   }
 | |
| 
 | |
|   public final String readUTF() throws IOException
 | |
|   {
 | |
|     return readUTF(this);
 | |
|   }
 | |
| 
 | |
|   public final static String readUTF(DataInput in) throws IOException
 | |
|   {
 | |
|     final int UTFlen = in.readUnsignedShort();
 | |
|     byte[] buf = new byte[UTFlen];
 | |
|     StringBuffer strbuf = new StringBuffer();
 | |
| 
 | |
|     // 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);
 | |
|     for (int i = 0; i < UTFlen; )
 | |
|       {
 | |
| 	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 >= UTFlen || (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 >= UTFlen ||
 | |
| 		(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();
 | |
|   }
 | |
| 
 | |
|   public final int skipBytes(int n) throws IOException
 | |
|   {
 | |
|     // The contract in the Java Lang. Spec. says that this never
 | |
|     // throws an EOFException and infers that it doesn't block (since
 | |
|     // it may skip less than the requested number of bytes).
 | |
|     // BUT, the JCL book specifically says that this method blocks
 | |
|     // and can throw an EOFException.  Finally, the Java 1.2 online
 | |
|     // doc simply refers to the general contract.  As such, we will
 | |
|     // stick to the contract and assume for now that the JCL book
 | |
|     // is incorrect.
 | |
| 
 | |
|     // Since we're only skipping at most an int number of bytes, the cast
 | |
|     // of return value to an int is fine.
 | |
|     if (n > 0)
 | |
|       {
 | |
| 	n = Math.min(n, available());
 | |
|         return (int) super.skip((long) n);
 | |
|       }
 | |
| 
 | |
|     return 0;
 | |
|   }
 | |
| }
 |