On Thu, 2005-07-21 at 18:24 -0600, Tom Tromey wrote:
> Aaron> This it a utility class for Reading/Writing values and untagged-values.
> Aaron> http://java.sun.com/j2se/1.5.0/docs/guide/jpda/jdwp-spec.html
>
> Looks good, thanks.
> (Though please fix the "primative"->"primitive" typo...)
Ok, Committed.
I also added setAccessible(true) to when I access the Fields so I can
access the private variables as well.
thanks,
Aaron
ChangeLog
2005-07-20 Aaron Luchko <[EMAIL PROTECTED]>
* gnu/classpath/jdwp/util/Value.java: Class to read/write JDWP
untagged values and tagged values.
* gnu/classpath/jdwp/processor/ObjectReferenceCommandSet.java:
use new api for Values and IVirtualMachine and fix message in
exception.
* gnu/classpath/jdwp/processor/ReferenceTypeCommandSet.java:
use new api for Values and fix message in exception.
--- /dev/null 2005-06-09 16:29:11.371620296 -0400
+++ gnu/classpath/jdwp/util/Value.java 2005-07-27 11:40:33.000000000 -0400
@@ -0,0 +1,297 @@
+/* Value.java -- class to read/write JDWP tagged and untagged values
+ Copyright (C) 2005 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.classpath.jdwp.util;
+
+import gnu.classpath.jdwp.Jdwp;
+import gnu.classpath.jdwp.JdwpConstants;
+import gnu.classpath.jdwp.exception.InvalidFieldException;
+import gnu.classpath.jdwp.exception.JdwpException;
+import gnu.classpath.jdwp.exception.JdwpInternalErrorException;
+import gnu.classpath.jdwp.id.ObjectId;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+/**
+ * A class to read/write JDWP tagged and untagged values.
+ *
+ * @author Aaron Luchko <[EMAIL PROTECTED]>
+ */
+public class Value
+{
+ /**
+ * Will write the given object as an untagged value to the DataOutputStream.
+ *
+ * @param os write the value here
+ * @param obj the Object to write
+ * @throws IOException
+ * @throws InvalidFieldException
+ */
+ public static void writeUntaggedValue(DataOutputStream os, Object obj)
+ throws InvalidFieldException, IOException
+ {
+ writeValue(os, obj, false);
+ }
+
+ /**
+ * Will write the given object as a tagged value to the DataOutputStream.
+ *
+ * @param os write the value here
+ * @param obj the Object to write
+ * @throws IOException
+ * @throws InvalidFieldException
+ */
+ public static void writeTaggedValue(DataOutputStream os, Object obj)
+ throws InvalidFieldException, IOException
+ {
+ writeValue(os, obj, true);
+ }
+
+ /**
+ * Will write the given object as either a value or an untagged value to the
+ * DataOutputStream.
+ *
+ * @param os write the value here
+ * @param obj the Object to write
+ * @param tagged true if the value is tagged, false otherwise
+ * @throws IOException
+ * @throws InvalidFieldException
+ */
+ private static void writeValue(DataOutputStream os, Object obj,
+ boolean tagged)
+ throws IOException, InvalidFieldException
+ {
+ Class clazz = obj.getClass();
+ if (clazz.isPrimitive())
+ {
+ if (clazz == byte.class)
+ {
+ if (tagged)
+ os.writeByte(JdwpConstants.Tag.BYTE);
+ os.writeByte(((Byte) obj).byteValue());
+ }
+ else if (clazz == char.class)
+ {
+ if (tagged)
+ os.writeByte(JdwpConstants.Tag.CHAR);
+ os.writeChar(((Character) obj).charValue());
+ }
+ else if (clazz == float.class)
+ {
+ if (tagged)
+ os.writeByte(JdwpConstants.Tag.FLOAT);
+ os.writeFloat(((Float) obj).floatValue());
+ }
+ else if (clazz == double.class)
+ {
+ if (tagged)
+ os.writeByte(JdwpConstants.Tag.DOUBLE);
+ os.writeDouble(((Double) obj).doubleValue());
+ }
+ else if (clazz == int.class)
+ {
+ if (tagged)
+ os.writeByte(JdwpConstants.Tag.BYTE);
+ os.writeInt(((Integer) obj).intValue());
+ }
+ else if (clazz == long.class)
+ {
+ if (tagged)
+ os.writeByte(JdwpConstants.Tag.LONG);
+ os.writeLong(((Long) obj).longValue());
+ }
+ else if (clazz == short.class)
+ {
+ if (tagged)
+ os.writeByte(JdwpConstants.Tag.SHORT);
+ os.writeInt(((Short) obj).shortValue());
+ }
+ else if (clazz == void.class)
+ { // A 'void' has no data
+ if (tagged)
+ os.writeByte(JdwpConstants.Tag.VOID);
+ }
+ else if (clazz == boolean.class)
+ {
+ if (tagged)
+ os.writeByte(JdwpConstants.Tag.BOOLEAN);
+ os.writeBoolean(((Boolean) obj).booleanValue());
+ }
+ else
+ { // This shouldn't be possible
+ throw new InvalidFieldException("Field has invalid primitive!");
+ }
+ }
+ else
+ {
+ // Object is an Object, not a primitive type wrapped in an object
+ // Write the appropriate tag
+ if (tagged)
+ {
+ if (clazz.isArray())
+ os.writeByte(JdwpConstants.Tag.ARRAY);
+ else if (obj instanceof String)
+ os.writeByte(JdwpConstants.Tag.STRING);
+ else if (obj instanceof Thread)
+ os.writeByte(JdwpConstants.Tag.THREAD);
+ else if (obj instanceof ThreadGroup)
+ os.writeByte(JdwpConstants.Tag.THREAD_GROUP);
+ else if (obj instanceof ClassLoader)
+ os.writeByte(JdwpConstants.Tag.CLASS_LOADER);
+ else if (obj instanceof Class)
+ os.writeByte(JdwpConstants.Tag.CLASS_OBJECT);
+ else
+ os.writeByte(JdwpConstants.Tag.OBJECT);
+ }
+ ObjectId oid = Jdwp.getIdManager().getId(obj);
+ oid.write(os);
+ }
+ }
+
+ /**
+ * Reads the appropriate object for the tagged value contained in the
+ * ByteBuffer.
+ *
+ * @param bb contains the Object
+ * @return The Object referenced by the value
+ * @throws JdwpException
+ * @throws IOException
+ */
+ public static Object getObj(ByteBuffer bb)
+ throws JdwpException, IOException
+ {
+ return getUntaggedObj(bb, bb.get());
+ }
+
+ /**
+ * Reads the an object of the given Class from the untagged value contained
+ * in the ByteBuffer.
+ *
+ * @param bb contains the Object
+ * @param type corresponds to the TAG of value to be read
+ * @return
+ * @throws JdwpException
+ * @throws IOException
+ */
+ public static Object getUntaggedObj(ByteBuffer bb, Class type)
+ throws JdwpException, IOException
+ {
+ if (type.isPrimitive())
+ {
+ if (type == byte.class)
+ return new Byte(bb.get());
+ else if (type == char.class)
+ return new Character(bb.getChar());
+ else if (type == float.class)
+ return new Float(bb.getFloat());
+ else if (type == double.class)
+ return new Double(bb.getDouble());
+ else if (type == int.class)
+ return new Integer(bb.getInt());
+ else if (type == long.class)
+ return new Long(bb.getLong());
+ else if (type == short.class)
+ return new Short(bb.getShort());
+ else if (type == boolean.class)
+ return (bb.get() == 0) ? new Boolean(false) : new Boolean(true);
+ else if (type == void.class)
+ return new byte[0];
+ else
+ { // This shouldn't be possible
+ throw new InvalidFieldException("Field has invalid primitive!");
+ }
+ }
+ else
+ {
+ // Field is an object
+ ObjectId oid = Jdwp.getIdManager().readId(bb);
+ return oid.getObject();
+ }
+ }
+
+ /**
+ * Reads the an object of the given Class from the untagged value contained
+ * in the ByteBuffer.
+ *
+ * @param bb contains the Object
+ * @param tag TAG of the Value to be read
+ * @return the object
+ * @throws JdwpException
+ * @throws IOException
+ */
+ public static Object getUntaggedObj(ByteBuffer bb, byte tag)
+ throws JdwpException, IOException
+ {
+ switch (tag)
+ {
+ case JdwpConstants.Tag.BYTE:
+ return new Byte(bb.get());
+ case JdwpConstants.Tag.CHAR:
+ return new Character(bb.getChar());
+ case JdwpConstants.Tag.FLOAT:
+ return new Float(bb.getFloat());
+ case JdwpConstants.Tag.DOUBLE:
+ return new Double(bb.getDouble());
+ case JdwpConstants.Tag.INT:
+ return new Integer(bb.getInt());
+ case JdwpConstants.Tag.LONG:
+ return new Long(bb.getLong());
+ case JdwpConstants.Tag.SHORT:
+ return new Short(bb.getShort());
+ case JdwpConstants.Tag.VOID:
+ return new byte[0];
+ case JdwpConstants.Tag.BOOLEAN:
+ return (bb.get() == 0) ? new Boolean(false) : new Boolean(true);
+ case JdwpConstants.Tag.STRING:
+ return JdwpString.readString(bb);
+ case JdwpConstants.Tag.ARRAY:
+ case JdwpConstants.Tag.THREAD:
+ case JdwpConstants.Tag.OBJECT:
+ case JdwpConstants.Tag.THREAD_GROUP:
+ case JdwpConstants.Tag.CLASS_LOADER:
+ case JdwpConstants.Tag.CLASS_OBJECT:
+ // All these cases are ObjectIds
+ ObjectId oid = Jdwp.getIdManager().readId(bb);
+ return oid.getObject();
+ default:
+ throw new JdwpInternalErrorException("Could not find TAG:" + tag);
+ }
+ }
+}
Index: gnu/classpath/jdwp/processor/ObjectReferenceCommandSet.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/classpath/jdwp/processor/ObjectReferenceCommandSet.java,v
retrieving revision 1.1
diff -u -p -r1.1 ObjectReferenceCommandSet.java
--- gnu/classpath/jdwp/processor/ObjectReferenceCommandSet.java 12 Jul 2005 18:22:02 -0000 1.1
+++ gnu/classpath/jdwp/processor/ObjectReferenceCommandSet.java 27 Jul 2005 15:49:45 -0000
@@ -36,6 +36,7 @@ this exception to your version of the li
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
+
package gnu.classpath.jdwp.processor;
import gnu.classpath.jdwp.IVirtualMachine;
@@ -103,7 +104,7 @@ public class ObjectReferenceCommandSet i
break;
default:
throw new NotImplementedException("Command " + command +
- " not found in String Reference Command Set.");
+ " not found in ObjectReference Command Set.");
}
}
catch (IOException ex)
@@ -138,7 +139,22 @@ public class ObjectReferenceCommandSet i
for (int i = 0; i < numFields; i++)
{
Field field = (Field) idMan.readId(bb).getObject();
- Value.writeValueFromField(os, field, obj);
+ try
+ {
+ field.setAccessible(true); // Might be a private field
+ Object value = field.get(obj);
+ Value.writeTaggedValue(os, value);
+ }
+ catch (IllegalArgumentException ex)
+ {
+ // I suppose this would best qualify as an invalid field then
+ throw new InvalidFieldException(ex);
+ }
+ catch (IllegalAccessException ex)
+ {
+ // Since we set it as accessible this really shouldn't happen
+ throw new JdwpInternalErrorException(ex);
+ }
}
}
@@ -153,9 +169,10 @@ public class ObjectReferenceCommandSet i
for (int i = 0; i < numFields; i++)
{
Field field = (Field) idMan.readId(bb).getObject();
- Object value = Value.getObj(bb, field);
+ Object value = Value.getUntaggedObj(bb, field.getType());
try
{
+ field.setAccessible(true); // Might be a private field
field.set(obj, value);
}
catch (IllegalArgumentException ex)
@@ -165,7 +182,7 @@ public class ObjectReferenceCommandSet i
}
catch (IllegalAccessException ex)
{
- // We should be able to access any field
+ // Since we set it as accessible this really shouldn't happen
throw new JdwpInternalErrorException(ex);
}
}
@@ -208,7 +225,7 @@ public class ObjectReferenceCommandSet i
if ((invokeOptions & JdwpConstants.InvokeOptions.INVOKE_SINGLE_THREADED) != 0)
{ // We must suspend all other running threads first
- vm.suspendAllThreads();
+ vm.suspendAllThreadsExcept(Thread.currentThread().getThreadGroup());
}
boolean nonVirtual;
if ((invokeOptions & JdwpConstants.InvokeOptions.INVOKE_NONVIRTUAL) != 0)
@@ -220,8 +237,8 @@ public class ObjectReferenceCommandSet i
vmi.executeMethod(obj, thread, clazz, method, values, nonVirtual);
Object value = vmi.getReturnedValue();
ObjectId exceptionId = vmi.getExceptionId();
-
- Value.writeValue(os, value);
+
+ Value.writeTaggedValue(os, value);
exceptionId.writeTagged(os);
}
Index: gnu/classpath/jdwp/processor/ReferenceTypeCommandSet.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/classpath/jdwp/processor/ReferenceTypeCommandSet.java,v
retrieving revision 1.1
diff -u -p -r1.1 ReferenceTypeCommandSet.java
--- gnu/classpath/jdwp/processor/ReferenceTypeCommandSet.java 7 Jul 2005 20:50:47 -0000 1.1
+++ gnu/classpath/jdwp/processor/ReferenceTypeCommandSet.java 27 Jul 2005 15:49:45 -0000
@@ -1,4 +1,4 @@
-/* ReferenceTypeCommandSet.java -- lass to implement the ReferenceType
+/* ReferenceTypeCommandSet.java -- class to implement the ReferenceType
Command Set
Copyright (C) 2005 Free Software Foundation
@@ -36,6 +36,7 @@ this exception to your version of the li
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
+
package gnu.classpath.jdwp.processor;
import gnu.classpath.jdwp.IVirtualMachine;
@@ -125,7 +126,7 @@ public class ReferenceTypeCommandSet imp
break;
default:
throw new NotImplementedException("Command " + command +
- " not found in String Reference Command Set.");
+ " not found in ReferenceType Command Set.");
}
}
catch (IOException ex)
@@ -218,7 +219,24 @@ public class ReferenceTypeCommandSet imp
// We don't actually need the clazz to get the field but we might as
// well check that the debugger got it right
if (fieldClazz.isAssignableFrom(clazz))
- Value.writeStaticValueFromField(os, field);
+ {
+ try
+ {
+ field.setAccessible(true); // Might be a private field
+ Object value = field.get(null);
+ Value.writeTaggedValue(os, value);
+ }
+ catch (IllegalArgumentException ex)
+ {
+ // I suppose this would best qualify as an invalid field then
+ throw new InvalidFieldException(ex);
+ }
+ catch (IllegalAccessException ex)
+ {
+ // Since we set it as accessible this really shouldn't happen
+ throw new JdwpInternalErrorException(ex);
+ }
+ }
else
throw new InvalidFieldException(fieldId.getId());
}
_______________________________________________
Classpath-patches mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/classpath-patches