Fixed problem opening other sources
[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 **********************************************************************/
11 package net.sourceforge.phpdt.internal.debug.core;
12
13 import java.io.IOException;
14 import java.io.BufferedReader;
15 import java.io.OutputStream;
16 import java.util.Vector;
17 import java.lang.System;
18 import org.eclipse.debug.core.DebugException;
19 import net.sourceforge.phpdt.internal.debug.core.model.PHPStackFrame;
20 import net.sourceforge.phpdt.internal.debug.core.model.PHPVariable;
21 import net.sourceforge.phpdt.internal.debug.core.model.PHPValue;
22 import net.sourceforge.phpdt.internal.debug.core.PHPDBGMod;
23
24 public class PHPDBGInterface {
25
26         // Public
27         public boolean sessionEnded= false;
28         public int sessType= -1;        
29         public int BPUnderHit= 0;
30         public String sessID= new String();
31         
32         // Private
33         private int[] LastBPRead= new int[10];
34         private Vector DBGBPList= new Vector();
35         private PHPStackFrame[] DBGStackList;
36         private PHPVariable[] DBGVariableList;
37         private Vector DBGMods= new Vector();
38         private Vector DBGVars= new Vector();
39         private BufferedReader in;
40         private OutputStream os;
41         private boolean shouldStop= false, isRef= false, hasChildren= false, isObject= false;
42         private String evalRet= new String("");
43         private String serGlobals= new String("");
44         private String typeRead= new String("");
45         private String className= new String("");
46         private int finalPos=0, refCounter=0, rawCounter=1000;
47         private PHPDBGProxy proxy= null;
48          
49         public PHPDBGInterface(BufferedReader in, OutputStream os, PHPDBGProxy proxy) {
50                 DBGBPList.clear();
51                 this.in= in;
52                 this.os= os;
53                 this.proxy= proxy;
54         }
55
56         public int addBreakpoint(String mod_name, int line) throws IOException {
57                 return setBreakpoint(mod_name, "", line, PHPDBGBase.BPS_ENABLED + PHPDBGBase.BPS_UNRESOLVED, 0, 0, 0, 0, 0);
58         }
59
60         public void removeBreakpoint(String mod_name, int line, int bpNo) throws IOException {
61                 setBreakpoint(mod_name, "", line, PHPDBGBase.BPS_DISABLED, 0, 0, 0, bpNo, 0);
62         }
63
64         public void requestDBGVersion() throws IOException {
65                 PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_REQUEST);
66                 PHPDBGFrame DBGFrame= new PHPDBGFrame(PHPDBGBase.FRAME_VER);
67                 
68                 DBGPacket.addFrame(DBGFrame);
69
70                 if(proxy.getSocket().isClosed()) return;
71                 DBGPacket.sendPacket(os);
72         }
73
74         public void getSourceTree() throws IOException {
75                 PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_REQUEST);
76                 PHPDBGFrame DBGFrame= new PHPDBGFrame(PHPDBGBase.FRAME_SRC_TREE);
77                 
78                 DBGPacket.addFrame(DBGFrame);
79                 
80                 if(proxy.getSocket().isClosed()) return;
81                 DBGPacket.sendPacket(os);
82
83                 // Wait response (1 second) and read response
84                 waitResponse(1000);
85                 flushAllPackets();
86         }
87
88         public void addDBGModName(String modName) throws IOException {
89                 PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_REQUEST);
90                 PHPDBGFrame DBGFrame= new PHPDBGFrame(PHPDBGBase.FRAME_RAWDATA);
91                 
92                 rawCounter++;
93                 DBGFrame.addInt(rawCounter);                            // FRAME_RAWDATA ID
94                 DBGFrame.addInt(modName.length() + 1);          // length of rawdata (+ null char)
95                 DBGFrame.addString(modName);                            // file name
96                 DBGFrame.addChar('\0');                                         // null char
97
98                 DBGPacket.addFrame(DBGFrame);
99                 
100                 if(proxy.getSocket().isClosed()) return;
101                 DBGPacket.sendPacket(os);
102         }
103
104         // Returns DBG Breakpoint ID
105         private int setBreakpoint(String mod_name, String condition, int line, int state, int istemp, int hitcount, int skiphits, int bpno, int isunderhit) throws IOException {
106                 int modNo= 0;
107
108                 PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_REQUEST);
109                 PHPDBGFrame DBGFrame1= new PHPDBGFrame(PHPDBGBase.FRAME_BPS);
110                 PHPDBGFrame DBGFrame2= new PHPDBGFrame(PHPDBGBase.FRAME_RAWDATA);
111
112                 modNo= getModByName(mod_name);
113                 
114                 if(modNo >= 0) {
115                         DBGFrame1.addInt(modNo);        // mod number
116                 } else {
117                         DBGFrame1.addInt(0);            // mod number (0 use file name)
118                 }
119                 
120                 DBGFrame1.addInt(line);                 // line number
121                 
122                 if(modNo >= 0) {
123                         DBGFrame1.addInt(0);                    // use mod number
124                 } else {
125                         rawCounter++;
126                         DBGFrame1.addInt(rawCounter);   // ID of FRAME_RAWDATA to send file name
127                 }
128
129                 DBGFrame1.addInt(state);                // state BPS_*
130                 DBGFrame1.addInt(istemp);               // istemp
131                 DBGFrame1.addInt(hitcount);             // hit count
132                 DBGFrame1.addInt(skiphits);             // skip hits
133                 DBGFrame1.addInt(0);                    // ID of condition
134                 DBGFrame1.addInt(bpno);                 // breakpoint number
135                 DBGFrame1.addInt(isunderhit);   // is under hit
136                 
137                 if(modNo < 0) {
138                         DBGFrame2.addInt(rawCounter);                           // FRAME_RAWDATA ID
139                         DBGFrame2.addInt(mod_name.length() + 1);        // length of rawdata (+ null char)
140                         DBGFrame2.addString(mod_name);                          // file name
141                         DBGFrame2.addChar('\0');                                        // null char
142                         // First add file name data
143                         DBGPacket.addFrame(DBGFrame2);
144                 }
145
146                 // Second add command data
147                 DBGPacket.addFrame(DBGFrame1);
148
149                 if(proxy.getSocket().isClosed()) return 0;
150                 DBGPacket.sendPacket(os);
151
152                 clearLastBP();
153
154                 // Wait response (1 second) and read response
155                 waitResponse(1000);
156                 flushAllPackets();
157
158                 return LastBPRead[8];
159         }
160
161         private void clearLastBP() {
162                 int i;
163
164                 for(i=0; i < LastBPRead.length; i++)
165                         LastBPRead[i]= 0;
166         }
167
168         private void copyToLastBP(int[] BPBody) {
169                 int i;
170
171                 for(i=0; i < LastBPRead.length; i++)
172                         LastBPRead[i]= BPBody[i];
173         }
174
175         public void continueExecution() throws IOException {
176                 BPUnderHit= 0;
177                 PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_CONTINUE);
178                 if(proxy.getSocket().isClosed()) return;
179                 DBGPacket.sendPacket(os);
180         }
181
182         private int getBPUnderHit() {
183                 int i, BPUnder=0;
184                 int[] dbg_bpl_body= new int[10];
185
186                 // look for bp under hit
187                 for(i=0; i < DBGBPList.size(); i++) {
188                         dbg_bpl_body= (int[]) DBGBPList.get(i);
189                         if(dbg_bpl_body[9] == 1) {
190                                 BPUnder= dbg_bpl_body[8];
191                         }
192                 }
193                 return BPUnder;
194         }
195
196         public void stepInto() throws IOException {
197                 BPUnderHit= 0;
198                 PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_STEPINTO);
199                 if(proxy.getSocket().isClosed()) return;
200                 DBGPacket.sendPacket(os);
201         }
202
203         public void stepOver() throws IOException {
204                 BPUnderHit= 0;
205                 PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_STEPOVER);
206                 if(proxy.getSocket().isClosed()) return;
207                 DBGPacket.sendPacket(os);
208         }
209
210         public void stepOut() throws IOException {
211                 BPUnderHit= 0;
212                 PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_STEPOUT);
213                 if(proxy.getSocket().isClosed()) return;
214                 DBGPacket.sendPacket(os);
215         }
216
217         public void stopExecution() throws IOException {
218                 BPUnderHit= 0;
219                 PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_STOP);
220                 if(proxy.getSocket().isClosed()) return;
221                 DBGPacket.sendPacket(os);
222         }
223
224         public PHPVariable[] getVariables(PHPStackFrame stack) throws IOException, DebugException  {
225                 PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_REQUEST);
226                 PHPDBGFrame DBGFrame1= new PHPDBGFrame(PHPDBGBase.FRAME_EVAL);
227                 //PHPDBGFrame DBGFrame2= new PHPDBGFrame(PHPDBGBase.FRAME_RAWDATA);
228         
229                 DBGFrame1.addInt(0);                                            // istr = raw data ID
230                 DBGFrame1.addInt(1);                                            // scope_id = -1 means current location, 0 never used, +1 first depth
231
232                 /*              
233                 String evalBlock= new String("$GLOBALS");
234                 DBGFrame2.addInt(1);                                            // FRAME_RAWDATA ID
235                 DBGFrame2.addInt(evalBlock.length() + 1);       // length of rawdata (+ null char)
236                 DBGFrame2.addString(evalBlock);                         // eval block
237                 DBGFrame2.addChar('\0');                                        // null char
238                 */
239                 
240                 // Add command data
241                 DBGPacket.addFrame(DBGFrame1);
242                 
243                 if(proxy.getSocket().isClosed()) return null;
244                 DBGPacket.sendPacket(os);
245
246                 waitResponse(1000);
247                 flushAllPackets();
248                 
249                 // Process serialized variables
250                 DBGVariableList= procVars(stack);
251
252                 return DBGVariableList;
253         }
254
255         public void evalBlock(String evalString) throws IOException, DebugException  {
256                 PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_REQUEST);
257                 PHPDBGFrame DBGFrame1= new PHPDBGFrame(PHPDBGBase.FRAME_EVAL);
258                 PHPDBGFrame DBGFrame2= new PHPDBGFrame(PHPDBGBase.FRAME_RAWDATA);
259
260                 rawCounter++;
261                 DBGFrame1.addInt(rawCounter);                           // istr = raw data ID
262                 DBGFrame1.addInt(1);                                            // scope_id = -1 means current location, 0 never used, +1 first depth
263
264                 DBGFrame2.addInt(rawCounter);                           // FRAME_RAWDATA ID
265                 DBGFrame2.addInt(evalString.length() + 1);      // length of rawdata (+ null char)
266                 DBGFrame2.addString(evalString);                        // eval block
267                 DBGFrame2.addChar('\0');                                        // null char
268
269                 // Add raw data first
270                 DBGPacket.addFrame(DBGFrame2);          
271                 // Add command data
272                 DBGPacket.addFrame(DBGFrame1);
273                 
274                 if(proxy.getSocket().isClosed()) return;
275                 DBGPacket.sendPacket(os);
276
277                 waitResponse(1000);
278                 flushAllPackets();
279         }
280
281         public void flushAllPackets() throws IOException {
282                 while(readResponse() != 0);
283         }
284
285         public String getModByNo(int modNo) {
286                 int i;
287                 PHPDBGMod dbg_mod;
288
289                 // look for mod
290                 for(i=0; i < DBGMods.size(); i++) {
291                         dbg_mod= (PHPDBGMod) DBGMods.get(i);
292                         if(dbg_mod.getNo() == modNo) {
293                                 return dbg_mod.getName(); 
294                         }
295                 }
296                 return "";
297         }
298
299         private int getModByName(String modName) {
300                 int i;
301                 PHPDBGMod dbg_mod;
302
303                 // look for mod
304                 for(i=0; i < DBGMods.size(); i++) {
305                         dbg_mod= (PHPDBGMod) DBGMods.get(i);
306                         if(dbg_mod.getName().equalsIgnoreCase(modName)) {
307                                 return dbg_mod.getNo(); 
308                         }
309                 }
310                 return -1;
311         }
312
313         private String getRawFrameData(char[] framesInfo, int frameNo) {
314                 int nextFrame= 0;
315                 int[] dbg_frame= new int[2];
316                 
317                 while(nextFrame < framesInfo.length) {
318                         dbg_frame[0] = PHPDBGBase.Char4ToInt(framesInfo, nextFrame);            // frame name
319                         dbg_frame[1] = PHPDBGBase.Char4ToInt(framesInfo, nextFrame + 4);        // frame size
320
321                         nextFrame += 8;
322                         if(dbg_frame[1] == 0) return "";
323
324                         switch(dbg_frame[0]) {
325                                 case PHPDBGBase.FRAME_RAWDATA:
326                                         if(frameNo == PHPDBGBase.Char4ToInt(framesInfo, nextFrame)) {
327                                                 int toRead= PHPDBGBase.Char4ToInt(framesInfo, nextFrame + 4);
328                                                 return String.copyValueOf(framesInfo, nextFrame + 8, toRead);
329                                         }
330                                         break;
331                         }
332                         // go to next frame
333                         nextFrame += dbg_frame[1];
334                 }
335                 return "";
336         }
337
338         public PHPVariable[] getInstVars(PHPVariable phpVar) throws DebugException {
339                 Vector vecVars= new Vector();
340                 PHPVariable localPHPVar;
341                 int i=0;
342                 
343                 // already unserialized
344                 for(i=0; i < DBGVars.size(); i++) {
345                         localPHPVar= (PHPVariable)DBGVars.get(i);
346                         if(localPHPVar.getParent() == phpVar) {
347                                 vecVars.add(localPHPVar);
348                         }
349                 }
350                 PHPVariable[] arrVars= new PHPVariable[vecVars.size()];
351                 arrVars= (PHPVariable[]) vecVars.toArray(arrVars);
352
353                 return arrVars;
354         }
355         
356         private PHPVariable[] procVars(PHPStackFrame stack) throws DebugException {
357                 Vector vecVars= new Vector();
358                 
359                 // unserialize
360                 finalPos= 0;
361                 refCounter= 0;
362                 doUnserialize(stack, vecVars, null);
363
364                 DBGVars= vecVars;
365                 
366                 return(getInstVars(null));
367         }
368
369         private String readValue(String serialVars) throws DebugException {
370                 int startPos=0, endPos=0, lenStr=0, i=0, elements=0;
371                 String ret= new String("");
372
373                 switch(serialVars.charAt(0)) {
374                         case 'a':       // associative array, a:elements:{[index][value]...}
375                                 typeRead= "hash";
376                                 startPos= 1;
377                                 endPos= serialVars.indexOf(':', startPos + 1);
378                                 if(endPos == -1) return "";
379                                 finalPos += endPos + 2;
380                                 ret= new String(serialVars.substring(startPos + 1, endPos));
381                                 
382                                 hasChildren= true;
383                                 break;
384                         case 'O':       // object, O:name_len:"name":elements:{[attribute][value]...}
385                                 typeRead= "object";
386                                 
387                                 startPos= 1;
388                                 endPos= serialVars.indexOf(':', startPos + 1);
389                                 if(endPos == -1) return "";
390                                 
391                                 // get object class
392                                 lenStr= Integer.parseInt(serialVars.substring(startPos + 1, endPos));
393                                 startPos= endPos + 2;
394                                 endPos= lenStr + startPos;
395                                 className= new String(serialVars.substring(startPos, endPos).toString());
396
397                                 // get num of elements
398                                 startPos= endPos + 1;
399                                 endPos= serialVars.indexOf(':', startPos + 1);
400                                 if(endPos == -1) return "";
401                                 finalPos += endPos + 2;
402                                 ret= new String(serialVars.substring(startPos + 1, endPos));
403
404                                 isObject= true;
405                                 hasChildren= true;                              
406                                 break;
407                         case 's':       // string, s:length:"data";
408                                 typeRead= "string";
409                                 startPos= 1;
410                                 endPos= serialVars.indexOf(':', startPos + 1);
411                                 if(endPos == -1) return "";
412
413                                 lenStr= Integer.parseInt(serialVars.substring(startPos + 1, endPos));
414                                 startPos= endPos + 2;
415                                 endPos= lenStr + startPos;
416                                 ret= new String(serialVars.substring(startPos, endPos).toString());
417                                 finalPos += endPos + 2; 
418                                 break;
419                         case 'i':       // integer, i:123;
420                                 typeRead= "integer";
421                                 startPos= 1;
422                                 endPos= serialVars.indexOf(';', startPos + 1);
423                                 if(endPos == -1) return "";
424
425                                 ret= new String(serialVars.substring(startPos + 1, endPos).toString());
426                                 finalPos += endPos + 1;
427                                 break;
428                         case 'd':       // double (float), d:1.23;
429                                 typeRead= "double";
430                                 startPos= 1;
431                                 endPos= serialVars.indexOf(';', startPos + 1);
432                                 if(endPos == -1) return "";
433         
434                                 ret= new String(serialVars.substring(startPos + 1, endPos).toString());
435                                 finalPos += endPos + 1;
436                                 break;
437                         case 'N':       // NULL, N;
438                                 typeRead= "null";
439                                 ret= "nil";
440                                 finalPos += 2;
441                                 break;
442                         case 'b':       // bool, b:0 or 1
443                                 typeRead= "boolean";
444                                 ret= (serialVars.charAt(2) == '1')?"true":"false";
445                                 finalPos += endPos + 4;
446                                 break;
447                         case 'z':       // resource, z:typename_len:"typename":valres;
448                                 typeRead= "resource";
449                                 
450                                 startPos= 1;
451                                 endPos= serialVars.indexOf(':', startPos + 1);
452                                 if(endPos == -1) return "";
453                 
454                                 // get resource type name
455                                 lenStr= Integer.parseInt(serialVars.substring(startPos + 1, endPos));
456                                 startPos= endPos + 2;
457                                 endPos= lenStr + startPos;
458                                 className= new String(serialVars.substring(startPos, endPos).toString());
459
460                                 // get resource value
461                                 startPos= endPos + 1;
462                                 endPos= serialVars.indexOf(';', startPos + 1);
463                                 if(endPos == -1) return "";
464                                 ret= new String(serialVars.substring(startPos + 1, endPos));
465                                 finalPos += endPos + 1;
466                                 break;
467                         case 'r':
468                         case 'R':
469                                 typeRead= "reference";
470                                 startPos= 1;
471                                 endPos= serialVars.indexOf(';', startPos + 1);
472                                 if(endPos == -1) return "0";
473
474                                 ret= new String(serialVars.substring(startPos + 1, endPos));
475                                 finalPos += endPos + 1;
476                                 isRef= true;
477                                 break;
478                         case ';':
479                                 typeRead= "unknown";
480                                 finalPos+= 1;
481                                 break;
482                         case '?':
483                                 finalPos+= 1;
484                         default:
485                                 finalPos+= 1;
486                                 typeRead= "unknown";
487                                 break;
488                 }
489                 return ret;
490         }
491
492         private void doUnserialize(PHPStackFrame stack, Vector vecVars, PHPVariable parent) throws DebugException {
493                 int i, elements= 0;
494                 PHPVariable newVar= null;
495                 String value= new String("");
496                 String name= new String("");
497                 String tmp= new String("");
498                 String[] tmpSplit;
499
500                 if(finalPos > serGlobals.length() || serGlobals.equals("") || serGlobals.substring(finalPos).equals("")) return;
501
502                 isRef= false;
503                 hasChildren= false;
504                 isObject= false;
505                 name= readValue(serGlobals.substring(finalPos));
506                 
507                 if(hasChildren) {
508                         // main array
509                         if(refCounter == 0) {
510                                 value= name;
511                                 name= "";
512                         }
513                 } else {
514                         hasChildren= false;
515                         isRef= false;
516                         value= readValue(serGlobals.substring(finalPos));
517                         // replaceAll doesn't work, why???
518                         tmpSplit= value.split("\\\\");
519                         value= "";
520                         for(i= 0; i < tmpSplit.length; i++) {
521                                 value= value + tmpSplit[i];
522                                 if(!tmpSplit[i].equals("")) {
523                                         if(i < (tmpSplit.length - 1)) {
524                                                 value= value + "\\";
525                                         }
526                                 }
527                         }
528                 }
529                 
530                 if(!name.equals("")) {
531                         if(isRef) {
532                                 PHPVariable varPHP;
533                                 for(i=0; i < vecVars.size(); i++) {
534                                         varPHP= (PHPVariable) vecVars.get(i);
535                                         if(varPHP.getObjectId().equals(value)) {
536                                                 newVar= new PHPVariable(stack, name, "local", true, (PHPValue)varPHP.getValue());
537                                                 break;                                          
538                                         }
539                                 }
540                                 if(newVar == null) {
541                                         newVar= new PHPVariable(stack, name, "local", false, null);
542                                 }
543                         } else {
544                                 refCounter++;
545                                 newVar= new PHPVariable(stack, name, "local", value, typeRead, hasChildren, Integer.toString(refCounter), className);
546                         }
547                         newVar.setParent(parent);
548                         vecVars.add(newVar);
549                 }
550                 if(hasChildren) {
551                         elements= Integer.parseInt(value);
552                         for(i=0; i < elements; i++)
553                                 doUnserialize(stack, vecVars, newVar);
554
555                         // skip "}"
556                         finalPos += 1;
557                 }
558         }
559
560         public int readResponse() throws IOException {
561                 int bytesToRead=0, nextFrame=0, i=0, cmdReceived=0, stackIndex=0;
562                 char[] dbg_header_struct_read= new char[16];
563                 int[] dbg_header_struct= new int[4];
564                 int[] dbg_bpl_tmp= new int[10];
565                 int[] dbg_frame= new int[2];
566                 int[] dbg_eval_tmp= new int[3];
567                 int[] dbg_src_tree_tmp= new int[4];
568                 Vector rawList= new Vector();
569                 Vector stackList= new Vector();
570                 PHPStackFrame[] newStackList;
571                 
572                 rawList.clear();
573                 stackList.clear();
574                 // Read from input
575                 while(readInput(dbg_header_struct_read, 16) != 0) {
576                         dbg_header_struct[0] = PHPDBGBase.Char4ToInt(dbg_header_struct_read, 0);
577                         dbg_header_struct[1] = PHPDBGBase.Char4ToInt(dbg_header_struct_read, 4);
578                         dbg_header_struct[2] = PHPDBGBase.Char4ToInt(dbg_header_struct_read, 8);
579                         dbg_header_struct[3] = PHPDBGBase.Char4ToInt(dbg_header_struct_read, 12);
580                         
581                         // Check DBG sync bytes
582                         if(dbg_header_struct[0] != 0x5953) return 0;
583                         
584                         cmdReceived= dbg_header_struct[1];
585                         bytesToRead= dbg_header_struct[3];
586
587                         //System.out.println("Response Received: " + cmdReceived);
588                         char[] entirePack= new char[bytesToRead];
589
590                         if(bytesToRead > 0) {
591                                 if(readInput(entirePack, bytesToRead) < bytesToRead) return 0;
592                         }
593                         
594                         // First process frames
595                         nextFrame= 0;
596                         while(nextFrame < bytesToRead) {
597                                 dbg_frame[0] = PHPDBGBase.Char4ToInt(entirePack, nextFrame);            // frame name
598                                 dbg_frame[1] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 4);        // frame size
599                                 nextFrame += 8;
600                                 if(dbg_frame[1] == 0) return 0;
601                                 switch(dbg_frame[0]) {
602                                         case PHPDBGBase.FRAME_STACK:
603                                                 int[] dbg_stack_new= new int[4];
604                                                 dbg_stack_new[0] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 0);    // line no
605                                                 dbg_stack_new[1] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 4);    // mod no
606                                                 dbg_stack_new[2] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 8);    // scope id
607                                                 dbg_stack_new[3] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 12);   // id of description string
608
609                                                 stackIndex++;
610                                                 if(dbg_stack_new[1] != 0) {                                             
611                                                         PHPStackFrame newStack= new PHPStackFrame(null, getModByNo(dbg_stack_new[1]), dbg_stack_new[0], stackIndex, getRawFrameData(entirePack, dbg_stack_new[3]), dbg_stack_new[1]);
612                                                         stackList.add(newStack);
613                                                 }
614                                                 break;
615                                         case PHPDBGBase.FRAME_SOURCE:
616                                                 break;
617                                         case PHPDBGBase.FRAME_SRC_TREE:
618                                                 dbg_src_tree_tmp[0] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 0);         // parent_mod_no
619                                                 dbg_src_tree_tmp[1] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 4);         // parent_line_no               /* NOT USED */
620                                                 dbg_src_tree_tmp[2] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 8);         // mod_no
621                                                 dbg_src_tree_tmp[3] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 12);        // imod_name
622
623                                                 if(getModByNo(dbg_src_tree_tmp[2]).equals("")) {
624                                                         String fileName= new String(getRawFrameData(entirePack, dbg_src_tree_tmp[3]));
625                                                         // Remove '\0' char
626                                                         if(fileName.length() > 0) fileName= fileName.substring(0, fileName.length() - 1);
627
628                                                         if(dbg_src_tree_tmp[2] != 0) {
629                                                                 PHPDBGMod modNew= new PHPDBGMod(dbg_src_tree_tmp[2], fileName);
630                                                                 DBGMods.add(modNew);
631                                                         }
632                                                 }
633                                                 break;
634                                         case PHPDBGBase.FRAME_RAWDATA:
635                                                 break;
636                                         case PHPDBGBase.FRAME_ERROR:
637                                                 break;
638                                         case PHPDBGBase.FRAME_EVAL:
639                                                 String evalString= new String("");
640                                                 dbg_eval_tmp[0] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 0); // istr
641                                                 dbg_eval_tmp[1] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 4); // iresult
642                                                 dbg_eval_tmp[2] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 8); // ierror
643
644                                                 evalRet= getRawFrameData(entirePack, dbg_eval_tmp[1]);
645                                                 evalString= getRawFrameData(entirePack, dbg_eval_tmp[0]);
646                                                 serGlobals= evalRet;
647                                                 break;
648                                         case PHPDBGBase.FRAME_BPS:
649                                                 break;
650                                         case PHPDBGBase.FRAME_BPL:
651                                                 int[] dbg_bpl_new= new int[10];
652                                                 dbg_bpl_new[0] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 0);
653                                                 dbg_bpl_new[1] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 4);
654                                                 dbg_bpl_new[2] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 8);
655                                                 dbg_bpl_new[3] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 12);
656                                                 dbg_bpl_new[4] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 16);
657                                                 dbg_bpl_new[5] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 20);
658                                                 dbg_bpl_new[6] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 24);
659                                                 dbg_bpl_new[7] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 28);
660                                                 dbg_bpl_new[8] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 32);
661                                                 dbg_bpl_new[9] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 36);
662         
663                                                 // look if breakpoint already exists in vector
664                                                 for(i=0; i < DBGBPList.size(); i++) {
665                                                         dbg_bpl_tmp= (int[]) DBGBPList.get(i);
666                                                         if(dbg_bpl_tmp[8] == dbg_bpl_new[8]) {
667                                                                 DBGBPList.remove(i);
668                                                                 break;
669                                                         }
670                                                 }
671
672                                                 // add breakpoint to vector
673                                                 DBGBPList.add(dbg_bpl_new);
674                                                 copyToLastBP(dbg_bpl_new);
675                                                 
676                                                 // mod no returned?
677                                                 if(getModByNo(dbg_bpl_new[0]).equals("")) {
678                                                         String fileName= new String(getRawFrameData(entirePack, dbg_bpl_new[2]));
679                                                         // Remove '\0' char
680                                                         if(fileName.length() > 0) fileName= fileName.substring(0, fileName.length() - 1);
681                                                         if(dbg_bpl_new[0] != 0) {
682                                                                 PHPDBGMod modNew= new PHPDBGMod(dbg_bpl_new[0], fileName);
683                                                                 DBGMods.add(modNew);
684                                                         }
685                                                 }                                                       
686                                                 break;
687                                         case PHPDBGBase.FRAME_VER:
688                                                 break;
689                                         case PHPDBGBase.FRAME_SID:
690                                                 break;
691                                         case PHPDBGBase.FRAME_SRCLINESINFO:
692                                                 break;
693                                         case PHPDBGBase.FRAME_SRCCTXINFO:
694                                                 break;
695                                         case PHPDBGBase.FRAME_LOG:
696                                                 break;
697                                         case PHPDBGBase.FRAME_PROF:
698                                                 break;
699                                         case PHPDBGBase.FRAME_PROF_C:
700                                                 break;
701                                         case PHPDBGBase.FRAME_SET_OPT:
702                                                 break;
703                                 }
704                                 // go to next frame
705                                 nextFrame += dbg_frame[1];
706                         }
707                         
708                         // Now process command
709                         switch(cmdReceived) {
710                                 case PHPDBGBase.DBGC_REPLY:
711                                         break;
712                                 case PHPDBGBase.DBGC_STARTUP:
713                                         break;
714                                 case PHPDBGBase.DBGC_END:
715                                         sessionEnded= true;
716                                         break;
717                                 case PHPDBGBase.DBGC_BREAKPOINT:
718                                         newStackList= new PHPStackFrame[stackList.size()];
719                                         newStackList= (PHPStackFrame[]) stackList.toArray(newStackList);
720                                         DBGStackList= newStackList;
721                                         BPUnderHit= getBPUnderHit();
722                                         break;
723                                 case PHPDBGBase.DBGC_STEPINTO_DONE:
724                                 case PHPDBGBase.DBGC_STEPOVER_DONE:
725                                 case PHPDBGBase.DBGC_STEPOUT_DONE:
726                                 case PHPDBGBase.DBGC_EMBEDDED_BREAK:
727                                         BPUnderHit= 1;
728                                         newStackList= new PHPStackFrame[stackList.size()];
729                                         newStackList= (PHPStackFrame[]) stackList.toArray(newStackList);
730                                         DBGStackList= newStackList;
731                                         break;
732                                 case PHPDBGBase.DBGC_ERROR:
733                                         newStackList= new PHPStackFrame[stackList.size()];
734                                         newStackList= (PHPStackFrame[]) stackList.toArray(newStackList);
735                                         DBGStackList= newStackList;
736                                         break;
737                                 case PHPDBGBase.DBGC_LOG:
738                                         break;
739                                 case PHPDBGBase.DBGC_SID:
740                                         break;
741                                 case PHPDBGBase.DBGC_PAUSE:
742                                         break;
743                         }
744                 }
745
746                 return cmdReceived;
747         }
748
749         public PHPStackFrame[] getStackList() {
750                 return DBGStackList;
751         }
752
753         private int readInput(char[] buffer, int bytes) throws IOException {
754                 int bytesRead= 0;
755
756                 for(int i=0; i < bytes; i++) {
757                         if(in.ready()) {
758                                 buffer[i]= (char) (in.read() & 0x00FF);
759                                 bytesRead++;
760                         }
761                         else
762                                 break;                          
763                 }
764                 return bytesRead;
765         }
766         
767         public void setShouldStop() {
768                 this.shouldStop= true;
769         }
770
771         public void waitResponse(long milliseconds) throws IOException {
772                 long timeout= System.currentTimeMillis() + milliseconds;
773                 while(System.currentTimeMillis() < timeout) {
774                         if(in.ready() || shouldStop) {
775                                 break;
776                         }
777                 }
778         }
779 }