1 /* DataInputStream.java -- FilteredInputStream that implements DataInput 2 Copyright (C) 1998, 1999, 2000, 2001, 2003 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., 59 Temple Place, Suite 330, Boston, MA 19 02111-1307 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 package java.io; 39 40 /* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3 41 * "The Java Language Specification", ISBN 0-201-63451-1 42 * plus online API docs for JDK 1.2 beta from http://www.javasoft.com. 43 * Status: Believed complete and correct. 44 */ 45 46 /** 47 * This subclass of <code>FilteredInputStream</code> implements the 48 * <code>DataInput</code> interface that provides method for reading primitive 49 * Java data types from a stream. 50 * 51 * @see DataInput 52 * 53 * @author Warren Levy <warrenl@cygnus.com> 54 * @author Aaron M. Renn <arenn@urbanophile.com> 55 * @date October 20, 1998. 56 */ 57 public class DataInputStream extends FilterInputStream implements DataInput 58 { 59 // readLine() hack to ensure that an '\r' not followed by an '\n' is 60 // handled correctly. If set, readLine() will ignore the first char it sees 61 // if that char is a '\n' 62 boolean ignoreInitialNewline = false; 63 64 // Byte buffer, used to make primitive read calls more efficient. 65 byte[] buf = new byte [8]; 66 67 /** 68 * This constructor initializes a new <code>DataInputStream</code> 69 * to read from the specified subordinate stream. 70 * 71 * @param in The subordinate <code>InputStream</code> to read from 72 */ DataInputStream(InputStream in)73 public DataInputStream (InputStream in) 74 { 75 super (in); 76 } 77 78 /** 79 * This method reads bytes from the underlying stream into the specified 80 * byte array buffer. It will attempt to fill the buffer completely, but 81 * may return a short count if there is insufficient data remaining to be 82 * read to fill the buffer. 83 * 84 * @param b The buffer into which bytes will be read. 85 * 86 * @return The actual number of bytes read, or -1 if end of stream reached 87 * before reading any bytes. 88 * 89 * @exception IOException If an error occurs. 90 */ read(byte[] b)91 public final int read (byte[] b) throws IOException 92 { 93 return in.read (b, 0, b.length); 94 } 95 96 /** 97 * This method reads bytes from the underlying stream into the specified 98 * byte array buffer. It will attempt to read <code>len</code> bytes and 99 * will start storing them at position <code>off</code> into the buffer. 100 * This method can return a short count if there is insufficient data 101 * remaining to be read to complete the desired read length. 102 * 103 * @param b The buffer into which bytes will be read. 104 * @param off The offset into the buffer to start storing bytes. 105 * @param len The requested number of bytes to read. 106 * 107 * @return The actual number of bytes read, or -1 if end of stream reached 108 * before reading any bytes. 109 * 110 * @exception IOException If an error occurs. 111 */ read(byte[] b, int off, int len)112 public final int read (byte[] b, int off, int len) throws IOException 113 { 114 return in.read (b, off, len); 115 } 116 117 /** 118 * This method reads a Java boolean value from an input stream. It does 119 * so by reading a single byte of data. If that byte is zero, then the 120 * value returned is <code>false</code>. If the byte is non-zero, then 121 * the value returned is <code>true</code>. 122 * <p> 123 * This method can read a <code>boolean</code> written by an object 124 * implementing the <code>writeBoolean()</code> method in the 125 * <code>DataOutput</code> interface. 126 * 127 * @return The <code>boolean</code> value read 128 * 129 * @exception EOFException If end of file is reached before reading 130 * the boolean 131 * @exception IOException If any other error occurs 132 * 133 * @see DataOutput#writeBoolean 134 */ readBoolean()135 public final boolean readBoolean () 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 */ readByte()155 public final byte readByte () 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 */ readChar()185 public final char readChar () throws IOException 186 { 187 readFully (buf, 0, 2); 188 return convertToChar (buf); 189 } 190 191 /** 192 * This method reads a Java double value from an input stream. It operates 193 * by first reading a <code>long</code> value from the stream by calling the 194 * <code>readLong()</code> method in this interface, then converts 195 * that <code>long</code> to a <code>double</code> using the 196 * <code>longBitsToDouble</code> method in the class 197 * <code>java.lang.Double</code> 198 * <p> 199 * This method can read a <code>double</code> written by an object 200 * implementing the <code>writeDouble()</code> method in the 201 * <code>DataOutput</code> interface. 202 * 203 * @return The <code>double</code> value read 204 * 205 * @exception EOFException If end of file is reached before reading 206 * the double 207 * @exception IOException If any other error occurs 208 * 209 * @see DataOutput#writeDouble 210 * @see java.lang.Double#longBitsToDouble 211 */ readDouble()212 public final double readDouble () throws IOException 213 { 214 return Double.longBitsToDouble (readLong ()); 215 } 216 217 /** 218 * This method reads a Java float value from an input stream. It 219 * operates by first reading an <code>int</code> value from the 220 * stream by calling the <code>readInt()</code> method in this 221 * interface, then converts that <code>int</code> to a 222 * <code>float</code> using the <code>intBitsToFloat</code> method 223 * in the class <code>java.lang.Float</code> 224 * <p> 225 * This method can read a <code>float</code> written by an object 226 * implementing the <code>writeFloat()</code> method in the 227 * <code>DataOutput</code> interface. 228 * 229 * @return The <code>float</code> value read 230 * 231 * @exception EOFException If end of file is reached before reading the float 232 * @exception IOException If any other error occurs 233 * 234 * @see DataOutput#writeFloat 235 * @see java.lang.Float#intBitsToFloat 236 */ readFloat()237 public final float readFloat () throws IOException 238 { 239 return Float.intBitsToFloat (readInt ()); 240 } 241 242 /** 243 * This method reads raw bytes into the passed array until the array is 244 * full. Note that this method blocks until the data is available and 245 * throws an exception if there is not enough data left in the stream to 246 * fill the buffer. Note also that zero length buffers are permitted. 247 * In this case, the method will return immediately without reading any 248 * bytes from the stream. 249 * 250 * @param b The buffer into which to read the data 251 * 252 * @exception EOFException If end of file is reached before filling the 253 * buffer 254 * @exception IOException If any other error occurs 255 */ readFully(byte[] b)256 public final void readFully (byte[] b) throws IOException 257 { 258 readFully (b, 0, b.length); 259 } 260 261 /** 262 * This method reads raw bytes into the passed array <code>buf</code> 263 * starting 264 * <code>offset</code> bytes into the buffer. The number of bytes read 265 * will be 266 * exactly <code>len</code>. Note that this method blocks until the data is 267 * available and throws an exception if there is not enough data left in 268 * the stream to read <code>len</code> bytes. Note also that zero length 269 * buffers are permitted. In this case, the method will return immediately 270 * without reading any bytes from the stream. 271 * 272 * @param buf The buffer into which to read the data 273 * @param offset The offset into the buffer to start storing data 274 * @param len The number of bytes to read into the buffer 275 * 276 * @exception EOFException If end of file is reached before filling the 277 * buffer 278 * @exception IOException If any other error occurs 279 */ readFully(byte[] b, int off, int len)280 public final void readFully (byte[] b, int off, int len) throws IOException 281 { 282 while (len > 0) 283 { 284 // in.read will block until some data is available. 285 int numread = in.read (b, off, len); 286 if (numread < 0) 287 throw new EOFException (); 288 len -= numread; 289 off += numread; 290 } 291 } 292 293 /** 294 * This method reads a Java <code>int</code> value from an input stream 295 * It operates by reading four bytes from the stream and converting them to 296 * a single Java <code>int</code>. The bytes are stored most 297 * significant byte first (i.e., "big endian") regardless of the native 298 * host byte ordering. 299 * <p> 300 * As an example, if <code>byte1</code> through <code>byte4</code> represent 301 * the first four bytes read from the stream, they will be 302 * transformed to an <code>int</code> in the following manner: 303 * <p> 304 * <code>(int)(((byte1 & 0xFF) << 24) + ((byte2 & 0xFF) << 16) + 305 * ((byte3 & 0xFF)<< 8) + (byte4 & 0xFF)))</code> 306 * <p> 307 * The value returned is in the range of -2147483648 to 2147483647. 308 * <p> 309 * This method can read an <code>int</code> written by an object 310 * implementing the <code>writeInt()</code> method in the 311 * <code>DataOutput</code> interface. 312 * 313 * @return The <code>int</code> value read 314 * 315 * @exception EOFException If end of file is reached before reading the int 316 * @exception IOException If any other error occurs 317 * 318 * @see DataOutput#writeInt 319 */ readInt()320 public final int readInt () throws IOException 321 { 322 readFully (buf, 0, 4); 323 return convertToInt (buf); 324 } 325 326 /** 327 * This method reads the next line of text data from an input 328 * stream. It operates by reading bytes and converting those bytes 329 * to <code>char</code> values by treating the byte read as the low 330 * eight bits of the <code>char</code> and using 0 as the high eight 331 * bits. Because of this, it does not support the full 16-bit 332 * Unicode character set. 333 * <p> 334 * The reading of bytes ends when either the end of file or a line 335 * terminator is encountered. The bytes read are then returned as a 336 * <code>String</code> A line terminator is a byte sequence 337 * consisting of either <code>\r</code>, <code>\n</code> or 338 * <code>\r\n</code>. These termination charaters are discarded and 339 * are not returned as part of the string. 340 * <p> 341 * This method can read data that was written by an object implementing the 342 * <code>writeLine()</code> method in <code>DataOutput</code>. 343 * 344 * @return The line read as a <code>String</code> 345 * 346 * @exception IOException If an error occurs 347 * 348 * @see DataOutput 349 * 350 * @deprecated 351 */ readLine()352 public final String readLine () throws IOException 353 { 354 StringBuffer strb = new StringBuffer (); 355 356 readloop: while (true) 357 { 358 int c = 0; 359 char ch = ' '; 360 boolean getnext = true; 361 while (getnext) 362 { 363 getnext = false; 364 c = in.read(); 365 if (c < 0) // got an EOF 366 return strb.length () > 0 ? strb.toString () : null; 367 ch = (char) c; 368 if ((ch &= 0xFF) == '\n') 369 // hack to correctly handle '\r\n' sequences 370 if (ignoreInitialNewline) 371 { 372 ignoreInitialNewline = false; 373 getnext = true; 374 } 375 else 376 break readloop; 377 } 378 379 if (ch == '\r') 380 { 381 // FIXME: The following code tries to adjust the stream back one 382 // character if the next char read is '\n'. As a last resort, 383 // it tries to mark the position before reading but the bottom 384 // line is that it is possible that this method will not properly 385 // deal with a '\r' '\n' combination thus not fulfilling the 386 // DataInput contract for readLine. It's not a particularly 387 // safe approach threadwise since it is unsynchronized and 388 // since it might mark an input stream behind the users back. 389 // Along the same vein it could try the same thing for 390 // ByteArrayInputStream and PushbackInputStream, but that is 391 // probably overkill since this is deprecated & BufferedInputStream 392 // is the most likely type of input stream. 393 // 394 // The alternative is to somehow push back the next byte if it 395 // isn't a '\n' or to have the reading methods of this class 396 // keep track of whether the last byte read was '\r' by readLine 397 // and then skip the very next byte if it is '\n'. Either way, 398 // this would increase the complexity of the non-deprecated methods 399 // and since it is undesirable to make non-deprecated methods 400 // less efficient, the following seems like the most reasonable 401 // approach. 402 int next_c = 0; 403 char next_ch = ' '; 404 if (in instanceof BufferedInputStream) 405 { 406 next_c = in.read(); 407 next_ch = (char) (next_c & 0xFF); 408 if ((next_ch != '\n') && (next_c >= 0)) 409 { 410 BufferedInputStream bin = (BufferedInputStream) in; 411 if (bin.pos > 0) 412 bin.pos--; 413 } 414 } 415 else if (markSupported()) 416 { 417 next_c = in.read(); 418 next_ch = (char) (next_c & 0xFF); 419 if ((next_ch != '\n') && (next_c >= 0)) 420 { 421 mark(1); 422 if ((in.read() & 0xFF) != '\n') 423 reset(); 424 } 425 } 426 // In order to catch cases where 'in' isn't a BufferedInputStream 427 // and doesn't support mark() (such as reading from a Socket), set 428 // a flag that instructs readLine() to ignore the first character 429 // it sees _if_ that character is a '\n'. 430 else ignoreInitialNewline = true; 431 break; 432 } 433 strb.append(ch); 434 } 435 436 return strb.length() > 0 ? strb.toString() : ""; 437 } 438 439 /** 440 * This method reads a Java <code>long</code> value from an input stream 441 * It operates by reading eight bytes from the stream and converting them to 442 * a single Java <code>long</code>. The bytes are stored most 443 * significant byte first (i.e., "big endian") regardless of the native 444 * host byte ordering. 445 * <p> 446 * As an example, if <code>byte1</code> through <code>byte8</code> represent 447 * the first eight bytes read from the stream, they will be 448 * transformed to an <code>long</code> in the following manner: 449 * <p> 450 * <code>(long)(((byte1 & 0xFF) << 56) + ((byte2 & 0xFF) << 48) + 451 * ((byte3 & 0xFF) << 40) + ((byte4 & 0xFF) << 32) + 452 * ((byte5 & 0xFF) << 24) + ((byte6 & 0xFF) << 16) + 453 * ((byte7 & 0xFF) << 8) + (byte8 & 0xFF))) 454 * </code> 455 * <p> 456 * The value returned is in the range of -9223372036854775808 to 457 * 9223372036854775807. 458 * <p> 459 * This method can read an <code>long</code> written by an object 460 * implementing the <code>writeLong()</code> method in the 461 * <code>DataOutput</code> interface. 462 * 463 * @return The <code>long</code> value read 464 * 465 * @exception EOFException If end of file is reached before reading the long 466 * @exception IOException If any other error occurs 467 * 468 * @see DataOutput#writeLong 469 */ readLong()470 public final long readLong () throws IOException 471 { 472 readFully (buf, 0, 8); 473 return convertToLong (buf); 474 } 475 476 /** 477 * This method reads a signed 16-bit value into a Java in from the 478 * stream. It operates by reading two bytes from the stream and 479 * converting them to a single 16-bit Java <code>short</code>. The 480 * two bytes are stored most significant byte first (i.e., "big 481 * endian") regardless of the native host byte ordering. 482 * <p> 483 * As an example, if <code>byte1</code> and <code>byte2</code> 484 * represent the first and second byte read from the stream 485 * respectively, they will be transformed to a <code>short</code>. in 486 * the following manner: 487 * <p> 488 * <code>(short)(((byte1 & 0xFF) << 8) | (byte2 & 0xFF))</code> 489 * <p> 490 * The value returned is in the range of -32768 to 32767. 491 * <p> 492 * This method can read a <code>short</code> written by an object 493 * implementing the <code>writeShort()</code> method in the 494 * <code>DataOutput</code> interface. 495 * 496 * @return The <code>short</code> value read 497 * 498 * @exception EOFException If end of file is reached before reading the value 499 * @exception IOException If any other error occurs 500 * 501 * @see DataOutput#writeShort 502 */ readShort()503 public final short readShort () throws IOException 504 { 505 readFully (buf, 0, 2); 506 return convertToShort (buf); 507 } 508 509 /** 510 * This method reads 8 unsigned bits into a Java <code>int</code> 511 * value from the stream. The value returned is in the range of 0 to 512 * 255. 513 * <p> 514 * This method can read an unsigned byte written by an object 515 * implementing the <code>writeUnsignedByte()</code> method in the 516 * <code>DataOutput</code> interface. 517 * 518 * @return The unsigned bytes value read as a Java <code>int</code>. 519 * 520 * @exception EOFException If end of file is reached before reading the value 521 * @exception IOException If any other error occurs 522 * 523 * @see DataOutput#writeByte 524 */ readUnsignedByte()525 public final int readUnsignedByte () throws IOException 526 { 527 return convertToUnsignedByte (in.read ()); 528 } 529 530 /** 531 * This method reads 16 unsigned bits into a Java int value from the stream. 532 * It operates by reading two bytes from the stream and converting them to 533 * a single Java <code>int</code> The two bytes are stored most 534 * significant byte first (i.e., "big endian") regardless of the native 535 * host byte ordering. 536 * <p> 537 * As an example, if <code>byte1</code> and <code>byte2</code> 538 * represent the first and second byte read from the stream 539 * respectively, they will be transformed to an <code>int</code> in 540 * the following manner: 541 * <p> 542 * <code>(int)(((byte1 & 0xFF) << 8) + (byte2 & 0xFF))</code> 543 * <p> 544 * The value returned is in the range of 0 to 65535. 545 * <p> 546 * This method can read an unsigned short written by an object 547 * implementing the <code>writeUnsignedShort()</code> method in the 548 * <code>DataOutput</code> interface. 549 * 550 * @return The unsigned short value read as a Java <code>int</code> 551 * 552 * @exception EOFException If end of file is reached before reading the value 553 * @exception IOException If any other error occurs 554 * 555 * @see DataOutput#writeShort 556 */ readUnsignedShort()557 public final int readUnsignedShort () throws IOException 558 { 559 readFully (buf, 0, 2); 560 return convertToUnsignedShort (buf); 561 } 562 563 /** 564 * This method reads a <code>String</code> from an input stream that 565 * is encoded in a modified UTF-8 format. This format has a leading 566 * two byte sequence that contains the remaining number of bytes to 567 * read. This two byte sequence is read using the 568 * <code>readUnsignedShort()</code> method of this interface. 569 * <p> 570 * After the number of remaining bytes have been determined, these 571 * bytes are read an transformed into <code>char</code> values. 572 * These <code>char</code> values are encoded in the stream using 573 * either a one, two, or three byte format. The particular format 574 * in use can be determined by examining the first byte read. 575 * <p> 576 * If the first byte has a high order bit of 0, then that character 577 * consists on only one byte. This character value consists of 578 * seven bits that are at positions 0 through 6 of the byte. As an 579 * example, if <code>byte1</code> is the byte read from the stream, 580 * it would be converted to a <code>char</code> like so: 581 * <p> 582 * <code>(char)byte1</code> 583 * <p> 584 * If the first byte has 110 as its high order bits, then the 585 * character consists of two bytes. The bits that make up the character 586 * value are in positions 0 through 4 of the first byte and bit positions 587 * 0 through 5 of the second byte. (The second byte should have 588 * 10 as its high order bits). These values are in most significant 589 * byte first (i.e., "big endian") order. 590 * <p> 591 * As an example, if <code>byte1</code> and <code>byte2</code> are 592 * the first two bytes read respectively, and the high order bits of 593 * them match the patterns which indicate a two byte character 594 * encoding, then they would be converted to a Java 595 * <code>char</code> like so: 596 * <p> 597 * <code>(char)(((byte1 & 0x1F) << 6) | (byte2 & 0x3F))</code> 598 * <p> 599 * If the first byte has a 1110 as its high order bits, then the 600 * character consists of three bytes. The bits that make up the character 601 * value are in positions 0 through 3 of the first byte and bit positions 602 * 0 through 5 of the other two bytes. (The second and third bytes should 603 * have 10 as their high order bits). These values are in most 604 * significant byte first (i.e., "big endian") order. 605 * <p> 606 * As an example, if <code>byte1</code> <code>byte2</code> and 607 * <code>byte3</code> are the three bytes read, and the high order 608 * bits of them match the patterns which indicate a three byte 609 * character encoding, then they would be converted to a Java 610 * <code>char</code> like so: 611 * <p> 612 * <code>(char)(((byte1 & 0x0F) << 12) | ((byte2 & 0x3F) << 6) | 613 * (byte3 & 0x3F))</code> 614 * <p> 615 * Note that all characters are encoded in the method that requires 616 * the fewest number of bytes with the exception of the character 617 * with the value of <code>\u0000</code> which is encoded as two 618 * bytes. This is a modification of the UTF standard used to 619 * prevent C language style <code>NUL</code> values from appearing 620 * in the byte stream. 621 * <p> 622 * This method can read data that was written by an object implementing the 623 * <code>writeUTF()</code> method in <code>DataOutput</code> 624 * 625 * @return The <code>String</code> read 626 * 627 * @exception EOFException If end of file is reached before reading 628 * the String 629 * @exception UTFDataFormatException If the data is not in UTF-8 format 630 * @exception IOException If any other error occurs 631 * 632 * @see DataOutput#writeUTF 633 */ readUTF()634 public final String readUTF () throws IOException 635 { 636 return readUTF (this); 637 } 638 639 /** 640 * This method reads a String encoded in UTF-8 format from the 641 * specified <code>DataInput</code> source. 642 * 643 * @param in The <code>DataInput</code> source to read from 644 * 645 * @return The String read from the source 646 * 647 * @exception IOException If an error occurs 648 * 649 * @see DataInput#readUTF 650 */ readUTF(DataInput in)651 public final static String readUTF (DataInput in) throws IOException 652 { 653 final int UTFlen = in.readUnsignedShort (); 654 byte[] buf = new byte [UTFlen]; 655 656 // This blocks until the entire string is available rather than 657 // doing partial processing on the bytes that are available and then 658 // blocking. An advantage of the latter is that Exceptions 659 // could be thrown earlier. The former is a bit cleaner. 660 in.readFully (buf, 0, UTFlen); 661 662 return convertFromUTF (buf); 663 } 664 665 /** 666 * This method attempts to skip and discard the specified number of bytes 667 * in the input stream. It may actually skip fewer bytes than requested. 668 * This method will not skip any bytes if passed a negative number of bytes 669 * to skip. 670 * 671 * @param n The requested number of bytes to skip. 672 * 673 * @return The requested number of bytes to skip. 674 * 675 * @exception IOException If an error occurs. 676 * @specnote The JDK docs claim that this returns the number of bytes 677 * actually skipped. The JCL claims that this method can throw an 678 * EOFException. Neither of these appear to be true in the JDK 1.3's 679 * implementation. This tries to implement the actual JDK behaviour. 680 */ skipBytes(int n)681 public final int skipBytes (int n) throws IOException 682 { 683 if (n <= 0) 684 return 0; 685 try 686 { 687 return (int) in.skip (n); 688 } 689 catch (EOFException x) 690 { 691 // do nothing. 692 } 693 return n; 694 } 695 convertToBoolean(int b)696 static boolean convertToBoolean (int b) throws EOFException 697 { 698 if (b < 0) 699 throw new EOFException (); 700 701 return (b != 0); 702 } 703 convertToByte(int i)704 static byte convertToByte (int i) throws EOFException 705 { 706 if (i < 0) 707 throw new EOFException (); 708 709 return (byte) i; 710 } 711 convertToUnsignedByte(int i)712 static int convertToUnsignedByte (int i) throws EOFException 713 { 714 if (i < 0) 715 throw new EOFException (); 716 717 return (i & 0xFF); 718 } 719 convertToChar(byte[] buf)720 static char convertToChar (byte[] buf) 721 { 722 return (char) ((buf [0] << 8) 723 | (buf [1] & 0xff)); 724 } 725 convertToShort(byte[] buf)726 static short convertToShort (byte[] buf) 727 { 728 return (short) ((buf [0] << 8) 729 | (buf [1] & 0xff)); 730 } 731 convertToUnsignedShort(byte[] buf)732 static int convertToUnsignedShort (byte[] buf) 733 { 734 return (((buf [0] & 0xff) << 8) 735 | (buf [1] & 0xff)); 736 } 737 convertToInt(byte[] buf)738 static int convertToInt (byte[] buf) 739 { 740 return (((buf [0] & 0xff) << 24) 741 | ((buf [1] & 0xff) << 16) 742 | ((buf [2] & 0xff) << 8) 743 | (buf [3] & 0xff)); 744 } 745 convertToLong(byte[] buf)746 static long convertToLong (byte[] buf) 747 { 748 return (((long)(buf [0] & 0xff) << 56) | 749 ((long)(buf [1] & 0xff) << 48) | 750 ((long)(buf [2] & 0xff) << 40) | 751 ((long)(buf [3] & 0xff) << 32) | 752 ((long)(buf [4] & 0xff) << 24) | 753 ((long)(buf [5] & 0xff) << 16) | 754 ((long)(buf [6] & 0xff) << 8) | 755 ((long)(buf [7] & 0xff))); 756 } 757 758 // FIXME: This method should be re-thought. I suspect we have multiple 759 // UTF-8 decoders floating around. We should use the standard charset 760 // converters, maybe and adding a direct call into one of the new 761 // NIO converters for a super-fast UTF8 decode. convertFromUTF(byte[] buf)762 static String convertFromUTF (byte[] buf) 763 throws EOFException, UTFDataFormatException 764 { 765 // Give StringBuffer an initial estimated size to avoid 766 // enlarge buffer frequently 767 StringBuffer strbuf = new StringBuffer (buf.length / 2 + 2); 768 769 for (int i = 0; i < buf.length; ) 770 { 771 if ((buf [i] & 0x80) == 0) // bit pattern 0xxxxxxx 772 strbuf.append ((char) (buf [i++] & 0xFF)); 773 else if ((buf [i] & 0xE0) == 0xC0) // bit pattern 110xxxxx 774 { 775 if (i + 1 >= buf.length 776 || (buf [i + 1] & 0xC0) != 0x80) 777 throw new UTFDataFormatException (); 778 779 strbuf.append((char) (((buf [i++] & 0x1F) << 6) 780 | (buf [i++] & 0x3F))); 781 } 782 else if ((buf [i] & 0xF0) == 0xE0) // bit pattern 1110xxxx 783 { 784 if (i + 2 >= buf.length 785 || (buf [i + 1] & 0xC0) != 0x80 786 || (buf [i + 2] & 0xC0) != 0x80) 787 throw new UTFDataFormatException (); 788 789 strbuf.append ((char) (((buf [i++] & 0x0F) << 12) 790 | ((buf [i++] & 0x3F) << 6) 791 | (buf [i++] & 0x3F))); 792 } 793 else // must be ((buf [i] & 0xF0) == 0xF0 || (buf [i] & 0xC0) == 0x80) 794 throw new UTFDataFormatException (); // bit patterns 1111xxxx or 795 // 10xxxxxx 796 } 797 798 return strbuf.toString (); 799 } 800 } 801