responsestream.java
来自「jtds的源码 是你学习java的好东西」· Java 代码 · 共 515 行 · 第 1/2 页
JAVA
515 行
// jTDS JDBC Driver for Microsoft SQL Server and Sybase
// Copyright (C) 2004 The jTDS Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
package net.sourceforge.jtds.jdbc;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.io.UnsupportedEncodingException;
import net.sourceforge.jtds.util.*;
/**
* Implements an input stream for the server response.
* <p/>
* Implementation note:
* <ol>
* <li>This class contains methods to read different types of data from the
* server response stream in TDS format.
* <li>Character translation of String items is carried out.
* </ol>
*
* @author Mike Hutchinson.
* @version $Id: ResponseStream.java,v 1.20 2005/10/27 13:22:33 alin_sinpalean Exp $
*/
public class ResponseStream {
/** The shared network socket. */
private final SharedSocket socket;
/** The Input packet buffer. */
private byte[] buffer;
/** The offset of the next byte to read. */
private int bufferPtr;
/** The length of current input packet. */
private int bufferLen;
/** The unique stream id. */
private final int streamId;
/** True if stream is closed. */
private boolean isClosed;
/** A shared byte buffer. */
private final byte[] byteBuffer = new byte[255];
/** A shared char buffer. */
private final char[] charBuffer = new char[255];
/**
* Constructs a <code>RequestStream</code> object.
*
* @param socket the shared socket object to write to
* @param streamId the unique id for this stream (from ResponseStream)
* @param bufferSize the initial buffer size
*/
ResponseStream(SharedSocket socket, int streamId, int bufferSize){
this.streamId = streamId;
this.socket = socket;
this.buffer = new byte[bufferSize];
this.bufferLen = bufferSize;
this.bufferPtr = bufferSize;
}
/**
* Retrieves the unique stream id.
*
* @return the unique stream id as an <code>int</code>
*/
int getStreamId() {
return this.streamId;
}
/**
* Retrieves the next input byte without reading forward.
*
* @return the next byte in the input stream as an <code>int</code>
* @throws IOException if an I/O error occurs
*/
int peek() throws IOException {
int b = read();
bufferPtr--; // Backup one
return b;
}
/**
* Reads the next input byte from the server response stream.
*
* @return the next byte in the input stream as an <code>int</code>
* @throws IOException if an I/O error occurs
*/
int read() throws IOException {
if (bufferPtr >= bufferLen) {
getPacket();
}
return (int) buffer[bufferPtr++] & 0xFF;
}
/**
* Reads a byte array from the server response stream.
*
* @param b the byte array to read into
* @return the number of bytes read as an <code>int</code>
* @throws IOException if an I/O error occurs
*/
int read(byte[] b) throws IOException {
return read(b, 0, b.length);
}
/**
* Reads a byte array from the server response stream, specifying a start
* offset and length.
*
* @param b the byte array
* @param off the starting offset in the array
* @param len the number of bytes to read
* @return the number of bytes read as an <code>int</code>
* @throws IOException if an I/O error occurs
*/
int read(byte[] b, int off, int len) throws IOException {
int bytesToRead = len;
while (bytesToRead > 0) {
if (bufferPtr >= bufferLen) {
getPacket();
}
int available = bufferLen - bufferPtr;
int bc = (available > bytesToRead) ? bytesToRead : available;
System.arraycopy(buffer, bufferPtr, b, off, bc);
off += bc;
bytesToRead -= bc;
bufferPtr += bc;
}
return len;
}
/**
* Reads a char array from the server response stream.
*
* @param c the char array
* @return the byte array as a <code>byte[]</code>
* @throws IOException if an I/O error occurs
*/
int read(char[] c) throws IOException {
for (int i = 0; i < c.length; i++) {
if (bufferPtr >= bufferLen) {
getPacket();
}
int b1 = buffer[bufferPtr++] & 0xFF;
if (bufferPtr >= bufferLen) {
getPacket();
}
int b2 = buffer[bufferPtr++] << 8;
c[i] = (char) (b2 | b1);
}
return c.length;
}
/**
* Reads a <code>String</code> object from the server response stream. If
* the TDS protocol version is 4.2 or 5.0 decode the string use the default
* server charset, otherwise use UCS2-LE (Unicode).
*
* @param len the length of the string to read <b>in bytes</b> in the case
* of TDS 4.2/5.0 and <b>in characters</b> for TDS 7.0+
* (UCS2-LE encoded strings)
* @return the result as a <code>String</code>
* @throws IOException if an I/O error occurs
*/
String readString(int len) throws IOException {
if (socket.getTdsVersion() >= Driver.TDS70) {
return readUnicodeString(len);
}
return readNonUnicodeString(len);
}
/**
* Skips a <code>String</code> from the server response stream. If the TDS
* protocol version is 4.2 or 5.0 <code>len</code> is the length in bytes,
* otherwise it's the length in UCS2-LE characters (length in bytes == 2 *
* <code>len</code>).
*
* @param len the length of the string to skip <b>in bytes</b> in the case
* of TDS 4.2/5.0 and <b>in characters</b> for TDS 7.0+
* (UCS2-LE encoded strings)
* @throws IOException if an I/O error occurs
*/
void skipString(int len) throws IOException {
if (len <= 0) {
return;
}
if (socket.getTdsVersion() >= Driver.TDS70) {
skip(len * 2);
} else {
skip(len);
}
}
/**
* Reads a UCS2-LE (Unicode) encoded String object from the server response
* stream.
*
* @param len the length of the string to read <b>in characters</b>
* @return the result as a <code>String</code>
* @throws IOException if an I/O error occurs
*/
String readUnicodeString(int len) throws IOException {
char[] chars = (len > charBuffer.length) ? new char[len] : charBuffer;
for (int i = 0; i < len; i++) {
if (bufferPtr >= bufferLen) {
getPacket();
}
int b1 = buffer[bufferPtr++] & 0xFF;
if (bufferPtr >= bufferLen) {
getPacket();
}
int b2 = buffer[bufferPtr++] << 8;
chars[i] = (char) (b2 | b1);
}
return new String(chars, 0, len);
}
/**
* Reads a non Unicode <code>String</code> from the server response stream,
* creating the <code>String</code> from a translated <code>byte</code>
* array.
*
* @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) throws IOException {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?