int
in the range 0
aoqi@0: * to 255
. If no byte is available because the end of
aoqi@0: * the stream has been reached, the value -1
is returned.
aoqi@0: * This method blocks until input data is available, the end of the
aoqi@0: * stream is detected, or an exception is thrown.
aoqi@0: *
aoqi@0: * @return the next byte of data, or -1
if the end of the
aoqi@0: * stream is reached.
aoqi@0: * @exception IOException if an I/O error occurs.
aoqi@0: */
aoqi@0: @Override
aoqi@0: public int read() throws IOException {
aoqi@0: if (spaces > 0) {
aoqi@0: // We have cached space characters, return one
aoqi@0: spaces--;
aoqi@0: return ' ';
aoqi@0: }
aoqi@0:
aoqi@0: int c = in.read();
aoqi@0:
aoqi@0: if (c == ' ') {
aoqi@0: // Got space, keep reading till we get a non-space char
aoqi@0: while ((c = in.read()) == ' ') {
aoqi@0: spaces++;
aoqi@0: }
aoqi@0:
aoqi@0: if (c == '\r' || c == '\n' || c == -1) {
aoqi@0: spaces = 0;
aoqi@0: } else {
aoqi@0: // The non-space char is NOT CR/LF, the spaces are valid.
aoqi@0: ((PushbackInputStream)in).unread(c);
aoqi@0: c = ' ';
aoqi@0: }
aoqi@0: return c; // return either len
decoded bytes of data from this input stream
aoqi@0: * into an array of bytes. This method blocks until some input is
aoqi@0: * available.
aoqi@0: *
aoqi@0: *
aoqi@0: * @param buf the buffer into which the data is read.
aoqi@0: * @param off the start offset of the data.
aoqi@0: * @param len the maximum number of bytes read.
aoqi@0: * @return the total number of bytes read into the buffer, or
aoqi@0: * -1
if there is no more data because the end of
aoqi@0: * the stream has been reached.
aoqi@0: * @exception IOException if an I/O error occurs.
aoqi@0: */
aoqi@0: @Override
aoqi@0: public int read(byte[] buf, int off, int len) throws IOException {
aoqi@0: int i, c;
aoqi@0: for (i = 0; i < len; i++) {
aoqi@0: if ((c = read()) == -1) {
aoqi@0: if (i == 0) {
aoqi@0: i = -1; // return -1 , NOT 0.
aoqi@0: }
aoqi@0: break;
aoqi@0: }
aoqi@0: buf[off+i] = (byte)c;
aoqi@0: }
aoqi@0: return i;
aoqi@0: }
aoqi@0:
aoqi@0: /**
aoqi@0: * Skips over and discards n bytes of data from this stream.
aoqi@0: */
aoqi@0: @Override
aoqi@0: public long skip(long n) throws IOException {
aoqi@0: long skipped = 0;
aoqi@0: while (n-- > 0 && read() >= 0) {
aoqi@0: skipped++;
aoqi@0: }
aoqi@0: return skipped;
aoqi@0: }
aoqi@0:
aoqi@0: /**
aoqi@0: * Tests if this input stream supports marks. Currently this class
aoqi@0: * does not support marks
aoqi@0: */
aoqi@0: @Override
aoqi@0: public boolean markSupported() {
aoqi@0: return false;
aoqi@0: }
aoqi@0:
aoqi@0: /**
aoqi@0: * Returns the number of bytes that can be read from this input
aoqi@0: * stream without blocking. The QP algorithm does not permit
aoqi@0: * a priori knowledge of the number of bytes after decoding, so
aoqi@0: * this method just invokes the available
method
aoqi@0: * of the original input stream.
aoqi@0: */
aoqi@0: @Override
aoqi@0: public int available() throws IOException {
aoqi@0: // This is bogus ! We don't really know how much
aoqi@0: // bytes are available *after* decoding
aoqi@0: return in.available();
aoqi@0: }
aoqi@0:
aoqi@0: /**** begin TEST program
aoqi@0: public static void main(String argv[]) throws Exception {
aoqi@0: FileInputStream infile = new FileInputStream(argv[0]);
aoqi@0: QPDecoderStream decoder = new QPDecoderStream(infile);
aoqi@0: int c;
aoqi@0:
aoqi@0: while ((c = decoder.read()) != -1)
aoqi@0: System.out.print((char)c);
aoqi@0: System.out.println();
aoqi@0: }
aoqi@0: *** end TEST program ****/
aoqi@0: }