revert runtime file.
[repair.git] / Repair / RepairInterpreter / bitreader.cc
1 // Interface for reading structures
2
3 #include <assert.h>
4 #include "bitreader.h"
5 #include "element.h"
6 #include "Hashtable.h"
7 #include "tmodel.h"
8 #include "amodel.h"
9 #include "model.h"
10 #include "processabstract.h"
11
12 bitreader::bitreader(model *m, Hashtable *e) {
13   globalmodel=m;
14   env=e;
15
16
17 Element * bitreader::readfieldorarray(Element *element, Field * field, Element * index) {
18   assert(element->type()==ELEMENT_OBJECT);
19   //  Hashtable *env=new Hashtable((int (*)(void *)) & hashstring,(int (*)(void *,void *)) &equivalentstrings);;  
20   if (element->getobject()==NULL)
21     return NULL;
22   structure *type=element->getstructure();
23   //  assert(type->getnumparams()==element->getnumparams());
24   /* build parameter mapping */
25   /*  for(int i=0;i<type->getnumparams();i++) {
26       env->put(type->getparam(i)->getname(),element->paramvalue(i));
27       }*/
28   char *fieldname=field->field();
29   ttype *typeoffield=NULL;
30   AElementexpr *lindex=NULL;
31   for(int i=0;i<type->getnumlabels();i++) {
32     if (equivalentstrings(type->getlabel(i)->getname(),fieldname)) {
33       /* got label not field... */
34       typeoffield=type->getlabel(i)->gettype();
35       fieldname=type->getlabel(i)->getfield();
36       lindex=type->getlabel(i)->getindex();
37       break;
38     }
39   }
40   int offset=0;
41   int bitoffset=0;
42   for(int i=0;i<type->getnumfields();i++) {
43     if(equivalentstrings(type->getfield(i)->getname(), fieldname)) {
44       /* got fieldname */
45       if (typeoffield==NULL)
46         typeoffield=type->getfield(i)->gettype();
47       break;
48     } else {
49       offset+=type->getfield(i)->gettype()->getbytes(this,globalmodel,env);
50     }
51   }
52   if (index!=NULL||lindex!=NULL) {
53     if (lindex!=NULL)
54       index=evaluateexpr(globalmodel,lindex,env,true,true);
55     if(typeoffield->gettype()==TTYPE_BIT) {
56       offset+=(index->intvalue())/8;
57       bitoffset=(index->intvalue())%8;
58     } else {
59       if (index->intvalue()!=0) {
60         /* Don't want to force computation of basesize unless we really need to...
61            we'd like to handle the filesystem example...:) */
62         int size=typeoffield->basesize(this,globalmodel,env);
63         offset+=size*index->intvalue();
64       }
65     }
66     if (lindex!=NULL)
67       delete(index);
68   }
69   Element *ele=NULL;
70   void *addr=(void *)(((char *) element->getobject())+offset);
71   if (typeoffield->isptr())
72     addr=*((void **)addr);
73   switch(typeoffield->gettype()) {
74   case TTYPE_INT:
75     {
76       int i=*((int *) addr);
77       ele=new Element(i);
78       break;
79     }
80   case TTYPE_SHORT:
81     {
82       short i=*((short *) addr);
83       ele=new Element(i);
84       break;
85     }
86   case TTYPE_BIT:
87     {
88       char c=*((char *) addr);
89       ele=new Element((bool)((c&(1<<bitoffset))!=0));
90       break;
91     }
92   case TTYPE_BYTE:
93     {
94       char c=*((char *)addr);
95       ele=new Element(c);
96       break;
97     }
98   case TTYPE_STRUCT:
99     {
100       /*      Element **earray=new Element *[typeoffield->getnumparamvalues()];
101               for(int i=0;i<typeoffield->getnumparamvalues();i++) {
102               earray[i]=evaluateexpr(this,typeoffield->getparamvalues(i),env);
103               }*/
104       ele=new Element(addr,globalmodel->getstructure(typeoffield->getname()));
105       break;
106     }
107   }
108   return ele;
109 }
110