View Javadoc
1 /* ------------------------------------------------------------------- 2 * Java source file for the class JBeansReader 3 * 4 * Copyright (c), 2002, Masahiro Takatsuka. 5 * All Rights Researved. 6 * 7 * Original Author: Masahiro Takatsuka (masa@jbeans.net) 8 * $Author: takatsukam $ 9 * 10 * $Date: 2003/07/25 04:51:45 $ 11 * 12 * $Id: JBeansReader.java,v 1.1.1.1 2003/07/25 04:51:45 takatsukam Exp $ 13 * 14 * Reference: Document no: 15 * ___ ___ 16 * 17 * To Do: 18 * ___ 19 * 20 ------------------------------------------------------------------- */ 21 22 /* --------------------------- Package ---------------------------- */ 23 package net.jbeans.io; 24 25 /* ------------------ Import classes (packages) ------------------- *//package-summary/html">color="#329900"> ------------------ Import classes (packages) ------------------- *//package-summary.html">color="#329900">/* ------------------ Import classes (packages) ------------------- *//package-summary.html">color="#329900"> ------------------ Import classes (packages) ------------------- */ 26 import java.io.*; 27 28 /*==================================================================== 29 Implementation of class JBeansReader 30 ====================================================================*/ 31 /*** 32 * JBeansReader reads strings and numbers from a reader or an input stream. 33 * 34 * @version $Revision: 1.1.1.1 $ 35 * @author Masahiro Takatsuka (masa@jbeans.net) 36 * @see Reader 37 */ 38 39 public final class JBeansReader extends Reader { 40 protected static final String STREAM_CLOSED = "Stream closed"; 41 private BufferedReader br = null; 42 private String delimiters = null; 43 private boolean retTokens; 44 private boolean eof = false; // has EOF been reached 45 46 /*** 47 * Construct a newly created JBeansReader 48 * 49 * @param in An InputStream. 50 * @param delim the delimiters. 51 * @param returnTokens flag indicating whether to return the delimiters 52 * as tokens. 53 */ 54 public JBeansReader(InputStream in, String delim, boolean returnTokens) { 55 this.br = new BufferedReader(new InputStreamReader(in)); 56 this.delimiters = (delim == null) ? "" : delim; // 2000-Jan-12 0.1.1 57 this.retTokens = returnTokens; 58 } 59 60 /*** 61 * Construct a newly created JBeansReader 62 * 63 * @param in An InputStream. 64 * @param delim the delimiters. 65 */ 66 public JBeansReader(InputStream in, String delim) { 67 this(in, delim, false); 68 } 69 70 /*** 71 * Construct a newly created JBeansReader 72 * 73 * @param in An InputStream. 74 */ 75 public JBeansReader(InputStream in) { 76 this(in, " \t\n\r\f", false); 77 } 78 79 /*** 80 * Construct a newly created JBeansReader 81 * 82 * @param in A Reader. 83 * @param delim the delimiters. 84 * @param returnTokens flag indicating whether to return the delimiters 85 * as tokens. 86 */ 87 public JBeansReader(Reader in, String delim, boolean returnTokens) { 88 this.br = new BufferedReader(in); 89 this.delimiters = (delim == null) ? "" : delim; // 2000-Jan-12 0.1.1 90 this.retTokens = returnTokens; 91 } 92 93 /*** 94 * Construct a newly created JBeansReader 95 * 96 * @param in A Reader. 97 * @param delim the delimiters. 98 */ 99 public JBeansReader(Reader in, String delim) { 100 this(in, delim, false); 101 } 102 103 /*** 104 * Construct a newly created JBeansReader 105 * 106 * @param in A Reader. 107 */ 108 public JBeansReader(Reader in) { 109 this(in, " \t\n\r\f", false); 110 } 111 112 /*** 113 * Read characters into a portion of an array. 114 * 115 * @param cbuf Destination buffer 116 * @param off Offset at which to start storing characters 117 * @param len Maximum number of characters to read 118 * 119 * @return The number of characters read, or -1 if the end of the stream 120 * has been reached 121 * 122 * @exception IOException If an I/O error occurs 123 */ 124 public final int read(char cbuf[], int off, int len) throws IOException { 125 synchronized (lock) { 126 ensureOpen(); 127 return this.br.read(cbuf, off, len); 128 } 129 } 130 131 /*** 132 * Reads the specified numbers of characters and returns as a String. 133 */ 134 public final String read(int len) throws IOException { 135 StringBuffer sbuf = new StringBuffer(); 136 boolean flag = false; 137 for (int i = 0; i < len; i++) { 138 char c = (char) this.br.read(); 139 if (c == '\n') { 140 return sbuf.toString(); 141 } 142 if (c != ' ') { 143 if (!flag) { 144 flag = true; 145 } 146 sbuf.append(c); 147 } 148 } 149 if (!flag) { 150 return null; 151 } else { 152 return sbuf.toString(); 153 } 154 } 155 156 /*** 157 * Reads the specified numbers of characters from the specified Reader 158 * and returns as a String. 159 */ 160 public final static char[] readChars(Reader reader, int len) throws IOException { 161 char[] chars = new char[len]; 162 readChars(chars, reader, len); 163 return chars; 164 } 165 166 /*** 167 * Reads the specified numbers of characters from the specified Reader 168 * and returns as a String. 169 */ 170 public final static int readChars(char[] chars, Reader reader, int len) throws IOException { 171 boolean flag = false; 172 int i = 0; 173 for (i = 0; i < len; i++) { 174 char c = (char) reader.read(); 175 if (c == '\n') { 176 break; 177 } 178 chars[i] = c; 179 } 180 181 return i; 182 } 183 184 /*** 185 * Reads the specified numbers of characters from the specified Reader 186 * and returns as a String. 187 */ 188 public final static String read(Reader reader, int len) throws IOException { 189 StringBuffer sbuf = new StringBuffer(); 190 boolean flag = false; 191 for (int i = 0; i < len; i++) { 192 char c = (char) reader.read(); 193 if (c == '\n') { 194 return sbuf.toString(); 195 } 196 if (c != ' ') { 197 if (!flag) { 198 flag = true; 199 } 200 sbuf.append(c); 201 } 202 } 203 if (!flag) { 204 return null; 205 } else { 206 return sbuf.toString(); 207 } 208 } 209 210 /*** Check to make sure that the stream has not been closed */ 211 private void ensureOpen() throws IOException { 212 if (this.br == null) { 213 throw new IOException(STREAM_CLOSED); 214 } 215 } 216 217 /*** 218 * Tell whether this stream is ready to be read. An InputReader is 219 * ready if its input buffer is not empty, or if bytes are available to be 220 * read from the underlying byte stream. 221 * 222 * @exception IOException If an I/O error occurs 223 */ 224 public final boolean ready() throws IOException { 225 synchronized (lock) { 226 ensureOpen(); 227 return this.br.ready(); 228 } 229 } 230 231 /*** 232 * Close the stream. 233 * 234 * @exception IOException If an I/O error occurs 235 */ 236 public final void close() throws IOException { 237 synchronized (lock) { 238 try { 239 ensureOpen(); 240 this.br.close(); 241 this.br = null; 242 } catch (IOException ioe) { 243 if (! ioe.getMessage().equals(STREAM_CLOSED)) { 244 throw ioe; 245 } 246 } 247 } 248 } 249 250 /*** 251 * Skips delimiters. 252 */ 253 private void skipDelimiters() throws IOException { 254 int ch; 255 if (!this.retTokens) { 256 this.br.mark(1); // set a mark. 257 while ((ch = this.br.read()) != -1 && 258 this.delimiters.indexOf((char)ch) >= 0) { 259 this.br.mark(1); 260 } 261 if (ch == -1) { // has reached EOF. 262 this.eof = true; 263 } else { 264 this.br.reset(); // go back one char. 265 } 266 } 267 } 268 269 /*** 270 * Read a line of text. A line is considered to be terminated by any one 271 * of a line feed ('\n'), a carriage return ('\r'), or a carriage return 272 * followed immediately by a linefeed. 273 * 274 * @return A String containing the contents of the line, not including 275 * any line-termination characters, or null if the end of the 276 * stream has been reached 277 * 278 * @exception IOException If an I/O error occurs 279 */ 280 public final String readLine() throws IOException { 281 String line = this.br.readLine(); 282 if (line == null) 283 this.eof = true; 284 return line; 285 } 286 287 /*** 288 * Read a line of text. A line is considered to be terminated by any one 289 * of a line feed ('\n'), a carriage return ('\r'), or a carriage return 290 * followed immediately by a linefeed. 291 * 292 * @return A String containing the contents of the line, not including 293 * any line-termination characters, or null if the end of the 294 * stream has been reached 295 * 296 * @exception IOException If an I/O error occurs 297 */ 298 public final String readLine(String commentchars) throws IOException { 299 String line = null; 300 while ((line = this.br.readLine()) != null && 301 commentchars.indexOf(line.charAt(0)) >= 0) { 302 ; 303 } 304 if (line == null) 305 this.eof = true; 306 return line; 307 } 308 309 /*** 310 * Read a line of text. A line is considered to be terminated by any one 311 * of a line feed ('\n'), a carriage return ('\r'), or a carriage return 312 * followed immediately by a linefeed. 313 * 314 * @return A String containing the contents of the line, not including 315 * any line-termination characters, or null if the end of the 316 * stream has been reached 317 * 318 * @exception IOException If an I/O error occurs 319 */ 320 public final String readLine(char commentchar) throws IOException { 321 String line = null; 322 while ((line = this.br.readLine()) != null && 323 commentchar == line.charAt(0)) { 324 ; 325 } 326 if (line == null) 327 this.eof = true; 328 return line; 329 } 330 331 /*** 332 * Read one token as a string. 333 * 334 * @return A String containing the string, or null if the end of the 335 * stream has been reached. 336 * 337 * @exception IOException If an I/O error occurs 338 */ 339 public final String readToken() throws IOException { 340 skipDelimiters(); 341 if (this.eof) { // has reached EOF during skipDelimiters() 342 return null; 343 } 344 345 StringBuffer buf = new StringBuffer(); 346 int ch; 347 this.br.mark(1); // set a mark. 348 while ((ch = this.br.read()) != -1 && 349 this.delimiters.indexOf((char)ch) < 0) { 350 this.br.mark(1); 351 buf.append((char)ch); 352 } 353 if (ch == -1) // has reached EOF. 354 this.eof = true; 355 356 357 if (this.retTokens && (buf.length() == 0) && 358 (this.delimiters.indexOf((char)ch) >= 0)){ 359 buf.append((char)ch); 360 } else { 361 this.br.reset(); // go back one char. 362 } 363 364 return buf.toString(); 365 } 366 367 /*** 368 * Reads a <code>boolean</code> from this data input stream. This 369 * method reads a single byte from the underlying input stream. A 370 * value of <code>0</code> represents <code>false</code>. Any other 371 * value represents <code>true</code>. This method blocks until 372 * either the byte is read, the end of the stream is detected, or an 373 * exception is thrown. 374 * 375 * @return the <code>boolean</code> value read. 376 * @exception EOFException if this input stream has reached the end. 377 * @exception IOException if an I/O error occurs. 378 */ 379 public final boolean readBoolean() throws IOException { 380 return (Boolean.valueOf(readToken())).booleanValue(); 381 } 382 383 /*** 384 * Reads a signed 8-bit value from this data input stream. This 385 * method reads a byte from the underlying input stream. If the byte 386 * read is <code>b</code>, where 387 * 0 <= <code>b</code> <= 255, then the 388 * result is: 389 * <ul><code> 390 * (byte)(b) 391 * </code></ul> 392 * <p> 393 * This method blocks until either the byte is read, the end of the 394 * stream is detected, or an exception is thrown. 395 * 396 * @return the next byte of this input stream as a signed 8-bit 397 * <code>byte</code>. 398 * @exception EOFException if this input stream has reached the end. 399 * @exception IOException if an I/O error occurs. 400 */ 401 public final byte readByte() throws IOException { 402 return Byte.parseByte(readToken()); 403 } 404 405 /*** 406 * Reads a signed 16-bit number from this data input stream. The 407 * method reads two bytes from the underlying input stream. If the two 408 * bytes read, in order, are <code>b1</code> and <code>b2</code>, 409 * where each of the two values is between <code>0</code> and 410 * <code>255</code>, inclusive, then the result is equal to: 411 * <ul><code> 412 * (short)((b1 << 8) | b2) 413 * </code></ul> 414 * <p> 415 * This method blocks until the two bytes are read, the end of the 416 * stream is detected, or an exception is thrown. 417 * 418 * @return the next two bytes of this input stream, interpreted as a 419 * signed 16-bit number. 420 * @exception EOFException if this input stream reaches the end before 421 * reading two bytes. 422 * @exception IOException if an I/O error occurs. 423 */ 424 public final short readShort() throws IOException { 425 return Short.parseShort(readToken()); 426 } 427 428 /*** 429 * Reads a Unicode character from this data input stream. This 430 * method reads two bytes from the underlying input stream. If the 431 * bytes read, in order, are <code>b1</code> and <code>b2</code>, 432 * where 0 <= <code>b1</code>, 433 * <code>b1</code> <= 255, then the result is equal to: 434 * <ul><code> 435 * (char)((b1 << 8) | b2) 436 * </code></ul> 437 * <p> 438 * This method blocks until either the two bytes are read, the end of 439 * the stream is detected, or an exception is thrown. 440 * 441 * @return the next two bytes of this input stream as a Unicode 442 * character. 443 * @exception EOFException if this input stream reaches the end before 444 * reading two bytes. 445 * @exception IOException if an I/O error occurs. 446 */ 447 public final char readChar() throws IOException { 448 skipDelimiters(); 449 if (this.eof) { // has reached EOF during skipDelimiters() 450 return (char)-1; 451 } 452 453 int ch; 454 this.br.mark(1); // set a mark. 455 if ((ch = this.br.read()) != -1 ) { 456 if (!this.retTokens && this.delimiters.indexOf((char)ch) >= 0) { 457 this.br.reset(); 458 } else { 459 this.br.mark(1); 460 } 461 } else { 462 this.eof = true; // has reached EOF. 463 } 464 465 return (char)ch; 466 } 467 468 /*** 469 * Reads a signed 32-bit integer from this data input stream. This 470 * method reads four bytes from the underlying input stream. If the 471 * bytes read, in order, are <code>b1</code>, <code>b2</code>, 472 * <code>b3</code>, and <code>b4</code>, where 473 * 0 <= <code>b1</code>, <code>b2</code>, 474 * <code>b3</code>, <code>b4</code> <= 255, then the 475 * result is equal to: 476 * <ul><code> 477 * (b1 << 24) | (b2 << 16) + (b3 << 8) +b4 478 * </code></ul> 479 * <p> 480 * This method blocks until the four bytes are read, the end of the 481 * stream is detected, or an exception is thrown. 482 * 483 * @return the next four bytes of this input stream, interpreted as an 484 * <code>int</code>. 485 * @exception EOFException if this input stream reaches the end before 486 * reading four bytes. 487 * @exception IOException if an I/O error occurs. 488 */ 489 public final int readInt() throws IOException { 490 return Integer.parseInt(readToken()); 491 } 492 493 /*** 494 * Reads a signed 64-bit integer from this data input stream. This 495 * method reads eight bytes from the underlying input stream. If the 496 * bytes read, in order, are <code>b1</code>, <code>b2</code>, 497 * <code>b3</code>, <code>b4</code>, <code>b5</code>, 498 * <code>b6</code>, <code>b7</code>, and <code>b8</code>, where 499 * <ul><code> 500 * 0 <= b1, b2, b3, b4, b5, b6, b7, b8 <= 255, 501 * </code></ul> 502 * <p> 503 * then the result is equal to: 504 * <p><blockquote><pre> 505 * ((long)b1 << 56) + ((long)b2 << 48) + 506 * ((long)b3 << 40) + ((long)b4 << 32) + 507 * ((long)b5 << 24) + (b6 << 16) + 508 * (b7 << 8) + b8 509 * </pre></blockquote> 510 * <p> 511 * This method blocks until the eight bytes are read, the end of the 512 * stream is detected, or an exception is thrown. 513 * 514 * @return the next eight bytes of this input stream, interpreted as a 515 * <code>long</code>. 516 * @exception EOFException if this input stream reaches the end before 517 * reading eight bytes. 518 * @exception IOException if an I/O error occurs. 519 */ 520 public final long readLong() throws IOException { 521 return Long.parseLong(readToken()); 522 } 523 524 /*** 525 * Reads a <code>float</code> from this data input stream. This 526 * method reads an <code>int</code> value as if by the 527 * <code>readInt</code> method and then converts that 528 * <code>int</code> to a <code>float</code> using the 529 * <code>intBitsToFloat</code> method in class <code>Float</code>. 530 * This method blocks until the four bytes are read, the end of the 531 * stream is detected, or an exception is thrown. 532 * 533 * @return the next four bytes of this input stream, interpreted as a 534 * <code>float</code>. 535 * @exception EOFException if this input stream reaches the end before 536 * reading four bytes. 537 * @exception IOException if an I/O error occurs. 538 */ 539 public final float readFloat() throws IOException { 540 return Float.parseFloat(readToken()); 541 } 542 543 /*** 544 * Reads a <code>double</code> from this data input stream. This 545 * method reads a <code>long</code> value as if by the 546 * <code>readLong</code> method and then converts that 547 * <code>long</code> to a <code>double</code> using the 548 * <code>longBitsToDouble</code> method in class <code>Double</code>. 549 * <p> 550 * This method blocks until the eight bytes are read, the end of the 551 * stream is detected, or an exception is thrown. 552 * 553 * @return the next eight bytes of this input stream, interpreted as a 554 * <code>double</code>. 555 * @exception EOFException if this input stream reaches the end before 556 * reading eight bytes. 557 * @exception IOException if an I/O error occurs. 558 */ 559 public final double readDouble() throws IOException { 560 return Double.parseDouble(readToken()); 561 } 562 563 564 /*** 565 * Test routine. 566 * 567 * @param args the command line arguments. 568 */ 569 public final static void main(String[] args) { 570 try { 571 JBeansReader ir = new JBeansReader(new FileReader("FileIOException.java")); 572 String token = null; 573 while ((token = ir.readToken()) != null) { 574 System.out.print(token); 575 } 576 ir.close(); 577 } catch (FileNotFoundException fnfe) { 578 System.err.println(fnfe); 579 } catch (IOException fnfe) { 580 System.err.println(fnfe); 581 } 582 } 583 }

This page was automatically generated by Maven