3 IMPORT SYSTEM
, Kernel
, Files
;
5 (* !!! make better store type and version checking *)
8 Name
= ARRAY 256 OF SHORTCHAR
;
10 ShortString
= POINTER TO ARRAY OF SHORTCHAR
;
11 String
= POINTER TO ARRAY OF CHAR;
15 next
, down
, len
: INTEGER;
20 Model
* = POINTER TO ABSTRACT
RECORD END;
22 Reader
* = POINTER TO ABSTRACT
RECORD
27 StdModel
= POINTER TO RECORD (Model
)
32 StdReader
= POINTER TO RECORD (Reader
)
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
;
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;
57 PROCEDURE (m
: StdModel
) Length (): INTEGER;
63 PROCEDURE (r
: StdReader
) Base (): StdModel
;
68 PROCEDURE (r
: StdReader
) Pos (): INTEGER;
73 PROCEDURE (r
: StdReader
) SetPos (pos
: INTEGER);
76 ASSERT(pos
<= r
.base
.len
, 21);
80 PROCEDURE (r
: StdReader
) Read
;
82 IF r
.i
< r
.base
.len
THEN
83 r
.char
:= r
.base
.str
[r
.i
]; r
.eot
:= FALSE
; INC(r
.i
)
85 r
.char
:= 0X
; r
.eot
:= TRUE
89 PROCEDURE (r
: StdReader
) ReadPrev
;
92 DEC(r
.i
); r
.char
:= r
.base
.str
[r
.i
]; r
.eot
:= FALSE
94 r
.char
:= 0X
; r
.eot
:= TRUE
99 PROCEDURE Import
* (loc
: Files
.Locator
; IN name
: Files
.Name
; OUT m
: Model
; OUT res
: INTEGER);
101 docTag
= 6F4F4443H
; docVersion
= 0;
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
;
109 NEW(text
); NEW(text
.str
, Step
); chid
:= 0
111 len
:= LEN(text
.str
);
112 IF chid
+ 1 >= len
THEN
113 NEW(t
, len
+ Step
); t^
:= text
.str$
; text
.str
:= t
;
115 text
.str
[chid
] := ch
; INC(chid
);
116 text
.str
[chid
] := 0X
;
120 PROCEDURE ReadSChar (OUT x
: SHORTCHAR
);
124 x
:= SHORT(CHR(i
MOD 256))
127 PROCEDURE ReadInt (OUT x
: INTEGER);
128 VAR i
: ARRAY 4 OF BYTE;
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
134 PROCEDURE ReadBool (OUT x
: BOOLEAN);
141 PROCEDURE ReadStore (OUT s
: Store
);
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 *)
148 tag
, version
, ch
: SHORTCHAR
; i
, x
: INTEGER;
150 ReadSChar(tag
); s
.isElem
:= tag
= elem
;
151 ASSERT((tag
= store
) OR (tag
= elem
), 100);
153 WHILE tag
= newExt
DO
154 REPEAT ReadSChar(ch
) UNTIL ch
= 0X
;
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 *)
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);
172 ASSERT(version
= storeVersion
, 104)
176 PROCEDURE ReadStdTextModel
;
179 noLCharStdModelVersion
= 0; stdModelVersion
= 1;
183 org
, len
, dictlen
, i
, w
, h
: INTEGER;
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;
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
197 (* attr := dictattr[ano] *)
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
)
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
)
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 *)
218 res
:= 4 (* unsupported text model version *)
220 END ReadStdTextModel
;
222 PROCEDURE ReadTextModel
;
225 conteinerVersion
= 0;
226 textModelVersion
= 0;
232 IF TRUE (*s.type = "TextModels.StdModelDesc"*) THEN
234 IF version
= modelVersion
THEN (* Models.Model *)
236 IF version
= conteinerVersion
THEN (* Containers.Container *)
238 IF version
= textModelVersion
THEN (* TextModels.Model *)
241 res
:= 4 (* unsupported text model version *)
244 res
:= 4 (* unsupported text model version *)
247 res
:= 4 (* unsupported text model version *)
250 res
:= 3 (* unsupported version *)
254 PROCEDURE ReadDocument
;
258 IF TRUE (*s.type = "Documents.StdDocumentDesc"*) THEN
259 r
.SetPos(s
.down
); (* !!! *)
261 IF TRUE (*s.type = "Documents.ModelDesc"*) THEN
262 r
.SetPos(s
.down
); (* !!! *)
264 IF TRUE (*s.type = "TextViews.StdViewDesc"*) THEN
265 r
.SetPos(s
.down
); (* !!! *)
268 res
:= 3 (* unsupported version *)
271 res
:= 3 (* unsupported version *)
274 res
:= 3 (* unsupported version *)
279 ASSERT(loc
# NIL, 20);
280 ASSERT(name
# "", 21);
282 f
:= Files
.dir
.Old(loc
, name
, Files
.shared
);
284 IF f
.Length() > 8 THEN (* !!! calculate minimal document size *)
285 r
:= f
.NewReader(NIL);
289 IF version
= docVersion
THEN
294 res
:= 3 (* unsupported version *)
298 res
:= 2 (* not document *)
302 res
:= 2 (* not document *)
305 res
:= 1 (* unable to open *)
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
;
313 Import(loc
, name
, m
, res
);
315 f
:= Files
.dir
.Old(loc
, name
, Files
.shared
);
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
);
322 NEW(text
); text
.str
:= l
; text
.len
:= LEN(text
.str$
); m
:= text
; res
:= 0 (* ok *)
324 res
:= 5 (* broken encoding *)
328 res
:= 1 (* unable to open *)