/////////////////////////////////////////////////////////////////////////////
// Copyright (c) 1998, California Institute of Technology.
// ALL RIGHTS RESERVED. U.S. Government Sponsorship acknowledged.
//
// Please read the full copyright notice in the file COPYRIGHT
// in this directory.
//
// Author: Jake Hamby, NASA/Jet Propulsion Laboratory
// Jake.Hamby@jpl.nasa.gov
/////////////////////////////////////////////////////////////////////////////
package dods.dap;
import java.io.*;
/**
* The HeaderInputStream filters the input to only read lines of text until
* the "Data:" line. This is required because overzealous buffering in the
* DDSParser will read the data as well as the DDS otherwise.
*
* @version $Revision: 1.2 $
* @author jehamby
* @see DConnect
*/
class HeaderInputStream extends FilterInputStream {
/** Each line is buffered here. */
private byte lineBuf[];
/** Number of bytes remaining in buffer. */
private int bytesRemaining;
/** Current buffer offset. */
private int currentOffset;
/** End sequence to look for: "\nData:\n" */
private byte[] endSequence = {(byte)'\n', (byte)'D', (byte)'a', (byte)'t',
(byte)'a', (byte)':', (byte)'\n'};
/** Flag when end sequence has been found */
private boolean endFound;
/** Construct a new HeaderInputStream. */
public HeaderInputStream(InputStream in) {
super(in);
lineBuf = new byte[4096];
bytesRemaining = currentOffset = 0;
endFound = false;
}
/** Return the number of bytes in the buffer. */
public int available() {
return bytesRemaining;
}
/** Returns that we don't support the mark() and reset() methods. */
public boolean markSupported() {
return false;
}
/** Reads a single byte of data */
public int read() throws IOException {
// if the buffer is empty, get more bytes
if (bytesRemaining == 0 && !endFound)
getMoreBytes();
// if the buffer is still empty, return EOF
if (bytesRemaining == 0)
return -1;
else {
bytesRemaining--;
return lineBuf[currentOffset++];
}
}
/** Get more bytes into buffer. Stop when endSequence is found. */
private void getMoreBytes() throws IOException {
currentOffset = 0; // reset current array offset to 0
int bytesRead = 0; // bytes read so far
int lookingFor = 0; // character in endSequence to look for
for(; bytesRead < lineBuf.length; bytesRead++) {
int c = in.read();
if (c == -1)
break; // break on EOL and return what we have so far
lineBuf[bytesRead] = (byte)c;
if (lineBuf[bytesRead] == endSequence[lookingFor]) {
lookingFor++;
if (lookingFor == endSequence.length) {
endFound = true;
break;
}
} else if (lineBuf[bytesRead] == endSequence[0]) { // CHANGED JC
lookingFor = 1;
} else {
lookingFor = 0;
}
}
bytesRemaining = bytesRead; // number of bytes we've read
}
/**
* Reads up to len bytes of data from this input stream into an array of
* bytes. This method blocks until some input is available.
*/
public int read(byte b[], int off, int len) throws IOException {
if (len <= 0) {
return 0;
}
int c = read();
if (c == -1)
return -1;
b[off] = (byte)c;
// We've read one byte successfully, let's try for more
int i = 1;
try {
for (; i < len ; i++) {
c = read();
if (c == -1) {
break;
}
b[off + i] = (byte)c;
}
} catch (IOException e) {
}
return i;
}
/** Skips over and discards n bytes of data from the input stream. */
public long skip(long n) {
if (bytesRemaining >= n) {
bytesRemaining -= n;
return n;
} else {
int oldBytesRemaining = bytesRemaining;
bytesRemaining = 0;
return oldBytesRemaining;
}
}
}