KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdi > internal > ArrayReferenceImpl


1 /*******************************************************************************
2  * Copyright (c) 2000, 2005 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.jdi.internal;
12
13
14 import java.io.ByteArrayOutputStream JavaDoc;
15 import java.io.DataInputStream JavaDoc;
16 import java.io.DataOutputStream JavaDoc;
17 import java.io.IOException JavaDoc;
18 import java.util.ArrayList JavaDoc;
19 import java.util.Iterator JavaDoc;
20 import java.util.List JavaDoc;
21
22 import org.eclipse.jdi.internal.jdwp.JdwpCommandPacket;
23 import org.eclipse.jdi.internal.jdwp.JdwpID;
24 import org.eclipse.jdi.internal.jdwp.JdwpObjectID;
25 import org.eclipse.jdi.internal.jdwp.JdwpReplyPacket;
26
27 import com.sun.jdi.ArrayReference;
28 import com.sun.jdi.ClassNotLoadedException;
29 import com.sun.jdi.InternalException;
30 import com.sun.jdi.InvalidTypeException;
31 import com.sun.jdi.ObjectCollectedException;
32 import com.sun.jdi.Type;
33 import com.sun.jdi.Value;
34
35 /**
36  * this class implements the corresponding interfaces
37  * declared by the JDI specification. See the com.sun.jdi package
38  * for more information.
39  *
40  */

