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