DEADSOFTWARE

Add type handling (disabled until StdTextModel.internalize is implemented)
authorGert van Valkenhoef <g.h.m.van.valkenhoef@rug.nl>
Tue, 9 Aug 2011 22:03:13 +0000 (23:03 +0100)
committerGert van Valkenhoef <g.h.m.van.valkenhoef@rug.nl>
Tue, 9 Aug 2011 22:03:13 +0000 (23:03 +0100)
Makefile
odcread.cc
reader.cc
reader.h
store.cc
store.h
typeregister.cc [new file with mode: 0644]
typeregister.h [new file with mode: 0644]

index b3cdd9916856491cfeb60c8dfab498b2348a95d1..1ad67d51ef4708a3a483dab9a454343be7b3618f 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
-HEADERS=oberon.h store.h reader.h domain.h alien.h
+HEADERS=oberon.h store.h reader.h domain.h alien.h typeregister.h
 
-odcread: odcread.o reader.o store.o util.o alien.o
+odcread: odcread.o reader.o store.o util.o alien.o typeregister.o
        g++ -o $@ $^
 
 %.o: %.cc $(HEADERS)
index a6765e913ab97614b3ceb0d877ca21e0b6a1d1fd..e049bb071e7bd90a263bbca7043cb66c930123a2 100644 (file)
@@ -32,5 +32,7 @@ int main(int argc, char *argv[]) {
        odc::Store* s = odc::importDocument(in);
        std::cout << s->toString() << std::endl;
        std::cout << in.tellg() << " " << in.eof() << std::endl;
+
+       std::cout << odc::ContainerModel(0).getTypePath().toString() << std::endl;
        return 0;
 }
index 08bd498f174bbe7167562eff91fb8cd7fae2bd4d..3ccfb7144bae80159e5172977dd3e9f475a55de9 100644 (file)
--- a/reader.cc
+++ b/reader.cc
@@ -14,6 +14,12 @@ SHORTCHAR Reader::readSChar() {
        return out;
 }
 
+BYTE Reader::readByte() {
+       BYTE out;
+       d_rider.read((char*)&out, 1);
+       return out;
+}
+
 INTEGER Reader::readInt() {
        char *buf = new char[4];
        d_rider.read(buf, 4);
@@ -32,6 +38,14 @@ void Reader::readSString(SHORTCHAR *out) {
        }
 }
 
