DEADSOFTWARE

Modularize, some progress toward reading stores
[odcread.git] / reader.h
1 #ifndef _READER_H_
2 #define _READER_H_
4 #include <iostream>
6 #include <oberon.h>
7 #include <store.h>
9 namespace odc {
11 /**
12 * TYPE Reader
13 * Reader for Component Pascal values like integers, reals, or sets. A reader contains a Files.Reader, to which it forwards most operations.
14 * Readers are used in the Store.Internalize procedure.
15 * Readers are not extensible.
16 */
17 class Reader {
18 private:
19 /*
20 * rider-: Files.Reader
21 * The file rider which links a Reader to a file.
22 */
23 std::istream &d_rider;
25 /*
26 * cancelled-: BOOLEAN valid during a Store.Internalize call
27 * Tells whether the currently executing Internalize has been called by ReadVersion or TurnIntoAlien.
28 */
29 bool d_cancelled;
31 /**
32 * readAlien-: BOOLEAN
33 * Tells whether any alien has been read since the last ConnectTo.
34 */
35 bool d_readAlien;
37 INTEGER d_nextElemId;
38 INTEGER d_nextStoreId;
40 public:
41 /**
42 * Construct a reader from the istream rider.
43 * @param rider An istream (binary mode).
44 */
45 Reader(std::istream &rider);
47 /**
48 * PROCEDURE (VAR rd: Reader) ConnectTo (f: Files.File)
49 * NEW
50 * 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.
51 * ConnectTo is used internally.
52 *
53 * Pre
54 * 20 (f = NIL) OR (rd.rider = NIL)
55 *
56 * Post
57 * f = NIL
58 * rd.rider = NIL
59 * f # NIL
60 * (rd.rider # NIL) & (rd.rider.Base() = f)
61 * rd.Pos() = 0
62 */
63 // FIXME
65 /**
66 * PROCEDURE (VAR rd: Reader) Pos (): INTEGER
67 * NEW
68 * Returns the reader's current position.
69 *
70 * Post
71 * 0 <= result <= rd.rider.Base().Length()
72 */
73 // FIXME
75 /**
76 * PROCEDURE (VAR rd: Reader) SetPos (pos: INTEGER)
77 * NEW
78 * Sets the reader's current position to pos.
79 *
80 * Pre
81 * 20 pos >= 0
82 * 21 pos <= rd.rider.Base().Length()
83 *
84 * Post
85 * rd.Pos() = pos
86 * ~rd.rider.eof
87 */
88 // FIXME
90 /**
91 * PROCEDURE (VAR rd: Reader) ReadBool (OUT x: BOOLEAN)
92 * NEW
93 * Reads a Boolean value.
94 */
95 /**
96 * PROCEDURE (VAR rd: Reader) ReadSChar (OUT x: SHORTCHAR)
97 * NEW
98 * Reads a short character (00X..0FFX).
99 */
100 SHORTCHAR readSChar();
101 /* PROCEDURE (VAR rd: Reader) ReadXChar (OUT x: CHAR)
102 * NEW
103 * Same as ReadSChar, but has a CHAR-type parameter.
104 * This procedure is provided to simplify migration from Release 1.2 to 1.3.
105 *
106 * PROCEDURE (VAR rd: Reader) ReadChar (OUT x: CHAR)
107 * NEW
108 * Reads a character (0000X..0FFFFX).
109 *
110 * PROCEDURE (VAR rd: Reader) ReadByte (OUT x: BYTE)
111 * NEW
112 * Reads a very short integer (-128..127).
113 *
114 * PROCEDURE (VAR rd: Reader) ReadSInt (OUT x: SHORTINT)
115 * NEW
116 * Reads a short integer (-32768..32767).
117 *
118 * PROCEDURE (VAR rd: Reader) ReadXInt (OUT x: INTEGER)
119 * NEW
120 * Same as ReadSInt, but has an INTEGER-type parameter.
121 * This procedure is provided to simplify migration from Release 1.2 to 1.3.
122 */
124 /**
125 * PROCEDURE (VAR rd: Reader) ReadInt (OUT x: INTEGER)
126 * NEW
127 * Reads an integer (-2147483648..2147483647).
128 */
129 INTEGER readInt();
130 /*
131 * PROCEDURE (VAR rd: Reader) ReadLong (OUT x: LONGINT)
132 * NEW
133 * Reads a long integer (-9223372036854775808..9223372036854775807).
134 *
135 * PROCEDURE (VAR rd: Reader) ReadSReal (OUT x: SHORTREAL)
136 * NEW
137 * Reads a short real (32-bit IEEE number).
138 *
139 * PROCEDURE (VAR rd: Reader) ReadXReal (OUT x: REAL)
140 * NEW
141 * Same as ReadSReal, but has a REAL-type parameter.
142 * This procedure is provided to simplify migration from Release 1.2 to 1.3.
143 *
144 * PROCEDURE (VAR rd: Reader) ReadReal (OUT x: REAL)
145 * NEW
146 * Reads a real (64-bit IEEE number).
147 *
148 * PROCEDURE (VAR rd: Reader) ReadSet (OUT x: SET)
149 * NEW
150 * Reads a set (32 elements).
151 *
152 * PROCEDURE (VAR rd: Reader) ReadSString (OUT x: ARRAY OF SHORTCHAR)
153 * NEW
154 * Reads a 0X-terminated short string.
155 *
156 * Pre
157 * invalid index LEN(x) > Length(string)
158 *
159 * PROCEDURE (VAR rd: Reader) ReadXString (OUT x: ARRAY OF CHAR)
160 * NEW
161 * Same as ReadSString, but has a string-type parameter.
162 * This procedure is provided to simplify migration from Release 1.2 to 1.3.
163 *
164 * PROCEDURE (VAR rd: Reader) ReadString (OUT x: ARRAY OF CHAR)
165 * NEW
166 * Reads a 0X-terminated string.
167 *
168 * Pre
169 * invalid index LEN(x) > Length(string)
170 *
171 * PROCEDURE (VAR rd: Reader) ReadStore (OUT x: Store)
172 * NEW
173 * 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.
174 * 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.
175 * 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).
176 *
177 * Pre
178 * 20 the reader is at the start position of a new store
179 *
180 * Post
181 * empty store on file
182 * x = NIL
183 * non-empty store on file
184 * x # NIL
185 * x IS Alien
186 * x.cause # 0
187 * x.type # ""
188 * x.file # NIL
189 * x.pos >= 0 beginning of store's data
190 * x.len >= 0 length of store's data
191 * alien store contents are on x.file in the range [x.pos .. x.pos + x.len[.
192 * These data include only the store's contents, not its prefix
193 * ~(x IS Alien)
194 * x was read successfully
195 */
196 Store *readStore();
197 /**
198 * PROCEDURE (VAR rd: Reader) ReadVersion (min, max: INTEGER; OUT version: INTEGER)
199 * NEW
200 * 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.
201 *
202 * Pre
203 * 20 0 <= min <= max
204 *
205 * Post
206 * min <= version <= max
207 * legal version
208 * (version < min) OR (version > max)
209 * illegal version
210 * rd.cause = alienVersion
211 * rd.cancelled
212 * rd.readAlien
213 *
214 * PROCEDURE (VAR rd: Reader) TurnIntoAlien (cause: INTEGER)
215 * NEW
216 * 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.
217 *
218 * Pre
219 * 20 cause > 0
220 */
222 private:
223 Store *readStoreOrElemStore(bool isElem);
224 Store *readNilStore();
225 Store *readLinkStore();
226 Store *readNewLinkStore();
228 /*
229 TypeName* = ARRAY 64 OF CHAR;
230 TypePath* = ARRAY 16 OF TypeName;
231 OpName* = ARRAY 32 OF CHAR;
232 */
233 inline CHAR *newTypeName() {
234 return new CHAR[64];
236 inline CHAR **newTypePath() {
237 CHAR **out = new CHAR*[16];
238 for (int i = 0; i < 16; ++i) {
239 out[i] = newTypeName();
241 return out;
243 void readPath(CHAR **path);
244 };
246 } // namespace odc
248 #endif // _READER_H_