checked in changes
[repair.git] / Repair / RepairInterpreter / bitwriter.cc
1 // Interface for writing structures
2
3 #include <assert.h>
4 #include <stdio.h>
5 #include "bitwriter.h"
6 #include "bitreader.h"
7 #include "element.h"
8 #include "Hashtable.h"
9 #include "tmodel.h"
10 #include "amodel.h"
11 #include "model.h"
12 #include "processabstract.h"
13
14
15 bitwriter::bitwriter(model *m, Hashtable *e) {
16   globalmodel=m;
17   bitread=new bitreader(m,e);
18   env=e;
19 }
20
21 void bitwriter::writefieldorarray(Element *element, Field * field, Element * index, Element *target) {
22   assert(element->type()==ELEMENT_OBJECT);
23   // DEBUG STATEMENT
24   /*
25     element->print();
26     printf(".");
27     field->print();
28     if (index!=NULL) {
29     printf("[");
30     index->print();
31     printf("]");
32     }
33     printf("=");
34     target->print();
35     printf("\n");
36   */
37   //  Hashtable *env=new Hashtable((int (*)(void *)) & hashstring,(int (*)(void *,void *)) &equivalentstrings);;  
38   structure *type=element->getstructure();
39   //assert(type->getnumparams()==element->getnumparams());
40
41   /* build parameter mapping */
42   /*  for(int i=0;i<type->getnumparams();i++) {
43       env->put(type->getparam(i)->getname(),element->paramvalue(i));
44       }*/
45   char *fieldname=field->field();
46   ttype *typeoffield=NULL;
47   AElementexpr *lindex=NULL;
48   for(int i=0;i<type->getnumlabels();i++) {
49     if (equivalentstrings(type->getlabel(i)->getname(),fieldname)) {
50       /* got label not field... */
51       typeoffield=type->getlabel(i)->gettype();
52       fieldname=type->getlabel(i)->getfield();
53       lindex=type->getlabel(i)->getindex();
54       break;
55     }
56   }
57   int offset=0;
58   int bitoffset=0;
59   for(int i=0;i<type->getnumfields();i++) {
60     if(equivalentstrings(type->getfield(i)->getname(), fieldname)) {
61       /* got fieldname */
62       if (typeoffield==NULL)
63         typeoffield=type->getfield(i)->gettype();
64       break;
65     } else {
66       offset+=type->getfield(i)->gettype()->getbytes(bitread,globalmodel,env);
67     }
68   }
69   if (index!=NULL||lindex!=NULL) {
70     if (lindex!=NULL)
71       index=evaluateexpr(globalmodel,lindex,env,true,true);
72     if(typeoffield->gettype()==TTYPE_BIT) {
73       offset+=(index->intvalue())/8;
74       bitoffset=(index->intvalue())%8;
75     } else {
76       int size=typeoffield->basesize(bitread,globalmodel,env);
77       offset+=size*index->intvalue();
78     }
79     if (lindex!=NULL)
80       delete(index);
81   }
82   void *addr=(void *)(((char *) element->getobject())+offset);
83
84   if (typeoffield->isptr())
85     addr=*((void **)addr);
86   switch(typeoffield->gettype()) {
87   case TTYPE_INT:
88     {
89       *((int *) addr)=target->intvalue();
90       break;
91     }
92   case TTYPE_SHORT:
93     {
94       *((short *) addr)=target->getshortvalue();
95       break;
96     }
97   case TTYPE_BIT:
98     {
99       char c=*((char *) addr);
100       char co=c;
101       bool b=target->getboolvalue();
102       char mask=0xFF^(1<<bitoffset);
103       if (b)
104         c=(c&mask)|(1<<bitoffset);
105       else
106         c=c&mask;
107       *((char *)addr)=c;
108       /*
109         if (co!=c)
110         printf("Change: %hhd %hhd\n",co,c);
111       */
112       break;
113     }
114   case TTYPE_BYTE:
115     {
116       *((char *)addr)=target->getbytevalue();
117       break;
118     }
119   case TTYPE_STRUCT:
120     {
121       assert(typeoffield->isptr());
122       *((void **)(((char *) element->getobject())+offset))=target->getobject();
123       break;
124     }
125   }
126 }
127