Frames | No Frames |
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 & 0xFF) << 8) | (byte2 & 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 & 0xFF) << 24) + ((byte2 & 0xFF) << 16) + 313: * ((byte3 & 0xFF)<< 8) + (byte4 & 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 & 0xFF) << 56) + ((byte2 & 0xFF) << 48) + 402: * ((byte3 & 0xFF) << 40) + ((byte4 & 0xFF) << 32) + 403: * ((byte5 & 0xFF) << 24) + ((byte6 & 0xFF) << 16) + 404: * ((byte7 & 0xFF) << 8) + (byte8 & 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 & 0xFF) << 8) | (byte2 & 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 & 0xFF) << 8) + (byte2 & 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: }