asn1_iterators-generic_seqof.adb 3.26 KB
Newer Older
1 2
package body ASN1_Iterators.Generic_SeqOf is

3 4 5 6 7 8 9 10
   procedure Initialize (Self: in out ASN1_Variable_SeqOf) is
   begin
      Self.Value.Length := Self.Length;
      if Self.Length >= 1 then
         Self.RestVal := new P.ASN1_SeqOf (Self.Length);
         Self.RestIt  :=
            new P.ASN1_SeqOf_It'(P.ASN1_SeqOf_It (Self.RestVal.Iterate));
         Self.RestIt.Ptr := Self.RestIt.First;
11
      end if;
12
   end;
13

14 15
   function Has_Element_Variable_SeqOf (Ptr : ASN1_Variable_SeqOf_Ptr)
      return Boolean is (Length_Pkg.Has_Element (Length_Pkg.Ptr (Ptr.LenIt)));
16

17
   function Iterate (Self : ASN1_Variable_SeqOf)
18
      return Iterators_Variable_SeqOf.Forward_Iterator'Class is
19
   begin
20
     return I: ASN1_Variable_SeqOf_It do
21
        I.Ptr := Self'Unrestricted_Access;
22
     end return;
23
   end;
24

25 26 27
   function First (Item : ASN1_Variable_SeqOf_It)
      return ASN1_Variable_SeqOf_Ptr is
   begin
28
      -- Initialize the iterator (Compute first value)
29
      Item.Ptr.LenIt  := Length_Pkg.Iterator (Item.Ptr.LenVal.Iterate);
30 31

      -- Copy only the actual size, since the arrays may be different in size
32 33
      Item.Ptr.Value.Data (1 .. Item.Ptr.RestIt.Ptr.Value.Data'Length) :=
         Item.Ptr.RestIt.Ptr.Value.Data;
34
      return Item.Ptr;
35
   end;
36

37 38 39 40 41 42 43
   function Next (Item : ASN1_Variable_SeqOf_It;
                  Ptr  : ASN1_Variable_SeqOf_Ptr)
      return ASN1_Variable_SeqOf_Ptr
   is
      pragma Unreferenced (Item);
      Ptr_elem : Length_Pkg.Iterator_Ptr := Length_Pkg.Ptr(Ptr.LenIt);
   begin
44 45
      Ptr.RestIt.Ptr := Ptr.RestIt.Next (Ptr.RestIt.Ptr);
      if P.Has_Element_SeqOf (Ptr.RestIt.Ptr) then
46 47
          Ptr.Value.Data (1 .. Ptr.RestIt.Ptr.Value.Data'Length) :=
             Ptr.RestIt.Ptr.Value.Data;
48
      else
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
         Ptr.RestIt.Ptr := Ptr.RestIt.First;
         -- Exhausted "rest": iterate on the first item
         Ptr_elem := Ptr.LenIt.Next (Ptr_elem);
         if Length_Pkg.Has_Element (Ptr_elem) then
            Ptr.Value.Length := Integer (Ptr_Elem.Value.Value);
            Ptr.Length       := Ptr.Value.Length;
            Ptr.RestVal      := new P.ASN1_SeqOf(Ptr.Value.Length);
            Ptr.RestIt       :=
               new P.ASN1_SeqOf_It'(P.ASN1_SeqOf_It (Ptr.RestVal.Iterate));
            Ptr.RestIt.Ptr   := Ptr.RestIt.First;
            Ptr.Value.Data (1 .. Ptr.RestIt.Ptr.Value.Data'Length) :=
               Ptr.RestIt.Ptr.Value.Data;
         end if;
      end if;
      return Ptr;
   end;

   --  Interface functions for the generic Seqof to act as a SimpleType
   function Simple_Init return Instance is
      Initial_Value : Instance;
   begin
      Initialize (Initial_Value);
      return Initial_Value;
   end Simple_Init;

   function Simple_Has_Elem (Value : Instance) return Boolean is
      Val : aliased Instance := Value;
   begin
      return Has_Element_Variable_SeqOf (Val'Unchecked_Access);
   end Simple_Has_Elem;

   function Simple_First return Instance is
      It : ASN1_Variable_SeqOf_It;
      Res : aliased Instance;
   begin
      It.Ptr := Res'Unchecked_Access;
      return It.First.all;
   end Simple_First;

   function Simple_Next (Value : Instance) return Instance is
      Val : aliased Instance := Value;
      It : ASN1_Variable_SeqOf_It := (Ptr => Val'Unchecked_Access);
   begin
      return It.Next (Val'Unchecked_Access).all;
   end Simple_Next;
94 95
end;