EMMA Coverage Report (generated Fri May 26 15:35:26 CDT 2006)
[all classes][com.mysql.jdbc]

COVERAGE SUMMARY FOR SOURCE FILE [ChannelBuffer.java]

nameclass, %method, %block, %line, %
ChannelBuffer.java100% (1/1)65%  (30/46)51%  (623/1210)54%  (135.2/249)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class ChannelBuffer100% (1/1)65%  (30/46)51%  (623/1210)54%  (135.2/249)
ChannelBuffer (byte []): void 0%   (0/1)0%   (0/20)0%   (0/7)
getBytes (int, int): byte [] 0%   (0/1)0%   (0/25)0%   (0/8)
readByte (int): byte 0%   (0/1)0%   (0/5)0%   (0/1)
readIntAsLong (): int 0%   (0/1)0%   (0/32)0%   (0/2)
readLength (): long 0%   (0/1)0%   (0/24)0%   (0/7)
readLongInt (): int 0%   (0/1)0%   (0/24)0%   (0/2)
readLongLong (): long 0%   (0/1)0%   (0/72)0%   (0/2)
readString (String): String 0%   (0/1)0%   (0/62)0%   (0/8)
readnBytes (): int 0%   (0/1)0%   (0/26)0%   (0/7)
setByteBuffer (byte []): void 0%   (0/1)0%   (0/5)0%   (0/2)
writeDouble (double): void 0%   (0/1)0%   (0/10)0%   (0/4)
writeFieldLength (long): void 0%   (0/1)0%   (0/50)0%   (0/14)
writeFloat (float): void 0%   (0/1)0%   (0/42)0%   (0/8)
writeLenBytes (byte []): void 0%   (0/1)0%   (0/23)0%   (0/6)
writeLenString (String, String, String, SingleByteCharsetConverter, boolean):... 0%   (0/1)0%   (0/38)0%   (0/10)
writeLongLong (long): void 0%   (0/1)0%   (0/79)0%   (0/11)
readFieldLength (): long 100% (1/1)46%  (11/24)43%  (3/7)
newReadLength (): long 100% (1/1)64%  (23/36)50%  (4/8)
bufferToArray (): byte [] 100% (1/1)80%  (45/56)79%  (11/14)
ChannelBuffer (int, boolean): void 100% (1/1)87%  (27/31)90%  (9/10)
getBytes (int): byte [] 100% (1/1)90%  (26/29)75%  (6/8)
readLenByteArray (int): byte [] 100% (1/1)93%  (27/29)86%  (6/7)
ensureCapacity (int): void 100% (1/1)95%  (81/85)95%  (19/20)
clear (): void 100% (1/1)100% (6/6)100% (2/2)
fastSkipLenString (): int 100% (1/1)100% (17/17)100% (3/3)
getBufLength (): int 100% (1/1)100% (4/4)100% (1/1)
getByteBuffer (): byte [] 100% (1/1)100% (3/3)100% (1/1)
getCapacity (): int 100% (1/1)100% (4/4)100% (1/1)
getNioBuffer (): ByteBuffer 100% (1/1)100% (3/3)100% (1/1)
getPosition (): int 100% (1/1)100% (4/4)100% (1/1)
isLastDataPacket (): boolean 100% (1/1)100% (22/22)100% (2/2)
readByte (): byte 100% (1/1)100% (6/6)100% (2/2)
readInt (): int 100% (1/1)100% (14/14)100% (1/1)
readLong (): long 100% (1/1)100% (36/36)100% (2/2)
readString (): String 100% (1/1)100% (42/42)100% (9/9)
setBufLength (int): void 100% (1/1)100% (13/13)100% (4/4)
setPosition (int): void 100% (1/1)100% (6/6)100% (2/2)
writeByte (byte): void 100% (1/1)100% (12/12)100% (4/4)
writeBytesNoNull (byte []): void 100% (1/1)100% (17/17)100% (5/5)
writeBytesNoNull (byte [], int, int): void 100% (1/1)100% (14/14)100% (4/4)
writeInt (int): void 100% (1/1)100% (23/23)100% (5/5)
writeLong (long): void 100% (1/1)100% (43/43)100% (7/7)
writeLongInt (int): void 100% (1/1)100% (31/31)100% (6/6)
writeString (String): void 100% (1/1)100% (20/20)100% (5/5)
writeStringNoNull (String): void 100% (1/1)100% (20/20)100% (5/5)
writeStringNoNull (String, String, String, boolean): void 100% (1/1)100% (23/23)100% (6/6)

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 */
25package com.mysql.jdbc;
26 
27import java.io.UnsupportedEncodingException;
28import java.nio.ByteBuffer;
29 
30import java.sql.SQLException;
31 
32/**
33 * Buffer contains code to read and write packets from/to the MySQL server.
34 * 
35 * @version $Id: ChannelBuffer.java 4054 2005-08-11 20:16:51Z mmatthews $
36 * @author Mark Matthews
37 */
38class ChannelBuffer extends Buffer {
39 
40        private byte[] asBytes = null;
41 
42        // private int position = 0;
43 
44        private int bufLength = 0;
45 
46        private ByteBuffer directBuffer;
47 
48        private boolean dirty = true;
49 
50        ChannelBuffer(byte[] buf) {
51                this.directBuffer = ByteBuffer.wrap(buf);
52                setBufLength(buf.length);
53        }
54 
55        ChannelBuffer(int size, boolean direct) {
56 
57                if (direct) {
58                        this.directBuffer = ByteBuffer.allocateDirect(size);
59                } else {
60                        this.directBuffer = ByteBuffer.allocate(size);
61                }
62 
63                // this.directBuffer.limit(size);
64                setBufLength(size);
65                // this.position = MysqlIO.HEADER_LENGTH;
66                this.directBuffer.position(MysqlIO.HEADER_LENGTH);
67        }
68 
69        private byte[] bufferToArray() {
70                if (!this.dirty) {
71                        return this.asBytes;
72                } else if (this.directBuffer.hasArray()) {
73                        this.asBytes = this.directBuffer.array();
74                        this.dirty = false;
75 
76                        return this.asBytes;
77                } else {
78                        int bufferLength = this.directBuffer.limit();
79 
80                        this.asBytes = new byte[bufferLength];
81 
82                        int oldPosition = getPosition();
83 
84                        this.directBuffer.position(0);
85                        this.directBuffer.get(this.asBytes, 0, bufferLength);
86                        this.directBuffer.position(oldPosition);
87                        this.dirty = false;
88 
89                        return this.asBytes;
90                }
91        }
92 
93        final void clear() {
94                this.directBuffer.position(MysqlIO.HEADER_LENGTH);
95        }
96 
97        final void ensureCapacity(int additionalData) throws SQLException {
98                int bufferCapacity = this.directBuffer.capacity();
99 
100                int currentPosition = this.directBuffer.position();
101 
102                if ((currentPosition + additionalData) > getBufLength()) {
103                        if ((currentPosition + additionalData) < bufferCapacity) {
104                                // byteBuffer.length is != getBufLength() all of the time
105                                // due to re-using of packets (we don't shrink them)
106                                //
107                                // If we can, don't re-alloc, just set buffer length
108                                // to size of current buffer
109                                setBufLength(currentPosition + additionalData);
110                        } else {
111                                //
112                                // Otherwise, re-size, and pad so we can avoid
113                                // allocing again in the near future
114                                //
115 
116                                int newLength = (int) (bufferCapacity * 1.25);
117 
118                                if (newLength < 4096) {
119                                        newLength = 4096;
120                                }
121 
122                                if (newLength < (bufferCapacity + additionalData)) {
123                                        newLength = bufferCapacity + (int) (additionalData * 1.25);
124                                }
125 
126                                if (newLength < bufferCapacity) {
127                                        newLength = bufferCapacity + additionalData;
128                                }
129 
130                                ByteBuffer largerBuffer = ByteBuffer.allocateDirect(newLength);
131 
132                                this.directBuffer.position(0);
133                                largerBuffer.put(this.directBuffer);
134                                this.directBuffer = largerBuffer;
135                                this.directBuffer.position(currentPosition);
136 
137                                bufferCapacity = this.directBuffer.capacity(); // re-alloc'd
138                                setBufLength(bufferCapacity);
139 
140                        }
141                }
142        }
143 
144        /**
145         * Skip over a length-encoded string
146         * 
147         * @return The position past the end of the string
148         */
149        public int fastSkipLenString() {
150                long len = this.readFieldLength();
151 
152                // position += len;
153 
154                this.directBuffer.position((int) (this.directBuffer.position() + len));
155 
156                return (int) len; // this is safe, as this is only
157        }
158 
159        int getBufLength() {
160                return this.directBuffer.limit();
161        }
162 
163        /**
164         * Returns the array of bytes this Buffer is using to read from.
165         * 
166         * @return byte array being read from
167         */
168        public byte[] getByteBuffer() {
169                return bufferToArray();
170        }
171 
172        final byte[] getBytes(int len) {
173                byte[] b = new byte[len];
174                byte[] nioByteBuffer = bufferToArray();
175 
176                try {
177 
178                        System.arraycopy(nioByteBuffer, this.directBuffer.position(), b, 0,
179                                        len);
180                        // this.position += len; // update cursor
181                        this.directBuffer.position((this.directBuffer.position() + len));
182                } catch (ArrayIndexOutOfBoundsException aiobex) {
183                        throw aiobex;
184                }
185 
186                return b;
187        }
188 
189        /*
190         * (non-Javadoc)
191         * 
192         * @see com.mysql.jdbc.Buffer#getBytes(int, int)
193         */
194        byte[] getBytes(int offset, int len) {
195                byte[] b = new byte[len];
196                byte[] nioByteBuffer = bufferToArray();
197 
198                try {
199 
200                        System.arraycopy(nioByteBuffer, offset, b, 0, len);
201                        // this.position += len; // update cursor
202                        this.directBuffer.position((offset + len));
203                } catch (ArrayIndexOutOfBoundsException aiobex) {
204                        throw aiobex;
205                }
206 
207                return b;
208        }
209 
210        int getCapacity() {
211                return this.directBuffer.capacity();
212        }
213 
214        public ByteBuffer getNioBuffer() {
215                return this.directBuffer;
216        }
217 
218        /**
219         * Returns the current position to write to/ read from
220         * 
221         * @return the current position to write to/ read from
222         */
223        public int getPosition() {
224                // if (directBuffer.position() != this.position) {
225                // System.err.println("WARN: directBuffer position != this.position");
226                // }
227 
228                return this.directBuffer.position();
229        }
230 
231        // 2000-06-05 Changed
232        final boolean isLastDataPacket() {
233                boolean hasMarker = ((this.directBuffer.get(0) & 0xff) == 254);
234 
235                return (hasMarker && this.bufLength < 9);
236        }
237 
238        final long newReadLength() {
239                int sw = this.directBuffer.get(this.directBuffer.position()) & 0xff;
240                this.directBuffer.position(this.directBuffer.position() + 1);
241 
242                switch (sw) {
243                case 251:
244                        return 0;
245 
246                case 252:
247                        return readInt();
248 
249                case 253:
250                        return readLongInt();
251 
252                case 254: // changed for 64 bit lengths
253                        return readLongLong();
254 
255                default:
256                        return sw;
257                }
258        }
259 
260        final byte readByte() {
261                byte b = this.directBuffer.get();
262 
263                return b;
264        }
265 
266        final byte readByte(int readAt) {
267                return this.directBuffer.get(readAt);
268        }
269 
270        final long readFieldLength() {
271                int sw = this.directBuffer.get() & 0xff;
272 
273                switch (sw) {
274                case 251:
275                        return NULL_LENGTH;
276 
277                case 252:
278                        return readInt();
279 
280                case 253:
281                        return readLongInt();
282 
283                case 254:
284                        return readLongLong();
285 
286                default:
287                        return sw;
288                }
289        }
290 
291        final int readInt() {
292                return (this.directBuffer.get() & 0xff)
293                                | ((this.directBuffer.get() & 0xff) << 8);
294        }
295 
296        final int readIntAsLong() {
297                int i = (this.directBuffer.get() & 0xff)
298                                | ((this.directBuffer.get() & 0xff) << 8)
299                                | ((this.directBuffer.get() & 0xff) << 16)
300                                | ((this.directBuffer.get() & 0xff) << 24);
301 
302                // this.directBuffer.position(this.position);
303 
304                return i;
305        }
306 
307        final byte[] readLenByteArray(int offset) {
308                long len = this.readFieldLength();
309 
310                if (len == NULL_LENGTH) {
311                        return null;
312                }
313 
314                if (len == 0) {
315                        return Constants.EMPTY_BYTE_ARRAY;
316                }
317 
318                this.directBuffer.position(this.directBuffer.position() + offset);
319                // this.directBuffer.position(this.position);
320 
321                return getBytes((int) len);
322        }
323 
324        final long readLength() {
325                int sw = this.directBuffer.get() & 0xff;
326                // this.directBuffer.position(this.position);
327 
328                switch (sw) {
329                case 251:
330                        return 0;
331 
332                case 252:
333                        return readInt();
334 
335                case 253:
336                        return readLongInt();
337 
338                case 254:
339                        return readLong();
340 
341                default:
342                        return sw;
343                }
344        }
345 
346        final long readLong() {
347                long l = ((long)this.directBuffer.get() & 0xff)
348                                | (((long)this.directBuffer.get() & 0xff) << 8)
349                                | (((long)this.directBuffer.get() & 0xff) << 16)
350                                | (((long)this.directBuffer.get() & 0xff) << 24);
351 
352                // this.directBuffer.position(this.position);
353 
354                return l;
355        }
356 
357        final int readLongInt() {
358 
359                int i = (this.directBuffer.get() & 0xff)
360                                | ((this.directBuffer.get() & 0xff) << 8)
361                                | ((this.directBuffer.get() & 0xff) << 16);
362 
363                // this.directBuffer.position(this.position);
364 
365                return i;
366        }
367 
368        // 2000-06-05 Fixed
369        final long readLongLong() {
370 
371                long l = (this.directBuffer.get() & 0xff)
372                                | ((long) (this.directBuffer.get() & 0xff) << 8)
373                                | ((long) (this.directBuffer.get() & 0xff) << 16)
374                                | ((long) (this.directBuffer.get() & 0xff) << 24)
375                                | ((long) (this.directBuffer.get() & 0xff) << 32)
376                                | ((long) (this.directBuffer.get() & 0xff) << 40)
377                                | ((long) (this.directBuffer.get() & 0xff) << 48)
378                                | ((long) (this.directBuffer.get() & 0xff) << 56);
379 
380                // this.directBuffer.position(this.position);
381 
382                return l;
383        }
384 
385        final int readnBytes() {
386                int sw = this.directBuffer.get() & 0xff;
387                // this.directBuffer.position(this.position);
388 
389                switch (sw) {
390                case 1:
391                        return this.directBuffer.get() & 0xff;
392 
393                case 2:
394                        return this.readInt();
395 
396                case 3:
397                        return this.readLongInt();
398 
399                case 4:
400                        return (int) this.readLong();
401 
402                default:
403                        return 255;
404                }
405        }
406 
407        //
408        // Read a null-terminated string
409        //
410        // To avoid alloc'ing a new byte array, we
411        // do this by hand, rather than calling getNullTerminatedBytes()
412        //
413        final String readString() {
414 
415                int len = 0;
416                int maxLen = getBufLength();
417                int oldPosition = getPosition();
418 
419                while ((getPosition() < maxLen) && (this.directBuffer.get() != 0)) {
420                        len++;
421                }
422 
423                setPosition(oldPosition);
424 
425                String s = new String(bufferToArray(), getPosition(), len);
426 
427                this.directBuffer.position(getPosition() + len + 1); // update cursor
428 
429                return s;
430        }
431 
432        final String readString(String encoding) throws SQLException {
433 
434                int len = 0;
435 
436                int maxLen = getBufLength();
437 
438                while ((getPosition() < maxLen) && (this.directBuffer.get() != 0)) {
439                        len++;
440                }
441 
442                try {
443                        return new String(bufferToArray(), getPosition(), len, encoding);
444                } catch (UnsupportedEncodingException uEE) {
445                        throw new SQLException(
446                                        Messages.getString("ChannelBuffer.0") //$NON-NLS-1$
447                                                        + encoding + Messages.getString("ChannelBuffer.1"), SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
448                } finally {
449                        this.directBuffer.position(getPosition() + len + 1); // update
450                                                                                                                                        // cursor
451                }
452        }
453 
454        void setBufLength(int bufLengthToSet) {
455                this.bufLength = bufLengthToSet;
456                this.directBuffer.limit(this.bufLength);
457                this.dirty = true;
458        }
459 
460        /**
461         * Sets the array of bytes to use as a buffer to read from.
462         * 
463         * @param byteBuffer
464         *            the array of bytes to use as a buffer
465         */
466        public void setByteBuffer(byte[] byteBuffer) {
467                this.directBuffer = ByteBuffer.wrap(byteBuffer);
468        }
469 
470        /**
471         * Set the current position to write to/ read from
472         * 
473         * @param position
474         *            the position (0-based index)
475         */
476        public void setPosition(int position) {
477                // this.position = position;
478                this.directBuffer.position(position);
479        }
480 
481        final void writeByte(byte b) throws SQLException {
482                ensureCapacity(1);
483 
484                this.directBuffer.put(b);
485                this.dirty = true;
486        }
487 
488        // Write a byte array
489        final void writeBytesNoNull(byte[] bytes) throws SQLException {
490                int len = bytes.length;
491                ensureCapacity(len);
492 
493                this.directBuffer.put(bytes, 0, len);
494                this.dirty = true;
495        }
496 
497        // Write a byte array with the given offset and length
498        final void writeBytesNoNull(byte[] bytes, int offset, int length)
499                        throws SQLException {
500                ensureCapacity(length);
501 
502                this.directBuffer.put(bytes, offset, length);
503 
504                this.dirty = true;
505        }
506 
507        final void writeDouble(double d) throws SQLException {
508                long l = Double.doubleToLongBits(d);
509                writeLongLong(l);
510                this.dirty = true;
511        }
512 
513        final void writeFieldLength(long length) throws SQLException {
514                if (length < 251) {
515                        writeByte((byte) length);
516                } else if (length < 65536L) {
517                        ensureCapacity(3);
518                        writeByte((byte) 252);
519                        writeInt((int) length);
520                } else if (length < 16777216L) {
521                        ensureCapacity(4);
522                        writeByte((byte) 253);
523                        writeLongInt((int) length);
524                } else {
525                        ensureCapacity(9);
526                        writeByte((byte) 254);
527                        writeLongLong(length);
528                }
529 
530        }
531 
532        final void writeFloat(float f) throws SQLException {
533                ensureCapacity(4);
534 
535                int i = Float.floatToIntBits(f);
536 
537                this.directBuffer.put((byte) (i & 0xff));
538                this.directBuffer.put((byte) (i >>> 8));
539                this.directBuffer.put((byte) (i >>> 16));
540                this.directBuffer.put((byte) (i >>> 24));
541 
542                this.dirty = true;
543        }
544 
545        // 2000-06-05 Changed
546        final void writeInt(int i) throws SQLException {
547                ensureCapacity(2);
548                this.directBuffer.put((byte) (i & 0xff));
549                this.directBuffer.put((byte) (i >>> 8));
550 
551                this.dirty = true;
552        }
553 
554        // Write a String using the specified character
555        // encoding
556        final void writeLenBytes(byte[] b) throws SQLException {
557                int len = b.length;
558                ensureCapacity(len + 9);
559                writeFieldLength(len);
560                this.directBuffer.put(b, 0, len);
561 
562                this.dirty = true;
563        }
564 
565        // Write a String using the specified character
566        // encoding
567        final void writeLenString(String s, String encoding, String serverEncoding,
568                        SingleByteCharsetConverter converter, boolean parserKnowsUnicode)
569                        throws UnsupportedEncodingException, SQLException {
570                byte[] b = null;
571 
572                if (converter != null) {
573                        b = converter.toBytes(s);
574                } else {
575                        b = StringUtils.getBytes(s, encoding, serverEncoding,
576                                        parserKnowsUnicode);
577                }
578 
579                int len = b.length;
580                ensureCapacity(len + 9);
581                writeFieldLength(len);
582                this.directBuffer.put(b, 0, len);
583 
584                this.dirty = true;
585        }
586 
587        // 2000-06-05 Changed
588        final void writeLong(long i) throws SQLException {
589                ensureCapacity(4);
590 
591                this.directBuffer.put((byte) (i & 0xff));
592                this.directBuffer.put((byte) (i >>> 8));
593                this.directBuffer.put((byte) (i >>> 16));
594                this.directBuffer.put((byte) (i >>> 24));
595 
596                this.dirty = true;
597        }
598 
599        // 2000-06-05 Changed
600        final void writeLongInt(int i) throws SQLException {
601                ensureCapacity(3);
602 
603                this.directBuffer.put((byte) (i & 0xff));
604                this.directBuffer.put((byte) (i >>> 8));
605                this.directBuffer.put((byte) (i >>> 16));
606 
607                this.dirty = true;
608        }
609 
610        final void writeLongLong(long i) throws SQLException {
611                ensureCapacity(8);
612 
613                this.directBuffer.put((byte) (i & 0xff));
614                this.directBuffer.put((byte) (i >>> 8));
615                this.directBuffer.put((byte) (i >>> 16));
616                this.directBuffer.put((byte) (i >>> 24));
617                this.directBuffer.put((byte) (i >>> 32));
618                this.directBuffer.put((byte) (i >>> 40));
619                this.directBuffer.put((byte) (i >>> 48));
620                this.directBuffer.put((byte) (i >>> 56));
621 
622                this.dirty = true;
623        }
624 
625        // Write null-terminated string
626        final void writeString(String s) throws SQLException {
627                ensureCapacity((s.length() * 2) + 1);
628 
629                writeStringNoNull(s);
630                this.directBuffer.put((byte) 0);
631 
632                this.dirty = true;
633        }
634 
635        // Write string, with no termination
636        final void writeStringNoNull(String s) throws SQLException {
637                int len = s.length();
638                ensureCapacity(len * 2);
639 
640                this.directBuffer.put(s.getBytes(), 0, len);
641 
642                this.dirty = true;
643        }
644 
645        // Write a String using the specified character
646        // encoding
647        final void writeStringNoNull(String s, String encoding,
648                        String serverEncoding, boolean parserKnowsUnicode)
649                        throws UnsupportedEncodingException, SQLException {
650                byte[] b = StringUtils.getBytes(s, encoding, serverEncoding,
651                                parserKnowsUnicode);
652 
653                int len = b.length;
654                ensureCapacity(len);
655 
656                this.directBuffer.put(b, 0, len);
657 
658                this.dirty = true;
659        }
660}

[all classes][com.mysql.jdbc]
EMMA 2.0.4217 (C) Vladimir Roubtsov