Source for gnu.classpath.jdwp.util.Value

   1: /* Value.java -- class to read/write JDWP tagged and untagged values
   2:    Copyright (C) 2005 Free Software Foundation
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10: 
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version. */
  37: 
  38: 
  39: package gnu.classpath.jdwp.util;
  40: 
  41: import gnu.classpath.jdwp.JdwpConstants;
  42: import gnu.classpath.jdwp.VMIdManager;
  43: import gnu.classpath.jdwp.exception.InvalidFieldException;
  44: import gnu.classpath.jdwp.exception.JdwpException;
  45: import gnu.classpath.jdwp.exception.JdwpInternalErrorException;
  46: import gnu.classpath.jdwp.exception.NotImplementedException;
  47: import gnu.classpath.jdwp.id.ObjectId;
  48: 
  49: import java.io.DataOutputStream;
  50: import java.io.IOException;
  51: import java.nio.ByteBuffer;
  52: 
  53: /**
  54:  * A class to read/write JDWP tagged and untagged values.
  55:  * 
  56:  * @author Aaron Luchko <aluchko@redhat.com>
  57:  */
  58: public class Value
  59: {
  60:   /**
  61:    * Will write the given object as an untagged value to the DataOutputStream.
  62:    * 
  63:    * @param os write the value here
  64:    * @param obj the Object to write
  65:    * @throws IOException
  66:    * @throws InvalidFieldException
  67:    */  
  68:   public static void writeUntaggedValue(DataOutputStream os, Object obj)
  69:     throws JdwpException, IOException
  70:   {
  71:     writeValue(os, obj, false);
  72:   }
  73:   
  74:   /**
  75:    * Will write the given object as a tagged value to the DataOutputStream.
  76:    * 
  77:    * @param os write the value here
  78:    * @param obj the Object to write
  79:    * @throws IOException
  80:    * @throws InvalidFieldException
  81:    */
  82:   public static void writeTaggedValue(DataOutputStream os, Object obj)
  83:     throws JdwpException, IOException
  84:   {
  85:     writeValue(os, obj, true);
  86:   }
  87:   
  88:   /**
  89:    * Will write the given object as either a value or an untagged value to the
  90:    * DataOutputStream.
  91:    * 
  92:    * @param os write the value here
  93:    * @param obj the Object to write
  94:    * @param tagged true if the value is tagged, false otherwise
  95:    * @throws IOException
  96:    * @throws InvalidFieldException
  97:    */
  98:   private static void writeValue(DataOutputStream os, Object obj,
  99:                                 boolean tagged)
 100:     throws IOException, JdwpException
 101:   {
 102:     Class clazz = obj.getClass();
 103:     if (clazz.isPrimitive())
 104:       {
 105:         if (clazz == byte.class)
 106:           {
 107:             if (tagged)
 108:               os.writeByte(JdwpConstants.Tag.BYTE);
 109:             os.writeByte(((Byte) obj).byteValue());
 110:           }
 111:         else if (clazz == char.class)
 112:           {
 113:             if (tagged)
 114:               os.writeByte(JdwpConstants.Tag.CHAR);
 115:             os.writeChar(((Character) obj).charValue());
 116:           }
 117:         else if (clazz == float.class)
 118:           {
 119:             if (tagged)
 120:               os.writeByte(JdwpConstants.Tag.FLOAT);
 121:             os.writeFloat(((Float) obj).floatValue());
 122:           }
 123:         else if (clazz == double.class)
 124:           {
 125:             if (tagged)
 126:               os.writeByte(JdwpConstants.Tag.DOUBLE);
 127:             os.writeDouble(((Double) obj).doubleValue());
 128:           }
 129:         else if (clazz == int.class)
 130:           {
 131:             if (tagged)
 132:               os.writeByte(JdwpConstants.Tag.BYTE);
 133:             os.writeInt(((Integer) obj).intValue());
 134:           }
 135:         else if (clazz == long.class)
 136:           {
 137:             if (tagged)
 138:               os.writeByte(JdwpConstants.Tag.LONG);
 139:             os.writeLong(((Long) obj).longValue());
 140:           }
 141:         else if (clazz == short.class)
 142:           {
 143:             if (tagged)
 144:               os.writeByte(JdwpConstants.Tag.SHORT);
 145:             os.writeInt(((Short) obj).shortValue());
 146:           }
 147:         else if (clazz == void.class)
 148:           { // A 'void' has no data
 149:             if (tagged)
 150:               os.writeByte(JdwpConstants.Tag.VOID);
 151:           }
 152:         else if (clazz == boolean.class)
 153:           {
 154:             if (tagged)
 155:               os.writeByte(JdwpConstants.Tag.BOOLEAN);
 156:             os.writeBoolean(((Boolean) obj).booleanValue());
 157:           }
 158:         else
 159:           { // This shouldn't be possible
 160:             throw new JdwpInternalErrorException(
 161:               "Field has invalid primitive!");
 162:           }
 163:       }
 164:     else
 165:       {
 166:         // Object is an Object, not a primitive type wrapped in an object
 167:         // Write the appropriate tag
 168:         if (tagged)
 169:           {
 170:             if (clazz.isArray())
 171:               os.writeByte(JdwpConstants.Tag.ARRAY);
 172:             else if (obj instanceof String)
 173:               os.writeByte(JdwpConstants.Tag.STRING);
 174:             else if (obj instanceof Thread)
 175:               os.writeByte(JdwpConstants.Tag.THREAD);
 176:             else if (obj instanceof ThreadGroup)
 177:               os.writeByte(JdwpConstants.Tag.THREAD_GROUP);
 178:             else if (obj instanceof ClassLoader)
 179:               os.writeByte(JdwpConstants.Tag.CLASS_LOADER);
 180:             else if (obj instanceof Class)
 181:               os.writeByte(JdwpConstants.Tag.CLASS_OBJECT);
 182:             else
 183:               os.writeByte(JdwpConstants.Tag.OBJECT);
 184:           }
 185:         ObjectId oid = VMIdManager.getDefault().getObjectId(obj);
 186:         oid.write(os);
 187:       }
 188:   }
 189: 
 190:   /**
 191:    * Reads the appropriate object for the tagged value contained in the 
 192:    * ByteBuffer.
 193:    * 
 194:    * @param bb contains the Object
 195:    * @return The Object referenced by the value
 196:    * @throws JdwpException
 197:    * @throws IOException
 198:    */
 199:   public static Object getObj(ByteBuffer bb)
 200:     throws JdwpException, IOException
 201:   {
 202:     return getUntaggedObj(bb, bb.get());
 203:   }
 204: 
 205:   /**
 206:    * Reads the an object of the given Class from the untagged value contained
 207:    * in the ByteBuffer.
 208:    * 
 209:    * @param bb contains the Object
 210:    * @param type corresponds to the TAG of value to be read 
 211:    * @return
 212:    * @throws JdwpException
 213:    * @throws IOException
 214:    */
 215:   public static Object getUntaggedObj(ByteBuffer bb, Class type)
 216:     throws JdwpException, IOException
 217:   {
 218:     if (type.isPrimitive())
 219:       {
 220:         if (type == byte.class)
 221:           return new Byte(bb.get());
 222:         else if (type == char.class)
 223:           return new Character(bb.getChar());
 224:         else if (type == float.class)
 225:           return new Float(bb.getFloat());
 226:         else if (type == double.class)
 227:           return new Double(bb.getDouble());
 228:         else if (type == int.class)
 229:           return new Integer(bb.getInt());
 230:         else if (type == long.class)
 231:           return new Long(bb.getLong());
 232:         else if (type == short.class)
 233:           return new Short(bb.getShort());
 234:         else if (type == boolean.class)
 235:           return (bb.get() == 0) ? new Boolean(false) : new Boolean(true);
 236:         else if (type == void.class)
 237:           return new byte[0];
 238:         else
 239:           { // This shouldn't be possible
 240:             throw new JdwpInternalErrorException(
 241:               "Field has invalid primitive!");
 242:           }
 243:       }
 244:     else
 245:       {
 246:         // Field is an object
 247:         ObjectId oid = VMIdManager.getDefault().readObjectId(bb);
 248:         return oid.getObject();
 249:       }
 250:   }
 251: 
 252:   /**
 253:    * Reads the an object of the given Class from the untagged value contained
 254:    * in the ByteBuffer.
 255:    * 
 256:    * @param bb contains the Object
 257:    * @param tag TAG of the Value to be read
 258:    * @return the object
 259:    * @throws JdwpException
 260:    * @throws IOException
 261:    */
 262:   public static Object getUntaggedObj(ByteBuffer bb, byte tag)
 263:     throws JdwpException, IOException
 264:   {
 265:     switch (tag)
 266:       {
 267:       case JdwpConstants.Tag.BYTE:
 268:         return new Byte(bb.get());
 269:       case JdwpConstants.Tag.CHAR:
 270:         return new Character(bb.getChar());
 271:       case JdwpConstants.Tag.FLOAT:
 272:         return new Float(bb.getFloat());
 273:       case JdwpConstants.Tag.DOUBLE:
 274:         return new Double(bb.getDouble());
 275:       case JdwpConstants.Tag.INT:
 276:         return new Integer(bb.getInt());
 277:       case JdwpConstants.Tag.LONG:
 278:         return new Long(bb.getLong());
 279:       case JdwpConstants.Tag.SHORT:
 280:         return new Short(bb.getShort());
 281:       case JdwpConstants.Tag.VOID:
 282:         return new byte[0];
 283:       case JdwpConstants.Tag.BOOLEAN:
 284:         return (bb.get() == 0) ? new Boolean(false) : new Boolean(true);
 285:       case JdwpConstants.Tag.STRING:
 286:         return JdwpString.readString(bb);
 287:       case JdwpConstants.Tag.ARRAY:
 288:       case JdwpConstants.Tag.THREAD:
 289:       case JdwpConstants.Tag.OBJECT:
 290:       case JdwpConstants.Tag.THREAD_GROUP:
 291:       case JdwpConstants.Tag.CLASS_LOADER:
 292:       case JdwpConstants.Tag.CLASS_OBJECT:
 293:         // All these cases are ObjectIds
 294:         ObjectId oid = VMIdManager.getDefault().readObjectId(bb);
 295:         return oid.getObject();
 296:       default:
 297:         throw new NotImplementedException("Tag " + tag
 298:                                           + " is not implemented.");
 299:       }
 300:   }
 301: }