Source for gnu.CORBA.CDR.LittleEndianInputStream

   1: /* LittleEndianInputStream.java --
   2:    Copyright (C) 1998, 1999, 2000, 2001, 2003, 2005  Free Software Foundation
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10: 
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version. */
  37: 
  38: 
  39: package gnu.CORBA.CDR;
  40: 
  41: import java.io.DataInput;
  42: import java.io.EOFException;
  43: import java.io.FilterInputStream;
  44: import java.io.IOException;
  45: import java.io.InputStream;
  46: import java.io.PushbackInputStream;
  47: 
  48: /**
  49:  * This class reads data in the Little Endian format. It reuses
  50:  * code from GNU Classpath DataInputStream.
  51:  *
  52:  * @author Audrius Meskauskas (AudriusA@Bioinformatics.org)
  53:  * @author Warren Levy (warrenl@cygnus.com)
  54:  * @author Aaron M. Renn (arenn@urbanophile.com)
  55:  */
  56: public class LittleEndianInputStream
  57:   extends FilterInputStream
  58:   implements AbstractDataInput
  59: {
  60:   // Byte buffer, used to make primitive read calls more efficient.
  61:   byte[] buf = new byte[ 8 ];
  62: 
  63:   /**
  64:    * This constructor initializes a new <code>DataInputStream</code>
  65:    * to read from the specified subordinate stream.
  66:    *
  67:    * @param in The subordinate <code>InputStream</code> to read from
  68:    */
  69:   public LittleEndianInputStream(InputStream in)
  70:   {
  71:     super(in);
  72:   }
  73: 
  74:   /**
  75:    * This method reads bytes from the underlying stream into the specified
  76:    * byte array buffer.  It will attempt to fill the buffer completely, but
  77:    * may return a short count if there is insufficient data remaining to be
  78:    * read to fill the buffer.
  79:    *
  80:    * @param b The buffer into which bytes will be read.
  81:    *
  82:    * @return The actual number of bytes read, or -1 if end of stream reached
  83:    * before reading any bytes.
  84:    *
  85:    * @exception IOException If an error occurs.
  86:    */
  87:   public int read(byte[] b)
  88:            throws IOException
  89:   {
  90:     return in.read(b, 0, b.length);
  91:   }
  92: 
  93:   /**
  94:    * This method reads bytes from the underlying stream into the specified
  95:    * byte array buffer.  It will attempt to read <code>len</code> bytes and
  96:    * will start storing them at position <code>off</code> into the buffer.
  97:    * This method can return a short count if there is insufficient data
  98:    * remaining to be read to complete the desired read length.
  99:    *
 100:    * @param b The buffer into which bytes will be read.
 101:    * @param off The offset into the buffer to start storing bytes.
 102:    * @param len The requested number of bytes to read.
 103:    *
 104:    * @return The actual number of bytes read, or -1 if end of stream reached
 105:    * before reading any bytes.
 106:    *
 107:    * @exception IOException If an error occurs.
 108:    */
 109:   public int read(byte[] b, int off, int len)
 110:            throws IOException
 111:   {
 112:     return in.read(b, off, len);
 113:   }
 114: 
 115:   /**
 116:    * This method reads a Java boolean value from an input stream.  It does
 117:    * so by reading a single byte of data.  If that byte is zero, then the
 118:    * value returned is <code>false</code>.  If the byte is non-zero, then
 119:    * the value returned is <code>true</code>.
 120:    * <p>
 121:    * This method can read a <code>boolean</code> written by an object
 122:    * implementing the <code>writeBoolean()</code> method in the
 123:    * <code>DataOutput</code> interface.
 124:    *
 125:    * @return The <code>boolean</code> value read
 126:    *
 127:    * @exception EOFException If end of file is reached before reading
 128:    * the boolean
 129:    * @exception IOException If any other error occurs
 130:    *
 131:    * @see DataOutput#writeBoolean
 132:    */
 133:   public boolean readBoolean()
 134:                       throws IOException
 135:   {
 136:     return convertToBoolean(in.read());
 137:   }
 138: 
 139:   /**
 140:    * This method reads a Java byte value from an input stream.  The value
 141:    * is in the range of -128 to 127.
 142:    * <p>
 143:    * This method can read a <code>byte</code> written by an object
 144:    * implementing the <code>writeByte()</code> method in the
 145:    * <code>DataOutput</code> interface.
 146:    *
 147:    * @return The <code>byte</code> value read
 148:    *
 149:    * @exception EOFException If end of file is reached before reading the byte
 150:    * @exception IOException If any other error occurs
 151:    *
 152:    * @see DataOutput#writeByte
 153:    */
 154:   public byte readByte()
 155:                 throws IOException
 156:   {
 157:     return convertToByte(in.read());
 158:   }
 159: 
 160:   /**
 161:    * This method reads a Java <code>char</code> value from an input stream.
 162:    * It operates by reading two bytes from the stream and converting them to
 163:    * a single 16-bit Java <code>char</code>.  The two bytes are stored most
 164:    * significant byte first (i.e., "big endian") regardless of the native
 165:    * host byte ordering.
 166:    * <p>
 167:    * As an example, if <code>byte1</code> and <code>byte2</code>
 168:    * represent the first and second byte read from the stream
 169:    * respectively, they will be transformed to a <code>char</code> in
 170:    * the following manner:
 171:    * <p>
 172:    * <code>(char)(((byte1 &amp; 0xFF) &lt;&lt; 8) | (byte2 &amp; 0xFF)</code>
 173:    * <p>
 174:    * This method can read a <code>char</code> written by an object
 175:    * implementing the <code>writeChar()</code> method in the
 176:    * <code>DataOutput</code> interface.
 177:    *
 178:    * @return The <code>char</code> value read
 179:    *
 180:    * @exception EOFException If end of file is reached before reading the char
 181:    * @exception IOException If any other error occurs
 182:    *
 183:    * @see DataOutput#writeChar
 184:    */
 185:   public char readChar()
 186:                 throws IOException
 187:   {
 188:     readFully(buf, 0, 2);
 189:     return convertToChar(buf);
 190:   }
 191: 
 192:   /**
 193:    * This method reads a Java double value from an input stream.  It operates
 194:    * by first reading a <code>long</code> value from the stream by calling the
 195:    * <code>readLong()</code> method in this interface, then converts
 196:    * that <code>long</code> to a <code>double</code> using the
 197:    * <code>longBitsToDouble</code> method in the class
 198:    * <code>java.lang.Double</code>
 199:    * <p>
 200:    * This method can read a <code>double</code> written by an object
 201:    * implementing the <code>writeDouble()</code> method in the
 202:    * <code>DataOutput</code> interface.
 203:    *
 204:    * @return The <code>double</code> value read
 205:    *
 206:    * @exception EOFException If end of file is reached before reading
 207:    * the double
 208:    * @exception IOException If any other error occurs
 209:    *
 210:    * @see DataOutput#writeDouble
 211:    * @see java.lang.Double#longBitsToDouble
 212:    */
 213:   public double readDouble()
 214:                     throws IOException
 215:   {
 216:     return Double.longBitsToDouble(readLong());
 217:   }
 218: 
 219:   /**
 220:    * This method reads a Java float value from an input stream.  It
 221:    * operates by first reading an <code>int</code> value from the
 222:    * stream by calling the <code>readInt()</code> method in this
 223:    * interface, then converts that <code>int</code> to a
 224:    * <code>float</code> using the <code>intBitsToFloat</code> method
 225:    * in the class <code>java.lang.Float</code>
 226:    * <p>
 227:    * This method can read a <code>float</code> written by an object
 228:    * implementing the <code>writeFloat()</code> method in the
 229:    * <code>DataOutput</code> interface.
 230:    *
 231:    * @return The <code>float</code> value read
 232:    *
 233:    * @exception EOFException If end of file is reached before reading the float
 234:    * @exception IOException If any other error occurs
 235:    *
 236:    * @see DataOutput#writeFloat
 237:    * @see java.lang.Float#intBitsToFloat
 238:    */
 239:   public float readFloat()
 240:                   throws IOException
 241:   {
 242:     return Float.intBitsToFloat(readInt());
 243:   }
 244: 
 245:   /**
 246:    * This method reads raw bytes into the passed array until the array is
 247:    * full.  Note that this method blocks until the data is available and
 248:    * throws an exception if there is not enough data left in the stream to
 249:    * fill the buffer.  Note also that zero length buffers are permitted.
 250:    * In this case, the method will return immediately without reading any
 251:    * bytes from the stream.
 252:    *
 253:    * @param b The buffer into which to read the data
 254:    *
 255:    * @exception EOFException If end of file is reached before filling the
 256:    * buffer
 257:    * @exception IOException If any other error occurs
 258:    */
 259:   public void readFully(byte[] b)
 260:                  throws IOException
 261:   {
 262:     readFully(b, 0, b.length);
 263:   }
 264: 
 265:   /**
 266:    * This method reads raw bytes into the passed array <code>buf</code>
 267:    * starting
 268:    * <code>offset</code> bytes into the buffer.  The number of bytes read
 269:    * will be
 270:    * exactly <code>len</code>.  Note that this method blocks until the data is
 271:    * available and throws an exception if there is not enough data left in
 272:    * the stream to read <code>len</code> bytes.  Note also that zero length
 273:    * buffers are permitted.  In this case, the method will return immediately
 274:    * without reading any bytes from the stream.
 275:    *
 276:    * @param buf The buffer into which to read the data
 277:    * @param offset The offset into the buffer to start storing data
 278:    * @param len The number of bytes to read into the buffer
 279:    *
 280:    * @exception EOFException If end of file is reached before filling the
 281:    * buffer
 282:    * @exception IOException If any other error occurs
 283:    */
 284:   public void readFully(byte[] buf, int offset, int len)
 285:                  throws IOException
 286:   {
 287:     if (len < 0)
 288:       throw new IndexOutOfBoundsException("Negative length: " + len);
 289: 
 290:     while (len > 0)
 291:       {
 292:         // in.read will block until some data is available.
 293:         int numread = in.read(buf, offset, len);
 294:         if (numread < 0)
 295:           throw new EOFException();
 296:         len -= numread;
 297:         offset += numread;
 298:       }
 299:   }
 300: 
 301:   /**
 302:    * This method reads a Java <code>int</code> value from an input stream
 303:    * It operates by reading four bytes from the stream and converting them to
 304:    * a single Java <code>int</code>.  The bytes are stored most
 305:    * significant byte first (i.e., "big endian") regardless of the native
 306:    * host byte ordering.
 307:    * <p>
 308:    * As an example, if <code>byte1</code> through <code>byte4</code> represent
 309:    * the first four bytes read from the stream, they will be
 310:    * transformed to an <code>int</code> in the following manner:
 311:    * <p>
 312:    * <code>(int)(((byte1 &amp; 0xFF) &lt;&lt; 24) + ((byte2 &amp; 0xFF) &lt;&lt; 16) +
 313:    * ((byte3 &amp; 0xFF)&lt;&lt; 8) + (byte4 &amp; 0xFF)))</code>
 314:    * <p>
 315:    * The value returned is in the range of -2147483648 to 2147483647.
 316:    * <p>
 317:    * This method can read an <code>int</code> written by an object
 318:    * implementing the <code>writeInt()</code> method in the
 319:    * <code>DataOutput</code> interface.
 320:    *
 321:    * @return The <code>int</code> value read
 322:    *
 323:    * @exception EOFException If end of file is reached before reading the int
 324:    * @exception IOException If any other error occurs
 325:    *
 326:    * @see DataOutput#writeInt
 327:    */
 328:   public int readInt()
 329:               throws IOException
 330:   {
 331:     readFully(buf, 0, 4);
 332:     return convertToInt(buf);
 333:   }
 334: 
 335:   /**
 336:    * This method reads the next line of text data from an input
 337:    * stream.  It operates by reading bytes and converting those bytes
 338:    * to <code>char</code> values by treating the byte read as the low
 339:    * eight bits of the <code>char</code> and using 0 as the high eight
 340:    * bits.  Because of this, it does not support the full 16-bit
 341:    * Unicode character set.
 342:    * <p>
 343:    * The reading of bytes ends when either the end of file or a line
 344:    * terminator is encountered.  The bytes read are then returned as a
 345:    * <code>String</code> A line terminator is a byte sequence
 346:    * consisting of either <code>\r</code>, <code>\n</code> or
 347:    * <code>\r\n</code>.  These termination charaters are discarded and
 348:    * are not returned as part of the string.
 349:    * <p>
 350:    * This method can read data that was written by an object implementing the
 351:    * <code>writeLine()</code> method in <code>DataOutput</code>.
 352:    *
 353:    * @return The line read as a <code>String</code>
 354:    *
 355:    * @exception IOException If an error occurs
 356:    *
 357:    * @see DataOutput
 358:    *
 359:    * @deprecated
 360:    */
 361:   public String readLine()
 362:                   throws IOException
 363:   {
 364:     StringBuffer strb = new StringBuffer();
 365: 
 366:     while (true)
 367:       {
 368:         int c = in.read();
 369:         if (c == -1) // got an EOF
 370:           return strb.length() > 0 ? strb.toString() : null;
 371:         if (c == '\r')
 372:           {
 373:             int next_c = in.read();
 374:             if (next_c != '\n' && next_c != -1)
 375:               {
 376:                 if (!(in instanceof PushbackInputStream))
 377:                   in = new PushbackInputStream(in);
 378:                 ((PushbackInputStream) in).unread(next_c);
 379:               }
 380:             break;
 381:           }
 382:         if (c == '\n')
 383:           break;
 384:         strb.append((char) c);
 385:       }
 386: 
 387:     return strb.length() > 0 ? strb.toString() : "";
 388:   }
 389: 
 390:   /**
 391:    * This method reads a Java <code>long</code> value from an input stream
 392:    * It operates by reading eight bytes from the stream and converting them to
 393:    * a single Java <code>long</code>.  The bytes are stored most
 394:    * significant byte first (i.e., "big endian") regardless of the native
 395:    * host byte ordering.
 396:    * <p>
 397:    * As an example, if <code>byte1</code> through <code>byte8</code> represent
 398:    * the first eight bytes read from the stream, they will be
 399:    * transformed to an <code>long</code> in the following manner:
 400:    * <p>
 401:    * <code>(long)(((byte1 &amp; 0xFF) &lt;&lt; 56) + ((byte2 &amp; 0xFF) &lt;&lt; 48) +
 402:    * ((byte3 &amp; 0xFF) &lt;&lt; 40) + ((byte4 &amp; 0xFF) &lt;&lt; 32) +
 403:    * ((byte5 &amp; 0xFF) &lt;&lt; 24) + ((byte6 &amp; 0xFF) &lt;&lt; 16) +
 404:    * ((byte7 &amp; 0xFF) &lt;&lt; 8) + (byte8 &amp; 0xFF)))
 405:    * </code>
 406:    * <p>
 407:    * The value returned is in the range of -9223372036854775808 to
 408:    * 9223372036854775807.
 409:    * <p>
 410:    * This method can read an <code>long</code> written by an object
 411:    * implementing the <code>writeLong()</code> method in the
 412:    * <code>DataOutput</code> interface.
 413:    *
 414:    * @return The <code>long</code> value read
 415:    *
 416:    * @exception EOFException If end of file is reached before reading the long
 417:    * @exception IOException If any other error occurs
 418:    *
 419:    * @see DataOutput#writeLong
 420:    */
 421:   public long readLong()
 422:                 throws IOException
 423:   {
 424:     readFully(buf, 0, 8);
 425:     return convertToLong(buf);
 426:   }
 427: 
 428:   /**
 429:    * This method reads a signed 16-bit value into a Java in from the
 430:    * stream.  It operates by reading two bytes from the stream and
 431:    * converting them to a single 16-bit Java <code>short</code>.  The
 432:    * two bytes are stored most significant byte first (i.e., "big
 433:    * endian") regardless of the native host byte ordering.
 434:    * <p>
 435:    * As an example, if <code>byte1</code> and <code>byte2</code>
 436:    * represent the first and second byte read from the stream
 437:    * respectively, they will be transformed to a <code>short</code>. in
 438:    * the following manner:
 439:    * <p>
 440:    * <code>(short)(((byte1 &amp; 0xFF) &lt;&lt; 8) | (byte2 &amp; 0xFF))</code>
 441:    * <p>
 442:    * The value returned is in the range of -32768 to 32767.
 443:    * <p>
 444:    * This method can read a <code>short</code> written by an object
 445:    * implementing the <code>writeShort()</code> method in the
 446:    * <code>DataOutput</code> interface.
 447:    *
 448:    * @return The <code>short</code> value read
 449:    *
 450:    * @exception EOFException If end of file is reached before reading the value
 451:    * @exception IOException If any other error occurs
 452:    *
 453:    * @see DataOutput#writeShort
 454:    */
 455:   public short readShort()
 456:                   throws IOException
 457:   {
 458:     readFully(buf, 0, 2);
 459:     return convertToShort(buf);
 460:   }
 461: 
 462:   /**
 463:    * This method reads 8 unsigned bits into a Java <code>int</code>
 464:    * value from the stream. The value returned is in the range of 0 to
 465:    * 255.
 466:    * <p>
 467:    * This method can read an unsigned byte written by an object
 468:    * implementing the <code>writeUnsignedByte()</code> method in the
 469:    * <code>DataOutput</code> interface.
 470:    *
 471:    * @return The unsigned bytes value read as a Java <code>int</code>.
 472:    *
 473:    * @exception EOFException If end of file is reached before reading the value
 474:    * @exception IOException If any other error occurs
 475:    *
 476:    * @see DataOutput#writeByte
 477:    */
 478:   public int readUnsignedByte()
 479:                        throws IOException
 480:   {
 481:     return convertToUnsignedByte(in.read());
 482:   }
 483: 
 484:   /**
 485:    * This method reads 16 unsigned bits into a Java int value from the stream.
 486:    * It operates by reading two bytes from the stream and converting them to
 487:    * a single Java <code>int</code>  The two bytes are stored most
 488:    * significant byte first (i.e., "big endian") regardless of the native
 489:    * host byte ordering.
 490:    * <p>
 491:    * As an example, if <code>byte1</code> and <code>byte2</code>
 492:    * represent the first and second byte read from the stream
 493:    * respectively, they will be transformed to an <code>int</code> in
 494:    * the following manner:
 495:    * <p>
 496:    * <code>(int)(((byte1 &amp; 0xFF) &lt;&lt; 8) + (byte2 &amp; 0xFF))</code>
 497:    * <p>
 498:    * The value returned is in the range of 0 to 65535.
 499:    * <p>
 500:    * This method can read an unsigned short written by an object
 501:    * implementing the <code>writeUnsignedShort()</code> method in the
 502:    * <code>DataOutput</code> interface.
 503:    *
 504:    * @return The unsigned short value read as a Java <code>int</code>
 505:    *
 506:    * @exception EOFException If end of file is reached before reading the value
 507:    * @exception IOException If any other error occurs
 508:    *
 509:    * @see DataOutput#writeShort
 510:    */
 511:   public int readUnsignedShort()
 512:                         throws IOException
 513:   {
 514:     readFully(buf, 0, 2);
 515:     return convertToUnsignedShort(buf);
 516:   }
 517: 
 518:   /**
 519:    * This method attempts to skip and discard the specified number of bytes
 520:    * in the input stream.  It may actually skip fewer bytes than requested.
 521:    * This method will not skip any bytes if passed a negative number of bytes
 522:    * to skip.
 523:    *
 524:    * @param n The requested number of bytes to skip.
 525:    *
 526:    * @return The requested number of bytes to skip.
 527:    *
 528:    * @exception IOException If an error occurs.
 529:    * @specnote The JDK docs claim that this returns the number of bytes
 530:    *  actually skipped. The JCL claims that this method can throw an
 531:    *  EOFException. Neither of these appear to be true in the JDK 1.3's
 532:    *  implementation. This tries to implement the actual JDK behaviour.
 533:    */
 534:   public int skipBytes(int n)
 535:                 throws IOException
 536:   {
 537:     if (n <= 0)
 538:       return 0;
 539:     try
 540:       {
 541:         return (int) in.skip(n);
 542:       }
 543:     catch (EOFException x)
 544:       {
 545:         // do nothing.
 546:       }
 547:     return n;
 548:   }
 549: 
 550:   protected boolean convertToBoolean(int b)
 551:                               throws EOFException
 552:   {
 553:     if (b < 0)
 554:       throw new EOFException();
 555: 
 556:     return (b != 0);
 557:   }
 558: 
 559:   protected byte convertToByte(int i)
 560:                         throws EOFException
 561:   {
 562:     if (i < 0)
 563:       throw new EOFException();
 564: 
 565:     return (byte) i;
 566:   }
 567: 
 568:   protected int convertToUnsignedByte(int i)
 569:                                throws EOFException
 570:   {
 571:     if (i < 0)
 572:       throw new EOFException();
 573: 
 574:     return (i & 0xFF);
 575:   }
 576: 
 577:   /**
 578:    * Less significant byte first.
 579:    */
 580:   protected char convertToChar(byte[] buf)
 581:   {
 582:     return (char) ((buf [ 1 ] << 8) | (buf [ 0 ] & 0xff));
 583:   }
 584: 
 585:   /**
 586:    * Less significant byte first.
 587:    */
 588:   protected short convertToShort(byte[] buf)
 589:   {
 590:     return (short) ((buf [ 1 ] << 8) | (buf [ 0 ] & 0xff));
 591:   }
 592: 
 593:   /**
 594:    * Less significant byte first.
 595:    */
 596:   protected int convertToUnsignedShort(byte[] buf)
 597:   {
 598:     return (((buf [ 1 ] & 0xff) << 8) | (buf [ 0 ] & 0xff));
 599:   }
 600: 
 601:   /**
 602:    * Less significant byte first.
 603:    */
 604:   protected int convertToInt(byte[] buf)
 605:   {
 606:     return (((buf [ 3 ] & 0xff) << 24) | ((buf [ 2 ] & 0xff) << 16) |
 607:            ((buf [ 1 ] & 0xff) << 8) | (buf [ 0 ] & 0xff));
 608:   }
 609: 
 610:   /**
 611:    * Less significant byte first.
 612:    */
 613:   protected long convertToLong(byte[] buf)
 614:   {
 615:     return (((long) (buf [ 7 ] & 0xff) << 56) |
 616:            ((long) (buf [ 6 ] & 0xff) << 48) |
 617:            ((long) (buf [ 5 ] & 0xff) << 40) |
 618:            ((long) (buf [ 4 ] & 0xff) << 32) |
 619:            ((long) (buf [ 3 ] & 0xff) << 24) |
 620:            ((long) (buf [ 2 ] & 0xff) << 16) |
 621:            ((long) (buf [ 1 ] & 0xff) << 8) | ((long) (buf [ 0 ] & 0xff)));
 622:   }
 623: 
 624:   /**
 625:    * This should never be called.
 626:    *
 627:    * @throws InternalError, always.
 628:    */
 629:   public String readUTF()
 630:   {
 631:     throw new InternalError();
 632:   }