package hep.io.sio;
import hep.io.xdr.XDRInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Vector;
/**
* An SIOInputStream provides all the functionality of an XDRInputStream, but adds the
* ability to do pointer relocation within records.
*/
public class SIOInputStream extends XDRInputStream {
private Vector map;
private static final SIORef nullRef = new NullRef();
SIOInputStream(InputStream in) {
super(in);
map = new Vector();
}
/**
* An input stream which shares a map with a parent stream
*/
public SIOInputStream(InputStream in, SIOInputStream parent) {
super(in);
map = parent.map;
}
void clear() {
map.removeAllElements();
}
/**
* Read an SIO PTAG and associate it with an Object o
*/
public void readPTag(Object o) throws IOException {
int i = readInt();
if (i < 0) {
return; // nothing points to this object
}
if (map.size() < i + 1) {
map.setSize(i + 1);
}
map.setElementAt(o, i);
}
/**
* Read an SIO PNTR.
* @return An SIORef which can be used to access the target object after the entire record has been read
*/
public SIORef readPntr() throws IOException {
int i = readInt();
if (i == 0) {
return nullRef;
}
return new SIORefImpl(i);
}
private class SIORefImpl implements SIORef {
SIORefImpl(int i) {
index = i;
}
public Object getObject() {
try {
return map.elementAt(index);
} catch (Exception x) {
return null;
}
}
private int index;
}
private static class NullRef implements SIORef {
public Object getObject() {
return null;
}
}
public void close() throws IOException {
// NOOP -- should not close underlying IO stream
}
}