responsestream.java

来自「jtds的源码 是你学习java的好东西」· Java 代码 · 共 515 行 · 第 1/2 页

JAVA
515
字号
        CharsetInfo info = socket.getCharsetInfo();

        return readString(len, info);
    }

    /**
     * Reads a <code>String</code> from the server response stream, translating
     * it from a <code>byte</code> array using the specified character set.
     *
     * @param len the length of the string to read <b>in bytes</b>
     * @return the result as a <code>String</code>
     * @throws IOException if an I/O error occurs
     */
    String readNonUnicodeString(int len, CharsetInfo charsetInfo)
            throws IOException {
        return readString(len, charsetInfo);
    }

    /**
     * Reads a <code>String</code> from the server response stream, creating
     * it from a translated <code>byte</code> array.
     *
     * @param len  the length of the string to read <b>in bytes</b>
     * @param info descriptor of the charset to use
     * @return the result as a <code>String</code>
     * @throws IOException if an I/O error occurs
     */
    String readString(int len, CharsetInfo info) throws IOException {
        String charsetName = info.getCharset();
        byte[] bytes = (len > byteBuffer.length) ? new byte[len] : byteBuffer;

        read(bytes, 0, len);

        try {
            return new String(bytes, 0, len, charsetName);
        } catch (UnsupportedEncodingException e) {
            return new String(bytes, 0, len);
        }
    }

    /**
     * Reads a <code>short</code> value from the server response stream.
     *
     * @return the result as a <code>short</code>
     * @throws IOException if an I/O error occurs
     */
    short readShort() throws IOException {
        int b1 = read();

        return (short) (b1 | (read() << 8));
    }

    /**
     * Reads an <code>int</code> value from the server response stream.
     *
     * @return the result as a <code>int</code>
     * @throws IOException if an I/O error occurs
     */
    int readInt() throws IOException {
        int b1 = read();
        int b2 = read() << 8;
        int b3 = read() << 16;
        int b4 = read() << 24;

        return b4 | b3 | b2 | b1;
    }

    /**
     * Reads a <code>long</code> value from the server response stream.
     *
     * @return the result as a <code>long</code>
     * @throws IOException if an I/O error occurs
     */
    long readLong() throws IOException {
        long b1 = ((long) read());
        long b2 = ((long) read()) << 8;
        long b3 = ((long) read()) << 16;
        long b4 = ((long) read()) << 24;
        long b5 = ((long) read()) << 32;
        long b6 = ((long) read()) << 40;
        long b7 = ((long) read()) << 48;
        long b8 = ((long) read()) << 56;

        return b1 | b2 | b3 | b4 | b5 | b6 | b7 | b8;
    }

    /**
     * Reads an <code>unsigned long</code> value from the server response stream.
     *
     * @return the result as a <code>BigDecimal</code>
     * @throws IOException if an I/O error occurs
     */
    BigDecimal readUnsignedLong() throws IOException {
        int  b1 = ((int) read() & 0xFF);
        long b2 = ((long) read());
        long b3 = ((long) read()) << 8;
        long b4 = ((long) read()) << 16;
        long b5 = ((long) read()) << 24;
        long b6 = ((long) read()) << 32;
        long b7 = ((long) read()) << 40;
        long b8 = ((long) read()) << 48;
        // Convert via String as BigDecimal(long) is actually BigDecimal(double)
        // on older versions of java
        return new BigDecimal(Long.toString(b2 | b3 | b4 | b5 | b6 | b7 | b8))
                        .multiply(new BigDecimal(256))
                        .add(new BigDecimal(b1));
    }

    /**
     * Discards bytes from the server response stream.
     *
     * @param skip the number of bytes to discard
     * @return the number of bytes skipped
     */
    int skip(int skip) throws IOException {
        int tmp = skip;

        while (skip > 0) {
            if (bufferPtr >= bufferLen) {
                getPacket();
            }

            int available = bufferLen - bufferPtr;

            if (skip > available) {
                skip -= available;
                bufferPtr = bufferLen;
            } else {
                bufferPtr += skip;
                skip = 0;
            }
        }

        return tmp;
    }

    /**
     * Consumes the rest of the server response, without parsing it.
     * <p/>
     * <b>Note:</b> Use only in extreme cases, packets will not be parsed and
     * could leave the connection in an inconsistent state.
     */
    void skipToEnd() {
        try {
            // No more data to read.
            bufferPtr = bufferLen;
            // Now consume all data until we get an exception.
            while (true) {
                buffer = socket.getNetPacket(streamId, buffer);
            }
        } catch (IOException ex) {
            // Ignore it. Probably no more packets.
        }
    }

    /**
     * Closes this response stream. The stream id is unlinked from the
     * underlying shared socket as well.
     */
    void close() {
        isClosed = true;
        socket.closeStream(streamId);
    }

    /**
     * Retrieves the TDS version number.
     *
     * @return the TDS version as an <code>int</code>
     */
    int getTdsVersion() {
        return socket.getTdsVersion();
    }

    /**
     * Retrieves the server type.
     *
     * @return the server type as an <code>int</code>
     */
    int getServerType() {
        return socket.serverType;
    }

    /**
     * Creates a simple <code>InputStream</code> over the server response.
     * <p/>
     * This method can be used to obtain a stream which can be passed to
     * <code>InputStreamReader</code>s to assist in reading multi byte
     * character sets.
     *
     * @param len the number of bytes available in the server response
     * @return the <code>InputStream</code> built over the server response
     */
    InputStream getInputStream(int len) {
        return new TdsInputStream(this, len);
    }

    /**
     * Read the next TDS packet from the network.
     *
     * @throws IOException if an I/O error occurs
     */
    private void getPacket() throws IOException {
        while (bufferPtr >= bufferLen) {
            if (isClosed) {
                throw new IOException("ResponseStream is closed");
            }

            buffer = socket.getNetPacket(streamId, buffer);
            bufferLen = (((int) buffer[2] & 0xFF) << 8) | ((int) buffer[3] & 0xFF);
            bufferPtr = TdsCore.PKT_HDR_LEN;

            if (Logger.isActive()) {
                Logger.logPacket(streamId, true, buffer);
            }
        }
    }

    /**
     * Simple inner class implementing an <code>InputStream</code> over the
     * server response.
     */
    private static class TdsInputStream extends InputStream {
        /** The underlying <code>ResponseStream</code>. */
        ResponseStream tds;
        /** The maximum amount of data to make available. */
        int maxLen;

        /**
         * Creates a <code>TdsInputStream</code> instance.
         *
         * @param tds    the underlying <code>ResponseStream</code>
         * @param maxLen the maximum amount of data that will be available
         */
        public TdsInputStream(ResponseStream tds, int maxLen) {
            this.tds = tds;
            this.maxLen = maxLen;
        }

        public int read() throws IOException {
            return (maxLen-- > 0)? tds.read(): -1;
        }

        public int read(byte[] bytes, int offset, int len) throws IOException {
            if (maxLen < 1) {
                return -1;
            } else {
                int bc = Math.min(maxLen, len);
                if (bc > 0) {
                    bc = tds.read(bytes, offset, bc);
                    maxLen -= (bc == -1) ? 0 : bc;
                }
                return bc;
            }
        }
    }
}

⌨️ 快捷键说明

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