DEADSOFTWARE

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