From: Gert van Valkenhoef Date: Tue, 15 Nov 2011 17:52:36 +0000 (+0000) Subject: Reader split into files X-Git-Url: https://deadsoftware.ru/gitweb?p=odcread.git;a=commitdiff_plain;h=067f77e22bace6d17204e3f1f677dd6a5ca6f563 Reader split into files --- diff --git a/Makefile b/Makefile index 90f9d3d..260da91 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -MODULES := reader store alien typeregister textmodel fold +MODULES := reader store alien typeregister textmodel fold typepath # Add module directories to the include path CFLAGS += -I. diff --git a/reader/Make.inc b/reader/Make.inc index caf7946..6f5e81a 100644 --- a/reader/Make.inc +++ b/reader/Make.inc @@ -1 +1,4 @@ -SRCS += reader/reader.cc reader/util.cc +READER_SRC := addPathComponent.cc fixTypeName.cc readAlien.cc reader.cc \ + readLinkStore.cc readNewLinkStore.cc readNilStore.cc readPath.cc \ + readStore.cc readStoreOrElemStore.cc readVersion.cc util.cc +SRCS += $(patsubst %,reader/%,$(READER_SRC)) diff --git a/reader/addPathComponent.cc b/reader/addPathComponent.cc new file mode 100644 index 0000000..5def034 --- /dev/null +++ b/reader/addPathComponent.cc @@ -0,0 +1,14 @@ +#include "reader/reader.ih" + +namespace odc { + +void Reader::addPathComponent(bool first, const std::string &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 diff --git a/reader/fixTypeName.cc b/reader/fixTypeName.cc new file mode 100644 index 0000000..cc33fe5 --- /dev/null +++ b/reader/fixTypeName.cc @@ -0,0 +1,13 @@ +#include "reader/reader.ih" + +namespace odc { + +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; +} + +} // namespace odc diff --git a/reader/readAlien.cc b/reader/readAlien.cc new file mode 100644 index 0000000..2ccf9f0 --- /dev/null +++ b/reader/readAlien.cc @@ -0,0 +1,23 @@ +#include "reader/reader.ih" + +namespace odc { + +void Reader::readAlien(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) + 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 + d_rider.seekg(next); + AlienComponent *comp = new AlienPart(readStore()); + alien->getComponents().push_back(comp); + next = d_state->next > 0 ? d_state->next : end; + } + } +} + +} // namespace odc diff --git a/reader/readLinkStore.cc b/reader/readLinkStore.cc new file mode 100644 index 0000000..b087189 --- /dev/null +++ b/reader/readLinkStore.cc @@ -0,0 +1,15 @@ + +#include "reader/reader.ih" + +namespace odc { + +Store *Reader::readLinkStore() { + throw "Reader::readLinkStore() not implemented"; +} +// ELSIF kind = link THEN +// rd.ReadInt(id); rd.ReadInt(comment); rd.ReadInt(next); +// rd.st.end := rd.Pos(); +// IF (next > 0) OR ((next = 0) & ODD(comment)) THEN rd.st.next := rd.st.end + next ELSE rd.st.next := 0 END; +// x := ThisStore(rd.eDict, id) + +} // namespace odc diff --git a/reader/readNewLinkStore.cc b/reader/readNewLinkStore.cc new file mode 100644 index 0000000..24f8806 --- /dev/null +++ b/reader/readNewLinkStore.cc @@ -0,0 +1,14 @@ +#include "reader/reader.ih" + +namespace odc { + +Store *Reader::readNewLinkStore() { + throw "Reader::readNewLinkStore() not implemented"; +} +// ELSIF kind = newlink THEN +// rd.ReadInt(id); rd.ReadInt(comment); rd.ReadInt(next); +// rd.st.end := rd.Pos(); +// IF (next > 0) OR ((next = 0) & ODD(comment)) THEN rd.st.next := rd.st.end + next ELSE rd.st.next := 0 END; +// x := ThisStore(rd.sDict, id) + +} // namespace odc diff --git a/reader/readNilStore.cc b/reader/readNilStore.cc new file mode 100644 index 0000000..aa1e4f2 --- /dev/null +++ b/reader/readNilStore.cc @@ -0,0 +1,22 @@ +#include "reader/reader.ih" + +namespace odc { + +Store *Reader::readNilStore() { + INTEGER comment = readInt(); + std::streamoff next = readInt(); + d_state->end = d_rider.tellg(); + if (next > 0 || (next == 0 && comment % 2 == 1)) { + d_state->next = d_state->end + next; + } else { + d_state->next = 0; + } + return 0; +} +// IF kind = nil THEN +// rd.ReadInt(comment); rd.ReadInt(next); +// rd.st.end := rd.Pos(); +// IF (next > 0) OR ((next = 0) & ODD(comment)) THEN rd.st.next := rd.st.end + next ELSE rd.st.next := 0 END; +// x := NIL + +} // namespace odc diff --git a/reader/readPath.cc b/reader/readPath.cc new file mode 100644 index 0000000..397f2ac --- /dev/null +++ b/reader/readPath.cc @@ -0,0 +1,42 @@ +#include "reader/reader.ih" + +namespace odc { + +TypePath Reader::readPath() { + TypePath path; + SHORTCHAR kind = readSChar(); + SHORTCHAR *buf = new SHORTCHAR[64]; // TypeName has a maximum of length 64 (including terminator). + int i; + for (i = 0; kind == Store::NEWEXT; ++i) { + readSString(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); + std::string name(buf); + path.push_back(fixTypeName(name)); + addPathComponent(i == 0, path[i]); + ++i; + } else if (kind == Store::OLDTYPE) { + int id = readInt(); + if (i > 0) { + d_typeList[d_typeList.size() - 1]->baseId = id; + } + while (id != -1) { + path.push_back(d_typeList[id]->name); + id = d_typeList[id]->baseId; +// IF path[i] # elemTName THEN INC(i) END + ++i; + } + } else { + throw 100; + } + return path; +} + +} // namespace odc diff --git a/reader/readStore.cc b/reader/readStore.cc new file mode 100644 index 0000000..1ab921f --- /dev/null +++ b/reader/readStore.cc @@ -0,0 +1,28 @@ +#include "reader/reader.ih" + +namespace odc { + +Store* Reader::readStore() { + SHORTCHAR kind = readSChar(); + if (kind == Store::NIL) { + //std::cout << "NIL STORE" << std::endl; + return readNilStore(); + } else if (kind == Store::LINK) { + //std::cout << "LINK STORE" << std::endl; + return readLinkStore(); + } else if (kind == Store::NEWLINK) { + //std::cout << "NEWLINK STORE" << std::endl; + return readNewLinkStore(); + } else if (kind == Store::STORE) { + //std::cout << "STORE STORE" << std::endl; + return readStoreOrElemStore(false); + } else if (kind == Store::ELEM) { + //std::cout << "ELEM STORE" << std::endl; + return readStoreOrElemStore(true); + } else { + //std::cout << std::hex << (unsigned int)kind << std::endl; + throw 20; + } +} + +} // namespace odc diff --git a/reader/readStoreOrElemStore.cc b/reader/readStoreOrElemStore.cc new file mode 100644 index 0000000..0c89bb3 --- /dev/null +++ b/reader/readStoreOrElemStore.cc @@ -0,0 +1,108 @@ +#include "reader/reader.ih" + +namespace odc { + +Store *Reader::readStoreOrElemStore(bool isElem) { + INTEGER id = isElem ? d_elemList.size() : d_storeList.size(); + TypePath path = readPath(); + //std::cout << path.toString() << std::endl; + const std::string &type = path[0]; + INTEGER comment = readInt(); + 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; + 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); + } else { + 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) + } + if (isElem) { + d_elemList.push_back(x); + } else { + d_storeList.push_back(x); + } + } else { + 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; + } else { + // join(d_store, alien) + } + if (isElem) { + d_elemList.push_back(alien); + } else { + d_storeList.push_back(alien); + } + ReaderState *save = d_state; + d_state = new ReaderState(); + readAlien(alien, downPos, save->end); + delete d_state; + d_state = save; + 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; +} + +} // namespace odc diff --git a/reader/readVersion.cc b/reader/readVersion.cc new file mode 100644 index 0000000..5b13aff --- /dev/null +++ b/reader/readVersion.cc @@ -0,0 +1,13 @@ +#include "reader/reader.ih" + +namespace odc { + +INTEGER Reader::readVersion(INTEGER min, INTEGER max) { + INTEGER version = readByte(); + if (version < min || version > max) { + turnIntoAlien(ALIENVERSION); + } + return version; +} + +} // namespace odc diff --git a/reader/reader.cc b/reader/reader.cc index 9f3402c..1395bba 100644 --- a/reader/reader.cc +++ b/reader/reader.cc @@ -1,8 +1,4 @@ -#include "reader/reader.h" -#include "alien/alien.h" - -#include -#include +#include "reader/reader.ih" namespace odc { @@ -103,251 +99,4 @@ bool Reader::isCancelled() { return d_cancelled; } -INTEGER Reader::readVersion(INTEGER min, INTEGER max) { - INTEGER version = readByte(); - if (version < min || version > max) { - turnIntoAlien(ALIENVERSION); - } - return version; -} - -Store* Reader::readStore() { - SHORTCHAR kind = readSChar(); - if (kind == Store::NIL) { - //std::cout << "NIL STORE" << std::endl; - return readNilStore(); - } else if (kind == Store::LINK) { - //std::cout << "LINK STORE" << std::endl; - return readLinkStore(); - } else if (kind == Store::NEWLINK) { - //std::cout << "NEWLINK STORE" << std::endl; - return readNewLinkStore(); - } else if (kind == Store::STORE) { - //std::cout << "STORE STORE" << std::endl; - return readStoreOrElemStore(false); - } else if (kind == Store::ELEM) { - //std::cout << "ELEM STORE" << std::endl; - return readStoreOrElemStore(true); - } else { - //std::cout << std::hex << (unsigned int)kind << std::endl; - throw 20; - } -} -// PROCEDURE (VAR rd: Reader) ReadStore* (OUT x: Store), NEW; -// VAR a: Alien; t: Kernel.Type; -// len, pos, pos1, id, comment, next, down, downPos, nextTypeId, nextElemId, nextStoreId: INTEGER; -// kind: SHORTCHAR; path: TypePath; type: TypeName; -// save: ReaderState; - -Store *Reader::readNilStore() { - INTEGER comment = readInt(); - std::streamoff next = readInt(); - d_state->end = d_rider.tellg(); - if (next > 0 || (next == 0 && comment % 2 == 1)) { - d_state->next = d_state->end + next; - } else { - d_state->next = 0; - } - return 0; -} -// IF kind = nil THEN -// rd.ReadInt(comment); rd.ReadInt(next); -// rd.st.end := rd.Pos(); -// IF (next > 0) OR ((next = 0) & ODD(comment)) THEN rd.st.next := rd.st.end + next ELSE rd.st.next := 0 END; -// x := NIL - -Store *Reader::readLinkStore() { - throw "Reader::readLinkStore() not implemented"; -} -// ELSIF kind = link THEN -// rd.ReadInt(id); rd.ReadInt(comment); rd.ReadInt(next); -// rd.st.end := rd.Pos(); -// IF (next > 0) OR ((next = 0) & ODD(comment)) THEN rd.st.next := rd.st.end + next ELSE rd.st.next := 0 END; -// x := ThisStore(rd.eDict, id) - -Store *Reader::readNewLinkStore() { - throw "Reader::readNewLinkStore() not implemented"; -} -// ELSIF kind = newlink THEN -// rd.ReadInt(id); rd.ReadInt(comment); rd.ReadInt(next); -// rd.st.end := rd.Pos(); -// IF (next > 0) OR ((next = 0) & ODD(comment)) THEN rd.st.next := rd.st.end + next ELSE rd.st.next := 0 END; -// x := ThisStore(rd.sDict, id) - -Store *Reader::readStoreOrElemStore(bool isElem) { - INTEGER id = isElem ? d_elemList.size() : d_storeList.size(); - TypePath path = readPath(); - //std::cout << path.toString() << std::endl; - const std::string &type = path[0]; - INTEGER comment = readInt(); - 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; - 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); - } else { - 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) - } - if (isElem) { - d_elemList.push_back(x); - } else { - d_storeList.push_back(x); - } - } else { - 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; - } else { - // join(d_store, alien) - } - if (isElem) { - d_elemList.push_back(alien); - } else { - d_storeList.push_back(alien); - } - ReaderState *save = d_state; - d_state = new ReaderState(); - internalizeAlien(alien, downPos, save->end); - delete d_state; - d_state = save; - 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; -} - - -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) - 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 - d_rider.seekg(next); - AlienComponent *comp = new AlienPart(readStore()); - alien->getComponents().push_back(comp); - next = d_state->next > 0 ? d_state->next : end; - } - } -} - -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(); - SHORTCHAR *buf = new SHORTCHAR[64]; // TypeName has a maximum of length 64 (including terminator). - int i; - for (i = 0; kind == Store::NEWEXT; ++i) { - readSString(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); - std::string name(buf); - path.push_back(fixTypeName(name)); - addPathComponent(i == 0, path[i]); - ++i; - } else if (kind == Store::OLDTYPE) { - int id = readInt(); - if (i > 0) { - d_typeList[d_typeList.size() - 1]->baseId = id; - } - while (id != -1) { - path.push_back(d_typeList[id]->name); - id = d_typeList[id]->baseId; -// IF path[i] # elemTName THEN INC(i) END - ++i; - } - } else { - throw 100; - } - return path; -} - -void Reader::addPathComponent(bool first, const std::string &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 diff --git a/reader/reader.h b/reader/reader.h index eb593b5..7c843c1 100644 --- a/reader/reader.h +++ b/reader/reader.h @@ -5,11 +5,13 @@ #include #include "oberon.h" -#include "store/store.h" -#include "alien/alien.h" +#include "typepath/typepath.h" namespace odc { +class Store; +class Alien; + struct TypeEntry { const std::string name; INTEGER baseId; @@ -210,7 +212,7 @@ private: /** * Read an alien store. */ - void internalizeAlien(Alien *alien, std::streampos down, std::streampos end); + void readAlien(Alien *alien, std::streampos down, std::streampos end); /** * Make store name consistent with names found in BlackBox source. diff --git a/reader/reader.ih b/reader/reader.ih new file mode 100644 index 0000000..ce965e8 --- /dev/null +++ b/reader/reader.ih @@ -0,0 +1,7 @@ +#include "reader/reader.h" + +#include "store/store.h" +#include "alien/alien.h" + +#include +#include diff --git a/store/store.cc b/store/store.cc index c85d831..76f0586 100644 --- a/store/store.cc +++ b/store/store.cc @@ -4,27 +4,8 @@ #include - namespace odc { -template T join(const A & begin, const A & end, const T &sep) { - T result; - - if (begin != end) { - A it = begin; - result.append(*it); - for (++it; it != end; ++it) { - result.append(sep).append(*it); - } - } - - return result; -} - -std::string TypePath::toString() const { - return join(begin(), end(), std::string("->")); -} - const std::string Store::TYPENAME("Stores.Store^"); const TopTypeProxy Store::PROXY; diff --git a/store/store.h b/store/store.h index 5743cb0..b21f9f8 100644 --- a/store/store.h +++ b/store/store.h @@ -7,15 +7,11 @@ #include "oberon.h" #include "typeregister/typeregister.h" #include "visitor/visitor.h" +#include "typepath/typepath.h" namespace odc { class Reader; // forward decl - class TypePath : public std::vector { - public: - std::string toString() const; - }; - /** * TYPE Store * ABSTRACT diff --git a/typepath/Make.inc b/typepath/Make.inc new file mode 100644 index 0000000..258f37f --- /dev/null +++ b/typepath/Make.inc @@ -0,0 +1 @@ +SRCS += typepath/toString.cc diff --git a/typepath/toString.cc b/typepath/toString.cc new file mode 100644 index 0000000..dd532b1 --- /dev/null +++ b/typepath/toString.cc @@ -0,0 +1,23 @@ +#include "typepath/typepath.ih" + +namespace odc { + +template T join(const A & begin, const A & end, const T &sep) { + T result; + + if (begin != end) { + A it = begin; + result.append(*it); + for (++it; it != end; ++it) { + result.append(sep).append(*it); + } + } + + return result; +} + +std::string TypePath::toString() const { + return join(begin(), end(), std::string("->")); +} + +} // namespace odc diff --git a/typepath/typepath.h b/typepath/typepath.h new file mode 100644 index 0000000..c5bd027 --- /dev/null +++ b/typepath/typepath.h @@ -0,0 +1,16 @@ +#ifndef _TYPEPATH_H_ +#define _TYPEPATH_H_ + +#include +#include + +namespace odc { + + class TypePath : public std::vector { + public: + std::string toString() const; + }; + +} + +#endif // _TYPEPATH_H_ diff --git a/typepath/typepath.ih b/typepath/typepath.ih new file mode 100644 index 0000000..b20767a --- /dev/null +++ b/typepath/typepath.ih @@ -0,0 +1 @@ +#include "typepath/typepath.h"