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