-
Notifications
You must be signed in to change notification settings - Fork 2
/
Stores.cp
110 lines (86 loc) · 2.94 KB
/
Stores.cp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
MODULE ObxStores;
(**
project = "BlackBox"
organization = "www.oberon.ch"
contributors = "Oberon microsystems"
version = "System/Rsrc/About"
copyright = "System/Rsrc/About"
license = "Docu/BB-License"
changes = ""
issues = ""
**)
(*
This example illustrates the persistency service implemented by Stores. It is shown how a graph
of linked nodes can be externalized and internalized, maintaining invariants like objects refered to
through multiple pointers and cycles. Stores also offeres a mechanism to just copy such a graph.
To run the example, click on the commanders below:
ObxStores.WriteRead ObxStores.Copy
*)
IMPORT Dialog, Files, Stores;
TYPE
Node = POINTER TO RECORD (Stores.Store)
a, b: Node
END;
(* Methods of Node *)
PROCEDURE (n: Node) Externalize (VAR w: Stores.Writer);
BEGIN
w.WriteStore(n.a); w.WriteStore(n.b)
END Externalize;
PROCEDURE (n: Node) Internalize (VAR r: Stores.Reader);
VAR s: Stores.Store;
BEGIN
r.ReadStore(s);
IF (s # NIL) & (s IS Node) THEN n.a := s(Node) ELSE n.a := NIL END;
r.ReadStore(s);
IF (s # NIL) & (s IS Node) THEN n.b := s(Node) ELSE n.b := NIL END
END Internalize;
PROCEDURE (n: Node) CopyFrom (source: Stores.Store);
BEGIN
WITH source: Node DO
IF source.a # NIL THEN n.a := Stores.CopyOf(source.a)(Node) ELSE n.a := NIL END;
IF source.b # NIL THEN n.b := Stores.CopyOf(source.b)(Node) ELSE n.b := NIL END
END
END CopyFrom;
(* Build and check a graph of Nodes *)
PROCEDURE NewGraph (): Node;
VAR n: Node;
BEGIN
NEW(n);
NEW(n.a); Stores.Join(n, n.a);
NEW(n.b); Stores.Join(n, n.b);
n.a.a := n.b; n.a.b := NIL; n.b.a := n.a; n.b.b := n.b;
RETURN n
END NewGraph;
PROCEDURE GraphOk (n: Node): BOOLEAN;
BEGIN
RETURN (n # n.a) & (n # n.b) & (n.a # n.b) & (n.a.a = n.b) & (n.a.b = NIL) & (n.b.a = n.a) & (n.b.b = n.b)
& Stores.Joined(n, n.a) & Stores.Joined(n, n.b)
END GraphOk;
(* Demonstrate Ex- and Internalization *)
PROCEDURE WriteRead*;
VAR n, m: Node; f: Files.File; w: Stores.Writer; r: Stores.Reader; s: Stores.Store;
BEGIN
(* allocate and check new graph *)
n := NewGraph(); ASSERT(GraphOk(n), 1);
(* externalize graph to a temporary file *)
f := Files.dir.Temp();
w.ConnectTo(f); w.WriteStore(n);
(* read graph back from file *)
r.ConnectTo(f); r.ReadStore(s); m := s(Node);
(* check graph to be internalized with nodes correctly linked and joined *)
ASSERT(GraphOk(m), 2);
Dialog.ShowMsg("WriteRead test ok.")
END WriteRead;
(* Demonstrate Copying *)
PROCEDURE Copy*;
VAR n, m: Node;
BEGIN
(* allocate and check new graph *)
n := NewGraph(); ASSERT(GraphOk(n), 1);
(* copy entire graph *)
m := Stores.CopyOf(n)(Node);
(* check graph to be internalized with nodes correctly linked and joined *)
ASSERT(GraphOk(m), 2);
Dialog.ShowMsg("Copy test ok.")
END Copy;
END ObxStores.