KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > mysql > jdbc > ByteArrayBuffer


1 /*
2  Copyright (C) 2002-2004 MySQL AB
3
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of version 2 of the GNU General Public License as
6  published by the Free Software Foundation.
7
8  There are special exceptions to the terms and conditions of the GPL
9  as it is applied to this software. View the full text of the
10  exception in file EXCEPTIONS-CONNECTOR-J in the directory of this
11  software distribution.
12
13  This program is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17
18  You should have received a copy of the GNU General Public License
19  along with this program; if not, write to the Free Software
20  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21
22
23
24  */

25 package com.mysql.jdbc;
26
27 import java.io.UnsupportedEncodingException JavaDoc;
28 import java.nio.ByteBuffer JavaDoc;
29
30 import java.sql.SQLException JavaDoc;
31
32 /**
33  * Buffer contains code to read and write packets from/to the MySQL server.
34  *
35  * @version $Id: ByteArrayBuffer.java,v 1.1.2.1 2005/05/13 18:58:38 mmatthews
36  * Exp $
37  * @author Mark Matthews
38  */

39 class ByteArrayBuffer extends Buffer {
40
41     private int bufLength = 0;
42
43     private byte[] byteBuffer;
44
45     private int position = 0;
46
47     ByteArrayBuffer(byte[] buf) {
48         this.byteBuffer = buf;
49         setBufLength(buf.length);
50     }
51
52     ByteArrayBuffer(int size) {
53         this.byteBuffer = new byte[size];
54         setBufLength(this.byteBuffer.length);
55         this.position = MysqlIO.HEADER_LENGTH;
56     }
57
58     final void clear() {
59         this.position = MysqlIO.HEADER_LENGTH;
60     }
61
62     final void ensureCapacity(int additionalData) throws SQLException JavaDoc {
63         if ((this.position + additionalData) > getBufLength()) {
64             if ((this.position + additionalData) < this.byteBuffer.length) {
65                 // byteBuffer.length is != getBufLength() all of the time
66
// due to re-using of packets (we don't shrink them)
67
//
68
// If we can, don't re-alloc, just set buffer length
69
// to size of current buffer
70
setBufLength(this.byteBuffer.length);
71             } else {
72                 //
73
// Otherwise, re-size, and pad so we can avoid
74
// allocing again in the near future
75
//
76
int newLength = (int) (this.byteBuffer.length * 1.25);
77
78                 if (newLength < (this.byteBuffer.length + additionalData)) {
79                     newLength = this.byteBuffer.length
80                             + (int) (additionalData * 1.25);
81                 }
82
83                 if (newLength < this.byteBuffer.length) {
84                     newLength = this.byteBuffer.length + additionalData;
85                 }
86
87                 byte[] newBytes = new byte[newLength];
88
89                 System.arraycopy(this.byteBuffer, 0, newBytes, 0,
90                         this.byteBuffer.length);
91                 this.byteBuffer = newBytes;
92                 setBufLength(this.byteBuffer.length);
93             }
94         }
95     }
96
97     /**
98      * Skip over a length-encoded string
99      *
100      * @return The position past the end of the string
101      */

102     public int fastSkipLenString() {
103         long len = this.readFieldLength();
104
105         this.position += len;
106
107         return (int) len; // this is safe, as this is only
108
}
109
110     protected final byte[] getBufferSource() {
111         return this.byteBuffer;
112     }
113
114     int getBufLength() {
115         return this.bufLength;
116     }
117
118     /**
119      * Returns the array of bytes this Buffer is using to read from.
120      *
121      * @return byte array being read from
122      */

123     public byte[] getByteBuffer() {
124         return this.byteBuffer;
125     }
126
127     final byte[] getBytes(int len) {
128         byte[] b = new byte[len];
129         System.arraycopy(this.byteBuffer, this.position, b, 0, len);
130         this.position += len; // update cursor
131

132         return b;
133     }
134
135     /*
136      * (non-Javadoc)
137      *
138      * @see com.mysql.jdbc.Buffer#getBytes(int, int)
139      */

140     byte[] getBytes(int offset, int len) {
141         byte[] dest = new byte[len];
142         System.arraycopy(this.byteBuffer, offset, dest, 0, len);
143
144         return dest;
145     }
146
147     int getCapacity() {
148         return this.byteBuffer.length;
149     }
150
151     public ByteBuffer JavaDoc getNioBuffer() {
152         throw new IllegalArgumentException JavaDoc(Messages
153                 .getString("ByteArrayBuffer.0")); //$NON-NLS-1$
154
}
155
156     /**
157      * Returns the current position to write to/ read from
158      *
159      * @return the current position to write to/ read from
160      */

161     public int getPosition() {
162         return this.position;
163     }
164
165     // 2000-06-05 Changed
166
final boolean isLastDataPacket() {
167         return ((getBufLength() < 9) && ((this.byteBuffer[0] & 0xff) == 254));
168     }
169
170     final long newReadLength() {
171         int sw = this.byteBuffer[this.position++] & 0xff;
172
173         switch (sw) {
174         case 251:
175             return 0;
176
177         case 252:
178             return readInt();
179
180         case 253:
181             return readLongInt();
182
183         case 254: // changed for 64 bit lengths
184
return readLongLong();
185
186         default:
187             return sw;
188         }
189     }
190
191     final byte readByte() {
192         return this.byteBuffer[this.position++];
193     }
194
195     final byte readByte(int readAt) {
196         return this.byteBuffer[readAt];
197     }
198
199     final long readFieldLength() {
200         int sw = this.byteBuffer[this.position++] & 0xff;
201
202         switch (sw) {
203         case 251:
204             return NULL_LENGTH;
205
206         case 252:
207             return readInt();
208
209         case 253:
210             return readLongInt();
211
212         case 254:
213             return readLongLong();
214
215         default:
216             return sw;
217         }
218     }
219
220     // 2000-06-05 Changed
221
final int readInt() {
222         byte[] b = this.byteBuffer; // a little bit optimization
223

224         return (b[this.position++] & 0xff) | ((b[this.position++] & 0xff) << 8);
225     }
226
227     final int readIntAsLong() {
228         byte[] b = this.byteBuffer;
229
230         return (b[this.position++] & 0xff) | ((b[this.position++] & 0xff) << 8)
231                 | ((b[this.position++] & 0xff) << 16)
232                 | ((b[this.position++] & 0xff) << 24);
233     }
234
235     final byte[] readLenByteArray(int offset) {
236         long len = this.readFieldLength();
237
238         if (len == NULL_LENGTH) {
239             return null;
240         }
241
242         if (len == 0) {
243             return Constants.EMPTY_BYTE_ARRAY;
244         }
245
246         this.position += offset;
247
248         return getBytes((int) len);
249     }
250
251     final long readLength() {
252         int sw = this.byteBuffer[this.position++] & 0xff;
253
254         switch (sw) {
255         case 251:
256             return 0;
257
258         case 252:
259             return readInt();
260
261         case 253:
262             return readLongInt();
263
264         case 254:
265             return readLong();
266
267         default:
268             return sw;
269         }
270     }
271
272     // 2000-06-05 Fixed
273
final long readLong() {
274         byte[] b = this.byteBuffer;
275
276         return (b[this.position++] & 0xff) | ((b[this.position++] & 0xff) << 8)
277                 | ((b[this.position++] & 0xff) << 16)
278                 | ((b[this.position++] & 0xff) << 24);
279     }
280
281     // 2000-06-05 Changed
282
final int readLongInt() {
283         byte[] b = this.byteBuffer;
284
285         return (b[this.position++] & 0xff) | ((b[this.position++] & 0xff) << 8)
286                 | ((b[this.position++] & 0xff) << 16);
287     }
288
289     // 2000-06-05 Fixed
290
final long readLongLong() {
291         byte[] b = this.byteBuffer;
292
293         return (b[this.position++] & 0xff)
294                 | ((long) (b[this.position++] & 0xff) << 8)
295                 | ((long) (b[this.position++] & 0xff) << 16)
296                 | ((long) (b[this.position++] & 0xff) << 24)
297                 | ((long) (b[this.position++] & 0xff) << 32)
298                 | ((long) (b[this.position++] & 0xff) << 40)
299                 | ((long) (b[this.position++] & 0xff) << 48)
300                 | ((long) (b[this.position++] & 0xff) << 56);
301     }
302
303     final int readnBytes() {
304         int sw = this.byteBuffer[this.position++] & 0xff;
305
306         switch (sw) {
307         case 1:
308             return this.byteBuffer[this.position++] & 0xff;
309
310         case 2:
311             return this.readInt();
312
313         case 3:
314             return this.readLongInt();
315
316         case 4:
317             return (int) this.readLong();
318
319         default:
320             return 255;
321         }
322     }
323
324     //
325
// Read a null-terminated string
326
//
327
// To avoid alloc'ing a new byte array, we
328
// do this by hand, rather than calling getNullTerminatedBytes()
329
//
330
final String JavaDoc readString() {
331         int i = this.position;
332         int len = 0;
333         int maxLen = getBufLength();
334
335         while ((i < maxLen) && (this.byteBuffer[i] != 0)) {
336             len++;
337             i++;
338         }
339
340         String JavaDoc s = new String JavaDoc(this.byteBuffer, this.position, len);
341         this.position += (len + 1); // update cursor
342

343         return s;
344     }
345
346     final String JavaDoc readString(String JavaDoc encoding) throws SQLException JavaDoc {
347         int i = this.position;
348         int len = 0;
349         int maxLen = getBufLength();
350
351         while ((i < maxLen) && (this.byteBuffer[i] != 0)) {
352             len++;
353             i++;
354         }
355
356         try {
357             return new String JavaDoc(this.byteBuffer, this.position, len, encoding);
358         } catch (UnsupportedEncodingException JavaDoc uEE) {
359             throw new SQLException JavaDoc(Messages.getString("ByteArrayBuffer.1") //$NON-NLS-1$
360
+ encoding + "'", SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
361
} finally {
362             this.position += (len + 1); // update cursor
363
}
364     }
365
366     void setBufLength(int bufLengthToSet) {
367         this.bufLength = bufLengthToSet;
368     }
369
370     /**
371      * Sets the array of bytes to use as a buffer to read from.
372      *
373      * @param byteBuffer
374      * the array of bytes to use as a buffer
375      */

376     public void setByteBuffer(byte[] byteBufferToSet) {
377         this.byteBuffer = byteBufferToSet;
378     }
379
380     /**
381      * Set the current position to write to/ read from
382      *
383      * @param position
384      * the position (0-based index)
385      */

386     public void setPosition(int positionToSet) {
387         this.position = positionToSet;
388     }
389
390     final void writeByte(byte b) throws SQLException JavaDoc {
391         ensureCapacity(1);
392
393         this.byteBuffer[this.position++] = b;
394     }
395
396     // Write a byte array
397
final void writeBytesNoNull(byte[] bytes) throws SQLException JavaDoc {
398         int len = bytes.length;
399         ensureCapacity(len);
400         System.arraycopy(bytes, 0, this.byteBuffer, this.position, len);
401         this.position += len;
402     }
403
404     // Write a byte array with the given offset and length
405
final void writeBytesNoNull(byte[] bytes, int offset, int length)
406             throws SQLException JavaDoc {
407         ensureCapacity(length);
408         System.arraycopy(bytes, offset, this.byteBuffer, this.position, length);
409         this.position += length;
410     }
411
412     final void writeDouble(double d) throws SQLException JavaDoc {
413         long l = Double.doubleToLongBits(d);
414         writeLongLong(l);
415     }
416
417     final void writeFieldLength(long length) throws SQLException JavaDoc {
418         if (length < 251) {
419             writeByte((byte) length);
420         } else if (length < 65536L) {
421             ensureCapacity(3);
422             writeByte((byte) 252);
423             writeInt((int) length);
424         } else if (length < 16777216L) {
425             ensureCapacity(4);
426             writeByte((byte) 253);
427             writeLongInt((int) length);
428         } else {
429             ensureCapacity(9);
430             writeByte((byte) 254);
431             writeLongLong(length);
432         }
433     }
434
435     final void writeFloat(float f) throws SQLException JavaDoc {
436         ensureCapacity(4);
437
438         int i = Float.floatToIntBits(f);
439         byte[] b = this.byteBuffer;
440         b[this.position++] = (byte) (i & 0xff);
441         b[this.position++] = (byte) (i >>> 8);
442         b[this.position++] = (byte) (i >>> 16);
443         b[this.position++] = (byte) (i >>> 24);
444     }
445
446     // 2000-06-05 Changed
447
final void writeInt(int i) throws SQLException JavaDoc {
448         ensureCapacity(2);
449
450         byte[] b = this.byteBuffer;
451         b[this.position++] = (byte) (i & 0xff);
452         b[this.position++] = (byte) (i >>> 8);
453     }
454
455     // Write a String using the specified character
456
// encoding
457
final void writeLenBytes(byte[] b) throws SQLException JavaDoc {
458         int len = b.length;
459         ensureCapacity(len + 9);
460         writeFieldLength(len);
461         System.arraycopy(b, 0, this.byteBuffer, this.position, len);
462         this.position += len;
463     }
464
465     // Write a String using the specified character
466
// encoding
467
final void writeLenString(String JavaDoc s, String JavaDoc encoding, String JavaDoc serverEncoding,
468             SingleByteCharsetConverter converter, boolean parserKnowsUnicode)
469             throws UnsupportedEncodingException JavaDoc, SQLException JavaDoc {
470         byte[] b = null;
471
472         if (converter != null) {
473             b = converter.toBytes(s);
474         } else {
475             b = StringUtils.getBytes(s, encoding, serverEncoding,
476                     parserKnowsUnicode);
477         }
478
479         int len = b.length;
480         ensureCapacity(len + 9);
481         writeFieldLength(len);
482         System.arraycopy(b, 0, this.byteBuffer, this.position, len);
483         this.position += len;
484     }
485
486     // 2000-06-05 Changed
487
final void writeLong(long i) throws SQLException JavaDoc {
488         ensureCapacity(4);
489
490         byte[] b = this.byteBuffer;
491         b[this.position++] = (byte) (i & 0xff);
492         b[this.position++] = (byte) (i >>> 8);
493         b[this.position++] = (byte) (i >>> 16);
494         b[this.position++] = (byte) (i >>> 24);
495     }
496
497     // 2000-06-05 Changed
498
final void writeLongInt(int i) throws SQLException JavaDoc {
499         ensureCapacity(3);
500         byte[] b = this.byteBuffer;
501         b[this.position++] = (byte) (i & 0xff);
502         b[this.position++] = (byte) (i >>> 8);
503         b[this.position++] = (byte) (i >>> 16);
504     }
505
506     final void writeLongLong(long i) throws SQLException JavaDoc {
507         ensureCapacity(8);
508         byte[] b = this.byteBuffer;
509         b[this.position++] = (byte) (i & 0xff);
510         b[this.position++] = (byte) (i >>> 8);
511         b[this.position++] = (byte) (i >>> 16);
512         b[this.position++] = (byte) (i >>> 24);
513         b[this.position++] = (byte) (i >>> 32);
514         b[this.position++] = (byte) (i >>> 40);
515         b[this.position++] = (byte) (i >>> 48);
516         b[this.position++] = (byte) (i >>> 56);
517     }
518
519     // Write null-terminated string
520
final void writeString(String JavaDoc s) throws SQLException JavaDoc {
521         ensureCapacity((s.length() * 2) + 1);
522         writeStringNoNull(s);
523         this.byteBuffer[this.position++] = 0;
524     }
525
526     // Write string, with no termination
527
final void writeStringNoNull(String JavaDoc s) throws SQLException JavaDoc {
528         int len = s.length();
529         ensureCapacity(len * 2);
530         System.arraycopy(s.getBytes(), 0, this.byteBuffer, this.position, len);
531         this.position += len;
532
533         // for (int i = 0; i < len; i++)
534
// {
535
// this.byteBuffer[this.position++] = (byte)s.charAt(i);
536
// }
537
}
538
539     // Write a String using the specified character
540
// encoding
541
final void writeStringNoNull(String JavaDoc s, String JavaDoc encoding,
542             String JavaDoc serverEncoding, boolean parserKnowsUnicode)
543             throws UnsupportedEncodingException JavaDoc, SQLException JavaDoc {
544         byte[] b = StringUtils.getBytes(s, encoding, serverEncoding,
545                 parserKnowsUnicode);
546
547         int len = b.length;
548         ensureCapacity(len);
549         System.arraycopy(b, 0, this.byteBuffer, this.position, len);
550         this.position += len;
551     }
552
553 }
554
Popular Tags