001: /* ContentReader.java NanoXML/Java
002: *
003: * $Revision: 1.17 $
004: * $Date: 2005/01/05 17:20:04 $
005: * $Name: $
006: *
007: * This file is part of NanoXML 2 for Java.
008: * Copyright (C) 2000-2002 Marc De Scheemaecker, All Rights Reserved.
009: *
010: * This software is provided 'as-is', without any express or implied warranty.
011: * In no event will the authors be held liable for any damages arising from the
012: * use of this software.
013: *
014: * Permission is granted to anyone to use this software for any purpose,
015: * including commercial applications, and to alter it and redistribute it
016: * freely, subject to the following restrictions:
017: *
018: * 1. The origin of this software must not be misrepresented; you must not
019: * claim that you wrote the original software. If you use this software in
020: * a product, an acknowledgment in the product documentation would be
021: * appreciated but is not required.
022: *
023: * 2. Altered source versions must be plainly marked as such, and must not be
024: * misrepresented as being the original software.
025: *
026: * 3. This notice may not be removed or altered from any source distribution.
027: */
028:
029: package net.n3.nanoxml;
030:
031: import java.io.Reader;
032: import java.io.IOException;
033:
034: /**
035: * This reader reads data from another reader until a new element has
036: * been encountered.
037: *
038: * @author Marc De Scheemaecker
039: * @version $Name: $, $Revision: 1.17 $
040: */
041: class ContentReader extends Reader {
042:
043: /**
044: * The encapsulated reader.
045: */
046: private IXMLReader reader;
047:
048: /**
049: * Buffer.
050: */
051: private String buffer;
052:
053: /**
054: * Pointer into the buffer.
055: */
056: private int bufferIndex;
057:
058: /**
059: * The entity resolver.
060: */
061: private IXMLEntityResolver resolver;
062:
063: /**
064: * Creates the reader.
065: *
066: * @param reader the encapsulated reader
067: * @param resolver the entity resolver
068: * @param buffer data that has already been read from <code>reader</code>
069: */
070: ContentReader(IXMLReader reader, IXMLEntityResolver resolver,
071: String buffer) {
072: this .reader = reader;
073: this .resolver = resolver;
074: this .buffer = buffer;
075: this .bufferIndex = 0;
076: }
077:
078: /**
079: * Cleans up the object when it's destroyed.
080: */
081: protected void finalize() throws Throwable {
082: this .reader = null;
083: this .resolver = null;
084: this .buffer = null;
085: super .finalize();
086: }
087:
088: /**
089: * Reads a block of data.
090: *
091: * @param outputBuffer where to put the read data
092: * @param offset first position in buffer to put the data
093: * @param size maximum number of chars to read
094: *
095: * @return the number of chars read, or -1 if at EOF
096: *
097: * @throws java.io.IOException
098: * if an error occurred reading the data
099: */
100: public int read(char[] outputBuffer, int offset, int size)
101: throws IOException {
102: try {
103: int charsRead = 0;
104: int bufferLength = this .buffer.length();
105:
106: if ((offset + size) > outputBuffer.length) {
107: size = outputBuffer.length - offset;
108: }
109:
110: while (charsRead < size) {
111: String str = "";
112: char ch;
113:
114: if (this .bufferIndex >= bufferLength) {
115: str = XMLUtil.read(this .reader, '&');
116: ch = str.charAt(0);
117: } else {
118: ch = this .buffer.charAt(this .bufferIndex);
119: this .bufferIndex++;
120: outputBuffer[charsRead] = ch;
121: charsRead++;
122: continue; // don't interprete chars in the buffer
123: }
124:
125: if (ch == '<') {
126: this .reader.unread(ch);
127: break;
128: }
129:
130: if ((ch == '&') && (str.length() > 1)) {
131: if (str.charAt(1) == '#') {
132: ch = XMLUtil.processCharLiteral(str);
133: } else {
134: XMLUtil.processEntity(str, this .reader,
135: this .resolver);
136: continue;
137: }
138: }
139:
140: outputBuffer[charsRead] = ch;
141: charsRead++;
142: }
143:
144: if (charsRead == 0) {
145: charsRead = -1;
146: }
147:
148: return charsRead;
149: } catch (XMLParseException e) {
150: throw new IOException(e.getMessage());
151: }
152: }
153:
154: /**
155: * Skips remaining data and closes the stream.
156: *
157: * @throws java.io.IOException
158: * if an error occurred reading the data
159: */
160: public void close() throws IOException {
161: try {
162: int bufferLength = this .buffer.length();
163:
164: for (;;) {
165: String str = "";
166: char ch;
167:
168: if (this .bufferIndex >= bufferLength) {
169: str = XMLUtil.read(this .reader, '&');
170: ch = str.charAt(0);
171: } else {
172: ch = this .buffer.charAt(this .bufferIndex);
173: this .bufferIndex++;
174: continue; // don't interprete chars in the buffer
175: }
176:
177: if (ch == '<') {
178: this .reader.unread(ch);
179: break;
180: }
181:
182: if ((ch == '&') && (str.length() > 1)) {
183: if (str.charAt(1) != '#') {
184: XMLUtil.processEntity(str, this .reader,
185: this .resolver);
186: }
187: }
188: }
189: } catch (XMLParseException e) {
190: throw new IOException(e.getMessage());
191: }
192: }
193:
194: }
|