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.xerces.impl.io;
019:
020: import java.io.InputStream;
021: import java.io.IOException;
022: import java.io.Reader;
023: import java.util.Locale;
024: import org.apache.xerces.util.MessageFormatter;
025: import org.apache.xerces.impl.msg.XMLMessageFormatter;
026:
027: /**
028: * A simple ASCII byte reader. This is an optimized reader for reading
029: * byte streams that only contain 7-bit ASCII characters.
030: *
031: * @xerces.internal
032: *
033: * @author Andy Clark, IBM
034: *
035: * @version $Id: ASCIIReader.java 446716 2006-09-15 20:28:48Z mrglavas $
036: */
037: public class ASCIIReader extends Reader {
038:
039: //
040: // Constants
041: //
042:
043: /** Default byte buffer size (2048). */
044: public static final int DEFAULT_BUFFER_SIZE = 2048;
045:
046: //
047: // Data
048: //
049:
050: /** Input stream. */
051: protected final InputStream fInputStream;
052:
053: /** Byte buffer. */
054: protected final byte[] fBuffer;
055:
056: // message formatter; used to produce localized
057: // exception messages
058: private final MessageFormatter fFormatter;
059:
060: //Locale to use for messages
061: private final Locale fLocale;
062:
063: //
064: // Constructors
065: //
066:
067: /**
068: * Constructs an ASCII reader from the specified input stream
069: * using the default buffer size.
070: *
071: * @param inputStream The input stream.
072: * @param messageFormatter the MessageFormatter to use to message reporting.
073: * @param locale the Locale for which messages are to be reported
074: */
075: public ASCIIReader(InputStream inputStream,
076: MessageFormatter messageFormatter, Locale locale) {
077: this (inputStream, DEFAULT_BUFFER_SIZE, messageFormatter, locale);
078: } // <init>(InputStream, MessageFormatter, Locale)
079:
080: /**
081: * Constructs an ASCII reader from the specified input stream
082: * and buffer size.
083: *
084: * @param inputStream The input stream.
085: * @param size The initial buffer size.
086: * @param messageFormatter the MessageFormatter to use to message reporting.
087: * @param locale the Locale for which messages are to be reported
088: */
089: public ASCIIReader(InputStream inputStream, int size,
090: MessageFormatter messageFormatter, Locale locale) {
091: this (inputStream, new byte[size], messageFormatter, locale);
092: } // <init>(InputStream, int, MessageFormatter, Locale)
093:
094: /**
095: * Constructs an ASCII reader from the specified input stream and buffer.
096: *
097: * @param inputStream The input stream.
098: * @param buffer The byte buffer.
099: * @param messageFormatter the MessageFormatter to use to message reporting.
100: * @param locale the Locale for which messages are to be reported
101: */
102: public ASCIIReader(InputStream inputStream, byte[] buffer,
103: MessageFormatter messageFormatter, Locale locale) {
104: fInputStream = inputStream;
105: fBuffer = buffer;
106: fFormatter = messageFormatter;
107: fLocale = locale;
108: } // <init>(InputStream, byte[], MessageFormatter, Locale)
109:
110: //
111: // Reader methods
112: //
113:
114: /**
115: * Read a single character. This method will block until a character is
116: * available, an I/O error occurs, or the end of the stream is reached.
117: *
118: * <p> Subclasses that intend to support efficient single-character input
119: * should override this method.
120: *
121: * @return The character read, as an integer in the range 0 to 127
122: * (<tt>0x00-0x7f</tt>), or -1 if the end of the stream has
123: * been reached
124: *
125: * @exception IOException If an I/O error occurs
126: */
127: public int read() throws IOException {
128: int b0 = fInputStream.read();
129: if (b0 >= 0x80) {
130: throw new MalformedByteSequenceException(fFormatter,
131: fLocale, XMLMessageFormatter.XML_DOMAIN,
132: "InvalidASCII",
133: new Object[] { Integer.toString(b0) });
134: }
135: return b0;
136: } // read():int
137:
138: /**
139: * Read characters into a portion of an array. This method will block
140: * until some input is available, an I/O error occurs, or the end of the
141: * stream is reached.
142: *
143: * @param ch Destination buffer
144: * @param offset Offset at which to start storing characters
145: * @param length Maximum number of characters to read
146: *
147: * @return The number of characters read, or -1 if the end of the
148: * stream has been reached
149: *
150: * @exception IOException If an I/O error occurs
151: */
152: public int read(char ch[], int offset, int length)
153: throws IOException {
154: if (length > fBuffer.length) {
155: length = fBuffer.length;
156: }
157: int count = fInputStream.read(fBuffer, 0, length);
158: for (int i = 0; i < count; i++) {
159: int b0 = fBuffer[i];
160: if (b0 < 0) {
161: throw new MalformedByteSequenceException(fFormatter,
162: fLocale, XMLMessageFormatter.XML_DOMAIN,
163: "InvalidASCII", new Object[] { Integer
164: .toString(b0 & 0x0FF) });
165: }
166: ch[offset + i] = (char) b0;
167: }
168: return count;
169: } // read(char[],int,int)
170:
171: /**
172: * Skip characters. This method will block until some characters are
173: * available, an I/O error occurs, or the end of the stream is reached.
174: *
175: * @param n The number of characters to skip
176: *
177: * @return The number of characters actually skipped
178: *
179: * @exception IOException If an I/O error occurs
180: */
181: public long skip(long n) throws IOException {
182: return fInputStream.skip(n);
183: } // skip(long):long
184:
185: /**
186: * Tell whether this stream is ready to be read.
187: *
188: * @return True if the next read() is guaranteed not to block for input,
189: * false otherwise. Note that returning false does not guarantee that the
190: * next read will block.
191: *
192: * @exception IOException If an I/O error occurs
193: */
194: public boolean ready() throws IOException {
195: return false;
196: } // ready()
197:
198: /**
199: * Tell whether this stream supports the mark() operation.
200: */
201: public boolean markSupported() {
202: return fInputStream.markSupported();
203: } // markSupported()
204:
205: /**
206: * Mark the present position in the stream. Subsequent calls to reset()
207: * will attempt to reposition the stream to this point. Not all
208: * character-input streams support the mark() operation.
209: *
210: * @param readAheadLimit Limit on the number of characters that may be
211: * read while still preserving the mark. After
212: * reading this many characters, attempting to
213: * reset the stream may fail.
214: *
215: * @exception IOException If the stream does not support mark(),
216: * or if some other I/O error occurs
217: */
218: public void mark(int readAheadLimit) throws IOException {
219: fInputStream.mark(readAheadLimit);
220: } // mark(int)
221:
222: /**
223: * Reset the stream. If the stream has been marked, then attempt to
224: * reposition it at the mark. If the stream has not been marked, then
225: * attempt to reset it in some way appropriate to the particular stream,
226: * for example by repositioning it to its starting point. Not all
227: * character-input streams support the reset() operation, and some support
228: * reset() without supporting mark().
229: *
230: * @exception IOException If the stream has not been marked,
231: * or if the mark has been invalidated,
232: * or if the stream does not support reset(),
233: * or if some other I/O error occurs
234: */
235: public void reset() throws IOException {
236: fInputStream.reset();
237: } // reset()
238:
239: /**
240: * Close the stream. Once a stream has been closed, further read(),
241: * ready(), mark(), or reset() invocations will throw an IOException.
242: * Closing a previously-closed stream, however, has no effect.
243: *
244: * @exception IOException If an I/O error occurs
245: */
246: public void close() throws IOException {
247: fInputStream.close();
248: } // close()
249:
250: } // class ASCIIReader
|