You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by ge...@apache.org on 2006/11/28 18:49:31 UTC
svn commit: r480141 [19/38] - in
/harmony/enhanced/jdktools/trunk/modules/jpda: ./ doc/ doc/images/ make/
src/ src/common/ src/common/other/ src/common/other/jpda/
src/common/other/jpda/jdwp/ src/common/other/jpda/jdwp/agent/
src/common/other/jpda/jdwp...
Added: harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/framework/jdwp/PacketDispatcher.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/framework/jdwp/PacketDispatcher.java?view=auto&rev=480141
==============================================================================
--- harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/framework/jdwp/PacketDispatcher.java (added)
+++ harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/framework/jdwp/PacketDispatcher.java Tue Nov 28 09:49:08 2006
@@ -0,0 +1,730 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Anton V. Karnachuk
+ * @version $Revision: 1.5 $
+ */
+
+/**
+ * Created on 16.03.2005
+ */
+package org.apache.harmony.jpda.tests.framework.jdwp;
+
+import java.util.List;
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+import org.apache.harmony.jpda.tests.framework.LogWriter;
+import org.apache.harmony.jpda.tests.framework.TestOptions;
+import org.apache.harmony.jpda.tests.framework.jdwp.exceptions.TimeoutException;
+
+/**
+ * This class provides asynchronous sending JDWP commands and receiving JDWP
+ * events through established JDWP connection and supports timeout for these
+ * operations.
+ */
+public class PacketDispatcher extends Thread {
+
+ /**
+ * Variables below are intended only to help with tests failures
+ * investigation. They turn on/off some kinds of trace during
+ * tests execution which can clear up details of test failure.
+ *
+ * commandsNumberForTrace and begCommandIdForTrace define trace
+ * of sent JDWP commands and received replies for these commands:
+ * - begCommandIdForTrace defines starting command ID for trace
+ * (the first command has ID=1, the second - ID=2 and so on).
+ * if <= 0 then the same as = 1.
+ * - commandsNumberForTrace defines number of command for trace.
+ * if <= 0 then commands' trace is off.
+ *
+ * - eventRequestIDForTrace defines trace of received events
+ * according to request ID value:
+ * if < 0 then this trace is off;
+ * if = 0 then trace is for all received events;
+ * if > 0 then trace is for received events, which are triggered
+ * by this specified request ID value;
+ *
+ * - eventKindForTrace defines trace of received events
+ * according to this specified kind of event.
+ * if = 0 then this trace is off;
+ * See JDWPConstants.EventKind class for values of
+ * event kinds.
+ */
+ int begCommandIdForTrace = 1;
+
+ int commandsNumberForTrace = 0;
+
+ int eventRequestIDForTrace = -1;
+
+ byte eventKindForTrace = 0;
+
+ /**
+ * Internal class to synchronize jdwp events. When an event is received it
+ * is stored in eventQueue. If there are any thread that waits for event it
+ * is notified.
+ */
+ private class EventsSynchronyzer {
+
+ /**
+ * List of received events.
+ */
+ private List eventQueue;
+
+ /**
+ * A default constructor.
+ */
+ EventsSynchronyzer() {
+ // initialize eventQueue
+ eventQueue = new ArrayList();
+ }
+
+ /**
+ * Notifies thread that the new event has been received.
+ *
+ * @param eventPacket
+ * instance of EventPacket
+ * @throws InterruptedException
+ */
+ public void notifyThread(EventPacket eventPacket)
+ throws InterruptedException {
+
+ // use this object as lock
+ synchronized (this) {
+ // add the event to eventQueue
+ eventQueue.add(eventPacket);
+
+ // notify next waiting thread
+ this.notify();
+ }
+ }
+
+ /**
+ * Waits for new event during timeout.
+ *
+ * @param timeout
+ * wait timeout
+ * @return EventPacket
+ * @throws InterruptedException
+ * @throws IOException
+ * @throws TimeoutException
+ * if no event was received
+ */
+ public EventPacket waitForNextEvent(long timeout)
+ throws InterruptedException, IOException {
+
+ // use this object as lock
+ synchronized (this) {
+
+ // if there is already received event in eventQueue,
+ // then return it
+ synchronized (eventQueue) {
+ if (!eventQueue.isEmpty()) {
+ return (EventPacket) eventQueue.remove(0);
+ }
+
+ // if eventQueue is empty and connection is already closed
+ // reraise the exception
+ if (connectionException != null)
+ throw connectionException;
+ }
+
+ // wait for the next event
+ this.wait(timeout);
+
+ // We have the following opportunities here -
+ // next event was received, exception in main cyrcle or timeout
+ // happens
+ synchronized (eventQueue) {
+ if (!eventQueue.isEmpty()) {
+ // event received
+ EventPacket event = (EventPacket) eventQueue.remove(0);
+ return event;
+ }
+
+ if (connectionException != null) {
+ // if eventQueue is empty and connection is already
+ // closed
+ // reraise the exception
+ throw connectionException;
+ }
+ }
+ }
+
+ // no events were occurred during timeout
+ throw new TimeoutException(false);
+ }
+
+ /**
+ * This method is called when connection is closed. It notifies all the
+ * waiting threads.
+ */
+ public void terminate() {
+ synchronized (this) {
+ this.notifyAll();
+ }
+ }
+ }
+
+ /**
+ * Internal class to synchronize jdwp commands. It sends command packets
+ * through connection and returns replies.
+ */
+ class CommandsSynchronyzer {
+
+ private int commandId;
+
+ private Hashtable commands;
+
+ private Hashtable replies;
+
+ /**
+ * A default constructor.
+ */
+ CommandsSynchronyzer() {
+ commands = new Hashtable();
+ replies = new Hashtable();
+
+ // set first command id to 1
+ commandId = 1;
+ }
+
+ /**
+ * Gets the next new id for a command.
+ *
+ * @return int
+ */
+ private synchronized int getNextId() {
+ return commandId++;
+ }
+
+ /**
+ * Notifies thread that reply packet was received.
+ *
+ * @param replyPacket
+ * instance of ReplyPacket
+ * @throws IOException
+ * @throws InterruptedException
+ */
+ public void notifyThread(ReplyPacket replyPacket) throws IOException,
+ InterruptedException {
+
+ synchronized (commands) {
+
+ // obtain the current command id
+ Integer Id = new Integer(replyPacket.getId());
+
+ // obtain the current command packet by command id
+ CommandPacket command = (CommandPacket) commands.remove(Id);
+ if (command == null) {
+ // we received reply's id that does not correspond to any
+ // command
+ throw new IOException(
+ "Reply id is corresponded to no command. Id = "
+ + Id);
+ }
+
+ synchronized (command) {
+ // put the reply in replies queue
+ synchronized (replies) {
+ replies.put(new Integer(replyPacket.getId()),
+ replyPacket);
+ }
+ // notify waiting thread
+ command.notifyAll();
+ }
+ }
+ }
+
+ /**
+ * Sends command and waits for the reply during timeout.
+ *
+ * @param command
+ * instance of CommandPacket
+ * @param timeout
+ * reply wait timeout
+ * @return
+ * @throws TimeoutException
+ * if no reply was received
+ */
+ public ReplyPacket waitForReply(CommandPacket command, long timeout)
+ throws InterruptedException, IOException {
+
+ synchronized (command) {
+
+ // if connection is already closed reraise the exception
+ if (connectionException != null)
+ throw connectionException;
+
+ // obtain new command id
+ Integer Id = new Integer(getNextId());
+ command.setId(Id.intValue());
+
+ // add command into commands hashtable
+ synchronized (commands) {
+ commands.put(Id, command);
+
+ // below is trace for sent coomasnds
+ if (commandsNumberForTrace > 0) {
+ int begCommandId = begCommandIdForTrace > 1 ? begCommandIdForTrace
+ : 1;
+ if (Id.intValue() >= begCommandId) {
+ if ((Id.intValue() - begCommandId) < commandsNumberForTrace) {
+ logWriter
+ .println(">>>>>>>>>> PacketDispatcher: PERFORM command: ID = "
+ + Id.intValue()
+ + "; CommandSet = "
+ + command.getCommandSet()
+ + "; Command = "
+ + command.getCommand() + "...");
+ }
+ }
+ }
+
+ // write this package to connection
+ connection.writePacket(command.toBytesArray());
+ }
+
+ // if connection is already closed reraise the exception
+ if (connectionException != null)
+ throw connectionException;
+
+ // wait for reply
+ command.wait(timeout);
+
+ // receive the reply
+ ReplyPacket currentReply = null;
+ synchronized (replies) {
+ currentReply = (ReplyPacket) replies.remove(Id);
+ }
+
+ // if reply is ok, return it
+ if (currentReply != null) {
+ return currentReply;
+ }
+
+ // if connection is already closed reraise the exception
+ if (connectionException != null)
+ throw connectionException;
+ }
+
+ // no event was occurred during timeout
+ throw new TimeoutException(false);
+ }
+
+ /**
+ * Sends command without waiting for the reply and returns id of the
+ * sent command.
+ *
+ * @param command
+ * instance of CommandPacket
+ * @return command id
+ * @throws IOException
+ */
+ public int sendCommand(CommandPacket command) throws IOException {
+
+ // if connection is already closed reraise the exception
+ if (connectionException != null)
+ throw connectionException;
+
+ // obtain new command id
+ Integer Id = new Integer(getNextId());
+ command.setId(Id.intValue());
+
+ // add command into commands hashtable
+ synchronized (commands) {
+ commands.put(Id, command);
+
+ // below is trace for sent coomasnds
+ if (commandsNumberForTrace > 0) {
+ int begCommandId = begCommandIdForTrace > 1 ? begCommandIdForTrace
+ : 1;
+ if (Id.intValue() >= begCommandId) {
+ if ((Id.intValue() - begCommandId) < commandsNumberForTrace) {
+ logWriter
+ .println(">>>>>>>>>> PacketDispatcher: PERFORM command: ID = "
+ + Id.intValue()
+ + "; CommandSet = "
+ + command.getCommandSet()
+ + "; Command = "
+ + command.getCommand() + "...");
+ }
+ }
+ }
+
+ // write this package to connection
+ connection.writePacket(command.toBytesArray());
+ }
+
+ // if connection is already closed reraise the exception
+ if (connectionException != null) {
+ throw connectionException;
+ }
+
+ return Id.intValue();
+
+ }
+
+ /**
+ * Receives the reply during timeout for command with specified command
+ * ID.
+ *
+ * @param commandId
+ * id of previously sent commend
+ * @param timeout
+ * receive timeout
+ * @return received ReplyPacket
+ * @throws TimeoutException
+ * if no reply was received
+ */
+ public ReplyPacket receiveReply(int commandId, long timeout)
+ throws InterruptedException, IOException {
+
+ // if connection is already closed reraise the exception
+ if (connectionException != null)
+ throw connectionException;
+
+ // receive the reply
+ ReplyPacket currentReply = null;
+ long endTimeMlsecForWait = System.currentTimeMillis() + timeout;
+ synchronized (replies) {
+ while (true) {
+ currentReply = (ReplyPacket) replies.remove(new Integer(
+ commandId));
+ // if reply is ok, return it
+ if (currentReply != null) {
+ return currentReply;
+ }
+ // if connection is already closed reraise the exception
+ if (connectionException != null) {
+ throw connectionException;
+ }
+ if (System.currentTimeMillis() >= endTimeMlsecForWait) {
+ break;
+ }
+ replies.wait(100);
+ }
+ }
+ // no expected reply was found during timeout
+ throw new TimeoutException(false);
+ }
+
+ /**
+ * This method is called when connection is closed. It notifies all the
+ * waiting threads.
+ *
+ */
+ public void terminate() {
+
+ synchronized (commands) {
+ // enumerate all waiting commands
+ for (Enumeration en = commands.keys(); en.hasMoreElements();) {
+ CommandPacket command = (CommandPacket) commands.get(en
+ .nextElement());
+ synchronized (command) {
+ // notify the waiting object
+ command.notifyAll();
+ }
+ }
+ }
+ }
+ }
+
+ /** Transport which is used to sent and receive packets. */
+ private TransportWrapper connection;
+
+ /** Current test run configuration. */
+ TestOptions config;
+
+ private CommandsSynchronyzer commandsSynchronyzer;
+
+ private EventsSynchronyzer eventsSynchronyzer;
+
+ private LogWriter logWriter;
+
+ private IOException connectionException;
+
+ /**
+ * Creates new PacketDispatcher instance.
+ *
+ * @param connection
+ * open connection for reading and writing packets
+ * @param config
+ * test run options
+ * @param logWriter
+ * LogWriter object
+ */
+ public PacketDispatcher(TransportWrapper connection, TestOptions config,
+ LogWriter logWriter) {
+
+ this.connection = connection;
+ this.config = config;
+ this.logWriter = logWriter;
+
+ commandsSynchronyzer = new CommandsSynchronyzer();
+ eventsSynchronyzer = new EventsSynchronyzer();
+
+ // make thread daemon
+ setDaemon(true);
+
+ // start the thread
+ start();
+ }
+
+ /**
+ * Reads packets from connection and dispatches them between waiting
+ * threads.
+ */
+ public void run() {
+
+ connectionException = null;
+
+ try {
+ // start listening for replies
+ while (!isInterrupted()) {
+
+ // read packet from transport
+ byte[] packet = connection.readPacket();
+
+ // break cycle if empty packet
+ if (packet == null || packet.length == 0)
+ break;
+
+ // check flags
+ if (packet.length < Packet.FLAGS_INDEX) {
+ logWriter
+ .println(">>>>>>>>>> PacketDispatcher WARNING: WRONG received packet size = "
+ + packet.length);
+ } else {
+ int flag = packet[Packet.FLAGS_INDEX] & 0xFF;
+ if (flag != 0) {
+ if (flag != Packet.REPLY_PACKET_FLAG) {
+ logWriter
+ .println(">>>>>>>>>> PacketDispatcher WARNING: WRONG received packet flags = "
+ + Integer.toHexString(flag));
+ }
+ }
+ }
+
+ // check the reply flag
+ if (Packet.isReply(packet)) {
+ // new reply
+ ReplyPacket replyPacket = new ReplyPacket(packet);
+
+ // check for received reply packet length
+ int packetLength = replyPacket.getLength();
+ if (packetLength < Packet.HEADER_SIZE) {
+ logWriter
+ .println(">>>>>>>>>> PacketDispatcher WARNING: WRONG received packet length = "
+ + packetLength);
+ }
+
+ // below is trace for received coomasnds
+ if (commandsNumberForTrace > 0) {
+ int replyID = replyPacket.getId();
+ int begCommandId = begCommandIdForTrace > 1 ? begCommandIdForTrace
+ : 1;
+ if (replyID >= begCommandId) {
+ if ((replyID - begCommandId) < commandsNumberForTrace) {
+ logWriter
+ .println(">>>>>>>>>> PacketDispatcher: Received REPLY ID = "
+ + replyID);
+ }
+ }
+ }
+
+ commandsSynchronyzer.notifyThread(replyPacket);
+ } else {
+ // new event
+ EventPacket eventPacket = new EventPacket(packet);
+ // below is to check received events for correctness
+
+ // below is trace for received events
+ ParsedEvent[] parsedEvents = ParsedEvent
+ .parseEventPacket(eventPacket);
+ if ((eventRequestIDForTrace >= 0)
+ || (eventKindForTrace > 0)) {
+ for (int i = 0; i < parsedEvents.length; i++) {
+ boolean trace = false;
+ int eventRequestID = parsedEvents[i].getRequestID();
+ if (eventRequestIDForTrace == 0) {
+ trace = true;
+ } else {
+ if (eventRequestID == eventRequestIDForTrace) {
+ trace = true;
+ }
+ }
+ byte eventKind = parsedEvents[i].getEventKind();
+ if (eventKind == eventKindForTrace) {
+ trace = true;
+ }
+ if (trace) {
+ logWriter
+ .println(">>>>>>>>>> PacketDispatcher: Received_EVENT["
+ + i
+ + "]: eventRequestID= "
+ + eventRequestID
+ + "; eventKind = "
+ + eventKind
+ + "("
+ + JDWPConstants.EventKind
+ .getName(eventKind)
+ + ")");
+ }
+ }
+ }
+ eventsSynchronyzer.notifyThread(eventPacket);
+ }
+ }
+
+ // this exception is send for all waiting threads
+ connectionException = new TimeoutException(true);
+ } catch (IOException e) {
+ // connection exception is send for all waiting threads
+ connectionException = e;
+
+ // print stack trace
+ e.printStackTrace();
+ } catch (InterruptedException e) {
+ // connection exception is send for all waiting threads
+ connectionException = new InterruptedIOException(e.getMessage());
+ connectionException.initCause(e);
+
+ // print stack trace
+ e.printStackTrace();
+ }
+
+ // notify all the waiting threads
+ eventsSynchronyzer.terminate();
+ commandsSynchronyzer.terminate();
+ }
+
+ /**
+ * Receives event from event queue if there are any events or waits during
+ * timeout for any event occurrence. This method should not be used
+ * simultaneously from different threads. If there were no reply during the
+ * timeout, TimeoutException is thrown.
+ *
+ * @param timeout
+ * timeout in milliseconds
+ * @return received event packet
+ * @throws IOException
+ * is any connection error occurred
+ * @throws InterruptedException
+ * if reading packet was interrupted
+ * @throws TimeoutException
+ * if timeout exceeded
+ */
+ public EventPacket receiveEvent(long timeout) throws IOException,
+ InterruptedException, TimeoutException {
+
+ return eventsSynchronyzer.waitForNextEvent(timeout);
+ }
+
+ /**
+ * Sends JDWP command packet and waits for reply packet during default
+ * timeout. If there were no reply packet during the timeout,
+ * TimeoutException is thrown.
+ *
+ * @return received reply packet
+ * @throws InterruptedException
+ * if reading packet was interrupted
+ * @throws IOException
+ * if any connection error occurred
+ * @throws TimeoutException
+ * if timeout exceeded
+ */
+ public ReplyPacket performCommand(CommandPacket command)
+ throws InterruptedException, IOException, TimeoutException {
+
+ return performCommand(command, config.getTimeout());
+ }
+
+ /**
+ * Sends JDWP command packet and waits for reply packet during certain
+ * timeout. If there were no reply packet during the timeout,
+ * TimeoutException is thrown.
+ *
+ * @param command
+ * command packet to send
+ * @param timeout
+ * timeout in milliseconds
+ * @return received reply packet
+ * @throws InterruptedException
+ * if packet reading was interrupted
+ * @throws IOException
+ * if any connection error occurred
+ * @throws TimeoutException
+ * if timeout exceeded
+ */
+ public ReplyPacket performCommand(CommandPacket command, long timeout)
+ throws InterruptedException, IOException, TimeoutException {
+
+ return commandsSynchronyzer.waitForReply(command, timeout);
+ }
+
+ /**
+ * Sends CommandPacket to debuggee VM without waiting for the reply. This
+ * method is intended for special cases when there is need to divide
+ * command's performing into two actions: command's sending and receiving
+ * reply (e.g. for asynchronous JDWP commands' testing). After this method
+ * the 'receiveReply()' method must be used latter for receiving reply for
+ * sent command. It is NOT recommended to use this method for usual cases -
+ * 'performCommand()' method must be used.
+ *
+ * @param command
+ * Command packet to be sent
+ * @return command ID of sent command
+ * @throws IOException
+ * if any connection error occurred
+ */
+ public int sendCommand(CommandPacket command) throws IOException {
+ return commandsSynchronyzer.sendCommand(command);
+ }
+
+ /**
+ * Waits for reply for command which was sent before by 'sendCommand()'
+ * method. Specified timeout is used as time limit for waiting. This method
+ * (jointly with 'sendCommand()') is intended for special cases when there
+ * is need to divide command's performing into two actions: command's
+ * sending and receiving reply (e.g. for asynchronous JDWP commands'
+ * testing). It is NOT recommended to use 'sendCommand()- receiveReply()'
+ * pair for usual cases - 'performCommand()' method must be used.
+ *
+ * @param commandId
+ * Command ID of sent before command, reply from which is
+ * expected to be received
+ * @param timeout
+ * Specified timeout in milliseconds to wait for reply
+ * @return received ReplyPacket
+ * @throws IOException
+ * if any connection error occurred
+ * @throws InterruptedException
+ * if reply packet's waiting was interrupted
+ * @throws TimeoutException
+ * if timeout exceeded
+ */
+ public ReplyPacket receiveReply(int commandId, long timeout)
+ throws InterruptedException, IOException, TimeoutException {
+ return commandsSynchronyzer.receiveReply(commandId, timeout);
+ }
+
+}
Propchange: harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/framework/jdwp/PacketDispatcher.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/framework/jdwp/ParsedEvent.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/framework/jdwp/ParsedEvent.java?view=auto&rev=480141
==============================================================================
--- harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/framework/jdwp/ParsedEvent.java (added)
+++ harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/framework/jdwp/ParsedEvent.java Tue Nov 28 09:49:08 2006
@@ -0,0 +1,579 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Anton V. Karnachuk
+ * @version $Revision: 1.3 $
+ */
+
+/**
+ * Created on 17.03.2005
+ */
+package org.apache.harmony.jpda.tests.framework.jdwp;
+
+import org.apache.harmony.jpda.tests.framework.TestErrorException;
+
+/**
+ * This class represent parsed EventPacket with received event set data.
+ */
+public class ParsedEvent {
+
+ private byte suspendPolicy;
+
+ private int requestID;
+
+ private byte eventKind;
+
+ /**
+ * Create new instance with specified data.
+ */
+ protected ParsedEvent(byte suspendPolicy, Packet packet, byte eventKind) {
+ this.suspendPolicy = suspendPolicy;
+ this.requestID = packet.getNextValueAsInt();
+ this.eventKind = eventKind;
+ }
+
+ /**
+ * Returns RequestID of this event set.
+ *
+ * @return RequestID of this event set
+ */
+ public int getRequestID() {
+ return requestID;
+ }
+
+ /**
+ * Returns suspend policy of this event set.
+ *
+ * @return suspend policy of this event set
+ */
+ public byte getSuspendPolicy() {
+ return suspendPolicy;
+ }
+
+ /**
+ * @return Returns the eventKind.
+ */
+ public byte getEventKind() {
+ return eventKind;
+ }
+
+ /**
+ * The class extends ParsedEvent by associating it with a thread.
+ */
+ public static class EventThread extends ParsedEvent {
+
+ private long threadID;
+
+ /**
+ * A constructor.
+ *
+ * @param suspendPolicy
+ * @param packet
+ */
+ protected EventThread(byte suspendPolicy, Packet packet, byte eventKind) {
+ super(suspendPolicy, packet, eventKind);
+ this.threadID = packet.getNextValueAsThreadID();
+ }
+
+ /**
+ * @return Returns the thread id.
+ */
+ public long getThreadID() {
+ return threadID;
+ }
+ }
+
+ /**
+ * The class extends EventThread by associating it with a location.
+ */
+ private static class EventThreadLocation extends EventThread {
+
+ private Location location;
+
+ /**
+ * A constructor.
+ *
+ * @param suspendPolicy
+ * @param packet
+ */
+ protected EventThreadLocation(byte suspendPolicy, Packet packet,
+ byte eventKind) {
+ super(suspendPolicy, packet, eventKind);
+ this.location = packet.getNextValueAsLocation();
+ }
+
+ /**
+ * @return Returns the location.
+ */
+ public Location getLocation() {
+ return location;
+ }
+ }
+
+ /**
+ * The class implements JDWP VM_START event.
+ */
+ public static final class Event_VM_START extends EventThread {
+
+ /**
+ * A constructor.
+ *
+ * @param suspendPolicy
+ * @param packet
+ */
+ private Event_VM_START(byte suspendPolicy, Packet packet) {
+ super(suspendPolicy, packet, JDWPConstants.EventKind.VM_START);
+ }
+ };
+
+ /**
+ * The class implements JDWP SINGLE_STEP event.
+ */
+ public static final class Event_SINGLE_STEP extends EventThreadLocation {
+
+ /**
+ * A constructor.
+ *
+ * @param suspendPolicy
+ * @param packet
+ */
+ private Event_SINGLE_STEP(byte suspendPolicy, Packet packet) {
+ super(suspendPolicy, packet, JDWPConstants.EventKind.SINGLE_STEP);
+ }
+ }
+
+ /**
+ * The class implements JDWP BREAKPOINT event.
+ */
+ public static final class Event_BREAKPOINT extends EventThreadLocation {
+
+ /**
+ * A constructor.
+ *
+ * @param suspendPolicy
+ * @param packet
+ */
+ private Event_BREAKPOINT(byte suspendPolicy, Packet packet) {
+ super(suspendPolicy, packet, JDWPConstants.EventKind.BREAKPOINT);
+ }
+ }
+
+ /**
+ * The class implements JDWP METHOD_ENTRY event.
+ */
+ public static final class Event_METHOD_ENTRY extends EventThreadLocation {
+
+ /**
+ * A constructor.
+ *
+ * @param suspendPolicy
+ * @param packet
+ */
+ private Event_METHOD_ENTRY(byte suspendPolicy, Packet packet) {
+ super(suspendPolicy, packet, JDWPConstants.EventKind.METHOD_ENTRY);
+ }
+ }
+
+ /**
+ * The class implements JDWP METHOD_EXIT event.
+ */
+ public static final class Event_METHOD_EXIT extends EventThreadLocation {
+
+ /**
+ * A constructor.
+ *
+ * @param suspendPolicy
+ * @param packet
+ */
+ private Event_METHOD_EXIT(byte suspendPolicy, Packet packet) {
+ super(suspendPolicy, packet, JDWPConstants.EventKind.METHOD_EXIT);
+ }
+ }
+
+ /**
+ * The class implements JDWP EXCEPTION event.
+ */
+ public static final class Event_EXCEPTION extends EventThreadLocation {
+
+ private TaggedObject exception;
+
+ private Location catchLocation;
+
+ /**
+ * A constructor.
+ *
+ * @param suspendPolicy
+ * @param packet
+ */
+ private Event_EXCEPTION(byte suspendPolicy, Packet packet) {
+ super(suspendPolicy, packet, JDWPConstants.EventKind.EXCEPTION);
+ exception = packet.getNextValueAsTaggedObject();
+ catchLocation = packet.getNextValueAsLocation();
+ }
+
+ /**
+ * @return Returns the location of the caught exception.
+ */
+ public Location getCatchLocation() {
+ return catchLocation;
+ }
+
+ /**
+ * @return Returns the exception.
+ */
+ public TaggedObject getException() {
+ return exception;
+ }
+ }
+
+ /**
+ * The class implements JDWP THREAD_START event.
+ */
+ public static final class Event_THREAD_START extends EventThread {
+
+ /**
+ * A constructor.
+ *
+ * @param suspendPolicy
+ * @param packet
+ */
+ private Event_THREAD_START(byte suspendPolicy, Packet packet) {
+ super(suspendPolicy, packet, JDWPConstants.EventKind.THREAD_START);
+ }
+ };
+
+ /**
+ * The class implements JDWP THREAD_DEATH event.
+ */
+ public static final class Event_THREAD_DEATH extends EventThread {
+
+ /**
+ * A constructor.
+ *
+ * @param suspendPolicy
+ * @param packet
+ */
+ private Event_THREAD_DEATH(byte suspendPolicy, Packet packet) {
+ super(suspendPolicy, packet, JDWPConstants.EventKind.THREAD_DEATH);
+ }
+ };
+
+ /**
+ * The class implements JDWP CLASS_PREPARE event.
+ */
+ public static final class Event_CLASS_PREPARE extends EventThread {
+
+ private byte refTypeTag;
+
+ private long typeID;
+
+ private String signature;
+
+ private int status;
+
+ /**
+ * A constructor.
+ *
+ * @param suspendPolicy
+ * @param packet
+ */
+ protected Event_CLASS_PREPARE(byte suspendPolicy, Packet packet) {
+ super(suspendPolicy, packet, JDWPConstants.EventKind.CLASS_PREPARE);
+ refTypeTag = packet.getNextValueAsByte();
+ typeID = packet.getNextValueAsReferenceTypeID();
+ signature = packet.getNextValueAsString();
+ status = packet.getNextValueAsInt();
+ }
+
+ /**
+ * @return Returns the refTypeTag.
+ */
+ public byte getRefTypeTag() {
+ return refTypeTag;
+ }
+
+ /**
+ * @return Returns the signature.
+ */
+ public String getSignature() {
+ return signature;
+ }
+
+ /**
+ * @return Returns the status.
+ */
+ public int getStatus() {
+ return status;
+ }
+
+ /**
+ * @return Returns the typeID.
+ */
+ public long getTypeID() {
+ return typeID;
+ }
+ };
+
+ /**
+ * The class implements JDWP CLASS_UNLOAD event.
+ */
+ public static final class Event_CLASS_UNLOAD extends ParsedEvent {
+
+ private String signature;
+
+ /**
+ * A constructor.
+ *
+ * @param suspendPolicy
+ * @param packet
+ */
+ private Event_CLASS_UNLOAD(byte suspendPolicy, Packet packet) {
+ super(suspendPolicy, packet, JDWPConstants.EventKind.CLASS_UNLOAD);
+ signature = packet.getNextValueAsString();
+ }
+
+ /**
+ * @return Returns the signature.
+ */
+ public String getSignature() {
+ return signature;
+ }
+ };
+
+ /**
+ * The class implements JDWP FIELD_ACCESS event.
+ */
+ public static final class Event_FIELD_ACCESS extends EventThreadLocation {
+
+ private byte refTypeTag;
+
+ private long typeID;
+
+ private long fieldID;
+
+ private TaggedObject object;
+
+ /**
+ * A constructor.
+ *
+ * @param suspendPolicy
+ * @param packet
+ */
+ private Event_FIELD_ACCESS(byte suspendPolicy, Packet packet) {
+ super(suspendPolicy, packet, JDWPConstants.EventKind.FIELD_ACCESS);
+ refTypeTag = packet.getNextValueAsByte();
+ typeID = packet.getNextValueAsReferenceTypeID();
+ fieldID = packet.getNextValueAsFieldID();
+ object = packet.getNextValueAsTaggedObject();
+ }
+
+ /**
+ * @return Returns the fieldID.
+ */
+ public long getFieldID() {
+ return fieldID;
+ }
+
+ /**
+ * @return Returns the object.
+ */
+ public TaggedObject getObject() {
+ return object;
+ }
+
+ /**
+ * @return Returns the refTypeTag.
+ */
+ public byte getRefTypeTag() {
+ return refTypeTag;
+ }
+
+ /**
+ * @return Returns the typeID.
+ */
+ public long getTypeID() {
+ return typeID;
+ }
+ };
+
+ /**
+ * The class implements JDWP FIELD_MODIFICATION event.
+ */
+ public static final class Event_FIELD_MODIFICATION extends
+ EventThreadLocation {
+ private byte refTypeTag;
+
+ private long typeID;
+
+ private long fieldID;
+
+ private TaggedObject object;
+
+ private Value valueToBe;
+
+ /**
+ * A constructor.
+ * @param suspendPolicy
+ * @param packet
+ */
+ private Event_FIELD_MODIFICATION(byte suspendPolicy, Packet packet) {
+ super(suspendPolicy, packet,
+ JDWPConstants.EventKind.FIELD_MODIFICATION);
+ refTypeTag = packet.getNextValueAsByte();
+ typeID = packet.getNextValueAsReferenceTypeID();
+ fieldID = packet.getNextValueAsFieldID();
+ object = packet.getNextValueAsTaggedObject();
+ valueToBe = packet.getNextValueAsValue();
+ }
+
+ /**
+ * @return Returns the fieldID.
+ */
+ public long getFieldID() {
+ return fieldID;
+ }
+
+ /**
+ * @return Returns the object.
+ */
+ public TaggedObject getObject() {
+ return object;
+ }
+
+ /**
+ * @return Returns the refTypeTag.
+ */
+ public byte getRefTypeTag() {
+ return refTypeTag;
+ }
+
+ /**
+ * @return Returns the typeID.
+ */
+ public long getTypeID() {
+ return typeID;
+ }
+
+ /**
+ * @return Returns the valueToBe.
+ */
+ public Value getValueToBe() {
+ return valueToBe;
+ }
+ };
+
+ /**
+ * The class implements JDWP VM_DEATH event.
+ */
+ public static final class Event_VM_DEATH extends ParsedEvent {
+ /**
+ * A constructor.
+ * @param suspendPolicy
+ * @param packet
+ */
+ private Event_VM_DEATH(byte suspendPolicy, Packet packet) {
+ super(suspendPolicy, packet, JDWPConstants.EventKind.VM_DEATH);
+ }
+ };
+
+ /**
+ * Returns array of ParsedEvent extracted from given EventPacket.
+ *
+ * @param packet
+ * EventPacket to parse events
+ * @return array of extracted ParsedEvents
+ */
+ public static ParsedEvent[] parseEventPacket(Packet packet) {
+
+ Packet packetCopy = new Packet(packet.toBytesArray());
+
+ // Suspend Policy field
+ byte suspendPolicy = packetCopy.getNextValueAsByte();
+
+ // Number of events
+ int eventCount = packetCopy.getNextValueAsInt();
+
+ ParsedEvent[] events = new ParsedEvent[eventCount];
+
+ // For all events in packet
+ for (int i = 0; i < eventCount; i++) {
+ byte eventKind = packetCopy.getNextValueAsByte();
+ switch (eventKind) {
+ case JDWPConstants.EventKind.VM_START: {
+ events[i] = new Event_VM_START(suspendPolicy, packetCopy);
+ break;
+ }
+ case JDWPConstants.EventKind.SINGLE_STEP: {
+ events[i] = new Event_SINGLE_STEP(suspendPolicy, packetCopy);
+ break;
+ }
+ case JDWPConstants.EventKind.BREAKPOINT: {
+ events[i] = new Event_BREAKPOINT(suspendPolicy, packetCopy);
+ break;
+ }
+ case JDWPConstants.EventKind.METHOD_ENTRY: {
+ events[i] = new Event_METHOD_ENTRY(suspendPolicy, packetCopy);
+ break;
+ }
+ case JDWPConstants.EventKind.METHOD_EXIT: {
+ events[i] = new Event_METHOD_EXIT(suspendPolicy, packetCopy);
+ break;
+ }
+ case JDWPConstants.EventKind.EXCEPTION: {
+ events[i] = new Event_EXCEPTION(suspendPolicy, packetCopy);
+ break;
+ }
+ case JDWPConstants.EventKind.THREAD_START: {
+ events[i] = new Event_THREAD_START(suspendPolicy, packetCopy);
+ break;
+ }
+ case JDWPConstants.EventKind.THREAD_DEATH: {
+ events[i] = new Event_THREAD_DEATH(suspendPolicy, packetCopy);
+ break;
+ }
+ case JDWPConstants.EventKind.CLASS_PREPARE: {
+ events[i] = new Event_CLASS_PREPARE(suspendPolicy, packetCopy);
+ break;
+ }
+ case JDWPConstants.EventKind.CLASS_UNLOAD: {
+ events[i] = new Event_CLASS_UNLOAD(suspendPolicy, packetCopy);
+ break;
+ }
+ case JDWPConstants.EventKind.FIELD_ACCESS: {
+ events[i] = new Event_FIELD_ACCESS(suspendPolicy, packetCopy);
+ break;
+ }
+ case JDWPConstants.EventKind.FIELD_MODIFICATION: {
+ events[i] = new Event_FIELD_MODIFICATION(suspendPolicy,
+ packetCopy);
+ break;
+ }
+ case JDWPConstants.EventKind.VM_DEATH: {
+ events[i] = new Event_VM_DEATH(suspendPolicy, packetCopy);
+ break;
+ }
+ default: {
+ throw new TestErrorException("Unexpected kind of event: "
+ + eventKind);
+ }
+ }
+ }
+ return events;
+ }
+
+}
Propchange: harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/framework/jdwp/ParsedEvent.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/framework/jdwp/ReplyPacket.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/framework/jdwp/ReplyPacket.java?view=auto&rev=480141
==============================================================================
--- harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/framework/jdwp/ReplyPacket.java (added)
+++ harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/framework/jdwp/ReplyPacket.java Tue Nov 28 09:49:08 2006
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Khen G. Kim
+ * @version $Revision: 1.3 $
+ */
+
+/**
+ * Created on 10.01.2004
+ */
+package org.apache.harmony.jpda.tests.framework.jdwp;
+
+import org.apache.harmony.jpda.tests.framework.jdwp.Packet;
+
+/**
+ * This class represents JDWP reply packet.
+ */
+public class ReplyPacket extends Packet {
+
+ private final int ERROR_CODE_INDEX = 9;
+
+ private short error_code;
+
+ /**
+ * A default constructor that creates an empty ReplyPacket with empty header
+ * and no data.
+ */
+ public ReplyPacket() {
+ super();
+ }
+
+ /**
+ * A constructor that creates ReplyPacket from array of bytes including
+ * header and data sections.
+ *
+ * @param p
+ * the JDWP packet, given as array of bytes.
+ */
+ public ReplyPacket(byte p[]) {
+ super(p);
+ error_code = (short) super.readFromByteArray(p, ERROR_CODE_INDEX,
+ Packet.SHORT_SIZE);
+ }
+
+ /**
+ * Sets the error code value of the header of the ReplyPacket as short.
+ *
+ * @param val
+ * the error code.
+ */
+ public void setErrorCode(short val) {
+ error_code = val;
+ }
+
+ /**
+ * Gets the error code value of the header of the ReplyPacket.
+ *
+ * @return the error code value of the header of the ReplyPacket.
+ */
+ public short getErrorCode() {
+ return error_code;
+ }
+
+ /**
+ * Gets the representation of the ReplyPacket as array of bytes in the JDWP
+ * format including header and data sections.
+ *
+ * @return the representation of the ReplyPacket as array of bytes in the
+ * JDWP format.
+ */
+ public byte[] toBytesArray() {
+ byte res[] = super.toBytesArray();
+ super.writeAtByteArray(error_code, res, ERROR_CODE_INDEX,
+ Packet.SHORT_SIZE);
+ return res;
+ }
+}
Propchange: harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/framework/jdwp/ReplyPacket.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/framework/jdwp/SocketTransportWrapper.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/framework/jdwp/SocketTransportWrapper.java?view=auto&rev=480141
==============================================================================
--- harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/framework/jdwp/SocketTransportWrapper.java (added)
+++ harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/framework/jdwp/SocketTransportWrapper.java Tue Nov 28 09:49:08 2006
@@ -0,0 +1,320 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Ivan G. Popov
+ * @version $Revision: 1.5 $
+ */
+
+/**
+ * Created on 05.23.2004
+ */
+package org.apache.harmony.jpda.tests.framework.jdwp;
+
+
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketTimeoutException;
+import java.io.InputStream;
+import java.io.InterruptedIOException;
+import java.io.OutputStream;
+import java.io.IOException;
+
+import org.apache.harmony.jpda.tests.framework.jdwp.Packet;
+
+/**
+ * This class provides TransportWrapper for row TCP/IP socket connection.
+ *
+ */
+public class SocketTransportWrapper implements TransportWrapper {
+
+ public static final String HANDSHAKE_STRING = "JDWP-Handshake";
+
+ private ServerSocket serverSocket;
+ private Socket transportSocket;
+ private InputStream input;
+ private OutputStream output;
+
+ /**
+ * Starts listening for connection on given or default address.
+ *
+ * @param address address to listen or null for default address
+ * @return string representation of listening address
+ */
+ public String startListening(String address) throws IOException {
+ String hostName = null;
+ InetAddress hostAddr = null;
+ int port = 0;
+ if (address != null) {
+ String portName = null;
+ int i = address.indexOf(':');
+ if (i < 0) {
+ portName = address;
+ } else {
+ hostName = address.substring(0, i);
+ portName = address.substring(i+1);
+ }
+ try {
+ port = Integer.parseInt(portName);
+ } catch (NumberFormatException e) {
+ throw new IOException("Illegal port number in socket address: " + address);
+ }
+ }
+
+ if (hostName != null) {
+ hostAddr = InetAddress.getByName(hostName);
+ serverSocket = new ServerSocket(port, 0, hostAddr);
+ } else {
+ serverSocket = new ServerSocket(port);
+ }
+
+ // use as workaround for unspecified behaviour of isAnyLocalAddress()
+ InetAddress iAddress = null;
+ if (hostName != null) {
+ iAddress = serverSocket.getInetAddress();
+ } else {
+ iAddress = InetAddress.getLocalHost();
+ }
+
+ address = iAddress.getHostName() + ":" + serverSocket.getLocalPort();
+ return address;
+ }
+
+ /**
+ * Stops listening for connection on current address.
+ */
+ public void stopListening() throws IOException {
+ if (serverSocket != null) {
+ serverSocket.close();
+ }
+ }
+
+ /**
+ * Accepts transport connection for currently listened address and performs handshaking
+ * for specified timeout.
+ *
+ * @param acceptTimeout timeout for accepting in milliseconds
+ * @param handshakeTimeout timeout for handshaking in milliseconds
+ */
+ public void accept(long acceptTimeout, long handshakeTimeout) throws IOException {
+ synchronized (serverSocket) {
+ serverSocket.setSoTimeout((int) acceptTimeout);
+ try {
+ transportSocket = serverSocket.accept();
+ } finally {
+ serverSocket.setSoTimeout(0);
+ }
+ }
+ createStreams();
+ handshake(handshakeTimeout);
+ }
+
+ /**
+ * Attaches transport connection to given address and performs handshaking
+ * for specified timeout.
+ *
+ * @param address address for attaching
+ * @param attachTimeout timeout for attaching in milliseconds
+ * @param handshakeTimeout timeout for handshaking in milliseconds
+ */
+ public void attach(String address, long attachTimeout, long handshakeTimeout) throws IOException {
+ if (address == null) {
+ throw new IOException("Illegal socket address: " + address);
+ }
+
+ String hostName = null;
+ int port = 0;
+ {
+ String portName = null;
+ int i = address.indexOf(':');
+ if (i < 0) {
+ throw new IOException("Illegal socket address: " + address);
+ } else {
+ hostName = address.substring(0, i);
+ portName = address.substring(i+1);
+ }
+ try {
+ port = Integer.parseInt(portName);
+ } catch (NumberFormatException e) {
+ throw new IOException("Illegal port number in socket address: " + address);
+ }
+ }
+
+ long finishTime = System.currentTimeMillis() + attachTimeout;
+ long sleepTime = 4 * 1000; // millesecinds
+ IOException exception = null;
+ try {
+ do {
+ try {
+ transportSocket = new Socket(hostName, port);
+ break;
+ } catch (IOException e) {
+ Thread.sleep(sleepTime);
+ }
+ } while (attachTimeout == 0 || System.currentTimeMillis() < finishTime);
+ } catch (InterruptedException e) {
+ throw new InterruptedIOException("Interruption in attaching to " + address);
+ }
+
+ if (transportSocket == null) {
+ if (exception != null) {
+ throw exception;
+ } else {
+ throw new SocketTimeoutException("Timeout exceeded in attaching to " + address);
+ }
+ }
+
+ createStreams();
+ handshake(handshakeTimeout);
+ }
+
+ /**
+ * Closes transport connection.
+ */
+ public void close() throws IOException {
+ if (input != null) {
+ input.close();
+ }
+ if (output != null) {
+ output.close();
+ }
+
+ if (transportSocket != null && input == null && output == null && !transportSocket.isClosed()) {
+ transportSocket.close();
+ }
+ if (serverSocket != null) {
+ serverSocket.close();
+ }
+ }
+
+ /**
+ * Checks if transport connection is open.
+ *
+ * @return true if transport connection is open
+ */
+ public boolean isOpen() {
+ return (transportSocket != null
+ && transportSocket.isConnected()
+ && !transportSocket.isClosed());
+ }
+
+ /**
+ * Reads packet bytes from transport connection.
+ *
+ * @return packet as byte array or null or empty packet if connection was closed
+ */
+ public byte[] readPacket() throws IOException {
+
+ // read packet header
+ byte[] header = new byte[Packet.HEADER_SIZE];
+ int off = 0;
+
+ while (off < Packet.HEADER_SIZE) {
+ try {
+ int bytesRead = input.read(header, off, Packet.HEADER_SIZE - off);
+ if (bytesRead < 0) {
+ break;
+ }
+ off += bytesRead;
+ } catch (IOException e) {
+ // workaround for "Socket Closed" exception if connection was closed
+ break;
+ }
+ }
+
+ if (off == 0) {
+ return null;
+ }
+ if (off < Packet.HEADER_SIZE) {
+ throw new IOException("Connection closed in reading packet header");
+ }
+
+ // extract packet length
+ int len = Packet.getPacketLength(header);
+ if (len < Packet.HEADER_SIZE) {
+ throw new IOException("Wrong packet size detected: " + len);
+ }
+
+ // allocate packet bytes and store header there
+ byte[] bytes = new byte[len];
+ System.arraycopy(header, 0, bytes, 0, Packet.HEADER_SIZE);
+
+ // read packet data
+ while (off < len) {
+ int bytesRead = input.read(bytes, off, len - off);
+ if (bytesRead < 0) {
+ break;
+ }
+ off += bytesRead;
+ }
+ if (off < len) {
+ throw new IOException("Connection closed in reading packet data");
+ }
+
+ return bytes;
+ }
+
+ /**
+ * Writes packet bytes to transport connection.
+ *
+ * @param packet
+ * packet as byte array
+ */
+ public void writePacket(byte[] packet) throws IOException {
+ output.write(packet);
+ output.flush();
+ }
+
+ /**
+ * Performs handshaking for given timeout.
+ *
+ * @param handshakeTimeout timeout for handshaking in milliseconds
+ */
+ protected void handshake(long handshakeTimeout) throws IOException {
+ transportSocket.setSoTimeout((int) handshakeTimeout);
+
+ try {
+ output.write(HANDSHAKE_STRING.getBytes());
+ output.flush();
+ int len = HANDSHAKE_STRING.length();
+ byte[] bytes = new byte[len];
+ int off = 0;
+ while (off < len) {
+ int bytesRead = input.read(bytes, off, len - off);
+ if (bytesRead < 0) {
+ break;
+ }
+ off += bytesRead;
+ }
+ String response = new String(bytes, 0, off);
+ if (!response.equals(HANDSHAKE_STRING)) {
+ throw new IOException("Unexpected handshake response: " + response);
+ }
+ } finally {
+ transportSocket.setSoTimeout(0);
+ }
+ }
+
+ /**
+ * Creates input/output streams for connection socket.
+ */
+ protected void createStreams() throws IOException {
+ input = transportSocket.getInputStream();
+ output = transportSocket.getOutputStream();
+ }
+}
Propchange: harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/framework/jdwp/SocketTransportWrapper.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/framework/jdwp/TaggedObject.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/framework/jdwp/TaggedObject.java?view=auto&rev=480141
==============================================================================
--- harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/framework/jdwp/TaggedObject.java (added)
+++ harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/framework/jdwp/TaggedObject.java Tue Nov 28 09:49:08 2006
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Aleksey V. Yantsen
+ * @version $Revision: 1.2 $
+ */
+
+/**
+ * Created on 10.25.2004
+ */
+package org.apache.harmony.jpda.tests.framework.jdwp;
+
+import org.apache.harmony.jpda.tests.framework.jdwp.JDWPConstants;
+
+/**
+ * This class represents tagged-objectID value in JDWP packet.
+ */
+public class TaggedObject {
+ public byte tag;
+ public long objectID;
+
+ /**
+ * Creates new value with empty tag.
+ */
+ public TaggedObject() {
+ tag = JDWPConstants.Tag.NO_TAG;
+ objectID = 0;
+ }
+
+ /**
+ * Creates new value with specified data.
+ */
+ public TaggedObject(byte tag, long objectID) {
+ this.tag = tag;
+ this.objectID = objectID;
+ }
+}
\ No newline at end of file
Propchange: harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/framework/jdwp/TaggedObject.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/framework/jdwp/TransportWrapper.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/framework/jdwp/TransportWrapper.java?view=auto&rev=480141
==============================================================================
--- harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/framework/jdwp/TransportWrapper.java (added)
+++ harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/framework/jdwp/TransportWrapper.java Tue Nov 28 09:49:08 2006
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Ivan G. Popov
+ * @version $Revision: 1.5 $
+ */
+
+/**
+ * Created on 05.23.2004
+ */
+package org.apache.harmony.jpda.tests.framework.jdwp;
+
+import java.io.IOException;
+
+/**
+ * This interface provides wrapper around JDWP transport connection.
+ * Particular implementation can interact directly with raw connection
+ * like SocketTransportWrapper or use JDI service provider interfaces
+ * to support all pluggable JDI transports.
+ *
+ */
+public interface TransportWrapper {
+
+ /**
+ * Starts listening for connection on given or default address.
+ *
+ * @param address address to listen or null for default address
+ * @return string representation of listening address
+ */
+ public String startListening(String address) throws IOException;
+
+ /**
+ * Stops listening for connection on current address.
+ */
+ public void stopListening() throws IOException;
+
+ /**
+ * Accepts transport connection for currently listened address and performs handshaking
+ * for specified timeout.
+ *
+ * @param acceptTimeout timeout for accepting in milliseconds
+ * @param handshakeTimeout timeout for handshaking in milliseconds
+ */
+ public void accept(long acceptTimeout, long handshakeTimeout) throws IOException;
+
+ /**
+ * Attaches transport connection to given address and performs handshaking
+ * for specified timeout.
+ *
+ * @param address address for attaching
+ * @param attachTimeout timeout for attaching in milliseconds
+ * @param handshakeTimeout timeout for handshaking in milliseconds
+ */
+ public void attach(String address, long attachTimeout, long handshakeTimeout) throws IOException;
+
+ /**
+ * Closes transport connection.
+ */
+ public void close() throws IOException;
+
+ /**
+ * Checks if transport connection is open.
+ *
+ * @return true if transport connection is open
+ */
+ public boolean isOpen();
+
+ /**
+ * Reads packet from transport connection.
+ *
+ * @return packet as byte array or null or empty packet if connection was closed
+ */
+ public byte[] readPacket() throws IOException;
+
+ /**
+ * Writes packet to transport connection.
+ *
+ * @param packet packet as byte array
+ */
+ public void writePacket(byte[] packet) throws IOException;
+}
Propchange: harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/framework/jdwp/TransportWrapper.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/framework/jdwp/TypesLengths.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/framework/jdwp/TypesLengths.java?view=auto&rev=480141
==============================================================================
--- harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/framework/jdwp/TypesLengths.java (added)
+++ harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/framework/jdwp/TypesLengths.java Tue Nov 28 09:49:08 2006
@@ -0,0 +1,309 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Aleksey V. Yantsen
+ * @version $Revision: 1.6 $
+ */
+
+/**
+ * Created on 12.23.2004
+ */
+package org.apache.harmony.jpda.tests.framework.jdwp;
+
+import org.apache.harmony.jpda.tests.framework.TestErrorException;
+
+/**
+ * This class provides types length for VM-independent and VM-dependent types.
+ */
+public class TypesLengths {
+
+ // Type IDs
+ public static final byte BYTE_ID = 1;
+
+ public static final byte BOOLEAN_ID = 2;
+
+ public static final byte INT_ID = 3;
+
+ public static final byte LONG_ID = 4;
+
+ public static final byte SHORT_ID = 5;
+
+ public static final byte FLOAT_ID = 6;
+
+ public static final byte DOUBLE_ID = 7;
+
+ public static final byte VOID_ID = 8;
+
+ public static final byte OBJECT_ID = 9;
+
+ public static final byte ARRAY_ID = 10;
+
+ public static final byte STRING_ID = 11;
+
+ public static final byte THREAD_ID = 12;
+
+ public static final byte THREADGROUP_ID = 13;
+
+ public static final byte METHOD_ID = 14;
+
+ public static final byte FIELD_ID = 15;
+
+ public static final byte FRAME_ID = 16;
+
+ public static final byte LOCATION_ID = 17;
+
+ public static final byte REFERENCE_TYPE_ID = 18;
+
+ public static final byte CLASS_ID = 19;
+
+ public static final byte CLASSLOADER_ID = 20;
+
+ public static final byte CLASSOBJECT_ID = 21;
+
+ public static final byte CHAR_ID = 22;
+
+ // Type lengths in bytes (VM-independent)
+
+ private static int byteLength = 1;
+
+ private static int booleanLength = 1;
+
+ private static int intLength = 4;
+
+ private static int longLength = 8;
+
+ private static int shortLength = 2;
+
+ private static int floatLength = 4;
+
+ private static int doubleLength = 8;
+
+ private static int voidLength = 0;
+
+ private static int charLength = 2;
+
+ // Type lengths in bytes (VM-dependent)
+
+ private static int objectLength;
+
+ private static int arrayLength;
+
+ private static int stringLength;
+
+ private static int threadLength;
+
+ private static int threadGroupLength;
+
+ private static int methodLength;
+
+ private static int fieldLength;
+
+ private static int frameLength;
+
+ private static int locationLength;
+
+ private static int referenceLength;
+
+ private static int classLength;
+
+ private static int classLoaderLength;
+
+ private static int classObjectLength;
+
+ /**
+ * Gets types length for type ID.
+ *
+ * @param typeID
+ * Type ID
+ * @return type length
+ */
+ public static int getTypeLength(byte typeID) throws TestErrorException {
+ switch (typeID) {
+ case BYTE_ID: {
+ return byteLength;
+ }
+ case BOOLEAN_ID: {
+ return booleanLength;
+ }
+ case INT_ID: {
+ return intLength;
+ }
+ case LONG_ID: {
+ return longLength;
+ }
+ case SHORT_ID: {
+ return shortLength;
+ }
+ case FLOAT_ID: {
+ return floatLength;
+ }
+ case DOUBLE_ID: {
+ return doubleLength;
+ }
+ case VOID_ID: {
+ return voidLength;
+ }
+ case OBJECT_ID: {
+ return objectLength;
+ }
+ case ARRAY_ID: {
+ return arrayLength;
+ }
+ case STRING_ID: {
+ return stringLength;
+ }
+ case THREAD_ID: {
+ return threadLength;
+ }
+ case THREADGROUP_ID: {
+ return threadGroupLength;
+ }
+ case METHOD_ID: {
+ return methodLength;
+ }
+ case FIELD_ID: {
+ return fieldLength;
+ }
+ case FRAME_ID: {
+ return frameLength;
+ }
+ case LOCATION_ID: {
+ return locationLength;
+ }
+ case REFERENCE_TYPE_ID: {
+ return referenceLength;
+ }
+ case CLASS_ID: {
+ return classLength;
+ }
+ case CLASSLOADER_ID: {
+ return classLoaderLength;
+ }
+ case CLASSOBJECT_ID: {
+ return classObjectLength;
+ }
+ case CHAR_ID: {
+ return charLength;
+ }
+ default:
+ throw new TestErrorException("Unexpected type ID: " + typeID);
+ }
+ }
+
+ /**
+ * Sets types length for type ID
+ *
+ * @param typeID Type ID
+ * @param typeLength type length
+ */
+ public static void setTypeLength(byte typeID, int typeLength)
+ throws TestErrorException {
+ switch (typeID) {
+ case BYTE_ID: {
+ byteLength = typeLength;
+ return;
+ }
+ case BOOLEAN_ID: {
+ booleanLength = typeLength;
+ return;
+ }
+ case INT_ID: {
+ intLength = typeLength;
+ return;
+ }
+ case LONG_ID: {
+ longLength = typeLength;
+ return;
+ }
+ case SHORT_ID: {
+ shortLength = typeLength;
+ return;
+ }
+ case FLOAT_ID: {
+ floatLength = typeLength;
+ return;
+ }
+ case DOUBLE_ID: {
+ doubleLength = typeLength;
+ return;
+ }
+ case VOID_ID: {
+ voidLength = typeLength;
+ return;
+ }
+ case OBJECT_ID: {
+ objectLength = typeLength;
+ return;
+ }
+ case ARRAY_ID: {
+ arrayLength = typeLength;
+ return;
+ }
+ case STRING_ID: {
+ stringLength = typeLength;
+ return;
+ }
+ case THREAD_ID: {
+ threadLength = typeLength;
+ return;
+ }
+ case THREADGROUP_ID: {
+ threadGroupLength = typeLength;
+ return;
+ }
+ case METHOD_ID: {
+ methodLength = typeLength;
+ return;
+ }
+ case FIELD_ID: {
+ fieldLength = typeLength;
+ return;
+ }
+ case FRAME_ID: {
+ frameLength = typeLength;
+ return;
+ }
+ case LOCATION_ID: {
+ locationLength = typeLength;
+ return;
+ }
+ case REFERENCE_TYPE_ID: {
+ referenceLength = typeLength;
+ return;
+ }
+ case CLASS_ID: {
+ classLength = typeLength;
+ return;
+ }
+ case CLASSLOADER_ID: {
+ classLoaderLength = typeLength;
+ return;
+ }
+ case CLASSOBJECT_ID: {
+ classObjectLength = typeLength;
+ return;
+ }
+ case CHAR_ID: {
+ classObjectLength = charLength;
+ return;
+ }
+ default:
+ throw new TestErrorException("Unexpected type ID: " + typeID);
+ }
+ }
+}
Propchange: harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/framework/jdwp/TypesLengths.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/framework/jdwp/Value.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/framework/jdwp/Value.java?view=auto&rev=480141
==============================================================================
--- harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/framework/jdwp/Value.java (added)
+++ harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/framework/jdwp/Value.java Tue Nov 28 09:49:08 2006
@@ -0,0 +1,292 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Aleksey V. Yantsen
+ * @version $Revision: 1.4 $
+ */
+
+/**
+ * Created on 10.25.2004
+ */
+package org.apache.harmony.jpda.tests.framework.jdwp;
+
+import org.apache.harmony.jpda.tests.framework.TestErrorException;
+import org.apache.harmony.jpda.tests.framework.jdwp.JDWPConstants;
+
+/**
+ * This class represents generic value used in JDWP packets.
+ */
+public class Value {
+
+ private byte tag;
+
+ private Number numberValue;
+
+ private boolean booleanValue;
+
+ private char charValue;
+
+ /**
+ * Creates new value with no tag.
+ */
+ public Value() {
+ tag = JDWPConstants.Tag.NO_TAG;
+ }
+
+ /**
+ * Creates new ID value with specified tag.
+ */
+ public Value(byte tag, long value) {
+ this.tag = tag;
+ this.numberValue = new Long(value);
+ }
+
+ /**
+ * Creates new byte value.
+ */
+ public Value(byte value) {
+ this.tag = JDWPConstants.Tag.BYTE_TAG;
+ this.numberValue = new Byte(value);
+ }
+
+ /**
+ * Creates new short value.
+ */
+ public Value(short value) {
+ this.tag = JDWPConstants.Tag.SHORT_TAG;
+ this.numberValue = new Short(value);
+ }
+
+ /**
+ * Creates new int value.
+ */
+ public Value(int value) {
+ this.tag = JDWPConstants.Tag.INT_TAG;
+ this.numberValue = new Integer(value);
+ }
+
+ /**
+ * Creates new long value.
+ */
+ public Value(long value) {
+ this.tag = JDWPConstants.Tag.LONG_TAG;
+ this.numberValue = new Long(value);
+ }
+
+ /**
+ * Creates new short value.
+ */
+ public Value(float value) {
+ this.tag = JDWPConstants.Tag.FLOAT_TAG;
+ this.numberValue = new Float(value);
+ }
+
+ /**
+ * Creates new double value.
+ */
+ public Value(double value) {
+ this.tag = JDWPConstants.Tag.DOUBLE_TAG;
+ this.numberValue = new Double(value);
+ }
+
+ /**
+ * Creates new boolean value.
+ */
+ public Value(boolean value) {
+ this.tag = JDWPConstants.Tag.BOOLEAN_TAG;
+ this.booleanValue = value;
+ }
+
+ /**
+ * Creates new char value.
+ */
+ public Value(char value) {
+ this.tag = JDWPConstants.Tag.CHAR_TAG;
+ this.charValue = value;
+ }
+
+ /**
+ * Returns tag of this value.
+ *
+ * @return Returns the tag.
+ */
+ public byte getTag() {
+ return tag;
+ }
+
+ /**
+ * Returns byte representation of this value.
+ *
+ * @return byte value
+ */
+ public byte getByteValue() {
+ return numberValue.byteValue();
+ }
+
+ /**
+ * Returns short representation of this value.
+ *
+ * @return short value
+ */
+ public short getShortValue() {
+ return numberValue.shortValue();
+ }
+
+ /**
+ * Returns int representation of this value.
+ *
+ * @return int value
+ */
+ public int getIntValue() {
+ return numberValue.intValue();
+ }
+
+ /**
+ * Returns long representation of this value.
+ *
+ * @return long value
+ */
+ public long getLongValue() {
+ return numberValue.longValue();
+ }
+
+ /**
+ * Returns float representation of this value.
+ *
+ * @return float value
+ */
+ public float getFloatValue() {
+ return numberValue.floatValue();
+ }
+
+ /**
+ * Returns double representation of this value.
+ *
+ * @return double value
+ */
+ public double getDoubleValue() {
+ return numberValue.doubleValue();
+ }
+
+ /**
+ * Returns boolean representation of this value.
+ *
+ * @return boolean value
+ */
+ public boolean getBooleanValue() {
+ return booleanValue;
+ }
+
+ /**
+ * Returns char representation of this value.
+ *
+ * @return char value
+ */
+ public char getCharValue() {
+ return charValue;
+ }
+
+ /**
+ * Compares with other value.
+ */
+ public boolean equals(Object arg0) {
+ if (!(arg0 instanceof Value))
+ return false;
+
+ Value value0 = (Value) arg0;
+ if (value0.tag != value0.tag)
+ return false;
+
+ switch (tag) {
+ case JDWPConstants.Tag.BOOLEAN_TAG:
+ return getBooleanValue() == value0.getBooleanValue();
+ case JDWPConstants.Tag.BYTE_TAG:
+ return getByteValue() == value0.getByteValue();
+ case JDWPConstants.Tag.CHAR_TAG:
+ return getCharValue() == value0.getCharValue();
+ case JDWPConstants.Tag.DOUBLE_TAG:
+ if (Double.isNaN(getDoubleValue())
+ && (Double.isNaN(value0.getDoubleValue())))
+ return true;
+ return getDoubleValue() == value0.getDoubleValue();
+ case JDWPConstants.Tag.FLOAT_TAG:
+ if (Float.isNaN(getFloatValue())
+ && (Float.isNaN(value0.getFloatValue())))
+ return true;
+ return getFloatValue() == value0.getFloatValue();
+ case JDWPConstants.Tag.INT_TAG:
+ return getIntValue() == value0.getIntValue();
+ case JDWPConstants.Tag.LONG_TAG:
+ return getLongValue() == value0.getLongValue();
+ case JDWPConstants.Tag.SHORT_TAG:
+ return getShortValue() == value0.getShortValue();
+ case JDWPConstants.Tag.STRING_TAG:
+ case JDWPConstants.Tag.ARRAY_TAG:
+ case JDWPConstants.Tag.CLASS_LOADER_TAG:
+ case JDWPConstants.Tag.CLASS_OBJECT_TAG:
+ case JDWPConstants.Tag.OBJECT_TAG:
+ case JDWPConstants.Tag.THREAD_GROUP_TAG:
+ case JDWPConstants.Tag.THREAD_TAG:
+ return getLongValue() == value0.getLongValue();
+ }
+
+ throw new TestErrorException("Illegal tag value");
+ }
+
+ /**
+ * Converts this value to string representation for printing.
+ */
+ public String toString() {
+
+ switch (tag) {
+ case JDWPConstants.Tag.BOOLEAN_TAG:
+ return "boolean: " + getBooleanValue();
+ case JDWPConstants.Tag.BYTE_TAG:
+ return "byte: " + getByteValue();
+ case JDWPConstants.Tag.CHAR_TAG:
+ return "char: " + getCharValue();
+ case JDWPConstants.Tag.DOUBLE_TAG:
+ return "double: " + getDoubleValue();
+ case JDWPConstants.Tag.FLOAT_TAG:
+ return "float: " + getFloatValue();
+ case JDWPConstants.Tag.INT_TAG:
+ return "int: " + getIntValue();
+ case JDWPConstants.Tag.LONG_TAG:
+ return "long: " + getLongValue();
+ case JDWPConstants.Tag.SHORT_TAG:
+ return "short: " + getShortValue();
+ case JDWPConstants.Tag.STRING_TAG:
+ return "StringID: " + getLongValue();
+ case JDWPConstants.Tag.ARRAY_TAG:
+ return "ObjectID: " + getLongValue();
+
+ case JDWPConstants.Tag.CLASS_LOADER_TAG:
+ return "ClassLoaderID: " + getLongValue();
+ case JDWPConstants.Tag.CLASS_OBJECT_TAG:
+ return "ClassObjectID: " + getLongValue();
+ case JDWPConstants.Tag.OBJECT_TAG:
+ return "ObjectID: " + getLongValue();
+ case JDWPConstants.Tag.THREAD_GROUP_TAG:
+ return "ThreadGroupID: " + getLongValue();
+ case JDWPConstants.Tag.THREAD_TAG:
+ return "ThreadID: " + getLongValue();
+ }
+
+ throw new TestErrorException("Illegal tag value: " + tag);
+ }
+}
Propchange: harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/framework/jdwp/Value.java
------------------------------------------------------------------------------
svn:eol-style = native