DEADSOFTWARE

Solve oldType path lookup, found SEGFAULT
[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 class TypeEntry {
14 public:
15 SHORTCHAR *name;
16 INTEGER baseId;
18 TypeEntry(SHORTCHAR *typeName) : name(typeName), baseId(-1) {}
19 };
21 /**
22 * TYPE Reader
23 * Reader for Component Pascal values like integers, reals, or sets. A reader contains a Files.Reader, to which it forwards most operations.
24 * Readers are used in the Store.Internalize procedure.
25 * Readers are not extensible.
26 */
27 class Reader {
28 private:
29 /*
30 * rider-: Files.Reader
31 * The file rider which links a Reader to a file.
32 */
33 std::istream &d_rider;
35 /*
36 * cancelled-: BOOLEAN valid during a Store.Internalize call
37 * Tells whether the currently executing Internalize has been called by ReadVersion or TurnIntoAlien.
38 */
39 bool d_cancelled;
41 /**
42 * readAlien-: BOOLEAN
43 * Tells whether any alien has been read since the last ConnectTo.
44 */
45 bool d_readAlien;
47 std::vector<TypeEntry*> d_typeList;
49 std::vector<Store*> d_elemList; // FIXME: WTH, why are these different?
50 std::vector<Store*> d_storeList;
52 Store *d_store;
54 struct ReaderState {
55 /**
56 * Position of the next store in the current level
57 */
58 std::streampos next;
59 /**
60 * Position just after the last read store
61 */
62 std::streampos end;
63 };
64 ReaderState *d_state;
66 INTEGER d_cause;
68 public:
69 /**
70 * Construct a reader from the istream rider.
71 * @param rider An istream (binary mode).
72 */
73 Reader(std::istream &rider);
75 /**
76 * PROCEDURE (VAR rd: Reader) ConnectTo (f: Files.File)
77 * NEW
78 * 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.
79 * ConnectTo is used internally.
80 *
81 * Pre
82 * 20 (f = NIL) OR (rd.rider = NIL)
83 *
84 * Post
85 * f = NIL
86 * rd.rider = NIL
87 * f # NIL
88 * (rd.rider # NIL) & (rd.rider.Base() = f)
89 * rd.Pos() = 0
90 */
91 // FIXME
93 /**
94 * PROCEDURE (VAR rd: Reader) Pos (): INTEGER
95 * NEW
96 * Returns the reader's current position.
97 *
98 * Post
99 * 0 <= result <= rd.rider.Base().Length()
100 */
101 // FIXME
103 /**
104 * PROCEDURE (VAR rd: Reader) SetPos (pos: INTEGER)
105 * NEW
106 * Sets the reader's current position to pos.
107 *
108 * Pre
109 * 20 pos >= 0
110 * 21 pos <= rd.rider.Base().Length()
111 *
112 * Post
113 * rd.Pos() = pos
114 * ~rd.rider.eof
115 */
116 // FIXME
118 /**
119 * PROCEDURE (VAR rd: Reader) ReadBool (OUT x: BOOLEAN)
120 * NEW
121 * Reads a Boolean value.
122 */
123 /**
124 * PROCEDURE (VAR rd: Reader) ReadSChar (OUT x: SHORTCHAR)
125 * NEW
126 * Reads a short character (00X..0FFX).
127 */
128 SHORTCHAR readSChar();
129 /* PROCEDURE (VAR rd: Reader) ReadXChar (OUT x: CHAR)
130 * NEW
131 * Same as ReadSChar, but has a CHAR-type parameter.
132 * This procedure is provided to simplify migration from Release 1.2 to 1.3.
133 */
134 CHAR readXChar();
135 /**
136 * PROCEDURE (VAR rd: Reader) ReadChar (OUT x: CHAR)
137 * NEW
138 * Reads a character (0000X..0FFFFX).
139 *
140 * PROCEDURE (VAR rd: Reader) ReadByte (OUT x: BYTE)
141 * NEW
142 * Reads a very short integer (-128..127).
143 *
144 * PROCEDURE (VAR rd: Reader) ReadSInt (OUT x: SHORTINT)
145 * NEW
146 * Reads a short integer (-32768..32767).
147 *
148 * PROCEDURE (VAR rd: Reader) ReadXInt (OUT x: INTEGER)
149 * NEW
150 * Same as ReadSInt, but has an INTEGER-type parameter.
151 * This procedure is provided to simplify migration from Release 1.2 to 1.3.
152 */
154 /**
155 * PROCEDURE (VAR rd: Reader) ReadInt (OUT x: INTEGER)
156 * NEW
157 * Reads an integer (-2147483648..2147483647).
158 */
159 INTEGER readInt();
160 /*
161 * PROCEDURE (VAR rd: Reader) ReadLong (OUT x: LONGINT)
162 * NEW
163 * Reads a long integer (-9223372036854775808..9223372036854775807).
164 *
165 * PROCEDURE (VAR rd: Reader) ReadSReal (OUT x: SHORTREAL)
166 * NEW
167 * Reads a short real (32-bit IEEE number).
168 *
169 * PROCEDURE (VAR rd: Reader) ReadXReal (OUT x: REAL)
170 * NEW
171 * Same as ReadSReal, but has a REAL-type parameter.
172 * This procedure is provided to simplify migration from Release 1.2 to 1.3.
173 *
174 * PROCEDURE (VAR rd: Reader) ReadReal (OUT x: REAL)
175 * NEW
176 * Reads a real (64-bit IEEE number).
177 *
178 * PROCEDURE (VAR rd: Reader) ReadSet (OUT x: SET)
179 * NEW
180 * Reads a set (32 elements).
181 */
182 /**
183 * PROCEDURE (VAR rd: Reader) ReadSString (OUT x: ARRAY OF SHORTCHAR)
184 * NEW
185 * Reads a 0X-terminated short string.
186 *
187 * Pre
188 * invalid index LEN(x) > Length(string)
189 */
190 void readSString(SHORTCHAR *out);
191 /**
192 * PROCEDURE (VAR rd: Reader) ReadXString (OUT x: ARRAY OF CHAR)
193 * NEW
194 * Same as ReadSString, but has a string-type parameter.
195 * This procedure is provided to simplify migration from Release 1.2 to 1.3.
196 */
197 //void readXString(CHAR *out);
198 /**
199 * PROCEDURE (VAR rd: Reader) ReadString (OUT x: ARRAY OF CHAR)
200 * NEW
201 * Reads a 0X-terminated string.
202 *
203 * Pre
204 * invalid index LEN(x) > Length(string)
205 *
206 * PROCEDURE (VAR rd: Reader) ReadStore (OUT x: Store)
207 * NEW
208 * 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.
209 * 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.
210 * 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).
211 *
212 * Pre
213 * 20 the reader is at the start position of a new store
214 *
215 * Post
216 * empty store on file
217 * x = NIL
218 * non-empty store on file
219 * x # NIL
220 * x IS Alien
221 * x.cause # 0
222 * x.type # ""
223 * x.file # NIL
224 * x.pos >= 0 beginning of store's data
225 * x.len >= 0 length of store's data
226 * alien store contents are on x.file in the range [x.pos .. x.pos + x.len[.
227 * These data include only the store's contents, not its prefix
228 * ~(x IS Alien)
229 * x was read successfully
230 */
231 Store *readStore();
232 /**
233 * PROCEDURE (VAR rd: Reader) ReadVersion (min, max: INTEGER; OUT version: INTEGER)
234 * NEW
235 * 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.
236 *
237 * Pre
238 * 20 0 <= min <= max
239 *
240 * Post
241 * min <= version <= max
242 * legal version
243 * (version < min) OR (version > max)
244 * illegal version
245 * rd.cause = alienVersion
246 * rd.cancelled
247 * rd.readAlien
248 *
249 * PROCEDURE (VAR rd: Reader) TurnIntoAlien (cause: INTEGER)
250 * NEW
251 * 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.
252 *
253 * Pre
254 * 20 cause > 0
255 */
257 private:
258 Store *readStoreOrElemStore(bool isElem);
259 Store *readNilStore();
260 Store *readLinkStore();
261 Store *readNewLinkStore();
262 void internalizeAlien(Alien *alien, std::streampos down, std::streampos end);
264 /*
265 TypeName* = ARRAY 64 OF CHAR;
266 TypePath* = ARRAY 16 OF TypeName;
267 OpName* = ARRAY 32 OF CHAR;
268 */
269 inline SHORTCHAR *newTypeName() {
270 return new SHORTCHAR[64];
272 inline SHORTCHAR **newTypePath() {
273 SHORTCHAR **out = new SHORTCHAR*[16];
274 for (int i = 0; i < 16; ++i) {
275 out[i] = newTypeName();
277 return out;
279 void readPath(SHORTCHAR **path);
280 /**
281 * Add another component to the current path. If first==true, start a new path.
282 */
283 void addPathComponent(bool first, SHORTCHAR *typeName);
284 };
286 } // namespace odc
288 #endif // _READER_H_