📄 tdscomm.java
字号:
//
// Copyright 1998 CDS Networks, Inc., Medford Oregon
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. All advertising materials mentioning features or use of this software
// must display the following acknowledgement:
// This product includes software developed by CDS Networks, Inc.
// 4. The name of CDS Networks, Inc. may not be used to endorse or promote
// products derived from this software without specific prior
// written permission.
//
// THIS SOFTWARE IS PROVIDED BY CDS NETWORKS, INC. ``AS IS'' AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL CDS NETWORKS, INC. BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//
package com.internetcds.jdbc.tds;
import java.io.*;
import java.net.*;
import com.internetcds.util.HexDump;
import com.internetcds.util.Logger;
import java.sql.Timestamp;
/**
* Handle the communications for a Tds instance.
*
* @version $Id: TdsComm.java,v 1.1 2003/04/29 18:07:53 sinisa Exp $
* @author Craig Spannring
* @author Igor Petrovski
*/
public class TdsComm implements TdsDefinitions
{
public static final String cvsVersion = "$Id: TdsComm.java,v 1.1 2003/04/29 18:07:53 sinisa Exp $";
//Dusan
static int z = 0;
static final int headerLength = 8;
//
// The following constants are the packet types.
//
// They are the first databayte in the packet and
// define the type of data in that packet.
public static final byte QUERY = 1;
public static final byte LOGON = 2;
public static final byte PROC = 3;
public static final byte REPLY = 4;
public static final byte CANCEL = 6;
public static final byte LOGON70 = 16; // Added 2000-06-05
// The minimum packet length that a TDS implementation can support
// is 512 bytes. This implementation will not support packets longer
// than 512. This will simplify the connection negotiation.
//
// XXX Some future release of this driver should be modified to
// negotiate longer packet sizes with the DB server.
private static final int maxPacketLength = 4096;
// in and out are the sockets used for all communication with the
// server.
private DataOutputStream out = null;
private DataInputStream in = null;
// outBuffer is used to construct the physical packets that will
// be sent to the database server.
byte outBuffer[];
// nextOutBufferIndex is an index into outBuffer where the next
// byte of data will be stored while constructing a packet.
int nextOutBufferIndex = 0;
// The type of the TDS packet that is being constructed
// in outBuffer.
int packetType = 0;
// Place to store the incoming data from the DB server.
byte inBuffer[];
// index of next byte that will be 'read' from inBuffer
int inBufferIndex = 0;
// Total Number of bytes stored in inBuffer. (The number includes bytes
// that have been 'read' as well as bytes that still need to be 'read'.
int inBufferLen = 0;
// Track how many packets we have sent and received
int packetsSent = 0;
int packetsReceived = 0;
// For debuging purposes it would be nice to uniquely identify each Tds
// stream. id will be a unique value for each instance of this class.
static int id = 0;
// Added 2000-06-07. Used to control TDS version-specific behavior.
private int tdsVer = TDS42;
public TdsComm(Socket sock, int tdsVer_)
throws java.io.IOException
{
out = new DataOutputStream(sock.getOutputStream());
in = new DataInputStream(sock.getInputStream());
outBuffer = new byte[4096];
inBuffer = new byte[4096];
// Added 2000-06-07
tdsVer = tdsVer_;
id++;
}
public void close()
{
// nop for now.
}
/**
* start a TDS packet.
*
* <br>
* This method should be called to start a logical TDS packet.
*
* @param type Type of the packet. Can be QUERY, LOGON, PROC,
* REPLY, or CANCEL.
*/
public synchronized void startPacket(int type)
{
// Only one thread at a time can be building an outboudn packet.
// This is primarily a concern with building cancel packets.
while(someThreadIsBuildingPacket())
{
try
{
wait();
}
catch (java.lang.InterruptedException e)
{
// nop
}
}
packetType = type;
nextOutBufferIndex = headerLength;
}
/**
* Is some thread currently building a logical TDS packet?
*
* @return true iff a packet is being built.
*/
public boolean someThreadIsBuildingPacket()
{
return packetType!=0;
}
/**
* append a byte onto the end of the logical TDS packet.
*
* <p>
* Append a byte onto the end of the logical TDS packet. When a
* physical packet is full send it to the server.
*
* @param b byte to add to the TDS packet
*/
public void appendByte(byte b)
throws java.io.IOException
{
if (nextOutBufferIndex == maxPacketLength)
{
// If we have a full physical packet then ship it out to the
// network.
sendPhysicalPacket(false);
nextOutBufferIndex = headerLength;
}
storeByte(nextOutBufferIndex, b);
nextOutBufferIndex++;
} // appendByte()
/**
* append an array of bytes onto the end of the logical TDS packet.
*
* @param b bytes to add to the TDS packet
*/
public void appendBytes(byte[] b)
throws java.io.IOException
{
appendBytes(b, b.length, (byte)0);
} // appendBytes()
/**
* append an array of bytes onto the end of the logical TDS packet.
*
* @param b bytes to add to the TDS packet
* @param len maximum number of bytes to transmit
* @param pad fill with this byte until len is reached
*/
public void appendBytes(byte[] b, int len, byte pad)
throws java.io.IOException
{
int i = 0;
for (; i<b.length && i<len; i++)
{
appendByte(b[i]);
}
for (; i<len; i++)
{
appendByte(pad);
}
}
/**
* append a short int onto the end of the logical TDS packet.
* <p>
* @param s short int to add to the TDS packet
*/
public void appendShort(short s)
throws java.io.IOException
{
appendByte((byte)((s>>8)&0xff));
appendByte((byte)((s>>0)&0xff));
}
/**
* Appends a short int onto the end of the logical TDS packet.
* <p>
* @param s short int to add to the TDS packet
*/
public void appendTdsShort(short s)
throws java.io.IOException
{
appendByte((byte)((s>>0)&0xff));
appendByte((byte)((s>>8)&0xff));
}
/**
* append a Double onto the end of the logical TDS packet.
* <p>
* Append the Double value onto the end of the TDS packet as a
* SYBFLT8.
*
* @param value Double to add to the TDS packet
*/
public void appendFlt8(Double value)
throws java.io.IOException
{
long l = Double.doubleToLongBits(value.doubleValue());
appendByte((byte)((l>>0)&0xff));
appendByte((byte)((l>>8)&0xff));
appendByte((byte)((l>>16)&0xff));
appendByte((byte)((l>>24)&0xff));
appendByte((byte)((l>>32)&0xff));
appendByte((byte)((l>>40)&0xff));
appendByte((byte)((l>>48)&0xff));
appendByte((byte)((l>>56)&0xff));
}
public void appendInt(int i)
throws java.io.IOException
{
appendByte((byte)((i>>24)&0xff));
appendByte((byte)((i>>16)&0xff));
appendByte((byte)((i>>8)&0xff));
appendByte((byte)((i>>0)&0xff));
}
public void appendTdsInt(int i)
throws java.io.IOException
{
appendByte((byte)((i>>0)&0xff));
appendByte((byte)((i>>8)&0xff));
appendByte((byte)((i>>16)&0xff));
appendByte((byte)((i>>24)&0xff));
}
public void appendInt64(long i)
throws java.io.IOException
{
appendByte((byte)((i>>56)&0xff));
appendByte((byte)((i>>48)&0xff));
appendByte((byte)((i>>40)&0xff));
appendByte((byte)((i>>32)&0xff));
appendByte((byte)((i>>24)&0xff));
appendByte((byte)((i>>16)&0xff));
appendByte((byte)((i>>8)&0xff));
appendByte((byte)((i>>0)&0xff));
}
/**
* Appends the 16-bit characters from the caller's string, without
* narrowing the characters.
*
* Sybase let's the client decide what byte order to use but it \
* appears that SQLServer 7.0 little-endian byte order.
*
* Added 2000-06-05
*/
public void appendChars(String s) throws java.io.IOException {
for (int i = 0; i < s.length(); ++i) {
int c = s.charAt(i);
byte b1 = (byte)(c & 0xFF);
byte b2 = (byte)((c >> 8) & 0xFF);
appendByte(b1);
appendByte(b2);
}
}
/*
* Stefan Bodewig 2000-06-21
*
* removed appendString() to keep the encoding to and from the
* server charset in on place - i.e. Tds.
*
* It had to be Tds as we need to specify the length for the
* String as well, sometimes before we send the actual data,
* sometimes after we've sent them.
*
* If we need to know the length beforehand in Tds, we'd have to
* convert the data twice, once to get the length and once to send
* them.
*/
// public void appendString(
// String s,
// int length,
// byte pad)
// throws java.io.IOException
// {
// int i;
// byte dst[];
//
//
// dst = encoder.getBytes(s.substring(0, (length<=s.length() ? length
// : s.length())));
//
// for(i=0; i<dst.length; i++)
// {
// appendByte(dst[i]);
// }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -