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

📄 tdscomm.java

📁 Java写的TDS协议(JDBC/ODBC)实现
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
        }
    }


    /*
     *  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]);
//      }
//
//      for(; i<length; i++)
//      {
//         appendByte(pad);
//      }
//   }


    /**
     *  Send the logical packet. <p>
     *
     *  Send the logical packet the has been constructed.
     *
     *@exception  java.io.IOException  @todo Description of Exception
     */
    public synchronized void sendPacket()
             throws java.io.IOException
    {
        sendPhysicalPacket( true );
        nextOutBufferIndex = 0;
        packetType = 0;
        notify();
    }


    /**
     *  store a byte of data at a particular location in the outBuffer.
     *
     *@param  index  position in outBuffer to store data
     *@param  value  value to store in the outBuffer.
     */
    private void storeByte(
            int index,
            byte value )
    {
        outBuffer[index] = value;
    }


    /**
     *  store a short integer of data at a particular location in the outBuffer.
     *
     *@param  index  position in outBuffer to store data
     *@param  s      @todo Description of Parameter
     */
    private void storeShort(
            int index,
            short s )
    {
        outBuffer[index] = ( byte ) ( ( s >> 8 ) & 0xff );
        outBuffer[index + 1] = ( byte ) ( ( s >> 0 ) & 0xff );
    }


    /**
     *  send the data in the outBuffer. <p>
     *
     *  Fill in the TDS packet header data and send the data in outBuffer to the
     *  DB server.
     *
     *@param  isLastSegment            is this the last physical packet that
     *      makes up the physical packet?
     *@exception  java.io.IOException  @todo Description of Exception
     */
    private void sendPhysicalPacket( boolean isLastSegment )
             throws java.io.IOException
    {
        if ( nextOutBufferIndex > headerLength
                 || packetType == CANCEL ) {
            // packet type
            storeByte( 0, ( byte ) ( packetType & 0xff ) );
            storeByte( 1, isLastSegment ? ( byte ) 1 : ( byte ) 0 );
            storeShort( 2, ( short ) nextOutBufferIndex );
            storeByte( 4, ( byte ) 0 );
            storeByte( 5, ( byte ) 0 );
            storeByte( 6, ( byte ) ( tdsVer == TDS70 ? 1 : 0 ) );
            storeByte( 7, ( byte ) 0 );

            out.write( outBuffer, 0, nextOutBufferIndex );
            packetsSent++;

            if ( Logger.isActive() ) {
                String dump = HexDump.hexDump( outBuffer, nextOutBufferIndex );
                String t = ( new Timestamp(
                        System.currentTimeMillis() ) ).toString();
                Logger.println( "Instance " + id + " @ " + t
                         + " sent packet #" + packetsSent + "\n" + dump );
            }
        }
    }


    /**
     *  peek at the next byte of data. <p>
     *
     *  This returns the next byte of data that would be returned by getByte(),
     *  but does not actually consume the data. <b>Note-</b> We can't
     *  synchronize this method (or most of the other methods in this class)
     *  because of the way cancels are handled. If a thread is waiting for a
     *  response from the server the cancelController class must be able to call
     *  sendPacket() to cancel the request.
     *
     *@return                                            The next byte of data
     *      that will be returned by getByte()
     *@exception  net.sourceforge.jtds.jdbc.TdsException
     *@exception  java.io.IOException
     */
    public byte peek()
        throws net.sourceforge.jtds.jdbc.TdsException, java.io.IOException
    {
        // If out of data, read another physical packet.
        if( inBufferIndex >= inBufferLen )
            getPhysicalPacket();

        return inBuffer[inBufferIndex];
    }


    /**
     *  read a byte of data from the DB server. <p>
     *
     *  This will return the next byte of data from the DB server. <p>
     *
     *  <B>Warning</B> If there is not data available this method will block.
     *
     *@return                                            The Byte value
     *@exception  net.sourceforge.jtds.jdbc.TdsException  @todo Description of
     *      Exception
     *@exception  java.io.IOException                    @todo Description of
     *      Exception
     */
    public byte getByte()
             throws net.sourceforge.jtds.jdbc.TdsException,
            java.io.IOException
    {
        byte result;

        if ( inBufferIndex >= inBufferLen ) {
            // out of data, read another physical packet.
            getPhysicalPacket();
        }

        result = inBuffer[inBufferIndex++];
        return result;
    }

    /**
     * Reads and returns <code>len</code> bytes. If <code>exclusiveBuffer</code>
     * is <code>true</code>, a new buffer of that size will be allocated.
     * Otherwise, {@link resBuffer} will be used. Note that in this second case
     * the returned buffer will very likely have a larger size than the
     * number of bytes requested.
     */
    public byte[] getBytes(int len, boolean exclusiveBuffer)
        throws net.sourceforge.jtds.jdbc.TdsException, java.io.IOException
    {
        byte result[] = null;
        int i;

        // Do not keep an internal result buffer larger than 16k.
        // This would unnecessarily use up memory.
        if( exclusiveBuffer || len>16384 )
            result = new byte[len];
        else
        {
            if( resBuffer.length < len )
                resBuffer = new byte[len];
            result = resBuffer;
        }

        for( i=0; i<len; )
        {
            if( inBufferIndex >= inBufferLen )
                getPhysicalPacket();

            int avail = inBufferLen - inBufferIndex;
            avail = avail>len-i ? len-i : avail;

            System.arraycopy(inBuffer, inBufferIndex, result, i, avail);
            i += avail;
            inBufferIndex += avail;
        }

        return result;
    }


    /**
     *  Reads bytes or characters (depending on TDS version) and constructs a
     *  string with them. Sybase will let the client choose byte ordering, but
     *  SQLServer 7.0 wants little endian only. In the interest of simplicity,
     *  just use little endian regardless of the type of server. Added
     *  2000-06-05.
     *
     *@param  len                                        @todo Description of
     *      Parameter
     *@return                                            The String value
     *@exception  net.sourceforge.jtds.jdbc.TdsException  @todo Description of
     *      Exception
     *@exception  java.io.IOException                    @todo Description of
     *      Exception
     */
    public String getString( int len )
             throws net.sourceforge.jtds.jdbc.TdsException,
            java.io.IOException
    {
        if ( tdsVer == TDS70 ) {
            char[] chars = new char[len];
            for ( int i = 0; i < len; ++i ) {
                int lo = getByte() & 0xFF;
                int hi = getByte() & 0xFF;
                chars[i] = ( char ) ( lo | ( hi << 8 ) );
            }
            return new String( chars );
        }
        else {
            return new String( getBytes(len, false), 0, len );
        }
    }


    public void skip( int i )
             throws net.sourceforge.jtds.jdbc.TdsException,
            java.io.IOException
    {
        for ( ; i > 0; i-- ) {
            getByte();
        }
    }
    // skip()


    public int getNetShort()
             throws TdsException, java.io.IOException
    {
        byte tmp[] = new byte[2];
        tmp[0] = getByte();
        tmp[1] = getByte();
        return ntohs( tmp, 0 );
    }


    public int getTdsShort()
             throws net.sourceforge.jtds.jdbc.TdsException, java.io.IOException
    {
        int lo = ( ( int ) getByte() & 0xff );
        int hi = ( ( int ) getByte() & 0xff ) << 8;
        return lo | hi;
    }


    public int getTdsInt()
             throws net.sourceforge.jtds.jdbc.TdsException, java.io.IOException
    {
        int result;

        int b1 = ( ( int ) getByte() & 0xff );
        int b2 = ( ( int ) getByte() & 0xff ) << 8;
        int b3 = ( ( int ) getByte() & 0xff ) << 16;
        int b4 = ( ( int ) getByte() & 0xff ) << 24;

        result = b4 | b3 | b2 | b1;

        return result;
    }


    public long getTdsInt64()
             throws net.sourceforge.jtds.jdbc.TdsException, java.io.IOException
    {
        long b1 = ( ( long ) getByte() & 0xff );
        long b2 = ( ( long ) getByte() & 0xff ) << 8;
        long b3 = ( ( long ) getByte() & 0xff ) << 16;
        long b4 = ( ( long ) getByte() & 0xff ) << 24;
        long b5 = ( ( long ) getByte() & 0xff ) << 32;
        long b6 = ( ( long ) getByte() & 0xff ) << 40;
        long b7 = ( ( long ) getByte() & 0xff ) << 48;
        long b8 = ( ( long ) getByte() & 0xff ) << 56;
        return b1 | b2 | b3 | b4 | b5 | b6 | b7 | b8;
    }


    /**
     * Read a physical packet.<p>
     * <B>Warning</B> This method will block until it gets all of the input.
     * <p>
     * <b>Note:</b> This method should not be synchronized (at least not on
     * <code>this</code> object) because it would prevent us from sending
     * CANCEL packets, which are sent asynchronously.
     *
     * @exception  TdsException         @todo Description of Exception
     * @exception  java.io.IOException  @todo Description of Exception
     */
    private void getPhysicalPacket()
        throws TdsException, java.io.IOException
    {

        // read the header
        for ( int nread = 0; nread < 8;  ) {
            nread += in.read( tmpBuf, nread, 8 - nread );
        }

        if ( Logger.isActive() ) {
            String dump = net.sourceforge.jtds.util.HexDump.hexDump( tmpBuf, 8 );
            String t = ( new Timestamp(
                    System.currentTimeMillis() ) ).toString();

            Logger.println( "Instance " + id + " @ " + t
                     + " received header #" + ( packetsReceived + 1 )
                     + "\n" + dump );
        }

        byte packetType = tmpBuf[0];
        if ( packetType != LOGON
                 && packetType != QUERY
                 && packetType != REPLY ) {
            throw new TdsUnknownPacketType( packetType, tmpBuf );
        }

        // figure out how many bytes are remaining in this packet.
        int len = ntohs( tmpBuf, 2 ) - 8;

        // Added 2000-06-05
        if ( len >= inBuffer.length ) {
            inBuffer = new byte[len];
        }

        if ( len < 0 ) {
            throw new TdsException( "Confused by a length of " + len );
        }

        // now get the data
        for ( int nread = 0; nread < len;  ) {
            nread += in.read( inBuffer, nread, len - nread );
        }
        packetsReceived++;

        // adjust the bookkeeping info about the incoming buffer
        inBufferLen = len;
        inBufferIndex = 0;

        if ( Logger.isActive() ) {
            String dump = net.sourceforge.jtds.util.HexDump.hexDump( inBuffer, len );
            String t = ( new Timestamp(
                    System.currentTimeMillis() ) ).toString();

            Logger.println( "Instance " + id + " @ " + t
                     + " received data #" + ( packetsReceived )
                     + "\n" + dump );
        }
    }


    void resizeOutbuf( int newsize )
    {
        if ( newsize > outBufferLen ) {
            byte[] newBuf = new byte[newsize];
            System.arraycopy( outBuffer, 0, newBuf, 0, outBufferLen );
            outBufferLen = newsize;
            outBuffer = newBuf;
        }
    }


    /**
     *  convert two bytes in a byte array into a Java short integer.
     *
     *@param  buf     array of data
     *@param  offset  index into the buf array where the short integer is
     *      stored.
     *@return         @todo Description of the Returned Value
     */
    private static int ntohs( byte buf[], int offset )
    {
        int lo = ( ( int ) buf[offset + 1] & 0xff );
        int hi = ( ( ( int ) buf[offset] & 0xff ) << 8 );

        return hi | lo;
        // return an int since we really want an _unsigned_
    }
}

⌨️ 快捷键说明

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