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