1 /* ArrayReferenceCommandSet.java -- class to implement the Array 2 Reference Command Set 3 Copyright (C) 2005 Free Software Foundation 4 5 This file is part of GNU Classpath. 6 7 GNU Classpath is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 2, or (at your option) 10 any later version. 11 12 GNU Classpath is distributed in the hope that it will be useful, but 13 WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with GNU Classpath; see the file COPYING. If not, write to the 19 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 20 02110-1301 USA. 21 22 Linking this library statically or dynamically with other modules is 23 making a combined work based on this library. Thus, the terms and 24 conditions of the GNU General Public License cover the whole 25 combination. 26 27 As a special exception, the copyright holders of this library give you 28 permission to link this library with independent modules to produce an 29 executable, regardless of the license terms of these independent 30 modules, and to copy and distribute the resulting executable under 31 terms of your choice, provided that you also meet, for each linked 32 terms of your choice, provided that you also meet, for each linked 33 independent module, the terms and conditions of the license of that 34 module. An independent module is a module which is not derived from 35 or based on this library. If you modify this library, you may extend 36 this exception to your version of the library, but you are not 37 obligated to do so. If you do not wish to do so, delete this 38 exception statement from your version. */ 39 40 41 package gnu.classpath.jdwp.processor; 42 43 import gnu.classpath.jdwp.JdwpConstants; 44 import gnu.classpath.jdwp.exception.InvalidObjectException; 45 import gnu.classpath.jdwp.exception.JdwpException; 46 import gnu.classpath.jdwp.exception.JdwpInternalErrorException; 47 import gnu.classpath.jdwp.exception.NotImplementedException; 48 import gnu.classpath.jdwp.id.ObjectId; 49 import gnu.classpath.jdwp.value.Value; 50 import gnu.classpath.jdwp.value.ValueFactory; 51 52 import java.io.DataOutputStream; 53 import java.io.IOException; 54 import java.lang.reflect.Array; 55 import java.nio.ByteBuffer; 56 57 /** 58 * A class representing the ArrayReference Command Set. 59 * 60 * @author Aaron Luchko <aluchko@redhat.com> 61 */ 62 public class ArrayReferenceCommandSet 63 extends CommandSet 64 { runCommand(ByteBuffer bb, DataOutputStream os, byte command)65 public boolean runCommand(ByteBuffer bb, DataOutputStream os, byte command) 66 throws JdwpException 67 { 68 try 69 { 70 switch (command) 71 { 72 case JdwpConstants.CommandSet.ArrayReference.LENGTH: 73 executeLength(bb, os); 74 break; 75 case JdwpConstants.CommandSet.ArrayReference.GET_VALUES: 76 executeGetValues(bb, os); 77 break; 78 case JdwpConstants.CommandSet.ArrayReference.SET_VALUES: 79 executeSetValues(bb, os); 80 break; 81 default: 82 throw new NotImplementedException("Command " + command + 83 " not found in Array Reference Command Set."); 84 } 85 } 86 catch (IOException ex) 87 { 88 // The DataOutputStream we're using isn't talking to a socket at all 89 // So if we throw an IOException we're in serious trouble 90 throw new JdwpInternalErrorException(ex); 91 } 92 93 return false; 94 } 95 executeLength(ByteBuffer bb, DataOutputStream os)96 private void executeLength(ByteBuffer bb, DataOutputStream os) 97 throws InvalidObjectException, IOException 98 { 99 ObjectId oid = idMan.readObjectId(bb); 100 Object array = oid.getObject(); 101 os.writeInt(Array.getLength(array)); 102 } 103 executeGetValues(ByteBuffer bb, DataOutputStream os)104 private void executeGetValues(ByteBuffer bb, DataOutputStream os) 105 throws JdwpException, IOException 106 { 107 ObjectId oid = idMan.readObjectId(bb); 108 Object array = oid.getObject(); 109 int first = bb.getInt(); 110 int length = bb.getInt(); 111 112 // We need to write out the byte signifying the type of array first 113 Class clazz = array.getClass().getComponentType(); 114 115 // Uugh, this is a little ugly but it's the only time we deal with 116 // arrayregions 117 if (clazz == byte.class) 118 os.writeByte(JdwpConstants.Tag.BYTE); 119 else if (clazz == char.class) 120 os.writeByte(JdwpConstants.Tag.CHAR); 121 else if (clazz == float.class) 122 os.writeByte(JdwpConstants.Tag.FLOAT); 123 else if (clazz == double.class) 124 os.writeByte(JdwpConstants.Tag.DOUBLE); 125 else if (clazz == int.class) 126 os.writeByte(JdwpConstants.Tag.BYTE); 127 else if (clazz == long.class) 128 os.writeByte(JdwpConstants.Tag.LONG); 129 else if (clazz == short.class) 130 os.writeByte(JdwpConstants.Tag.SHORT); 131 else if (clazz == void.class) 132 os.writeByte(JdwpConstants.Tag.VOID); 133 else if (clazz == boolean.class) 134 os.writeByte(JdwpConstants.Tag.BOOLEAN); 135 else if (clazz.isArray()) 136 os.writeByte(JdwpConstants.Tag.ARRAY); 137 else if (String.class.isAssignableFrom(clazz)) 138 os.writeByte(JdwpConstants.Tag.STRING); 139 else if (Thread.class.isAssignableFrom(clazz)) 140 os.writeByte(JdwpConstants.Tag.THREAD); 141 else if (ThreadGroup.class.isAssignableFrom(clazz)) 142 os.writeByte(JdwpConstants.Tag.THREAD_GROUP); 143 else if (ClassLoader.class.isAssignableFrom(clazz)) 144 os.writeByte(JdwpConstants.Tag.CLASS_LOADER); 145 else if (Class.class.isAssignableFrom(clazz)) 146 os.writeByte(JdwpConstants.Tag.CLASS_OBJECT); 147 else 148 os.writeByte(JdwpConstants.Tag.OBJECT); 149 150 // Write all the values, primitives should be untagged and Objects must be 151 // tagged 152 for (int i = first; i < first + length; i++) 153 { 154 Value val = ValueFactory.createFromObject(Array.get(array, i), clazz); 155 if (clazz.isPrimitive()) 156 val.writeUntagged(os); 157 else 158 val.writeTagged(os); 159 } 160 } 161 executeSetValues(ByteBuffer bb, DataOutputStream os)162 private void executeSetValues(ByteBuffer bb, DataOutputStream os) 163 throws IOException, JdwpException 164 { 165 ObjectId oid = idMan.readObjectId(bb); 166 Object array = oid.getObject(); 167 int first = bb.getInt(); 168 int length = bb.getInt(); 169 Class type = array.getClass().getComponentType(); 170 for (int i = first; i < first + length; i++) 171 { 172 Object value = Value.getUntaggedObject(bb, type); 173 Array.set(array, i, value); 174 } 175 } 176 } 177