...
 
Commits (3)
......@@ -6,7 +6,7 @@ Author/Contact: Maxime.Perrotin@esa.int
Generic iterator functions in Ada for generating all combinations of values of ASN.1 data types
Support integer, enumerated, sequence, sequence of (fixed and variable sizes)
Support integer, enumerated, sequence, sequence of (fixed and variable sizes), choice, real, boolean
Work in progress... Part of the TASTE project.
......@@ -38,8 +38,7 @@ package body ASN1_Iterators.Generic_Basic is
return Position;
end;
function Iterate (Container : ASN1_Container)
return Forward_Iterator is
function Iterate (Container : ASN1_Container) return Iterator'Class is
begin
return I: Iterator do
I.Position := Container'Unrestricted_Access;
......
......@@ -33,13 +33,11 @@ package ASN1_Iterators.Generic_Basic is
function Get_Cursor (Item : Iterator) return Cursor is (Item.Position);
overriding function First (Item : Iterator) return Cursor;
overriding function Next (Item : Iterator;
overriding function First (Item : Iterator) return Cursor;
overriding function Next (Item : Iterator;
Position : Cursor) return Cursor;
subtype Forward_Iterator is Iterators.Forward_Iterator'Class;
function Iterate (Container : ASN1_Container) return Forward_Iterator;
function Iterate (Container : ASN1_Container) return Iterator'Class;
function Element (Container : ASN1_Container;
Position : Cursor)
......
......@@ -15,7 +15,7 @@ package body ASN1_Iterators.Generic_Fixed_SeqOf is
function Has_Element (Position: Cursor) return Boolean is
Result : constant Boolean :=
(P.Has_Element(P.Get_Cursor (Position.FirstIt)));
(Elem_Has_Element (Elem_It_Get_Cursor (Position.FirstIt)));
begin
-- Ada.Text_IO.Put_Line ("Has_element in Fixed_SeqOF: " & Result'Img);
return Result;
......@@ -30,13 +30,18 @@ package body ASN1_Iterators.Generic_Fixed_SeqOf is
end;
function First (Item : Iterator) return Cursor is
Elem_Cursor : P.Cursor := P.Get_Cursor (Get_Cursor (Item).FirstIt);
Elem_Cursor : Element_Cursor :=
Elem_It_Get_Cursor (Get_Cursor (Item).FirstIt);
begin
-- Initialize the iterator (Compute first value)
Item.Position.FirstIt := P.Iterator (Item.Position.FirstVal.Iterate);
Elem_Cursor := P.First (Item.Position.FirstIt);
Item.Position.Value.Data (1) := P.Element (Item.Position.FirstVal,
Elem_Cursor);
Item.Position.FirstIt :=
Element_Iterator (Elem_Iterate (Item.Position.FirstVal));
Elem_Cursor := Elem_First (Item.Position.FirstIt);
Item.Position.Value.Data (1) := Elem_Element (Item.Position.FirstVal,
Elem_Cursor);
if Item.Position.Length > 1 then
Item.Position.Value.Data (2 .. Item.Position.Length) :=
Item.Position.RestIt.Position.Value.Data
......@@ -48,7 +53,7 @@ package body ASN1_Iterators.Generic_Fixed_SeqOf is
function Next (Item : Iterator;
Position : Cursor) return Cursor is
pragma Unreferenced (Item);
Ptr_elem : P.Cursor := P.Get_Cursor (Position.FirstIt);
Ptr_elem : Element_Cursor := Elem_It_Get_Cursor (Position.FirstIt);
begin
if Position.Length > 1 then
Position.RestIt.Position := Position.RestIt.Next
......@@ -60,10 +65,10 @@ package body ASN1_Iterators.Generic_Fixed_SeqOf is
else
Position.RestIt.Position := Position.RestIt.First;
-- Exhausted "rest": iterate on the first item
Ptr_elem := P.Next(Position.FirstIt, Ptr_elem);
if P.Has_Element (Ptr_elem) then
Ptr_elem := Elem_Next (Position.FirstIt, Ptr_elem);
if Elem_Has_Element (Ptr_elem) then
Position.Value.Data (1) :=
P.Element (Position.FirstVal, Ptr_elem);
Elem_Element (Position.FirstVal, Ptr_elem);
Position.Value.Data (2 .. Position.Length) :=
Position.RestIt.Position.Value.Data
(1 .. Position.RestIt.Position.Length);
......@@ -71,9 +76,10 @@ package body ASN1_Iterators.Generic_Fixed_SeqOf is
end if;
else
-- Size is 0 or 1
Ptr_elem := P.Next (Position.FirstIt, Ptr_elem);
if P.Has_Element (Ptr_elem) then
Position.Value.Data (1) := P.Element (Position.FirstVal, Ptr_elem);
Ptr_elem := Elem_Next (Position.FirstIt, Ptr_elem);
if Elem_Has_Element (Ptr_elem) then
Position.Value.Data (1) := Elem_Element (Position.FirstVal,
Ptr_elem);
end if;
end if;
return Position;
......
......@@ -7,10 +7,27 @@ with ASN1_Iterators.Generic_Basic;
with ASN1_Iterators.SimpleTypes;
generic
with package P is new Generic_Basic (<>);
-- with package P is new Generic_Basic (<>);
type Element_Sort is private;
type Element_Container is new Controlled with private;
type Element_Cursor is access all Element_Container;
with package Element_Iterators is new Ada.Iterator_Interfaces (<>);
type Element_Iterator is new Element_Iterators.Forward_Iterator
with private;
with function Elem_It_Get_Cursor (Elem : Element_Iterator)
return Element_Cursor;
with function Elem_Has_Element (Elem : Element_Cursor) return Boolean;
with function Elem_Iterate (Container : Element_Container)
return Element_Iterator'Class;
-- return Element_Iterators.Forward_Iterator'Class;
with function Elem_First (Item : Element_Iterator) return Element_Cursor;
with function Elem_Next (Item : Element_Iterator; Position : Element_Cursor)
return Element_Cursor;
with function Elem_Element (Container : Element_Container;
Position : Element_Cursor) return Element_Sort;
package ASN1_Iterators.Generic_Fixed_SeqOf is
type DataArray is array (natural range <>) of P.Sort;
type DataArray is array (natural range <>) of Element_Sort; --P.Sort;
type SeqOf (Max : Natural) is record
Length : Integer;
......@@ -25,8 +42,8 @@ package ASN1_Iterators.Generic_Fixed_SeqOf is
Length : Natural := Size;
Value : SeqOf (Size);
-- First value
FirstVal : P.ASN1_Container;
FirstIt : P.Iterator;
FirstVal : Element_Container; -- P.ASN1_Container;
FirstIt : Element_Iterator; -- P.Iterator;
-- The rest (recursive)
Rest : access ASN1_Container;
RestIt : access Iterator;
......
......@@ -14,10 +14,39 @@ use Interfaces;
generic
Min : Natural;
Max : Natural;
with package Basic is new Generic_Basic (<>);
-- with package Basic is new Generic_Basic (<>);
type Element_Sort is private;
type Element_Container is new Controlled with private;
type Element_Cursor is access all Element_Container;
with package Element_Iterators is new Ada.Iterator_Interfaces (<>);
type Element_Iterator is new Element_Iterators.Forward_Iterator
with private;
with function Elem_It_Get_Cursor (Elem : Element_Iterator)
return Element_Cursor;
with function Elem_Has_Element (Elem : Element_Cursor) return Boolean;
with function Elem_Iterate (Container : Element_Container)
return Element_Iterator'Class;
-- return Element_Iterators.Forward_Iterator'Class;
with function Elem_First (Item : Element_Iterator) return Element_Cursor;
with function Elem_Next (Item : Element_Iterator; Position : Element_Cursor)
return Element_Cursor;
with function Elem_Element (Container : Element_Container;
Position : Element_Cursor) return Element_Sort;
package ASN1_Iterators.Generic_SeqOf is
package P is new Generic_Fixed_SeqOF (P => Basic);
package P is new Generic_Fixed_SeqOF
(Element_Sort,
Element_Container,
Element_Cursor,
Element_Iterators,
Element_Iterator,
Elem_It_Get_Cursor,
Elem_Has_Element,
Elem_Iterate,
Elem_First,
Elem_Next,
Elem_Element);
-- Create an integer type with a range constraint to iterate on
subtype Len_Sort is Natural range Min .. Max;
function Init_Len return Len_Sort is (Min);
......
This diff is collapsed.
......@@ -36,11 +36,26 @@ MyChoice ::= CHOICE {
choice-b MySeqOf
}
-- Simple boolean
Boolean ::= BOOLEAN
-- Real with disjoint set of values
MyReal ::= REAL (0.2 .. 1.5 | 10.5 .. 14.5)
-- Integer with disjoint set of values
MyInt2 ::= INTEGER (-5 .. 0 | 10 | 20 .. 25 | 27 | 29)
-- Array of any type
SeqOfSeq ::= SEQUENCE (SIZE (2)) OF MySeq3
-- Sequence with a field of type SEQUENCE
MySeq5 ::= SEQUENCE {
a MySeq3
}
-- Choice with a field of type SEQUENCE
MyChoice2 ::= CHOICE {
a MySeq3
}
END
......@@ -9,20 +9,6 @@ use Ada.Text_IO;
procedure test_generic is
-- THIS IS HOW TO DO IT MANUALLY:
-- -- create an Integer type with a range constraint
-- package MyInteger is new Generic_Integer (1, 4);
--
-- -- create an iterator for a variable size array of integers
-- Package MyVarSeqOf_Pkg is new Generic_SeqOf (Min => 1,
-- Max => 5,
-- Basic => MyInteger.It);
--
-- -- create an iterator for an array of integers as defined above
-- Package MySeqOF_Pkg is new Generic_SeqOf (Min => 3,
-- Max => 3,
-- Basic => MyInteger.It);
--
use MyInteger_Pkg;
use MySeqOf_Pkg;
use MyVarSeqOf_Pkg;
......@@ -33,6 +19,9 @@ procedure test_generic is
use MySeq3_Pkg;
use MySeq4_Pkg;
use MyChoice_Pkg;
use MySeq5_Pkg;
use MyChoice2_Pkg;
use SeqOfSeq_Pkg;
-- Test cases
MyIt : MyInteger_Pkg.Instance;
......@@ -48,10 +37,10 @@ procedure test_generic is
Bool : Boolean_Pkg.Instance;
Real : MyReal_Pkg.Instance;
MyInt2 : MyInt2_Pkg.Instance;
Seq5 : MySeq5_Pkg.Instance;
Choice2 : MyChoice2_Pkg.Instance;
ArraySeq : SeqOfSeq_Pkg.Instance;
SeqOfItm : asn1SccMySeqOf;
VarSeqOfItm : asn1SccMyVarSeqOf;
SeqOfEnumItm : asn1SccMySeqOfEnum;
i : Natural := 1;
count : Natural := 0;
package F_IO is new Ada.Text_IO.Float_IO (asn1SccMyReal);
......@@ -60,15 +49,13 @@ begin
-- test: compute all possible values of the integer type
-- (equivalent to "for each in 1..3 loop put_line(each'img); end loop;")
for each of MyIt loop
-- Put_Line(each'img);
Put_Line (Image (each));
end loop;
-- test: compute all combinations of values for the fixed-size array
Put_Line ("Variable-size array:");
for each of Var_SeqOf loop
To_ASN1 (From => each, To => VarSeqOfItm);
Put (Image (VarSeqOfItm));
Put (Image (To_ASN1 (each)) & " ");
i := (if i mod 10 = 0 then 1 else i + 1);
if i = 1 then
New_Line;
......@@ -80,8 +67,7 @@ begin
Put_Line ("Fixed-size array:");
i := 1;
for each of Fixed_SeqOf loop
To_ASN1 (From => each, To => SeqOfItm);
Put (Image (SeqOfItm));
Put (Image (To_ASN1 (each)) & " ");
i := (if i mod 10 = 0 then 1 else i + 1);
if i = 1 then
New_Line;
......@@ -96,9 +82,8 @@ begin
New_Line;
Put_Line ("Sequence of Enumerated type");
for Each of SeqOfEnum loop
To_ASN1 (From => Each, To => SeqOfEnumItm);
Put (Image (SeqOfEnumItm) & " ");
for each of SeqOfEnum loop
Put (Image (To_ASN1 (each)) & " ");
end loop;
New_Line;
New_Line;
......@@ -122,7 +107,7 @@ begin
end if;
end loop;
New_Line;
Put_Line ("total: " & count'img & " values were computed");
Put_Line ("total: " & count'Img & " values were computed");
New_Line;
Put_Line ("Sequence with two enums field");
......@@ -194,5 +179,24 @@ begin
Put (each'Img & " ");
end loop;
New_Line;
New_Line;
Put_Line ("SEQUENCE WITH A SINGLE SEQUENCE FIELD");
for each of Seq5 loop
Put (Image (each) & " ");
end loop;
New_Line;
New_Line;
Put_Line ("CHOICE WITH A SINGLE SEQUENCE OPTION");
for each of Choice2 loop
Put (Image (each) & " ");
end loop;
New_Line;
New_Line;
Put_Line ("SEQUENCE OF SEQUENCE (Fixed size)");
for each of ArraySeq loop
Put (Image (To_ASN1 (each)));
Put (" ");
end loop;
New_Line;
end test_generic;