OSDN Git Service

original
[gb-231r1-is01/Gingerbread_2.3.3_r1_IS01.git] / libcore / support / src / test / java / tests / support / Support_StringReader.java
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 tests.support;
19
20 import java.io.IOException;
21 import java.io.Reader;
22
23 public class Support_StringReader extends Reader {
24     private String str;
25
26     private int markpos = -1;
27
28     private int pos = 0;
29
30     private int count;
31
32     /**
33      * Construct a StringReader on the String <code>str</code>. The size of
34      * the reader is set to the <code>length()</code> of the String and the
35      * Object to synchronize access through is set to <code>str</code>.
36      *
37      * @param str
38      *            the String to filter reads on.
39      */
40     public Support_StringReader(String str) {
41         super(str);
42         this.str = str;
43         this.count = str.length();
44     }
45
46     /**
47      * This method closes this StringReader. Once it is closed, you can no
48      * longer read from it. Only the first invocation of this method has any
49      * effect.
50      *
51      */
52     @Override
53     public void close() {
54         synchronized (lock) {
55             if (isOpen()) {
56                 str = null;
57             }
58         }
59     }
60
61     /**
62      * Answer a boolean indicating whether or not this StringReader is open.
63      */
64     private boolean isOpen() {
65         return str != null;
66     }
67
68     /**
69      * Set a Mark position in this Reader. The parameter <code>readLimit</code>
70      * is ignored for StringReaders. Sending reset() will reposition the reader
71      * back to the marked position provided the mark has not been invalidated.
72      *
73      * @param readlimit
74      *            ignored for StringReaders.
75      *
76      * @exception java.io.IOException
77      *                If an error occurs attempting mark this StringReader.
78      */
79     @Override
80     public void mark(int readLimit) throws IOException {
81         if (readLimit >= 0) {
82             synchronized (lock) {
83                 if (isOpen()) {
84                     markpos = pos;
85                 } else {
86                     throw new IOException("StringReader is closed");
87                 }
88             }
89         } else {
90             throw new IllegalArgumentException();
91         }
92     }
93
94     /**
95      * Answers a boolean indicating whether or not this StringReader supports
96      * mark() and reset(). This method always returns true.
97      *
98      * @return <code>true</code> if mark() and reset() are supported,
99      *         <code>false</code> otherwise. This implementation always
100      *         returns <code>true</code>.
101      */
102     @Override
103     public boolean markSupported() {
104         return true;
105     }
106
107     /**
108      * Reads a single character from this StringReader and returns the result as
109      * an int. The 2 higher-order bytes are set to 0. If the end of reader was
110      * encountered then return -1.
111      *
112      * @return the character read or -1 if end of reader.
113      *
114      * @exception java.io.IOException
115      *                If the StringReader is already closed.
116      */
117     @Override
118     public int read() throws IOException {
119         synchronized (lock) {
120             if (isOpen()) {
121                 if (pos != count) {
122                     return str.charAt(pos++);
123                 }
124                 return -1;
125             }
126             throw new IOException("StringReader is closed");
127         }
128     }
129
130     /**
131      * Reads at most <code>count</code> characters from this StringReader and
132      * stores them at <code>offset</code> in the character array
133      * <code>buf</code>. Returns the number of characters actually read or -1
134      * if the end of reader was encountered.
135      *
136      * @param buf
137      *            character array to store the read characters
138      * @param offset
139      *            offset in buf to store the read characters
140      * @param count
141      *            maximum number of characters to read
142      * @return the number of characters read or -1 if end of reader.
143      *
144      * @exception java.io.IOException
145      *                If the StringReader is closed.
146      */
147     @Override
148     public int read(char buf[], int offset, int count) throws IOException {
149         // avoid int overflow
150         if (0 <= offset && offset <= buf.length && 0 <= count
151                 && count <= buf.length - offset) {
152             synchronized (lock) {
153                 if (isOpen()) {
154                     if (pos == this.count) {
155                         return -1;
156                     }
157                     int end = pos + count > this.count ? this.count : pos
158                             + count;
159                     str.getChars(pos, end, buf, offset);
160                     int read = end - pos;
161                     pos = end;
162                     return read;
163                 }
164                 throw new IOException("StringReader is closed");
165             }
166         }
167         throw new ArrayIndexOutOfBoundsException();
168     }
169
170     /**
171      * Answers a <code>boolean</code> indicating whether or not this
172      * StringReader is ready to be read without blocking. If the result is
173      * <code>true</code>, the next <code>read()</code> will not block. If
174      * the result is <code>false</code> this Reader may or may not block when
175      * <code>read()</code> is sent. The implementation in StringReader always
176      * returns <code>true</code> even when it has been closed.
177      *
178      * @return <code>true</code> if the receiver will not block when
179      *         <code>read()</code> is called, <code>false</code> if unknown
180      *         or blocking will occur.
181      *
182      * @exception java.io.IOException
183      *                If an IO error occurs.
184      */
185     @Override
186     public boolean ready() throws IOException {
187         synchronized (lock) {
188             if (isOpen()) {
189                 return true;
190             }
191             throw new IOException("StringReader is closed");
192         }
193     }
194
195     /**
196      * Reset this StringReader's position to the last <code>mark()</code>
197      * location. Invocations of <code>read()/skip()</code> will occur from
198      * this new location. If this Reader was not marked, the StringReader is
199      * reset to the beginning of the String.
200      *
201      * @exception java.io.IOException
202      *                If this StringReader has already been closed.
203      */
204     @Override
205     public void reset() throws IOException {
206         synchronized (lock) {
207             if (isOpen()) {
208                 pos = markpos != -1 ? markpos : 0;
209             } else {
210                 throw new IOException("StringReader is closed");
211             }
212         }
213     }
214
215     /**
216      * Skips <code>count</code> number of characters in this StringReader.
217      * Subsequent <code>read()</code>'s will not return these characters
218      * unless <code>reset()</code> is used.
219      *
220      * @param count
221      *            The number of characters to skip.
222      * @return the number of characters actually skipped.
223      *
224      * @exception java.io.IOException
225      *                If this StringReader has already been closed.
226      */
227     @Override
228     public long skip(long count) throws IOException {
229         synchronized (lock) {
230             if (isOpen()) {
231                 if (count <= 0) {
232                     return 0;
233                 }
234                 long skipped = 0;
235                 if (count < this.count - pos) {
236                     pos = pos + (int) count;
237                     skipped = count;
238                 } else {
239                     skipped = this.count - pos;
240                     pos = this.count;
241                 }
242                 return skipped;
243             }
244             throw new IOException("StringReader is closed");
245         }
246     }
247 }