DEADSOFTWARE

Testing odcread against a bunch of existing .odc files
[odcread.git] / reader.h
1 #ifndef _READER_H_
2 #define _READER_H_
4 #include <iostream>
5 #include <vector>
7 #include <oberon.h>
8 #include <store.h>
9 #include <alien.h>
11 namespace odc {
13 struct TypeEntry {
14 const std::string name;
15 INTEGER baseId;
17 TypeEntry(const std::string &typeName) : name(typeName), baseId(-1) {}
18 };
20 /**
21 * Used by Store.internalize() to read from file.
22 */
23 class Reader {
24 private:
25 /**
26 * The store was read as an Alien because its type is not registered.
27 * @see TypeRegister.
28 */
29 static const unsigned int TYPENOTFOUND = 1;
30 /**
31 * The store was read as an Alien because its version is not in the accepted range.
32 */
33 static const unsigned int ALIENVERSION = 2;
35 /**
36 * The input stream associated with this reader.
37 */
38 std::istream &d_rider;
40 /**
41 * Whether the currently executing Store.internalize() has been cancelled.
42 * If so, it will be read as an Alien.
43 */
44 bool d_cancelled;
46 /**
47 * Cause of current read being an Alien.
48 */
49 unsigned int d_cause;
51 /**
52 * Whether any alien has been read from the input stream.
53 */
54 bool d_readAlien;
56 /**
57 * The TypeList should be used for consistency checking on type paths.
58 * Currently unused.
59 */
60 std::vector<TypeEntry*> d_typeList;
62 /**
63 * List of stores that have been read already, to enable repeated occurences
64 * of a single store to reference them.
65 * Elem type stores have IDs that are separate from the IDs of other stores.
66 */
67 std::vector<Store*> d_elemList;
68 /**
69 * List of stores that have been read already, to enable repeated occurences
70 * of a single store to reference them.
71 * Elem type stores have IDs that are separate from the IDs of other stores.
72 */
73 std::vector<Store*> d_storeList;
75 /**
76 * Stores the reader state so that we can rewind a failed Store.internalize().
77 */
78 struct ReaderState {
79 /**
80 * Position of the next store in the current level
81 */
82 std::streampos next;
83 /**
84 * Position just after the last read store
85 */
86 std::streampos end;
87 };
89 /**
90 * The store that is currently being read.
91 */
92 Store *d_store;
94 /**
95 * Reader state at the start of reading the current store (before calling Store.internalize())....
96 */
97 ReaderState *d_state;
99 public:
100 /**
101 * Construct a reader from the istream rider.
102 * @param rider An istream (binary mode).
103 */
104 Reader(std::istream &rider);
106 /* Omitted reading methods:
108 * There are a number of ReadX* methods that read a SHORT type but return a LONG type. Those have been omitted.
110 * PROCEDURE (VAR rd: Reader) ReadBool (OUT x: BOOLEAN)
111 * NEW
112 * Reads a Boolean value.
114 * PROCEDURE (VAR rd: Reader) ReadLong (OUT x: LONGINT)
115 * NEW
116 * Reads a long integer (-9223372036854775808..9223372036854775807).
117 *
118 * PROCEDURE (VAR rd: Reader) ReadSReal (OUT x: SHORTREAL)
119 * NEW
120 * Reads a short real (32-bit IEEE number).
121 *
122 * PROCEDURE (VAR rd: Reader) ReadReal (OUT x: REAL)
123 * NEW
124 * Reads a real (64-bit IEEE number).
125 *
126 * PROCEDURE (VAR rd: Reader) ReadSet (OUT x: SET)
127 * NEW
128 * Reads a set (32 elements).
130 * PROCEDURE (VAR rd: Reader) ReadString (OUT x: ARRAY OF CHAR)
131 * NEW
132 * Reads a 0X-terminated string.
133 */
134 /**
135 * Reads a short character (00X..0FFX).
136 */
137 SHORTCHAR readSChar();
138 /**
139 * Reads a string of short characters (00X..0FFX).
140 */
141 void readSChar(SHORTCHAR *buf, size_t len);
142 /**
143 * Reads a character (0000X..0FFFFX).
144 */
145 CHAR readLChar();
146 /**
147 * Reads a string of characters (0000X..0FFFFX).
148 */
149 void readLChar(CHAR *buf, size_t len);
150 /**
151 * Reads a very short integer (-128..127).
152 */
153 BYTE readByte();
154 /**
155 * Reads a short integer (-32768..32767).
156 */
157 SHORTINT readSInt();
158 /**
159 * Reads an integer (-2147483648..2147483647).
160 */
161 INTEGER readInt();
162 /**
163 * Reads a 0X-terminated short string.
164 * Used to read string that have a known maximum length.
165 */
166 void readSString(SHORTCHAR *out);
167 /**
168 * (Explanation from the BlackBox source.)
169 * 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.
170 * 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.
171 * 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).
172 */
173 Store *readStore();
174 /**
175 * (Explanation from the BlackBox source.)
176 * Read a version byte and return it in version. If version is not in the
177 * specified range [min .. max], the store currently being read is turned
178 * into an alien, with cause = alienVersion.
179 */
180 INTEGER readVersion(INTEGER min, INTEGER max);
181 /**
182 * (Explanation from the BlackBox source.)
183 * A store which is currently being internalized can turn itself into an
184 * alien, e.g., if it has read a component store which is an alien.
185 */
186 void turnIntoAlien(int cause);
188 /**
189 * @return Whether the current read has been cancelled.
190 */
191 bool isCancelled();
193 private:
194 /**
195 * Read a store.
196 */
197 Store *readStoreOrElemStore(bool isElem);
198 /**
199 * Read a Nil store. A Nil store doesn't contain anything, but may require us to skip some bytes.
200 */
201 Store *readNilStore();
202 /**
203 * Read a link to an Elem-type store.
204 */
205 Store *readLinkStore();
206 /**
207 * Read a link to a non-Elem-type store.
208 */
209 Store *readNewLinkStore();
210 /**
211 * Read an alien store.
212 */
213 void internalizeAlien(Alien *alien, std::streampos down, std::streampos end);
215 /**
216 * Make store name consistent with names found in BlackBox source.
217 */
218 std::string &fixTypeName(std::string &name);
220 /**
221 * Read a type path.
222 */
223 TypePath readPath();
224 /**
225 * Add another component to the current path. If first==true, start a new path.
226 */
227 void addPathComponent(bool first, const std::string &typeName);
228 };
230 } // namespace odc
232 #endif // _READER_H_