DEADSOFTWARE

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