summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 32b22b4)
raw | patch | inline | side by side (parent: 32b22b4)
author | Gert van Valkenhoef <g.h.m.van.valkenhoef@rug.nl> | |
Tue, 9 Aug 2011 22:03:13 +0000 (23:03 +0100) | ||
committer | Gert van Valkenhoef <g.h.m.van.valkenhoef@rug.nl> | |
Tue, 9 Aug 2011 22:03:13 +0000 (23:03 +0100) |
Makefile | patch | blob | history | |
odcread.cc | patch | blob | history | |
reader.cc | patch | blob | history | |
reader.h | patch | blob | history | |
store.cc | patch | blob | history | |
store.h | patch | blob | history | |
typeregister.cc | [new file with mode: 0644] | patch | blob |
typeregister.h | [new file with mode: 0644] | patch | blob |
diff --git a/Makefile b/Makefile
index b3cdd9916856491cfeb60c8dfab498b2348a95d1..1ad67d51ef4708a3a483dab9a454343be7b3618f 100644 (file)
--- a/Makefile
+++ b/Makefile
-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)
diff --git a/odcread.cc b/odcread.cc
index a6765e913ab97614b3ceb0d877ca21e0b6a1d1fd..e049bb071e7bd90a263bbca7043cb66c930123a2 100644 (file)
--- a/odcread.cc
+++ b/odcread.cc
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;
}
diff --git a/reader.cc b/reader.cc
index 08bd498f174bbe7167562eff91fb8cd7fae2bd4d..3ccfb7144bae80159e5172977dd3e9f475a55de9 100644 (file)
--- a/reader.cc
+++ b/reader.cc
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);
}
}
+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) {
// 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();
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();
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) {
diff --git a/reader.h b/reader.h
index 764a27618138fa5d4d7f098b04510fff6151964a..e9b0234b4972c403099584334386b9d7cb137b62 100644 (file)
--- a/reader.h
+++ b/reader.h
* 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).
* 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.
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.
diff --git a/store.cc b/store.cc
index 82e20e67c7c1e0dac7cb4a1358706e811057af19..fe5fa62c66ac91ad384da4f305c7696bfa600717 100644 (file)
--- a/store.cc
+++ b/store.cc
#include <store.h>
+#include <reader.h>
+
+#include <iostream>
+
namespace odc {
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
index 039354d5b5c120737498795f9267a65babea13ca..54438ab4845b72d44b563fa16c1901897b79099a 100644 (file)
--- a/store.h
+++ b/store.h
#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:
*/
class Store {
private:
+ static const std::string TYPENAME;
+ static const TypeProxy<Store> PROXY;
+ static TypePath *s_typePath;
+
INTEGER d_id;
public:
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
* 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)
* 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
*/
// 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
--- /dev/null
+++ b/typeregister.cc
@@ -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
--- /dev/null
+++ b/typeregister.h
@@ -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_