Modified: 1764120 - Variables View doesn't show global vars in class context
[phpeclipse.git] / net.sourceforge.phpeclipse.debug.core / src / net / sourceforge / phpdt / internal / debug / core / PHPDBGInterface.java
1 /**********************************************************************
2 Copyright (c) 2000, 2002 IBM Corp. and others.
3 All rights reserved. This program and the accompanying materials
4 are made available under the terms of the Common Public License v1.0
5 which accompanies this distribution, and is available at
6 http://www.eclipse.org/legal/cpl-v10.html
7
8 Contributors:
9         Vicente Fernando - www.alfersoft.com.ar - Initial implementation
10         Christian Perkonig - remote debug
11 **********************************************************************/
12 package net.sourceforge.phpdt.internal.debug.core;
13
14 import java.io.BufferedReader;
15 import java.io.IOException;
16 import java.io.OutputStream;
17 import java.util.Arrays;
18 import java.util.Collections;
19 import java.util.Vector;
20
21 import net.sourceforge.phpdt.internal.debug.core.model.PHPDBGEvalString;
22 import net.sourceforge.phpdt.internal.debug.core.model.PHPStackFrame;
23 import net.sourceforge.phpdt.internal.debug.core.model.PHPValue;
24 import net.sourceforge.phpdt.internal.debug.core.model.PHPVariable;
25
26 import org.eclipse.core.runtime.IStatus;
27 import org.eclipse.core.runtime.Status;
28 import org.eclipse.debug.core.DebugException;
29
30 /**
31  * The interface object are created by the proxy
32  *
33  */
34 public class PHPDBGInterface {
35         public boolean                  sessionEnded = false;
36         public int                              sessType = -1;
37         public int                              BPUnderHit = 0;
38         public String                           sessID = new String();
39
40         private int[]                           LastBPRead = new int[10];
41         private Vector                  DBGBPList = new Vector();
42         private Vector                  DBGVarList = new Vector();
43         private PHPStackFrame[]         DBGStackList = new PHPStackFrame[0];
44         private Vector                  DBGMods = new Vector();                         // The module names and their numbers
45         private Vector                  stackListOld = new Vector();
46         private BufferedReader  in;
47         private OutputStream            os;                                                             // The stream which goes to DBG
48         private boolean                         shouldStop = false;
49         private String                  evalRet = new String("");
50         //private String                        serGlobals = new String("");
51         private int                             rawCounter = 1000;                                      // An rawData frame ID counter
52         private PHPDBGProxy             proxy = null;
53         private int                             lastCmd = -1;
54         private int                             sid = 0;
55         private boolean                         stopOnError = false;
56         private char[]                  lastCommand = new char[4];
57
58         private static final String GlobalVariablesTitle = PHPDebugCorePlugin
59                         .getResourceString("VariablesView.GlobalVariables.title");
60
61         /**
62          * @param in    The input stream (communication from DBG).
63          * @param os    The output stream (communication to DBG).
64          * @param proxy The proxy to which this interface belongs.
65          */
66         public PHPDBGInterface (BufferedReader in, OutputStream os, PHPDBGProxy proxy) {
67                 DBGBPList.clear ();
68
69                 this.in         = in;
70                 this.os         = os;
71                 this.proxy      = proxy;
72         }
73
74         /**
75          *
76          * @param mod_name  The module (source file) to which we add the breakpoint.
77          * @param line      The line where the breakpoint is set.
78          * @param hitCount  The number of hit counts before suspend.
79          * @param condition The break condition
80          * @return          Breakpoint ID ???.
81          */
82         public int addBreakpoint (String mod_name, int line, int hitCount, String condition) throws IOException {
83                 return setBreakpoint (mod_name, condition, line, PHPDBGBase.BPS_ENABLED + PHPDBGBase.BPS_UNRESOLVED, 0, hitCount, 0, 0, 0);
84         }
85
86         /**
87          *
88          * @param mod_name The module (source file) to which we add the breakpoint.
89          * @param line     The line where the breakpoint is set.
90          * @param bpNo     The breakpoint ID ???.
91          */
92         public void removeBreakpoint (String mod_name, int line, int bpNo) throws IOException {
93                 setBreakpoint (mod_name, "", line, PHPDBGBase.BPS_DISABLED, 0, 0, 0, bpNo, 0);
94         }
95
96         /**
97          * Is this method used anywhere?
98          *
99          */
100         public void requestDBGVersion () throws IOException {
101                 PHPDBGPacket DBGPacket;                                     // A DBG message packet
102                 PHPDBGFrame  DBGFrame;                                      // A frame within a DBG packet
103
104                 DBGPacket = new PHPDBGPacket (PHPDBGBase.DBGA_REQUEST);     // A request for DBG
105                 DBGFrame  = new PHPDBGFrame (PHPDBGBase.FRAME_VER);         // We want the version of DBG
106
107                 DBGPacket.addFrame (DBGFrame);                              // Add the 'what we want' to the DBG packet
108
109                 if (proxy.getSocket ().isClosed ()) {                                           // Can we communiate with DBG?
110                         return;                                                 //  No
111                 }
112
113                 DBGPacket.sendPacket (os);                                                                      // Send the request to DBG
114         }
115
116         /**
117          * Called by the proxy
118          *
119          */
120         public void getSourceTree () throws IOException {
121                 PHPDBGPacket DBGPacket;                                     // A DBG message packet
122                 PHPDBGFrame  DBGFrame;                                      // A frame within a DBG packet
123
124                 DBGPacket = new PHPDBGPacket (PHPDBGBase.DBGA_REQUEST);     // A request for DBG
125                 DBGFrame  = new PHPDBGFrame (PHPDBGBase.FRAME_SRC_TREE);        // We want a source tree from DBG
126
127                 DBGPacket.addFrame (DBGFrame);                              // Add the 'what we want' to the DBG packet
128
129                 if (proxy.getSocket ().isClosed ()) {                                           // Can we communiate with DBG?
130                         return;                                                                                                 //  No
131                 }
132
133                 DBGPacket.sendPacket (os);                                  // Send the request to DBG
134
135                 waitResponse (1000);                                        // Wait for the DBG response (1 second)
136                 flushAllPackets ();                                                                             // Read and process the response from DBG
137         }
138
139         /**
140          * Is this method called from anywhere?
141          *
142          * @param modName The modul (filename).
143          */
144         public void addDBGModName (String modName) throws IOException {
145                 PHPDBGPacket DBGPacket;                                     // A DBG message packet
146                 PHPDBGFrame  DBGFrame;                                      // A frame within a DBG packet
147
148                 DBGPacket = new PHPDBGPacket (PHPDBGBase.DBGA_REQUEST);     // A request for DBG
149                 DBGFrame  = new PHPDBGFrame (PHPDBGBase.FRAME_RAWDATA);     // We want Module name from DBG
150
151                 rawCounter++;                                               // Increment the rawData ID counter
152                 DBGFrame.addInt (rawCounter);                                                           // FRAME_RAWDATA ID
153                 DBGFrame.addInt (modName.length () + 1);                                        // The length of rawdata string (incl. null char termination)
154                 DBGFrame.addString (modName);                                                           // The file name (module name)
155                 DBGFrame.addChar ('\0');                                                                        // Add the C-String null termination
156
157                 DBGPacket.addFrame (DBGFrame);
158
159                 if (proxy.getSocket ().isClosed ()) {                                           // Can we communiate with DBG?
160                         return;                                                                                                 //  No
161                 }
162
163                 DBGPacket.sendPacket (os);
164         }
165
166         /**
167          * This method is called for adding or removing breakpoints.
168          *
169          * @param mod_name      The module name (file name).
170          * @param condition     Info about the condition when to break (not used at the moment).
171          * @param line          The breakpoints line.
172          * @param state         Info whether this breakpoint has to be dis- or enabled.
173          * @param istep         Always 0.
174          * @param hitcount      Always 0.
175          * @param skiphits      Always 0.
176          * @param bpno          The breakpoint ID.
177          * @param isunderhit    ???
178          * @return
179          */
180         private int setBreakpoint (String mod_name, String condition, int line, int state, int istemp, int hitcount, int skiphits, int bpno, int isunderhit) throws IOException {
181                 PHPDBGPacket    DBGPacket;
182                 PHPDBGFrame     DBGFrame1;
183                 PHPDBGFrame     DBGFrame2;
184                 PHPDBGFrame             DBGFrame3;
185                 int                     modNo;
186
187                 DBGPacket       = new PHPDBGPacket (PHPDBGBase.DBGA_REQUEST);
188                 DBGFrame1       = new PHPDBGFrame (PHPDBGBase.FRAME_BPS);
189                 DBGFrame2       = new PHPDBGFrame (PHPDBGBase.FRAME_RAWDATA);
190                 DBGFrame3       = new PHPDBGFrame (PHPDBGBase.FRAME_RAWDATA);
191
192                 modNo           = getModByName (mod_name);                                              // Get the module ID by name
193
194                 if (modNo >= 0) {                                           // Did we find a module ID for the module name?
195                         DBGFrame1.addInt (modNo);                                                               // Add the module ID to frame 1
196                 } else {
197                         DBGFrame1.addInt (0);                                                                   // mod number (0 use file name)
198                 }
199
200                 DBGFrame1.addInt (line);                                                                        // line number
201
202                 if (modNo >= 0) {                                           // Did we find a module ID for the module name?
203                         DBGFrame1.addInt (0);                                                                   // use mod number
204                 } else {
205                         rawCounter++;
206                         DBGFrame1.addInt (rawCounter);                                                  // ID of FRAME_RAWDATA to send file name
207                 }
208
209                 if (modNo < 0) {                                            // Did we find a module ID for the module name?
210                         DBGFrame2.addInt (rawCounter);                                      // FRAME_RAWDATA ID
211                         DBGFrame2.addInt (mod_name.length() + 1);                   // length of rawdata (+ null char)
212                         DBGFrame2.addString (mod_name);                                     // file name
213                         DBGFrame2.addChar ('\0');                                                   // null char
214
215                         DBGPacket.addFrame (DBGFrame2);                         // First add file name data
216                 }
217
218                 DBGFrame1.addInt (state);                                       // state BPS_*
219                 DBGFrame1.addInt (istemp);                                      // istemp
220                 DBGFrame1.addInt (0);                                               // hit count; this is not supported as one might think
221                 DBGFrame1.addInt (hitcount);                                // skip hits is what we think is hit count.
222
223                 if (!condition.equals ("")) {                                                           // Do we have a condition for breakpoint
224                         rawCounter++;                                                                                   // Set to new ID
225                         DBGFrame1.addInt (rawCounter);                          // ID of condition
226
227                         DBGFrame3.addInt (rawCounter);                                      // FRAME_RAWDATA ID
228                         DBGFrame3.addInt (condition.length() + 1);                  // length of rawdata (+ null char)
229                         DBGFrame3.addString (condition);                                        // The break condition
230                         DBGFrame3.addChar ('\0');                                                   // null char
231
232                         DBGPacket.addFrame (DBGFrame3);                         // First add break condition
233                 }
234                 else {
235                         DBGFrame1.addInt (0);                                           // ID of condition is 0, because there is no condition
236                 }
237
238                 DBGFrame1.addInt (bpno);                                            // breakpoint number
239                 DBGFrame1.addInt (isunderhit);                                  // is under hit
240
241                 DBGPacket.addFrame (DBGFrame1);                                                         // Second add command data
242
243                 if (proxy.getSocket ().isClosed ()) {                                           // Can we communiate with DBG?
244                         return 0;                                               //  No
245                 }
246
247                 DBGPacket.sendPacket (os);                                  // Send the request to DBG
248
249                 clearLastBP ();
250
251                 waitResponse (1000);                                        // Wait for the DBG response (1 second)
252                 flushAllPackets ();                                         // Read and process the response from DBG
253
254                 return LastBPRead[8];                                                                           // Return what ???
255         }
256
257         /**
258          *
259          */
260         private void clearLastBP () {
261                 int i;
262
263                 for (i = 0; i < LastBPRead.length; i++) {
264                         LastBPRead[i] = 0;
265                 }
266         }
267
268         /**
269          *
270          */
271         private void copyToLastBP (int[] BPBody) {
272                 int i;
273
274                 for (i = 0; i < LastBPRead.length; i++) {
275                         LastBPRead[i] = BPBody[i];
276                 }
277         }
278
279         /**
280          *
281          */
282         public void continueExecution () throws IOException {
283                 PHPDBGPacket DBGPacket;
284
285                 BPUnderHit = 0;
286                 DBGPacket  = new PHPDBGPacket (PHPDBGBase.DBGA_CONTINUE);
287
288                 if (proxy.getSocket ().isClosed ()) {                                           // Can we communiate with DBG?
289                         return;                                                 //  No
290                 }
291
292                 DBGPacket.sendPacket (os);                                  // Send the request to DBG
293
294                 lastCommand = PHPDBGBase.DBGA_CONTINUE;                     // Store the info about the command we sent
295         }
296
297         /**
298          *
299          */
300         public void pauseExecution () throws IOException {
301                 PHPDBGPacket DBGPacket;
302
303                 DBGPacket = new PHPDBGPacket (PHPDBGBase.IntToChar4 (PHPDBGBase.DBGC_PAUSE));
304
305                 if (proxy.getSocket ().isClosed ()) {                                           // Can we communiate with DBG?
306                          return;                                                //  No
307                 }
308
309                 DBGPacket.sendPacket (os);                                  // Send the request to DBG
310         }
311
312         /**
313          *
314          */
315         private int getBPUnderHit () {
316                 int i;
317                 int BPUnder             = 0;
318                 int[] dbg_bpl_body      = new int[10];
319
320                 for (i = 0; i < DBGBPList.size (); i++) {                               // look for bp under hit
321                         dbg_bpl_body = (int[]) DBGBPList.get (i);
322
323                         if (dbg_bpl_body[9] == 1) {
324                                 BPUnder = dbg_bpl_body[8];
325                         }
326                 }
327
328                 return BPUnder;
329         }
330
331         public int getLastCmd()
332         {
333                 return lastCmd;
334         }
335
336         public int getSID()
337         {
338           return sid;
339         }
340
341         public void setLastCmd (int cmd)
342         {
343                 lastCmd = cmd;
344         }
345
346         /**
347          *
348          */
349         public void stepInto () throws IOException {
350                 PHPDBGPacket DBGPacket;
351
352                 BPUnderHit = 0;
353                 DBGPacket  = new PHPDBGPacket (PHPDBGBase.DBGA_STEPINTO);
354
355                 if (proxy.getSocket ().isClosed ()) {                                           // Can we communiate with DBG?
356                         return;                                                 //  No
357                 }
358
359                 DBGPacket.sendPacket (os);                                  // Send the request to DBG
360
361                 lastCommand = PHPDBGBase.DBGA_STEPINTO;                                         // Store the info about the command we sent
362         }
363
364         /**
365          *
366          */
367         public void stepOver () throws IOException {
368                 PHPDBGPacket DBGPacket;
369
370                 BPUnderHit = 0;
371                 DBGPacket  = new PHPDBGPacket (PHPDBGBase.DBGA_STEPOVER);
372
373                 if (proxy.getSocket ().isClosed ()) {                                           // Can we communiate with DBG?
374                         return;                                                 //  No
375                 }
376
377                 DBGPacket.sendPacket (os);                                  // Send the request to DBG
378
379                 lastCommand = PHPDBGBase.DBGA_STEPOVER;                     // Store the info about the command we sent
380         }
381
382         /**
383          *
384          */
385         public void stepOut () throws IOException {
386                 PHPDBGPacket DBGPacket;
387
388                 BPUnderHit = 0;
389                 DBGPacket  = new PHPDBGPacket (PHPDBGBase.DBGA_STEPOUT);
390
391                 if (proxy.getSocket ().isClosed ()) {                                           // Can we communiate with DBG?
392                         return;                                                 //  No
393                 }
394
395                 DBGPacket.sendPacket (os);                                  // Send the request to DBG
396
397                 lastCommand = PHPDBGBase.DBGA_STEPOUT;                      // Store the info about the command we sent
398         }
399
400         /**
401          *
402          */
403         public void stopExecution () throws IOException {
404                 PHPDBGPacket DBGPacket;
405
406                 BPUnderHit = 0;
407                 DBGPacket  = new PHPDBGPacket (PHPDBGBase.DBGA_STOP);
408
409                 if (proxy.getSocket ().isClosed ()) {                                           // Can we communiate with DBG?
410                         return;                                                 //  No
411                 }
412
413                 DBGPacket.sendPacket (os);                                  // Send the request to DBG
414         }
415
416         /**
417          * This method is called by the proxy.
418          * It sends a request to DBG to get the current variables
419          * with their values. It waits for the response and processes
420          * the input from DBG.
421          *
422          * @param stack The stackframe for which we want the variables.
423          * @return      The array of variables
424          */
425         public synchronized Vector getVariables(PHPStackFrame stack) throws IOException, DebugException {
426                 PHPDBGPacket            DBGPacket;
427                 PHPDBGFrame             DBGFrame1;
428                 PHPDBGEvalString        evalStr;
429
430                 Vector globalList = new Vector();
431                 // IStackFrame[] stacks = stack.getThread().getStackFrames();
432                 // ( PHPStackFrame.getThread().getStackFrames() returns DBGStackList )
433                 if (DBGStackList.length > 1) {
434                         // get global variables (and assign them to 'main()' stackframe)
435                         globalList = getVariables(DBGStackList[DBGStackList.length - 1], PHPDBGBase.GLOBAL_SCOPE_ID);
436                         if (!globalList.isEmpty()) {
437                                 // remove unexpected '$this=?' variable
438                                 PHPVariable var = (PHPVariable) globalList.get(0);
439                                 PHPValue val = (PHPValue) var.getValue();
440                                 Vector workList = val.getChildVariables();
441                                 for (int i = 0; i < workList.size(); i++) {
442                                         if (((PHPVariable) workList.get(i)).getName().equals("$this")) {
443                                                 workList.remove(i);
444                                                 break;
445                                         }
446                                 }
447                                 var.setName(GlobalVariablesTitle);
448                                 var.setModifiable(false);
449                         }
450                 }
451
452 //              DBGPacket = new PHPDBGPacket (PHPDBGBase.DBGA_REQUEST);     //
453 //          DBGFrame1 = new PHPDBGFrame (PHPDBGBase.FRAME_EVAL);        //
454 //
455 //              DBGFrame1.addInt (0);                                                                           // istr = raw data ID
456 //              DBGFrame1.addInt (1);                                                                           // scope_id = -1 means current location, 0 never used, +1 first depth
457 //
458 //              DBGPacket.addFrame (DBGFrame1);                             // Add command data
459 //
460 //              if (proxy.getSocket ().isClosed ()) {                       // Do we have a socket for DBG communication?
461 //                      return new Vector ();                                                                   // No, then leave here with an empty vector 
462 //              }
463 //
464 //              serGlobals = "";
465 //              DBGPacket.sendPacket (os);                                  // Send the request to DBG
466 //
467 //              waitResponse (1000);                                        // Wait for the DBG response (1 second)
468 //              flushAllPackets ();                                         // Read and process the response from DBG
469 //
470 //              evalStr         = new PHPDBGEvalString (stack, serGlobals); // Process serialized variables
471 //              DBGVarList      = evalStr.getVariables ();
472
473                 int scopeID = stack.getScopeID(); 
474                 if (scopeID == PHPDBGBase.CURLOC_SCOPE_ID) {
475                         // current stackframe
476                         DBGVarList = getVariables(stack, PHPDBGBase.CURLOC_SCOPE_ID);
477                 } else if ((scopeID == PHPDBGBase.CURLOC_SCOPE_ID + 1) && !globalList.isEmpty()) {
478                         // 'main()' stackframe
479                         PHPVariable var = (PHPVariable) globalList.get(0);
480                         PHPValue val = (PHPValue) var.getValue();
481                         DBGVarList = val.getChildVariables();
482                         return DBGVarList;
483                 } else {
484                         // back-trace stackframe
485                         // Never: DBGVarList = getVariables(stack, scopeID);
486                         // DBG 2.15.5 causes Application Error (on win32) in some cases
487                         DBGVarList.clear();
488                 }
489
490                 if (DBGVarList.size() > 0) {                                                            // Did we get back variables?
491                         PHPVariable var = (PHPVariable) DBGVarList.get(0);              // Yes, then get the first PHPVariable
492                         PHPValue    val = (PHPValue) var.getValue();                    // Get the value
493
494                         if (var.getName().equals("")) {                                                 // Is the root node an empty node (usually it is)
495                                 DBGVarList = val.getChildVariables();                           // Then remove the empty node.
496                                                                                                                                         // With removing the empty root node, it wouldn't be necessary to
497                                                                                                                                         // set the name to an empty string. So the code below is just for
498                                                                                                                                         // info or in case the users want to have the empty root node.
499
500                                                                                                                                         // The eclipse variable view cannot handle Variables which have an empty name
501                                                                                                                                         // when it comes to variable tree restore operation. Without a name, no restore!
502                                 //var.setName (" ");                                                            // Give a name to the variable root node. Even if it is only a space :-)
503                         }                                                                                                               // TODO the best would be to remove the empty root node, but this would
504                                                                                                                                         // require a understanding and reworking of the PHPDBGEvalstring class.
505                 }
506
507                 if (!globalList.isEmpty()) {
508                         DBGVarList.add(globalList.get(0));
509                 }
510
511                 return DBGVarList;                                                                                      // Return the variables as list
512         }
513
514         /**
515          * 
516          * @throws IOException 
517          */
518         private Vector getVariables(PHPStackFrame stack, int scope_id) throws IOException {
519                 PHPDBGPacket DBGPacket = new PHPDBGPacket(PHPDBGBase.DBGA_REQUEST);
520                 PHPDBGFrame DBGFrame1 = new PHPDBGFrame(PHPDBGBase.FRAME_EVAL);
521
522                 DBGFrame1.addInt(0);
523                 DBGFrame1.addInt(scope_id);
524
525                 DBGPacket.addFrame(DBGFrame1);
526                 evalRet = "";
527
528                 if (proxy.getSocket().isClosed()) {
529                         return new Vector();
530                 }
531                 DBGPacket.sendPacket(os);
532                 waitResponse(1000);
533                 flushAllPackets();
534
535                 PHPDBGEvalString evalStr = new PHPDBGEvalString(stack, evalRet);
536                 return evalStr.getVariables();
537         }
538
539         /**
540          *
541          * @param logString
542          */
543         public void log(String logString) throws IOException, DebugException  {
544                 PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_REQUEST);
545                 PHPDBGFrame DBGFrame1= new PHPDBGFrame(PHPDBGBase.FRAME_LOG);
546                 PHPDBGFrame DBGFrame2= new PHPDBGFrame(PHPDBGBase.FRAME_RAWDATA);
547
548                 rawCounter++;
549                 DBGFrame1.addInt(rawCounter);                           // ilog
550                 DBGFrame1.addInt(1);                                            // type
551                 DBGFrame1.addInt(0);                                            // mod_no
552                 DBGFrame1.addInt(0);                                            // line_no
553                 DBGFrame1.addInt(0);                                            // imod_name
554                 DBGFrame1.addInt(0);                                            // ext_info
555
556                 DBGFrame2.addInt(rawCounter);                           // FRAME_RAWDATA ID
557                 DBGFrame2.addInt(logString.length() + 1);       // length of rawdata (+ null char)
558                 DBGFrame2.addString(logString);                         // log string
559                 DBGFrame2.addChar('\0');                                        // null char
560
561                 // Add raw data first
562                 DBGPacket.addFrame(DBGFrame2);
563                 // Add command data
564                 DBGPacket.addFrame(DBGFrame1);
565
566                 if (proxy.getSocket ().isClosed ()) {                   // Do we have a socket for DBG communication?
567                         return;                                                                                         //  No, then leave here
568                 }
569
570                 DBGPacket.sendPacket(os);
571
572                 waitResponse(1000);
573                 flushAllPackets();
574         }
575
576         public synchronized PHPVariable[] evalBlock(PHPStackFrame stack, String evalString) throws IOException, DebugException {
577                 PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_REQUEST);
578                 PHPDBGFrame DBGFrame1= new PHPDBGFrame(PHPDBGBase.FRAME_EVAL);
579                 PHPDBGFrame DBGFrame2= new PHPDBGFrame(PHPDBGBase.FRAME_RAWDATA);
580
581                 rawCounter++;
582                 DBGFrame1.addInt(rawCounter);                           // istr = raw data ID
583                 //DBGFrame1.addInt(1);                                          // scope_id = -1 means current location, 0 never used, +1 first depth
584                 DBGFrame1.addInt(stack.getScopeID());
585
586                 DBGFrame2.addInt(rawCounter);                           // FRAME_RAWDATA ID
587                 DBGFrame2.addInt(evalString.length() + 1);      // length of rawdata (+ null char)
588                 DBGFrame2.addString(evalString);                        // eval block
589                 DBGFrame2.addChar('\0');                                        // null char
590
591                 // Add raw data first
592                 DBGPacket.addFrame(DBGFrame2);
593                 // Add command data
594                 DBGPacket.addFrame(DBGFrame1);
595
596                 if (proxy.getSocket().isClosed()) {                     // Do we have a socket for DBG communication?
597                         return null;                                                    //  No, then leave here
598                 }
599                 DBGPacket.sendPacket(os);
600
601                 waitResponse(1000);
602                 flushAllPackets();
603
604                 PHPDBGEvalString evalStr=new PHPDBGEvalString(stack,evalRet);
605
606                 return evalStr.getVars();
607         }
608
609         /**
610          * Read and process everthing we got from DBG
611          */
612         public void flushAllPackets () throws IOException {
613                 while (readResponse() != 0);
614         }
615
616         /**
617          * Get the modules name by its number
618          *
619          * @param modNo The number (id) of the module
620          * @return      The name of the module
621          */
622         public String getModByNo (int modNo) {
623                 int             i;
624                 PHPDBGMod       dbg_mod;
625
626                 for (i = 0; i < DBGMods.size (); i++) {                         // For all the modules we have within the array
627                         dbg_mod = (PHPDBGMod) DBGMods.get (i);                      // Get the module
628
629                         if (dbg_mod.getNo () == modNo) {                            // Is the module from the array the module we want?
630                                 return dbg_mod.getName ();                              //  Yes, return the name of the module
631                         }
632                 }
633
634                 return "";                                                      // If nothing was found return emtpy string
635         }
636
637         /**
638          *
639          * @param  modName The name of the module for which we want the ID
640          * @return
641          * - The ID of the module
642          * - -1 if nothing was found
643          */
644         private int getModByName (String modName) {
645                 int             i;
646                 PHPDBGMod       dbg_mod;
647
648                 for (i = 0; i < DBGMods.size (); i++) {                         // For all the modules we have within the array
649                         dbg_mod = (PHPDBGMod) DBGMods.get (i);                      // Get the module
650
651                         if (dbg_mod.getName ().equalsIgnoreCase (modName)) {            // Is the module from the array the module we want?
652                                 return dbg_mod.getNo ();                                //  Yes, return the name of the module
653                         }
654                 }
655
656                 return -1;                                                      // If nothing was found return -1
657         }
658
659         /**
660          * Return the string for the given frame number
661          *
662          * @param framesInfo The buffer which is to read
663          * @param frameNo    The frame number
664          * @return
665          */
666         private String getRawFrameData (char[] framesInfo, int frameNo) {
667                 int   nextFrame = 0;                                                    // The current read position within the buffer
668                 int[] dbg_frame = new int[2];                                           // The two frame header numbers
669
670                 while (nextFrame < framesInfo.length) {                                 // As long we have something within the buffer
671                         dbg_frame[0] = PHPDBGBase.Char4ToInt (framesInfo, nextFrame);           // The frame type
672                         dbg_frame[1] = PHPDBGBase.Char4ToInt (framesInfo, nextFrame + 4);       // The frame size
673
674                         nextFrame   += 8;                                                   // The current read position
675
676                         if (dbg_frame[1] == 0) {                                            // If frame size is 0
677                                 return "";                                                      //  return an emtpy string
678                         }
679
680                         switch (dbg_frame[0]) {                                                     // Switch for the frame type
681                                 case PHPDBGBase.FRAME_RAWDATA:                                                  // The only frame type we are interrested in
682                                         if (frameNo == PHPDBGBase.Char4ToInt (framesInfo, nextFrame)) {         // Is it correct  number of the frame
683                                                 int toRead;                                                     //
684
685                                                 toRead = PHPDBGBase.Char4ToInt (framesInfo, nextFrame + 4);     // The size of the string
686
687                                                 if ((int) framesInfo[nextFrame + 8 + toRead - 1] == 0) {                                // Is there a string termination at the end?
688                                                         return String.copyValueOf (framesInfo, nextFrame + 8, toRead - 1);      // Then copy frame content to String without the \0 and return
689                                                 }
690
691                                                 return String.copyValueOf (framesInfo, nextFrame + 8, toRead);  // Copy frame content to String and return
692                                         }
693                                         break;
694                         }
695
696                         nextFrame += dbg_frame[1];                                                                      // Go for the next frame (add the length of the current one)
697                 }
698
699                 return "";                                                                                                                                              // We did not found any FRAM_RAWDATA, so return an emtpy strin
700         }
701
702         /**
703          * Reset the availability flag for all stackframes in the list.
704          *
705          * @param list          The list of old stackframes
706          */
707         private void resetAvailability (Vector list) {
708                 int             i;
709
710                 for (i = 0; i < list.size (); i++) {
711                         ((PHPStackFrame) list.get(i)).setAvailable (false);                                     //
712                 }
713         }
714
715         /**
716          * Check whether the new stackframe is in the list of old stackframes.
717          * Test for identical stackframe (identical means same description and same line number).
718          *
719          * @param stackFrameNew The stackframe to check whether he is already within the old stackframe list
720          * @param list          The list of old stackframes
721          * @return
722          *  - true if we have found the identical stackframe within the list
723          *  - false if we did not find the identical stackframe within the list
724          */
725         private boolean isStackFrameInList (PHPStackFrame stackFrameNew, Vector list) {
726                 int             i;
727                 PHPStackFrame   stackFrameOld;
728
729                 for (i = 0; i < list.size (); i++) {
730                         stackFrameOld = (PHPStackFrame) list.get (i);                                           //
731
732                         if (stackFrameNew.getDescription ().equals (stackFrameOld.getDescription ()) &&
733                                 stackFrameNew.getLineNumber () == stackFrameOld.getLineNumber ()) {     // Did we find the sent stackframe within the list of old stackframes?
734                                 stackFrameOld.setAvailable (true);                                      // We found the new stackframe in the list of old stack frames
735                 stackFrameOld.setIndex (stackFrameNew.getIndex ());
736                 stackFrameOld.setScopeID(stackFrameNew.getScopeID());
737                                 return true;                                                            // The stackframe was found in the list
738                         }
739                 }
740
741                 return false;
742         }
743
744         /**
745          * Check whether the new stackframe is in the list of old stackframes.
746          * Test for exact stackframe (exact means same description and same line number).
747          *
748          * @param stackFrameNew The stackframe to check whether he is already within the old stackframe list
749          * @param list          The list of old stackframes
750          * @return
751          *  - true if we have exactly this stackframe within the list
752          *  - false if we did not find the exact stackframe within the list
753          */
754         private void markIdenticalStackFrames (Vector oldList, Vector newList) {
755                 int             i;
756                 PHPStackFrame   stackFrameNew;
757
758                 resetAvailability (oldList);                                                    // Reset the availability flag of the old stack frames
759                 resetAvailability (newList);                                                    // Reset the availability flag of the old stack frames
760
761                 for (i = 0; i < newList.size (); i++) {                                                                                 // For all stackList entries
762                         stackFrameNew = (PHPStackFrame) newList.get (i);
763
764                         if (isStackFrameInList (stackFrameNew, oldList)) {                          // Is this stackframe in the list
765                                 stackFrameNew.setAvailable (true);                                                                              //
766                                                                                                                                                                                 //
767                                 break;
768                         }
769                 }
770         }
771
772         /**
773          *
774          * The stackList contains the currently read stackframes which were sent
775          * from DBG. The DBG interface holds a list of the active stack frames.
776          * This method replicates the 'static' stackframe list with the DBG stackframe list
777          * Replication is done in the following way:
778          * <ul>
779          * <li> It looks for new stackframes within the DBG stackframe list and
780          *      adds them to the 'static' list.
781          * <li> It looks for stackframes within the 'static' list, and removes them
782          *              from the 'static' list in case they do not appear within the DBG list.
783          * <li> It looks for stackframes which are already existent and replicates the
784          *              line number and the index number.
785          * <li> At the end, the 'static' stackframe list has to be sorted by the stackframes
786          *              index numbers.
787          * </ul>
788          *
789          * Removes the unused stackframes from the list, or adds stackframes which
790          * are not yet in the list.
791          *
792          *
793          * @param stackList
794          */
795         private void updateStackFrameList (Vector stackList) {
796                 int                     i;
797                 int             n;
798                 PHPStackFrame   stackFrameNew;
799                 PHPStackFrame   stackFrameOld;
800                 PHPStackFrame[] newStackList;
801
802                 markIdenticalStackFrames (stackListOld, stackList);                     // Check whether the newly send stack frames can be found in the list
803                                                                                                                                                                 // of old stack frames
804
805                 for (i = 0; i < stackList.size (); i++) {                                                               // For all stackList entries
806                         stackFrameNew = (PHPStackFrame) stackList.get(i);
807
808                         for (n = 0; n < stackListOld.size (); n++) {                                    // For all StackFrames in the StackFrame list
809                                 stackFrameOld = (PHPStackFrame) stackListOld.get (n);                   //
810
811                                 if (stackFrameOld.isAvailable ()) {                             // If this stack frame was already found in the new list skip it
812                                         continue;
813                                 }
814
815                                 if (stackFrameNew.getDescription ().equals (stackFrameOld.getDescription ())) {// Did we find the sent stackframe within the list of old stackframes?
816                                         stackFrameOld.setLineNumber (stackFrameNew.getLineNumber ());
817                                         stackFrameOld.setIndex (stackFrameNew.getIndex ());
818                                         stackFrameOld.setScopeID(stackFrameNew.getScopeID());
819
820                                         stackFrameOld.setAvailable (true);                                                      // And mark this stack frame as available
821                                         stackFrameNew.setAvailable (true);                                                      // And mark this stack frame as available
822
823                                         break;                                                                  //  Yes, then break;
824                                 }
825                         }
826
827                         if (!stackFrameNew.isAvailable ()) {                                // Did not find the new stackframe within the list?
828                                  stackFrameNew.setAvailable (true);                                                             // Mark the stack frame as available and
829                                  stackListOld.add (stackFrameNew);                              //  then add the new stackframe
830                         }
831                 }
832
833                 // And now for removing unused stackframes from list
834
835                 for (n = 0; n < stackListOld.size (); n++) {                                            // For all StackFrames in the StackFrame list
836                         stackFrameOld = (PHPStackFrame) stackListOld.get (n);                           //
837
838                         i = 0;
839                         if (!stackFrameOld.isAvailable ()) {
840                                 i = stackList.size ();
841                         }
842
843                         if (i == stackList.size ()) {                                           // Did not find the old stackframe within the list of new ones
844                                  stackListOld.remove (n);                                       //  then remove the old stackframe from list
845                                  n -= 1;                                                        // Adjust the stack list index
846                         }
847                 }
848
849                 Collections.sort (stackListOld);                                                                                // Sort the 'static' stackframe list by the stackframe index numbers.
850                                                                                                                                                                 //
851                 newStackList = new PHPStackFrame[stackListOld.size ()];
852                 newStackList = (PHPStackFrame[]) stackListOld.toArray (newStackList);
853                 DBGStackList = newStackList;
854         }
855
856     /**
857      * Read the response from DBG and process the frame
858      *
859          * @return
860          * - The received command
861          * - or 0 if something was wrong
862      */
863         public int readResponse () throws IOException {
864         int     bytesToRead            = 0;                         // The number of byte to read for the current DBG block
865         int     nextFrame              = 0;                         // The current read position within entirePack
866         int     i                      = 0;
867         int     cmdReceived            = 0;
868         int     stackIndex             = 0;
869         boolean errorStack             = false;
870         char[]  dbg_header_struct_read = new char[16];              // The buffer for the first 16 bytes of a block
871         int[]   dbg_header_struct      = new int[4];                // The first four numbers (long) of a block
872         int[]   dbg_bpl_tmp            = new int[10];
873         int[]   dbg_frame              = new int[2];
874         int[]   dbg_eval_tmp           = new int[3];
875         int[]   dbg_src_tree_tmp       = new int[4];                //
876         int[]   dbg_error_tmp          = new int[2];
877         Vector  rawList                = new Vector();
878         Vector  stackList              = new Vector();              // Intermediate stacklist which is build up in FRAME_STACK frame
879
880         rawList.clear ();
881         stackList.clear ();
882
883                 // Read from input
884         while (readInput (dbg_header_struct_read, 16) != 0) {                               // Read 16 byte from input stream
885                         dbg_header_struct[0] = PHPDBGBase.Char4ToInt (dbg_header_struct_read, 0);               // Debug sync header
886             dbg_header_struct[1] = PHPDBGBase.Char4ToInt (dbg_header_struct_read, 4);           // Command
887             dbg_header_struct[2] = PHPDBGBase.Char4ToInt (dbg_header_struct_read, 8);       //
888             dbg_header_struct[3] = PHPDBGBase.Char4ToInt (dbg_header_struct_read, 12);      // Bytes within this block
889
890             if (dbg_header_struct[0] != 0x5953) {                                           // Check DBG sync bytes
891                 return 0;                                                                   // Wrong header
892             }
893
894             cmdReceived = dbg_header_struct[1];                                             // Get the command
895             setLastCmd (cmdReceived);                                                                                                           // Store the info about the current command
896             bytesToRead = dbg_header_struct[3];                                                                                         // Get the number of bytes to read for this block
897
898                         //System.out.println("Response Received: " + cmdReceived);
899                         char[] entirePack = new char[bytesToRead];                                      // Store the block data into buffer 'entirePack'
900
901             if (bytesToRead > 0) {                                                          // If there is something within the frame
902                 if (readInput (entirePack, bytesToRead) < bytesToRead) {                    // Read the frame into the buffer
903                     return 0;                                                               // We did not read enough bytes, error
904                 }
905                         }
906                         
907                         nextFrame = 0;                                                                  // Start with the first frame
908
909                         while (nextFrame < bytesToRead) {                                               // As long as we have something within this block
910                                 dbg_frame[0] = PHPDBGBase.Char4ToInt (entirePack, nextFrame);                           // The name of the frame
911                                 dbg_frame[1] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 4);               // The size of the frame
912                                 nextFrame   += 8;                                                           // The next read position
913
914                                 if (dbg_frame[1] == 0) {                                                    // Something within the frame?
915                                         return 0;                                                               //  Nothing to read, error
916                                 }
917
918                                 switch (dbg_frame[0]) {
919                                         case PHPDBGBase.FRAME_STACK:
920                                                 int[] dbg_stack_new = new int[4];                                       //
921
922                                                 dbg_stack_new[0] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 0);   // Source line number
923                                                 dbg_stack_new[1] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 4);   // Module number
924                                                 dbg_stack_new[2] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 8);   // Scope id
925                                                 dbg_stack_new[3] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 12);  // ID of description string
926
927                                                 if ((dbg_stack_new[1] != 0) && !errorStack) {
928                                                         PHPStackFrame newStack;
929
930                                                         stackIndex++;
931                                                         newStack = new PHPStackFrame (null,                                 // The thread
932                                                                                       getModByNo (dbg_stack_new[1]),        // The name of the module (file)
933                                                                                       dbg_stack_new[0],                     // The source line number
934                                                                                                                   stackIndex,
935                                                                                                                   getRawFrameData (entirePack,          // Get the string from this packet
936                                                                                                                                    dbg_stack_new[3]),   // The frame ID for which we want the string
937                                                                                                                   dbg_stack_new[1],                                     // The module number
938                                                                                                                   dbg_stack_new[2]);
939                                                         stackList.add (newStack);
940                                                 }
941
942                                                 errorStack = false;
943                                                 break;
944
945                                         case PHPDBGBase.FRAME_SOURCE:                                                   // Nothing to be done here
946                                                 break;                                                                      // TODO: what's with that frame? Something interesting
947
948                                         case PHPDBGBase.FRAME_SRC_TREE:                                                 //
949                                                 dbg_src_tree_tmp[0] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 0);        // The parent module number
950                                                 dbg_src_tree_tmp[1] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 4);        // The parent line number (not used)
951                                                 dbg_src_tree_tmp[2] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 8);        // The module number
952                                                 dbg_src_tree_tmp[3] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 12);       // The filename number
953
954                                                 if (getModByNo (dbg_src_tree_tmp[2]).equals ("")) {
955                                                         String fileName;
956
957                                                         fileName = new String (getRawFrameData (entirePack, dbg_src_tree_tmp[3]));      // Get the filename
958
959                                                         if (dbg_src_tree_tmp[2] != 0) {                                             // If there is a module number
960                                                                 PHPDBGMod modNew;
961
962                                                                 modNew = new PHPDBGMod (dbg_src_tree_tmp[2], fileName);                 // Create a module object
963
964                                                                 DBGMods.add (modNew);                                                   // And store it to array
965                                                         }
966                                                 }
967                                                 break;
968
969                                         case PHPDBGBase.FRAME_RAWDATA:                                                      // Nothing to be done here
970                                                 break;                                                                          //  FRAME_RAWDATA are processed within getRawFrameData
971
972                                         case PHPDBGBase.FRAME_ERROR:                                                                                                            // An error frame
973                                                 errorStack       = true;                                                                                                                // Yes, we have an error stack
974                                                 dbg_error_tmp[0] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 0);                   // Error type
975                                                 dbg_error_tmp[1] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 4);                   // Error message ID
976
977                                                 String error = "\n";                                                            //
978
979                                                 switch (dbg_error_tmp[0]) {                                                                                                             // Switch on error type
980                                                         case PHPDBGBase.E_ERROR:                        error += "[Error]";                     break;
981                                                         case PHPDBGBase.E_WARNING:                      error += "[Warning]";                   break;
982                                                         case PHPDBGBase.E_PARSE:                        error += "[Parse Error]";               break;
983                                                         case PHPDBGBase.E_NOTICE:                       error += "[Notice]";                    break;
984                                                         case PHPDBGBase.E_CORE_ERROR:           error += "[Core Error]";                break;
985                                                         case PHPDBGBase.E_CORE_WARNING:         error += "[Core Warning]";              break;
986                                                         case PHPDBGBase.E_COMPILE_ERROR:        error += "[Compile Error]";             break;
987                                                         case PHPDBGBase.E_COMPILE_WARNING:      error += "[Compile Warning]";   break;
988                                                         case PHPDBGBase.E_USER_ERROR:           error += "[User Error]";                break;
989                                                         case PHPDBGBase.E_USER_WARNING:         error += "[User Warning]";              break;
990                                                         case PHPDBGBase.E_USER_NOTICE:          error += "[User Notice]";               break;
991                                                         default:                                                        error += "[Unexpected Error]";  break;
992                                                 }
993
994                                                 error += ": ";
995                                                 error += new String (getRawFrameData (entirePack, dbg_error_tmp[1]));                   // Add the error string for this error message ID
996                                                 error += "\n";                                                                  // Append a CR
997
998                                                 PHPDebugCorePlugin.log (new DebugException (new Status (IStatus.WARNING,
999                                                                                                         PHPDebugCorePlugin.PLUGIN_ID,
1000                                                                                                                                                                 IStatus.OK,
1001                                                                                                                                                                 error, null)));
1002
1003                                                 // To print errors on the console, I must execute a code in the
1004                                                 // php context, that write the stderr... I didn't found a better way
1005                                                 // TODO: Find a better way????
1006
1007 //                                              String codeExec= "";
1008 //                                              codeExec= "fwrite(fopen('php://stderr', 'w'),\\\"" + error + "\\\");";
1009 //                                              try {
1010 //                                                      evalBlock("eval(\"" + codeExec + "\");");
1011 //                                              } catch (DebugException e) {
1012 //                                                      PHPDebugCorePlugin.log(e);
1013 //                                              }
1014 //
1015                                                 if (!stopOnError) {                                                             // Is always false (Did not see where this is set to true!?)
1016                                                         if (lastCommand.equals (PHPDBGBase.DBGA_CONTINUE)) {                        // If last command for PHP was a 'continue',
1017                                                                 continueExecution ();                                                   //  send continue again
1018                                                         } else if (lastCommand.equals (PHPDBGBase.DBGA_STEPINTO)) {                 // If last command for PHP was a 'step into',
1019                                                                 stepInto ();                                                            //  send 'step into' again
1020                                                         } else if (lastCommand.equals (PHPDBGBase.DBGA_STEPOUT)) {                  // If last command for PHP was a 'step out',
1021                                                                 stepOut ();                                                             //  send 'step out' again
1022                                                         } else if (lastCommand.equals (PHPDBGBase.DBGA_STEPOVER)) {                 // If last command for PHP was a 'step over',
1023                                                                 stepOver ();                                                            //  send 'step over' again
1024                                                         }
1025                                                 }
1026                                                 break;
1027
1028                                         case PHPDBGBase.FRAME_EVAL:
1029                                                 String evalString;
1030
1031                                                 evalString      = new String ("");
1032                                                 dbg_eval_tmp[0] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 0);                    // istr
1033                                                 dbg_eval_tmp[1] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 4);                    // iresult
1034                                                 dbg_eval_tmp[2] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 8);                    // ierror
1035
1036                                                 evalRet                 = getRawFrameData (entirePack, dbg_eval_tmp[1]);                //
1037                                                 evalString              = getRawFrameData (entirePack, dbg_eval_tmp[0]);                //
1038                                                 //serGlobals            = evalRet;                                                      //
1039                                                 break;
1040
1041                                         case PHPDBGBase.FRAME_BPS:                                                          //
1042                                                 break;                                                                          //
1043
1044                                         case PHPDBGBase.FRAME_BPL:
1045                                                 int[] dbg_bpl_new;
1046
1047                                                 dbg_bpl_new        = new int[10];
1048                                                 dbg_bpl_new[0] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 0);
1049                                                 dbg_bpl_new[1] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 4);
1050                                                 dbg_bpl_new[2] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 8);
1051                                                 dbg_bpl_new[3] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 12);
1052                                                 dbg_bpl_new[4] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 16);
1053                                                 dbg_bpl_new[5] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 20);
1054                                                 dbg_bpl_new[6] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 24);
1055                                                 dbg_bpl_new[7] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 28);
1056                                                 dbg_bpl_new[8] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 32);
1057                                                 dbg_bpl_new[9] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 36);
1058
1059                                                 // look if breakpoint already exists in vector
1060                                                 for (i = 0; i < DBGBPList.size (); i++) {
1061                                                         dbg_bpl_tmp = (int[]) DBGBPList.get (i);
1062
1063                                                         if (dbg_bpl_tmp[8] == dbg_bpl_new[8]) {
1064                                                                 DBGBPList.remove (i);
1065
1066                                                                 break;
1067                                                         }
1068                                                 }
1069
1070                                                 // add breakpoint to vector
1071                                                 DBGBPList.add (dbg_bpl_new);
1072                                                 copyToLastBP (dbg_bpl_new);
1073
1074                                                 // mod no returned?
1075                                                 if (getModByNo (dbg_bpl_new[0]).equals ("")) {
1076                                                         String fileName;
1077
1078                                                         fileName = new String (getRawFrameData (entirePack, dbg_bpl_new[2]));
1079
1080                                                         if (dbg_bpl_new[0] != 0) {
1081                                                                 PHPDBGMod modNew;
1082
1083                                                                 modNew = new PHPDBGMod (dbg_bpl_new[0], fileName);
1084
1085                                                                 DBGMods.add (modNew);
1086                                                         }
1087                                                 }
1088                                                 break;
1089
1090                                         case PHPDBGBase.FRAME_VER:
1091                                                 break;
1092
1093                                         case PHPDBGBase.FRAME_SID:
1094                                                 sid = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 0);
1095                                                 break;
1096
1097                                         case PHPDBGBase.FRAME_SRCLINESINFO:
1098                                                 break;
1099
1100                                         case PHPDBGBase.FRAME_SRCCTXINFO:
1101                                                 break;
1102
1103                                         case PHPDBGBase.FRAME_LOG:
1104                                                 break;
1105
1106                                         case PHPDBGBase.FRAME_PROF:
1107                                                 break;
1108
1109                                         case PHPDBGBase.FRAME_PROF_C:
1110                                                 break;
1111
1112                                         case PHPDBGBase.FRAME_SET_OPT:
1113                                                 break;
1114                                 }
1115
1116                                 nextFrame += dbg_frame[1];                                                      // go to next frame
1117                         }
1118
1119                         // Now process command
1120                         switch(cmdReceived) {
1121                                 case PHPDBGBase.DBGC_REPLY:
1122                                         break;
1123
1124                                 case PHPDBGBase.DBGC_STARTUP:
1125                                         break;
1126
1127                                 case PHPDBGBase.DBGC_END:
1128                                         sessionEnded = true;
1129                                         this.proxy.setTerminated();
1130                                         break;
1131
1132                                 case PHPDBGBase.DBGC_BREAKPOINT:
1133                                         BPUnderHit   = getBPUnderHit ();
1134                                         updateStackFrameList (stackList);
1135                                         break;
1136
1137                                 case PHPDBGBase.DBGC_STEPINTO_DONE:
1138                                 case PHPDBGBase.DBGC_STEPOVER_DONE:
1139                                 case PHPDBGBase.DBGC_STEPOUT_DONE:
1140                                 case PHPDBGBase.DBGC_EMBEDDED_BREAK:
1141                                 case PHPDBGBase.DBGC_PAUSE:
1142                                         BPUnderHit   = 1;
1143                                         updateStackFrameList (stackList);
1144                                         break;
1145
1146                                 case PHPDBGBase.DBGC_ERROR:
1147                                         stackList.clear ();
1148                                         updateStackFrameList (stackList);
1149                                         break;
1150
1151                                 case PHPDBGBase.DBGC_LOG:
1152                                         break;
1153
1154                                 case PHPDBGBase.DBGC_SID:
1155                                         break;
1156                         }
1157                 }
1158
1159                 return cmdReceived;                                         // Return the command we received with this block
1160         }
1161
1162     /**
1163      *
1164      */
1165
1166         public PHPStackFrame[] getStackList() {
1167                 return DBGStackList;
1168         }
1169
1170         /**
1171          * Reads from input buffer (response sent from DBG) the given number of chars
1172          * into frame buffer.
1173          *
1174          * @param buffer  The frame buffer where to store the read data from DBG.
1175          * @param bytes   The number of bytes (chars) which are to read from input stream.
1176          * @return        The number of bytes actually read.
1177          */
1178         private int readInput (char[] buffer, int bytes) throws IOException {
1179                 int bytesRead = 0;                                                                                      // Reset the bytes read counter
1180
1181                 for (int i = 0; i < bytes; i++) {                           // For the number of bytes we should read
1182                         if (in.ready ()) {                                                                              // If input stream is ready for reading
1183                                 buffer[i] = (char) (in.read () & 0x00FF);           // Read a char and store only the least significant 8-bits
1184                                 bytesRead++;                                        // Increment the bytes read counter
1185                         }
1186                         else {                                                  // Input stream is not ready
1187                                 break;                                              // Break the loop
1188                         }
1189                 }
1190
1191                 return bytesRead;                                                                                       // Return the number of bytes actually read
1192         }
1193
1194         /**
1195          * PHPProxy could stop the waiting for a response with this method.
1196          *
1197          */
1198         public void setShouldStop () {
1199                 this.shouldStop = true;
1200         }
1201
1202         /**
1203          * @param milliseconds The maximum time in milliseconds we wait for something
1204          *                     to be send from DBG.
1205          * @return             - true if something was received from DBG
1206          *                                         - false if nothing was send from DBG within the given time
1207          *
1208          */
1209         public boolean waitResponse (long milliseconds) throws IOException {
1210                 long timeout;
1211
1212                 timeout = System.currentTimeMillis () + milliseconds;           // Calculate the system time till we wait.
1213
1214                 while (System.currentTimeMillis () < timeout) {             // Is waiting time running out?
1215                         if (in.ready () || shouldStop) {                        //  No, so did we get something or should we stop now
1216                                 break;                                              //   Yes, break the waiting
1217                         }
1218                 }
1219
1220                 return in.ready ();                                         // true if we got something from DBG
1221         }
1222 }