KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdi > internal > spy > 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.spy;
12
13
14 import java.io.ByteArrayInputStream JavaDoc;
15 import java.io.DataInputStream JavaDoc;
16 import java.io.DataOutputStream JavaDoc;
17 import java.io.IOException JavaDoc;
18 import java.io.InputStream JavaDoc;
19 import java.io.OutputStream JavaDoc;
20 import java.lang.reflect.Field JavaDoc;
21 import java.lang.reflect.Modifier JavaDoc;
22
23 /**
24  * This class implements the corresponding Java Debug Wire Protocol (JDWP) packet
25  * declared by the JDWP specification.
26  *
27  */

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

44     /*package*/ void setId(int id) {
45         fId = id;
46     }
47
48     /**
49      * @return Returns Id.
50      */

51     public int getId() {
52         return fId;
53     }
54     
55     /**
56      * Set Flags.
57      */

58     /*package*/ void setFlags(byte flags) {
59         fFlags = flags;
60     }
61     
62     /**
63      * @return Returns Flags.
64      */

65     public byte getFlags() {
66         return fFlags;
67     }
68
69     /**
70      * @return Returns total length of packet.
71      */

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

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

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

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

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

111     protected abstract void readSpecificHeaderFields(DataInputStream JavaDoc dataInStream) throws IOException JavaDoc;
112     
113     /**
114      * Writes header fields that are specific for a type of packet.
115      */

116     protected abstract void writeSpecificHeaderFields(DataOutputStream JavaDoc dataOutStream) throws IOException JavaDoc;
117     
118     /**
119      * Reads complete packet.
120      */

121     public static JdwpPacket read(InputStream JavaDoc inStream) throws IOException JavaDoc {
122         DataInputStream JavaDoc dataInStream = new DataInputStream JavaDoc(inStream);
123
124         // Read header.
125
int packetLength = dataInStream.readInt();
126         int id = dataInStream.readInt();
127         byte flags = dataInStream.readByte();
128
129         // Determine type: command or reply.
130
JdwpPacket packet;
131         if ((flags & FLAG_REPLY_PACKET) != 0)
132             packet = new JdwpReplyPacket();
133         else
134             packet = new JdwpCommandPacket();
135             
136         // Assign generic header fields.
137
packet.setId(id);
138         packet.setFlags(flags);
139             
140         // Read specific header fields and data.
141
packet.readSpecificHeaderFields(dataInStream);
142         if (packetLength - MIN_PACKET_LENGTH > 0) {
143             packet.fDataBuf = new byte[packetLength - MIN_PACKET_LENGTH];
144             dataInStream.readFully(packet.fDataBuf);
145         }
146         
147         return packet;
148     }
149     
150     /**
151      * Writes complete packet.
152      */

153     public void write(OutputStream JavaDoc outStream) throws IOException JavaDoc {
154         DataOutputStream JavaDoc dataOutStream = new DataOutputStream JavaDoc(outStream);
155         
156         writeHeader(dataOutStream);
157         writeData(dataOutStream);
158     }
159     
160     /**
161      * Writes header of packet.
162      */

163     protected void writeHeader(DataOutputStream JavaDoc dataOutStream) throws IOException JavaDoc {
164         dataOutStream.writeInt(getLength());
165         dataOutStream.writeInt(getId());
166         dataOutStream.writeByte(getFlags());
167         writeSpecificHeaderFields(dataOutStream);
168     }
169     
170     /**
171      * Writes data of packet.
172      */

173     protected void writeData(DataOutputStream JavaDoc dataOutStream) throws IOException JavaDoc {
174         if (fDataBuf != null) {
175             dataOutStream.write(fDataBuf);
176         }
177     }
178
179
180     /**
181      * Retrieves constant mappings.
182      */

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

226     public static String JavaDoc[] getFlagMap() {
227         getConstantMaps();
228         return fgFlagStrings;
229     }
230 }
231
Popular Tags