KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > n3 > nanoxml > ContentReader


1 /* ContentReader.java NanoXML/Java
2  *
3  * $Revision: 1421 $
4  * $Date: 2006-03-12 17:32:32 +0100 (Sun, 12 Mar 2006) $
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 import java.io.IOException JavaDoc;
32 import java.io.Reader JavaDoc;
33
34 /**
35  * This reader reads data from another reader until a certain string is encountered.
36  *
37  * @author Marc De Scheemaecker
38  * @version $Name$, $Version$
39  */

40 class ContentReader extends Reader JavaDoc
41 {
42
43     /**
44      * The encapsulated reader.
45      */

46     private IXMLReader reader;
47
48     /**
49      * The encapsulated entityResolver.
50      */

51     private IXMLEntityResolver entityResolver;
52
53     /**
54      * The escape char (& or %).
55      */

56     private char escapeChar;
57
58     /**
59      * The delimiter that will indicate the end of the stream.
60      */

61     private char[] delimiter;
62
63     /**
64      * The characters that have been read too much.
65      */

66     private String JavaDoc charsReadTooMuch;
67
68     /**
69      * The number of characters in the delimiter that stil need to be scanned.
70      */

71     private int charsToGo;
72
73     /**
74      * True if the escape char (& or %) needs to be left untouched.
75      */

76     private boolean useLowLevelReader;
77
78     /**
79      * True if we are passed the initial prefix.
80      */

81     private boolean pastInitialPrefix;
82
83     /**
84      * Creates the reader.
85      *
86      * @param reader the encapsulated reader
87      * @param entityResolver resolves entities
88      * @param escapeChar escape character (& or %)
89      * @param delimiter the delimiter, as a backwards string, that will indicate the end of the
90      * stream
91      * @param useLowLevelReader true if & needs to be left untouched; false if entities need to
92      * be processed
93      * @param prefix chars that are already read
94      */

95     ContentReader(IXMLReader reader, IXMLEntityResolver entityResolver, char escapeChar,
96             char[] delimiter, boolean useLowLevelReader, String JavaDoc prefix)
97     {
98         this.delimiter = delimiter;
99         this.charsToGo = this.delimiter.length;
100         this.charsReadTooMuch = prefix;
101         this.useLowLevelReader = useLowLevelReader;
102         this.pastInitialPrefix = false;
103         this.reader = reader;
104         this.entityResolver = entityResolver;
105         this.escapeChar = escapeChar;
106     }
107
108     /**
109      * Cleans up the object when it's destroyed.
110      */

111     protected void finalize() throws Throwable JavaDoc
112     {
113         this.reader = null;
114         this.entityResolver = null;
115         this.delimiter = null;
116         this.charsReadTooMuch = null;
117         super.finalize();
118     }
119
120     /**
121      * Reads a block of data.
122      *
123      * @param buffer where to put the read data
124      * @param offset first position in buffer to put the data
125      * @param size maximum number of chars to read
126      *
127      * @return the number of chars read, or -1 if at EOF
128      *
129      * @throws java.io.IOException if an error occurred reading the data
130      */

131     public int read(char[] buffer, int offset, int size) throws IOException JavaDoc
132     {
133         int charsRead = 0;
134         boolean isEntity[] = new boolean[1];
135         isEntity[0] = false;
136
137         if ((offset + size) > buffer.length)
138         {
139             size = buffer.length - offset;
140         }
141
142         while ((this.charsToGo > 0) && (charsRead < size))
143         {
144             char ch;
145
146             if (this.charsReadTooMuch.length() > 0)
147             {
148                 ch = this.charsReadTooMuch.charAt(0);
149                 this.charsReadTooMuch = this.charsReadTooMuch.substring(1);
150             }
151             else
152             {
153                 this.pastInitialPrefix = true;
154
155                 try
156                 {
157                     if (useLowLevelReader)
158                     {
159                         ch = this.reader.read();
160                     }
161                     else
162                     {
163                         ch = XMLUtil.read(this.reader, isEntity, this.escapeChar,
164                                 this.entityResolver);
165
166                         if (!isEntity[0])
167                         {
168                             if (ch == '&')
169                             {
170                                 this.reader.startNewStream(XMLUtil.scanEntity(isEntity,
171                                         this.reader, this.escapeChar, this.entityResolver));
172                                 ch = this.reader.read();
173                             }
174                         }
175                     }
176                 }
177                 catch (XMLParseException e)
178                 {
179                     throw new RuntimeException JavaDoc(e.getMessage());
180                     // necessary to be able to implement Reader
181
}
182             }
183
184             if (isEntity[0])
185             {
186                 buffer[offset + charsRead] = ch;
187                 charsRead++;
188             }
189             else
190             {
191                 if ((ch == (this.delimiter[this.charsToGo - 1])) && pastInitialPrefix)
192                 {
193                     --this.charsToGo;
194                 }
195                 else if (this.charsToGo < this.delimiter.length)
196                 {
197                     this.charsReadTooMuch = new String JavaDoc(this.delimiter, this.charsToGo + 1,
198                             this.delimiter.length - this.charsToGo)
199                             + ch;
200                     this.charsToGo = this.delimiter.length;
201                     buffer[offset + charsRead] = this.delimiter[this.charsToGo - 1];
202                     charsRead++;
203                 }
204                 else
205                 {
206                     buffer[offset + charsRead] = ch;
207                     charsRead++;
208                 }
209             }
210         }
211
212         if (charsRead == 0)
213         {
214             charsRead = -1;
215         }
216
217         return charsRead;
218     }
219
220     /**
221      * Skips remaining data and closes the stream.
222      *
223      * @throws java.io.IOException if an error occurred reading the data
224      */

225     public void close() throws IOException JavaDoc
226     {
227         while (this.charsToGo > 0)
228         {
229             char ch;
230
231             if (this.charsReadTooMuch.length() > 0)
232             {
233                 ch = this.charsReadTooMuch.charAt(0);
234                 this.charsReadTooMuch = this.charsReadTooMuch.substring(1);
235             }
236             else
237             {
238                 if (useLowLevelReader)
239                 {
240                     ch = this.reader.read();
241                 }
242                 else
243                 {
244                     try
245                     {
246                         ch = XMLUtil.read(this.reader, null, this.escapeChar, this.entityResolver);
247                     }
248                     catch (XMLParseException e)
249                     {
250                         throw new RuntimeException JavaDoc(e.getMessage());
251                         // necessary to be able to implement Reader
252
}
253                 }
254             }
255
256             if (ch == (this.delimiter[this.charsToGo - 1]))
257             {
258                 --this.charsToGo;
259             }
260             else if (this.charsToGo < this.delimiter.length)
261             {
262                 this.charsReadTooMuch = new String JavaDoc(this.delimiter, this.charsToGo + 1,
263                         this.delimiter.length - this.charsToGo)
264                         + ch;
265                 this.charsToGo = this.delimiter.length;
266             }
267         }
268     }
269
270 }
271
Popular Tags