summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 252b7a3)
raw | patch | inline | side by side (parent: 252b7a3)
author | Gert van Valkenhoef <g.h.m.van.valkenhoef@rug.nl> | |
Wed, 10 Aug 2011 20:12:41 +0000 (21:12 +0100) | ||
committer | Gert van Valkenhoef <g.h.m.van.valkenhoef@rug.nl> | |
Wed, 10 Aug 2011 20:12:41 +0000 (21:12 +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 | |
textmodel.cc | [new file with mode: 0644] | patch | blob |
textmodel.h | [new file with mode: 0644] | patch | blob |
diff --git a/Makefile b/Makefile
index 1ad67d51ef4708a3a483dab9a454343be7b3618f..c933edc1a60e9aae1f39808e273438968abc6abc 100644 (file)
--- a/Makefile
+++ b/Makefile
HEADERS=oberon.h store.h reader.h domain.h alien.h typeregister.h
-odcread: odcread.o reader.o store.o util.o alien.o typeregister.o
+odcread: odcread.o reader.o store.o util.o alien.o typeregister.o textmodel.o
g++ -o $@ $^
%.o: %.cc $(HEADERS)
diff --git a/odcread.cc b/odcread.cc
index e049bb071e7bd90a263bbca7043cb66c930123a2..c843713451fae3916191777dd283528713841fa7 100644 (file)
--- a/odcread.cc
+++ b/odcread.cc
std::cout << s->toString() << std::endl;
std::cout << in.tellg() << " " << in.eof() << std::endl;
- std::cout << odc::ContainerModel(0).getTypePath().toString() << std::endl;
+ odc::TypePath path;
+ odc::ContainerModel(0).getTypePath(&path);
+ std::cout << path.toString() << std::endl;
return 0;
}
diff --git a/reader.cc b/reader.cc
index 3ccfb7144bae80159e5172977dd3e9f475a55de9..b027bd57299f3347c75b7c87d98c8dbcddc73c37 100644 (file)
--- a/reader.cc
+++ b/reader.cc
#include <alien.h>
#include <string>
+#include <assert.h>
namespace odc {
}
}
+void Reader::turnIntoAlien(int cause) {
+ assert(cause > 0);
+ d_cancelled = true;
+ d_cause = cause;
+ d_readAlien = true;
+}
+
+bool Reader::isCancelled() {
+ return d_cancelled;
+}
+
INTEGER Reader::readVersion(INTEGER min, INTEGER max) {
INTEGER version = readByte();
- //if (version < min || version > max) {
- // rd.TurnIntoAlien(alienVersion)
- //}
+ if (version < min || version > max) {
+ turnIntoAlien(ALIENVERSION);
+ }
return version;
}
std::cout << "ELEM STORE" << std::endl;
return readStoreOrElemStore(true);
} else {
+ std::cout << std::hex << (unsigned int)kind << std::endl;
throw 20;
}
}
}
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);
-// IF down # 0 THEN
-// ASSERT(downPos < rd.st.next, 103)
-// END
-// END;
-// IF down # 0 THEN
-// ASSERT(downPos > pos1, 104);
-// ASSERT(downPos < rd.st.end, 105)
-// END;
+ assert(len >= 0);
+ if (next != 0) {
+ assert(d_state->next > pos1);
+ if (down != 0) {
+ assert(downPos < d_state->next);
+ }
+ }
+ if (down > 0) {
+ assert(downPos > pos1);
+ assert(downPos < d_state->end);
+ }
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
+ d_cause = TYPENOTFOUND;
}
if (x != 0) { // IF READING SUCCEEDS, INSERT MORE CHECKS HERE
+ if (true) { // samePath(x, path)
+ ReaderState *save = d_state;
+ d_state = new ReaderState();
+ x->internalize(*this);
+ delete d_state;
+ d_state = save;
+
+ if (d_cause != 0) {
+ x = 0;
+ }
+ assert(d_rider.tellg() == d_state->end);
+ assert(!d_rider.eof());
+ } else {
+// rd.cause := inconsistentType; AlienTypeReport(rd.cause, type);
+ x = 0;
+ }
+ }
+
+ if (x != 0) {
+ if (d_store == 0) {
+ d_store = x;
+ } else {
+ // join(d_store, x)
+ std::cout << "Man, should have written join(.,.)" << std::endl;
+ }
+ if (isElem) {
+ d_elemList.push_back(x);
+ } else {
+ d_storeList.push_back(x);
+ }
} else {
-// rd.SetPos(pos);
-// ASSERT(rd.cause # 0, 107);
+ d_rider.seekg(pos); // x->internalize() could have left us anywhere
+ assert(d_cause != 0);
Alien *alien = new Alien(id, path); //, d_cause); //,file
if (d_store == 0) {
d_store = alien;
d_storeList.push_back(alien);
}
ReaderState *save = d_state;
-// rd.nextTypeId := nextTypeId; rd.nextElemId := nextElemId; rd.nextStoreId := nextStoreId;
+ d_state = new ReaderState();
internalizeAlien(alien, downPos, save->end);
+ delete d_state;
d_state = save;
-// ASSERT(rd.Pos() = rd.st.end, 108);
-// rd.cause := 0; rd.cancelled := FALSE; rd.readAlien := TRUE
+ assert(d_rider.tellg() == d_state->end);
+
+ // we've just read the alien, so reset the state
+ d_cause = 0;
+ d_cancelled = false;
+ d_readAlien = true;
return alien;
}
return x;
}
-// t := ThisType(type);
-// IF t # NIL THEN
-// x := NewStore(t); x.isElem := kind = elem
-// ELSE
-// rd.cause := thisTypeRes; AlienTypeReport(rd.cause, type);
-// x := NIL
-// END;
-// IF x # NIL THEN
-// IF SamePath(t, path) THEN
-// IF kind = elem THEN
-// x.id := id; AddStore(rd.eDict, rd.eHead, x)
-// ELSE
-// x.id := id; AddStore(rd.sDict, rd.sHead, x)
-// END;
-// save := rd.st; rd.cause := 0; rd.cancelled := FALSE;
-// x.Internalize(rd);
-// rd.st := save;
-// IF rd.cause # 0 THEN x := NIL
-// ELSIF (rd.Pos() # rd.st.end) OR rd.rider.eof THEN
-// rd.cause := inconsistentVersion; AlienReport(rd.cause);
-// x := NIL
-// END
-// ELSE
-// rd.cause := inconsistentType; AlienTypeReport(rd.cause, type);
-// x := NIL
-// END
-// END;
-//
-// IF x # NIL THEN
-// IF rd.noDomain THEN
-// rd.store := x;
-// rd.noDomain := FALSE
-// ELSE
-// Join(rd.store, x)
-// END
-// ELSE (* x is an alien *)
-// rd.SetPos(pos);
-// ASSERT(rd.cause # 0, 107);
-// NEW(a); a.path := path; a.cause := rd.cause; a.file := rd.rider.Base();
-// IF rd.noDomain THEN
-// rd.store := a;
-// rd.noDomain := FALSE
-// ELSE
-// Join(rd.store, a)
-// END;
-// IF kind = elem THEN
-// a.id := id; AddStore(rd.eDict, rd.eHead, a)
-// ELSE
-// a.id := id; AddStore(rd.sDict, rd.sHead, a)
-// END;
-// save := rd.st;
-// rd.nextTypeId := nextTypeId; rd.nextElemId := nextElemId; rd.nextStoreId := nextStoreId;
-// InternalizeAlien(rd, a.comps, downPos, pos, len);
-// rd.st := save;
-// x := a;
-// ASSERT(rd.Pos() = rd.st.end, 108);
-// rd.cause := 0; rd.cancelled := FALSE; rd.readAlien := TRUE
-// END
void Reader::internalizeAlien(Alien *alien, std::streampos down, std::streampos end) {
diff --git a/reader.h b/reader.h
index e9b0234b4972c403099584334386b9d7cb137b62..b4f475ca725bceff119d4f2bd790171995d4bd56 100644 (file)
--- a/reader.h
+++ b/reader.h
*/
class Reader {
private:
+ static const unsigned int TYPENOTFOUND = 1;
+ static const unsigned int ALIENVERSION = 2;
+
/*
* rider-: Files.Reader
* The file rider which links a Reader to a file.
/*
* cancelled-: BOOLEAN valid during a Store.Internalize call
- * Tells whether the currently executing Internalize has been called by ReadVersion or TurnIntoAlien.
+ * Tells whether the currently executing Internalize has been cancelled by ReadVersion or TurnIntoAlien.
*/
bool d_cancelled;
*/
bool d_readAlien;
+ /**
+ * Cause of current read being alien.
+ */
+ unsigned int d_cause;
+
std::vector<TypeEntry*> d_typeList;
std::vector<Store*> d_elemList; // FIXME: WTH, why are these different?
};
ReaderState *d_state;
- INTEGER d_cause;
-
public:
/**
* Construct a reader from the istream rider.
* Pre
* 20 cause > 0
*/
+ void turnIntoAlien(int cause);
+
+ bool isCancelled();
private:
Store *readStoreOrElemStore(bool isElem);
diff --git a/store.cc b/store.cc
index ba0842508d6bf15218d54ce4f6c54a84748c529d..c2fd5b4d8696e62da10f8b04b6d4e08488a2a003 100644 (file)
--- a/store.cc
+++ b/store.cc
const std::string Store::TYPENAME("Stores.Store^");
const TypeProxy<Store> Store::PROXY;
-TypePath *Store::s_typePath = 0;
Store::Store(INTEGER id): d_id(id) {}
return Store::getType();
}
-const TypePath &Store::getTypePath() const {
- if (s_typePath == 0) {
- s_typePath = calcTypePath(getTypeName());
- }
- return *s_typePath;
+void Store::getTypePath(TypePath *out) const {
+ return calcTypePath(out, getTypeName());
}
-TypePath *Store::calcTypePath(const std::string &name) const {
+void Store::calcTypePath(TypePath *path, 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();
+ calcTypePath(path, *super);
}
path->push_back(name);
- return path;
}
void Store::internalize(Reader &reader) {
}
void Elem::internalize(Reader &reader) {
- Store::internalize(reader); // just being explicit
+ Store::internalize(reader);
+ if (reader.isCancelled()) return;
+ reader.readVersion(0, 0);
}
const std::string Model::TYPENAME("Models.Model^");
void Model::internalize(Reader &reader) {
Elem::internalize(reader);
+ if (reader.isCancelled()) return;
reader.readVersion(0, 0);
}
void ContainerModel::internalize(Reader &reader) {
Model::internalize(reader);
+ if (reader.isCancelled()) return;
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 54438ab4845b72d44b563fa16c1901897b79099a..da8434060bf2af7999e2440fb45e85fb33efaef6 100644 (file)
--- a/store.h
+++ b/store.h
private:
static const std::string TYPENAME;
static const TypeProxy<Store> PROXY;
- static TypePath *s_typePath;
INTEGER d_id;
* Get the TypePath to this object's type.
* @see TypePath
*/
- const TypePath &getTypePath() const;
+ void getTypePath(TypePath *path) const;
/**
* PROCEDURE (s: Store) Domain (): Domain
virtual std::string toString();
private:
- TypePath *calcTypePath(const std::string &name) const;
+ void calcTypePath(TypePath * out, const std::string &name) const;
};
class Elem : public Store {
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/textmodel.cc b/textmodel.cc
--- /dev/null
+++ b/textmodel.cc
@@ -0,0 +1,138 @@
+#include <textmodel.h>
+#include <reader.h>
+
+#include <vector>
+
+namespace odc {
+
+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);
+ if (reader.isCancelled()) return;
+ 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();
+}
+
+/*
+ * This is my current theory of how the StdTextModel storage format works:
+ * byte 0: version
+ * byte 1-5: len (length of piece descriptions)
+ * byte 6-5+len: piece descriptions
+ * byte 6+len-end: pieces (length of each defined in piece descriptions)
+ */
+void StdTextModel::internalize(Reader &reader) {
+ TextModel::internalize(reader);
+ if (reader.isCancelled()) return;
+ reader.readVersion(0, 1);
+ if (reader.isCancelled()) return;
+
+ std::vector<Store *> dict;
+ INTEGER len = reader.readInt();
+ BYTE ano = reader.readByte();
+ std::cout << "len " << len << " ano " << (int)ano << std::endl;
+ while (ano != -1) {
+ if (ano == dict.size()) {
+ Store *attr = reader.readStore(); // readAttributes(); Stores.Join(t, attr)
+ dict.push_back(attr);
+ }
+ INTEGER pieceLen = reader.readInt();
+ if (pieceLen > 0) { // shortchar piece
+ std::cout << "Found SChar piece" << std::endl;
+// NEW(sp); sp.len := len; sp.attr := attr;
+// sp.file := rd.rider.Base(); sp.org := org; un := sp;
+// INC(org, len) -- increment org by len ?
+ } else if (pieceLen < 0) { // longchar piece
+ std::cout << "Found LChar piece" << std::endl;
+// 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) -- increment org by len ?
+ } else { // embedded view
+ reader.readInt(); reader.readInt();
+ Store *view = reader.readStore(); // fixme: save somewhere
+// 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) -- increment org by one?? WTH?
+ }
+ ano = reader.readByte();
+ }
+// rd.SetPos(org);
+}
+// 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/textmodel.h b/textmodel.h
--- /dev/null
+++ b/textmodel.h
@@ -0,0 +1,38 @@
+#ifndef _TEXTMODEL_H_
+#define _TEXTMODEL_H_
+
+#include <oberon.h>
+#include <typeregister.h>
+#include <store.h>
+
+namespace odc {
+
+ 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);
+ };
+
+} // namespace odc
+
+#endif // _TEXTMODEL_H_