X-Git-Url: https://deadsoftware.ru/gitweb?p=odcread.git;a=blobdiff_plain;f=reader%2Freader.cc;h=1395bba09f9592d5dcf77ca9770838d01d81d536;hp=9f3402ce370f8ee5afba72bbf618bbe7784be963;hb=067f77e22bace6d17204e3f1f677dd6a5ca6f563;hpb=1a28b45a936c8e2033f7d406f93946e90d273e6d 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