225fd860719197e4bed2c29ee0967d11cea4e4b2
[org.ibex.io.git] / src / org / ibex / io / CharBufReader.java
1 // Copyright 2000-2007 the Contributors, as shown in the revision logs.
2 // Licensed under the Apache Public Source License 2.0 ("the License").
3 // You may not use this file except in compliance with the License.
4
5 package org.ibex.io;
6 import java.io.*;
7
8 /** package-private class */
9 class CharBufReader extends Reader {
10
11     private Reader reader;
12     private char[] buf = new char[8192];
13     private int start = 0;
14     private int end = 0;
15     
16     public CharBufReader(Reader r) { this.reader = r; }
17
18     public boolean ready() throws IOException { return bufSize()>0; }
19     private int bufSize() { if (end==start) { end=start=0; } return end-start; }
20     private int fillBufIfEmpty() {
21         try {
22             if (bufSize() > 0) return bufSize();
23             start = 0;
24             do {
25                 end = reader.read(buf, 0, buf.length);
26             } while(end==0);
27             if (end == -1) { end = 0; return -1; }
28             return end;
29         } catch (IOException e) { Stream.ioe(e); return -1; }
30     }
31
32     public int available() { return end-start; }
33     public void close() {
34         try {
35             if (reader != null) reader.close();
36         } catch (IOException e) { Stream.ioe(e); }
37     }
38
39     public int read(char[] c, int pos, int len) {
40         if (fillBufIfEmpty() == -1) return -1;
41         if (len > end - start) len = end - start;
42         System.arraycopy(buf, start, c, pos, len);
43         start += len;
44         return len;
45     }
46
47     public char getc(boolean peek) {
48         if (fillBufIfEmpty() <= 0) throw new Stream.EOF();
49         return peek ? buf[start] : buf[start++];
50     }
51
52     private StringBuffer lineReaderStringBuffer = new StringBuffer();
53     public String readln() {
54         lineReaderStringBuffer.setLength(0);
55         boolean readsome = false;
56         OUT: while(true) {
57             if (fillBufIfEmpty() <= 0) break;
58             readsome = true;
59             for(int i=start; i<end; i++)
60                 if (buf[i] == '\n') {
61                     // this should (in theory) handle CR, LF,
62                     // CRLF, and LFCR properly, assuming that the
63                     // file consistently uses the same ending
64                     // throughout.
65                     int begin = start;
66                     int len = i-start;
67                     start = i+1;
68                     if (buf[begin] == '\r') { begin++; len--; }
69                     while (len > 0 && buf[begin+len-1] == '\r') { len--; }
70                     lineReaderStringBuffer.append(buf, begin, len);
71                     break OUT;
72                 }
73             lineReaderStringBuffer.append(buf, start, end-start);
74             start = end = 0;
75         }
76         if (!readsome) return null;
77         String ret = lineReaderStringBuffer.toString();
78         lineReaderStringBuffer.setLength(0);
79         return ret;
80     }
81
82     public void unbuffer(Writer writer) {
83         if (bufSize()<=0) return;
84         try {
85             writer.write(buf, start, end-start);
86         } catch (IOException e) {
87             Stream.ioe(e);
88         }
89     }
90 }