1 /* 2 * Copyright (c) 1998, 2003, 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.tools.jdi; 27 28 import com.sun.jdi.*; 29 import java.io.IOException; 30 31 public class Packet extends Object { 32 public final static short NoFlags = 0x0; 33 public final static short Reply = 0x80; 34 public final static short ReplyNoError = 0x0; 35 36 static int uID = 1; 37 final static byte[] nullData = new byte[0]; 38 39 // Note! flags, cmdSet, and cmd are all byte values. 40 // We represent them as shorts to make them easier 41 // to work with. 42 int id; 43 short flags; 44 short cmdSet; 45 short cmd; 46 short errorCode; 47 byte[] data; 48 volatile boolean replied = false; 49 50 /** 51 * Return byte representation of the packet 52 */ toByteArray()53 public byte[] toByteArray() { 54 int len = data.length + 11; 55 byte b[] = new byte[len]; 56 b[0] = (byte)((len >>> 24) & 0xff); 57 b[1] = (byte)((len >>> 16) & 0xff); 58 b[2] = (byte)((len >>> 8) & 0xff); 59 b[3] = (byte)((len >>> 0) & 0xff); 60 b[4] = (byte)((id >>> 24) & 0xff); 61 b[5] = (byte)((id >>> 16) & 0xff); 62 b[6] = (byte)((id >>> 8) & 0xff); 63 b[7] = (byte)((id >>> 0) & 0xff); 64 b[8] = (byte)flags; 65 if ((flags & Packet.Reply) == 0) { 66 b[9] = (byte)cmdSet; 67 b[10] = (byte)cmd; 68 } else { 69 b[9] = (byte)((errorCode >>> 8) & 0xff); 70 b[10] = (byte)((errorCode >>> 0) & 0xff); 71 } 72 if (data.length > 0) { 73 System.arraycopy(data, 0, b, 11, data.length); 74 } 75 return b; 76 } 77 78 /** 79 * Create a packet from its byte array representation 80 */ fromByteArray(byte b[])81 public static Packet fromByteArray(byte b[]) throws IOException { 82 if (b.length < 11) { 83 throw new IOException("packet is insufficient size"); 84 } 85 86 int b0 = b[0] & 0xff; 87 int b1 = b[1] & 0xff; 88 int b2 = b[2] & 0xff; 89 int b3 = b[3] & 0xff; 90 int len = ((b0 << 24) | (b1 << 16) | (b2 << 8) | (b3 << 0)); 91 if (len != b.length) { 92 throw new IOException("length size mis-match"); 93 } 94 95 int b4 = b[4] & 0xff; 96 int b5 = b[5] & 0xff; 97 int b6 = b[6] & 0xff; 98 int b7 = b[7] & 0xff; 99 100 Packet p = new Packet(); 101 p.id = ((b4 << 24) | (b5 << 16) | (b6 << 8) | (b7 << 0)); 102 103 p.flags = (short)(b[8] & 0xff); 104 105 if ((p.flags & Packet.Reply) == 0) { 106 p.cmdSet = (short)(b[9] & 0xff); 107 p.cmd = (short)(b[10] & 0xff); 108 } else { 109 short b9 = (short)(b[9] & 0xff); 110 short b10 = (short)(b[10] & 0xff); 111 p.errorCode = (short)((b9 << 8) + (b10 << 0)); 112 } 113 114 p.data = new byte[b.length - 11]; 115 System.arraycopy(b, 11, p.data, 0, p.data.length); 116 return p; 117 } 118 Packet()119 Packet() 120 { 121 id = uniqID(); 122 flags = NoFlags; 123 data = nullData; 124 } 125 uniqID()126 static synchronized private int uniqID() 127 { 128 /* 129 * JDWP spec does not require this id to be sequential and 130 * increasing, but our implementation does. See 131 * VirtualMachine.notifySuspend, for example. 132 */ 133 return uID++; 134 } 135 } 136