+INTEGER Reader::readVersion(INTEGER min, INTEGER max) {
+       INTEGER version = readByte();
+       //if (version < min || version > max) {
+               //                      rd.TurnIntoAlien(alienVersion)
+       //}
+       return version;
+}
+
 Store* Reader::readStore() {
        SHORTCHAR kind = readSChar();
        if (kind == Store::NIL) {
@@ -118,15 +132,17 @@ Store *Reader::readStoreOrElemStore(bool isElem) {
 //                             ASSERT(downPos < rd.st.end, 105)
 //                     END;
 
-       void *t = 0; // FIXME type lookup here
+       const TypeProxyBase *t = TypeRegister::getInstance().get(type); // FIXME type lookup here
+       Store *x = 0;
        if (t != 0) {
+               x = t->newInstance(id);
+               x->internalize(*this);
 //                             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);
@@ -234,6 +250,14 @@ void Reader::internalizeAlien(Alien *alien, std::streampos down, std::streampos
        }
 }
 
+std::string &Reader::fixTypeName(std::string &name) {
+       size_t pos = name.size() - 4;
+       if (pos > 0 && name.substr(pos, 4).compare("Desc") == 0) {
+               return name.replace(pos, 4, "^");
+       }
+       return name;
+}
+
 TypePath Reader::readPath() {
        TypePath path;
        SHORTCHAR kind = readSChar();
@@ -241,7 +265,8 @@ TypePath Reader::readPath() {
        int i;
        for (i = 0; kind == Store::NEWEXT; ++i) {
                readSString(buf);
-               path.push_back(std::string(buf));
+               std::string name(buf);
+               path.push_back(fixTypeName(name));
                addPathComponent(i == 0, path[i]);
 //                     IF path[i] # elemTName THEN INC(i) END;
                kind = readSChar();
@@ -249,7 +274,8 @@ TypePath Reader::readPath() {
 
        if (kind == Store::NEWBASE) {
                readSString(buf);
-               path.push_back(std::string(buf));
+               std::string name(buf);
+               path.push_back(fixTypeName(name));
                addPathComponent(i == 0, path[i]);
                ++i;
        } else if (kind == Store::OLDTYPE) {
index 764a27618138fa5d4d7f098b04510fff6151964a..e9b0234b4972c403099584334386b9d7cb137b62 100644 (file)
--- a/reader.h
+++ b/reader.h
@@ -135,11 +135,14 @@ private:
         * PROCEDURE (VAR rd: Reader) ReadChar (OUT x: CHAR)
         * NEW
         * Reads a character (0000X..0FFFFX).
-        * 
+        */ 
+       /**
         * PROCEDURE (VAR rd: Reader) ReadByte (OUT x: BYTE)
         * NEW
         * Reads a very short integer (-128..127).
-        * 
+        */ 
+       BYTE readByte();
+       /**
         * PROCEDURE (VAR rd: Reader) ReadSInt (OUT x: SHORTINT)
         * NEW
         * Reads a short integer (-32768..32767).
@@ -244,7 +247,9 @@ private:
         *      rd.cause = alienVersion
         *      rd.cancelled
         *      rd.readAlien
-        * 
+        */ 
+       INTEGER readVersion(INTEGER min, INTEGER max);
+       /*
         * PROCEDURE (VAR rd: Reader) TurnIntoAlien (cause: INTEGER)
         * NEW
         * A store which is currently being internalized can turn itself into an alien, e.g., if it has read a component store which is an alien.
@@ -260,6 +265,7 @@ private:
        Store *readNewLinkStore();
        void internalizeAlien(Alien *alien, std::streampos down, std::streampos end);
        
+       std::string &fixTypeName(std::string &name);
        TypePath readPath();
        /**
         * Add another component to the current path. If first==true, start a new path.
index 82e20e67c7c1e0dac7cb4a1358706e811057af19..fe5fa62c66ac91ad384da4f305c7696bfa600717 100644 (file)
--- a/store.cc
+++ b/store.cc
@@ -1,4 +1,8 @@
 #include <store.h>
+#include <reader.h>
+
+#include <iostream>
+
 
 namespace odc {
 
@@ -20,14 +24,208 @@ std::string TypePath::toString() const {
        return join(begin(), end(), std::string("->"));
 }
 
+const std::string Store::TYPENAME("Stores.Store^");
+const TypeProxy<Store> Store::PROXY;
+TypePath *Store::s_typePath = 0;
+
 Store::Store(INTEGER id): d_id(id) {}
 
 INTEGER Store::getId() {
        return d_id;
 }
 
-Domain* Store::getDomain() {
+const std::string &Store::getType() {
+       return Store::TYPENAME;
+}
+
+const std::string *Store::getSuper() {
        return 0;
 }
 
+const std::string &Store::getTypeName() const {
+       return Store::getType();
+}
+
+const TypePath &Store::getTypePath() const {
+       if (s_typePath == 0) {
+               s_typePath = calcTypePath(getTypeName());
+       }
+       return *s_typePath;
+}
+
+TypePath *Store::calcTypePath(const std::string &name) const {
+       const std::string *super = TypeRegister::getInstance().get(name)->getSuper();
+       TypePath *path;
+       if (super != 0) {
+               path = calcTypePath(*super);
+       } else {
+               path = new TypePath();
+       }
+       path->push_back(name);
+       return path;
+}
+
+void Store::internalize(Reader &reader) {
+       reader.readVersion(0, 0);
+}
+
+std::string Store::toString() {
+       return getTypeName(); 
+}
+
+const std::string Elem::TYPENAME("Stores.Elem^");
+const TypeProxy<Elem> Elem::PROXY;
+
+Elem::Elem(INTEGER id) : Store(id) {}
+
+const std::string &Elem::getType() {
+       return TYPENAME;
+}
+
+const std::string *Elem::getSuper() {
+       return &Store::getType();
+}
+
+const std::string &Elem::getTypeName() const {
+       return getType();
+}
+
+void Elem::internalize(Reader &reader) {
+       Store::internalize(reader); // just being explicit
+}
+
+const std::string Model::TYPENAME("Models.Model^");
+const TypeProxy<Model> Model::PROXY;
+
+Model::Model(INTEGER id) : Elem(id) {}
+
+const std::string &Model::getType() {
+       return TYPENAME;
+}
+
+const std::string *Model::getSuper() {
+       return &Elem::getType();
+}
+
+const std::string &Model::getTypeName() const {
+       return getType();
+}
+
+void Model::internalize(Reader &reader) {
+       Model::internalize(reader);
+       reader.readVersion(0, 0);
 }
+
+const std::string ContainerModel::TYPENAME("Containers.Model^");
+const TypeProxy<ContainerModel> ContainerModel::PROXY;
+
+ContainerModel::ContainerModel(INTEGER id) : Model(id) {}
+
+const std::string &ContainerModel::getType() {
+       return TYPENAME;
+}
+
+const std::string *ContainerModel::getSuper() {
+       return &Model::getType();
+}
+
+const std::string &ContainerModel::getTypeName() const {
+       return getType();
+}
+
+void ContainerModel::internalize(Reader &reader) {
+       Model::internalize(reader);
+       reader.readVersion(0, 0);
+}
+
+const std::string TextModel::TYPENAME("TextModels.Model^");
+const TypeProxy<TextModel> TextModel::PROXY;
+
+TextModel::TextModel(INTEGER id) : ContainerModel(id) {}
+
+const std::string &TextModel::getType() {
+       return TYPENAME;
+}
+
+const std::string *TextModel::getSuper() {
+       return &ContainerModel::getType();
+}
+
+const std::string &TextModel::getTypeName() const {
+       return getType();
+}
+
+void TextModel::internalize(Reader &reader) {
+       ContainerModel::internalize(reader);
+       reader.readVersion(0, 0);
+}
+
+const std::string StdTextModel::TYPENAME("TextModels.StdModel^");
+//const TypeProxy<StdTextModel> StdTextModel::PROXY;
+
+StdTextModel::StdTextModel(INTEGER id) : TextModel(id) {}
+
+const std::string &StdTextModel::getType() {
+       return TYPENAME;
+}
+
+const std::string *StdTextModel::getSuper() {
+       return &TextModel::getType();
+}
+
+const std::string &StdTextModel::getTypeName() const {
+       return getType();
+}
+
+void StdTextModel::internalize(Reader &reader) {
+       TextModel::internalize(reader);
+       reader.readVersion(0, 1);
+
+//     PROCEDURE (t: StdModel) Internalize (VAR rd: Stores.Reader);
+//             VAR u, un: Run; sp: Piece; lp: LPiece; v: ViewRef;
+//                     org, len: INTEGER; ano: BYTE; thisVersion: INTEGER;
+//                     attr: Attributes; dict: AttrDict;
+//     BEGIN
+//             ASSERT(t.Domain() = NIL, 20); ASSERT(t.len = 0, 21);
+//             t.Internalize^(rd); IF rd.cancelled THEN RETURN END;
+//             rd.ReadVersion(minVersion, maxStdModelVersion, thisVersion);
+//             IF rd.cancelled THEN RETURN END;
+//             StdInit(t);
+//             dict.len := 0; u := t.trailer;
+//             rd.ReadInt(len); org := rd.Pos() + len;
+//             rd.ReadByte(ano);
+//             WHILE ano # -1 DO
+//                     IF ano = dict.len THEN
+//                             ReadAttr(rd, attr); Stores.Join(t, attr);
+//                             IF dict.len < dictSize THEN dict.attr[dict.len] := attr; INC(dict.len) END
+//                     ELSE
+//                             attr := dict.attr[ano]
+//                     END;
+//                     rd.ReadInt(len);
+//                     IF len > 0 THEN (* piece *)
+//                             NEW(sp); sp.len := len; sp.attr := attr;
+//                             sp.file := rd.rider.Base(); sp.org := org; un := sp;
+//                             INC(org, len)
+//                     ELSIF len < 0 THEN      (* longchar piece *)
+//                             len := -len; ASSERT(~ODD(len), 100);
+//                             NEW(lp); lp.len := len DIV 2; lp.attr := attr;
+//                             lp.file := rd.rider.Base(); lp.org := org; un := lp;
+//                             INC(org, len)
+//                     ELSE    (* len = 0  =>  embedded view *)
+//                             NEW(v); v.len := 1; v.attr := attr;
+//                             rd.ReadInt(v.w); rd.ReadInt(v.h); Views.ReadView(rd, v.view);
+//                             v.view.InitContext(NewContext(v, t));
+//                             un := v; INC(org)
+//                     END;
+//                     INC(t.len, un.len); u.next := un; un.prev := u; u := un;
+//                     rd.ReadByte(ano)
+//             END;
+//             rd.SetPos(org);
+//             u.next := t.trailer; t.trailer.prev := u
+//     END Internalize;
+//
+}
+
+
+
+} // namespace odc
diff --git a/store.h b/store.h
index 039354d5b5c120737498795f9267a65babea13ca..54438ab4845b72d44b563fa16c1901897b79099a 100644 (file)
--- a/store.h
+++ b/store.h
@@ -3,11 +3,13 @@
 
 #include <oberon.h>
 #include <domain.h>
+#include <typeregister.h>
 
 #include <string>
 #include <vector>
 
 namespace odc {
+       class Reader; // forward decl
 
        class TypePath : public std::vector<std::string> {
                public:
@@ -23,6 +25,10 @@ namespace odc {
         */
        class Store {
        private:
+               static const std::string TYPENAME;
+               static const TypeProxy<Store> PROXY;
+               static TypePath *s_typePath;
+
                INTEGER d_id;
 
        public: 
@@ -39,6 +45,25 @@ namespace odc {
 
                INTEGER getId();
                
+               /**
+                * Get the TypeName of this object.
+                * @see TypeRegister
+                */
+               static const std::string &getType();
+               /**
+                * Get the TypeName of the supertype of this object. Return 0 pointer if no supertype.
+                * @see TypeRegister
+                */
+               static const std::string *getSuper();
+               /**
+                * Get the TypeName for this object.
+                */
+               virtual const std::string &getTypeName() const;
+               /**
+                * Get the TypePath to this object's type.
+                * @see TypePath
+                */
+               const TypePath &getTypePath() const;
 
                /**
                 * PROCEDURE (s: Store) Domain (): Domain
@@ -46,7 +71,7 @@ namespace odc {
                 * A store may be associated with a domain. This is done by the procedure InitDomain, which assigns a domain to the store.
                 * Domain may be called by arbitrary clients.
                 */
-               Domain* getDomain();
+               //Domain* getDomain();
 
                /**
                 * PROCEDURE (s: Store) CopyFrom- (source: Store)
@@ -72,7 +97,7 @@ namespace odc {
                 * source.Domain() = NIL        guaranteed
                 * source is not yet initialized        guaranteed
                 */
-//              void internalize(Reader &reader) {
+                virtual void internalize(Reader &reader);
 //     PROCEDURE (s: Store) Internalize- (VAR rd: Reader), NEW, EXTENSIBLE;
 //             VAR thisVersion: INTEGER;
 //     BEGIN
@@ -105,9 +130,102 @@ namespace odc {
                 */
                // FIXME
 
-               virtual std::string toString() = 0;
+               virtual std::string toString();
+
+               private:
+               TypePath *calcTypePath(const std::string &name) const;
        };
 
+       class Elem : public Store {
+               private:
+               static const std::string TYPENAME;
+               static const TypeProxy<Elem> PROXY;
+
+               public:
+               Elem(INTEGER id);
+               
+               /**
+                * Get the TypeName of this object.
+                * @see TypeRegister
+                */
+               static const std::string &getType();
+               /**
+                * Get the TypeName of the supertype of this object. Return 0 pointer if no supertype.
+                * @see TypeRegister
+                */
+               static const std::string *getSuper();
+               /**
+                * Get the TypeName for this object.
+                */
+               virtual const std::string &getTypeName() const;
+
+               virtual void internalize(Reader &reader);
+       };
+
+       class Model : public Elem {
+               private:
+               static const std::string TYPENAME;
+               static const TypeProxy<Model> PROXY;
+
+               public:
+               Model(INTEGER id);
+               
+               /**
+                * Get the TypeName of this object.
+                * @see TypeRegister
+                */
+               static const std::string &getType();
+               /**
+                * Get the TypeName of the supertype of this object. Return 0 pointer if no supertype.
+                * @see TypeRegister
+                */
+               static const std::string *getSuper();
+               /**
+                * Get the TypeName for this object.
+                */
+               virtual const std::string &getTypeName() const;
+
+               virtual void internalize(Reader &reader);
+       };
+
+       class ContainerModel : public Model {
+               private:
+               static const std::string TYPENAME;
+               static const TypeProxy<ContainerModel> PROXY;
+
+               public:
+               ContainerModel(INTEGER id);
+               static const std::string &getType();
+               static const std::string *getSuper();
+               virtual const std::string &getTypeName() const;
+               virtual void internalize(Reader &reader);
+       };
+
+       class TextModel : public ContainerModel {
+               private:
+               static const std::string TYPENAME;
+               static const TypeProxy<TextModel> PROXY;
+
+               public:
+               TextModel(INTEGER id);
+               static const std::string &getType();
+               static const std::string *getSuper();
+               virtual const std::string &getTypeName() const;
+               virtual void internalize(Reader &reader);
+       };
+
+       class StdTextModel : public TextModel {
+               private:
+               static const std::string TYPENAME;
+               static const TypeProxy<StdTextModel> PROXY;
+
+               public:
+               StdTextModel(INTEGER id);
+               static const std::string &getType();
+               static const std::string *getSuper();
+               virtual const std::string &getTypeName() const;
+               virtual void internalize(Reader &reader);
+       };
 }
 
 #endif // _STORE_H_
diff --git a/typeregister.cc b/typeregister.cc
new file mode 100644 (file)
index 0000000..b2ba566
--- /dev/null
@@ -0,0 +1,30 @@
+#include <typeregister.h>
+
+#include <iostream>
+
+namespace odc {
+
+TypeRegister::TypeRegister(): d_map() {}
+
+TypeRegister *TypeRegister::s_instance = 0;
+
+TypeRegister &TypeRegister::getInstance() {
+       if (s_instance == 0) {
+               s_instance = new TypeRegister();
+       }
+       return *s_instance;
+}
+
+void TypeRegister::add(const std::string &name, TypeProxyBase *proxy) {
+       d_map[name] = proxy;
+}
+
+const TypeProxyBase *TypeRegister::get(const std::string &name) {
+       return d_map[name];
+}
+
+TypeProxyBase::TypeProxyBase(const std::string &name) {
+       TypeRegister::getInstance().add(name, this);
+}
+
+}
diff --git a/typeregister.h b/typeregister.h
new file mode 100644 (file)
index 0000000..d647b5b
--- /dev/null
@@ -0,0 +1,51 @@
+#ifndef _CLASSREGISTER_H_
+#define _CLASSREGISTER_H_
+
+#include <oberon.h>
+#include <map>
+#include <string>
+
+namespace odc {
+       class Store;
+       class TypeProxyBase; // forward declaration
+
+       class TypeRegister {
+               static TypeRegister *s_instance;
+
+               std::map<std::string, TypeProxyBase *> d_map;
+
+               TypeRegister();
+               TypeRegister(const TypeRegister &other); // NI
+               TypeRegister &operator=(const TypeRegister &other); // NI
+
+               public:
+               static TypeRegister &getInstance();
+
+               void add(const std::string &name, TypeProxyBase *proxy);
+               const TypeProxyBase *get(const std::string &name);
+       };
+
+       class TypeProxyBase {
+               public:
+               TypeProxyBase(const std::string &name);
+               virtual const std::string &getName() const = 0;
+               virtual const std::string *getSuper() const = 0;
+               virtual Store *newInstance(INTEGER id) const = 0;
+       };
+
+       template <class T> class TypeProxy : public TypeProxyBase {
+               public:
+               TypeProxy(): TypeProxyBase(T::getType()) {}
+               virtual const std::string &getName() const {
+                       return T::getType();
+               }
+               virtual const std::string *getSuper() const {
+                       return T::getSuper();
+               }
+               virtual Store *newInstance(INTEGER id) const {
+                       return new T(id);
+               }
+       };
+}
+
+#endif // _CLASSREGISTER_H_