DEADSOFTWARE

Can now read entire "empty" document as Alien
authorGert van Valkenhoef <g.h.m.van.valkenhoef@rug.nl>
Mon, 8 Aug 2011 20:37:02 +0000 (21:37 +0100)
committerGert van Valkenhoef <g.h.m.van.valkenhoef@rug.nl>
Mon, 8 Aug 2011 20:37:02 +0000 (21:37 +0100)
Makefile
alien.cc [new file with mode: 0644]
alien.h [new file with mode: 0644]
odcread.cc
reader.cc
reader.h
store.cc
store.h

index e03bf66b81765e6def5abb7a416c956c6c589aa5..b3cdd9916856491cfeb60c8dfab498b2348a95d1 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
-HEADERS=oberon.h store.h reader.h domain.h
+HEADERS=oberon.h store.h reader.h domain.h alien.h
 
-odcread: odcread.o reader.o store.o util.o
+odcread: odcread.o reader.o store.o util.o alien.o
        g++ -o $@ $^
 
 %.o: %.cc $(HEADERS)
diff --git a/alien.cc b/alien.cc
new file mode 100644 (file)
index 0000000..7a225b7
--- /dev/null
+++ b/alien.cc
@@ -0,0 +1,31 @@
+#include <alien.h>
+
+namespace odc {
+
+AlienPiece::AlienPiece(const char * const _data, const size_t _len): data(_data), len(_len) {}
+
+std::string AlienPiece::toString() {
+       return std::string("AlienPiece");
+}
+
+AlienPart::AlienPart(Store * const _store): store(_store) {}
+
+std::string AlienPart::toString() {
+       return store->toString();
+}
+
+Alien::Alien(INTEGER id, SHORTCHAR **path): Store(id), d_path(path), d_comps() {}
+
+std::vector<AlienComponent*> & Alien::getComponents() {
+       return d_comps;
+}
+
+std::string Alien::toString() {
+       std::string sofar = std::string(d_path[0]) + "{ ";
+       for (int i = 0; i < d_comps.size(); ++i) {
+               sofar += d_comps[i]->toString() + " ";
+       }
+       return sofar + "}";
+}
+
+}
diff --git a/alien.h b/alien.h
new file mode 100644 (file)
index 0000000..40ef09a
--- /dev/null
+++ b/alien.h
@@ -0,0 +1,59 @@
+#ifndef _ALIEN_H_
+#define _ALIEN_H_
+
+#include <oberon.h>
+#include <store.h>
+#include <iostream>
+#include <vector>
+
+namespace odc {
+
+/**
+ * Part of an alien store
+ */
+struct AlienComponent {
+       virtual std::string toString() = 0;
+};
+
+/**
+ * Totally unstructured part of an alien store
+ */
+struct AlienPiece : public AlienComponent {
+       const char * const data;
+       const size_t len;
+
+       AlienPiece(const char * const data, const size_t len);
+
+       virtual std::string toString();
+};
+
+/**
+ * Store component of an alien store
+ */
+struct AlienPart : public AlienComponent {
+       Store * const store;
+
+       AlienPart(Store * const _store);
+
+       virtual std::string toString();
+};
+
+class Alien : public Store {
+       SHORTCHAR **d_path;
+       std::vector<AlienComponent*> d_comps;
+
+       public:
+
+       Alien(INTEGER id, SHORTCHAR **path);
+
+       std::vector<AlienComponent*> & getComponents();
+
+       // cause-: INTEGER;     (** # 0, the cause that turned this store into an alien **)
+       // file-: Files.File;   (** base file holding alien pieces **)
+       // comps-: AlienComp    (** the constituent components of this alien store **)
+
+       virtual std::string toString();
+};
+
+}
+#endif // _ALIEN_H_
index 77a26947c5da21f3617a32dd341ff50dd68c2009..32fcd6b25471d2b368f16e05c10cf00105f0a77c 100644 (file)
@@ -1,5 +1,6 @@
 #include <iostream>
 #include <fstream>
+#include <string>
 
 #include <oberon.h>
 #include <reader.h>
