root / import / ext3D / trunk / install-extension3d / IzPack / src / lib / net / n3 / nanoxml / ContentReader.java @ 15280
History | View | Annotate | Download (8.67 KB)
1 |
/* ContentReader.java NanoXML/Java
|
---|---|
2 |
*
|
3 |
* $Revision: 1.1 $
|
4 |
* $Date: 2006/06/14 07:29:07 $
|
5 |
* $Name: $
|
6 |
*
|
7 |
* This file is part of NanoXML 2 for Java.
|
8 |
* Copyright (C) 2001 Marc De Scheemaecker, All Rights Reserved.
|
9 |
*
|
10 |
* This software is provided 'as-is', without any express or implied warranty.
|
11 |
* In no event will the authors be held liable for any damages arising from the
|
12 |
* use of this software.
|
13 |
*
|
14 |
* Permission is granted to anyone to use this software for any purpose,
|
15 |
* including commercial applications, and to alter it and redistribute it
|
16 |
* freely, subject to the following restrictions:
|
17 |
*
|
18 |
* 1. The origin of this software must not be misrepresented; you must not
|
19 |
* claim that you wrote the original software. If you use this software in
|
20 |
* a product, an acknowledgment in the product documentation would be
|
21 |
* appreciated but is not required.
|
22 |
*
|
23 |
* 2. Altered source versions must be plainly marked as such, and must not be
|
24 |
* misrepresented as being the original software.
|
25 |
*
|
26 |
* 3. This notice may not be removed or altered from any source distribution.
|
27 |
*/
|
28 |
|
29 |
package net.n3.nanoxml; |
30 |
|
31 |
|
32 |
import java.io.IOException; |
33 |
import java.io.Reader; |
34 |
|
35 |
|
36 |
/**
|
37 |
* This reader reads data from another reader until a certain string is
|
38 |
* encountered.
|
39 |
*
|
40 |
* @author Marc De Scheemaecker
|
41 |
* @version $Name: $, $Version$
|
42 |
*/
|
43 |
class ContentReader |
44 |
extends Reader |
45 |
{ |
46 |
|
47 |
/**
|
48 |
* The encapsulated reader.
|
49 |
*/
|
50 |
private IXMLReader reader;
|
51 |
|
52 |
|
53 |
/**
|
54 |
* The encapsulated entityResolver.
|
55 |
*/
|
56 |
private IXMLEntityResolver entityResolver;
|
57 |
|
58 |
|
59 |
/**
|
60 |
* The escape char (& or %).
|
61 |
*/
|
62 |
private char escapeChar; |
63 |
|
64 |
|
65 |
/**
|
66 |
* The delimiter that will indicate the end of the stream.
|
67 |
*/
|
68 |
private char[] delimiter; |
69 |
|
70 |
|
71 |
/**
|
72 |
* The characters that have been read too much.
|
73 |
*/
|
74 |
private String charsReadTooMuch; |
75 |
|
76 |
|
77 |
/**
|
78 |
* The number of characters in the delimiter that stil need to be
|
79 |
* scanned.
|
80 |
*/
|
81 |
private int charsToGo; |
82 |
|
83 |
|
84 |
/**
|
85 |
* True if the escape char (& or %) needs to be left untouched.
|
86 |
*/
|
87 |
private boolean useLowLevelReader; |
88 |
|
89 |
|
90 |
/**
|
91 |
* True if we are passed the initial prefix.
|
92 |
*/
|
93 |
private boolean pastInitialPrefix; |
94 |
|
95 |
|
96 |
/**
|
97 |
* Creates the reader.
|
98 |
*
|
99 |
* @param reader the encapsulated reader
|
100 |
* @param entityResolver resolves entities
|
101 |
* @param escapeChar escape character (& or %)
|
102 |
* @param delimiter the delimiter, as a backwards string, that will
|
103 |
* indicate the end of the stream
|
104 |
* @param useLowLevelReader true if & needs to be left untouched;
|
105 |
* false if entities need to be processed
|
106 |
* @param prefix chars that are already read
|
107 |
*/
|
108 |
ContentReader(IXMLReader reader, |
109 |
IXMLEntityResolver entityResolver, |
110 |
char escapeChar,
|
111 |
char[] delimiter, |
112 |
boolean useLowLevelReader,
|
113 |
String prefix)
|
114 |
{ |
115 |
this.delimiter = delimiter;
|
116 |
this.charsToGo = this.delimiter.length; |
117 |
this.charsReadTooMuch = prefix;
|
118 |
this.useLowLevelReader = useLowLevelReader;
|
119 |
this.pastInitialPrefix = false; |
120 |
this.reader = reader;
|
121 |
this.entityResolver = entityResolver;
|
122 |
this.escapeChar = escapeChar;
|
123 |
} |
124 |
|
125 |
|
126 |
/**
|
127 |
* Cleans up the object when it's destroyed.
|
128 |
*/
|
129 |
protected void finalize() |
130 |
throws Throwable |
131 |
{ |
132 |
this.reader = null; |
133 |
this.entityResolver = null; |
134 |
this.delimiter = null; |
135 |
this.charsReadTooMuch = null; |
136 |
super.finalize();
|
137 |
} |
138 |
|
139 |
|
140 |
/**
|
141 |
* Reads a block of data.
|
142 |
*
|
143 |
* @param buffer where to put the read data
|
144 |
* @param offset first position in buffer to put the data
|
145 |
* @param size maximum number of chars to read
|
146 |
*
|
147 |
* @return the number of chars read, or -1 if at EOF
|
148 |
*
|
149 |
* @throws java.io.IOException
|
150 |
* if an error occurred reading the data
|
151 |
*/
|
152 |
public int read(char[] buffer, |
153 |
int offset,
|
154 |
int size)
|
155 |
throws IOException |
156 |
{ |
157 |
int charsRead = 0; |
158 |
boolean isEntity[] = new boolean[1]; |
159 |
isEntity[0] = false; |
160 |
|
161 |
if ((offset + size) > buffer.length) {
|
162 |
size = buffer.length - offset; |
163 |
} |
164 |
|
165 |
while ((this.charsToGo > 0) && (charsRead < size)) { |
166 |
char ch;
|
167 |
|
168 |
if (this.charsReadTooMuch.length() > 0) { |
169 |
ch = this.charsReadTooMuch.charAt(0); |
170 |
this.charsReadTooMuch = this.charsReadTooMuch.substring(1); |
171 |
} else {
|
172 |
this.pastInitialPrefix = true; |
173 |
|
174 |
try {
|
175 |
if (useLowLevelReader) {
|
176 |
ch = this.reader.read();
|
177 |
} else {
|
178 |
ch = XMLUtil.read(this.reader, isEntity,
|
179 |
this.escapeChar,
|
180 |
this.entityResolver);
|
181 |
|
182 |
if (! isEntity[0]) { |
183 |
if (ch == '&') { |
184 |
this.reader.startNewStream(
|
185 |
XMLUtil.scanEntity(isEntity, |
186 |
this.reader,
|
187 |
this.escapeChar,
|
188 |
this.entityResolver));
|
189 |
ch = this.reader.read();
|
190 |
} |
191 |
} |
192 |
} |
193 |
} catch (XMLParseException e) { |
194 |
throw new RuntimeException(e.getMessage()); |
195 |
// necessary to be able to implement Reader
|
196 |
} |
197 |
} |
198 |
|
199 |
if (isEntity[0]) { |
200 |
buffer[offset + charsRead] = ch; |
201 |
charsRead++; |
202 |
} else {
|
203 |
if ((ch == (this.delimiter[this.charsToGo - 1])) |
204 |
&& pastInitialPrefix) { |
205 |
--this.charsToGo;
|
206 |
} else if (this.charsToGo < this.delimiter.length) { |
207 |
this.charsReadTooMuch
|
208 |
= new String(this.delimiter, this.charsToGo + 1, |
209 |
this.delimiter.length - this.charsToGo) |
210 |
+ ch; |
211 |
this.charsToGo = this.delimiter.length; |
212 |
buffer[offset + charsRead] |
213 |
= this.delimiter[this.charsToGo - 1]; |
214 |
charsRead++; |
215 |
} else {
|
216 |
buffer[offset + charsRead] = ch; |
217 |
charsRead++; |
218 |
} |
219 |
} |
220 |
} |
221 |
|
222 |
if (charsRead == 0) { |
223 |
charsRead = -1;
|
224 |
} |
225 |
|
226 |
return charsRead;
|
227 |
} |
228 |
|
229 |
|
230 |
/**
|
231 |
* Skips remaining data and closes the stream.
|
232 |
*
|
233 |
* @throws java.io.IOException
|
234 |
* if an error occurred reading the data
|
235 |
*/
|
236 |
public void close() |
237 |
throws IOException |
238 |
{ |
239 |
while (this.charsToGo > 0) { |
240 |
char ch;
|
241 |
|
242 |
if (this.charsReadTooMuch.length() > 0) { |
243 |
ch = this.charsReadTooMuch.charAt(0); |
244 |
this.charsReadTooMuch = this.charsReadTooMuch.substring(1); |
245 |
} else {
|
246 |
if (useLowLevelReader) {
|
247 |
ch = this.reader.read();
|
248 |
} else {
|
249 |
try {
|
250 |
ch = XMLUtil.read(this.reader, null, this.escapeChar, |
251 |
this.entityResolver);
|
252 |
} catch (XMLParseException e) { |
253 |
throw new RuntimeException(e.getMessage()); |
254 |
// necessary to be able to implement Reader
|
255 |
} |
256 |
} |
257 |
} |
258 |
|
259 |
if (ch == (this.delimiter[this.charsToGo - 1])) { |
260 |
--this.charsToGo;
|
261 |
} else if (this.charsToGo < this.delimiter.length) { |
262 |
this.charsReadTooMuch
|
263 |
= new String(this.delimiter, this.charsToGo + 1, |
264 |
this.delimiter.length - this.charsToGo) |
265 |
+ ch; |
266 |
this.charsToGo = this.delimiter.length; |
267 |
} |
268 |
} |
269 |
} |
270 |
|
271 |
} |