Path: blob/master/test/hotspot/jtreg/vmTestbase/nsk/share/jdwp/Packet.java
41161 views
/*1* Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223package nsk.share.jdwp;2425import nsk.share.*;2627import java.util.Vector;28import java.io.*;2930/**31* This class represents a JDWP packet.32*/33public class Packet extends ByteBuffer {3435/** JDWP packet flags constant. */36// public final static byte flNoFlags = (byte)0x0;37/** JDWP packet flags constant. */38// public final static byte flReply = (byte)0x80;3940/** Offset of "length" field of JDWP packet. */41public final static int LengthOffset = 0;42/** Offset of "id" field of JDWP packet. */43public final static int IdOffset = LengthOffset + 4;44/** Offset of "flags" field of JDWP packet. */45public final static int FlagsOffset = IdOffset + 4;46/** Offset of full "command" field of JDWP packet. */47public final static int FullCommandOffset = FlagsOffset + 1;48/** Offset of "command" field of JDWP command packet. */49public final static int CommandSetOffset = FullCommandOffset;50/** Offset of "command" field of JDWP command packet. */51public final static int CommandOffset = CommandSetOffset + 1;52/** Offset of "error" field of JDWP reply packet. */53public final static int ErrorCodeOffset = FlagsOffset + 1;54/** Offset of "data" section of JDWP packet. */55public final static int DataOffset = FullCommandOffset + 2;5657/** Size of JDWP packet header. */58public final static int PacketHeaderSize = DataOffset;5960/**61* Makes empty JDWP packet.62*/63public Packet() {64super();65resetBuffer();66}6768/**69* Makes JDWP packet with data from the specified byte buffer.70*/71// public Packet(ByteBuffer packet) {72public Packet(Packet packet) {73super(packet);74resetPosition();75}7677/**78* Clear buffer of the packet.79*/80public void resetBuffer() {81super.resetBuffer();82while (length() < PacketHeaderSize)83addByte((byte) 0);84setLength();85resetPosition();86}8788/**89* Return current position from begin of packet data area.90*/91public int currentDataPosition() {92return currentPosition() - PacketHeaderSize;93}9495/**96* Return value to the "length" field of JDWP packet.97*/98public int getLength() {99try {100return getInt(LengthOffset);101}102catch (BoundException e) {103throw new Failure("Caught unexpected exception while getting packet length value from header:\n\t"104+ e);105}106}107108/**109* Assign specified value to the "length" field of JDWP packet.110*/111public void setLength(int length) {112try {113putInt(LengthOffset, length);114}115catch (BoundException e) {116throw new Failure("Caught unexpected exception while setting packet length value into header:\n\t"117+ e);118}119}120121/**122* Assign packet length value to the "length" field of JDWP packet.123*/124public void setLength() {125setLength(length());126}127128/**129* Return value of the "id" field of JDWP packet.130*/131public int getPacketID() {132try {133return getInt(IdOffset);134}135catch (BoundException e) {136throw new Failure("Caught unexpected exception while getting packet ID value from header:\n\t"137+ e);138}139}140141/**142* Assign value to the "id" field of JDWP packet.143*/144public void setPacketID(int Id) {145try {146putInt(IdOffset, Id);147}148catch (BoundException e) {149throw new Failure("Caught unexpected exception while setting packet ID value into header:\n\t"150+ e);151}152}153154/**155* Return value of the "flags" field of JDWP packet.156*/157public byte getFlags() {158try {159return getByte(FlagsOffset);160}161catch (BoundException e) {162throw new Failure("Caught unexpected exception while getting packet flags value from header:\n\t"163+ e);164}165}166167/**168* Assign value to the "flags" field of JDWP packet.169*/170public void setFlags(byte flags) {171try {172putByte(FlagsOffset, flags);173}174catch (BoundException e) {175throw new Failure("Caught unexpected exception while setting packet flags value into header:\n\t"176+ e);177}178}179180/**181* Sets the current parser position to "data" field of JDWP packet.182*/183public void resetPosition() {184resetPosition(PacketHeaderSize);185}186187/**188* Return size of the "data" part of JDWP packet.189*/190public int getDataSize() {191return length() - PacketHeaderSize;192}193194//////////////////////////////////////////////////////////////////////////195196/**197* Append fieldID to the end of this buffer.198*/199public void addFieldID(long b) {200addID(b, JDWP.TypeSize.FIELD_ID);201}202203/**204* Append methodID to the end of this buffer.205*/206public void addMethodID(long b) {207addID(b, JDWP.TypeSize.METHOD_ID);208}209210/**211* Append objectID to the end of this buffer.212*/213public void addObjectID(long b) {214addID(b, JDWP.TypeSize.OBJECT_ID);215}216217/**218* Append referenceID to the end of this buffer.219*/220public void addReferenceTypeID(long b) {221addID(b, JDWP.TypeSize.REFERENCE_TYPE_ID);222}223224/**225* Append frameID to the end of this buffer.226*/227public void addFrameID(long b) {228addID(b, JDWP.TypeSize.FRAME_ID);229}230231/**232* Append string value (an UTF-8 encoded string, not zero terminated,233* preceded by a four-byte integer length) to the end of this buffer.234*/235public void addString(String value) {236final int count = JDWP.TypeSize.INT + value.length();237addInt(value.length());238try {239addBytes(value.getBytes("UTF-8"), 0, value.length());240} catch (UnsupportedEncodingException e) {241throw new Failure("Unsupported UTF-8 ecnoding while adding string value to JDWP packet:\n\t"242+ e);243}244}245246/**247* Append location value to the end of this buffer.248*/249public void addLocation(JDWP.Location location) {250addBytes(location.getBytes(), 0, location.length());251}252253/**254* Append untagged value to the end of this buffer.255*/256public void addUntaggedValue(JDWP.UntaggedValue value, byte tag) {257value.addValueTo(this, tag);258}259260/**261* Append tagged value to the end of this buffer.262*/263public void addValue(JDWP.Value value) {264value.addValueTo(this);265}266267//////////////////////////////////////////////////////////////////////////268// get packet data269//////////////////////////////////////////////////////////////////////////270271/**272* Read a fieldID value from byte buffer at the current parser position.273*274* @throws BoundException if there is no valid value bytes at the given position275*/276public long getFieldID() throws BoundException {277return getID(JDWP.TypeSize.FIELD_ID);278}279280/**281* Read a methodID value from byte buffer at the current parser position.282*283* @throws BoundException if there is no valid value bytes at the given position284*/285public long getMethodID() throws BoundException {286return getID(JDWP.TypeSize.METHOD_ID);287}288289/**290* Read an objectID value from byte buffer at the current parser position.291*292* @throws BoundException if there is no valid value bytes at the given position293*/294public long getObjectID() throws BoundException {295return getID(JDWP.TypeSize.OBJECT_ID);296}297298/**299* Read a referenceTypeID value from byte buffer at the current parser position.300*301* @throws BoundException if there is no valid value bytes at the given position302*/303public long getReferenceTypeID() throws BoundException {304return getID(JDWP.TypeSize.REFERENCE_TYPE_ID);305}306307/**308* Read a frameID value from byte buffer at the current parser position.309*310* @throws BoundException if there is no valid value bytes at the given position311*/312public long getFrameID() throws BoundException {313return getID(JDWP.TypeSize.FRAME_ID);314}315316/**317* Read from this buffer a string value at the current parser318* position and returns this value.319*320* @throws BoundException if there are no valid string bytes in the buffer321*/322public String getString() throws BoundException {323final int count = JDWP.TypeSize.INT;324int available = length() - currentPosition();325if (count > available) {326throw new BoundException("Unable to get " + count + " bytes of string length value at " +327offsetString() + " (available bytes: " + available + ")" );328}329330int len = getInt();331332if (len < 0)333throw new BoundException("Negative length of string to get: " + len);334335if (len == 0)336return "";337338available = length() - currentPosition();339if (len > available) {340throw new BoundException("Unable to get " + len + " bytes of string value at " +341offsetString() + " (available bytes: " + available + ")" );342}343344byte[] s = new byte[len];345for (int i = 0; i < len; i++)346s[i] = getByte();347348try {349return new String(s, "UTF-8");350} catch (UnsupportedEncodingException e) {351throw new Failure("Unsupported UTF-8 ecnoding while extracting string value from JDWP packet:\n\t"352+ e);353}354}355356/**357* Reads from this buffer an location value at the current parser358* position and returns this value.359*360* @throws BoundException if there are no enough bytes in the buffer361*/362public JDWP.Location getLocation() throws BoundException {363final int count = JDWP.TypeSize.LOCATION;364final int available = length() - currentPosition();365if (count > available) {366throw new BoundException("Unable to get " + count + " bytes of location value at " +367offsetString() + " (available bytes: " + available + ")" );368}369370JDWP.Location location = new JDWP.Location();371try {372for (int i = 0; i < JDWP.TypeSize.LOCATION; i++) {373location.putByte(i, getByte());374}375}376catch (BoundException e) {377throw new TestBug("Caught unexpected bound exception while getting " +378count + " bytes of location value:\n\t" + e);379};380381return location;382}383384/**385* Reads from this buffer an untagged value at the current parser386* position and returns this value.387*388* @throws BoundException if there are no enough bytes in the buffer389*/390public JDWP.UntaggedValue getUntaggedValue(byte tag) throws BoundException {391JDWP.UntaggedValue value = new JDWP.UntaggedValue();392try {393value.getValueFrom(this, tag);394}395catch (BoundException e) {396throw new TestBug("Caught unexpected bound exception while getting " +397" bytes of a value:\n\t" + e);398};399400return value;401}402403/**404* Reads from this buffer a tagged value at the current parser405* position and returns this value.406*407* @throws BoundException if there are no enough bytes in the buffer408*/409public JDWP.Value getValue() throws BoundException {410JDWP.Value value = new JDWP.Value();411try {412value.getValueFrom(this);413}414catch (BoundException e) {415throw new TestBug("Caught unexpected bound exception while getting " +416" bytes of a value:\n\t" + e);417};418419return value;420}421422423////////////////////////////////////////////////////////////////424425/**426* Read packet bytes from the stream.427*428* @throws IOException if error occured when reading bytes429*/430public void readFrom(Transport transport) throws IOException {431resetBuffer();432433// System.err.println("Reading packet header");434try {435for (int i = 0; i < PacketHeaderSize; i++) {436byte b = transport.read();437putByte(i, b);438}439}440catch (BoundException e) {441throw new TestBug(e);442}443444int length = getLength();445446checkSpace(length - PacketHeaderSize);447448// System.err.println("Packet size: " + length);449for (int i = PacketHeaderSize; i < length; i++) {450byte b = transport.read();451addByte(b);452}453// System.err.println("Packet read successfully");454}455456/**457* Write packet bytes to the stream.458*459* @throws IOException if error occured when reading bytes460*/461public void writeTo(Transport transport) throws IOException {462setLength();463// System.err.println("Writing packet bytes: " + length());464transport.write(bytes, 0, length());465}466467/**468* Check packet header.469* This method check if packet has valid values in header fields.470*471* @throws PacketFormatException if packet header fields has error or invalid values472*/473public void checkHeader() throws PacketFormatException {474if (getLength() != length()) {475throw new PacketFormatException("Unexpected packet length value in the header:"476+ getLength());477}478}479480/**481* Check if packet is parsed totally and no trailing bytes left unparsed.482* This method check if packet has valid values in header fields.483*484* @throws PacketFormatException if there are trailing bytes left unparsed485*/486public void checkParsed() throws PacketFormatException {487if (! isParsed()) {488throw new PacketFormatException("Extra trailing bytes found in the packet at: "489+ offsetString());490}491}492493/**494* Return string representation of the packet header.495*/496public String headerToString() {497return "Packet header (" + PacketHeaderSize + " bytes):" + "\n"498+ " " + toHexString(LengthOffset, 4) + " (length) : 0x" + toHexDecString(getLength(), 8) + "\n"499+ " " + toHexString(IdOffset, 4) + " (id) : 0x" + toHexDecString(getPacketID(), 8) + "\n"500+ " " + toHexString(FlagsOffset, 4) + " (flags) : 0x" + toHexDecString(getFlags(), 2) + "\n";501}502503/**504* Return string representation of the packet.505*/506public String toString() {507return headerToString()508+ "Entire packet (" + length() + " bytes): " + "\n"509+ super.toString(0)510+ "Packet end";511}512513/**514* Exception indicated that packet has an ivnalid structure.515*/516class PacketFormatException extends BoundException {517PacketFormatException(String message) {518super(message);519}520}521}522523524