1/* 2 * reserved comment block 3 * DO NOT REMOVE OR ALTER! 4 */ 5/* 6 * Licensed to the Apache Software Foundation (ASF) under one or more 7 * contributor license agreements. See the NOTICE file distributed with 8 * this work for additional information regarding copyright ownership. 9 * The ASF licenses this file to You under the Apache License, Version 2.0 10 * (the "License"); you may not use this file except in compliance with 11 * the License. You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, software 16 * distributed under the License is distributed on an "AS IS" BASIS, 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 */ 21 22package com.sun.org.apache.xerces.internal.impl.io; 23 24import java.io.InputStream; 25import java.io.IOException; 26import java.io.Reader; 27import java.util.Locale; 28import com.sun.org.apache.xerces.internal.util.MessageFormatter; 29import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter; 30 31import com.sun.xml.internal.stream.util.BufferAllocator; 32import com.sun.xml.internal.stream.util.ThreadLocalBufferAllocator; 33 34/** 35 * A simple ASCII byte reader. This is an optimized reader for reading 36 * byte streams that only contain 7-bit ASCII characters. 37 * 38 * @xerces.internal 39 * 40 * @author Andy Clark, IBM 41 * 42 */ 43public class ASCIIReader 44 extends Reader { 45 46 // 47 // Constants 48 // 49 50 /** Default byte buffer size (2048). */ 51 public static final int DEFAULT_BUFFER_SIZE = 2048; 52 53 // 54 // Data 55 // 56 57 /** Input stream. */ 58 protected InputStream fInputStream; 59 60 /** Byte buffer. */ 61 protected byte[] fBuffer; 62 63 // message formatter; used to produce localized 64 // exception messages 65 private MessageFormatter fFormatter = null; 66 67 //Locale to use for messages 68 private Locale fLocale = null; 69 70 // 71 // Constructors 72 // 73 74 /** 75 * Constructs an ASCII reader from the specified input stream 76 * using the default buffer size. 77 * 78 * @param inputStream The input stream. 79 * @param messageFormatter the MessageFormatter to use to message reporting. 80 * @param locale the Locale for which messages are to be reported 81 */ 82 public ASCIIReader(InputStream inputStream, MessageFormatter messageFormatter, 83 Locale locale) { 84 this(inputStream, DEFAULT_BUFFER_SIZE, messageFormatter, locale); 85 } // <init>(InputStream, MessageFormatter, Locale) 86 87 /** 88 * Constructs an ASCII reader from the specified input stream 89 * and buffer size. 90 * 91 * @param inputStream The input stream. 92 * @param size The initial buffer size. 93 * @param messageFormatter the MessageFormatter to use to message reporting. 94 * @param locale the Locale for which messages are to be reported 95 */ 96 public ASCIIReader(InputStream inputStream, int size, 97 MessageFormatter messageFormatter, Locale locale) { 98 fInputStream = inputStream; 99 BufferAllocator ba = ThreadLocalBufferAllocator.getBufferAllocator(); 100 fBuffer = ba.getByteBuffer(size); 101 if (fBuffer == null) { 102 fBuffer = new byte[size]; 103 } 104 fFormatter = messageFormatter; 105 fLocale = locale; 106 } // <init>(InputStream,int, MessageFormatter, Locale) 107 108 // 109 // Reader methods 110 // 111 112 /** 113 * Read a single character. This method will block until a character is 114 * available, an I/O error occurs, or the end of the stream is reached. 115 * 116 * <p> Subclasses that intend to support efficient single-character input 117 * should override this method. 118 * 119 * @return The character read, as an integer in the range 0 to 127 120 * (<tt>0x00-0x7f</tt>), or -1 if the end of the stream has 121 * been reached 122 * 123 * @exception IOException If an I/O error occurs 124 */ 125 public int read() throws IOException { 126 int b0 = fInputStream.read(); 127 if (b0 >= 0x80) { 128 throw new MalformedByteSequenceException(fFormatter, 129 fLocale, XMLMessageFormatter.XML_DOMAIN, 130 "InvalidASCII", new Object [] {Integer.toString(b0)}); 131 } 132 return b0; 133 } // read():int 134 135 /** 136 * Read characters into a portion of an array. This method will block 137 * until some input is available, an I/O error occurs, or the end of the 138 * stream is reached. 139 * 140 * @param ch Destination buffer 141 * @param offset Offset at which to start storing characters 142 * @param length Maximum number of characters to read 143 * 144 * @return The number of characters read, or -1 if the end of the 145 * stream has been reached 146 * 147 * @exception IOException If an I/O error occurs 148 */ 149 public int read(char ch[], int offset, int length) throws IOException { 150 if (length > fBuffer.length) { 151 length = fBuffer.length; 152 } 153 int count = fInputStream.read(fBuffer, 0, length); 154 for (int i = 0; i < count; i++) { 155 int b0 = fBuffer[i]; 156 if (b0 < 0) { 157 throw new MalformedByteSequenceException(fFormatter, 158 fLocale, XMLMessageFormatter.XML_DOMAIN, 159 "InvalidASCII", new Object [] {Integer.toString(b0 & 0x0FF)}); 160 } 161 ch[offset + i] = (char)b0; 162 } 163 return count; 164 } // read(char[],int,int) 165 166 /** 167 * Skip characters. This method will block until some characters are 168 * available, an I/O error occurs, or the end of the stream is reached. 169 * 170 * @param n The number of characters to skip 171 * 172 * @return The number of characters actually skipped 173 * 174 * @exception IOException If an I/O error occurs 175 */ 176 public long skip(long n) throws IOException { 177 return fInputStream.skip(n); 178 } // skip(long):long 179 180 /** 181 * Tell whether this stream is ready to be read. 182 * 183 * @return True if the next read() is guaranteed not to block for input, 184 * false otherwise. Note that returning false does not guarantee that the 185 * next read will block. 186 * 187 * @exception IOException If an I/O error occurs 188 */ 189 public boolean ready() throws IOException { 190 return false; 191 } // ready() 192 193 /** 194 * Tell whether this stream supports the mark() operation. 195 */ 196 public boolean markSupported() { 197 return fInputStream.markSupported(); 198 } // markSupported() 199 200 /** 201 * Mark the present position in the stream. Subsequent calls to reset() 202 * will attempt to reposition the stream to this point. Not all 203 * character-input streams support the mark() operation. 204 * 205 * @param readAheadLimit Limit on the number of characters that may be 206 * read while still preserving the mark. After 207 * reading this many characters, attempting to 208 * reset the stream may fail. 209 * 210 * @exception IOException If the stream does not support mark(), 211 * or if some other I/O error occurs 212 */ 213 public void mark(int readAheadLimit) throws IOException { 214 fInputStream.mark(readAheadLimit); 215 } // mark(int) 216 217 /** 218 * Reset the stream. If the stream has been marked, then attempt to 219 * reposition it at the mark. If the stream has not been marked, then 220 * attempt to reset it in some way appropriate to the particular stream, 221 * for example by repositioning it to its starting point. Not all 222 * character-input streams support the reset() operation, and some support 223 * reset() without supporting mark(). 224 * 225 * @exception IOException If the stream has not been marked, 226 * or if the mark has been invalidated, 227 * or if the stream does not support reset(), 228 * or if some other I/O error occurs 229 */ 230 public void reset() throws IOException { 231 fInputStream.reset(); 232 } // reset() 233 234 /** 235 * Close the stream. Once a stream has been closed, further read(), 236 * ready(), mark(), or reset() invocations will throw an IOException. 237 * Closing a previously-closed stream, however, has no effect. 238 * 239 * @exception IOException If an I/O error occurs 240 */ 241 public void close() throws IOException { 242 BufferAllocator ba = ThreadLocalBufferAllocator.getBufferAllocator(); 243 ba.returnByteBuffer(fBuffer); 244 fBuffer = null; 245 fInputStream.close(); 246 } // close() 247 248} // class ASCIIReader 249