OSDN Git Service

414c4a33b8299fc84591319e8a84c24eb33257f9
[pf3gnuchains/gcc-fork.git] / libjava / classpath / gnu / classpath / jdwp / util / Value.java
1 /* Value.java -- class to read/write JDWP tagged and untagged values
2    Copyright (C) 2005, 2006, 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 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 the resultant object
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 Boolean.valueOf(bb.get() != 0);
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 }