1 25 package com.mysql.jdbc; 26 27 import java.io.UnsupportedEncodingException ; 28 import java.nio.ByteBuffer ; 29 30 import java.sql.SQLException ; 31 32 38 class ChannelBuffer extends Buffer { 39 40 private byte[] asBytes = null; 41 42 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 setBufLength(size); 65 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 setBufLength(currentPosition + additionalData); 110 } else { 111 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(); setBufLength(bufferCapacity); 139 140 } 141 } 142 } 143 144 149 public int fastSkipLenString() { 150 long len = this.readFieldLength(); 151 152 154 this.directBuffer.position((int) (this.directBuffer.position() + len)); 155 156 return (int) len; } 158 159 int getBufLength() { 160 return this.directBuffer.limit(); 161 } 162 163 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.directBuffer.position((this.directBuffer.position() + len)); 182 } catch (ArrayIndexOutOfBoundsException aiobex) { 183 throw aiobex; 184 } 185 186 return b; 187 } 188 189 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.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 223 public int getPosition() { 224 228 return this.directBuffer.position(); 229 } 230 231 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: 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 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 321 return getBytes((int) len); 322 } 323 324 final long readLength() { 325 int sw = this.directBuffer.get() & 0xff; 326 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 = (this.directBuffer.get() & 0xff) 348 | ((this.directBuffer.get() & 0xff) << 8) 349 | ((this.directBuffer.get() & 0xff) << 16) 350 | ((this.directBuffer.get() & 0xff) << 24); 351 352 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 365 return i; 366 } 367 368 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 382 return l; 383 } 384 385 final int readnBytes() { 386 int sw = this.directBuffer.get() & 0xff; 387 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 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); 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") + encoding + Messages.getString("ChannelBuffer.1"), SQLError.SQL_STATE_ILLEGAL_ARGUMENT); } finally { 449 this.directBuffer.position(getPosition() + len + 1); } 452 } 453 454 void setBufLength(int bufLengthToSet) { 455 this.bufLength = bufLengthToSet; 456 this.directBuffer.limit(this.bufLength); 457 this.dirty = true; 458 } 459 460 466 public void setByteBuffer(byte[] byteBuffer) { 467 this.directBuffer = ByteBuffer.wrap(byteBuffer); 468 } 469 470 476 public void setPosition(int position) { 477 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 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 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 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 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 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 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 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 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 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 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 } 661 | Popular Tags |