This it a utility class for Reading/Writing values and untagged-values. http://java.sun.com/j2se/1.5.0/docs/guide/jpda/jdwp-spec.html
As well this patch touches ObjectReferenceCommandSet.java and ReferenceTypeCommandSet.java. The main reason is this is a change to the Value api so they need to use the new api. This also does a couple trivial changes at the same time fixing a couple minor typos and a single line in ObjectReference reflecting a minor change in the api for IVirtualMachine. 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-20 16:36:18.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 primative!"); + } + } + else + { + // Object is an Object, not a primative 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 primative!"); + } + } + 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 20 Jul 2005 20:37:17 -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 ReferenceType Reference Command Set."); } } catch (IOException ex) @@ -138,7 +139,21 @@ public class ObjectReferenceCommandSet i for (int i = 0; i < numFields; i++) { Field field = (Field) idMan.readId(bb).getObject(); - Value.writeValueFromField(os, field, obj); + try + { + 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) + { + // We should be able to access any field + throw new JdwpInternalErrorException(ex); + } } } @@ -153,7 +168,7 @@ 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.set(obj, value); @@ -208,7 +223,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 +235,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 20 Jul 2005 20:37:17 -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 Reference Command Set."); } } catch (IOException ex) @@ -218,7 +219,23 @@ 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 + { + 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) + { + // We should be able to access any field + throw new JdwpInternalErrorException(ex); + } + } else throw new InvalidFieldException(fieldId.getId()); }
_______________________________________________ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches