KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdi > internal > jdwp > JdwpPacket


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.jdwp;
12
13
14 import java.io.ByteArrayInputStream JavaDoc;
15 import java.io.DataInputStream JavaDoc;
16 import java.io.IOException JavaDoc;
17 import java.lang.reflect.Field JavaDoc;
18 import java.lang.reflect.Modifier JavaDoc;
19
20 /**
21  * This class implements the corresponding Java Debug Wire Protocol (JDWP) packet
22  * declared by the JDWP specification.
23  *
24  */

25 public abstract class JdwpPacket {
26     /** General JDWP constants. */
27     public static final byte FLAG_REPLY_PACKET = (byte)0x80;
28     protected static final int MIN_PACKET_LENGTH = 11;
29     
30     /** Map with Strings for flag bits. */
31     private static String JavaDoc[] fgFlagStrings = null;
32
33     /** Header fields. */
34     protected int fId = 0;
35     protected byte fFlags = 0;
36     protected byte[] fDataBuf = null;
37     
38     /**
39      * Set Id.
40      */

41     /*package*/ void setId(int id) {
42         fId = id;
43     }
44
45     /**
46      * @return Returns Id.
47      */

48     public int getId() {
49         return fId;
50     }
51     
52     /**
53      * Set Flags.
54      */

55     /*package*/ void setFlags(byte flags) {
56         fFlags = flags;
57     }
58     
59     /**
60      * @return Returns Flags.
61      */

62     public byte getFlags() {
63         return fFlags;
64     }
65
66     /**
67      * @return Returns total length of packet.
68      */

69     public int getLength() {
70         return MIN_PACKET_LENGTH + getDataLength();
71     }
72     
73     /**
74      * @return Returns length of data in packet.
75      */

76     public int getDataLength() {
77         return fDataBuf == null ? 0 : fDataBuf.length;
78     }
79     
80     /**
81      * @return Returns data of packet.
82      */

83     public byte[] data() {
84         return fDataBuf;
85     }
86
87     /**
88      * @return Returns DataInputStream with reply data, or an empty stream if there is none.
89      */

90     public DataInputStream JavaDoc dataInStream() {
91         if (fDataBuf != null) {
92             return new DataInputStream JavaDoc(new ByteArrayInputStream JavaDoc(fDataBuf));
93         }
94         
95         return new DataInputStream JavaDoc(new ByteArrayInputStream JavaDoc(new byte[0]));
96     }
97
98     /**
99      * Assigns data to packet.
100      */

101     public void setData(byte[] data) {
102         fDataBuf = data;
103     }
104     
105     /**
106      * Reads header fields that are specific for a type of packet.
107      */

108     protected abstract int readSpecificHeaderFields(byte[] bytes, int index) throws IOException JavaDoc;
109     
110     /**
111      * Writes header fields that are specific for a type of packet.
112      */

113     protected abstract int writeSpecificHeaderFields(byte[] bytes, int index) throws IOException JavaDoc;
114     
115     /**
116      * Constructs a JdwpPacket from a byte[].
117      */

118     public static JdwpPacket build(byte[] bytes) throws IOException JavaDoc {
119         // length (int)
120
int a = (bytes[0]&0xff) << 24;
121         int b = (bytes[1]&0xff) << 16;
122         int c = (bytes[2]&0xff) << 8;
123         int d = (bytes[3]&0xff) << 0;
124         int packetLength = a+b+c+d;
125
126         // id (int)
127
a = (bytes[4]&0xff) << 24;
128         b = (bytes[5]&0xff) << 16;
129         c = (bytes[6]&0xff) << 8;
130         d = (bytes[7]&0xff) << 0;
131         int id = a+b+c+d;
132
133         // flags (byte)
134
byte flags = bytes[8];
135
136         // Determine type: command or reply.
137
JdwpPacket packet;
138         if ((flags & FLAG_REPLY_PACKET) != 0)
139             packet = new JdwpReplyPacket();
140         else
141             packet = new JdwpCommandPacket();
142             
143         // Assign generic header fields.
144
packet.setId(id);
145         packet.setFlags(flags);
146             
147         // Read specific header fields and data.
148
int index = 9;
149         index += packet.readSpecificHeaderFields(bytes, 9);
150         if (packetLength - MIN_PACKET_LENGTH > 0) {
151             packet.fDataBuf = new byte[packetLength - MIN_PACKET_LENGTH];
152             System.arraycopy(bytes, index, packet.fDataBuf, 0, packet.fDataBuf.length);
153         }
154         
155         return packet;
156     }
157     
158     public byte[] getPacketAsBytes() throws IOException JavaDoc {
159         int len = getLength();
160         byte[] bytes = new byte[len];
161         
162         //convert len to bytes
163
bytes[0] = (byte) (len >>> 24);
164         bytes[1] = (byte) (len >>> 16);
165         bytes[2] = (byte) (len >>> 8);
166         bytes[3] = (byte) (len >>> 0);
167         
168         //convert id to bytes
169
int id = getId();
170         bytes[4] = (byte) (id >>> 24);
171         bytes[5] = (byte) (id >>> 16);
172         bytes[6] = (byte) (id >>> 8);
173         bytes[7] = (byte) (id >>> 0);
174         
175         //flags
176
bytes[8] = getFlags();
177         
178         //convert specific header fields
179
int index = 9;
180         index += writeSpecificHeaderFields(bytes, index);
181         
182         if (index < len && fDataBuf!=null) {
183             //copy data
184
System.arraycopy(fDataBuf, 0, bytes, index, fDataBuf.length);
185         }
186         return bytes;
187     }
188
189     /**
190      * Retrieves constant mappings.
191      */

192     public static void getConstantMaps() {
193         if (fgFlagStrings != null) {
194             return;
195         }
196         
197         Field JavaDoc[] fields = JdwpPacket.class.getDeclaredFields();
198         fgFlagStrings = new String JavaDoc[8];
199         
200         for (int i = 0; i < fields.length; i++) {
201             Field JavaDoc field = fields[i];
202             if ((field.getModifiers() & Modifier.PUBLIC) == 0 || (field.getModifiers() & Modifier.STATIC) == 0 || (field.getModifiers() & Modifier.FINAL) == 0) {
203                 continue;
204             }
205                 
206             String JavaDoc name = field.getName();
207             if (!name.startsWith("FLAG_")) {//$NON-NLS-1$
208
continue;
209             }
210                 
211             name = name.substring(5);
212             
213             try {
214                 byte value = field.getByte(null);
215                 
216                 for (int j = 0; j < fgFlagStrings.length; j++) {
217                     if ((1 << j & value) != 0) {
218                         fgFlagStrings[j]= name;
219                         break;
220                     }
221                 }
222             } catch (IllegalAccessException JavaDoc e) {
223                 // Will not occur for own class.
224
} catch (IllegalArgumentException JavaDoc e) {
225                 // Should not occur.
226
// We should take care that all public static final constants
227
// in this class are bytes.
228
}
229         }
230     }
231     
232     /**
233      * @return Returns a mapping with string representations of flags.
234      */

235     public static String JavaDoc[] getFlagMap() {
236         getConstantMaps();
237         return fgFlagStrings;
238     }
239 }
240
Popular Tags