1 /* 2 * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 package nsk.share.jdwp; 25 26 import java.io.*; 27 import nsk.share.*; 28 29 /** 30 * This class represents a byte buffer of variable size. 31 */ 32 public class ByteBuffer { 33 34 /** 35 * Empty byte value (zero). 36 */ 37 private static final byte EMPTY_BYTE = (byte)0; 38 39 /** 40 * Current number of bytes in the buffer. 41 */ 42 private int CurrentSize; 43 44 /** 45 * Delta to increase buffer size. 46 */ 47 private int Delta; 48 49 /** 50 * Current offset from the buffer begin during parsing packet. 51 */ 52 int parseOffset; 53 54 /** 55 * Array of bytes in the buffer. 56 */ 57 protected byte[] bytes; 58 59 /** 60 * Make an empty <code>ByteBuffer</code> object. 61 */ ByteBuffer()62 public ByteBuffer() { 63 this(128, 128); 64 } 65 66 /** 67 * Make an empty <code>ByteBuffer</code> object with given initial capacity. 68 * When there is no space for a new byte in a buffer it's capacity 69 * grows by Delta. 70 */ ByteBuffer(int InitialSize, int Delta)71 public ByteBuffer(int InitialSize, int Delta) { 72 if (Delta <= 0) 73 Delta = 16; 74 this.Delta = Delta; 75 CurrentSize = 0; 76 bytes = new byte[InitialSize]; 77 parseOffset = 0; 78 } 79 80 /** 81 * Make a copy of specified byte buffer. 82 */ ByteBuffer(ByteBuffer buffer)83 public ByteBuffer(ByteBuffer buffer) { 84 int InitialSize = buffer.bytes.length; 85 Delta = buffer.Delta; 86 CurrentSize = buffer.CurrentSize; 87 bytes = new byte[InitialSize]; 88 for (int i = 0; i < CurrentSize; i++ ) { 89 bytes[i] = buffer.bytes[i]; 90 } 91 parseOffset = 0; 92 } 93 94 /** 95 * Return number of bytes in this buffer. 96 */ length()97 public int length() { 98 return CurrentSize; 99 } 100 101 /** 102 * Return array of bytes in this buffer. 103 */ getBytes()104 public byte[] getBytes() { 105 return bytes; 106 } 107 108 ////////////////////////////////////////////////////////////////////////// 109 110 /** 111 * Replace the byte at the specified offset in this buffer with the 112 * less significant byte from the int value. 113 * 114 * @throws BoundException if specified offset is out of buffer bounds 115 */ putByte(int off, byte value)116 public void putByte(int off, byte value) throws BoundException { 117 118 if ((off < 0) || (off >= CurrentSize)) 119 throw new BoundException("Unable to put one byte at " + offsetString(off)); 120 121 bytes[off] = value; 122 } 123 124 /** 125 * Replace len bytes starting at offset off with the bytes from the 126 * given byte array. 127 * 128 * @throws BoundException if offset and length are out of buffer bounds 129 */ putBytes(int off, byte[] value, int start, int len)130 public void putBytes(int off, byte[] value, int start, int len) throws BoundException { 131 if (len > (CurrentSize - off)) { 132 throw new BoundException("Unable to put " + len + " bytes at " + offsetString(off) + 133 " (available bytes: " + (CurrentSize - off) + ")" ); 134 } 135 try { 136 for (int i = 0; i < len; i++) 137 putByte(off++, value[start++]); 138 } catch (BoundException e) { 139 throw new Failure("Caught unexpected bound exception while putting " + len + 140 "bytes at " + offsetString(off) + ":\n\t" + e); 141 } 142 } 143 144 /** 145 * Replace count (1 - 8) bytes starting at offset off with the less 146 * significant bytes from the specified ID value. 147 * 148 * @throws BoundException if offset and count are out of buffer bounds 149 */ putID(int off, long value, int count)150 public void putID(int off, long value, int count) throws BoundException { 151 152 if ((count <= 0) || (count > 8)) 153 throw new TestBug("Illegal number of bytes of ID value to put: " + count); 154 155 if (count > CurrentSize - off) { 156 throw new BoundException("Unable to put " + count + " bytes of ID value at " + 157 offsetString(off) + " (available bytes: " + (CurrentSize - off) + ")" ); 158 } 159 160 try { 161 putValueBytes(off, value, count); 162 } catch (BoundException e) { 163 throw new Failure("Caught unexpected bound exception while putting " + count + 164 "bytes of ID value at " + offsetString(off) + ":\n\t" + e); 165 } 166 } 167 168 /** 169 * Replace four bytes starting at offset off with the bytes from the 170 * specified int value. 171 * 172 * @throws BoundException if offset is out of buffer bounds 173 */ putInt(int off, int value)174 public void putInt(int off, int value) throws BoundException { 175 final int count = JDWP.TypeSize.INT; 176 177 if (count > CurrentSize - off) { 178 throw new BoundException("Unable to put " + count + " bytes of int value at " + 179 offsetString(off) + " (available bytes: " + (CurrentSize - off) + ")" ); 180 } 181 182 try { 183 putValueBytes(off, value, count); 184 } catch (BoundException e) { 185 throw new Failure("Caught unexpected bound exception while putting " + count + 186 "bytes of int value at " + offsetString(off) + ":\n\t" + e); 187 } 188 } 189 190 /** 191 * Replace two bytes starting at offset off with the bytes 192 * from the specified short value. 193 * 194 * @throws BoundException if offset is out of buffer bounds 195 */ putShort(int off, short value)196 public void putShort(int off, short value) throws BoundException { 197 final int count = JDWP.TypeSize.SHORT; 198 199 if (count > CurrentSize - off) { 200 throw new BoundException("Unable to put " + count + " bytes of short value at " + 201 offsetString(off) + " (available bytes: " + (CurrentSize - off) + ")" ); 202 } 203 204 try { 205 putValueBytes(off, value, count); 206 } catch (BoundException e) { 207 throw new Failure("Caught unexpected bound exception while putting " + count + 208 "bytes of short value at " + offsetString(off) + ":\n\t" + e); 209 } 210 } 211 212 /** 213 * Replace eight bytes starting at offset off with the bytes 214 * from the specified long value. 215 * 216 * @throws BoundException if offset is out of buffer bounds 217 */ putLong(int off, long value)218 public void putLong(int off, long value) throws BoundException { 219 final int count = JDWP.TypeSize.LONG; 220 221 if (count > CurrentSize - off) { 222 throw new BoundException("Unable to put " + count + " bytes of long value at " + 223 offsetString(off) + " (available bytes: " + (CurrentSize - off) + ")" ); 224 } 225 226 try { 227 putValueBytes(off, value, count); 228 } catch (BoundException e) { 229 throw new Failure("Caught unexpected bound exception while putting " + count + 230 "bytes of long value at " + offsetString(off) + ":\n\t" + e); 231 } 232 } 233 234 /** 235 * Replace four bytes starting at offset off with the bytes 236 * from the specified float value. 237 * 238 * @throws BoundException if offset is out of buffer bounds 239 */ putFloat(int off, float value)240 public void putFloat(int off, float value) throws BoundException { 241 final int count = JDWP.TypeSize.FLOAT; 242 243 if (count > CurrentSize - off) { 244 throw new BoundException("Unable to put " + count + " bytes of float value at " + 245 offsetString(off) + " (available bytes: " + (CurrentSize - off) + ")" ); 246 } 247 248 try { 249 long l = Float.floatToIntBits(value); 250 putValueBytes(off, l, count); 251 } catch (BoundException e) { 252 throw new Failure("Caught unexpected bound exception while putting " + count + 253 "bytes of float value at " + offsetString(off) + ":\n\t" + e); 254 } 255 } 256 257 /** 258 * Replace eight bytes starting at offset off with the bytes 259 * from the specified double value. 260 * 261 * @throws BoundException if offset is out of buffer bounds 262 */ putDouble(int off, double value)263 public void putDouble(int off, double value) throws BoundException { 264 final int count = JDWP.TypeSize.DOUBLE; 265 266 if (count > CurrentSize - off) { 267 throw new BoundException("Unable to put " + count + " bytes of double value at " + 268 offsetString(off) + " (available bytes: " + (CurrentSize - off) + ")" ); 269 } 270 271 try { 272 long l = Double.doubleToLongBits(value); 273 putValueBytes(off, l, count); 274 } catch (BoundException e) { 275 throw new Failure("Caught unexpected bound exception while putting " + count + 276 "bytes of double value at " + offsetString(off) + ": \n\t" + e); 277 } 278 } 279 280 /** 281 * Replace two bytes starting at offset off with the bytes 282 * from the specified char value. 283 * 284 * @throws BoundException if offset is out of buffer bounds 285 */ putChar(int off, char value)286 public void putChar(int off, char value) throws BoundException { 287 final int count = JDWP.TypeSize.CHAR; 288 289 if (count > CurrentSize - off) { 290 throw new BoundException("Unable to put " + count + " bytes of char value at " + 291 offsetString(off) + " (available bytes: " + (CurrentSize - off) + ")" ); 292 } 293 294 try { 295 long l = (long)value; 296 putValueBytes(off, l, count); 297 } catch (BoundException e) { 298 throw new Failure("Caught unexpected bound exception while putting " + count + 299 "bytes of char value at " + offsetString(off) + ":\n\t" + e); 300 } 301 } 302 303 ////////////////////////////////////////////////////////////////////////// 304 305 /** 306 * Append the specified byte to the end of this buffer. 307 */ addByte(byte value)308 public void addByte(byte value) { 309 checkSpace(1); 310 311 int where = CurrentSize; 312 CurrentSize++; 313 314 try { 315 putByte(where, value); 316 } 317 catch (BoundException e) { 318 throw new TestBug("Caught unexpected bound exception while adding one byte:\n\t" 319 + e); 320 }; 321 } 322 323 /** 324 * Append specified byte value repeated count to the end of this buffer. 325 */ addBytes(byte value, int count)326 public void addBytes(byte value, int count) { 327 checkSpace(count); 328 for (int i = 0; i < count; i++) { 329 addByte(value); 330 } 331 } 332 333 /** 334 * Append the bytes from the specified byte array to the end of this buffer. 335 */ addBytes(byte[] value, int start, int len)336 public void addBytes(byte[] value, int start, int len) { 337 checkSpace(len); 338 339 int where = CurrentSize; 340 CurrentSize = CurrentSize + len; 341 342 try { 343 putBytes(where, value, start, len); 344 } 345 catch (BoundException e) { 346 throw new TestBug("Caught unexpected bound exception while adding " + 347 len + " bytes:\n\t" + e); 348 }; 349 } 350 351 /** 352 * Appends the count (1 - 8) less significant bytes from the 353 * specified ID value to the end of this buffer. 354 */ addID(long value, int count)355 public void addID(long value, int count) { 356 if ((count <= 0) || (count > 8)) 357 throw new TestBug("Illegal number bytes of ID value to add: " + count); 358 359 final int where = CurrentSize; 360 addBytes(EMPTY_BYTE, count); 361 362 try { 363 putID(where, value, count); 364 } 365 catch (BoundException e) { 366 throw new TestBug("Caught unexpected bound exception while adding " + 367 count + " bytes of ID value:\n\t" + e); 368 }; 369 } 370 371 /** 372 * Append four bytes from the specified int value to the 373 * end of this buffer. 374 */ addInt(int value)375 public void addInt(int value) { 376 final int count = JDWP.TypeSize.INT; 377 final int where = CurrentSize; 378 addBytes(EMPTY_BYTE, count); 379 380 try { 381 putInt(where, value); 382 } 383 catch (BoundException e) { 384 throw new TestBug("Caught unexpected bound exception while adding " + 385 count + " bytes of int value:\n\t" + e); 386 }; 387 } 388 389 /** 390 * Append two bytes from the specified int value to the 391 * end of this buffer. 392 */ addShort(short value)393 public void addShort(short value) { 394 final int count = JDWP.TypeSize.SHORT; 395 final int where = CurrentSize; 396 addBytes(EMPTY_BYTE, count); 397 try { 398 putShort(where, value); 399 } 400 catch (BoundException e) { 401 throw new TestBug("Caught unexpected bound exception while adding " + 402 count + " bytes of short value:\n\t" + e); 403 }; 404 } 405 406 /** 407 * Appends eight bytes from the specified long 408 * value to the end of this buffer. 409 */ addLong(long value)410 public void addLong(long value) { 411 final int count = JDWP.TypeSize.LONG; 412 final int where = CurrentSize; 413 addBytes(EMPTY_BYTE, count); 414 try { 415 putLong(where, value); 416 } 417 catch (BoundException e) { 418 throw new TestBug("Caught unexpected bound exception while adding " + 419 count + " bytes of long value:\n\t" + e); 420 }; 421 } 422 423 /** 424 * Appends four bytes from the specified float 425 * value to the end of this buffer. 426 */ addFloat(float value)427 public void addFloat(float value) { 428 final int count = JDWP.TypeSize.FLOAT; 429 final int where = CurrentSize; 430 addBytes(EMPTY_BYTE, count); 431 try { 432 putFloat(where, value); 433 } 434 catch (BoundException e) { 435 throw new TestBug("Caught unexpected bound exception while adding " + 436 count + " bytes of float value:\n\t" + e); 437 }; 438 } 439 440 /** 441 * Appends eight bytes from the specified double 442 * value to the end of this buffer. 443 */ addDouble(double value)444 public void addDouble(double value) { 445 final int count = JDWP.TypeSize.DOUBLE; 446 final int where = CurrentSize; 447 addBytes(EMPTY_BYTE, count); 448 try { 449 putDouble(where, value); 450 } 451 catch (BoundException e) { 452 throw new TestBug("Caught unexpected bound exception while adding " + 453 count + " bytes of double value:\n\t" + e); 454 }; 455 } 456 457 /** 458 * Appends four bytes from the specified char 459 * value to the end of this buffer. 460 */ addChar(char value)461 public void addChar(char value) { 462 final int count = JDWP.TypeSize.CHAR; 463 final int where = CurrentSize; 464 addBytes(EMPTY_BYTE, count); 465 try { 466 putChar(where, value); 467 } 468 catch (BoundException e) { 469 throw new TestBug("Caught unexpected bound exception while adding " + 470 count + " bytes of float value:\n\t" + e); 471 }; 472 } 473 474 ////////////////////////////////////////////////////////////////////////// 475 476 /** 477 * Read a byte value from this buffer at the specified position. 478 * 479 * @throws BoundException if there are no bytes at this position 480 */ getByte(int off)481 public byte getByte(int off) throws BoundException { 482 if (off < 0 || off >= CurrentSize) { 483 throw new BoundException("Unable to get one byte at " + offsetString(off) + 484 ": no bytes available"); 485 } 486 return bytes[off]; 487 } 488 489 /** 490 * Read count bytes (1-8) from this buffer at the specified 491 * position and returns a long value composed of these bytes. 492 * 493 * @throws BoundException if there are no so many bytes at this position 494 */ getID(int off, int count)495 public long getID(int off, int count) throws BoundException { 496 if ((count <= 0) || (count > 8)) 497 throw new TestBug("Illegal number of bytes of ID value to get: " + count); 498 499 if (count > CurrentSize - off) { 500 throw new BoundException("Unable to get " + count + " bytes of ID value at " + 501 offsetString(off) + " (available bytes: " + (CurrentSize - off) + ")" ); 502 } 503 504 try { 505 return getValueBytes(off, count); 506 } 507 catch (BoundException e) { 508 throw new TestBug("Caught unexpected bound exception while getting " + 509 count + " bytes of ID value at " + offsetString(off) + ":\n\t" + e); 510 } 511 } 512 513 /** 514 * Read four bytes from this buffer at the specified 515 * position and returns an integer value composed of these bytes. 516 * 517 * @throws BoundException if there are no so many bytes at this position 518 */ getInt(int off)519 public int getInt(int off) throws BoundException { 520 final int count = JDWP.TypeSize.INT; 521 if (count > CurrentSize - off) { 522 throw new BoundException("Unable to get " + count + " bytes of int value at " + 523 offsetString(off) + " (available bytes: " + (CurrentSize - off) + ")" ); 524 } 525 526 try { 527 return (int)getValueBytes(off, count); 528 } 529 catch (BoundException e) { 530 throw new TestBug("Caught unexpected bound exception while getting " + 531 count + " bytes of int value at " + offsetString(off) + ":\n\t" + e); 532 } 533 } 534 535 /** 536 * Read two bytes from this buffer at the specified 537 * position and returns a short value composed of these bytes. 538 * 539 * @throws BoundException if there are no so many bytes at this position 540 */ getShort(int off)541 public short getShort(int off) throws BoundException { 542 final int count = JDWP.TypeSize.SHORT; 543 if (count > CurrentSize - off) { 544 throw new BoundException("Unable to get " + count + " bytes of short value at " + 545 offsetString(off) + " (available bytes: " + (CurrentSize - off) + ")" ); 546 } 547 548 try { 549 return (short)getValueBytes(off, count); 550 } 551 catch (BoundException e) { 552 throw new TestBug("Caught unexpected bound exception while getting " + 553 count + " bytes of short value at " + offsetString(off) + ":\n\t" + e); 554 } 555 } 556 557 /** 558 * Read eight bytes from this buffer at the specified 559 * position and returns a long value composed of these bytes. 560 * 561 * @throws BoundException if there are no so many bytes at this position 562 */ getLong(int off)563 public long getLong(int off) throws BoundException { 564 final int count = JDWP.TypeSize.LONG; 565 if (count > CurrentSize - off) { 566 throw new BoundException("Unable to get " + count + " bytes of long value at " + 567 offsetString(off) + " (available bytes: " + (CurrentSize - off) + ")" ); 568 } 569 570 try { 571 return getValueBytes(off, count); 572 } 573 catch (BoundException e) { 574 throw new TestBug("Caught unexpected bound exception while getting " + 575 count + " bytes of long value at " + offsetString(off) + ":\n\t" + e); 576 } 577 } 578 579 /** 580 * Read eight bytes from this buffer at the specified 581 * position and returns a double value composed of these bytes. 582 * 583 * @throws BoundException if there are no so many bytes at this position 584 */ getDouble(int off)585 public double getDouble(int off) throws BoundException { 586 final int count = JDWP.TypeSize.DOUBLE; 587 if (count > CurrentSize - off) { 588 throw new BoundException("Unable to get " + count + " bytes of double value at " + 589 offsetString(off) + " (available bytes: " + (CurrentSize - off) + ")" ); 590 } 591 592 try { 593 long value = getValueBytes(off, count); 594 return Double.longBitsToDouble(value); 595 } 596 catch (BoundException e) { 597 throw new TestBug("Caught unexpected bound exception while getting " + 598 count + " bytes of long value at " + offsetString(off) + ":\n\t" + e); 599 } 600 } 601 602 /** 603 * Read four bytes from this buffer at the specified 604 * position and returns a float value composed of these bytes. 605 * 606 * @throws BoundException if there are no so many bytes at this position 607 */ getFloat(int off)608 public float getFloat(int off) throws BoundException { 609 final int count = JDWP.TypeSize.FLOAT; 610 if (count > CurrentSize - off) { 611 throw new BoundException("Unable to get " + count + " bytes of float value at " + 612 offsetString(off) + " (available bytes: " + (CurrentSize - off) + ")" ); 613 } 614 615 try { 616 int value = (int)getValueBytes(off, count); 617 return Float.intBitsToFloat(value); 618 } 619 catch (BoundException e) { 620 throw new TestBug("Caught unexpected bound exception while getting " + 621 count + " bytes of float value at " + offsetString(off) + ":\n\t" + e); 622 } 623 } 624 625 /** 626 * Read two bytes from this buffer at the specified 627 * position and returns a char value composed of these bytes. 628 * 629 * @throws BoundException if there are no so many bytes at this position 630 */ getChar(int off)631 public char getChar(int off) throws BoundException { 632 final int count = JDWP.TypeSize.CHAR; 633 if (count > CurrentSize - off) { 634 throw new BoundException("Unable to get " + count + " bytes of char value at " + 635 offsetString(off) + " (available bytes: " + (CurrentSize - off) + ")" ); 636 } 637 638 try { 639 int value = (int)getValueBytes(off, count); 640 return (char)value; 641 } 642 catch (BoundException e) { 643 throw new TestBug("Caught unexpected bound exception while getting " + 644 count + " bytes of char value at " + offsetString(off) + ":\n\t" + e); 645 } 646 } 647 648 ////////////////////////////////////////////////////////////////////////// 649 650 /** 651 * Set the current parser position to 0. 652 */ resetPosition()653 public void resetPosition() { 654 resetPosition(0); 655 } 656 657 /** 658 * Set the current parser position to the specified value. 659 */ resetPosition(int i)660 public void resetPosition(int i) { 661 parseOffset = i; 662 } 663 664 /** 665 * Return current parser position. 666 */ currentPosition()667 public int currentPosition() { 668 return parseOffset; 669 } 670 671 /** 672 * Return true if the parser pointer is set to the end of buffer. 673 */ isParsed()674 public boolean isParsed() { 675 return (parseOffset == CurrentSize); 676 } 677 678 /** 679 * Read a byte value from this buffer at the current parser position. 680 * 681 * @throws BoundException if there are no more bytes in the buffer 682 */ getByte()683 public byte getByte() throws BoundException { 684 return getByte(parseOffset++); 685 } 686 687 /** 688 * Read count bytes (1-8) from this buffer at the current parser 689 * position and returns a long value composed of these bytes. 690 * 691 * @throws BoundException if there are no so many bytes in the buffer 692 */ getID(int count)693 public long getID(int count) throws BoundException { 694 long value = getID(parseOffset, count); 695 parseOffset += count; 696 return value; 697 } 698 699 /** 700 * Read four bytes from this buffer at the current parser 701 * position and returns an integer value composed of these bytes. 702 * 703 * @throws BoundException if there are no so many bytes in the buffer 704 */ getInt()705 public int getInt() throws BoundException { 706 final int count = JDWP.TypeSize.INT; 707 int value = getInt(parseOffset); 708 parseOffset += count; 709 return value; 710 } 711 712 /** 713 * Read two bytes from this buffer at the current parser 714 * position and returns a short value composed of these bytes. 715 * 716 * @throws BoundException if there are no so many bytes in the buffer 717 */ getShort()718 public short getShort() throws BoundException { 719 final int count = JDWP.TypeSize.SHORT; 720 short value = getShort(parseOffset); 721 parseOffset += count; 722 return value; 723 } 724 725 /** 726 * Read eight bytes from this buffer at the current parser 727 * position and returns a long value composed of these bytes. 728 * 729 * @throws BoundException if there are no so many bytes in the buffer 730 */ getLong()731 public long getLong() throws BoundException { 732 final int count = JDWP.TypeSize.LONG; 733 long value = getLong(parseOffset); 734 parseOffset += count; 735 return value; 736 } 737 738 /** 739 * Read eight bytes from this buffer at the current parser 740 * position and returns a double value composed of these bytes. 741 * 742 * @throws BoundException if there are no so many bytes in the buffer 743 */ getDouble()744 public double getDouble() throws BoundException { 745 final int count = JDWP.TypeSize.DOUBLE; 746 double value = getDouble(parseOffset); 747 parseOffset += count; 748 return value; 749 } 750 751 /** 752 * Read four bytes from this buffer at the current parser 753 * position and returns a float value composed of these bytes. 754 * 755 * @throws BoundException if there are no so many bytes in the buffer 756 */ getFloat()757 public float getFloat() throws BoundException { 758 final int count = JDWP.TypeSize.FLOAT; 759 float value = getFloat(parseOffset); 760 parseOffset += count; 761 return value; 762 } 763 764 /** 765 * Read two bytes from this buffer at the current parser 766 * position and returns a char value composed of these bytes. 767 * 768 * @throws BoundException if there are no so many bytes in the buffer 769 */ getChar()770 public char getChar() throws BoundException { 771 final int count = JDWP.TypeSize.CHAR; 772 char value = getChar(parseOffset); 773 parseOffset += count; 774 return value; 775 } 776 777 /** 778 * Remove at least first count bytes from the buffer. 779 */ 780 deleteBytes(int count)781 public void deleteBytes(int count) { 782 int j = 0; 783 while (count < CurrentSize) 784 bytes[j++] = bytes[count++]; 785 786 CurrentSize = j; 787 } 788 789 /** 790 * Clear the buffer. 791 */ resetBuffer()792 public void resetBuffer() { 793 CurrentSize = 0; 794 } 795 796 /** 797 * Return string representation of the buffer starting at given offset. 798 */ toString(int start)799 public String toString(int start) { 800 801 String Result = "", HexLine = "", DisplayLine = ""; 802 803 int j = 0; 804 805 for (int i = start; i < length(); i++) { 806 807 HexLine = HexLine + toHexString(bytes[i], 2) + " "; 808 809 String ch = "."; 810 if (bytes[i] >= 0x20 && bytes[i] < 0x80) { 811 try { 812 ch = new String(bytes, i, 1, "US-ASCII"); 813 } catch (UnsupportedEncodingException ignore) { 814 } 815 } 816 DisplayLine = DisplayLine + ch; 817 818 if ((i == length() - 1) || (((i - start) & 0x0F) == 0x0F)) { 819 Result = Result + 820 " " + 821 toHexString(j, 4) + ": " + 822 PadR(HexLine, 48) + " " + 823 DisplayLine + "\n"; 824 HexLine = ""; 825 DisplayLine = ""; 826 j = j + 16; 827 } 828 } 829 return Result; 830 } 831 832 /** 833 * Return string representation of the buffer. 834 */ toString()835 public String toString() { 836 return toString(0); 837 } 838 839 /** 840 * Return string with hexadecimal representation of bytes. 841 */ toHexString(long b, int length)842 public static String toHexString(long b, int length) { 843 return Right(Long.toHexString(b), length).replace(' ', '0'); 844 } 845 846 /** 847 * Return string with hexadecimal representation of bytes. 848 */ toHexDecString(long b, int length)849 public static String toHexDecString(long b, int length) { 850 return toHexString(b, length) + " (" + b + ")"; 851 } 852 853 // ----- 854 855 /** 856 * Return string with hexadecimal representation of offset. 857 */ offsetString(int off)858 public static String offsetString(int off) { 859 return "0x" + toHexString(off, 4); 860 } 861 862 /** 863 * Return string with hexadecimal representation of the current offset. 864 */ offsetString()865 public String offsetString() { 866 return offsetString(currentPosition()); 867 } 868 869 // ----- 870 871 /** 872 * Check if there space for new bytes in the buffer. 873 */ checkSpace(int space)874 protected void checkSpace(int space) { 875 876 int newSize = CurrentSize + space; 877 878 if (bytes.length >= newSize) 879 return; 880 881 byte[] newBytes = new byte[newSize]; 882 883 for (int i = 0; i < CurrentSize; i++) 884 newBytes[i] = bytes[i]; 885 886 bytes = newBytes; 887 } 888 889 /** 890 * Replace count (1 - 8) bytes starting at offset off with the less 891 * significant bytes from the specified long value. 892 * 893 * @throws BoundException if offset and count are out of buffer bounds 894 */ putValueBytes(int off, long value, int count)895 protected void putValueBytes(int off, long value, int count) throws BoundException { 896 if ((count <= 0) || (count > 8)) 897 throw new TestBug("Illegal number of bytes of value to put: " + count); 898 899 if (count > CurrentSize - off) { 900 throw new BoundException("Unable to put " + count + " bytes of value at " + 901 off + " (available bytes: " + (CurrentSize - off) + ")" ); 902 } 903 904 int shift = (count - 1) * 8; 905 for (int i = 0; i < count; i++) { 906 putByte(off++, (byte) ((value >>> shift) & 0xFF)); 907 shift = shift - 8; 908 } 909 } 910 /** 911 * Appends the count (1 - 8) less significant bytes from the 912 * specified long value to the end of this buffer. 913 */ addValueBytes(long value, int count)914 protected void addValueBytes(long value, int count) throws BoundException { 915 if ((count <= 0) || (count > 8)) 916 throw new TestBug("Illegal number of bytes of value to add: " + count); 917 918 checkSpace(count); 919 920 int where = CurrentSize; 921 CurrentSize += count; 922 923 putValueBytes(where, value, count); 924 } 925 926 /** 927 * Read count bytes (1-8) from this buffer at the specified 928 * position and returns a long value composed of these bytes. 929 * 930 * @throws BoundException if there are no so many bytes in the buffer 931 */ getValueBytes(int off, int count)932 public long getValueBytes(int off, int count) throws BoundException { 933 if ((count <= 0) || (count > 8)) 934 throw new TestBug("Illegal number of bytes of value to get: " + count); 935 936 long l = 0; 937 938 for (int i = 0; i < count; i++) { 939 l = (l * 0x100) + ((long) getByte(off + i) & 0xFF); 940 } 941 942 return l; 943 } 944 945 /** 946 * Read count bytes (1-8) from this buffer at the current parser 947 * position and returns a long value composed of these bytes. 948 * 949 * @throws BoundException if there are no so many bytes in the buffer 950 */ 951 /* 952 protected long getValueBytes(int count) throws BoundException { 953 long value = getValueBytes(parseOffset); 954 parseOffset += count; 955 return value; 956 } 957 */ 958 959 // --- 960 PadL(String source, int length, String what)961 private static String PadL(String source, int length, String what) { 962 963 if (length <= 0) 964 return ""; 965 966 if (source.length() > length) 967 return PadL("", length, "*"); 968 969 while (source.length() < length) 970 source = what + source; 971 972 return source; 973 } 974 975 PadL(String source, int length)976 private static String PadL(String source, int length) { 977 return PadL(source, length, " "); 978 } 979 PadR(String source, int length, String what)980 private static String PadR(String source, int length, String what) { 981 982 if (length <= 0) 983 return ""; 984 985 if (source.length() > length) 986 return PadR("", length, "*"); 987 988 while (source.length() < length) 989 source = source + what; 990 991 return source; 992 } 993 PadR(String source, int length)994 private static String PadR(String source, int length) { 995 return PadR(source, length, " "); 996 } 997 Left(String source, int length)998 private static String Left(String source, int length) { 999 1000 if (length <= 0) 1001 return ""; 1002 1003 if (length <= source.length()) 1004 return source.substring(0, length); 1005 else 1006 return PadR(source, length); 1007 } 1008 Right(String source, int length)1009 private static String Right(String source, int length) { 1010 1011 if (length <= 0) 1012 return ""; 1013 1014 if (length <= source.length()) 1015 return source.substring(source.length() - length, source.length()); 1016 else 1017 return PadL(source, length); 1018 } 1019 1020 } 1021