View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    * 
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   * 
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
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      // Constants
38      //
39  
40      /***
41       * Default byte buffer size (2048).
42       */
43      public static final int DEFAULT_BUFFER_SIZE = 2048;
44  
45      //
46      // Data
47      //
48  
49      /***
50       * Input stream.
51       */
52      protected InputStream fInputStream;
53  
54      /***
55       * Byte buffer.
56       */
57      protected byte[] fBuffer;
58  
59      //
60      // Constructors
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      // Reader methods
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      } // read():int
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     } // read(char[],int,int)
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     } // 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      * @throws IOException If an I/O error occurs
147      */
148     public boolean ready() throws IOException {
149         return false;
150     } // ready()
151 
152     /***
153      * Tell whether this stream supports the mark() operation.
154      */
155     public boolean markSupported() {
156         return fInputStream.markSupported();
157     } // markSupported()
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     } // mark(int)
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     } // reset()
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     } // close()
202 
203 } // class ASCIIReader