From 75b3c194e9b084d81f69759d7de71d60f3fde3e1 Mon Sep 17 00:00:00 2001 From: Gert van Valkenhoef Date: Wed, 9 Nov 2011 20:07:21 +0000 Subject: [PATCH] Document reader.h and some cleanup of reader.cc --- reader.cc | 15 +-- reader.h | 269 +++++++++++++++++++++--------------------------------- 2 files changed, 114 insertions(+), 170 deletions(-) diff --git a/reader.cc b/reader.cc index 21cef1d..14b3b0c 100644 --- a/reader.cc +++ b/reader.cc @@ -133,6 +133,7 @@ Store* Reader::readStore() { // 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(); @@ -149,16 +150,18 @@ Store *Reader::readNilStore() { // 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() { - return 0; + 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() { - return 0; + throw "Reader::readNewLinkStore() not implemented"; } // ELSIF kind = newlink THEN // rd.ReadInt(id); rd.ReadInt(comment); rd.ReadInt(next); @@ -232,7 +235,8 @@ Store *Reader::readStoreOrElemStore(bool isElem) { d_store = x; } else { // join(d_store, x) - //std::cout << "Man, should have written join(.,.)" << std::endl; + // I have no idea what this would actually mean if it happened. + throw "Joining of stores not implemented"; } if (isElem) { d_elemList.push_back(x); @@ -247,7 +251,8 @@ Store *Reader::readStoreOrElemStore(bool isElem) { d_store = alien; } else { // join(d_store, alien) - //std::cout << "Man, should have written join(.,.)" << std::endl; + // I have no idea what this would actually mean if it happened. + throw "Joining of stores not implemented"; } if (isElem) { d_elemList.push_back(alien); @@ -276,14 +281,12 @@ void Reader::internalizeAlien(Alien *alien, std::streampos down, std::streampos 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) - //std::cout << "Alien Piece" << std::endl; 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 - //std::cout << "Alien Store" << std::endl; d_rider.seekg(next); AlienComponent *comp = new AlienPart(readStore()); alien->getComponents().push_back(comp); diff --git a/reader.h b/reader.h index 136fb47..e59f36c 100644 --- a/reader.h +++ b/reader.h @@ -18,46 +18,63 @@ struct TypeEntry { }; /** - * TYPE Reader - * Reader for Component Pascal values like integers, reals, or sets. A reader contains a Files.Reader, to which it forwards most operations. - * Readers are used in the Store.Internalize procedure. - * Readers are not extensible. + * Used by Store.internalize() to read from file. */ class Reader { private: + /** + * The store was read as an Alien because its type is not registered. + * @see TypeRegister. + */ static const unsigned int TYPENOTFOUND = 1; + /** + * The store was read as an Alien because its version is not in the accepted range. + */ static const unsigned int ALIENVERSION = 2; - /* - * rider-: Files.Reader - * The file rider which links a Reader to a file. + /** + * The input stream associated with this reader. */ std::istream &d_rider; - /* - * cancelled-: BOOLEAN valid during a Store.Internalize call - * Tells whether the currently executing Internalize has been cancelled by ReadVersion or TurnIntoAlien. + /** + * Whether the currently executing Store.internalize() has been cancelled. + * If so, it will be read as an Alien. */ bool d_cancelled; /** - * readAlien-: BOOLEAN - * Tells whether any alien has been read since the last ConnectTo. + * Cause of current read being an Alien. */ - bool d_readAlien; + unsigned int d_cause; /** - * Cause of current read being alien. + * Whether any alien has been read from the input stream. */ - unsigned int d_cause; + bool d_readAlien; + /** + * The TypeList should be used for consistency checking on type paths. + * Currently unused. + */ std::vector d_typeList; - std::vector d_elemList; // FIXME: WTH, why are these different? + /** + * List of stores that have been read already, to enable repeated occurences + * of a single store to reference them. + * Elem type stores have IDs that are separate from the IDs of other stores. + */ + std::vector d_elemList; + /** + * List of stores that have been read already, to enable repeated occurences + * of a single store to reference them. + * Elem type stores have IDs that are separate from the IDs of other stores. + */ std::vector d_storeList; - Store *d_store; - + /** + * Stores the reader state so that we can rewind a failed Store.internalize(). + */ struct ReaderState { /** * Position of the next store in the current level @@ -68,6 +85,15 @@ private: */ std::streampos end; }; + + /** + * The store that is currently being read. + */ + Store *d_store; + + /** + * Reader state at the start of reading the current store (before calling Store.internalize()).... + */ ReaderState *d_state; public: @@ -77,208 +103,123 @@ private: */ Reader(std::istream &rider); - /** - * PROCEDURE (VAR rd: Reader) ConnectTo (f: Files.File) + /* Omitted reading methods: + * + * There are a number of ReadX* methods that read a SHORT type but return a LONG type. Those have been omitted. + * + * PROCEDURE (VAR rd: Reader) ReadBool (OUT x: BOOLEAN) * NEW - * Connect the reader to a file. All the following operations require connected readers, i.e., rd.rider # NIL. This precondition is not checked explicitly, however. After connecting, the reader's position is at the beginning of the file. If the same reader should be reused on another file, it must first be closed, by connecting it to NIL. - * ConnectTo is used internally. - * - * Pre - * 20 (f = NIL) OR (rd.rider = NIL) - * - * Post - * f = NIL - * rd.rider = NIL - * f # NIL - * (rd.rider # NIL) & (rd.rider.Base() = f) - * rd.Pos() = 0 - */ - // FIXME - - /** - * PROCEDURE (VAR rd: Reader) Pos (): INTEGER + * Reads a Boolean value. + * + * PROCEDURE (VAR rd: Reader) ReadLong (OUT x: LONGINT) * NEW - * Returns the reader's current position. + * Reads a long integer (-9223372036854775808..9223372036854775807). * - * Post - * 0 <= result <= rd.rider.Base().Length() - */ - // FIXME - - /** - * PROCEDURE (VAR rd: Reader) SetPos (pos: INTEGER) + * PROCEDURE (VAR rd: Reader) ReadSReal (OUT x: SHORTREAL) * NEW - * Sets the reader's current position to pos. + * Reads a short real (32-bit IEEE number). * - * Pre - * 20 pos >= 0 - * 21 pos <= rd.rider.Base().Length() + * PROCEDURE (VAR rd: Reader) ReadReal (OUT x: REAL) + * NEW + * Reads a real (64-bit IEEE number). * - * Post - * rd.Pos() = pos - * ~rd.rider.eof - */ - // FIXME - - /** - * PROCEDURE (VAR rd: Reader) ReadBool (OUT x: BOOLEAN) + * PROCEDURE (VAR rd: Reader) ReadSet (OUT x: SET) * NEW - * Reads a Boolean value. + * Reads a set (32 elements). + * + * PROCEDURE (VAR rd: Reader) ReadString (OUT x: ARRAY OF CHAR) + * NEW + * Reads a 0X-terminated string. */ /** - * PROCEDURE (VAR rd: Reader) ReadSChar (OUT x: SHORTCHAR) - * NEW * Reads a short character (00X..0FFX). */ SHORTCHAR readSChar(); + /** + * Reads a string of short characters (00X..0FFX). + */ void readSChar(SHORTCHAR *buf, size_t len); - /* PROCEDURE (VAR rd: Reader) ReadXChar (OUT x: CHAR) - * NEW - * Same as ReadSChar, but has a CHAR-type parameter. - * This procedure is provided to simplify migration from Release 1.2 to 1.3. - */ /** - * PROCEDURE (VAR rd: Reader) ReadChar (OUT x: CHAR) - * NEW * Reads a character (0000X..0FFFFX). */ CHAR readLChar(); + /** + * Reads a string of characters (0000X..0FFFFX). + */ void readLChar(CHAR *buf, size_t len); /** - * 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). */ SHORTINT readSInt(); - /** - * PROCEDURE (VAR rd: Reader) ReadXInt (OUT x: INTEGER) - * NEW - * Same as ReadSInt, but has an INTEGER-type parameter. - * This procedure is provided to simplify migration from Release 1.2 to 1.3. - */ - /** - * PROCEDURE (VAR rd: Reader) ReadInt (OUT x: INTEGER) - * NEW * Reads an integer (-2147483648..2147483647). */ INTEGER readInt(); - /* - * PROCEDURE (VAR rd: Reader) ReadLong (OUT x: LONGINT) - * NEW - * Reads a long integer (-9223372036854775808..9223372036854775807). - * - * PROCEDURE (VAR rd: Reader) ReadSReal (OUT x: SHORTREAL) - * NEW - * Reads a short real (32-bit IEEE number). - * - * PROCEDURE (VAR rd: Reader) ReadXReal (OUT x: REAL) - * NEW - * Same as ReadSReal, but has a REAL-type parameter. - * This procedure is provided to simplify migration from Release 1.2 to 1.3. - * - * PROCEDURE (VAR rd: Reader) ReadReal (OUT x: REAL) - * NEW - * Reads a real (64-bit IEEE number). - * - * PROCEDURE (VAR rd: Reader) ReadSet (OUT x: SET) - * NEW - * Reads a set (32 elements). - */ /** - * PROCEDURE (VAR rd: Reader) ReadSString (OUT x: ARRAY OF SHORTCHAR) - * NEW * Reads a 0X-terminated short string. - * - * Pre - * invalid index LEN(x) > Length(string) + * Used to read string that have a known maximum length. */ void readSString(SHORTCHAR *out); /** - * PROCEDURE (VAR rd: Reader) ReadXString (OUT x: ARRAY OF CHAR) - * NEW - * Same as ReadSString, but has a string-type parameter. - * This procedure is provided to simplify migration from Release 1.2 to 1.3. - */ - //void readXString(CHAR *out); - /** - * PROCEDURE (VAR rd: Reader) ReadString (OUT x: ARRAY OF CHAR) - * NEW - * Reads a 0X-terminated string. - * - * Pre - * invalid index LEN(x) > Length(string) - * - * PROCEDURE (VAR rd: Reader) ReadStore (OUT x: Store) - * NEW + * (Explanation from the BlackBox source.) * Reads a store's type, allocates it, and then reads its contents, by calling the store's Internalize procedure. x may also be NIL, or an alien if the store's module cannot be loaded, or if internalization has been cancelled by the Internalize procedure. * If the store has already been read in, a pointer to the same store is returned instead of allocating a new one. This means that arbitrary graphs that have been written with WriteStore are reconstructed correctly, including alias pointers to the same store, cycles, etc. * If the file on which the reader operates does not contain correct input, then an assertion trap will be caused (traps 101 to trap 106). - * - * Pre - * 20 the reader is at the start position of a new store - * - * Post - * empty store on file - * x = NIL - * non-empty store on file - * x # NIL - * x IS Alien - * x.cause # 0 - * x.type # "" - * x.file # NIL - * x.pos >= 0 beginning of store's data - * x.len >= 0 length of store's data - * alien store contents are on x.file in the range [x.pos .. x.pos + x.len[. - * These data include only the store's contents, not its prefix - * ~(x IS Alien) - * x was read successfully */ Store *readStore(); /** - * PROCEDURE (VAR rd: Reader) ReadVersion (min, max: INTEGER; OUT version: INTEGER) - * NEW - * Read a version byte and return it in version. If version is not in the specified range [min .. max], the store currently being read is turned into an alien, with cause = alienVersion. - * - * Pre - * 20 0 <= min <= max - * - * Post - * min <= version <= max - * legal version - * (version < min) OR (version > max) - * illegal version - * rd.cause = alienVersion - * rd.cancelled - * rd.readAlien + * (Explanation from the BlackBox source.) + * Read a version byte and return it in version. If version is not in the + * specified range [min .. max], the store currently being read is turned + * into an alien, with cause = alienVersion. */ 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. - * - * Pre - * 20 cause > 0 + /** + * (Explanation from the BlackBox source.) + * 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. */ void turnIntoAlien(int cause); + /** + * @return Whether the current read has been cancelled. + */ bool isCancelled(); private: + /** + * Read a store. + */ Store *readStoreOrElemStore(bool isElem); + /** + * Read a Nil store. A Nil store doesn't contain anything, but may require us to skip some bytes. + */ Store *readNilStore(); + /** + * Read a link to an Elem-type store. + */ Store *readLinkStore(); + /** + * Read a link to a non-Elem-type store. + */ Store *readNewLinkStore(); + /** + * Read an alien store. + */ void internalizeAlien(Alien *alien, std::streampos down, std::streampos end); + /** + * Make store name consistent with names found in BlackBox source. + */ std::string &fixTypeName(std::string &name); + + /** + * Read a type path. + */ TypePath readPath(); /** * Add another component to the current path. If first==true, start a new path. -- 2.29.2