org.freehep.util.io.XMLSequence Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of freehep-io Show documentation
Show all versions of freehep-io Show documentation
FreeHEP extension to the java.io library
// Copyright 2003, FreeHEP.
package org.freehep.util.io;
import java.io.IOException;
import java.io.InputStream;
import java.util.NoSuchElementException;
/**
* The XMLSequence allows parsing by an XML Parser of concatenated XML segments.
* Each segment needs to start with "
*
* XMLSequence sequence = new XMLSequence(new FileInputStream("file.xml"));
*
* SAXParserFactory factory = SAXParserFactory.newInstance();
* XMLReader xmlReader = factory.newSAXParser().getXMLReader();
*
* while (sequence.hasNext()) {
* InputStream input = sequence.next();
* InputSource source = new InputSource(input);
* xmlReader.parse(source);
* input.close();
* }
* sequence.close();
*
*
*
* IMPORTANT: inherits from InputStream rather than FilterInputStream so that
* the correct read(byte[], int, int) method is used.
*
* @author Mark Donszelmann
* @version $Id: src/main/java/org/freehep/util/io/XMLSequence.java 96b41b903496
* 2005/11/21 19:50:18 duns $
*/
public class XMLSequence extends InputStream {
// xml declaration (lowercase!)
private int[] xml = new int[] { '<', '?', 'x', 'm', 'l' };
private int xmlIndex;
// look ahead buffer
private int buffer[] = new int[xml.length];
private int index;
private boolean bufferEmpty;
// underlying stream
private InputStream in;
private boolean closed;
private boolean eof;
/**
* Create a XML Sequence.
*
* @param input
* stream to read from
*/
public XMLSequence(InputStream input) {
super();
in = input;
closed = false;
eof = false;
xmlIndex = 0;
index = 0;
bufferEmpty = true;
}
/**
* Is another XML segment available.
*
* @return true if another XML segment can be read
*/
public boolean hasNext() {
if (closed) {
return false;
}
try {
return readUntilXMLDeclaration();
} catch (IOException e) {
return false;
}
}
/**
* Returns the next XML segment.
*
* @return stream to read next XML segment from.
* @throws IOException
* if read fails
*/
public InputStream next() throws IOException {
if (eof) {
throw new NoSuchElementException(getClass() + ": at EOF.");
}
if (closed) {
throw new NoSuchElementException(getClass() + ": already closed.");
}
if (!readUntilXMLDeclaration()) {
throw new NoSuchElementException(getClass()
+ ": No more sequences.");
}
xmlIndex = 0;
return new NoCloseInputStream(this);
}
@Override
public int read() throws IOException {
if (xmlIndex == xml.length) {
return -1;
}
if (closed) {
return -1;
}
int a = -1;
if (!eof) {
// fill buffer (at start of stream)
if (bufferEmpty) {
index = 0;
for (int i = 0; i < xml.length; i++) {
int c = in.read();
buffer[i] = c;
if (buffer[i] == xml[xmlIndex]) {
// we are reading 0) {
// we are reading <..., which is also fine.
xmlIndex++;
} else {
xmlIndex = 0;
}
}
bufferEmpty = false;
if (xmlIndex == xml.length) {
return -1;
}
}
// read next character
a = in.read();
if (a != -1) {
// check if seq
if (a == xml[xmlIndex]) {
xmlIndex++;
} else {
xmlIndex = 0;
}
} else {
// underlying end-of-file
eof = true;
}
}
// returned all...
if (eof && (buffer[index] == -1)) {
return -1;
}
// replace and return next character
int b = buffer[index];
buffer[index] = a;
index = (index + 1) % buffer.length;
return b;
}
@Override
public void mark(int readLimit) {
in.mark(readLimit);
}
@Override
public boolean markSupported() {
return in.markSupported();
}
@Override
public void reset() throws IOException {
if (closed) {
throw new IOException(getClass() + ": already closed.");
}
if (!in.markSupported()) {
throw new IOException(getClass() + ": does not support reset().");
}
in.reset();
xmlIndex = 0;
index = 0;
bufferEmpty = true;
eof = false;
}
@Override
public void close() throws IOException {
if (!closed) {
in.close();
closed = true;
}
}
private boolean readUntilXMLDeclaration() throws IOException {
while (read() >= 0) {
continue;
}
return (xmlIndex == xml.length);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy