View Javadoc

1   package org.paneris.util;
2   
3   import java.io.BufferedReader;
4   import java.io.File;
5   import java.io.FileNotFoundException;
6   import java.io.FileReader;
7   import java.io.FilterReader;
8   import java.io.IOException;
9   
10  public class CRLFFtellReader extends FilterReader {
11  
12    private long ftell = 0L;
13    private long markedFtell = 0L;
14  
15    /**
16     * Create a new <TT>CRLFFtellReader</TT>.
17     */
18  
19    public CRLFFtellReader(BufferedReader in) {
20      super(in);
21    }
22  
23    /**
24     * Create a new <TT>CRLFFtellReader</TT>.
25     */
26  
27    public CRLFFtellReader(File f) throws FileNotFoundException {
28      this(new BufferedReader(new FileReader(f)));
29    }
30  
31    /**
32     * Get the current position.
33     */
34  
35    public long getFtell() {
36      return ftell;
37    }
38  
39    /**
40     * Read a single character.
41     *
42     * @return     The character read, or -1 if the end of the stream has been
43     *             reached
44     *
45     * @exception  IOException  If an I/O error occurs
46     */
47  
48    public int read() throws IOException {
49      synchronized (lock) {
50        int c = super.read();
51        if (c != -1) ++ftell;
52        return c;
53      }
54    }
55  
56    /**
57     * Read characters into a portion of an array.
58     *
59     * @param      cbuf  Destination buffer
60     * @param      off   Offset at which to start storing characters
61     * @param      len   Maximum number of characters to read
62     *
63     * @return     The number of bytes read, or -1 if the end of the stream has
64     *             already been reached
65     *
66     * @exception  IOException  If an I/O error occurs
67     */
68  
69    public int read(char cbuf[], int off, int len) throws IOException {
70      synchronized (lock) {
71        if (len <= 0) return 0;
72  
73        int n = super.read(cbuf, off, len);
74        if (n > 0) ftell += n;
75        return n;
76      }
77    }
78  
79    /**
80     * Skip characters.
81     *
82     * @param  n  The number of characters to skip
83     *
84     * @return    The number of characters actually skipped
85     *
86     * @exception  IOException  If an I/O error occurs
87     */
88  
89    public long skip(long n) throws IOException {
90      synchronized (lock) {
91        long skipped = super.skip(n);
92        ftell += skipped;
93        return skipped;
94      }
95    }
96  
97    /**
98     * Mark the present position in the stream.  Subsequent calls to reset()
99     * will attempt to reposition the stream to this point, and will also reset
100    * the line number appropriately.
101    *
102    * @param  readAheadLimit  Limit on the number of characters that may be
103    *                         read while still preserving the mark.  After
104    *                         reading this many characters, attempting to
105    *                         reset the stream may fail.
106    *
107    * @exception  IOException  If an I/O error occurs
108    */
109 
110   public void mark(int readAheadLimit) throws IOException {
111     synchronized (lock) {
112       super.mark(readAheadLimit);
113       markedFtell = ftell;
114     }
115   }
116 
117   /**
118    * Reset the stream to the most recent mark.
119    *
120    * @exception  IOException  If the stream has not been marked,
121    *                          or if the mark has been invalidated
122    */
123 
124   public void reset() throws IOException {
125     synchronized (lock) {
126       super.reset();
127       ftell = markedFtell;
128     }
129   }
130 
131   /**
132    * Read a line from the stream.  FIXME if the line is not terminated with CR+LF,
133    * the <TT>getFtell()</TT> value will henceforth be off by one.  Really, an
134    * efficient and 100% correct <TT>CRLFFtellReader</TT> would have to be based on
135    * <TT>BufferedReader</TT>.
136    *
137    * @exception  IOException  If an I/O error occurs
138    */
139 
140   public String readLine() throws IOException {
141     synchronized (lock) {
142       String l = ((BufferedReader)in).readLine();
143       if (l != null) ftell += l.length() + 2;
144       return l;
145     }
146   }
147 }