001: /* CDATAReader.java NanoXML/Java
002: *
003: * $Revision: 1.3 $
004: * $Date: 2002/01/04 21:03:28 $
005: * $Name: RELEASE_2_2_1 $
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 the end of a CDATA section
036: * (]]>) has been encountered.
037: *
038: * @author Marc De Scheemaecker
039: * @version $Name: RELEASE_2_2_1 $, $Revision: 1.3 $
040: */
041: class CDATAReader extends Reader {
042:
043: /**
044: * The encapsulated reader.
045: */
046: private IXMLReader reader;
047:
048: /**
049: * Saved char.
050: */
051: private char savedChar;
052:
053: /**
054: * True if the end of the stream has been reached.
055: */
056: private boolean atEndOfData;
057:
058: /**
059: * Creates the reader.
060: *
061: * @param reader the encapsulated reader
062: */
063: CDATAReader(IXMLReader reader) {
064: this .reader = reader;
065: this .savedChar = 0;
066: this .atEndOfData = false;
067: }
068:
069: /**
070: * Cleans up the object when it's destroyed.
071: */
072: protected void finalize() throws Throwable {
073: this .reader = null;
074: super .finalize();
075: }
076:
077: /**
078: * Reads a block of data.
079: *
080: * @param buffer where to put the read data
081: * @param offset first position in buffer to put the data
082: * @param size maximum number of chars to read
083: *
084: * @return the number of chars read, or -1 if at EOF
085: *
086: * @throws java.io.IOException
087: * if an error occurred reading the data
088: */
089: public int read(char[] buffer, int offset, int size)
090: throws IOException {
091: int charsRead = 0;
092:
093: if (this .atEndOfData) {
094: return -1;
095: }
096:
097: if ((offset + size) > buffer.length) {
098: size = buffer.length - offset;
099: }
100:
101: while (charsRead < size) {
102: char ch = this .savedChar;
103:
104: if (ch == 0) {
105: ch = this .reader.read();
106: } else {
107: this .savedChar = 0;
108: }
109:
110: if (ch == ']') {
111: char ch2 = this .reader.read();
112:
113: if (ch2 == ']') {
114: char ch3 = this .reader.read();
115:
116: if (ch3 == '>') {
117: this .atEndOfData = true;
118: break;
119: }
120:
121: this .savedChar = ch2;
122: this .reader.unread(ch3);
123: } else {
124: this .reader.unread(ch2);
125: }
126: }
127: buffer[charsRead] = ch;
128: charsRead++;
129: }
130:
131: if (charsRead == 0) {
132: charsRead = -1;
133: }
134:
135: return charsRead;
136: }
137:
138: /**
139: * Skips remaining data and closes the stream.
140: *
141: * @throws java.io.IOException
142: * if an error occurred reading the data
143: */
144: public void close() throws IOException {
145: while (!this .atEndOfData) {
146: char ch = this .savedChar;
147:
148: if (ch == 0) {
149: ch = this .reader.read();
150: } else {
151: this .savedChar = 0;
152: }
153:
154: if (ch == ']') {
155: char ch2 = this .reader.read();
156:
157: if (ch2 == ']') {
158: char ch3 = this .reader.read();
159:
160: if (ch3 == '>') {
161: break;
162: }
163:
164: this .savedChar = ch2;
165: this .reader.unread(ch3);
166: } else {
167: this .reader.unread(ch2);
168: }
169: }
170: }
171:
172: this .atEndOfData = true;
173: }
174:
175: }
|