1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.struts2.jasper.xmlparser;
19
20 import org.apache.struts2.jasper.compiler.Localizer;
21
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.io.Reader;
25
26 /***
27 * A simple ASCII byte reader. This is an optimized reader for reading
28 * byte streams that only contain 7-bit ASCII characters.
29 *
30 * @author Andy Clark, IBM
31 * @version $Id: ASCIIReader.java 466606 2006-10-21 23:07:12Z markt $
32 */
33 public class ASCIIReader
34 extends Reader {
35
36
37
38
39
40 /***
41 * Default byte buffer size (2048).
42 */
43 public static final int DEFAULT_BUFFER_SIZE = 2048;
44
45
46
47
48
49 /***
50 * Input stream.
51 */
52 protected InputStream fInputStream;
53
54 /***
55 * Byte buffer.
56 */
57 protected byte[] fBuffer;
58
59
60
61
62
63 /***
64 * Constructs an ASCII reader from the specified input stream
65 * and buffer size.
66 *
67 * @param inputStream The input stream.
68 * @param size The initial buffer size.
69 */
70 public ASCIIReader(InputStream inputStream, int size) {
71 fInputStream = inputStream;
72 fBuffer = new byte[size];
73 }
74
75
76
77
78
79 /***
80 * Read a single character. This method will block until a character is
81 * available, an I/O error occurs, or the end of the stream is reached.
82 * <p/>
83 * <p> Subclasses that intend to support efficient single-character input
84 * should override this method.
85 *
86 * @return The character read, as an integer in the range 0 to 127
87 * (<tt>0x00-0x7f</tt>), or -1 if the end of the stream has
88 * been reached
89 * @throws IOException If an I/O error occurs
90 */
91 public int read() throws IOException {
92 int b0 = fInputStream.read();
93 if (b0 > 0x80) {
94 throw new IOException(Localizer.getMessage("jsp.error.xml.invalidASCII",
95 Integer.toString(b0)));
96 }
97 return b0;
98 }
99
100 /***
101 * Read characters into a portion of an array. This method will block
102 * until some input is available, an I/O error occurs, or the end of the
103 * stream is reached.
104 *
105 * @param ch Destination buffer
106 * @param offset Offset at which to start storing characters
107 * @param length Maximum number of characters to read
108 * @return The number of characters read, or -1 if the end of the
109 * stream has been reached
110 * @throws IOException If an I/O error occurs
111 */
112 public int read(char ch[], int offset, int length) throws IOException {
113 if (length > fBuffer.length) {
114 length = fBuffer.length;
115 }
116 int count = fInputStream.read(fBuffer, 0, length);
117 for (int i = 0; i < count; i++) {
118 int b0 = fBuffer[i];
119 if (b0 > 0x80) {
120 throw new IOException(Localizer.getMessage("jsp.error.xml.invalidASCII",
121 Integer.toString(b0)));
122 }
123 ch[offset + i] = (char) b0;
124 }
125 return count;
126 }
127
128 /***
129 * Skip characters. This method will block until some characters are
130 * available, an I/O error occurs, or the end of the stream is reached.
131 *
132 * @param n The number of characters to skip
133 * @return The number of characters actually skipped
134 * @throws IOException If an I/O error occurs
135 */
136 public long skip(long n) throws IOException {
137 return fInputStream.skip(n);
138 }
139
140 /***
141 * Tell whether this stream is ready to be read.
142 *
143 * @return True if the next read() is guaranteed not to block for input,
144 * false otherwise. Note that returning false does not guarantee that the
145 * next read will block.
146 * @throws IOException If an I/O error occurs
147 */
148 public boolean ready() throws IOException {
149 return false;
150 }
151
152 /***
153 * Tell whether this stream supports the mark() operation.
154 */
155 public boolean markSupported() {
156 return fInputStream.markSupported();
157 }
158
159 /***
160 * Mark the present position in the stream. Subsequent calls to reset()
161 * will attempt to reposition the stream to this point. Not all
162 * character-input streams support the mark() operation.
163 *
164 * @param readAheadLimit Limit on the number of characters that may be
165 * read while still preserving the mark. After
166 * reading this many characters, attempting to
167 * reset the stream may fail.
168 * @throws IOException If the stream does not support mark(),
169 * or if some other I/O error occurs
170 */
171 public void mark(int readAheadLimit) throws IOException {
172 fInputStream.mark(readAheadLimit);
173 }
174
175 /***
176 * Reset the stream. If the stream has been marked, then attempt to
177 * reposition it at the mark. If the stream has not been marked, then
178 * attempt to reset it in some way appropriate to the particular stream,
179 * for example by repositioning it to its starting point. Not all
180 * character-input streams support the reset() operation, and some support
181 * reset() without supporting mark().
182 *
183 * @throws IOException If the stream has not been marked,
184 * or if the mark has been invalidated,
185 * or if the stream does not support reset(),
186 * or if some other I/O error occurs
187 */
188 public void reset() throws IOException {
189 fInputStream.reset();
190 }
191
192 /***
193 * Close the stream. Once a stream has been closed, further read(),
194 * ready(), mark(), or reset() invocations will throw an IOException.
195 * Closing a previously-closed stream, however, has no effect.
196 *
197 * @throws IOException If an I/O error occurs
198 */
199 public void close() throws IOException {
200 fInputStream.close();
201 }
202
203 }