DEADSOFTWARE

Remove Domain class - unused
[odcread.git] / reader.cc
1 #include <reader.h>
2 #include <alien.h>
4 #include <string>
5 #include <assert.h>
7 namespace odc {
9 Reader::Reader(std::istream &rider): d_rider(rider), d_cancelled(false), d_readAlien(false), d_typeList(),
10 d_state(new ReaderState()) {}
12 SHORTCHAR Reader::readSChar() {
13 SHORTCHAR out;
14 d_rider.read(&out, 1);
15 return out;
16 }
18 void Reader::readSChar(SHORTCHAR *buf, size_t len) {
19 d_rider.read(buf, len);
20 }
22 CHAR Reader::readLChar() {
23 CHAR buf;
24 char *bufPtr = (char *)&buf;
25 d_rider.read(bufPtr, 2);
26 if (isLittleEndian()) {
27 return buf;
28 } else {
29 CHAR out;
30 char *outPtr = (char *)&out;
31 outPtr[0] = bufPtr[1]; outPtr[1] = bufPtr[0];
32 return out;
33 }
34 }
36 void Reader::readLChar(CHAR *buf, size_t len) {
37 char *bufPtr = (char *)buf;
38 int len2 = len * 2;
39 d_rider.read(bufPtr, len2);
40 if (isBigEndian()) {
41 char tmp;
42 for (int i = 0; i < len2; i += 2) {
43 tmp = bufPtr[i];
44 bufPtr[i] = bufPtr[i + 1];
45 bufPtr[i + 1] = tmp;
46 }
47 }
48 }
50 BYTE Reader::readByte() {
51 BYTE out;
52 d_rider.read((char*)&out, 1);
53 return out;
54 }
56 SHORTINT Reader::readSInt() {
57 SHORTINT buf;
58 char *bufPtr = (char*)&buf;
59 d_rider.read(bufPtr, 2);
60 if (isLittleEndian()) {
61 return buf;
62 } else {
63 SHORTINT out;
64 char *outPtr = (char *)&out;
65 outPtr[0] = bufPtr[1]; outPtr[1] = bufPtr[0];
66 return out;
67 }
68 }
70 INTEGER Reader::readInt() {
71 INTEGER buf;
72 char *bufPtr = (char*)&buf;
73 d_rider.read(bufPtr, 4);
74 if (isLittleEndian()) {
75 return buf;
76 } else {
77 INTEGER out;
78 char *outPtr = (char *)&out;
79 outPtr[0] = bufPtr[3]; outPtr[1] = bufPtr[2]; outPtr[2] = bufPtr[1]; outPtr[3] = bufPtr[0];
80 return out;
81 }
82 }
84 void Reader::readSString(SHORTCHAR *out) {
85 while (*out = readSChar()) {
86 ++out;
87 }
88 }
90 void Reader::turnIntoAlien(int cause) {
91 assert(cause > 0);
92 d_cancelled = true;
93 d_cause = cause;
94 d_readAlien = true;
95 }
97 bool Reader::isCancelled() {
98 return d_cancelled;
99 }
101 INTEGER Reader::readVersion(INTEGER min, INTEGER max) {
102 INTEGER version = readByte();
103 if (version < min || version > max) {
104 turnIntoAlien(ALIENVERSION);
106 return version;
109 Store* Reader::readStore() {
110 SHORTCHAR kind = readSChar();
111 if (kind == Store::NIL) {
112 //std::cout << "NIL STORE" << std::endl;
113 return readNilStore();
114 } else if (kind == Store::LINK) {
115 //std::cout << "LINK STORE" << std::endl;
116 return readLinkStore();
117 } else if (kind == Store::NEWLINK) {
118 //std::cout << "NEWLINK STORE" << std::endl;
119 return readNewLinkStore();
120 } else if (kind == Store::STORE) {
121 //std::cout << "STORE STORE" << std::endl;
122 return readStoreOrElemStore(false);
123 } else if (kind == Store::ELEM) {
124 //std::cout << "ELEM STORE" << std::endl;
125 return readStoreOrElemStore(true);
126 } else {
127 //std::cout << std::hex << (unsigned int)kind << std::endl;
128 throw 20;
131 // PROCEDURE (VAR rd: Reader) ReadStore* (OUT x: Store), NEW;
132 // VAR a: Alien; t: Kernel.Type;
133 // len, pos, pos1, id, comment, next, down, downPos, nextTypeId, nextElemId, nextStoreId: INTEGER;
134 // kind: SHORTCHAR; path: TypePath; type: TypeName;
135 // save: ReaderState;
136 Store *Reader::readNilStore() {
137 INTEGER comment = readInt();
138 std::streamoff next = readInt();
139 d_state->end = d_rider.tellg();
140 if (next > 0 || (next == 0 && comment % 2 == 1)) {
141 d_state->next = d_state->end + next;
142 } else {
143 d_state->next = 0;
145 return 0;
147 // IF kind = nil THEN
148 // rd.ReadInt(comment); rd.ReadInt(next);
149 // rd.st.end := rd.Pos();
150 // IF (next > 0) OR ((next = 0) & ODD(comment)) THEN rd.st.next := rd.st.end + next ELSE rd.st.next := 0 END;
151 // x := NIL
152 Store *Reader::readLinkStore() {
153 return 0;
155 // ELSIF kind = link THEN
156 // rd.ReadInt(id); rd.ReadInt(comment); rd.ReadInt(next);
157 // rd.st.end := rd.Pos();
158 // IF (next > 0) OR ((next = 0) & ODD(comment)) THEN rd.st.next := rd.st.end + next ELSE rd.st.next := 0 END;
159 // x := ThisStore(rd.eDict, id)
160 Store *Reader::readNewLinkStore() {
161 return 0;
163 // ELSIF kind = newlink THEN
164 // rd.ReadInt(id); rd.ReadInt(comment); rd.ReadInt(next);
165 // rd.st.end := rd.Pos();
166 // IF (next > 0) OR ((next = 0) & ODD(comment)) THEN rd.st.next := rd.st.end + next ELSE rd.st.next := 0 END;
167 // x := ThisStore(rd.sDict, id)
169 Store *Reader::readStoreOrElemStore(bool isElem) {
170 INTEGER id = isElem ? d_elemList.size() : d_storeList.size();
171 TypePath path = readPath();
172 //std::cout << path.toString() << std::endl;
173 const std::string &type = path[0];
174 INTEGER comment = readInt();
175 std::streampos pos1 = d_rider.tellg();
176 std::streamoff next = readInt();
177 std::streamoff down = readInt();
178 std::streamoff len = readInt();
179 std::streampos pos = d_rider.tellg();
180 if (next > 0) {
181 d_state->next = pos1 + next + (std::streamoff)4;
182 } else {
183 d_state->next = 0;
185 int downPos = 0;
186 if (down > 0) {
187 downPos = pos1 + down + (std::streamoff)8;
189 d_state->end = pos + len;
190 d_cause = 0;
191 assert(len >= 0);
192 if (next != 0) {
193 assert(d_state->next > pos1);
194 if (down != 0) {
195 assert(downPos < d_state->next);
198 if (down > 0) {
199 assert(downPos > pos1);
200 assert(downPos < d_state->end);
203 const TypeProxyBase *t = TypeRegister::getInstance().get(type); // FIXME type lookup here
204 Store *x = 0;
205 if (t != 0) {
206 x = t->newInstance(id);
207 } else {
208 d_cause = TYPENOTFOUND;
211 if (x != 0) { // IF READING SUCCEEDS, INSERT MORE CHECKS HERE
212 if (true) { // samePath(x, path)
213 ReaderState *save = d_state;
214 d_state = new ReaderState();
215 x->internalize(*this);
216 delete d_state;
217 d_state = save;
219 if (d_cause != 0) {
220 x = 0;
222 assert(d_rider.tellg() == d_state->end);
223 assert(!d_rider.eof());
224 } else {
225 // rd.cause := inconsistentType; AlienTypeReport(rd.cause, type);
226 x = 0;
230 if (x != 0) {
231 if (d_store == 0) {
232 d_store = x;
233 } else {
234 // join(d_store, x)
235 //std::cout << "Man, should have written join(.,.)" << std::endl;
237 if (isElem) {
238 d_elemList.push_back(x);
239 } else {
240 d_storeList.push_back(x);
242 } else {
243 d_rider.seekg(pos); // x->internalize() could have left us anywhere
244 assert(d_cause != 0);
245 Alien *alien = new Alien(id, path); //, d_cause); //,file
246 if (d_store == 0) {
247 d_store = alien;
248 } else {
249 // join(d_store, alien)
250 //std::cout << "Man, should have written join(.,.)" << std::endl;
252 if (isElem) {
253 d_elemList.push_back(alien);
254 } else {
255 d_storeList.push_back(alien);
257 ReaderState *save = d_state;
258 d_state = new ReaderState();
259 internalizeAlien(alien, downPos, save->end);
260 delete d_state;
261 d_state = save;
262 assert(d_rider.tellg() == d_state->end);
264 // we've just read the alien, so reset the state
265 d_cause = 0;
266 d_cancelled = false;
267 d_readAlien = true;
268 return alien;
271 return x;
275 void Reader::internalizeAlien(Alien *alien, std::streampos down, std::streampos end) {
276 std::streampos next = down != 0 ? down : end;
277 while (d_rider.tellg() < end) {
278 if (d_rider.tellg() < next) { // for some reason, this means its a piece (unstructured)
279 //std::cout << "Alien Piece" << std::endl;
280 size_t len = next - d_rider.tellg();
281 char *buf = new char[len];
282 d_rider.read(buf, len);
283 AlienComponent *comp = new AlienPiece(buf, len);
284 alien->getComponents().push_back(comp);
285 } else { // that means we've got a store
286 //std::cout << "Alien Store" << std::endl;
287 d_rider.seekg(next);
288 AlienComponent *comp = new AlienPart(readStore());
289 alien->getComponents().push_back(comp);
290 next = d_state->next > 0 ? d_state->next : end;
295 std::string &Reader::fixTypeName(std::string &name) {
296 size_t pos = name.size() - 4;
297 if (pos > 0 && name.substr(pos, 4).compare("Desc") == 0) {
298 return name.replace(pos, 4, "^");
300 return name;
303 TypePath Reader::readPath() {
304 TypePath path;
305 SHORTCHAR kind = readSChar();
306 SHORTCHAR *buf = new SHORTCHAR[64]; // TypeName has a maximum of length 64 (including terminator).
307 int i;
308 for (i = 0; kind == Store::NEWEXT; ++i) {
309 readSString(buf);
310 std::string name(buf);
311 path.push_back(fixTypeName(name));
312 addPathComponent(i == 0, path[i]);
313 // IF path[i] # elemTName THEN INC(i) END;
314 kind = readSChar();
317 if (kind == Store::NEWBASE) {
318 readSString(buf);
319 std::string name(buf);
320 path.push_back(fixTypeName(name));
321 addPathComponent(i == 0, path[i]);
322 ++i;
323 } else if (kind == Store::OLDTYPE) {
324 int id = readInt();
325 if (i > 0) {
326 d_typeList[d_typeList.size() - 1]->baseId = id;
328 while (id != -1) {
329 path.push_back(d_typeList[id]->name);
330 id = d_typeList[id]->baseId;
331 // IF path[i] # elemTName THEN INC(i) END
332 ++i;
334 } else {
335 throw 100;
337 return path;
340 void Reader::addPathComponent(bool first, const std::string &typeName) {
341 int next = d_typeList.size();
342 int curr = next - 1;
343 if (!first) {
344 d_typeList[curr]->baseId = next;
346 d_typeList.push_back(new TypeEntry(typeName));
349 } // namespace odc