fix bug #675.
[phpeclipse.git] / net.sourceforge.phpeclipse.xdebug.core / src / net / sourceforge / phpeclipse / xdebug / core / xdebug / XDebugConnection.java
1 /**
2  * 
3  */
4 package net.sourceforge.phpeclipse.xdebug.core.xdebug;
5
6 import java.io.DataInputStream;
7 import java.io.EOFException;
8 import java.io.IOException;
9 import java.io.OutputStreamWriter;
10 import java.io.UnsupportedEncodingException;
11 import java.net.Socket;
12
13 import net.sourceforge.phpeclipse.xdebug.core.Base64;
14 import net.sourceforge.phpeclipse.xdebug.core.PHPDebugUtils;
15 import net.sourceforge.phpeclipse.xdebug.core.XDebugCorePlugin;
16 //import net.sourceforge.phpeclipse.xdebug.core.xdebug.ResponseListener.XDebugResponse;
17
18 import org.eclipse.core.runtime.IStatus;
19
20 /**
21  * @author Christian Perkonig
22  *
23  */
24 public class XDebugConnection {
25         private int fTransactionID = 0;
26         private Socket fDebugSocket;
27         private OutputStreamWriter fDebugWriter;
28         private DataInputStream fDebugReader;
29
30         protected boolean fInitialized = false;
31         protected boolean fIsClosed = true;
32         
33         protected String fSessionID = "";
34         
35         public String getSessionID() {
36                 return fSessionID;
37         }
38         
39         public boolean isInitialized() {
40                 return fInitialized;
41         }
42         
43         public boolean isClosed() {
44                 return fIsClosed;
45         }
46
47         public XDebugConnection(Socket debugSocket) {
48                 fDebugSocket = debugSocket;
49                 fTransactionID = 0;
50                 fInitialized = false;
51                 try {
52                         fDebugWriter = new OutputStreamWriter(debugSocket.getOutputStream(), "UTF8");
53                         fDebugReader = new DataInputStream(debugSocket.getInputStream()); 
54                 } catch (UnsupportedEncodingException e) {
55                         e.printStackTrace();
56                 } catch (IOException e) {
57                         e.printStackTrace();
58                 }
59
60                 fIsClosed = false;
61
62                 String initString = readData();
63                 XDebugCorePlugin.log(IStatus.INFO,initString);
64
65                 int startIdx = initString.indexOf("idekey=\"");
66                 if (startIdx == -1)
67                         return;
68                 startIdx += 8;
69                 int endIdx=initString.indexOf('"',startIdx);
70                 if (endIdx==-1)
71                         return;
72                 fSessionID = initString.substring(startIdx,endIdx);
73                 fInitialized = true;
74         }
75         
76         protected String readData()     {
77                 if (fIsClosed)
78                         return null;
79                 
80         byte byteBuffer[]=null,b;
81                 int count=0;
82                 
83                 try {
84                         while ((b =fDebugReader.readByte()) != 0) {
85                                 count = count * 10 + b - '0';
86                         }
87                         byteBuffer = new byte[count];
88                         int readCount=0;
89                         int attempts=0;
90                         while ((count >0) && (attempts <5)) {
91                                 int rc=fDebugReader.read(byteBuffer,readCount,count);
92                                 count-=rc;
93                                 readCount+=rc;
94                                 if (count>65530)
95                                         try {
96                                                 Thread.sleep(200);
97                                         } catch (InterruptedException e) {
98                                         }
99                                 else
100                                         attempts++;
101                         }
102                         
103                         fDebugReader.readFully(byteBuffer,readCount,count);
104                         
105                         if((b= fDebugReader.readByte())!=0) // reads the NULL Byte at the end;
106                                 System.out.println("NULL-Byte missing!!"); 
107                 } catch (IOException e) {
108                         if (e instanceof EOFException == false) {
109                                 if (!fIsClosed) {
110                                         e.printStackTrace();
111                                 }
112                         }
113                         return null;
114                 }
115                 return new String(byteBuffer);
116         }
117         
118         private /*XDebugResponse*/ int sendRequest(String command, String arguments) {
119                 int id = -1;
120                 
121                 id = _sendRequest(command, arguments);
122
123                 //XDebugResponse response = getResponse(id);
124
125                 return /*response*/ id;
126         }
127
128         private synchronized int _sendRequest(String command, String arguments) {
129                 XDebugCorePlugin.log(IStatus.INFO,command+" -i "+fTransactionID+" "+arguments);
130                 synchronized (fDebugSocket) {
131                         try {
132                                 fDebugWriter.write(command);
133                                 fDebugWriter.write(" -i " + fTransactionID);
134                                 if (!"".equals(arguments))
135                                         fDebugWriter.write(" " + arguments);
136                                 fDebugWriter.write(0);
137                                 fDebugWriter.flush();
138                         } catch (IOException e) {
139                                 e.printStackTrace();
140                 }
141                 }
142
143                 return fTransactionID++;
144         }
145
146         public /*XDebugResponse*/ int eval(String Expression) {
147                 String encoded = Base64.encodeBytes(Expression.getBytes());
148                 
149                 return sendRequest("eval", "-- "+encoded);
150         }
151
152         public /*XDebugResponse*/ int featureGet(String featureName) {
153                 return sendRequest("feature_get","-n "+featureName);
154         }
155
156         public /*boolean*/ int  featureSet(String featureName, String value) {
157                 //XDebugResponse id = sendRequest("feature_set","-n "+featureName + " -v " + value);
158
159                 int id = sendRequest("feature_set","-n "+featureName + " -v " + value);
160                 
161                 return id;
162                 /*XDebugResponse response = getResponse(id);
163
164                 if (response.getAttributeValue("success").equals("1") )
165                         return true;
166                 else
167                         return false;*/
168         }
169
170         /*protected XDebugResponse getResponse(int id) {
171                 return fResponseList.get(id);
172         }
173
174         protected void addResponse(XDebugResponse response, int id) {
175                 fResponseList.add(response, id);
176         }*/
177         
178         public /*XDebugResponse*/ int  breakpointSetOld(String file, int lineNumber) {
179                 String arg;
180                 
181                 arg = "-t line -f file://"+PHPDebugUtils.escapeString(file)+" -n " + lineNumber;
182                 return sendRequest("breakpoint_set", arg);              
183         }
184         
185         public /*XDebugResponse*/ int  breakpointSet(String file, int lineNumber, int hitCount) {
186                 String arg;
187                 
188                 arg = "-t line -f file://"+PHPDebugUtils.escapeString(file)+" -n " + lineNumber;
189                 if (hitCount > 0) {
190                         arg += " -h " + hitCount;       
191                 }
192                 return sendRequest("breakpoint_set", arg);              
193         }
194         
195         public int  breakpointGet(int id) {
196                 String arg;
197                 
198                 arg = "-d " + id;
199                 return sendRequest("breakpoint_get", arg);              
200         }
201         
202         public /*XDebugResponse*/ int  breakpointRemove(int id) {
203                 return sendRequest("breakpoint_set", "-d " + id);
204         }
205
206         public /*XDebugResponse*/ int  stackGet(/*int Level*/) {
207                 /*if (Level > -1) {
208                         return sendRequest("stack_get", "-d " + Level);
209                 } else {*/
210                         return sendRequest("stack_get", "");                    
211                 //}
212         }
213         
214         public void stepOver() {
215                 sendRequest("step_over", "");
216         }
217
218         public void stepInto() {
219                 sendRequest("step_into", "");
220         }
221
222         public void stepOut() {
223                 sendRequest("step_out", "");
224         }
225
226         public void run() {
227                 sendRequest("run", "");
228         }
229
230         public void stop() {
231                 sendRequest("stop", "");
232         }
233
234         public /*XDebugResponse*/ int  propertySet(String Name, String Value) {
235                 String str = Base64.encodeBytes(Value.getBytes());
236                 int len = str.length();
237
238                 return sendRequest("property_set", "-n " + Name + " -l " + len + " -- " + str);
239         }
240
241         public /*XDebugResponse*/ int  contextGet(int Level, int Type) {
242                 return sendRequest("context_get", "-d " + Level + " -c " + Type);
243         }
244
245         public /*boolean*/int setVarValue(String Name, String Value) {
246                 //XDebugResponse dr = propertySet(Name, Value);
247
248                 int id = propertySet(Name, Value);
249                 //XDebugResponse response = getResponse(id);
250                 return id;
251                 
252                 /*if ((response.getAttributeValue("success")).equals("1"))
253                         return true;
254                 
255                 return false;*/
256         }
257         
258         /*public void startListener() {
259                 fResponseListener.schedule();
260         }
261         
262         public boolean stopListener() {
263                 return fResponseListener.cancel();
264         }*/
265         
266         public void close() {
267                 if (!fIsClosed) {
268                         fIsClosed = true;
269                         //fResponseListener.cancel();
270                         //fResponseListener = null;
271                         try {
272                                 fDebugSocket.close();
273                                 fDebugReader.close();
274                                 fDebugReader = null;
275                                 fDebugWriter.close();
276                         } catch (IOException e) {
277                                 e.printStackTrace();
278                         }
279                 }
280                 //fResponseListener.cancel();
281                 //fIsClosed=true;
282         }       
283 }