| /* |
| * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| |
| package nsk.share.jdwp; |
| |
| import java.io.*; |
| import nsk.share.*; |
| |
| /** |
| * This class represents a byte buffer of variable size. |
| */ |
| public class ByteBuffer { |
| |
| /** |
| * Empty byte value (zero). |
| */ |
| private static final byte EMPTY_BYTE = (byte)0; |
| |
| /** |
| * Current number of bytes in the buffer. |
| */ |
| private int CurrentSize; |
| |
| /** |
| * Delta to increase buffer size. |
| */ |
| private int Delta; |
| |
| /** |
| * Current offset from the buffer begin during parsing packet. |
| */ |
| int parseOffset; |
| |
| /** |
| * Array of bytes in the buffer. |
| */ |
| protected byte[] bytes; |
| |
| /** |
| * Make an empty <code>ByteBuffer</code> object. |
| */ |
| public ByteBuffer() { |
| this(128, 128); |
| } |
| |
| /** |
| * Make an empty <code>ByteBuffer</code> object with given initial capacity. |
| * When there is no space for a new byte in a buffer it's capacity |
| * grows by Delta. |
| */ |
| public ByteBuffer(int InitialSize, int Delta) { |
| if (Delta <= 0) |
| Delta = 16; |
| this.Delta = Delta; |
| CurrentSize = 0; |
| bytes = new byte[InitialSize]; |
| parseOffset = 0; |
| } |
| |
| /** |
| * Make a copy of specified byte buffer. |
| */ |
| public ByteBuffer(ByteBuffer buffer) { |
| int InitialSize = buffer.bytes.length; |
| Delta = buffer.Delta; |
| CurrentSize = buffer.CurrentSize; |
| bytes = new byte[InitialSize]; |
| for (int i = 0; i < CurrentSize; i++ ) { |
| bytes[i] = buffer.bytes[i]; |
| } |
| parseOffset = 0; |
| } |
| |
| /** |
| * Return number of bytes in this buffer. |
| */ |
| public int length() { |
| return CurrentSize; |
| } |
| |
| /** |
| * Return array of bytes in this buffer. |
| */ |
| public byte[] getBytes() { |
| return bytes; |
| } |
| |
| ////////////////////////////////////////////////////////////////////////// |
| |
| /** |
| * Replace the byte at the specified offset in this buffer with the |
| * less significant byte from the int value. |
| * |
| * @throws BoundException if specified offset is out of buffer bounds |
| */ |
| public void putByte(int off, byte value) throws BoundException { |
| |
| if ((off < 0) || (off >= CurrentSize)) |
| throw new BoundException("Unable to put one byte at " + offsetString(off)); |
| |
| bytes[off] = value; |
| } |
| |
| /** |
| * Replace len bytes starting at offset off with the bytes from the |
| * given byte array. |
| * |
| * @throws BoundException if offset and length are out of buffer bounds |
| */ |
| public void putBytes(int off, byte[] value, int start, int len) throws BoundException { |
| if (len > (CurrentSize - off)) { |
| throw new BoundException("Unable to put " + len + " bytes at " + offsetString(off) + |
| " (available bytes: " + (CurrentSize - off) + ")" ); |
| } |
| try { |
| for (int i = 0; i < len; i++) |
| putByte(off++, value[start++]); |
| } catch (BoundException e) { |
| throw new Failure("Caught unexpected bound exception while putting " + len + |
| "bytes at " + offsetString(off) + ":\n\t" + e); |
| } |
| } |
| |
| /** |
| * Replace count (1 - 8) bytes starting at offset off with the less |
| * significant bytes from the specified ID value. |
| * |
| * @throws BoundException if offset and count are out of buffer bounds |
| */ |
| public void putID(int off, long value, int count) throws BoundException { |
| |
| if ((count <= 0) || (count > 8)) |
| throw new TestBug("Illegal number of bytes of ID value to put: " + count); |
| |
| if (count > CurrentSize - off) { |
| throw new BoundException("Unable to put " + count + " bytes of ID value at " + |
| offsetString(off) + " (available bytes: " + (CurrentSize - off) + ")" ); |
| } |
| |
| try { |
| putValueBytes(off, value, count); |
| } catch (BoundException e) { |
| throw new Failure("Caught unexpected bound exception while putting " + count + |
| "bytes of ID value at " + offsetString(off) + ":\n\t" + e); |
| } |
| } |
| |
| /** |
| * Replace four bytes starting at offset off with the bytes from the |
| * specified int value. |
| * |
| * @throws BoundException if offset is out of buffer bounds |
| */ |
| public void putInt(int off, int value) throws BoundException { |
| final int count = JDWP.TypeSize.INT; |
| |
| if (count > CurrentSize - off) { |
| throw new BoundException("Unable to put " + count + " bytes of int value at " + |
| offsetString(off) + " (available bytes: " + (CurrentSize - off) + ")" ); |
| } |
| |
| try { |
| putValueBytes(off, value, count); |
| } catch (BoundException e) { |
| throw new Failure("Caught unexpected bound exception while putting " + count + |
| "bytes of int value at " + offsetString(off) + ":\n\t" + e); |
| } |
| } |
| |
| /** |
| * Replace two bytes starting at offset off with the bytes |
| * from the specified short value. |
| * |
| * @throws BoundException if offset is out of buffer bounds |
| */ |
| public void putShort(int off, short value) throws BoundException { |
| final int count = JDWP.TypeSize.SHORT; |
| |
| if (count > CurrentSize - off) { |
| throw new BoundException("Unable to put " + count + " bytes of short value at " + |
| offsetString(off) + " (available bytes: " + (CurrentSize - off) + ")" ); |
| } |
| |
| try { |
| putValueBytes(off, value, count); |
| } catch (BoundException e) { |
| throw new Failure("Caught unexpected bound exception while putting " + count + |
| "bytes of short value at " + offsetString(off) + ":\n\t" + e); |
| } |
| } |
| |
| /** |
| * Replace eight bytes starting at offset off with the bytes |
| * from the specified long value. |
| * |
| * @throws BoundException if offset is out of buffer bounds |
| */ |
| public void putLong(int off, long value) throws BoundException { |
| final int count = JDWP.TypeSize.LONG; |
| |
| if (count > CurrentSize - off) { |
| throw new BoundException("Unable to put " + count + " bytes of long value at " + |
| offsetString(off) + " (available bytes: " + (CurrentSize - off) + ")" ); |
| } |
| |
| try { |
| putValueBytes(off, value, count); |
| } catch (BoundException e) { |
| throw new Failure("Caught unexpected bound exception while putting " + count + |
| "bytes of long value at " + offsetString(off) + ":\n\t" + e); |
| } |
| } |
| |
| /** |
| * Replace four bytes starting at offset off with the bytes |
| * from the specified float value. |
| * |
| * @throws BoundException if offset is out of buffer bounds |
| */ |
| public void putFloat(int off, float value) throws BoundException { |
| final int count = JDWP.TypeSize.FLOAT; |
| |
| if (count > CurrentSize - off) { |
| throw new BoundException("Unable to put " + count + " bytes of float value at " + |
| offsetString(off) + " (available bytes: " + (CurrentSize - off) + ")" ); |
| } |
| |
| try { |
| long l = Float.floatToIntBits(value); |
| putValueBytes(off, l, count); |
| } catch (BoundException e) { |
| throw new Failure("Caught unexpected bound exception while putting " + count + |
| "bytes of float value at " + offsetString(off) + ":\n\t" + e); |
| } |
| } |
| |
| /** |
| * Replace eight bytes starting at offset off with the bytes |
| * from the specified double value. |
| * |
| * @throws BoundException if offset is out of buffer bounds |
| */ |
| public void putDouble(int off, double value) throws BoundException { |
| final int count = JDWP.TypeSize.DOUBLE; |
| |
| if (count > CurrentSize - off) { |
| throw new BoundException("Unable to put " + count + " bytes of double value at " + |
| offsetString(off) + " (available bytes: " + (CurrentSize - off) + ")" ); |
| } |
| |
| try { |
| long l = Double.doubleToLongBits(value); |
| putValueBytes(off, l, count); |
| } catch (BoundException e) { |
| throw new Failure("Caught unexpected bound exception while putting " + count + |
| "bytes of double value at " + offsetString(off) + ": \n\t" + e); |
| } |
| } |
| |
| /** |
| * Replace two bytes starting at offset off with the bytes |
| * from the specified char value. |
| * |
| * @throws BoundException if offset is out of buffer bounds |
| */ |
| public void putChar(int off, char value) throws BoundException { |
| final int count = JDWP.TypeSize.CHAR; |
| |
| if (count > CurrentSize - off) { |
| throw new BoundException("Unable to put " + count + " bytes of char value at " + |
| offsetString(off) + " (available bytes: " + (CurrentSize - off) + ")" ); |
| } |
| |
| try { |
| long l = (long)value; |
| putValueBytes(off, l, count); |
| } catch (BoundException e) { |
| throw new Failure("Caught unexpected bound exception while putting " + count + |
| "bytes of char value at " + offsetString(off) + ":\n\t" + e); |
| } |
| } |
| |
| ////////////////////////////////////////////////////////////////////////// |
| |
| /** |
| * Append the specified byte to the end of this buffer. |
| */ |
| public void addByte(byte value) { |
| checkSpace(1); |
| |
| int where = CurrentSize; |
| CurrentSize++; |
| |
| try { |
| putByte(where, value); |
| } |
| catch (BoundException e) { |
| throw new TestBug("Caught unexpected bound exception while adding one byte:\n\t" |
| + e); |
| }; |
| } |
| |
| /** |
| * Append specified byte value repeated count to the end of this buffer. |
| */ |
| public void addBytes(byte value, int count) { |
| checkSpace(count); |
| for (int i = 0; i < count; i++) { |
| addByte(value); |
| } |
| } |
| |
| /** |
| * Append the bytes from the specified byte array to the end of this buffer. |
| */ |
| public void addBytes(byte[] value, int start, int len) { |
| checkSpace(len); |
| |
| int where = CurrentSize; |
| CurrentSize = CurrentSize + len; |
| |
| try { |
| putBytes(where, value, start, len); |
| } |
| catch (BoundException e) { |
| throw new TestBug("Caught unexpected bound exception while adding " + |
| len + " bytes:\n\t" + e); |
| }; |
| } |
| |
| /** |
| * Appends the count (1 - 8) less significant bytes from the |
| * specified ID value to the end of this buffer. |
| */ |
| public void addID(long value, int count) { |
| if ((count <= 0) || (count > 8)) |
| throw new TestBug("Illegal number bytes of ID value to add: " + count); |
| |
| final int where = CurrentSize; |
| addBytes(EMPTY_BYTE, count); |
| |
| try { |
| putID(where, value, count); |
| } |
| catch (BoundException e) { |
| throw new TestBug("Caught unexpected bound exception while adding " + |
| count + " bytes of ID value:\n\t" + e); |
| }; |
| } |
| |
| /** |
| * Append four bytes from the specified int value to the |
| * end of this buffer. |
| */ |
| public void addInt(int value) { |
| final int count = JDWP.TypeSize.INT; |
| final int where = CurrentSize; |
| addBytes(EMPTY_BYTE, count); |
| |
| try { |
| putInt(where, value); |
| } |
| catch (BoundException e) { |
| throw new TestBug("Caught unexpected bound exception while adding " + |
| count + " bytes of int value:\n\t" + e); |
| }; |
| } |
| |
| /** |
| * Append two bytes from the specified int value to the |
| * end of this buffer. |
| */ |
| public void addShort(short value) { |
| final int count = JDWP.TypeSize.SHORT; |
| final int where = CurrentSize; |
| addBytes(EMPTY_BYTE, count); |
| try { |
| putShort(where, value); |
| } |
| catch (BoundException e) { |
| throw new TestBug("Caught unexpected bound exception while adding " + |
| count + " bytes of short value:\n\t" + e); |
| }; |
| } |
| |
| /** |
| * Appends eight bytes from the specified long |
| * value to the end of this buffer. |
| */ |
| public void addLong(long value) { |
| final int count = JDWP.TypeSize.LONG; |
| final int where = CurrentSize; |
| addBytes(EMPTY_BYTE, count); |
| try { |
| putLong(where, value); |
| } |
| catch (BoundException e) { |
| throw new TestBug("Caught unexpected bound exception while adding " + |
| count + " bytes of long value:\n\t" + e); |
| }; |
| } |
| |
| /** |
| * Appends four bytes from the specified float |
| * value to the end of this buffer. |
| */ |
| public void addFloat(float value) { |
| final int count = JDWP.TypeSize.FLOAT; |
| final int where = CurrentSize; |
| addBytes(EMPTY_BYTE, count); |
| try { |
| putFloat(where, value); |
| } |
| catch (BoundException e) { |
| throw new TestBug("Caught unexpected bound exception while adding " + |
| count + " bytes of float value:\n\t" + e); |
| }; |
| } |
| |
| /** |
| * Appends eight bytes from the specified double |
| * value to the end of this buffer. |
| */ |
| public void addDouble(double value) { |
| final int count = JDWP.TypeSize.DOUBLE; |
| final int where = CurrentSize; |
| addBytes(EMPTY_BYTE, count); |
| try { |
| putDouble(where, value); |
| } |
| catch (BoundException e) { |
| throw new TestBug("Caught unexpected bound exception while adding " + |
| count + " bytes of double value:\n\t" + e); |
| }; |
| } |
| |
| /** |
| * Appends four bytes from the specified char |
| * value to the end of this buffer. |
| */ |
| public void addChar(char value) { |
| final int count = JDWP.TypeSize.CHAR; |
| final int where = CurrentSize; |
| addBytes(EMPTY_BYTE, count); |
| try { |
| putChar(where, value); |
| } |
| catch (BoundException e) { |
| throw new TestBug("Caught unexpected bound exception while adding " + |
| count + " bytes of float value:\n\t" + e); |
| }; |
| } |
| |
| ////////////////////////////////////////////////////////////////////////// |
| |
| /** |
| * Read a byte value from this buffer at the specified position. |
| * |
| * @throws BoundException if there are no bytes at this position |
| */ |
| public byte getByte(int off) throws BoundException { |
| if (off < 0 || off >= CurrentSize) { |
| throw new BoundException("Unable to get one byte at " + offsetString(off) + |
| ": no bytes available"); |
| } |
| return bytes[off]; |
| } |
| |
| /** |
| * Read count bytes (1-8) from this buffer at the specified |
| * position and returns a long value composed of these bytes. |
| * |
| * @throws BoundException if there are no so many bytes at this position |
| */ |
| public long getID(int off, int count) throws BoundException { |
| if ((count <= 0) || (count > 8)) |
| throw new TestBug("Illegal number of bytes of ID value to get: " + count); |
| |
| if (count > CurrentSize - off) { |
| throw new BoundException("Unable to get " + count + " bytes of ID value at " + |
| offsetString(off) + " (available bytes: " + (CurrentSize - off) + ")" ); |
| } |
| |
| try { |
| return getValueBytes(off, count); |
| } |
| catch (BoundException e) { |
| throw new TestBug("Caught unexpected bound exception while getting " + |
| count + " bytes of ID value at " + offsetString(off) + ":\n\t" + e); |
| } |
| } |
| |
| /** |
| * Read four bytes from this buffer at the specified |
| * position and returns an integer value composed of these bytes. |
| * |
| * @throws BoundException if there are no so many bytes at this position |
| */ |
| public int getInt(int off) throws BoundException { |
| final int count = JDWP.TypeSize.INT; |
| if (count > CurrentSize - off) { |
| throw new BoundException("Unable to get " + count + " bytes of int value at " + |
| offsetString(off) + " (available bytes: " + (CurrentSize - off) + ")" ); |
| } |
| |
| try { |
| return (int)getValueBytes(off, count); |
| } |
| catch (BoundException e) { |
| throw new TestBug("Caught unexpected bound exception while getting " + |
| count + " bytes of int value at " + offsetString(off) + ":\n\t" + e); |
| } |
| } |
| |
| /** |
| * Read two bytes from this buffer at the specified |
| * position and returns a short value composed of these bytes. |
| * |
| * @throws BoundException if there are no so many bytes at this position |
| */ |
| public short getShort(int off) throws BoundException { |
| final int count = JDWP.TypeSize.SHORT; |
| if (count > CurrentSize - off) { |
| throw new BoundException("Unable to get " + count + " bytes of short value at " + |
| offsetString(off) + " (available bytes: " + (CurrentSize - off) + ")" ); |
| } |
| |
| try { |
| return (short)getValueBytes(off, count); |
| } |
| catch (BoundException e) { |
| throw new TestBug("Caught unexpected bound exception while getting " + |
| count + " bytes of short value at " + offsetString(off) + ":\n\t" + e); |
| } |
| } |
| |
| /** |
| * Read eight bytes from this buffer at the specified |
| * position and returns a long value composed of these bytes. |
| * |
| * @throws BoundException if there are no so many bytes at this position |
| */ |
| public long getLong(int off) throws BoundException { |
| final int count = JDWP.TypeSize.LONG; |
| if (count > CurrentSize - off) { |
| throw new BoundException("Unable to get " + count + " bytes of long value at " + |
| offsetString(off) + " (available bytes: " + (CurrentSize - off) + ")" ); |
| } |
| |
| try { |
| return getValueBytes(off, count); |
| } |
| catch (BoundException e) { |
| throw new TestBug("Caught unexpected bound exception while getting " + |
| count + " bytes of long value at " + offsetString(off) + ":\n\t" + e); |
| } |
| } |
| |
| /** |
| * Read eight bytes from this buffer at the specified |
| * position and returns a double value composed of these bytes. |
| * |
| * @throws BoundException if there are no so many bytes at this position |
| */ |
| public double getDouble(int off) throws BoundException { |
| final int count = JDWP.TypeSize.DOUBLE; |
| if (count > CurrentSize - off) { |
| throw new BoundException("Unable to get " + count + " bytes of double value at " + |
| offsetString(off) + " (available bytes: " + (CurrentSize - off) + ")" ); |
| } |
| |
| try { |
| long value = getValueBytes(off, count); |
| return Double.longBitsToDouble(value); |
| } |
| catch (BoundException e) { |
| throw new TestBug("Caught unexpected bound exception while getting " + |
| count + " bytes of long value at " + offsetString(off) + ":\n\t" + e); |
| } |
| } |
| |
| /** |
| * Read four bytes from this buffer at the specified |
| * position and returns a float value composed of these bytes. |
| * |
| * @throws BoundException if there are no so many bytes at this position |
| */ |
| public float getFloat(int off) throws BoundException { |
| final int count = JDWP.TypeSize.FLOAT; |
| if (count > CurrentSize - off) { |
| throw new BoundException("Unable to get " + count + " bytes of float value at " + |
| offsetString(off) + " (available bytes: " + (CurrentSize - off) + ")" ); |
| } |
| |
| try { |
| int value = (int)getValueBytes(off, count); |
| return Float.intBitsToFloat(value); |
| } |
| catch (BoundException e) { |
| throw new TestBug("Caught unexpected bound exception while getting " + |
| count + " bytes of float value at " + offsetString(off) + ":\n\t" + e); |
| } |
| } |
| |
| /** |
| * Read two bytes from this buffer at the specified |
| * position and returns a char value composed of these bytes. |
| * |
| * @throws BoundException if there are no so many bytes at this position |
| */ |
| public char getChar(int off) throws BoundException { |
| final int count = JDWP.TypeSize.CHAR; |
| if (count > CurrentSize - off) { |
| throw new BoundException("Unable to get " + count + " bytes of char value at " + |
| offsetString(off) + " (available bytes: " + (CurrentSize - off) + ")" ); |
| } |
| |
| try { |
| int value = (int)getValueBytes(off, count); |
| return (char)value; |
| } |
| catch (BoundException e) { |
| throw new TestBug("Caught unexpected bound exception while getting " + |
| count + " bytes of char value at " + offsetString(off) + ":\n\t" + e); |
| } |
| } |
| |
| ////////////////////////////////////////////////////////////////////////// |
| |
| /** |
| * Set the current parser position to 0. |
| */ |
| public void resetPosition() { |
| resetPosition(0); |
| } |
| |
| /** |
| * Set the current parser position to the specified value. |
| */ |
| public void resetPosition(int i) { |
| parseOffset = i; |
| } |
| |
| /** |
| * Return current parser position. |
| */ |
| public int currentPosition() { |
| return parseOffset; |
| } |
| |
| /** |
| * Return true if the parser pointer is set to the end of buffer. |
| */ |
| public boolean isParsed() { |
| return (parseOffset == CurrentSize); |
| } |
| |
| /** |
| * Read a byte value from this buffer at the current parser position. |
| * |
| * @throws BoundException if there are no more bytes in the buffer |
| */ |
| public byte getByte() throws BoundException { |
| return getByte(parseOffset++); |
| } |
| |
| /** |
| * Read count bytes (1-8) from this buffer at the current parser |
| * position and returns a long value composed of these bytes. |
| * |
| * @throws BoundException if there are no so many bytes in the buffer |
| */ |
| public long getID(int count) throws BoundException { |
| long value = getID(parseOffset, count); |
| parseOffset += count; |
| return value; |
| } |
| |
| /** |
| * Read four bytes from this buffer at the current parser |
| * position and returns an integer value composed of these bytes. |
| * |
| * @throws BoundException if there are no so many bytes in the buffer |
| */ |
| public int getInt() throws BoundException { |
| final int count = JDWP.TypeSize.INT; |
| int value = getInt(parseOffset); |
| parseOffset += count; |
| return value; |
| } |
| |
| /** |
| * Read two bytes from this buffer at the current parser |
| * position and returns a short value composed of these bytes. |
| * |
| * @throws BoundException if there are no so many bytes in the buffer |
| */ |
| public short getShort() throws BoundException { |
| final int count = JDWP.TypeSize.SHORT; |
| short value = getShort(parseOffset); |
| parseOffset += count; |
| return value; |
| } |
| |
| /** |
| * Read eight bytes from this buffer at the current parser |
| * position and returns a long value composed of these bytes. |
| * |
| * @throws BoundException if there are no so many bytes in the buffer |
| */ |
| public long getLong() throws BoundException { |
| final int count = JDWP.TypeSize.LONG; |
| long value = getLong(parseOffset); |
| parseOffset += count; |
| return value; |
| } |
| |
| /** |
| * Read eight bytes from this buffer at the current parser |
| * position and returns a double value composed of these bytes. |
| * |
| * @throws BoundException if there are no so many bytes in the buffer |
| */ |
| public double getDouble() throws BoundException { |
| final int count = JDWP.TypeSize.DOUBLE; |
| double value = getDouble(parseOffset); |
| parseOffset += count; |
| return value; |
| } |
| |
| /** |
| * Read four bytes from this buffer at the current parser |
| * position and returns a float value composed of these bytes. |
| * |
| * @throws BoundException if there are no so many bytes in the buffer |
| */ |
| public float getFloat() throws BoundException { |
| final int count = JDWP.TypeSize.FLOAT; |
| float value = getFloat(parseOffset); |
| parseOffset += count; |
| return value; |
| } |
| |
| /** |
| * Read two bytes from this buffer at the current parser |
| * position and returns a char value composed of these bytes. |
| * |
| * @throws BoundException if there are no so many bytes in the buffer |
| */ |
| public char getChar() throws BoundException { |
| final int count = JDWP.TypeSize.CHAR; |
| char value = getChar(parseOffset); |
| parseOffset += count; |
| return value; |
| } |
| |
| /** |
| * Remove at least first count bytes from the buffer. |
| */ |
| |
| public void deleteBytes(int count) { |
| int j = 0; |
| while (count < CurrentSize) |
| bytes[j++] = bytes[count++]; |
| |
| CurrentSize = j; |
| } |
| |
| /** |
| * Clear the buffer. |
| */ |
| public void resetBuffer() { |
| CurrentSize = 0; |
| } |
| |
| /** |
| * Return string representation of the buffer starting at given offset. |
| */ |
| public String toString(int start) { |
| |
| String Result = "", HexLine = "", DisplayLine = ""; |
| |
| int j = 0; |
| |
| for (int i = start; i < length(); i++) { |
| |
| HexLine = HexLine + toHexString(bytes[i], 2) + " "; |
| |
| String ch = "."; |
| if (bytes[i] >= 0x20 && bytes[i] < 0x80) { |
| try { |
| ch = new String(bytes, i, 1, "US-ASCII"); |
| } catch (UnsupportedEncodingException ignore) { |
| } |
| } |
| DisplayLine = DisplayLine + ch; |
| |
| if ((i == length() - 1) || (((i - start) & 0x0F) == 0x0F)) { |
| Result = Result + |
| " " + |
| toHexString(j, 4) + ": " + |
| PadR(HexLine, 48) + " " + |
| DisplayLine + "\n"; |
| HexLine = ""; |
| DisplayLine = ""; |
| j = j + 16; |
| } |
| } |
| return Result; |
| } |
| |
| /** |
| * Return string representation of the buffer. |
| */ |
| public String toString() { |
| return toString(0); |
| } |
| |
| /** |
| * Return string with hexadecimal representation of bytes. |
| */ |
| public static String toHexString(long b, int length) { |
| return Right(Long.toHexString(b), length).replace(' ', '0'); |
| } |
| |
| /** |
| * Return string with hexadecimal representation of bytes. |
| */ |
| public static String toHexDecString(long b, int length) { |
| return toHexString(b, length) + " (" + b + ")"; |
| } |
| |
| // ----- |
| |
| /** |
| * Return string with hexadecimal representation of offset. |
| */ |
| public static String offsetString(int off) { |
| return "0x" + toHexString(off, 4); |
| } |
| |
| /** |
| * Return string with hexadecimal representation of the current offset. |
| */ |
| public String offsetString() { |
| return offsetString(currentPosition()); |
| } |
| |
| // ----- |
| |
| /** |
| * Check if there space for new bytes in the buffer. |
| */ |
| protected void checkSpace(int space) { |
| |
| int newSize = CurrentSize + space; |
| |
| if (bytes.length >= newSize) |
| return; |
| |
| byte[] newBytes = new byte[newSize]; |
| |
| for (int i = 0; i < CurrentSize; i++) |
| newBytes[i] = bytes[i]; |
| |
| bytes = newBytes; |
| } |
| |
| /** |
| * Replace count (1 - 8) bytes starting at offset off with the less |
| * significant bytes from the specified long value. |
| * |
| * @throws BoundException if offset and count are out of buffer bounds |
| */ |
| protected void putValueBytes(int off, long value, int count) throws BoundException { |
| if ((count <= 0) || (count > 8)) |
| throw new TestBug("Illegal number of bytes of value to put: " + count); |
| |
| if (count > CurrentSize - off) { |
| throw new BoundException("Unable to put " + count + " bytes of value at " + |
| off + " (available bytes: " + (CurrentSize - off) + ")" ); |
| } |
| |
| int shift = (count - 1) * 8; |
| for (int i = 0; i < count; i++) { |
| putByte(off++, (byte) ((value >>> shift) & 0xFF)); |
| shift = shift - 8; |
| } |
| } |
| /** |
| * Appends the count (1 - 8) less significant bytes from the |
| * specified long value to the end of this buffer. |
| */ |
| protected void addValueBytes(long value, int count) throws BoundException { |
| if ((count <= 0) || (count > 8)) |
| throw new TestBug("Illegal number of bytes of value to add: " + count); |
| |
| checkSpace(count); |
| |
| int where = CurrentSize; |
| CurrentSize += count; |
| |
| putValueBytes(where, value, count); |
| } |
| |
| /** |
| * Read count bytes (1-8) from this buffer at the specified |
| * position and returns a long value composed of these bytes. |
| * |
| * @throws BoundException if there are no so many bytes in the buffer |
| */ |
| public long getValueBytes(int off, int count) throws BoundException { |
| if ((count <= 0) || (count > 8)) |
| throw new TestBug("Illegal number of bytes of value to get: " + count); |
| |
| long l = 0; |
| |
| for (int i = 0; i < count; i++) { |
| l = (l * 0x100) + ((long) getByte(off + i) & 0xFF); |
| } |
| |
| return l; |
| } |
| |
| /** |
| * Read count bytes (1-8) from this buffer at the current parser |
| * position and returns a long value composed of these bytes. |
| * |
| * @throws BoundException if there are no so many bytes in the buffer |
| */ |
| /* |
| protected long getValueBytes(int count) throws BoundException { |
| long value = getValueBytes(parseOffset); |
| parseOffset += count; |
| return value; |
| } |
| */ |
| |
| // --- |
| |
| private static String PadL(String source, int length, String what) { |
| |
| if (length <= 0) |
| return ""; |
| |
| if (source.length() > length) |
| return PadL("", length, "*"); |
| |
| while (source.length() < length) |
| source = what + source; |
| |
| return source; |
| } |
| |
| |
| private static String PadL(String source, int length) { |
| return PadL(source, length, " "); |
| } |
| |
| private static String PadR(String source, int length, String what) { |
| |
| if (length <= 0) |
| return ""; |
| |
| if (source.length() > length) |
| return PadR("", length, "*"); |
| |
| while (source.length() < length) |
| source = source + what; |
| |
| return source; |
| } |
| |
| private static String PadR(String source, int length) { |
| return PadR(source, length, " "); |
| } |
| |
| private static String Left(String source, int length) { |
| |
| if (length <= 0) |
| return ""; |
| |
| if (length <= source.length()) |
| return source.substring(0, length); |
| else |
| return PadR(source, length); |
| } |
| |
| private static String Right(String source, int length) { |
| |
| if (length <= 0) |
| return ""; |
| |
| if (length <= source.length()) |
| return source.substring(source.length() - length, source.length()); |
| else |
| return PadL(source, length); |
| } |
| |
| } |