Statistics
| Revision:

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
}