001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package org.apache.jasper.xmlparser;
019:
020: import java.io.InputStream;
021: import java.io.IOException;
022: import java.io.Reader;
023: import org.apache.jasper.compiler.Localizer;
024:
025: /**
026: * A simple ASCII byte reader. This is an optimized reader for reading
027: * byte streams that only contain 7-bit ASCII characters.
028: *
029: * @author Andy Clark, IBM
030: *
031: * @version $Id: ASCIIReader.java 467222 2006-10-24 03:17:11Z markt $
032: */
033: public class ASCIIReader extends Reader {
034:
035: //
036: // Constants
037: //
038:
039: /** Default byte buffer size (2048). */
040: public static final int DEFAULT_BUFFER_SIZE = 2048;
041:
042: //
043: // Data
044: //
045:
046: /** Input stream. */
047: protected InputStream fInputStream;
048:
049: /** Byte buffer. */
050: protected byte[] fBuffer;
051:
052: //
053: // Constructors
054: //
055:
056: /**
057: * Constructs an ASCII reader from the specified input stream
058: * and buffer size.
059: *
060: * @param inputStream The input stream.
061: * @param size The initial buffer size.
062: */
063: public ASCIIReader(InputStream inputStream, int size) {
064: fInputStream = inputStream;
065: fBuffer = new byte[size];
066: }
067:
068: //
069: // Reader methods
070: //
071:
072: /**
073: * Read a single character. This method will block until a character is
074: * available, an I/O error occurs, or the end of the stream is reached.
075: *
076: * <p> Subclasses that intend to support efficient single-character input
077: * should override this method.
078: *
079: * @return The character read, as an integer in the range 0 to 127
080: * (<tt>0x00-0x7f</tt>), or -1 if the end of the stream has
081: * been reached
082: *
083: * @exception IOException If an I/O error occurs
084: */
085: public int read() throws IOException {
086: int b0 = fInputStream.read();
087: if (b0 > 0x80) {
088: throw new IOException(Localizer.getMessage(
089: "jsp.error.xml.invalidASCII", Integer.toString(b0)));
090: }
091: return b0;
092: } // read():int
093:
094: /**
095: * Read characters into a portion of an array. This method will block
096: * until some input is available, an I/O error occurs, or the end of the
097: * stream is reached.
098: *
099: * @param ch Destination buffer
100: * @param offset Offset at which to start storing characters
101: * @param length Maximum number of characters to read
102: *
103: * @return The number of characters read, or -1 if the end of the
104: * stream has been reached
105: *
106: * @exception IOException If an I/O error occurs
107: */
108: public int read(char ch[], int offset, int length)
109: throws IOException {
110: if (length > fBuffer.length) {
111: length = fBuffer.length;
112: }
113: int count = fInputStream.read(fBuffer, 0, length);
114: for (int i = 0; i < count; i++) {
115: int b0 = fBuffer[i];
116: if (b0 > 0x80) {
117: throw new IOException(Localizer.getMessage(
118: "jsp.error.xml.invalidASCII", Integer
119: .toString(b0)));
120: }
121: ch[offset + i] = (char) b0;
122: }
123: return count;
124: } // read(char[],int,int)
125:
126: /**
127: * Skip characters. This method will block until some characters are
128: * available, an I/O error occurs, or the end of the stream is reached.
129: *
130: * @param n The number of characters to skip
131: *
132: * @return The number of characters actually skipped
133: *
134: * @exception IOException If an I/O error occurs
135: */
136: public long skip(long n) throws IOException {
137: return fInputStream.skip(n);
138: } // skip(long):long
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: *
147: * @exception IOException If an I/O error occurs
148: */
149: public boolean ready() throws IOException {
150: return false;
151: } // ready()
152:
153: /**
154: * Tell whether this stream supports the mark() operation.
155: */
156: public boolean markSupported() {
157: return fInputStream.markSupported();
158: } // markSupported()
159:
160: /**
161: * Mark the present position in the stream. Subsequent calls to reset()
162: * will attempt to reposition the stream to this point. Not all
163: * character-input streams support the mark() operation.
164: *
165: * @param readAheadLimit Limit on the number of characters that may be
166: * read while still preserving the mark. After
167: * reading this many characters, attempting to
168: * reset the stream may fail.
169: *
170: * @exception IOException If the stream does not support mark(),
171: * or if some other I/O error occurs
172: */
173: public void mark(int readAheadLimit) throws IOException {
174: fInputStream.mark(readAheadLimit);
175: } // mark(int)
176:
177: /**
178: * Reset the stream. If the stream has been marked, then attempt to
179: * reposition it at the mark. If the stream has not been marked, then
180: * attempt to reset it in some way appropriate to the particular stream,
181: * for example by repositioning it to its starting point. Not all
182: * character-input streams support the reset() operation, and some support
183: * reset() without supporting mark().
184: *
185: * @exception IOException If the stream has not been marked,
186: * or if the mark has been invalidated,
187: * or if the stream does not support reset(),
188: * or if some other I/O error occurs
189: */
190: public void reset() throws IOException {
191: fInputStream.reset();
192: } // reset()
193:
194: /**
195: * Close the stream. Once a stream has been closed, further read(),
196: * ready(), mark(), or reset() invocations will throw an IOException.
197: * Closing a previously-closed stream, however, has no effect.
198: *
199: * @exception IOException If an I/O error occurs
200: */
201: public void close() throws IOException {
202: fInputStream.close();
203: } // close()
204:
205: } // class ASCIIReader
|