7c71364a69ba198169a963bd45bc1a8459cf44ae
[phpeclipse.git] / net.sourceforge.phpeclipse.debug.core / src / net / sourceforge / phpdt / internal / debug / core / model / PHPDBGEvalString.java
1 package net.sourceforge.phpdt.internal.debug.core.model;
2
3 /*
4  * Created on 17.04.2004
5  *
6  * To change the template for this generated file go to
7  * Window - Preferences - Java - Code Generation - Code and Comments
8  */
9 /**
10  * @author Chris Admin
11  *
12  * To change the template for this generated type comment go to
13  * Window - Preferences - Java - Code Generation - Code and Comments
14  */
15
16 import java.util.Vector;
17
18 import net.sourceforge.phpdt.internal.debug.core.PHPDebugCorePlugin;
19
20 import org.eclipse.core.runtime.Status;
21 import org.eclipse.debug.core.DebugException;
22
23 /**
24  *
25  */
26 public class PHPDBGEvalString {
27
28         String                            workStr;
29         private PHPStackFrame fStackFrame;
30
31         /**
32          *
33          */
34         public PHPDBGEvalString (PHPStackFrame stack, String dataStr) {
35                 fStackFrame     = stack;
36                 workStr         = dataStr;
37         }
38
39         /**
40          *
41          * @param chstart
42          * @param chend
43          * @param startIdx
44          * @return
45          */
46         String ExtractSubStr (char chstart, char chend, int startIdx) throws DebugException {
47                 int     idx;
48                 int     i;
49                 String  rslt;
50                 Status  status;
51
52                 idx = startIdx;
53
54                 if (idx >= (workStr.length () - 1) ||
55                     workStr.charAt (idx) != chstart) {
56                         status = new Status (Status.ERROR, PHPDebugCorePlugin.getUniqueIdentifier (), Status.OK, "worng startIdx!", null);
57
58                         throw new DebugException (status);
59                 }
60
61                 i = ++idx;
62                 i = workStr.indexOf(chend, i);
63
64                 if (i == -1) {
65                         status = new Status (Status.ERROR, PHPDebugCorePlugin.getUniqueIdentifier (), Status.OK, "endchar not found!", null);
66
67                         throw new DebugException (status);
68                 }
69                 rslt    = workStr.substring (idx, i);
70                 workStr = workStr.substring (i + 1);
71
72                 return rslt;
73         }
74
75         /**
76          * @param slen
77          * @param startIdx
78          * @return
79          */
80         String ExtractQuotedSubStr (int slen, int startIdx) throws DebugException {
81                 int     idx;
82                 String  rslt;
83                 Status  status;
84
85                 idx = startIdx;
86
87                 if ((idx + slen + 1) >= workStr.length () ||
88                                 workStr.charAt (idx)!= '"' ||
89                                 workStr.charAt (idx + slen + 1) != '"') {
90                         status = new Status (Status.ERROR, PHPDebugCorePlugin.getUniqueIdentifier (), Status.OK, "no quoted substring found!", null);
91
92                         throw new DebugException (status);
93                 }
94
95                 rslt    = workStr.substring (idx + 1, idx + 1 + slen);
96                 workStr = workStr.substring (idx + 2 + slen);
97
98                 return rslt;
99         }
100
101         /**
102          *
103          * @param chstart
104          * @param chend
105          * @apram startIdx
106          * @return
107          */
108         int ExtractInt (char chstart, char chend, int startIdx) throws DebugException {
109                 String  subs;
110                 int     rslt;
111
112                 subs = ExtractSubStr (chstart, chend, startIdx);
113
114                 return (Integer.parseInt (subs));
115         }
116
117         /**
118          * @param name
119          * @param parent
120          * @param list       The list of PHPVariables
121          * @param var_list
122          * @param classname
123          * @param atype      The type of the variable (Either PEVT_ARRAY or PEVT_OBJECT)
124          * @return
125          */
126         PHPVariable ParseEvalArray (String name, PHPVariable parent, Vector list, Vector var_list, String classname, int atype)  throws DebugException {
127                 long            arritems;                                                                               // The number of items (or fields or entries) for the array (or short, array size)
128                 PHPVariable item;
129                 Vector          subitems = null;
130                 Status      status;
131
132                 arritems = ExtractInt (':', ':', 0);                                            // Get the number of items/fields for the array
133                                                                                                                                         // E.g. :12: means there are 12 entries in array
134
135                 if ((workStr.length () > 0) &&                              // Is there still something to parse?
136                     (workStr.charAt (0) != '{')) {                          // And the next character is not a '{', then output an error
137                         status = new Status (Status.ERROR, PHPDebugCorePlugin.getUniqueIdentifier (), Status.OK, "no array startcharacter!", null);
138
139                         throw new DebugException (status);
140                 }
141
142                 workStr = workStr.substring (1);                            // Remove the '{'
143                 item    = new PHPVariable (fStackFrame, name, parent, classname, atype, null);  // Create a new (empty) PHPVariable
144
145                 list.add (item);                                            // Add the newly created PHPVariable to list
146
147                 if (var_list != null) {                                     //
148                         var_list.add (item);                                    // Add the PHPVariable also to the var_list
149                 }
150
151                 if (arritems > 0) {                                         // If the array is not empty
152                         subitems = new Vector ();                               // Create a new child variable list for the array
153                 } else if (workStr.charAt (0) != '}') {                     // If the array is empty the next character has to be '}'
154                         status = new Status (Status.ERROR, PHPDebugCorePlugin.getUniqueIdentifier (), Status.OK, "no array endcharacter!", null);
155
156                         throw new DebugException (status);
157                 }
158
159                 while ((workStr.length () > 0) &&                           // Is there still something to parse?
160                        (workStr.charAt (0) != '}')) {                       // And the next character is not '}'
161                         Vector tmplst = new Vector ();                          // Create a temporary list
162
163                         parse ("", null, tmplst, null, false, 0);               // And parse the string for the array's name.
164
165                         if (tmplst.size () != 1) {                              // Parsing should return exactly on entry (which is the name)
166                                 status = new Status (Status.ERROR, PHPDebugCorePlugin.getUniqueIdentifier (), Status.OK, "no name found!", null);
167
168                                 throw new DebugException (status);
169                         }
170                                                                                                                                         // Go for the array values
171                         parse (((PHPVariable) tmplst.elementAt (0)).getValue ().getValueString (), item, subitems, var_list, true, 0);
172                 }
173
174                 ((PHPValue) item.getValue ()).addVariable (subitems);       // Append the list of all child variables to this PHPVariables PHPValue
175                 workStr = workStr.substring (1);                            // Remove the '}'
176
177                 return item;                                                // And return the PHPVariable we just build
178         }
179
180         /**
181          *
182          * @param name
183          * @param parent
184          * @param list
185          * @param var_list
186          * @param startIdx
187          */
188         void ParseEvalNULL (String name, PHPVariable parent, Vector list, Vector var_list, int startIdx) throws DebugException {
189                 int             idx;
190                 PHPVariable item;
191                 Status          status;
192
193                 idx = startIdx;
194
195                 if ((idx >= workStr.length ()) ||
196                     (workStr.charAt (idx) != ';')) {
197                         status = new Status (Status.ERROR, PHPDebugCorePlugin.getUniqueIdentifier (), Status.OK, "NULL not found!", null);
198
199                         throw new DebugException(status);
200                 }
201
202                 workStr = workStr.substring (1);
203                 item    = new PHPVariable (fStackFrame, name, parent, "NULL", PHPValue.PEVT_UNKNOWN, null);
204
205                 list.add (item);
206
207                 if (var_list != null) {
208                         var_list.add (item);
209                 }
210         }
211
212         /**
213          *
214          * @param name
215          * @param parent
216          * @param list
217          * @param var_list
218          * @param startIdx
219          */
220         boolean ParseEvalInt (String name, PHPVariable parent, Vector list, Vector var_list, int startIdx) throws DebugException {
221                 String          subs;
222                 PHPVariable item;
223
224                 subs = ExtractSubStr (':', ';', startIdx);
225                 item = new PHPVariable (fStackFrame, name, parent, subs, PHPValue.PEVT_LONG, null);
226
227                 list.add (item);
228
229                 if (var_list != null) {
230                         var_list.add (item);
231                 }
232
233                 return true;
234         }
235
236         /**
237          *
238          * @param name
239          * @param parent
240          * @param list
241          * @param var_list
242          * @param startIdx
243          */
244         boolean ParseEvalDouble (String name, PHPVariable parent, Vector list, Vector var_list, int startIdx) throws DebugException {
245                 String          subs;
246                 PHPVariable item;
247
248                 subs = ExtractSubStr (':', ';', startIdx);
249                 item = new PHPVariable (fStackFrame, name, parent, subs, PHPValue.PEVT_DOUBLE, null);
250
251                 list.add (item);
252
253                 if (var_list != null) {
254                         var_list.add (item);
255                 }
256
257                 return true;
258         }
259
260         /**
261          *
262          * @param name
263          * @param parent
264          * @param list
265          * @param var_list
266          * @param MakePhpStr
267          * @param startIdx
268          */
269         boolean ParseEvalString (String name, PHPVariable parent, Vector list, Vector var_list, boolean MakePhpStr, int startIdx)
270                                         throws DebugException {
271                 int                     slen;
272                 Status          status;
273                 String          subs;
274                 PHPVariable item;
275
276                 slen = ExtractInt( ':', ':',startIdx);
277
278                 if ((workStr.length () <= slen) ||
279                     (workStr.charAt (0) != '"')) {
280                         status = new Status (Status.ERROR, PHPDebugCorePlugin.getUniqueIdentifier (), Status.OK, "no String startcharecter!", null);
281
282                         throw new DebugException (status);
283                 }
284
285                 workStr = workStr.substring (1);
286                 subs    = workStr.substring (0, slen);
287
288                 // replace \\ with \
289                 subs = subs.replaceAll ("\\\\\\\\","\\\\");
290
291                 if (workStr.charAt (slen) != '"') {
292                         status = new Status (Status.ERROR, PHPDebugCorePlugin.getUniqueIdentifier (),Status.OK, "no String endcharecter!", null);
293                         throw new DebugException (status);
294                 }
295
296                 workStr = workStr.substring (slen + 2);
297
298 /*              if (MakePhpStr) {
299                         ConvertToPhpString(subs, &subs);
300                 }
301 */
302                 item = new PHPVariable (fStackFrame, name, parent, subs, PHPValue.PEVT_STRING, null);
303
304                 list.add (item);
305
306                 if (var_list != null) {
307                         var_list.add (item);
308                 }
309
310                 return true;
311         }
312
313         /**
314          *
315          * @param name
316          * @param parent
317          * @param list
318          * @param var_list
319          * @param startIdx
320          */
321         boolean ParseEvalBool (String name, PHPVariable parent, Vector list, Vector var_list, int startIdx) throws DebugException {
322                 long            v;
323                 PHPVariable item;
324
325                 v    = ExtractInt (':', ';', startIdx);
326                 item = new PHPVariable (fStackFrame, name, parent, (v==0) ? ("FALSE") : ("TRUE"), PHPValue.PEVT_BOOLEAN, null);
327
328                 list.add (item);
329
330                 if (var_list != null) {
331                         list.add (item);
332                 }
333
334                 return true;
335         }
336
337         /**
338          *
339          * @param name
340          * @param parent
341          * @param list
342          * @param var_list
343          * @param startIdx
344          */
345         boolean ParseEvalObject (String name, PHPVariable parent, Vector list, Vector var_list, int startIdx) throws DebugException {
346                 int             slen;
347                 String  classname;
348
349                 slen      = ExtractInt (':', ':', startIdx);
350                 classname = ExtractQuotedSubStr (slen, startIdx);
351
352                 if ((int) classname.length () != slen) {
353                         return false;
354                 }
355
356                 ParseEvalArray (name,parent, list, var_list, classname,PHPValue.PEVT_OBJECT);
357
358                 return true;
359         }
360
361         /**
362          *
363          * @param name
364          * @param parent
365          * @param list
366          * @param var_list
367          * @param startIdx
368          */
369         boolean ParseEvalResource (String name, PHPVariable parent, Vector list, Vector var_list, int startIdx) throws DebugException {
370                 PHPVariable item;
371                 int                     slen;
372                 String          restype;
373                 String          val;
374
375                 slen    = ExtractInt (':', ':', startIdx);
376                 restype = ExtractQuotedSubStr (slen, startIdx);
377                 val     = ExtractSubStr (':', ';', startIdx);
378
379                 item = new PHPVariable (fStackFrame, name, parent, restype + ":" + val, PHPValue.PEVT_RESOURCE, null);
380
381                 list.add (item);
382
383                 if (var_list != null) {
384                         list.add (item);
385                 }
386
387                 return true;
388         }
389
390
391         /**
392          *
393          * @param name
394          * @param parent
395          * @param list
396          * @param var_list
397          * @param startIdx
398          */
399         boolean ParseEvalRef (String name, PHPVariable parent, Vector list, Vector var_list, boolean isSoftRef, int startIdx) throws DebugException {
400                 int                     v;
401                 PHPVariable item;
402                 PHPVariable var_item;
403
404                 v    = ExtractInt(':', ';',startIdx);
405                 item = new PHPVariable (fStackFrame, name, parent, "", (isSoftRef) ? (PHPValue.PEVT_SOFTREF) : (PHPValue.PEVT_REF), null);
406                 v--;                                                                                                            // ref ID is 1-based, EvalList is 0-based
407
408                 if ((var_list == null) ||
409                     (v < 0) ||
410                         (v >= var_list.size ())) {
411 //                      item.ref = item; // self-resolving
412 //
413                         return true;
414                 } else {
415                         var_item = (PHPVariable) var_list.get (v);
416
417                         try {
418                                 item.setValue (var_item.getValue ());
419                                 item.setReferenceType (var_item.getReferenceType ());
420                                 ((PHPValue) item.getValue ()).setParent (item);
421                         } catch (DebugException e) {
422                                 // TODO Auto-generated catch block
423                                 e.printStackTrace ();
424                         }
425
426                         list.add (item);
427                 }
428
429                 return true;
430         }
431
432         /**
433          *
434          * @return The array of PHPVariables
435          */
436         public PHPVariable[] getVars () {
437                 Vector list     = new Vector ();
438                 Vector var_list = new Vector ();
439
440                 parse ("", null, list, var_list, false, 0);
441
442                 return (PHPVariable[]) list.toArray (new PHPVariable[list.size ()]);    // Convert the list to an array and return the array
443         }
444
445         /**
446          *
447          * @return The PHPVariables as list
448          */
449         public Vector getVariables () {
450                 Vector list     = new Vector ();
451                 Vector var_list = new Vector ();
452
453                 parse ("", null, list, var_list, false, 0);
454
455                 return list;                                                                                                                    // return the PHPVariable list
456         }
457
458         /**
459          *
460          *
461          *
462          * @param name        The name of the PHPVariable
463          * @param parent      The PHPVariable to which this parsing belongs
464          * @param list
465          * @param var_list
466          * @param MakePhpStr
467          * @param startIdx
468          */
469         boolean parse (String name, PHPVariable parent, Vector list, Vector var_list, boolean MakePhpStr, int startIdx) {
470                 boolean ret_val = false;
471                 char    ch;
472
473                 if (startIdx >= workStr.length ()) {                        // Is there something to parse
474                         return false;                                           // No, then leave here
475                 }
476
477                 ch              = workStr.charAt (startIdx);                        // The first character denotes the type of variable
478                 workStr = workStr.substring (1);                            // Remove the 'variable type' character
479
480                 try {
481                         switch (ch) {                                           // Switch according the 'variable type'
482                                 case 'N': ParseEvalNULL         (name, parent, list, var_list, startIdx);                                break;
483                                 case 'i': ParseEvalInt          (name, parent, list, var_list, startIdx);                                break;
484                                 case 'd': ParseEvalDouble       (name, parent, list, var_list, startIdx);                                break;
485                                 case 's': ParseEvalString       (name, parent, list, var_list, MakePhpStr, startIdx);    break;
486                                 case 'a': ParseEvalArray        (name, parent, list, var_list, "", PHPValue.PEVT_ARRAY); break;
487                                 case 'O': ParseEvalObject       (name, parent, list, var_list, startIdx);                                break;
488                                 case 'b': ParseEvalBool         (name, parent, list, var_list, startIdx);                                break;
489                                 case 'z': ParseEvalResource (name, parent, list, var_list, startIdx);                            break;
490                                 case 'R': ParseEvalRef          (name, parent, list, var_list, false, startIdx);                 break;
491                                 case 'r': ParseEvalRef          (name, parent, list, var_list, true, startIdx);                  break;
492                         }
493                 } catch (DebugException e) {
494                         // TODO Auto-generated catch block
495                         e.printStackTrace();
496                 }
497
498 /*              if (!ret_val) { // try to recover
499                         unsigned int i=*startIdx;
500                         while (i<str.length() && str[i]!='{' && str[i]!=';') i++;
501                         if (i<str.length() && str[i] == '{') {
502                                 unsigned int cnt=1;
503                                 i++;
504                                 while (i<str.length() && cnt!=0) {
505                                         if (str[i] == '{')
506                                                 cnt++;
507                                         else if (str[i] == '}')
508                                                 cnt--;
509                                         i++;
510                                 }
511                         }
512                         *startIdx = i;
513                 }
514 */
515                 return  ret_val;                                                                                        // Always false
516         }
517 }