adayaml_0.3.0_ab19e387/src/implementation/yaml-events-queue.adb

  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
--  part of AdaYaml, (c) 2017 Felix Krause
--  released under the terms of the MIT license, see the file "copying.txt"

package body Yaml.Events.Queue is
   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 Copy_Data (Source : Instance;
                        Target : not null Event_Array_Access) is
   begin
      Target (1 .. Source.Data.all'Last - Source.First_Pos + 1) :=
        Source.Data (Source.First_Pos .. Source.Data.all'Last);
      Target (Source.Data.all'Last - Source.First_Pos + 2 ..
                Source.Data.all'Last) :=
          Source.Data (1 .. Source.First_Pos - 1);
   end Copy_Data;

   procedure Append (Object : in out Instance; E : Event) is
      Position : Mark;
   begin
      Append (Object, E, Position);
   end Append;

   function Next_Index (Object : Instance) return Positive is
      (((Object.First_Pos + Object.Length - 1) mod
                 Object.Data.all'Length) + 1);

   procedure Append (Object : in out Instance; E : Event; Position : out Mark)
   is begin
      if Object.Stream_Count > 0 then
         raise State_Error with
           "cannot manipulate event queue while a Stream_Instance exists";
      end if;
      if Object.Length = Object.Data.all'Length then
         Object.Grow;
         Object.First_Pos := 1;
      end if;
      Position := Mark (Next_Index (Object));
      Object.Data (Positive (Position)) := E;
      Object.Length := Object.Length + 1;
   end Append;

   function Length (Object : in Instance) return Natural is
     (Object.Length);

   function Length (Object : Reference) return Natural is
     (Object.Data.Length);

   function First (Object : in Instance) return Event is
   begin
      if Object.Length = 0 then
         raise Constraint_Error with "no items in event queue";
      end if;
      return Object.Data (Object.First_Pos);
   end First;

   procedure Dequeue (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";
      elsif Object.Length = 0 then
         raise Constraint_Error with "no items in event queue";
      end if;
      Object.Length := Object.Length - 1;
      Object.First_Pos := Object.First_Pos + 1;
      if Object.First_Pos > Object.Data.all'Last then
         Object.First_Pos := 1;
      end if;
   end Dequeue;

   function Value (Object : Reference) return Accessor is
     ((Data => Object.Data));

   function New_Queue return Reference is
      Ptr : constant not null access Instance := new Instance;
   begin
      return Reference'(Ada.Finalization.Controlled with Data => Ptr);
   end New_Queue;

   function Element (Object : Instance; Position : Mark)
                     return Element_Accessor is
      Index : constant Positive := Positive (Position);
   begin
      if Index < Object.First_Pos and then Index >= Next_Index (Object) then
         raise State_Error with "no element at this index";
      end if;
      return (Data => Object.Data (Index)'Unrestricted_Access);
   end Element;

   function As_Stream (Object : Reference'Class) return Stream_Reference is
      Ptr : constant not null access Stream_Instance :=
        new Stream_Instance'(Refcount_Base with Buffer => Reference (Object),
                             Offset => 0);
   begin
      Ptr.Buffer.Data.Stream_Count := Ptr.Buffer.Data.Stream_Count + 1;
      return Stream_Reference'(Ada.Finalization.Controlled with
                                 Data => Ptr);
   end As_Stream;

   function Value (Object : Stream_Reference) return Stream_Accessor is
     ((Data => Object.Data));

   function Value (Object : Optional_Stream_Reference) return Stream_Accessor is
     ((Data => Object.Data));

   function Next (Object : in out Stream_Instance) return Event is
      Index : constant Positive :=
        (Object.Buffer.Data.First_Pos + Object.Offset) mod
        Object.Buffer.Data.Data.all'Last;
   begin
      if Object.Offset = Object.Buffer.Data.Length then
         raise Constraint_Error with
           "Tried to query more events than in queue";
      else
         return E : constant Event := Object.Buffer.Data.Data (Index) do
            Object.Offset := Object.Offset + 1;
         end return;
      end if;
   end Next;

   function Required (Object : Optional_Stream_Reference'Class)
                      return Stream_Reference is
   begin
      Object.Data.Increase_Refcount;
      return (Ada.Finalization.Controlled with Data => Object.Data);
   end Required;

   function Optional (Object : Stream_Reference'Class)
                     return Optional_Stream_Reference is
   begin
      Object.Data.Increase_Refcount;
      return (Ada.Finalization.Controlled with Data => Object.Data);
   end Optional;

   procedure Finalize (Object : in out Stream_Instance) is
   begin
      Object.Buffer.Data.Stream_Count := Object.Buffer.Data.Stream_Count - 1;
   end Finalize;

   overriding 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;

   overriding 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;
end Yaml.Events.Queue;