You are viewing a plain text version of this content. The canonical link for it is here.
Posted to slide-dev@jakarta.apache.org by re...@apache.org on 2001/04/14 04:11:38 UTC

cvs commit: jakarta-slide/src/webdav/client/src/org/apache/webdav/lib ResponseInputStream.java

remm        01/04/13 19:11:38

  Modified:    src/webdav/client/src/org/apache/webdav/lib
                        ResponseInputStream.java
  Log:
  - New buffered response stream, based on the one used in Catalina.
  
  Revision  Changes    Path
  1.8       +136 -89   jakarta-slide/src/webdav/client/src/org/apache/webdav/lib/ResponseInputStream.java
  
  Index: ResponseInputStream.java
  ===================================================================
  RCS file: /home/cvs/jakarta-slide/src/webdav/client/src/org/apache/webdav/lib/ResponseInputStream.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- ResponseInputStream.java	2001/04/13 01:39:17	1.7
  +++ ResponseInputStream.java	2001/04/14 02:11:38	1.8
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-slide/src/webdav/client/src/org/apache/webdav/lib/ResponseInputStream.java,v 1.7 2001/04/13 01:39:17 remm Exp $
  - * $Revision: 1.7 $
  - * $Date: 2001/04/13 01:39:17 $
  + * $Header: /home/cvs/jakarta-slide/src/webdav/client/src/org/apache/webdav/lib/ResponseInputStream.java,v 1.8 2001/04/14 02:11:38 remm Exp $
  + * $Revision: 1.8 $
  + * $Date: 2001/04/14 02:11:38 $
    *
    * ====================================================================
    *
  @@ -74,7 +74,7 @@
    * Socket input stream wrapper.
    *
    * @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
  - * @version $Revision: 1.7 $ $Date: 2001/04/13 01:39:17 $
  + * @version $Revision: 1.8 $ $Date: 2001/04/14 02:11:38 $
    */
   
   public class ResponseInputStream
  @@ -107,7 +107,8 @@
               (Header) responseHeaders.get("content-length");
           if (contentLength != null) {
               try {
  -                length = Integer.parseInt(contentLength.getValue());
  +                this.contentLength = 
  +                    Integer.parseInt(contentLength.getValue());
               } catch (NumberFormatException e) {
               }
           }
  @@ -147,19 +148,19 @@
       /**
        * Chunk buffer.
        */
  -    protected byte[] chunkBuffer = null;
  +    protected byte[] buffer = null;
   
   
       /**
        * Chunk length.
        */
  -    protected int chunkLength = 0;
  +    protected int length = 0;
   
   
       /**
        * Chunk buffer position.
        */
  -    protected int chunkPos = 0;
  +    protected int pos = 0;
   
   
       /**
  @@ -172,7 +173,7 @@
        * The content length past which we will not read, or -1 if there is
        * no defined content length.
        */
  -    protected int length = -1;
  +    protected int contentLength = -1;
   
   
       /**
  @@ -234,6 +235,41 @@
   
   
       /**
  +     * Read up to <code>len</code> bytes of data from the input stream
  +     * into an array of bytes.  An attempt is made to read as many as
  +     * <code>len</code> bytes, but a smaller number may be read,
  +     * possibly zero.  The number of bytes actually read is returned as
  +     * an integer.  This method blocks until input data is available,
  +     * end of file is detected, or an exception is thrown.
  +     *
  +     * @param b The buffer into which the data is read
  +     * @param off The start offset into array <code>b</code> at which
  +     *  the data is written
  +     * @param len The maximum number of bytes to read
  +     *
  +     * @exception IOException if an input/output error occurs
  +     */
  +    public int read(byte b[], int off, int len) throws IOException {
  +
  +        int avail = length - pos;
  +        if ((avail == 0) && (!fillBuffer()))
  +            return (-1);
  +
  +        avail = length - pos;
  +        if (avail == 0)
  +            return (-1);
  +        
  +        int toCopy = avail;
  +        if (avail > len)
  +            toCopy = len;
  +        System.arraycopy(buffer, pos, b, off, toCopy);
  +        pos += toCopy;
  +        return toCopy;
  +
  +    }
  +
  +
  +    /**
        * Read and return a single byte from this input stream, or -1 if end of
        * file has been encountered.
        *
  @@ -242,106 +278,117 @@
       public int read()
           throws IOException {
   
  -        // Has this stream been closed?
  -        if (closed)
  -            throw new IOException("Stream is closed");
  +        if (pos == length) {
  +            if (!fillBuffer())
  +                return (-1);
  +        }
   
  -        if (endChunk)
  -            return (-1);
  +        return (buffer[pos++] & 0xff);
  +        
  +    }
   
  -        if (chunk) {
   
  -            if ((chunkBuffer == null)
  -                || (chunkPos == chunkLength)) {
  +    // -------------------------------------------------------- Private Methods
   
  -                chunkPos = 0;
   
  -                try {
  -                    String line = readLine();
  -                    if (line != null)
  -                        chunkLength = Integer.parseInt(line.trim(), 16);
  -                    else
  -                        chunkLength = 0;
  -                } catch (NumberFormatException e) {
  -                    // Critical error, unable to parse the chunk length
  -                    chunkLength = 0;
  -                    chunk = false;
  -                    close();
  -                    return -1;
  -                }
  +    /**
  +     * Fill the chunk buffer.
  +     */
  +    private boolean fillBuffer() 
  +        throws IOException {
  +        
  +        // Has this stream been closed?
  +        if (closed)
  +            return false;
  +            //throw new IOException("Stream is closed");
   
  -                if (chunkLength == 0) {
  +        if (endChunk)
  +            return false;
   
  -                    // TODO : Parse the trailing headers, if any
  -                    readLine();
  -                    endChunk = true;
  -                    return (-1);
  -                    // TODO : Should the stream be automatically closed ?
  -
  -                } else {
  -
  -                    if ((chunkBuffer == null)
  -                        || (chunkLength > chunkBuffer.length))
  -                        chunkBuffer = new byte[chunkLength];
  -
  -                    // Now read the whole chunk into the buffer
  -
  -                    int nbRead = 0;
  -                    int currentRead = 0;
  -
  -                    while (nbRead < chunkLength) {
  -                        currentRead =
  -                            stream.read(chunkBuffer, nbRead,
  -                                        chunkLength - nbRead);
  -                        if (currentRead == -1)
  -                            throw new IOException("Unexpected end of stream");
  -                        nbRead += currentRead;
  -                    }
  +        // Have we read the specified content length already?
  +        if ((contentLength >= 0) && (count >= contentLength))
  +            return false;    // End of file indicator
   
  -                    if (interceptors != null) {
  -                        for (int i = 0; i < interceptors.length; i++) {
  -                            interceptors[i].bytesRead
  -                                (chunkBuffer, 0, chunkLength);
  -                        }
  +        pos = 0;
  +        
  +        if (chunk) {
  +            
  +            try {
  +                String numberValue = readLineFromStream().trim();
  +                length = Integer.parseInt(numberValue, 16);
  +            } catch (NumberFormatException e) {
  +                // Critical error, unable to parse the chunk length
  +                length = 0;
  +                chunk = false;
  +                close();
  +                return false;
  +            }
  +            
  +            if (length == 0) {
  +                
  +                // Skipping trailing headers, if any
  +                String trailingLine = readLineFromStream();
  +                while (!trailingLine.equals(""))
  +                    trailingLine = readLineFromStream();
  +                endChunk = true;
  +                return false;
  +                
  +            } else {
  +                
  +                if ((buffer == null)
  +                    || (length > buffer.length))
  +                    buffer = new byte[length];
  +                
  +                // Now read the whole chunk into the buffer
  +                
  +                int nbRead = 0;
  +                int currentRead = 0;
  +                
  +                while (nbRead < length) {
  +                    try {
  +                        currentRead = 
  +                            stream.read(buffer, nbRead, 
  +                                        length - nbRead);
  +                    } catch (Throwable t) {
  +                        t.printStackTrace();
  +                        throw new IOException();
                       }
  -
  -                    // Skipping the CRLF
  -                    stream.read();
  -                    stream.read();
  -
  +                    if (currentRead < 0) {
  +                        throw new IOException("Not enough bytes read");
  +                    }
  +                    nbRead += currentRead;
                   }
  -
  +                
  +                // Skipping the CRLF
  +                String blank = readLineFromStream();
  +                
               }
   
  -            return (chunkBuffer[chunkPos++]);
  -
           } else {
   
  -            // Have we read the specified content length already?
  -            if ((length >= 0) && (count >= length))
  -                return (-1);    // End of file indicator
  -
  -            // Read and count the next byte, then return it
  -            int b = stream.read();
  -
  -            if (interceptors != null) {
  -                for (int i = 0; i < interceptors.length; i++) {
  -                    interceptors[i].bytesRead(null, b, 1);
  -                }
  +            try {
  +                if (buffer == null)
  +                    buffer = new byte[4096];
  +                length = stream.read(buffer);
  +                count += length;
  +            } catch (Throwable t) {
  +                t.printStackTrace();
  +                throw new IOException();
               }
   
  -            if (b >= 0)
  -                count++;
  -            return (b);
  -
           }
  +        
  +        if (interceptors != null) {
  +            for (int i = 0; i < interceptors.length; i++) {
  +                interceptors[i].bytesRead(buffer, 0, length);
  +            }
  +        }
   
  +        return true;
  +        
       }
   
   
  -    // -------------------------------------------------------- Private Methods
  -
  -
       /**
        * Reads the input stream, one line at a time. Reads bytes into an array,
        * until it reads a certain number of bytes or reaches a newline character,
  @@ -352,7 +399,7 @@
        *  was encountered
        * @exception IOException   if an input or output exception has occurred
        */
  -    private String readLine()
  +    private String readLineFromStream()
           throws IOException {
   
           StringBuffer sb = new StringBuffer();