⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 protocol.java

📁 用于移动设备上的java虚拟机源代码
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
        /**     * Reads up to <code>len</code> bytes of data from the input stream into     * an array of bytes.     * This method reads NonChunked http connection input streams.     * This method can only be called after the InputStream setup is complete.     *     * @param      b     the buffer into which the data is read.     * @param      off   the start offset in array <code>b</code>     *                   at which the data is written.     * @param      len   the maximum number of bytes to read.     * @return     the total number of bytes read into the buffer, or     *             <code>-1</code> if there is no more data because the end of     *             the stream has been reached.     * @exception  IOException  if an I/O error occurs.     */    protected int readBytes(byte b[], int off, int len)        throws IOException {        int rc;                /*         * Be consistent about returning EOF once encountered.         */        if (eof) {            return (-1);        }        /*         * The InputStream close behavior will be different if close is called         * from another thread when reading.         */        synchronized (streamInput) {            readInProgress = true;        }        try {            /*             * If the http connection is chunked, call the readBytesChunked             * method             */            if (chunkedIn || chunksize > 0) {                /*                 * Non-chunked data of known length is treated as one big chunk                 */                return readBytesChunked(b, off, len);            }            /*             * Non-chunked unknown length             */            if (bytesleft == 0) {                /*                 * the internal input stream buffer is empty, read from the                 * stream                 */                if (len >= inputBufferSize) {                    /*                     * No need to buffer, if the caller has given a big buffer.                     */                    rc = streamInput.read(b, off, len);                } else {                    rc = streamInput.read(readbuf, 0, inputBufferSize);                    bytesleft = rc;                    bytesread = 0;                }                if (rc == -1) {                    /*                     * The next call to this method should not read.                     */                    eof = true;                    return -1;                }                totalbytesread += rc;                if (bytesleft == 0) {                    /*                     * The data was read directly into the caller's buffer.                     */                    return rc;                }            }            rc = readFromBuffer(b, off, len);            return rc;        } finally {            synchronized (streamInput) {                readInProgress = false;            }        }    }        /**     * Reads up to <code>len</code> bytes of data from the internal buffer into     * an array of bytes.     *     * @param      b     the buffer into which the data is read.     * @param      off   the start offset in array <code>b</code>     *                   at which the data is written.     * @param      len   the maximum number of bytes to read.     * @return     the total number of bytes read into the buffer, or     *             <code>-1</code> if there is no more data because the end of     *             the stream has been reached.     * @exception  IOException  if an I/O error occurs.     */    private int readFromBuffer(byte b[], int off, int len)        throws IOException {                /*         * copy http buffer data into user buffer, then         * increment and decrement counters         */                int rc;        if (len > bytesleft) {            rc = bytesleft;        } else {            rc = len;                    }        System.arraycopy(readbuf, bytesread, b, off, rc);        bytesleft -= rc;        bytesread += rc;                return rc;    }    /**     * Returns the number of bytes that can be read (or skipped over) from     * this input stream without blocking by the next caller of a method for     * this input stream.  The next caller might be the same thread or     * another thread.     *     * @return     the number of bytes that can be read from this input stream     *             without blocking.     * @exception  IOException  if an I/O error occurs.     */    public int available() throws IOException {        int bytesAvailable;        /*          * Only after all the headers have been processed can         * an accurate available count be provided.         */        if (!requestFinished || eof) {            return 0;        }        /*         * Regardless of chunked or non-chunked transfers -         * if data is already buffered return the amount          * buffered.         */        if (bytesleft > 0) {             return bytesleft;         }                        if (chunkedIn && totalbytesread == chunksize) {             /*              * Check if a new chunk size header is available.             */            return readChunkSizeNonBlocking();        }         /*         * Otherwise rely on the lower level stream available         * count for the nonchunked input stream.         */        bytesAvailable =  streamInput.available();        if (chunksize <= bytesAvailable) {            return chunksize;        }        return bytesAvailable;    }    /**      * Read a chunk size header into the readLine buffer     * without blocking. The stringbuffer is populated     * with characters one at a time. This routine is design     * so that a partial chunk size header could be read     * and then completed by a blocking read of the chunk      * or a subsequent call to available.     *     * @return available data that can be read     */    int readChunkSizeNonBlocking() throws IOException {        /*         * Check the underlying stream to see how many bytes are         * available. Do not read beyond the available characters,         * because that would block.         */        int len = streamInput.available();                /* Reset the last character from the current readLine buffer. */        int sblen = stringbuffer.length();        char lastchar = '\0';        if (sblen > 0) {            lastchar = stringbuffer.charAt(sblen - 1);        }        int size = -1;        /*         * Loop through the available characters until a full          * chunk size header is in the readLine buffer.         */        for (; len > 0; len--) {            char c = (char) streamInput.read();                        if (lastchar == '\r' && c == '\n') {                // remove the '\r' from the buffer                stringbuffer.setLength(stringbuffer.length() - 1);                if (stringbuffer.length() > 0) {                    // this is a size, not the CRLF at the end of a chunk                    try {                        String temp = stringbuffer.toString();                        int semi = temp.indexOf(';');                        // skip extensions                        if (semi > 0) {                            temp = temp.substring(0, semi);                        }                        /*                         * Reset the string buffer length so readline() will                         * not parse this line.                         */                        stringbuffer.setLength(0);                        size = Integer.parseInt(temp, 16);                    } catch (NumberFormatException nfe) {                        throw new IOException(                            "invalid chunk size number format");                    }                    break;                }            } else {                stringbuffer.append(c);                lastchar = c;            }        }                if (size < 0) {            // did not get the size            return 0;        }        /*         * Update the chunksize and the total bytes that have been         * read from the chunk. This will trigger the next call to         * readBytes to refill the buffers as needed.         */        chunksize = size;        if (size == 0) {            eof = true;            return 0;        }                totalbytesread = 0;        /*         * If the full chunk is available, return chunksize,         * otherwise return the remainder of the available         * bytes (e.g. partial chunk).         */        return (chunksize < len ? chunksize : len);            }        /**     * Reads up to <code>len</code> bytes of data from the input stream into     * an array of bytes.     * This method reads Chunked and known length non-chunked http connection     * input streams. For non-chunked set the field <code>chunkedIn</code>     * should be false.     *     * @param      b     the buffer into which the data is read.     * @param      off   the start offset in array <code>b</code>     *                   at which the data is written.     * @param      len   the maximum number of bytes to read.     * @return     the total number of bytes read into the buffer, or     *             <code>-1</code> if there is no more data because the end of     *             the stream has been reached.     * @exception  IOException  if an I/O error occurs.     */    protected int readBytesChunked(byte b[], int off, int len)        throws IOException {        int rc;        if (bytesleft == 0) {            /*             * the internal input stream buffer is empty, read from the stream             */            if (totalbytesread == chunksize) {                /*                 * read the end of the chunk and get the size of the                 * the next if there is one                 */                if (!chunkedIn) {                    /*                     * non-chucked data is treated as one big chunk so there                     * is no more data so just return as if there are no                     * more chunks                     */                    eof = true;                    return -1;                }                skipEndOfChunkCRLF();                chunksize = readChunkSize();                if (chunksize == 0) {                    eof = true;                    /*                     * REFERENCE: HTTP1.1 document                      * SECTION: 3.6.1 Chunked Transfer Coding                     * in some cases there may be an OPTIONAL trailer                     * containing entity-header fields. since we don't support                     * the available() method for TCP socket input streams and                     * for performance and reuse reasons we do not attempt to                     * clean up the current connections input stream.                      * check readResponseMessage() method in this class for                     * more details                     */                    return -1;                }                /*                 * we have not read any bytes from this new chunk                 */                totalbytesread = 0;            }            int bytesToRead = chunksize - totalbytesread;            if (len >= bytesToRead) {                /*                 * No need to buffer, if the caller has given a big buffer.                 */                rc = streamInput.read(b, off, bytesToRead);            } else if (len >= inputBufferSize) {                /*                 * No need to buffer, if the caller has given a big buffer.                 */                rc = streamInput.read(b, off, len);            } else {                if (inputBufferSize >= bytesToRead) {                    rc = streamInput.read(readbuf, 0, bytesToRead);                } else {                    rc = streamInput.read(readbuf, 0, inputBufferSize);                }                bytesleft = rc;                bytesread = 0;            }            if (rc == -1) {                /*                 * Network problem or the wrong length was sent by the server.                 */                eof = true;                throw new IOException("unexpected end of stream");            }            totalbytesread += rc;            if (bytesleft == 0) {                /*                 * The data was read directly into the caller's buffer.                 */                return rc;            }        }        rc = readFromBuffer(b, off, len);        return rc;    }    /**      * Read the chunk size from the input.     * It is a hex length followed by optional headers (ignored).     * and terminated with CRLF.     *     * @return size of the buffered read     */    private int readChunkSize() throws IOException {        int size = -1;        try {            String chunk = null;            try {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -