Commit 1f8180b4 authored by Maxime Perrotin's avatar Maxime Perrotin

Create a Generic_Simple iterator for SeqOf

parent 28e95302
...@@ -4,24 +4,23 @@ with Ada.Finalization; ...@@ -4,24 +4,23 @@ with Ada.Finalization;
use Ada.Finalization; use Ada.Finalization;
with ASN1_Iterators.Generic_Basic; with ASN1_Iterators.Generic_Basic;
with ASN1_Iterators.SimpleTypes;
generic generic
with package P is new Generic_Basic (<>); with package P is new Generic_Basic (<>);
package ASN1_Iterators.Generic_Fixed_SeqOf is package ASN1_Iterators.Generic_Fixed_SeqOf is
type DataArray is array (natural range <>) of P.Sort; type DataArray is array (natural range <>) of P.Sort;
type SeqOf (Max : Natural) is record type SeqOf (Max : Natural) is record
Length : Integer; Length : Integer;
Data : DataArray (1 .. Max); Data : DataArray (1 .. Max);
end record; end record;
type ASN1_SeqOf_Ptr; type ASN1_SeqOf_Ptr;
type ASN1_SeqOf_It; type ASN1_SeqOf_It;
type ASN1_SeqOf (Size : Natural) is new Controlled type ASN1_SeqOf (Size : Natural) is new Controlled
with record with record
Length : Natural := Size; Length : Natural := Size;
Value : SeqOf (Size); Value : SeqOf (Size);
-- First value -- First value
...@@ -30,33 +29,33 @@ package ASN1_Iterators.Generic_Fixed_SeqOf is ...@@ -30,33 +29,33 @@ package ASN1_Iterators.Generic_Fixed_SeqOf is
-- The rest (recursive) -- The rest (recursive)
Rest : access ASN1_SeqOf; Rest : access ASN1_SeqOf;
RestIt : access ASN1_SeqOf_It; RestIt : access ASN1_SeqOf_It;
end record end record
with Default_Iterator => Iterate, with Default_Iterator => Iterate,
Iterator_Element => SeqOf, Iterator_Element => SeqOf,
Constant_Indexing => Element_SeqOf_Value; Constant_Indexing => Element_SeqOf_Value;
type ASN1_SeqOf_Ptr is access all ASN1_SeqOf; type ASN1_SeqOf_Ptr is access all ASN1_SeqOf;
-- Constructor (called automatically) -- Constructor (called automatically)
procedure Initialize (Self : in out ASN1_SeqOf); procedure Initialize (Self : in out ASN1_SeqOf);
function Has_Element_SeqOf (Ptr : ASN1_SeqOf_Ptr) return Boolean; function Has_Element_SeqOf (Ptr : ASN1_SeqOf_Ptr) return Boolean;
package Iterators_SeqOf is package Iterators_SeqOf is
new Ada.Iterator_Interfaces (ASN1_SeqOf_Ptr, Has_Element_SeqOf); new Ada.Iterator_Interfaces (ASN1_SeqOf_Ptr, Has_Element_SeqOf);
type ASN1_SeqOf_It is new Iterators_SeqOf.Forward_Iterator with record type ASN1_SeqOf_It is new Iterators_SeqOf.Forward_Iterator with record
Ptr : ASN1_SeqOf_Ptr; Ptr : ASN1_SeqOf_Ptr;
end record; end record;
overriding function First (Item : ASN1_SeqOf_It) return ASN1_SeqOf_Ptr; overriding function First (Item : ASN1_SeqOf_It) return ASN1_SeqOf_Ptr;
overriding function Next (Item : ASN1_SeqOf_It; overriding function Next (Item : ASN1_SeqOf_It;
Ptr : ASN1_SeqOf_Ptr) return ASN1_SeqOf_Ptr; Ptr : ASN1_SeqOf_Ptr) return ASN1_SeqOf_Ptr;
function Iterate (self : ASN1_SeqOf) function Iterate (self : ASN1_SeqOf)
return Iterators_SeqOf.Forward_Iterator'Class; return Iterators_SeqOf.Forward_Iterator'Class;
function Element_SeqOf_Value (Self : ASN1_SeqOf; function Element_SeqOf_Value (Self : ASN1_SeqOf;
Ptr : ASN1_SeqOf_Ptr) Ptr : ASN1_SeqOf_Ptr)
return SeqOf is (self.Value); return SeqOf is (self.Value);
end; end;
package body ASN1_Iterators.Generic_SeqOf is package body ASN1_Iterators.Generic_SeqOf is
procedure Initialize (self: in out ASN1_Variable_SeqOf) is procedure Initialize (Self: in out ASN1_Variable_SeqOf) is
begin begin
self.value.length := self.length; Self.Value.Length := Self.Length;
if self.length >= 1 then if Self.Length >= 1 then
self.RestVal := new P.ASN1_SeqOf(Self.Length); Self.RestVal := new P.ASN1_SeqOf (Self.Length);
self.RestIt := Self.RestIt :=
new P.ASN1_SeqOf_It'(P.ASN1_SeqOf_It(Self.RestVal.Iterate)); new P.ASN1_SeqOf_It'(P.ASN1_SeqOf_It (Self.RestVal.Iterate));
self.RestIt.Ptr := self.RestIt.First; Self.RestIt.Ptr := Self.RestIt.First;
end if; end if;
end; end;
function Has_Element_Variable_SeqOf (Ptr: ASN1_Variable_SeqOf_Ptr) function Has_Element_Variable_SeqOf (Ptr : ASN1_Variable_SeqOf_Ptr)
return Boolean is (Length_Pkg.Has_Element(Length_Pkg.Ptr(Ptr.LenIt))); return Boolean is (Length_Pkg.Has_Element (Length_Pkg.Ptr (Ptr.LenIt)));
function Iterate (self : ASN1_Variable_SeqOf) function Iterate (Self : ASN1_Variable_SeqOf)
return Iterators_Variable_SeqOf.Forward_Iterator'Class is return Iterators_Variable_SeqOf.Forward_Iterator'Class is
begin begin
return I: ASN1_Variable_SeqOf_It do return I: ASN1_Variable_SeqOf_It do
I.Ptr := Self'Unrestricted_Access; I.Ptr := Self'Unrestricted_Access;
end return; end return;
end; end;
function First (Item : ASN1_Variable_SeqOf_It) function First (Item : ASN1_Variable_SeqOf_It)
return ASN1_Variable_SeqOf_Ptr is return ASN1_Variable_SeqOf_Ptr is
begin begin
-- Initialize the iterator (Compute first value) -- Initialize the iterator (Compute first value)
Item.Ptr.LenIt := Length_Pkg.Iterator(Item.Ptr.LenVal.Iterate); Item.Ptr.LenIt := Length_Pkg.Iterator (Item.Ptr.LenVal.Iterate);
-- Copy only the actual size, since the arrays may be different in size -- Copy only the actual size, since the arrays may be different in size
Item.Ptr.Value.Data (1 .. Item.Ptr.RestIt.Ptr.Value.Data'Length) := Item.Ptr.Value.Data (1 .. Item.Ptr.RestIt.Ptr.Value.Data'Length) :=
Item.Ptr.RestIt.Ptr.Value.Data; Item.Ptr.RestIt.Ptr.Value.Data;
return Item.Ptr; return Item.Ptr;
end; end;
function Next (Item : ASN1_Variable_SeqOf_It; function Next (Item : ASN1_Variable_SeqOf_It;
Ptr : ASN1_Variable_SeqOf_Ptr) Ptr : ASN1_Variable_SeqOf_Ptr)
return ASN1_Variable_SeqOf_Ptr return ASN1_Variable_SeqOf_Ptr
is is
pragma Unreferenced (Item); pragma Unreferenced (Item);
Ptr_elem : Length_Pkg.Iterator_Ptr := Length_Pkg.Ptr(Ptr.LenIt); Ptr_elem : Length_Pkg.Iterator_Ptr := Length_Pkg.Ptr(Ptr.LenIt);
begin begin
Ptr.RestIt.Ptr := Ptr.RestIt.Next (Ptr.RestIt.Ptr); Ptr.RestIt.Ptr := Ptr.RestIt.Next (Ptr.RestIt.Ptr);
if P.Has_Element_SeqOf (Ptr.RestIt.Ptr) then if P.Has_Element_SeqOf (Ptr.RestIt.Ptr) then
Ptr.Value.Data (1 .. Ptr.RestIt.Ptr.Value.Data'Length) := Ptr.Value.Data (1 .. Ptr.RestIt.Ptr.Value.Data'Length) :=
Ptr.RestIt.Ptr.Value.Data; Ptr.RestIt.Ptr.Value.Data;
else else
Ptr.RestIt.Ptr := Ptr.RestIt.First; Ptr.RestIt.Ptr := Ptr.RestIt.First;
-- Exhausted "rest": iterate on the first item -- Exhausted "rest": iterate on the first item
Ptr_elem := Ptr.LenIt.Next (Ptr_elem); Ptr_elem := Ptr.LenIt.Next (Ptr_elem);
if Length_Pkg.Has_Element (Ptr_elem) then if Length_Pkg.Has_Element (Ptr_elem) then
Ptr.Value.Length := Integer (Ptr_Elem.Value.Value); Ptr.Value.Length := Integer (Ptr_Elem.Value.Value);
Ptr.Length := Ptr.Value.Length; Ptr.Length := Ptr.Value.Length;
Ptr.RestVal := new P.ASN1_SeqOf(Ptr.Value.Length); Ptr.RestVal := new P.ASN1_SeqOf(Ptr.Value.Length);
Ptr.RestIt := Ptr.RestIt :=
new P.ASN1_SeqOf_It'(P.ASN1_SeqOf_It (Ptr.RestVal.Iterate)); new P.ASN1_SeqOf_It'(P.ASN1_SeqOf_It (Ptr.RestVal.Iterate));
Ptr.RestIt.Ptr := Ptr.RestIt.First; Ptr.RestIt.Ptr := Ptr.RestIt.First;
Ptr.Value.Data (1 .. Ptr.RestIt.Ptr.Value.Data'Length) := Ptr.Value.Data (1 .. Ptr.RestIt.Ptr.Value.Data'Length) :=
Ptr.RestIt.Ptr.Value.Data; Ptr.RestIt.Ptr.Value.Data;
end if; end if;
end if; end if;
return Ptr; return Ptr;
end; 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;
end; end;
...@@ -5,78 +5,93 @@ use Ada.Finalization; ...@@ -5,78 +5,93 @@ use Ada.Finalization;
with ASN1_Iterators.Generic_Fixed_SeqOf, with ASN1_Iterators.Generic_Fixed_SeqOf,
ASN1_Iterators.Generic_Integer, ASN1_Iterators.Generic_Integer,
ASN1_Iterators.Generic_Basic; ASN1_Iterators.Generic_Basic,
ASN1_Iterators.SimpleTypes;
with Interfaces; with Interfaces;
use Interfaces; use Interfaces;
-- Iterator for a variable-size array of basic type -- Iterator for a variable-size array of basic type
generic generic
Min : Natural; Min : Natural;
Max : Natural; Max : Natural;
with package Basic is new Generic_Basic (<>); with package Basic is new Generic_Basic (<>);
package ASN1_Iterators.Generic_SeqOf is package ASN1_Iterators.Generic_SeqOf is
Package P is new Generic_Fixed_SeqOF (P => Basic); Package P is new Generic_Fixed_SeqOF (P => Basic);
-- Create an integer type with a range constraint to iterate on -- Create an integer type with a range constraint to iterate on
package Length_ty is new Generic_Integer (Integer_64(Min), package Length_ty is new Generic_Integer (Integer_64(Min),
Integer_64(Max)); Integer_64(Max));
-- Instantiate the package to iterate on the integer for the length -- Instantiate the package to iterate on the integer for the length
package Length_Pkg renames Length_ty.It; package Length_Pkg renames Length_ty.It;
type ASN1_Variable_SeqOf_Ptr is private; type ASN1_Variable_SeqOf_Ptr is private;
subtype MySeqOf is P.SeqOf(Max); subtype MySeqOf is P.SeqOf(Max);
type ASN1_Variable_SeqOf is new Controlled type ASN1_Variable_SeqOf is new Controlled with record
with record Length : Natural := Min;
Length : Natural := Min; Value : MySeqOf; -- P.SeqOf(Max);
Value : MySeqOf; -- P.SeqOf(Max); -- Iterate on the length
-- Iterate on the length LenVal : Length_ty.Instance;
LenVal : Length_ty.Instance; LenIt : Length_Pkg.Iterator;
LenIt : Length_Pkg.Iterator; -- And on the value
-- And on the value RestVal : access P.ASN1_SeqOf;
RestVal : access P.ASN1_SeqOf; RestIt : access P.ASN1_SeqOf_It;
RestIt : access P.ASN1_SeqOf_It; end record
end record with Default_Iterator => Iterate,
with Default_Iterator => Iterate, Iterator_Element => MySeqOf, --P.SeqOf,
Iterator_Element => MySeqOf, --P.SeqOf, Constant_Indexing => Element_Variable_SeqOf_Value;
Constant_Indexing => Element_Variable_SeqOf_Value;
-- Constructor (called automatically)
-- Constructor (called automatically) procedure Initialize (Self: in out ASN1_Variable_SeqOf);
procedure Initialize(self: in out ASN1_Variable_SeqOf);
function Has_Element_Variable_SeqOf (Ptr : ASN1_Variable_SeqOf_Ptr)
function Has_Element_Variable_SeqOf (Ptr : ASN1_Variable_SeqOf_Ptr) return Boolean;
return Boolean;
package Iterators_Variable_SeqOf is
package Iterators_Variable_SeqOf is new Ada.Iterator_Interfaces (ASN1_Variable_SeqOf_Ptr,
new Ada.Iterator_Interfaces (ASN1_Variable_SeqOf_Ptr, Has_Element_Variable_SeqOf);
Has_Element_Variable_SeqOf);
type ASN1_Variable_SeqOf_It is
type ASN1_Variable_SeqOf_It new Iterators_Variable_SeqOf.Forward_Iterator with record
is new Iterators_Variable_SeqOf.Forward_Iterator with record
Ptr : ASN1_Variable_SeqOf_Ptr; Ptr : ASN1_Variable_SeqOf_Ptr;
end record; end record;
overriding overriding
function First (Item : ASN1_Variable_SeqOf_It) function First (Item : ASN1_Variable_SeqOf_It)
return ASN1_Variable_SeqOf_Ptr; return ASN1_Variable_SeqOf_Ptr;
overriding overriding
function Next (Item : ASN1_Variable_SeqOf_It; function Next (Item : ASN1_Variable_SeqOf_It;
Ptr : ASN1_Variable_SeqOf_Ptr) Ptr : ASN1_Variable_SeqOf_Ptr)
return ASN1_Variable_SeqOf_Ptr; return ASN1_Variable_SeqOf_Ptr;
function Iterate (self : ASN1_Variable_SeqOf) function Iterate (Self : ASN1_Variable_SeqOf)
return Iterators_Variable_SeqOf.Forward_Iterator'Class; return Iterators_Variable_SeqOf.Forward_Iterator'Class;
function Element_Variable_SeqOf_Value (Self : ASN1_Variable_SeqOf; function Element_Variable_SeqOf_Value (Self : ASN1_Variable_SeqOf;
Ptr : ASN1_Variable_SeqOf_Ptr) Ptr : ASN1_Variable_SeqOf_Ptr)
--return P.SeqOf is (Self.Value); return MySeqOf is (Self.Value);
return MySeqOf is (Self.Value);
subtype Instance is ASN1_Variable_SeqOf;
subtype Instance is ASN1_Variable_SeqOf;
-- Export as a simple type, to enable iteration such as Seq of SeqOf
private -- (since Generic_SeqOf takes a Generic_Basic as parameter)
type ASN1_Variable_SeqOf_Ptr is access all ASN1_Variable_SeqOf; -- NOTE : this compiles but I have not tested it yet...
function Simple_Init return Instance;
function Simple_Has_Elem (Value : Instance) return Boolean;
function Simple_First return Instance;
function Simple_Next (Value : Instance) return Instance;
package Simple_Generic_SeqOf is new SimpleTypes
(Sort => Instance,
Elem_Init => Simple_Init,
Has_Elem => Simple_Has_Elem,
Elem_First => Simple_First,
Elem_Next => Simple_Next);
package It is new Generic_Basic (P => Simple_Generic_SeqOf);
subtype Generic_Instance is It.Basic_ASN1_Iterator;
private
type ASN1_Variable_SeqOf_Ptr is access all ASN1_Variable_SeqOf;
end; end;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment