DEADSOFTWARE

move plain text loading to DswDocuments
[cpc.git] / src / generic / Dsw / Mod / Documents.cp
1 MODULE DswDocuments;
3 IMPORT SYSTEM, Kernel, Files;
5 (* !!! make better store type and version checking *)
7 TYPE
8 Name = ARRAY 256 OF SHORTCHAR;
10 ShortString = POINTER TO ARRAY OF SHORTCHAR;
11 String = POINTER TO ARRAY OF CHAR;
13 Store = RECORD
14 (* type: Name; *)
15 next, down, len: INTEGER;
16 pos, end: INTEGER;
17 isElem: BOOLEAN;
18 END;
20 Model* = POINTER TO ABSTRACT RECORD END;
22 Reader* = POINTER TO ABSTRACT RECORD
23 eot*: BOOLEAN;
24 char*: CHAR;
25 END;
27 StdModel = POINTER TO RECORD (Model)
28 str: String;
29 len: INTEGER
30 END;
32 StdReader = POINTER TO RECORD (Reader)
33 base: StdModel;
34 i: INTEGER
35 END;
37 VAR
38 oldReader: Files.Reader;
40 PROCEDURE (m: Model) NewReader* (old: Reader): Reader, NEW, ABSTRACT;
41 PROCEDURE (m: Model) Length* (): INTEGER, NEW, ABSTRACT;
43 PROCEDURE (r: Reader) Base* (): Model, NEW, ABSTRACT;
44 PROCEDURE (r: Reader) Pos* (): INTEGER, NEW, ABSTRACT;
45 PROCEDURE (r: Reader) SetPos* (pos: INTEGER), NEW, ABSTRACT;
46 PROCEDURE (r: Reader) Read*, NEW, ABSTRACT;
47 PROCEDURE (r: Reader) ReadPrev*, NEW, ABSTRACT;
49 PROCEDURE (m: StdModel) NewReader (old: Reader): StdReader;
50 VAR r: StdReader;
51 BEGIN
52 IF (old # NIL) & (old IS StdReader) THEN r := old(StdReader) ELSE NEW(r) END;
53 r.eot := FALSE; r.char := 0X; r.base := m; r.i := 0;
54 RETURN r
55 END NewReader;
57 PROCEDURE (m: StdModel) Length (): INTEGER;
58 BEGIN
59 RETURN m.len
60 END Length;
63 PROCEDURE (r: StdReader) Base (): StdModel;
64 BEGIN
65 RETURN r.base
66 END Base;
68 PROCEDURE (r: StdReader) Pos (): INTEGER;
69 BEGIN
70 RETURN r.i
71 END Pos;
73 PROCEDURE (r: StdReader) SetPos (pos: INTEGER);
74 BEGIN
75 ASSERT(pos >= 0, 20);
76 ASSERT(pos <= r.base.len, 21);
77 r.i := pos
78 END SetPos;
80 PROCEDURE (r: StdReader) Read;
81 BEGIN
82 IF r.i < r.base.len THEN
83 r.char := r.base.str[r.i]; r.eot := FALSE; INC(r.i)
84 ELSE
85 r.char := 0X; r.eot := TRUE
86 END
87 END Read;
89 PROCEDURE (r: StdReader) ReadPrev;
90 BEGIN
91 IF r.i > 0 THEN
92 DEC(r.i); r.char := r.base.str[r.i]; r.eot := FALSE
93 ELSE
94 r.char := 0X; r.eot := TRUE
95 END
96 END ReadPrev;
99 PROCEDURE Import* (loc: Files.Locator; IN name: Files.Name; OUT m: Model; OUT res: INTEGER);
100 CONST
101 docTag = 6F4F4443H; docVersion = 0;
102 Step = 256;
103 VAR f: Files.File; r: Files.Reader; tag, version, chid: INTEGER; s: Store; text: StdModel;
105 PROCEDURE AddChar (ch: CHAR);
106 VAR i, len: INTEGER; t: String;
107 BEGIN
108 IF text = NIL THEN
109 NEW(text); NEW(text.str, Step); chid := 0
110 END;
111 len := LEN(text.str);
112 IF chid + 1 >= len THEN
113 NEW(t, len + Step); t^ := text.str$; text.str := t;
114 END;
115 text.str[chid] := ch; INC(chid);
116 text.str[chid] := 0X;
117 text.len := chid
118 END AddChar;
120 PROCEDURE ReadSChar (OUT x: SHORTCHAR);
121 VAR i: BYTE;
122 BEGIN
123 r.ReadByte(i);
124 x := SHORT(CHR(i MOD 256))
125 END ReadSChar;
127 PROCEDURE ReadInt (OUT x: INTEGER);
128 VAR i: ARRAY 4 OF BYTE;
129 BEGIN
130 r.ReadBytes(i, 0, 4);
131 x := i[0] MOD 256 + i[1] MOD 256 * 256 + i[2] MOD 256 * 65536 + i[3] MOD 256 * 16777216
132 END ReadInt;
134 PROCEDURE ReadBool (OUT x: BOOLEAN);
135 VAR i: SHORTCHAR;
136 BEGIN
137 ReadSChar(i);
138 x := i # 0X
139 END ReadBool;
141 PROCEDURE ReadStore (OUT s: Store);
142 CONST
143 storeVersion = 0X;
144 newBase = 0F0X; newExt = 0F1X; oldType = 0F2X;
145 nil = 80X; link = 81X; store = 82X; elem = 83X; newlink = 84X;
146 elemTName = "Stores.ElemDesc"; modelTName = "Models.ModelDesc"; (* from pre-1.3 *)
147 VAR
148 tag, version, ch: SHORTCHAR; i, x: INTEGER;
149 BEGIN
150 ReadSChar(tag); s.isElem := tag = elem;
151 ASSERT((tag = store) OR (tag = elem), 100);
152 ReadSChar(tag);
153 WHILE tag = newExt DO
154 REPEAT ReadSChar(ch) UNTIL ch = 0X;
155 ReadSChar(tag)
156 END;
157 IF tag = newBase THEN (* !!! get base types *)
158 REPEAT ReadSChar(ch) UNTIL ch = 0X;
159 ELSIF tag = oldType THEN
160 ReadInt(x) (* !!! get from dictionary *)
161 ELSE
162 HALT(102)
163 END;
164 ReadInt(x); (* extension hook = 00000000 *)
165 ReadInt(s.next); s.next := s.next + r.Pos();
166 ReadInt(s.down); s.down := s.down + r.Pos();
167 ReadInt(s.len); s.pos := r.Pos(); s.end := s.pos + s.len;
168 ReadSChar(version); (* version *)
169 ASSERT(version = storeVersion, 103);
170 IF s.isElem THEN
171 ReadSChar(version);
172 ASSERT(version = storeVersion, 104)
173 END
174 END ReadStore;
176 PROCEDURE ReadStdTextModel;
177 CONST
178 dictSize = 32;
179 noLCharStdModelVersion = 0; stdModelVersion = 1;
180 VAR
181 s: Store;
182 version, ano: BYTE;
183 org, len, dictlen, i, w, h: INTEGER;
184 R: Files.Reader;
185 x: ARRAY 2 OF BYTE;
186 ch: CHAR;
187 BEGIN
188 r.ReadByte(version);
189 IF version IN {noLCharStdModelVersion, stdModelVersion} THEN
190 ReadInt(org); org := org + r.Pos(); R := f.NewReader(NIL); R.SetPos(org);
191 r.ReadByte(ano); dictlen := 0;
192 WHILE ano # -1 DO
193 IF ano = dictlen THEN
194 ReadStore(s); r.SetPos(s.end); (* attr IS TextModels.AttributesDesc *)
195 IF dictlen < dictSize THEN (* dictattr[dictlen] := attr *) INC(dictlen) END
196 ELSE
197 (* attr := dictattr[ano] *)
198 END;
199 ReadInt(len);
200 IF len > 0 THEN (* pice *)
201 FOR i := 0 TO len - 1 DO
202 R.ReadByte(x[0]); ch := CHR(x[0] MOD 256); AddChar(ch)
203 END
204 ELSIF len < 0 THEN (* longchar pice *)
205 ASSERT(len MOD 2 = 0);
206 FOR i := 0 TO (-len) DIV 2 - 1 DO
207 R.ReadBytes(x, 0, 2); ch := CHR(x[0] MOD 256 + x[1] MOD 256 * 256); AddChar(ch)
208 END
209 ELSE (* len = 0 => embedded view *)
210 ReadInt(w); ReadInt(h); R.ReadByte(x[0]); (* viewcode!!! *) AddChar(02X);
211 ReadStore(s); r.SetPos(s.end) (* random view type *)
212 END;
213 r.ReadByte(ano)
214 END;
215 m := text;
216 res := 0 (* ok *)
217 ELSE
218 res := 4 (* unsupported text model version *)
219 END
220 END ReadStdTextModel;
222 PROCEDURE ReadTextModel;
223 CONST
224 modelVersion = 0;
225 conteinerVersion = 0;
226 textModelVersion = 0;
227 VAR
228 s: Store;
229 version: BYTE;
230 BEGIN
231 ReadStore(s);
232 IF TRUE (*s.type = "TextModels.StdModelDesc"*) THEN
233 r.ReadByte(version);
234 IF version = modelVersion THEN (* Models.Model *)
235 r.ReadByte(version);
236 IF version = conteinerVersion THEN (* Containers.Container *)
237 r.ReadByte(version);
238 IF version = textModelVersion THEN (* TextModels.Model *)
239 ReadStdTextModel
240 ELSE
241 res := 4 (* unsupported text model version *)
242 END
243 ELSE
244 res := 4 (* unsupported text model version *)
245 END
246 ELSE
247 res := 4 (* unsupported text model version *)
248 END
249 ELSE
250 res := 3 (* unsupported version *)
251 END
252 END ReadTextModel;
254 PROCEDURE ReadDocument;
255 VAR s: Store;
256 BEGIN
257 ReadStore(s);
258 IF TRUE (*s.type = "Documents.StdDocumentDesc"*) THEN
259 r.SetPos(s.down); (* !!! *)
260 ReadStore(s);
261 IF TRUE (*s.type = "Documents.ModelDesc"*) THEN
262 r.SetPos(s.down); (* !!! *)
263 ReadStore(s);
264 IF TRUE (*s.type = "TextViews.StdViewDesc"*) THEN
265 r.SetPos(s.down); (* !!! *)
266 ReadTextModel
267 ELSE
268 res := 3 (* unsupported version *)
269 END
270 ELSE
271 res := 3 (* unsupported version *)
272 END
273 ELSE
274 res := 3 (* unsupported version *)
275 END
276 END ReadDocument;
278 BEGIN
279 ASSERT(loc # NIL, 20);
280 ASSERT(name # "", 21);
281 m := NIL; res := 0;
282 f := Files.dir.Old(loc, name, Files.shared);
283 IF f # NIL THEN
284 IF f.Length() > 8 THEN (* !!! calculate minimal document size *)
285 r := f.NewReader(NIL);
286 ReadInt(tag);
287 IF tag = docTag THEN
288 ReadInt(version);
289 IF version = docVersion THEN
290 ReadDocument;
291 f.Close
292 ELSE
293 f.Close;
294 res := 3 (* unsupported version *)
295 END
296 ELSE
297 f.Close;
298 res := 2 (* not document *)
299 END
300 ELSE
301 f.Close;
302 res := 2 (* not document *)
303 END
304 ELSE
305 res := 1 (* unable to open *)
306 END
307 END Import;
309 PROCEDURE Open* (loc: Files.Locator; IN name: Files.Name; OUT m: Model; OUT res: INTEGER);
310 VAR f: Files.File; r: Files.Reader; len: INTEGER; s: ShortString; l: String; text: StdModel;
311 BEGIN
312 m := NIL; res := 0;
313 Import(loc, name, m, res);
314 IF res = 2 THEN
315 f := Files.dir.Old(loc, name, Files.shared);
316 IF f # NIL THEN
317 len := f.Length();
318 r := f.NewReader(oldReader); oldReader := r; r.SetPos(0);
319 NEW(s, len + 1); r.ReadBytes(SYSTEM.THISARRAY(SYSTEM.ADR(s[0]), len + 1), 0, len);
320 NEW(l, len + 1); Kernel.Utf8ToString(s, l, res);
321 IF res = 0 THEN
322 NEW(text); text.str := l; text.len := LEN(text.str$); m := text; res := 0 (* ok *)
323 ELSE
324 res := 5 (* broken encoding *)
325 END;
326 f.Close
327 ELSE
328 res := 1 (* unable to open *)
329 END
330 END
331 END Open;
333 END DswDocuments.