Buffer.java
上传用户:sxlinghang
上传日期:2022-07-20
资源大小:1405k
文件大小:15k
源码类别:

数据库编程

开发平台:

Java

  1. /*
  2.    Copyright (C) 2002 MySQL AB
  3.       This program is free software; you can redistribute it and/or modify
  4.       it under the terms of the GNU General Public License as published by
  5.       the Free Software Foundation; either version 2 of the License, or
  6.       (at your option) any later version.
  7.       This program is distributed in the hope that it will be useful,
  8.       but WITHOUT ANY WARRANTY; without even the implied warranty of
  9.       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  10.       GNU General Public License for more details.
  11.       You should have received a copy of the GNU General Public License
  12.       along with this program; if not, write to the Free Software
  13.       Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  14.  */
  15. package com.mysql.jdbc;
  16. import java.io.UnsupportedEncodingException;
  17. import java.sql.SQLException;
  18. /**
  19.  * Buffer contains code to read and write packets from/to the MySQL server.
  20.  *
  21.  * @version $Id: Buffer.java,v 1.15.2.12 2004/01/07 01:36:34 mmatthew Exp $
  22.  * @author Mark Matthews
  23.  */
  24. class Buffer {
  25.     static final int NO_LENGTH_LIMIT = -1;
  26.     static final long NULL_LENGTH = -1;
  27.     private byte[] byteBuffer;
  28.     private boolean wasMultiPacket = false;
  29.     private int bufLength = 0;
  30.     private int position = 0;
  31.     private int sendLength = 0;
  32.     Buffer(byte[] buf) {
  33.         this.byteBuffer = buf;
  34.         setBufLength(buf.length);
  35.     }
  36.     Buffer(int size) {
  37.         this.byteBuffer = new byte[size];
  38.         setBufLength(this.byteBuffer.length);
  39.         this.position = MysqlIO.HEADER_LENGTH;
  40.     }
  41.     /**
  42.      * Sets the array of bytes to use as a buffer to read from.
  43.      *
  44.      * @param byteBuffer the array of bytes to use as a buffer
  45.      */
  46.     public void setByteBuffer(byte[] byteBuffer) {
  47.         this.byteBuffer = byteBuffer;
  48.     }
  49.     /**
  50.      * Returns the array of bytes this Buffer is using to read from.
  51.      *
  52.      * @return byte array being read from
  53.      */
  54.     public byte[] getByteBuffer() {
  55.         return this.byteBuffer;
  56.     }
  57.     /**
  58.      * Set the current position to write to/ read from
  59.      *
  60.      * @param position the position (0-based index)
  61.      */
  62.     public void setPosition(int position) {
  63.         this.position = position;
  64.     }
  65.     /**
  66.      * Returns the current position to write to/ read from
  67.      *
  68.      * @return the current position to write to/ read from
  69.      */
  70.     public int getPosition() {
  71.         return this.position;
  72.     }
  73.     /**
  74.      * Sets whether this packet was part of a multipacket
  75.      *
  76.      * @param flag was this packet part of a multipacket?
  77.      */
  78.     public void setWasMultiPacket(boolean flag) {
  79.         wasMultiPacket = flag;
  80.     }
  81.     /**
  82.      * Skip over a length-encoded string
  83.      *
  84.      * @return The position past the end of the string
  85.      */
  86.     public int fastSkipLenString() {
  87.         long len = this.readFieldLength();
  88.         position += len;
  89.         return (int) len; // this is safe, as this is only
  90.     }
  91.     /**
  92.      * Was this packet part of a multipacket?
  93.      *
  94.      * @return was this packet part of a multipacket?
  95.      */
  96.     public boolean wasMultiPacket() {
  97.         return wasMultiPacket;
  98.     }
  99.     protected final byte[] getBufferSource() {
  100.         return byteBuffer;
  101.     }
  102.     final byte[] getBytes(int len) {
  103.         byte[] b = new byte[len];
  104.         System.arraycopy(this.byteBuffer, this.position, b, 0, len);
  105.         this.position += len; // update cursor
  106.         return b;
  107.     }
  108.     // 2000-06-05 Changed
  109.     final boolean isLastDataPacket() {
  110.         return ((getBufLength() < 9) && ((this.byteBuffer[0] & 0xff) == 254));
  111.     }
  112.     final void clear() {
  113.         this.position = MysqlIO.HEADER_LENGTH;
  114.     }
  115.     final void dump() {
  116.      StringUtils.dumpAsHex(this.byteBuffer, getBufLength());
  117.     }
  118.     final void dumpHeader() {
  119.         for (int i = 0; i < MysqlIO.HEADER_LENGTH; i++) {
  120.             String hexVal = Integer.toHexString((int) this.byteBuffer[i] & 0xff);
  121.             if (hexVal.length() == 1) {
  122.                 hexVal = "0" + hexVal;
  123.             }
  124.             System.out.print(hexVal + " ");
  125.         }
  126.     }
  127.     final void dumpNBytes(int start, int nBytes) {
  128.         StringBuffer asciiBuf = new StringBuffer();
  129.         for (int i = start;
  130.                 (i < (start + nBytes)) && (i < this.byteBuffer.length); i++) {
  131.             String hexVal = Integer.toHexString((int) this.byteBuffer[i] & 0xff);
  132.             if (hexVal.length() == 1) {
  133.                 hexVal = "0" + hexVal;
  134.             }
  135.             System.out.print(hexVal + " ");
  136.             if ((this.byteBuffer[i] > 32) && (this.byteBuffer[i] < 127)) {
  137.                 asciiBuf.append((char) this.byteBuffer[i]);
  138.             } else {
  139.                 asciiBuf.append(".");
  140.             }
  141.             asciiBuf.append(" ");
  142.         }
  143.         System.out.println("    " + asciiBuf.toString());
  144.     }
  145.     final void ensureCapacity(int additionalData) throws SQLException {
  146.         if ((this.position + additionalData) > getBufLength()) {
  147.             if ((this.position + additionalData) < this.byteBuffer.length) {
  148.                 // byteBuffer.length is != getBufLength() all of the time
  149.                 // due to re-using of packets (we don't shrink them)
  150.                 //
  151.                 // If we can, don't re-alloc, just set buffer length 
  152.                 // to size of current buffer
  153.                 setBufLength(this.byteBuffer.length);
  154.             } else {
  155.                 //
  156.                 // Otherwise, re-size, and pad so we can avoid
  157.                 // allocing again in the near future
  158.                 //
  159.                 int newLength = (int) (this.byteBuffer.length * 1.25);
  160.                 if (newLength < (this.byteBuffer.length + additionalData)) {
  161.                     newLength = this.byteBuffer.length
  162.                         + (int) (additionalData * 1.25);
  163.                 }
  164.                 if (newLength < this.byteBuffer.length) {
  165.                     newLength = this.byteBuffer.length + additionalData;
  166.                 }
  167.                 byte[] newBytes = new byte[newLength];
  168.                 System.arraycopy(this.byteBuffer, 0, newBytes, 0,
  169.                     this.byteBuffer.length);
  170.                 this.byteBuffer = newBytes;
  171.                 setBufLength(this.byteBuffer.length);
  172.             }
  173.         }
  174.     }
  175.     final long newReadLength() {
  176.         int sw = this.byteBuffer[this.position++] & 0xff;
  177.         switch (sw) {
  178.         case 251:
  179.             return (long) 0;
  180.         case 252:
  181.             return (long) readInt();
  182.         case 253:
  183.             return (long) readLongInt();
  184.         case 254: // changed for 64 bit lengths
  185.             return (long) readLongLong();
  186.         default:
  187.             return (long) sw;
  188.         }
  189.     }
  190.     final byte readByte() {
  191.         return this.byteBuffer[this.position++];
  192.     }
  193.     final long readFieldLength() {
  194.         int sw = this.byteBuffer[this.position++] & 0xff;
  195.         switch (sw) {
  196.         case 251:
  197.             return NULL_LENGTH;
  198.         case 252:
  199.             return (long) readInt();
  200.         case 253:
  201.             return (long) readLongInt();
  202.         case 254:
  203.             return readLongLong();
  204.         default:
  205.             return (long) sw;
  206.         }
  207.     }
  208.     // 2000-06-05 Changed
  209.     final int readInt() {
  210.         byte[] b = this.byteBuffer; // a little bit optimization
  211.         return (b[this.position++] & 0xff) | ((b[this.position++] & 0xff) << 8);
  212.     }
  213.     final byte[] readLenByteArray(int offset) {
  214.         long len = this.readFieldLength();
  215.         if (len == NULL_LENGTH) {
  216.             return null;
  217.         }
  218.         if (len == 0) {
  219.             return new byte[0];
  220.         }
  221.         this.position += offset;
  222.         return getBytes((int) len);
  223.     }
  224.     final long readLength() {
  225.         int sw = this.byteBuffer[this.position++] & 0xff;
  226.         switch (sw) {
  227.         case 251:
  228.             return (long) 0;
  229.         case 252:
  230.             return (long) readInt();
  231.         case 253:
  232.             return (long) readLongInt();
  233.         case 254:
  234.             return (long) readLong();
  235.         default:
  236.             return (long) sw;
  237.         }
  238.     }
  239.     // 2000-06-05 Fixed
  240.     final long readLong() {
  241.         byte[] b = this.byteBuffer;
  242.         return (b[this.position++] & 0xff) | ((b[this.position++] & 0xff) << 8)
  243.         | ((b[this.position++] & 0xff) << 16)
  244.         | ((b[this.position++] & 0xff) << 24);
  245.     }
  246.     // 2000-06-05 Changed
  247.     final int readLongInt() {
  248.         byte[] b = this.byteBuffer;
  249.         return (b[this.position++] & 0xff) | ((b[this.position++] & 0xff) << 8)
  250.         | ((b[this.position++] & 0xff) << 16);
  251.     }
  252.     // 2000-06-05 Fixed
  253.     final long readLongLong() {
  254.         byte[] b = this.byteBuffer;
  255.         return (long) (b[this.position++] & 0xff)
  256.         | ((long) (b[this.position++] & 0xff) << 8)
  257.         | ((long) (b[this.position++] & 0xff) << 16)
  258.         | ((long) (b[this.position++] & 0xff) << 24)
  259.         | ((long) (b[this.position++] & 0xff) << 32)
  260.         | ((long) (b[this.position++] & 0xff) << 40)
  261.         | ((long) (b[this.position++] & 0xff) << 48)
  262.         | ((long) (b[this.position++] & 0xff) << 56);
  263.     }
  264.     //
  265.     // Read a null-terminated string
  266.     //
  267.     // To avoid alloc'ing a new byte array, we
  268.     // do this by hand, rather than calling getNullTerminatedBytes()
  269.     //
  270.     final String readString() {
  271.         int i = this.position;
  272.         int len = 0;
  273. int maxLen = getBufLength();
  274.         while ((i < maxLen) && (this.byteBuffer[i] != 0)) {
  275.             len++;
  276.             i++;
  277.         }
  278.         String s = new String(this.byteBuffer, this.position, len);
  279.         this.position += (len + 1); // update cursor
  280.         return s;
  281.     }
  282.     
  283.     final String readString(String encoding) throws SQLException {
  284. int i = this.position;
  285. int len = 0;
  286. int maxLen = getBufLength();
  287. while ((i < maxLen) && (this.byteBuffer[i] != 0)) {
  288. len++;
  289. i++;
  290. }
  291. this.position += (len + 1); // update cursor
  292. try {
  293. return new String(this.byteBuffer, this.position, len, encoding);
  294. } catch (UnsupportedEncodingException uEE) {
  295. throw new SQLException("Unsupported character encoding '" + encoding + "'", SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
  296. }
  297.     }
  298.     final int readnBytes() {
  299.         int sw = this.byteBuffer[this.position++] & 0xff;
  300.         switch (sw) {
  301.         case 1:
  302.             return this.byteBuffer[this.position++] & 0xff;
  303.         case 2:
  304.             return this.readInt();
  305.         case 3:
  306.             return this.readLongInt();
  307.         case 4:
  308.             return (int) this.readLong();
  309.         default:
  310.             return 255;
  311.         }
  312.     }
  313.     final void writeByte(byte b) throws SQLException {
  314.         ensureCapacity(1);
  315.         this.byteBuffer[this.position++] = b;
  316.     }
  317.     // Write a byte array
  318.     final void writeBytesNoNull(byte[] bytes) throws SQLException {
  319.         int len = bytes.length;
  320.         ensureCapacity(len);
  321.         System.arraycopy(bytes, 0, this.byteBuffer, this.position, len);
  322.         this.position += len;
  323.     }
  324.     // Write a byte array with the given offset and length
  325.     final void writeBytesNoNull(byte[] bytes, int offset, int length)
  326.         throws SQLException {
  327.         ensureCapacity(length);
  328.         System.arraycopy(bytes, offset, this.byteBuffer, this.position, length);
  329.         this.position += length;
  330.     }
  331.     final void writeDouble(double d) {
  332.         long l = Double.doubleToLongBits(d);
  333.         writeLongLong(l);
  334.     }
  335.     final void writeFloat(float f) {
  336.         int i = Float.floatToIntBits(f);
  337.         byte[] b = this.byteBuffer;
  338.         b[this.position++] = (byte) (i & 0xff);
  339.         b[this.position++] = (byte) (i >>> 8);
  340.         b[this.position++] = (byte) (i >>> 16);
  341.         b[this.position++] = (byte) (i >>> 24);
  342.     }
  343.     // 2000-06-05 Changed
  344.     final void writeInt(int i) {
  345.         byte[] b = this.byteBuffer;
  346.         b[this.position++] = (byte) (i & 0xff);
  347.         b[this.position++] = (byte) (i >>> 8);
  348.     }
  349.     // 2000-06-05 Changed
  350.     final void writeLong(long i) {
  351.         byte[] b = this.byteBuffer;
  352.         b[this.position++] = (byte) (i & 0xff);
  353.         b[this.position++] = (byte) (i >>> 8);
  354.         b[this.position++] = (byte) (i >>> 16);
  355.         b[this.position++] = (byte) (i >>> 24);
  356.     }
  357.     // 2000-06-05 Changed
  358.     final void writeLongInt(int i) {
  359.         byte[] b = this.byteBuffer;
  360.         b[this.position++] = (byte) (i & 0xff);
  361.         b[this.position++] = (byte) (i >>> 8);
  362.         b[this.position++] = (byte) (i >>> 16);
  363.     }
  364.     final void writeLongLong(long i) {
  365.         byte[] b = this.byteBuffer;
  366.         b[this.position++] = (byte) (i & 0xff);
  367.         b[this.position++] = (byte) (i >>> 8);
  368.         b[this.position++] = (byte) (i >>> 16);
  369.         b[this.position++] = (byte) (i >>> 24);
  370.         b[this.position++] = (byte) (i >>> 32);
  371.         b[this.position++] = (byte) (i >>> 40);
  372.         b[this.position++] = (byte) (i >>> 48);
  373.         b[this.position++] = (byte) (i >>> 56);
  374.     }
  375.     // Write null-terminated string
  376.     final void writeString(String s) throws SQLException {
  377.      ensureCapacity(s.length() + 1);
  378.     
  379.         writeStringNoNull(s);
  380.         this.byteBuffer[this.position++] = 0;
  381.     }
  382.     // Write string, with no termination
  383.     final void writeStringNoNull(String s) throws SQLException {
  384.         int len = s.length();
  385.         ensureCapacity(len);
  386.         System.arraycopy(s.getBytes(), 0, byteBuffer, position, len);
  387.         position += len;
  388.         //         for (int i = 0; i < len; i++)
  389.         //         {
  390.         //             this.byteBuffer[this.position++] = (byte)s.charAt(i);
  391.         //         }
  392.     }
  393.     // Write a String using the specified character
  394.     // encoding
  395.     final void writeStringNoNull(String s, String encoding, SingleByteCharsetConverter converter)
  396.         throws UnsupportedEncodingException, SQLException {
  397.         byte[] b = null;
  398.         
  399.         if (converter != null) {
  400.             b = converter.toBytes(s);
  401.         } else {
  402.             b = StringUtils.getBytes(s, encoding);
  403.         }
  404.         int len = b.length;
  405.         ensureCapacity(len);
  406.         System.arraycopy(b, 0, this.byteBuffer, this.position, len);
  407.         this.position += len;
  408.     }
  409.     void setBufLength(int bufLength) {
  410.         this.bufLength = bufLength;
  411.     }
  412.     int getBufLength() {
  413.         return bufLength;
  414.     }
  415.     void setSendLength(int sendLength) {
  416.         this.sendLength = sendLength;
  417.     }
  418. }