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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336 | -- part of AdaYaml, (c) 2017 Felix Krause
-- released under the terms of the MIT license, see the file "copying.txt"
package body Yaml.Events.Store is
function New_Store return Reference is
Ptr : constant not null access Instance := new Instance;
begin
return (Ada.Finalization.Controlled with Data => Ptr);
end New_Store;
function Value (Object : Reference) return Accessor is
((Data => Object.Data));
function Value (Object : Optional_Reference) return Accessor is
((Data => Object.Data));
function Optional (Object : Reference'Class) return Optional_Reference is
begin
Increase_Refcount (Object.Data);
return (Ada.Finalization.Controlled with Data => Object.Data);
end Optional;
function Required (Object : Optional_Reference'Class) return Reference is
begin
Increase_Refcount (Object.Data);
return (Ada.Finalization.Controlled with Data => Object.Data);
end Required;
procedure Memorize (Object : in out Instance; Item : Event; Force : Boolean)
is
use type Text.Reference;
begin
if Object.Stream_Count > 0 then
raise State_Error with
"cannot manipulate event queue while a Stream_Instance exists";
end if;
case Item.Kind is
when Annotation_Start =>
if Item.Annotation_Properties.Anchor /= Text.Empty then
Object.Anchor_Map.Include
(Item.Annotation_Properties.Anchor,
(Position => Object.Length + 1, Has_Been_Output => False));
elsif Object.Depth = 0 and not Force then
return;
end if;
if Object.Depth = After_Annotation_End then
Object.Depth := 1;
else
Object.Depth := Object.Depth + 1;
end if;
when Scalar =>
if Item.Scalar_Properties.Anchor /= Text.Empty then
Object.Anchor_Map.Include
(Item.Scalar_Properties.Anchor,
(Position => Object.Length + 1,
Has_Been_Output => False));
elsif Object.Depth = 0 and not Force then
return;
end if;
if Object.Depth = After_Annotation_End then
Object.Depth := 0;
end if;
when Mapping_Start =>
if Item.Collection_Properties.Anchor /= Text.Empty then
Object.Anchor_Map.Include
(Item.Collection_Properties.Anchor,
(Position => Object.Length + 1,
Has_Been_Output => False));
elsif Object.Depth = 0 and not Force then
return;
end if;
if Object.Depth = After_Annotation_End then
Object.Depth := 1;
else
Object.Depth := Object.Depth + 1;
end if;
when Sequence_Start =>
if Item.Collection_Properties.Anchor /= Text.Empty then
Object.Anchor_Map.Include
(Item.Collection_Properties.Anchor,
(Position => Object.Length + 1,
Has_Been_Output => False));
elsif Object.Depth = 0 and not Force then
return;
end if;
if Object.Depth = After_Annotation_End then
Object.Depth := 1;
else
Object.Depth := Object.Depth + 1;
end if;
when Mapping_End | Sequence_End =>
if Object.Depth = 0 and not Force then
return;
end if;
Object.Depth := Object.Depth - 1;
when Annotation_End =>
if Object.Depth = 0 and not Force then
return;
end if;
Object.Depth := Object.Depth - 1;
if Object.Depth = 0 then
Object.Depth := After_Annotation_End;
end if;
when others =>
if Object.Depth = 0 and not Force then
return;
elsif Object.Depth = After_Annotation_End then
Object.Depth := 0;
end if;
end case;
if Object.Length = Object.Data.all'Length then
Object.Grow;
end if;
Object.Length := Object.Length + 1;
Object.Data (Object.Length) := Item;
end Memorize;
procedure Memorize (Object : in out Instance; Item : Event) is
begin
Memorize (Object, Item, False);
end Memorize;
procedure Force_Memorize (Object : in out Instance; Item : Event;
Position : out Element_Cursor) is
begin
Memorize (Object, Item, True);
Position := Element_Cursor (Object.Length);
end Force_Memorize;
function Find (Object : Instance; Alias : Text.Reference)
return Anchor_Cursor is
(Anchor_Cursor (Object.Anchor_Map.Find (Alias)));
function Exists_In_Output (Position : Anchor_Cursor) return Boolean is
(Anchor_To_Index.Element
(Anchor_To_Index.Cursor (Position)).Has_Been_Output);
procedure Set_Exists_In_Output (Object : in out Instance;
Position : Anchor_Cursor) is
procedure Process (Key : Text.Reference;
Element : in out Anchor_Info) is
pragma Unreferenced (Key);
begin
Element.Has_Been_Output := True;
end Process;
begin
Anchor_To_Index.Update_Element (Object.Anchor_Map,
Anchor_To_Index.Cursor (Position),
Process'Access);
end Set_Exists_In_Output;
procedure Advance (Position : in out Element_Cursor) is
begin
Position := Element_Cursor'Succ (Position);
end Advance;
procedure Advance_At_Same_Level (Object : Instance;
Position : in out Element_Cursor) is
Depth : Natural := 0;
begin
loop
case Object.Data (Positive (Position)).Kind is
when Annotation_Start | Sequence_Start | Mapping_Start |
Document_Start =>
Depth := Depth + 1;
when Annotation_End =>
Depth := Depth - 1;
when Sequence_End | Mapping_End | Document_End =>
Depth := Depth - 1;
if Depth = 0 then
Position := Element_Cursor'Succ (Position);
return;
end if;
when Scalar | Alias =>
if Depth = 0 then
Position := Element_Cursor'Succ (Position);
return;
end if;
when Stream_Start | Stream_End =>
raise Stream_Error with "Unexpected event inside stream: " &
Object.Data (Positive (Position)).Kind'Img;
end case;
Position := Element_Cursor'Succ (Position);
end loop;
end Advance_At_Same_Level;
procedure Clear (Object : in out Instance) is
begin
if Object.Stream_Count > 0 then
raise State_Error with
"cannot manipulate event queue while a Stream_Instance exists";
end if;
Object.Anchor_Map.Clear;
Object.Depth := 0;
end Clear;
procedure Copy (Source : in Instance; Target : in out Instance) is
begin
if Target.Data.all'Length /= Source.Data.all'Length then
Target.Finalize;
Target.Data := new Event_Array (Source.Data.all'Range);
end if;
Target.Data.all := Source.Data.all;
Target.Length := Source.Length;
Target.Anchor_Map := Source.Anchor_Map;
Target.Depth := Source.Depth;
end Copy;
function Retrieve (Object : Reference'Class; Position : Anchor_Cursor)
return Stream_Reference is
Ptr : constant not null access Stream_Instance :=
new Stream_Instance'(Refcount_Base with Object => Reference (Object),
Depth => 0, Current => Anchor_To_Index.Element
(Anchor_To_Index.Cursor (Position)).Position);
begin
Object.Data.Stream_Count := Object.Data.Stream_Count + 1;
return Stream_Reference'(Ada.Finalization.Controlled with Data => Ptr);
end Retrieve;
function Retrieve (Object : Reference'Class; Position : Element_Cursor)
return Stream_Reference is
Ptr : constant not null access Stream_Instance :=
new Stream_Instance'(Refcount_Base with Object => Reference (Object),
Depth => 0, Current => Positive (Position));
begin
Object.Data.Stream_Count := Object.Data.Stream_Count + 1;
return Stream_Reference'(Ada.Finalization.Controlled with Data => Ptr);
end Retrieve;
function Value (Object : Stream_Reference) return Stream_Accessor is
((Data => Object.Data));
function Next (Object : in out Stream_Instance) return Event is
begin
if Object.Depth = 1 then
raise Constraint_Error with
"tried to query item after end of anchored node";
end if;
return Item : constant Event := Object.Object.Data.Data (Object.Current) do
case Item.Kind is
when Scalar => Object.Depth := Natural'Max (1, Object.Depth);
when Mapping_Start | Sequence_Start =>
Object.Depth := Natural'Max (2, Object.Depth + 1);
when others => null;
end case;
Object.Current := Object.Current + 1;
end return;
end Next;
function Exists (Object : Optional_Stream_Reference) return Boolean is
(Object.Data /= null);
function Value (Object : Optional_Stream_Reference) return Stream_Accessor is
((Data => Object.Data));
function Optional (Object : Stream_Reference'Class)
return Optional_Stream_Reference is
begin
Object.Data.Refcount := Object.Data.Refcount + 1;
return (Ada.Finalization.Controlled with Data => Object.Data);
end Optional;
procedure Clear (Object : in out Optional_Stream_Reference) is
begin
if Object.Data /= null then
Decrease_Refcount (Object.Data);
Object.Data := null;
end if;
end Clear;
function First (Object : Instance; Position : Anchor_Cursor) return Event is
(Object.Data (Anchor_To_Index.Element (Anchor_To_Index.Cursor
(Position)).Position));
function Element (Object : Instance; Position : Element_Cursor)
return Event is
(Object.Data (Positive (Position)));
procedure Adjust (Object : in out Reference) is
begin
Increase_Refcount (Object.Data);
end Adjust;
procedure Finalize (Object : in out Reference) is
begin
Decrease_Refcount (Object.Data);
end Finalize;
procedure Adjust (Object : in out Optional_Reference) is
begin
if Object.Data /= null then
Increase_Refcount (Object.Data);
end if;
end Adjust;
procedure Finalize (Object : in out Optional_Reference) is
begin
if Object.Data /= null then
Decrease_Refcount (Object.Data);
end if;
end Finalize;
procedure Finalize (Object : in out Stream_Instance) is
begin
Object.Object.Data.Stream_Count := Object.Object.Data.Stream_Count - 1;
end Finalize;
procedure Adjust (Object : in out Stream_Reference) is
begin
Increase_Refcount (Object.Data);
end Adjust;
procedure Finalize (Object : in out Stream_Reference) is
begin
Decrease_Refcount (Object.Data);
end Finalize;
procedure Adjust (Object : in out Optional_Stream_Reference) is
begin
if Object.Data /= null then
Increase_Refcount (Object.Data);
end if;
end Adjust;
procedure Finalize (Object : in out Optional_Stream_Reference) is
begin
if Object.Data /= null then
Decrease_Refcount (Object.Data);
end if;
end Finalize;
function To_Element_Cursor (Position : Anchor_Cursor) return Element_Cursor
is (if Position = No_Anchor then No_Element else
Element_Cursor (Anchor_To_Index.Element (Anchor_To_Index.Cursor
(Position)).Position));
end Yaml.Events.Store;
|