001: /*******************************************************************************
002: * Copyright (c) 2000, 2005 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.jdi.internal.jdwp;
011:
012: import java.io.DataInputStream;
013: import java.io.DataOutputStream;
014: import java.io.IOException;
015: import java.util.HashMap;
016: import java.util.Map;
017:
018: import org.eclipse.jdi.internal.VirtualMachineImpl;
019:
020: /**
021: * From this class all Java Debug Wire Protocol (JDWP) IDs
022: * declared by the JDWP specification are derived.
023: *
024: */
025: public abstract class JdwpID {
026: /** Tag Constants. */
027: public static final byte NULL_TAG = 91; // Used for tagged null values.
028: public static final byte ARRAY_TAG = 91; // '[' - an array object (objectID size).
029: public static final byte BYTE_TAG = 66; // 'B' - a byte value (1 byte).
030: public static final byte CHAR_TAG = 67; // 'C' - a character value (2 bytes).
031: public static final byte OBJECT_TAG = 76; // 'L' - an object (objectID size).
032: public static final byte FLOAT_TAG = 70; // 'F' - a float value (4 bytes).
033: public static final byte DOUBLE_TAG = 68; // 'D' - a double value (8 bytes).
034: public static final byte INT_TAG = 73; // 'I' - an int value (4 bytes).
035: public static final byte LONG_TAG = 74; // 'J' - a long value (8 bytes).
036: public static final byte SHORT_TAG = 83; // 'S' - a short value (2 bytes).
037: public static final byte VOID_TAG = 86; // 'V' - a void value (no bytes).
038: public static final byte BOOLEAN_TAG = 90; // 'Z' - a boolean value (1 byte).
039: public static final byte STRING_TAG = 115; // 's' - a String object (objectID size).
040: public static final byte THREAD_TAG = 116; // 't' - a Thread object (objectID size).
041: public static final byte THREAD_GROUP_TAG = 103; // 'g' - a ThreadGroup object (objectID size).
042: public static final byte CLASS_LOADER_TAG = 108; // 'l' - a ClassLoader object (objectID size).
043: public static final byte CLASS_OBJECT_TAG = 99; // 'c' - a class object object (objectID size).
044:
045: /** TypeTag Constants. */
046: public static final byte TYPE_TAG_CLASS = 1; // ReferenceType is a class.
047: public static final byte TYPE_TAG_INTERFACE = 2; // ReferenceType is an interface.
048: public static final byte TYPE_TAG_ARRAY = 3; // ReferenceType is an array.
049:
050: /** Mapping of command codes to strings. */
051: private static HashMap fTagMap = null;
052: private static HashMap fTypeTagMap = null;
053:
054: /** Jdwp representation of null ID. */
055: protected static final int VALUE_NULL = 0;
056:
057: /** The value of the ID */
058: protected long fValue = VALUE_NULL;
059: /** The virtual machine of the mirror object that uses this ID (needed for ID sizes. */
060: protected VirtualMachineImpl fVirtualMachine;
061:
062: /**
063: * Creates new JdwpID.
064: */
065: public JdwpID(VirtualMachineImpl vmImpl) {
066: fVirtualMachine = vmImpl;
067: }
068:
069: /**
070: * @return Returns true if two IDs refer to the same entity in the target VM.
071: * @see java.lang.Object#equals(Object)
072: */
073: public boolean equals(Object object) {
074: return object instanceof JdwpID
075: && fValue == ((JdwpID) object).fValue;
076: }
077:
078: /**
079: * @return Returns a has code for this object.
080: * @see java.lang.Object#hashCode
081: */
082: public int hashCode() {
083: return (int) fValue;
084: }
085:
086: /**
087: * @return Returns value of ID.
088: */
089: public final long value() {
090: return fValue;
091: }
092:
093: /**
094: * @return Returns string representation.
095: */
096: public String toString() {
097: return new Long(fValue).toString();
098: }
099:
100: /**
101: * @return Returns VM specific size of ID.
102: */
103: protected abstract int getSize();
104:
105: /**
106: * @return Returns true if ID is null.
107: */
108: public abstract boolean isNull();
109:
110: /**
111: * Reads ID.
112: */
113: public void read(DataInputStream inStream) throws IOException {
114: fValue = 0;
115: int size = getSize();
116: for (int i = 0; i < size; i++) {
117: int b = inStream.readUnsignedByte(); // Note that the byte must be treated as unsigned.
118: fValue = fValue << 8 | b;
119: }
120: }
121:
122: /**
123: * Writes ID.
124: */
125: public void write(DataOutputStream outStream) throws IOException {
126: int size = getSize();
127: for (int i = size - 1; i >= 0; i--) {
128: byte b = (byte) (fValue >>> 8 * i); // Note that >>> must be used because fValue must be treated as unsigned.
129: outStream.write(b);
130: }
131: }
132:
133: /**
134: * Retrieves constant mappings.
135: */
136: public static void getConstantMaps() {
137: if (fTagMap != null)
138: return;
139:
140: java.lang.reflect.Field[] fields = JdwpID.class
141: .getDeclaredFields();
142: fTagMap = new HashMap();
143: fTypeTagMap = new HashMap();
144: for (int i = 0; i < fields.length; i++) {
145: java.lang.reflect.Field field = fields[i];
146: if ((field.getModifiers() & java.lang.reflect.Modifier.PUBLIC) == 0
147: || (field.getModifiers() & java.lang.reflect.Modifier.STATIC) == 0
148: || (field.getModifiers() & java.lang.reflect.Modifier.FINAL) == 0)
149: continue;
150:
151: try {
152: String name = field.getName();
153: Integer intValue = new Integer(field.getInt(null));
154: if (name.startsWith("TYPE_TAG_")) { //$NON-NLS-1$
155: name = name.substring(9);
156: fTypeTagMap.put(intValue, name);
157: } else if (name.endsWith("_TAG")) { //$NON-NLS-1$
158: fTagMap.put(intValue, name);
159: }
160: } catch (IllegalAccessException e) {
161: // Will not occur for own class.
162: } catch (IllegalArgumentException e) {
163: // Should not occur.
164: // We should take care that all public static final constants
165: // in this class are numbers that are convertible to int.
166: }
167: }
168: }
169:
170: /**
171: * @return Returns a map with string representations of tags.
172: */
173: public static Map tagMap() {
174: getConstantMaps();
175: return fTagMap;
176: }
177:
178: /**
179: * @return Returns a map with string representations of type tags.
180: */
181: public static Map typeTagMap() {
182: getConstantMaps();
183: return fTypeTagMap;
184: }
185: }
|