@@ -26,6 +27,7 @@ namespace odc {
 int main(int argc, char *argv[]) {
        std::ifstream in(argv[1], std::ios::in | std::ios::binary);
        odc::Store* s = odc::importDocument(in);
-       std::cout << s << std::endl;
+       std::cout << s->toString() << std::endl;
+       std::cout << in.tellg() << " " << in.eof() << std::endl;
        return 0;
 }
index 54ca8c1a2ff99ffee3554ca75353775616ea6964..46a0b812e7334485a6d22b1add42c62b4eca787a 100644 (file)
--- a/reader.cc
+++ b/reader.cc
@@ -1,8 +1,12 @@
 #include <reader.h>
+#include <alien.h>
+
+#include <string>
 
 namespace odc {
 
-Reader::Reader(std::istream &rider): d_rider(rider), d_cancelled(false), d_readAlien(false) {}
+Reader::Reader(std::istream &rider): d_rider(rider), d_cancelled(false), d_readAlien(false), d_typeList(),
+       d_state(new ReaderState()) {}
 
 SHORTCHAR Reader::readSChar() {
        SHORTCHAR out;
@@ -22,6 +26,12 @@ INTEGER Reader::readInt() {
        }
 }
 
+void Reader::readSString(SHORTCHAR *out) {
+       while (*out = readSChar()) {
+               ++out;
+       }
+}
+
 Store* Reader::readStore() {
        SHORTCHAR kind = readSChar();
        if (kind == Store::NIL) {
@@ -69,24 +79,31 @@ Store *Reader::readNewLinkStore() {
 //                     x := ThisStore(rd.sDict, id)
 
 Store *Reader::readStoreOrElemStore(bool isElem) {
-       INTEGER id = isElem ? d_nextElemId++ : d_nextStoreId++;
-       CHAR** path = newTypePath();
+       INTEGER id = isElem ? d_elemList.size() : d_storeList.size();
+       SHORTCHAR** path = newTypePath();
        readPath(path);
-       CHAR* type = path[0];
-       std::cout << type << std::endl;
+       for (int i = 0; path[i] != 0; ++i) {
+               std::cout << path[i] << std::endl;
+       }
+       SHORTCHAR* type = path[0];
        INTEGER comment = readInt();
-       return 0;
-}
-//                     ReadPath(rd, path); type := path[0];
-//                     nextTypeId := rd.nextTypeId; nextElemId := rd.nextElemId; nextStoreId := rd.nextStoreId;
-//                     rd.ReadInt(comment);
-//                     pos1 := rd.Pos();
-//                     rd.ReadInt(next); rd.ReadInt(down); rd.ReadInt(len);
-//                     pos := rd.Pos();
-//                     IF next > 0 THEN rd.st.next := pos1 + next + 4 ELSE rd.st.next := 0 END;
-//                     IF down > 0 THEN downPos := pos1 + down + 8 ELSE downPos := 0 END;
-//                     rd.st.end := pos + len;
-//                     rd.cause := 0;
+       std::streampos pos1 = d_rider.tellg();
+       std::streamoff next = readInt();
+       std::streamoff down = readInt();
+       std::streamoff len = readInt();
+       std::streampos pos = d_rider.tellg();
+       if (next > 0) {
+               d_state->next = pos1 + next + (std::streamoff)4;
+       } else {
+               d_state->next = 0;
+       }
+       int downPos = 0;
+       if (down > 0) {
+               downPos = pos1 + down + (std::streamoff)8;
+       }
+       d_state->end = pos + len;
+       d_cause = 0;
+       // FIXME: insert whole bunch of checks here
 //                     ASSERT(len >= 0, 101);
 //                     IF next # 0 THEN
 //                             ASSERT(rd.st.next > pos1, 102);
@@ -98,6 +115,43 @@ Store *Reader::readStoreOrElemStore(bool isElem) {
 //                             ASSERT(downPos > pos1, 104);
 //                             ASSERT(downPos < rd.st.end, 105)
 //                     END;
+
+       void *t = 0; // FIXME type lookup here
+       if (t != 0) {
+//                             x := NewStore(t); x.isElem := kind = elem
+       } else {
+//                             rd.cause := thisTypeRes; AlienTypeReport(rd.cause, type);
+//                             x := NIL
+       }
+
+       Store *x = 0;
+       if (x != 0) { // IF READING SUCCEEDS, INSERT MORE CHECKS HERE
+       } else {
+//                             rd.SetPos(pos);
+//                             ASSERT(rd.cause # 0, 107);
+               Alien *alien = new Alien(id, path); //, d_cause); //,file
+               if (d_store == 0) {
+                       d_store = alien;
+               } else {
+                       // join(d_store, alien)
+                       std::cout << "Man, should have written join(.,.)" << std::endl;
+               }
+               if (isElem) {
+                       d_elemList.push_back(alien);
+               } else {
+                       d_storeList.push_back(alien);
+               }
+               ReaderState *save = d_state;
+//                             rd.nextTypeId := nextTypeId; rd.nextElemId := nextElemId; rd.nextStoreId := nextStoreId;
+               internalizeAlien(alien, downPos, save->end);
+               d_state = save;
+//                             ASSERT(rd.Pos() = rd.st.end, 108);
+//                             rd.cause := 0; rd.cancelled :=  FALSE; rd.readAlien := TRUE
+               return alien;
+       }
+
+       return x;
+}
 //                     t := ThisType(type);
 //                     IF t # NIL THEN
 //                             x := NewStore(t); x.isElem := kind = elem
@@ -157,28 +211,52 @@ Store *Reader::readStoreOrElemStore(bool isElem) {
 //                             rd.cause := 0; rd.cancelled :=  FALSE; rd.readAlien := TRUE
 //                     END
 
-void Reader::readPath(CHAR **path) {
+
+void Reader::internalizeAlien(Alien *alien, std::streampos down, std::streampos end) {
+       std::streampos next = down != 0 ? down : end;
+       while (d_rider.tellg() < end) {
+               if (d_rider.tellg() < next) { // for some reason, this means its a piece (unstructured)
+                       std::cout << "Alien Piece" << std::endl;
+                       size_t len = next - d_rider.tellg();
+                       char *buf = new char[len];
+                       d_rider.read(buf, len);
+                       AlienComponent *comp = new AlienPiece(buf, len);
+                       alien->getComponents().push_back(comp);
+               } else { // that means we've got a store
+                       std::cout << "Alien Store" << std::endl;
+                       d_rider.seekg(next);
+                       AlienComponent *comp = new AlienPart(readStore());
+                       alien->getComponents().push_back(comp);
+                       next = d_state->next > 0 ? d_state->next : end;
+               }
+       }
+}
+
+void Reader::readPath(SHORTCHAR **path) {
        SHORTCHAR kind = readSChar();
-       for (int i = 0; kind == Store::NEWEXT; ++i) {
-               std::cout << "NEWEXT" << std::endl;
-               //readXString(path[i]);
-//                     AddPathComp(rd); INC(rd.nextTypeId);
+       int i;
+       for (i = 0; kind == Store::NEWEXT; ++i) {
+               readSString(path[i]);
+               addPathComponent(i == 0, path[i]);
 //                     IF path[i] # elemTName THEN INC(i) END;
-//                     rd.ReadSChar(kind)
+               kind = readSChar();
        }
 
        if (kind == Store::NEWBASE) {
-               std::cout << "NEWBASE" << std::endl;
+               readSString(path[i]);
+               addPathComponent(i == 0, path[i]);
+               ++i;
        } else if (kind == Store::OLDTYPE) {
-               std::cout << "OLDTYPE" << std::endl;
+               int id = readInt();
+               d_typeList[d_typeList.size() - 1]->baseId = id;
+//                     REPEAT
+//                             GetThisType(rd.tDict, id, path[i]); id := ThisBaseId(rd.tDict, id);
+//                             IF path[i] # elemTName THEN INC(i) END
+//                     UNTIL id = -1
        } else {
                throw 100;
        }
-
-       // FIXME
-       path[0][0] = 'H';
-       path[0][1] = 'i';
-       path[0][2] = 0;
+       path[i] = 0;
 }
 //     PROCEDURE ReadPath (VAR rd: Reader; VAR path: TypePath);
 //             VAR h: TypeDict; id, extId: INTEGER; i: INTEGER; kind: SHORTCHAR;
@@ -213,4 +291,13 @@ void Reader::readPath(CHAR **path) {
 //             path[i] := ""
 //     END ReadPath;
 
+void Reader::addPathComponent(bool first, SHORTCHAR *typeName) {
+       int next = d_typeList.size();
+       int curr = next - 1;
+       if (!first) {
+               d_typeList[curr]->baseId = next;
+       }
+       d_typeList.push_back(new TypeEntry(typeName));
+}
+
 } // namespace odc
index cfd4fc53194f1242de4890a369e5765bc086bce5..208cf287a34875be20020ec159fe3fb44fb009fb 100644 (file)
--- a/reader.h
+++ b/reader.h
@@ -2,12 +2,22 @@
 #define _READER_H_
 
 #include <iostream>
+#include <vector>
 
 #include <oberon.h>
 #include <store.h>
+#include <alien.h>
 
 namespace odc {
 
+class TypeEntry {
+       public:
+       SHORTCHAR *name;
+       INTEGER baseId;
+
+       TypeEntry(SHORTCHAR *typeName) : name(typeName), baseId(-1) {}
+};
+
 /**
  * TYPE Reader
  * Reader for Component Pascal values like integers, reals, or sets. A reader contains a Files.Reader, to which it forwards most operations.
@@ -34,8 +44,26 @@ private:
         */
        bool d_readAlien;
 
-       INTEGER d_nextElemId;
-       INTEGER d_nextStoreId;
+       std::vector<TypeEntry*> d_typeList;
+
+       std::vector<Store*> d_elemList; // FIXME: WTH, why are these different?
+       std::vector<Store*> d_storeList;
+
+       Store *d_store;
+
+       struct ReaderState {
+               /**
+                * Position of the next store in the current level
+                */
+               std::streampos next;
+               /**
+                * Position just after the last read store
+                */
+               std::streampos end;
+       };
+       ReaderState *d_state;
+
+       INTEGER d_cause;
 
        public:
        /**
@@ -102,7 +130,9 @@ private:
         * NEW
         * Same as ReadSChar, but has a CHAR-type parameter.
         * This procedure is provided to simplify migration from Release 1.2 to 1.3.
-        * 
+        */
+       CHAR readXChar();
+       /** 
         * PROCEDURE (VAR rd: Reader) ReadChar (OUT x: CHAR)
         * NEW
         * Reads a character (0000X..0FFFFX).
@@ -148,19 +178,24 @@ private:
         * PROCEDURE (VAR rd: Reader) ReadSet (OUT x: SET)
         * NEW
         * Reads a set (32 elements).
-        * 
+        */
+       /**
         * PROCEDURE (VAR rd: Reader) ReadSString (OUT x: ARRAY OF SHORTCHAR)
         * NEW
         * Reads a 0X-terminated short string.
         * 
         * Pre
         * invalid index         LEN(x) > Length(string)
-        * 
+        */
+       void readSString(SHORTCHAR *out);
+       /** 
         * PROCEDURE (VAR rd: Reader) ReadXString (OUT x: ARRAY OF CHAR)
         * NEW
         * Same as ReadSString, but has a string-type parameter.
         * This procedure is provided to simplify migration from Release 1.2 to 1.3.
-        * 
+        */
+       //void readXString(CHAR *out);
+       /** 
         * PROCEDURE (VAR rd: Reader) ReadString (OUT x: ARRAY OF CHAR)
         * NEW
         * Reads a 0X-terminated string.
@@ -224,23 +259,28 @@ private:
        Store *readNilStore();
        Store *readLinkStore();
        Store *readNewLinkStore();
+       void internalizeAlien(Alien *alien, std::streampos down, std::streampos end);
        
        /*
                TypeName* = ARRAY 64 OF CHAR;
                TypePath* = ARRAY 16 OF TypeName;
                OpName* = ARRAY 32 OF CHAR;
         */
-       inline CHAR *newTypeName() {
-               return new CHAR[64];
+       inline SHORTCHAR *newTypeName() {
+               return new SHORTCHAR[64];
        }
-       inline CHAR **newTypePath() {
-               CHAR **out = new CHAR*[16];
+       inline SHORTCHAR **newTypePath() {
+               SHORTCHAR **out = new SHORTCHAR*[16];
                for (int i = 0; i < 16; ++i) {
                        out[i] = newTypeName();
                }
                return out;
        }
-       void readPath(CHAR **path);
+       void readPath(SHORTCHAR **path);
+       /**
+        * Add another component to the current path. If first==true, start a new path.
+        */
+       void addPathComponent(bool first, SHORTCHAR *typeName);
 };
 
 } // namespace odc
index 51729e1414e56a667e9d3a8c12eb7df32b242788..d7db23be164b68e41a7da87834f50e951aed801f 100644 (file)
--- a/store.cc
+++ b/store.cc
@@ -2,6 +2,12 @@
 
 namespace odc {
 
+Store::Store(INTEGER id): d_id(id) {}
+
+INTEGER Store::getId() {
+       return d_id;
+}
+
 Domain* Store::getDomain() {
        return 0;
 }
diff --git a/store.h b/store.h
index 381cca7907670fe4565ad135eae331d52aa6319d..be351b70ea70092709155aa9b1c2e750d95e7ceb 100644 (file)
--- a/store.h
+++ b/store.h
@@ -4,6 +4,8 @@
 #include <oberon.h>
 #include <domain.h>
 
+#include <string>
+
 namespace odc {
 
        /**
@@ -14,6 +16,9 @@ namespace odc {
         * Stores are used as base types for all objects that must be both extensible and persistent.
         */
        class Store {
+       private:
+               INTEGER d_id;
+
        public: 
                static const SHORTCHAR NEWBASE = 0xF0; // (* new base type (level = 0), i.e. not yet in dict *)
                static const SHORTCHAR NEWEXT = 0xF1;  // (* new extension type (level = 1), i.e. not yet in dict *)
@@ -23,6 +28,12 @@ namespace odc {
                static const SHORTCHAR STORE = 0x82;   // (* general store *)
                static const SHORTCHAR ELEM = 0x83;    // (* elem store *)
                static const SHORTCHAR NEWLINK = 0x84; // (* link to another non-elem store in same file *)
+
+               Store(INTEGER id);
+
+               INTEGER getId();
+               
+
                /**
                 * PROCEDURE (s: Store) Domain (): Domain
                 * NEW
@@ -87,6 +98,8 @@ namespace odc {
                 * s1 = s       guaranteed
                 */
                // FIXME
+
+               virtual std::string toString() = 0;
        };
 
 }