DEADSOFTWARE

Solve oldType path lookup, found SEGFAULT
[odcread.git] / reader.cc
1 #include <reader.h>
2 #include <alien.h>
4 #include <string>
6 namespace odc {
8 Reader::Reader(std::istream &rider): d_rider(rider), d_cancelled(false), d_readAlien(false), d_typeList(),
9 d_state(new ReaderState()) {}
11 SHORTCHAR Reader::readSChar() {
12 SHORTCHAR out;
13 d_rider.read(&out, 1);
14 return out;
15 }
17 INTEGER Reader::readInt() {
18 char *buf = new char[4];
19 d_rider.read(buf, 4);
20 if (isLittleEndian()) {
21 return *(INTEGER *)buf;
22 } else {
23 char *out = new char[4];
24 out[0] = buf[3]; out[1] = buf[2]; out[2] = buf[1]; out[3] = buf[0];
25 return *(INTEGER *)out;
26 }
27 }
29 void Reader::readSString(SHORTCHAR *out) {
30 while (*out = readSChar()) {
31 ++out;
32 }
33 }
35 Store* Reader::readStore() {
36 SHORTCHAR kind = readSChar();
37 if (kind == Store::NIL) {
38 std::cout << "NIL STORE" << std::endl;
39 return readNilStore();
40 } else if (kind == Store::LINK) {
41 std::cout << "LINK STORE" << std::endl;
42 return readLinkStore();
43 } else if (kind == Store::NEWLINK) {
44 std::cout << "NEWLINK STORE" << std::endl;
45 return readNewLinkStore();
46 } else if (kind == Store::STORE) {
47 std::cout << "STORE STORE" << std::endl;
48 return readStoreOrElemStore(false);
49 } else if (kind == Store::ELEM) {
50 std::cout << "ELEM STORE" << std::endl;
51 return readStoreOrElemStore(true);
52 } else {
53 throw 20;
54 }
55 }
56 // PROCEDURE (VAR rd: Reader) ReadStore* (OUT x: Store), NEW;
57 // VAR a: Alien; t: Kernel.Type;
58 // len, pos, pos1, id, comment, next, down, downPos, nextTypeId, nextElemId, nextStoreId: INTEGER;
59 // kind: SHORTCHAR; path: TypePath; type: TypeName;
60 // save: ReaderState;
61 Store *Reader::readNilStore() {
62 return 0;
63 }
64 // IF kind = nil THEN
65 // rd.ReadInt(comment); rd.ReadInt(next);
66 // rd.st.end := rd.Pos();
67 // IF (next > 0) OR ((next = 0) & ODD(comment)) THEN rd.st.next := rd.st.end + next ELSE rd.st.next := 0 END;
68 // x := NIL
69 Store *Reader::readLinkStore() {
70 return 0;
71 }
72 // ELSIF kind = link THEN
73 // rd.ReadInt(id); rd.ReadInt(comment); rd.ReadInt(next);
74 // rd.st.end := rd.Pos();
75 // IF (next > 0) OR ((next = 0) & ODD(comment)) THEN rd.st.next := rd.st.end + next ELSE rd.st.next := 0 END;
76 // x := ThisStore(rd.eDict, id)
77 Store *Reader::readNewLinkStore() {
78 return 0;
79 }
80 // ELSIF kind = newlink THEN
81 // rd.ReadInt(id); rd.ReadInt(comment); rd.ReadInt(next);
82 // rd.st.end := rd.Pos();
83 // IF (next > 0) OR ((next = 0) & ODD(comment)) THEN rd.st.next := rd.st.end + next ELSE rd.st.next := 0 END;
84 // x := ThisStore(rd.sDict, id)
86 Store *Reader::readStoreOrElemStore(bool isElem) {
87 INTEGER id = isElem ? d_elemList.size() : d_storeList.size();
88 SHORTCHAR** path = newTypePath();
89 readPath(path);
90 for (int i = 0; path[i] != 0; ++i) {
91 std::cout << path[i] << std::endl;
92 }
93 SHORTCHAR* type = path[0];
94 INTEGER comment = readInt();
95 std::streampos pos1 = d_rider.tellg();
96 std::streamoff next = readInt();
97 std::streamoff down = readInt();
98 std::streamoff len = readInt();
99 std::streampos pos = d_rider.tellg();
100 if (next > 0) {
101 d_state->next = pos1 + next + (std::streamoff)4;
102 } else {
103 d_state->next = 0;
105 int downPos = 0;
106 if (down > 0) {
107 downPos = pos1 + down + (std::streamoff)8;
109 d_state->end = pos + len;
110 d_cause = 0;
111 // FIXME: insert whole bunch of checks here
112 // ASSERT(len >= 0, 101);
113 // IF next # 0 THEN
114 // ASSERT(rd.st.next > pos1, 102);
115 // IF down # 0 THEN
116 // ASSERT(downPos < rd.st.next, 103)
117 // END
118 // END;
119 // IF down # 0 THEN
120 // ASSERT(downPos > pos1, 104);
121 // ASSERT(downPos < rd.st.end, 105)
122 // END;
124 void *t = 0; // FIXME type lookup here
125 if (t != 0) {
126 // x := NewStore(t); x.isElem := kind = elem
127 } else {
128 // rd.cause := thisTypeRes; AlienTypeReport(rd.cause, type);
129 // x := NIL
132 Store *x = 0;
133 if (x != 0) { // IF READING SUCCEEDS, INSERT MORE CHECKS HERE
134 } else {
135 // rd.SetPos(pos);
136 // ASSERT(rd.cause # 0, 107);
137 Alien *alien = new Alien(id, path); //, d_cause); //,file
138 if (d_store == 0) {
139 d_store = alien;
140 } else {
141 // join(d_store, alien)
142 std::cout << "Man, should have written join(.,.)" << std::endl;
144 if (isElem) {
145 d_elemList.push_back(alien);
146 } else {
147 d_storeList.push_back(alien);
149 ReaderState *save = d_state;
150 // rd.nextTypeId := nextTypeId; rd.nextElemId := nextElemId; rd.nextStoreId := nextStoreId;
151 internalizeAlien(alien, downPos, save->end);
152 d_state = save;
153 // ASSERT(rd.Pos() = rd.st.end, 108);
154 // rd.cause := 0; rd.cancelled := FALSE; rd.readAlien := TRUE
155 return alien;
158 return x;
160 // t := ThisType(type);
161 // IF t # NIL THEN
162 // x := NewStore(t); x.isElem := kind = elem
163 // ELSE
164 // rd.cause := thisTypeRes; AlienTypeReport(rd.cause, type);
165 // x := NIL
166 // END;
167 // IF x # NIL THEN
168 // IF SamePath(t, path) THEN
169 // IF kind = elem THEN
170 // x.id := id; AddStore(rd.eDict, rd.eHead, x)
171 // ELSE
172 // x.id := id; AddStore(rd.sDict, rd.sHead, x)
173 // END;
174 // save := rd.st; rd.cause := 0; rd.cancelled := FALSE;
175 // x.Internalize(rd);
176 // rd.st := save;
177 // IF rd.cause # 0 THEN x := NIL
178 // ELSIF (rd.Pos() # rd.st.end) OR rd.rider.eof THEN
179 // rd.cause := inconsistentVersion; AlienReport(rd.cause);
180 // x := NIL
181 // END
182 // ELSE
183 // rd.cause := inconsistentType; AlienTypeReport(rd.cause, type);
184 // x := NIL
185 // END
186 // END;
187 //
188 // IF x # NIL THEN
189 // IF rd.noDomain THEN
190 // rd.store := x;
191 // rd.noDomain := FALSE
192 // ELSE
193 // Join(rd.store, x)
194 // END
195 // ELSE (* x is an alien *)
196 // rd.SetPos(pos);
197 // ASSERT(rd.cause # 0, 107);
198 // NEW(a); a.path := path; a.cause := rd.cause; a.file := rd.rider.Base();
199 // IF rd.noDomain THEN
200 // rd.store := a;
201 // rd.noDomain := FALSE
202 // ELSE
203 // Join(rd.store, a)
204 // END;
205 // IF kind = elem THEN
206 // a.id := id; AddStore(rd.eDict, rd.eHead, a)
207 // ELSE
208 // a.id := id; AddStore(rd.sDict, rd.sHead, a)
209 // END;
210 // save := rd.st;
211 // rd.nextTypeId := nextTypeId; rd.nextElemId := nextElemId; rd.nextStoreId := nextStoreId;
212 // InternalizeAlien(rd, a.comps, downPos, pos, len);
213 // rd.st := save;
214 // x := a;
215 // ASSERT(rd.Pos() = rd.st.end, 108);
216 // rd.cause := 0; rd.cancelled := FALSE; rd.readAlien := TRUE
217 // END
220 void Reader::internalizeAlien(Alien *alien, std::streampos down, std::streampos end) {
221 std::streampos next = down != 0 ? down : end;
222 while (d_rider.tellg() < end) {
223 if (d_rider.tellg() < next) { // for some reason, this means its a piece (unstructured)
224 std::cout << "Alien Piece" << std::endl;
225 size_t len = next - d_rider.tellg();
226 char *buf = new char[len];
227 d_rider.read(buf, len);
228 AlienComponent *comp = new AlienPiece(buf, len);
229 alien->getComponents().push_back(comp);
230 } else { // that means we've got a store
231 std::cout << "Alien Store" << std::endl;
232 d_rider.seekg(next);
233 AlienComponent *comp = new AlienPart(readStore());
234 alien->getComponents().push_back(comp);
235 next = d_state->next > 0 ? d_state->next : end;
240 void Reader::readPath(SHORTCHAR **path) {
241 SHORTCHAR kind = readSChar();
242 int i;
243 for (i = 0; kind == Store::NEWEXT; ++i) {
244 std::cout << i << std::endl;
245 readSString(path[i]);
246 addPathComponent(i == 0, path[i]);
247 // IF path[i] # elemTName THEN INC(i) END;
248 kind = readSChar();
251 if (kind == Store::NEWBASE) {
252 std::cout << i << std::endl;
253 readSString(path[i]);
254 addPathComponent(i == 0, path[i]);
255 ++i;
256 } else if (kind == Store::OLDTYPE) {
257 int id = readInt();
258 d_typeList[d_typeList.size() - 1]->baseId = id;
259 while (id != -1) {
260 std::cout << "old " << i << "id " << id << d_typeList[id]->name << std::endl;
261 path[i] = d_typeList[id]->name;
262 id = d_typeList[id]->baseId;
263 ++i;
265 // REPEAT
266 // GetThisType(rd.tDict, id, path[i]); id := ThisBaseId(rd.tDict, id);
267 // IF path[i] # elemTName THEN INC(i) END
268 // UNTIL id = -1
269 } else {
270 throw 100;
272 std::cout << "term " << i << std::endl;
273 path[i] = 0;
275 // PROCEDURE ReadPath (VAR rd: Reader; VAR path: TypePath);
276 // VAR h: TypeDict; id, extId: INTEGER; i: INTEGER; kind: SHORTCHAR;
277 //
278 // PROCEDURE AddPathComp (VAR rd: Reader);
279 // BEGIN
280 // IF h # NIL THEN AddBaseId(h, extId, rd.nextTypeId) END;
281 // AddType(rd.tDict, rd.tHead, rd.nextTypeId, path[i]);
282 // h := rd.tHead; extId := rd.nextTypeId
283 // END AddPathComp;
284 //
285 // BEGIN
286 // h := NIL; i := 0; rd.ReadSChar(kind);
287 // WHILE kind = newExt DO
288 // rd.ReadXString(path[i]);
289 // AddPathComp(rd); INC(rd.nextTypeId);
290 // IF path[i] # elemTName THEN INC(i) END;
291 // rd.ReadSChar(kind)
292 // END;
293 // IF kind = newBase THEN
294 // rd.ReadXString(path[i]);
295 // AddPathComp(rd); INC(rd.nextTypeId); INC(i)
296 // ELSE
297 // ASSERT(kind = oldType, 100);
298 // rd.ReadInt(id);
299 // IF h # NIL THEN AddBaseId(h, extId, id) END;
300 // REPEAT
301 // GetThisType(rd.tDict, id, path[i]); id := ThisBaseId(rd.tDict, id);
302 // IF path[i] # elemTName THEN INC(i) END
303 // UNTIL id = -1
304 // END;
305 // path[i] := ""
306 // END ReadPath;
308 void Reader::addPathComponent(bool first, SHORTCHAR *typeName) {
309 int next = d_typeList.size();
310 int curr = next - 1;
311 if (!first) {
312 d_typeList[curr]->baseId = next;
314 d_typeList.push_back(new TypeEntry(typeName));
317 } // namespace odc