OSDN Git Service

Classpath JDWP merge with upstream
[pf3gnuchains/gcc-fork.git] / libjava / classpath / gnu / classpath / jdwp / value / ValueFactory.java
1 /* ValueFactory.java -- factory to create JDWP Values
2    Copyright (C) 2007 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 package gnu.classpath.jdwp.value;
39
40 import gnu.classpath.jdwp.JdwpConstants;
41 import gnu.classpath.jdwp.VMIdManager;
42 import gnu.classpath.jdwp.exception.InvalidClassException;
43 import gnu.classpath.jdwp.exception.InvalidObjectException;
44 import gnu.classpath.jdwp.exception.InvalidTagException;
45 import gnu.classpath.jdwp.exception.JdwpInternalErrorException;
46 import gnu.classpath.jdwp.id.ObjectId;
47 import gnu.classpath.jdwp.util.JdwpString;
48
49 import java.nio.ByteBuffer;
50
51 /**
52  * A factory to create JDWP Values.
53  * 
54  * @author Kyle Galloway <kgallowa@redhat.com>
55  */
56 public class ValueFactory
57 {
58   /**
59    * Creates a new Value of appropriate type for the value in the ByteBuffer
60    * by reading the tag byte from the front of the buffer.
61    * 
62    * @param bb contains the Object
63    * @return A new Value of appropriate type
64    * @throws JdwpInternalErrorException
65    * @throws InvalidObjectException
66    */
67   public static Value createFromTagged(ByteBuffer bb)
68     throws JdwpInternalErrorException, InvalidObjectException, InvalidTagException
69   {
70     return create(bb, bb.get());
71   }
72   
73   /**
74    * Creates a new Value of appropriate type for the value in the ByteBuffer
75    * by checking the type of the Class passed in.
76    * 
77    * @param bb contains the Object
78    * @param type a Class representing the type of the value in the ByteBuffer
79    * @return A new Value of appropriate type
80    * @throws JdwpInternalErrorException
81    * @throws InvalidObjectException
82    */
83   public static Value createFromUntagged(ByteBuffer bb, Class type)
84   throws JdwpInternalErrorException, InvalidObjectException, InvalidClassException
85   {
86     byte tag = getTagForClass(type);
87     
88     try
89       {
90         return create(bb, tag);
91       }
92     catch (InvalidTagException ite)
93       {
94         throw new InvalidClassException(ite);
95       }
96   }
97   
98   /**
99    * Creates a new Value of appropriate type for the value in the ByteBuffer.
100    * 
101    * @param bb contains the Object
102    * @param tag a byte representing the type of the object
103    * @return A new Value of appropriate type
104    * @throws JdwpInternalErrorException
105    * @throws InvalidObjectException
106    */
107   private static Value create(ByteBuffer bb, byte tag)
108     throws JdwpInternalErrorException, InvalidObjectException, InvalidTagException
109   {
110     Value val = null;
111     switch(tag)
112     {
113       case JdwpConstants.Tag.BYTE:
114         val = new ByteValue(bb.get());
115         break;
116       case JdwpConstants.Tag.BOOLEAN:
117         val = new BooleanValue((bb.get() != 0));
118         break;
119       case JdwpConstants.Tag.CHAR:
120         val = new CharValue(bb.getChar());
121         break;
122       case JdwpConstants.Tag.SHORT:
123         val = new ShortValue(bb.getShort());
124         break;
125       case JdwpConstants.Tag.INT:
126         val = new IntValue(bb.getInt());
127         break;
128       case JdwpConstants.Tag.FLOAT:
129         val = new FloatValue(bb.getFloat());
130         break;
131       case JdwpConstants.Tag.LONG:
132         val = new LongValue(bb.getLong());
133         break;
134       case JdwpConstants.Tag.DOUBLE:
135         val = new DoubleValue(bb.getDouble());
136         break;
137       case JdwpConstants.Tag.VOID:
138         val = new VoidValue();
139         break;
140       case JdwpConstants.Tag.ARRAY:
141       case JdwpConstants.Tag.THREAD:
142       case JdwpConstants.Tag.OBJECT:
143       case JdwpConstants.Tag.THREAD_GROUP:
144       case JdwpConstants.Tag.CLASS_LOADER:
145       case JdwpConstants.Tag.CLASS_OBJECT:
146         ObjectId oid = VMIdManager.getDefault().readObjectId(bb);
147         val = new ObjectValue(oid.getObject());
148         break;
149       case JdwpConstants.Tag.STRING:
150         val = new StringValue(JdwpString.readString(bb));
151         break;
152       default:
153         throw new InvalidTagException(tag);
154     }
155     
156     return val;
157   }
158   
159   /**
160    * Creates a tag for the type of the class.
161    * 
162    * @param klass the type to get a tag for
163    * @return a byte tag representing the class
164    * @throws JdwpInternalErrorException
165    * @throws InvalidObjectException
166    */
167   private static byte getTagForClass(Class klass)
168     throws JdwpInternalErrorException
169   {
170     byte tag;
171     
172     if (klass.isPrimitive())
173       {
174         if (klass == byte.class)
175           tag = JdwpConstants.Tag.BYTE;
176         else if (klass == boolean.class)
177           tag = JdwpConstants.Tag.BOOLEAN;
178         else if (klass == char.class)
179           tag = JdwpConstants.Tag.CHAR;
180         else if (klass == short.class)
181           tag = JdwpConstants.Tag.SHORT;
182         else if (klass == int.class)
183           tag = JdwpConstants.Tag.INT;
184         else if (klass == float.class)
185           tag = JdwpConstants.Tag.FLOAT;
186         else if (klass == long.class)
187           tag = JdwpConstants.Tag.LONG;
188         else if (klass == double.class)
189           tag = JdwpConstants.Tag.DOUBLE;
190         else if (klass == void.class)
191           tag = JdwpConstants.Tag.VOID;
192         else
193           throw new JdwpInternalErrorException("Invalid primitive class");
194       }
195     else
196       {
197         tag = JdwpConstants.Tag.OBJECT;
198       }
199     
200     return tag;
201   }
202   
203   /**
204    * Create a value type for an Object of type determined by a Class.  This is
205    * a special case where a value needs to be created, but the value to create
206    * it for is already in an object, not in a buffer.
207    * 
208    * @param value the Object to convert to a Value
209    * @param type the Class type of the object
210    * @return a new Value representing this object
211    */
212   public static Value createFromObject(Object value, Class type)
213   {
214     Value val = null;
215     
216     if (type.isPrimitive())
217       {
218         if (type == byte.class)
219           val = new ByteValue(((Byte) value).byteValue());
220         else if (type == boolean.class)
221           val = new BooleanValue(((Boolean) value).booleanValue());
222         else if (type == char.class)
223           val = new CharValue(((Character) value).charValue());
224         else if (type == short.class)
225           val = new ShortValue(((Short) value).shortValue());
226         else if (type == int.class)
227           val = new IntValue(((Integer) value).intValue());
228         else if (type == float.class)
229           val = new FloatValue(((Float) value).floatValue());
230         else if (type == long.class)
231           val = new LongValue(((Long) value).longValue());
232         else if (type == double.class)
233           val = new DoubleValue(((Double) value).doubleValue());
234         else if (type == void.class)
235           val = new VoidValue();
236       }
237     else
238       {
239         if (type.isAssignableFrom(String.class))
240           val = new StringValue ((String) value);
241         else
242           val = new ObjectValue(value);
243       }
244     
245     return val;
246   }
247 }