refactory whole plugin
[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.net.Socket;
11
12 import net.sourceforge.phpeclipse.xdebug.core.Base64;
13 import net.sourceforge.phpeclipse.xdebug.core.PHPDebugUtils;
14 import net.sourceforge.phpeclipse.xdebug.core.XDebugCorePlugin;
15 import net.sourceforge.phpeclipse.xdebug.core.xdebug.ResponseListener.DebugResponse;
16 import org.eclipse.core.runtime.IStatus;
17
18 /**
19  * @author Christian Perkonig
20  *
21  */
22 public class XDebugConnection {
23         int fTransactionID = 0;
24         private Socket fDebugSocket;
25         private OutputStreamWriter fDebugWriter;
26         private DataInputStream fDebugReader;
27         private ResponseList fResponseList;
28         private ResponseListener fResponseListener;
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, DataInputStream reader, OutputStreamWriter writer) {
48                 fResponseList = new ResponseList();
49                 fDebugWriter = writer;
50                 fDebugReader = reader;
51                 fDebugSocket = debugSocket;
52                 fTransactionID = 0;
53                 fInitialized = false;
54                 String initString = readData();
55                 XDebugCorePlugin.log(IStatus.INFO,initString);
56
57                 int startIdx = initString.indexOf("idekey=\"");
58                 if (startIdx == -1)
59                         return;
60                 startIdx += 8;
61                 int endIdx=initString.indexOf('"',startIdx);
62                 if (endIdx==-1)
63                         return;
64                 fSessionID = initString.substring(startIdx,endIdx);
65                 
66                 fInitialized = true;
67                 fIsClosed = false;
68                 fResponseListener = new ResponseListener(this);
69         }
70         
71         protected String readData()     {
72         byte byteBuffer[]=null,b;
73                 int count=0;
74                 
75                 try {
76                         while ((b =fDebugReader.readByte()) != 0) {
77                                 count = count * 10 + b - '0';
78 //                              count=count*10+Integer.parseInt(b);
79                         }
80                         byteBuffer = new byte[count];
81                         int readCount=0;
82                         int attempts=0;
83                         while ((count >0) && (attempts <5)) {
84                                 int rc=fDebugReader.read(byteBuffer,readCount,count);
85                                 count-=rc;
86                                 readCount+=rc;
87                                 if (count>65530)
88                                         try {
89                                                 Thread.sleep(200);
90                                         } catch (InterruptedException e) {
91                                         }
92                                 else
93                                         attempts++;
94                         }
95                         if((b= fDebugReader.readByte())!=0) // reads the NULL Byte at the end;
96                                 System.out.println("NULL-Byte missing!!"); 
97                 } catch (IOException e) {
98                         // TODO Auto-generated catch block
99                         if (e instanceof EOFException==false)
100                                 e.printStackTrace();
101                         return null;
102                 }
103                 return new String(byteBuffer);
104         }
105         
106         public DebugResponse sendRequest(String command, String arguments) {
107                 int id = -1;
108                 
109                 id = _sendRequest(command, arguments);
110
111                 DebugResponse response = getResponse(id);
112
113                 return response;
114         }
115
116         private synchronized int _sendRequest(String command, String arguments) {
117                 XDebugCorePlugin.log(IStatus.INFO,command+" -i "+fTransactionID+" "+arguments);
118                 synchronized (fDebugSocket) {
119                         try {
120                                 fDebugWriter.write(command);
121                                 fDebugWriter.write(" -i " + fTransactionID);
122                                 if (!"".equals(arguments))
123                                         fDebugWriter.write(" " + arguments);
124                                 fDebugWriter.write(0);
125                                 fDebugWriter.flush();
126                         } catch (IOException e) {
127                                 e.printStackTrace();
128                 }
129                 }
130
131                 return fTransactionID++;
132         }
133
134         public DebugResponse eval(String Expression) {
135                 String encoded = Base64.encodeBytes(Expression.getBytes());
136                 
137                 return sendRequest("eval", "-- "+encoded);
138         }
139
140         public DebugResponse featureGet(String featureName) {
141                 return sendRequest("feature_get","-n "+featureName);
142         }
143
144         public boolean featureSet(String featureName, String value) {
145                 DebugResponse id = sendRequest("feature_set","-n "+featureName + " -v " + value);
146
147                 if (id.getAttributeValue("success").equals("1") )
148                         return true;
149                 else
150                         return false;
151         }
152
153         protected DebugResponse getResponse(int id) {
154                 return fResponseList.get(id);
155         }
156
157         protected void addResponse(DebugResponse response, int id) {
158                 fResponseList.add(response, id);
159         }
160         
161         
162         public DebugResponse breakpointSet(String file, int lineNumber) {
163                 String arg;
164                 
165                 arg = "-t line -f file://"+PHPDebugUtils.escapeString(file)+" -n " + lineNumber;
166                 return sendRequest("breakpoint_set", arg);              
167         }
168         
169         public DebugResponse breakpointRemove(int id) {
170                 return sendRequest("breakpoint_set", "-d " + id);
171         }
172
173         public DebugResponse stackGet(int Level) {
174                 /*if (Level > -1) {
175                         return sendRequest("stack_get", "-d " + Level);
176                 } else {*/
177                         return sendRequest("stack_get", "");                    
178                 //}
179         }
180         
181         public void stepOver() {
182                 sendRequest("step_over", "");
183         }
184
185         public void stepInto() {
186                 sendRequest("step_into", "");
187         }
188
189         public void stepOut() {
190                 sendRequest("step_out", "");
191         }
192
193         public void run() {
194                 sendRequest("run", "");
195         }
196
197         public void stop() {
198                 sendRequest("stop", "");
199         }
200
201         public void startListener() {
202                 fResponseListener.schedule();
203         }
204         
205         public DebugResponse propertySet(String Name, String Value) {
206                 String str = Base64.encodeBytes(Value.getBytes());
207                 int len = str.length();
208
209                 return sendRequest("property_set", "-n " + Name + " -l " + len + " -- " + str);
210         }
211
212         public boolean setVarValue(String Name, String Value) {
213                 DebugResponse dr = propertySet(Name, Value);
214
215                 if ((dr.getAttributeValue("success")).equals("1"))
216                         return true;
217                 
218                 return false;
219         }
220         
221         public void close() {
222                 fIsClosed = true;
223                 //fResponseListener.cancel();
224                 //fResponseListener = null;
225                 try {
226                         fDebugReader.close();           
227                         fDebugWriter.close();
228                         fDebugSocket.close();
229                 } catch (IOException e) {
230                         e.printStackTrace();
231                 }
232                 fResponseListener.cancel();
233                 fIsClosed=true;
234         }
235         
236         public DebugResponse contextGet(int Level, int Type) {
237                 return sendRequest("context_get", "-d " + Level + " -c " + Type);
238         }
239 }