// Reads a single packet from the connection, adding it to the packet // queue when a complete packet is ready. private void _readOnePacket() throws IOException { byte[] data = null; // Read in the packet int length = _inStream.readInt(); if (length < 11) { throw new IOException("JDWP packet length < 11 (" + length + ")"); } data = new byte[length]; data[0] = (byte) (length >>> 24); data[1] = (byte) (length >>> 16); data[2] = (byte) (length >>> 8); data[3] = (byte) length; _inStream.readFully(data, 4, length - 4); JdwpPacket packet = JdwpPacket.fromBytes(data); if (packet != null) { synchronized (_commandQueue) { _commandQueue.add(packet); _commandQueue.notifyAll(); } } }
/** * Send an event notification to the debugger * * @param request the debugger request that wanted this event * @param event the event * @throws IOException */ public void sendEvent(EventRequest request, Event event) throws IOException { JdwpPacket pkt; synchronized (_bytes) { _bytes.reset(); pkt = event.toPacket(_doStream, request); pkt.setData(_bytes.toByteArray()); } sendPacket(pkt); }
/** * Convert the given bytes into a <code>JdwpPacket</code>. Uses the abstract method <code> * myFromBytes</code> to allow subclasses to process data. * * <p>If the given data does not represent a valid JDWP packet, it returns <code>null</code>. * * @param bytes packet data from the wire * @return number of bytes in <code>bytes</code> processed */ public static JdwpPacket fromBytes(byte[] bytes) { int i = 0; int length = ((bytes[i++] & 0xff) << 24 | (bytes[i++] & 0xff) << 16 | (bytes[i++] & 0xff) << 8 | (bytes[i++] & 0xff)); int id = 0; byte flags = 0; if (bytes.length == length) { id = ((bytes[i++] & 0xff) << 24 | (bytes[i++] & 0xff) << 16 | (bytes[i++] & 0xff) << 8 | (bytes[i++] & 0xff)); flags = bytes[i++]; Class clazz = null; if (flags == 0) clazz = JdwpCommandPacket.class; else if ((flags & JDWP_FLAG_REPLY) != 0) clazz = JdwpReplyPacket.class; else { // Malformed packet. Discard it. return null; } JdwpPacket pkt = null; try { pkt = (JdwpPacket) clazz.newInstance(); } catch (InstantiationException ie) { // Discard packet return null; } catch (IllegalAccessException iae) { // Discard packet return null; } pkt.setId(id); pkt.setFlags(flags); i += pkt.myFromBytes(bytes, i); byte[] data = new byte[length - i]; System.arraycopy(bytes, i, data, 0, data.length); pkt.setData(data); return pkt; } return null; }
/** * Constructs a <code>JdwpPacket</code> with the id from the given packet. * * @param pkt a packet whose id will be used in this new packet */ public JdwpPacket(JdwpPacket pkt) { _id = pkt.getId(); }
/** * Send a packet to the debugger * * @param pkt a <code>JdwpPacket</code> to send * @throws IOException */ public void sendPacket(JdwpPacket pkt) throws IOException { pkt.write(_outStream); }