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