CharTerminatedInputStreampublic class CharTerminatedInputStream extends InputStream An InputStream class that terminates the stream when it encounters a
particular byte sequence. |
Fields Summary |
---|
private InputStream | inThe wrapped input stream | private int[] | matchThe terminating character array | private int[] | bufferAn array containing the last N characters read from the stream, where
N is the length of the terminating character array | private int | posThe number of bytes that have been read that have not been placed
in the internal buffer. | private boolean | endFoundWhether the terminating sequence has been read from the stream |
Constructors Summary |
---|
public CharTerminatedInputStream(InputStream in, char[] terminator)A constructor for this object that takes a stream to be wrapped
and a terminating character sequence.
if (terminator == null) {
throw new IllegalArgumentException("The terminating character array cannot be null.");
}
if (terminator.length == 0) {
throw new IllegalArgumentException("The terminating character array cannot be of zero length.");
}
match = new int[terminator.length];
buffer = new int[terminator.length];
for (int i = 0; i < terminator.length; i++) {
match[i] = (int)terminator[i];
buffer[i] = (int)terminator[i];
}
this.in = in;
|
Methods Summary |
---|
public int | read()Read a byte off this stream.
if (endFound) {
//We've found the match to the terminator
return -1;
}
if (pos == 0) {
//We have no data... read in a record
int b = in.read();
if (b == -1) {
//End of stream reached without seeing the terminator
throw new java.net.ProtocolException("pre-mature end of data");
}
if (b != match[0]) {
//this char is not the first char of the match
return b;
}
//this is a match...put this in the first byte of the buffer,
// and fall through to matching logic
buffer[0] = b;
pos++;
} else {
if (buffer[0] != match[0]) {
//Maybe from a previous scan, there is existing data,
// and the first available char does not match the
// beginning of the terminating string.
return topChar();
}
//we have a match... fall through to matching logic.
}
//MATCHING LOGIC
//The first character is a match... scan for complete match,
// reading extra chars as needed, until complete match is found
for (int i = 0; i < match.length; i++) {
if (i >= pos) {
int b = in.read();
if (b == -1) {
//end of stream found, so match cannot be fulfilled.
// note we don't set endFound, because otherwise
// remaining part of buffer won't be returned.
return topChar();
}
//put the read char in the buffer
buffer[pos] = b;
pos++;
}
if (buffer[i] != match[i]) {
//we did not find a match... return the top char
return topChar();
}
}
//A complete match was made...
endFound = true;
return -1;
| private int | topChar()Private helper method to update the internal buffer of last read characters
int b = buffer[0];
if (pos > 1) {
//copy down the buffer to keep the fresh data at top
System.arraycopy(buffer, 1, buffer, 0, pos - 1);
}
pos--;
return b;
|
|