41 public class ArrayReferenceImpl extends ObjectReferenceImpl implements ArrayReference {
42     /** JDWP Tag. */
43     public static final byte tag = JdwpID.ARRAY_TAG;
44     
45     private int fLength = -1;
46     
47     /**
48      * Creates new ArrayReferenceImpl.
49      */

50     public ArrayReferenceImpl(VirtualMachineImpl vmImpl, JdwpObjectID objectID) {
51         super("ArrayReference", vmImpl, objectID); //$NON-NLS-1$
52
}
53     
54     /**
55      * @returns tag.
56      */

57     public byte getTag() {
58         return tag;
59     }
60     
61     /**
62      * @returns Returns an array component value.
63      */

64     public Value getValue(int index) throws IndexOutOfBoundsException JavaDoc {
65         return (Value)getValues(index, 1).get(0);
66     }
67     
68     /**
69      * @returns Returns all of the components in this array.
70      */

71     public List JavaDoc getValues() {
72         return getValues(0, -1);
73     }
74     
75     /**
76      * @returns Returns a range of array components.
77      */

78     public List JavaDoc getValues(int firstIndex, int length) throws IndexOutOfBoundsException JavaDoc {
79
80         int arrayLength= length();
81
82         if (firstIndex < 0 || firstIndex >= arrayLength) {
83             throw new IndexOutOfBoundsException JavaDoc(JDIMessages.ArrayReferenceImpl_Invalid_index_1);
84         }
85         
86         if (length == -1) {
87             // length == -1 means all elements to the end.
88
length = arrayLength - firstIndex;
89         } else if (length < -1) {
90             throw new IndexOutOfBoundsException JavaDoc(JDIMessages.ArrayReferenceImpl_Invalid_number_of_value_to_get_from_array_1);
91         } else if (firstIndex + length > arrayLength) {
92             throw new IndexOutOfBoundsException JavaDoc(JDIMessages.ArrayReferenceImpl_Attempted_to_get_more_values_from_array_than_length_of_array_2);
93         }
94             
95         // Note that this information should not be cached.
96
initJdwpRequest();
97         try {
98             ByteArrayOutputStream JavaDoc outBytes = new ByteArrayOutputStream JavaDoc();
99             DataOutputStream JavaDoc outData = new DataOutputStream JavaDoc(outBytes);
100             write(this, outData); // arrayObject
101
writeInt(firstIndex, "firstIndex", outData); //$NON-NLS-1$
102
writeInt(length, "length", outData); //$NON-NLS-1$
103

104             JdwpReplyPacket replyPacket = requestVM(JdwpCommandPacket.AR_GET_VALUES, outBytes);
105             switch (replyPacket.errorCode()) {
106                 case JdwpReplyPacket.INVALID_INDEX:
107                     throw new IndexOutOfBoundsException JavaDoc(JDIMessages.ArrayReferenceImpl_Invalid_index_of_array_reference_given_1);
108             }
109             defaultReplyErrorHandler(replyPacket.errorCode());
110             
111             DataInputStream JavaDoc replyData = replyPacket.dataInStream();
112     
113             /* NOTE: The JDWP documentation is not clear on this: it turns out that the following is received from the VM:
114              * - type tag;
115              * - length of array;
116              * - values of elements.
117              */

118
119             int type = readByte("type", JdwpID.tagMap(), replyData); //$NON-NLS-1$
120
int readLength = readInt("length", replyData); //$NON-NLS-1$
121
// See also ValueImpl.
122
switch(type) {
123                 // Multidimensional array.
124
case ArrayReferenceImpl.tag:
125                 // Object references.
126
case ClassLoaderReferenceImpl.tag:
127                 case ClassObjectReferenceImpl.tag:
128                 case StringReferenceImpl.tag:
129                 case ObjectReferenceImpl.tag:
130                 case ThreadGroupReferenceImpl.tag:
131                 case ThreadReferenceImpl.tag:
132                     return readObjectSequence(readLength, replyData);
133
134                 // Primitive type.
135
case BooleanValueImpl.tag:
136                 case ByteValueImpl.tag:
137                 case CharValueImpl.tag:
138                 case DoubleValueImpl.tag:
139                 case FloatValueImpl.tag:
140                 case IntegerValueImpl.tag:
141                 case LongValueImpl.tag:
142                 case ShortValueImpl.tag:
143                     return readPrimitiveSequence(readLength, type, replyData);
144
145                 case VoidValueImpl.tag:
146                 case 0:
147                 default:
148                     throw new InternalException(JDIMessages.ArrayReferenceImpl_Invalid_ArrayReference_Value_tag_encountered___2 + type);
149             }
150         } catch (IOException JavaDoc e) {
151             defaultIOExceptionHandler(e);
152             return null;
153         } finally {
154             handledJdwpRequest();
155         }
156     }
157
158     /**
159      * @returns Returns sequence of object reference values.
160      */

161     private List JavaDoc readObjectSequence(int length, DataInputStream JavaDoc in) throws IOException JavaDoc {
162         List JavaDoc elements = new ArrayList JavaDoc(length);
163         for (int i = 0; i < length; i++) {
164             ValueImpl value = ObjectReferenceImpl.readObjectRefWithTag(this, in);
165             elements.add(value);
166         }
167         return elements;
168     }
169     
170     /**
171      * @returns Returns sequence of values of primitive type.
172      */

173     private List JavaDoc readPrimitiveSequence(int length, int type, DataInputStream JavaDoc in) throws IOException JavaDoc {
174         List JavaDoc elements = new ArrayList JavaDoc(length);
175         for (int i = 0; i < length; i++) {
176             ValueImpl value = ValueImpl.readWithoutTag(this, type, in);
177             elements.add(value);
178         }
179         return elements;
180     }
181     
182     /**
183      * @returns Returns the number of components in this array.
184      */

185     public int length() {
186         if (fLength == -1) {
187             initJdwpRequest();
188             try {
189                 JdwpReplyPacket replyPacket = requestVM(JdwpCommandPacket.AR_LENGTH, this);
190                 defaultReplyErrorHandler(replyPacket.errorCode());
191                 DataInputStream JavaDoc replyData = replyPacket.dataInStream();
192                 fLength = readInt("length", replyData); //$NON-NLS-1$
193
} catch (IOException JavaDoc e) {
194                 defaultIOExceptionHandler(e);
195                 return 0;
196             } finally {
197                 handledJdwpRequest();
198             }
199         }
200         return fLength;
201     }
202     
203     /**
204      * Replaces an array component with another value.
205      */

206     public void setValue(int index, Value value) throws InvalidTypeException, ClassNotLoadedException {
207         ArrayList JavaDoc list = new ArrayList JavaDoc(1);
208         list.add(value);
209         setValues(index, list, 0, 1);
210     }
211     
212     /**
213      * Replaces all array components with other values.
214      */

215     public void setValues(List JavaDoc values) throws InvalidTypeException, ClassNotLoadedException {
216         setValues(0, values, 0, -1);
217     }
218     
219     /**
220      * Replaces a range of array components with other values.
221      */

222     public void setValues(int index, List JavaDoc values, int srcIndex, int length) throws InvalidTypeException, ClassNotLoadedException {
223         
224         int valuesSize= values.size();
225         int arrayLength= length();
226         
227         if (index < 0 || index >= arrayLength) {
228             throw new IndexOutOfBoundsException JavaDoc(JDIMessages.ArrayReferenceImpl_Invalid_index_1);
229         }
230         if (srcIndex < 0 || srcIndex >= valuesSize) {
231             throw new IndexOutOfBoundsException JavaDoc(JDIMessages.ArrayReferenceImpl_Invalid_srcIndex_2);
232         }
233         
234         if (length < -1) {
235             throw new IndexOutOfBoundsException JavaDoc(JDIMessages.ArrayReferenceImpl_Invalid_number_of_value_to_set_in_array_3);
236         } else if (length == -1) {
237             // length == -1 indicates as much values as possible.
238
length = arrayLength - index;
239             int lengthTmp= valuesSize - srcIndex;
240             if (lengthTmp < length) {
241                 length= lengthTmp;
242             }
243         } else if (index + length > arrayLength) {
244             throw new IndexOutOfBoundsException JavaDoc(JDIMessages.ArrayReferenceImpl_Attempted_to_set_more_values_in_array_than_length_of_array_3);
245         } else if (srcIndex + length > valuesSize) {
246             // Check if enough values are given.
247
throw new IndexOutOfBoundsException JavaDoc(JDIMessages.ArrayReferenceImpl_Attempted_to_set_more_values_in_array_than_given_4);
248         }
249         
250         // check and convert the values if needed.
251
List JavaDoc checkedValues= checkValues(values.subList(srcIndex, srcIndex + length), ((ArrayTypeImpl) referenceType()).componentType());
252
253         // Note that this information should not be cached.
254
initJdwpRequest();
255         try {
256             ByteArrayOutputStream JavaDoc outBytes = new ByteArrayOutputStream JavaDoc();
257             DataOutputStream JavaDoc outData = new DataOutputStream JavaDoc(outBytes);
258             write(this, outData);
259             writeInt(index, "index", outData); //$NON-NLS-1$
260
writeInt(length, "length", outData); //$NON-NLS-1$
261
Iterator JavaDoc iterValues= checkedValues.iterator();
262             while (iterValues.hasNext()) {
263                 ValueImpl value= (ValueImpl)iterValues.next();
264                 if (value != null) {
265                     value.write(this, outData);
266                 } else {
267                     ValueImpl.writeNull(this, outData);
268                 }
269             }
270     
271             JdwpReplyPacket replyPacket = requestVM(JdwpCommandPacket.AR_SET_VALUES, outBytes);
272             switch (replyPacket.errorCode()) {
273                 case JdwpReplyPacket.TYPE_MISMATCH:
274                     throw new InvalidTypeException();
275                 case JdwpReplyPacket.INVALID_CLASS:
276                     throw new ClassNotLoadedException(type().name());
277             }
278             defaultReplyErrorHandler(replyPacket.errorCode());
279         } catch (IOException JavaDoc e) {
280             defaultIOExceptionHandler(e);
281         } finally {
282             handledJdwpRequest();
283         }
284     }
285
286     /**
287      * Check the type and the vm of the values. If the given type is a primitive type,
288      * the values may be convert for match this type.
289      * @see ValueImpl#checkValue(Value, Type, VirtualMachineImpl)
290      */

291     private List JavaDoc checkValues(List JavaDoc values, Type type) throws InvalidTypeException {
292         List JavaDoc checkedValues= new ArrayList JavaDoc(values.size());
293         Iterator JavaDoc iterValues= values.iterator();
294         while (iterValues.hasNext()) {
295             checkedValues.add(ValueImpl.checkValue((Value) iterValues.next(), type, virtualMachineImpl()));
296         }
297         return checkedValues;
298     }
299     
300     /**
301      * @return Returns description of Mirror object.
302      */

303     public String JavaDoc toString() {
304         try {
305             StringBuffer JavaDoc buf = new StringBuffer JavaDoc(type().name());
306             // Insert length of string between (last) square braces.
307
buf.insert(buf.length() - 1, length());
308             // Append space and idString.
309
buf.append(' ');
310             buf.append(idString());
311             return buf.toString();
312         } catch (ObjectCollectedException e) {
313             return JDIMessages.ArrayReferenceImpl__Garbage_Collected__ArrayReference_5 + "[" + length() + "] " + idString(); //$NON-NLS-1$ //$NON-NLS-2$
314
} catch (Exception JavaDoc e) {
315             return fDescription;
316         }
317     }
318
319     /**
320      * @return Reads JDWP representation and returns new instance.
321      */

322     public static ArrayReferenceImpl read(MirrorImpl target, DataInputStream JavaDoc in) throws IOException JavaDoc {
323         VirtualMachineImpl vmImpl = target.virtualMachineImpl();
324         JdwpObjectID ID = new JdwpObjectID(vmImpl);
325         ID.read(in);
326         if (target.fVerboseWriter != null) {
327             target.fVerboseWriter.println("arrayReference", ID.value()); //$NON-NLS-1$
328
}
329
330         if (ID.isNull()) {
331             return null;
332         }
333             
334         ArrayReferenceImpl mirror = new ArrayReferenceImpl(vmImpl, ID);
335         return mirror;
336     }
337 }
338
Popular Tags