...
 
Commits (3)
......@@ -14,7 +14,7 @@ install: uninstall
test_build: clean install
mkdir -p build_test
cp test/DataView.asn build_test
cd build_test && taste-asn1-iterators DataView.asn
cd build_test && taste-asn1-iterators -g DataView.asn
gprbuild -p -P test_generic.gpr
test: test_build
......@@ -26,5 +26,6 @@ uninstall:
clean:
gprclean test_generic.gpr || :
gprclean asn1_iterators.gpr || :
rm -rf obj build_test
.PHONY: all clean install test test_build
......@@ -5,15 +5,15 @@ package body ASN1_Iterators.Generic_Basic is
-- When iterating, the sequence of call is:
-- First : Set the first value, set validity flag to true
-- Has_Element : Check if the element is valid, e.g. for an integer, <= Max
-- Elem_Value : Return the value that was set
-- Element : Return the value that was set
-- Next : Compute and set the next value
-- Next can raise an exception, after the last value, to set a validity
-- flag used by Has_Element.
procedure Initialize (Self : in out Basic_ASN1_Iterator) is
procedure Initialize (Container : in out ASN1_Container) is
begin
Self.Value.Initialize;
Self.Is_Valid := True;
Container.Value.Initialize;
Container.Is_Valid := True;
end;
function Has_Element (Position : Cursor) return Boolean is
......@@ -38,11 +38,11 @@ package body ASN1_Iterators.Generic_Basic is
return Position;
end;
function Iterate (Self : Basic_ASN1_Iterator)
function Iterate (Container : ASN1_Container)
return Forward_Iterator is
begin
return I: Iterator do
I.Position := Self'Unrestricted_Access;
I.Position := Container'Unrestricted_Access;
end return;
end;
end;
......@@ -9,18 +9,18 @@ package ASN1_Iterators.Generic_Basic is
-- Provides an iterator for a basic type
subtype Sort is P.Sort;
type Basic_ASN1_Iterator is new Controlled
type ASN1_Container is new Controlled
with record
Value : P.SimpleType;
Is_Valid : Boolean := True;
end record
with Default_Iterator => Iterate,
Iterator_Element => P.Sort,
Constant_Indexing => Elem_Value;
Constant_Indexing => Element;
procedure Initialize (self: in out Basic_ASN1_Iterator);
procedure Initialize (Container : in out ASN1_Container);
type Cursor is access all Basic_ASN1_Iterator;
type Cursor is access all ASN1_Container;
function Has_Element (Position : Cursor) return Boolean;
......@@ -39,9 +39,9 @@ package ASN1_Iterators.Generic_Basic is
subtype Forward_Iterator is Iterators.Forward_Iterator'Class;
function Iterate (Self : Basic_ASN1_Iterator) return Forward_Iterator;
function Iterate (Container : ASN1_Container) return Forward_Iterator;
function Elem_Value (Self : Basic_ASN1_Iterator;
Position : Cursor)
function Element (Container : ASN1_Container;
Position : Cursor)
return P.Sort is (Position.Value.Element_Value);
end ASN1_Iterators.Generic_Basic;
......@@ -22,5 +22,5 @@ package ASN1_Iterators.Generic_Enumerated is
package It is new Generic_Basic (P => Discrete_Type);
subtype Instance is It.Basic_ASN1_Iterator;
subtype Instance is It.ASN1_Container;
end ASN1_Iterators.Generic_Enumerated;
with Ada.Unchecked_Conversion;
-- with Ada.Text_IO;
package body ASN1_Iterators.Generic_Fixed_SeqOf is
procedure Initialize (Self: in out ASN1_SeqOf) is
procedure Initialize (Container : in out ASN1_Container) is
begin
Self.Value.Length := Self.Length;
if Self.Length > 1 then
Self.Rest := new ASN1_SeqOf (self.Length - 1);
Self.RestIt := new ASN1_SeqOf_It'(ASN1_SeqOf_It (Self.Rest.Iterate));
Self.RestIt.Position := Self.RestIt.First;
Container.Value.Length := Container.Length;
if Container.Length > 1 then
Container.Rest := new ASN1_Container (Container.Length - 1);
Container.RestIt := new Iterator'(Iterator (Container.Rest.Iterate));
Container.RestIt.Position := Container.RestIt.First;
end if;
end;
function Has_Element_SeqOf (Position: Cursor) return Boolean is
(P.Has_Element(P.Get_Cursor (Position.FirstIt)));
function Has_Element (Position: Cursor) return Boolean is
Result : constant Boolean :=
(P.Has_Element(P.Get_Cursor (Position.FirstIt)));
begin
-- Ada.Text_IO.Put_Line ("Has_element in Fixed_SeqOF: " & Result'Img);
return Result;
end Has_Element;
function Iterate (Self : ASN1_SeqOf)
return ASN1_SeqOf_It'Class is --Iterators_SeqOf.Forward_Iterator'Class is
function Iterate (Container : ASN1_Container)
return Iterator'Class is
begin
return I: ASN1_SeqOf_It do
I.Position := Self'Unrestricted_Access;
return I: Iterator do
I.Position := Container'Unrestricted_Access;
end return;
end;
function First (Item : ASN1_SeqOf_It) return Cursor is
Ptr_Elem : P.Cursor := P.Get_Cursor (Item.Position.FirstIt);
function First (Item : Iterator) return Cursor is
Elem_Cursor : P.Cursor := P.Get_Cursor (Get_Cursor (Item).FirstIt);
begin
-- Initialize the iterator (Compute first value)
Item.Position.FirstIt := P.Iterator (Item.Position.FirstVal.Iterate);
Ptr_Elem := P.First (Item.Position.FirstIt);
Item.Position.Value.Data (1) := P.Elem_Value (Item.Position.FirstVal,
Ptr_elem);
Elem_Cursor := P.First (Item.Position.FirstIt);
Item.Position.Value.Data (1) := P.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 (1 .. Item.Position.RestIt.Position.Length);
Item.Position.RestIt.Position.Value.Data
(1 .. Item.Position.RestIt.Position.Length);
end if;
return Item.Position;
end;
function Next (Item : ASN1_SeqOf_It;
function Next (Item : Iterator;
Position : Cursor) return Cursor is
pragma Unreferenced (Item);
Ptr_elem : P.Cursor := P.Get_Cursor (Position.FirstIt);
begin
if Position.Length > 1 then
Position.RestIt.Position := Position.RestIt.Next (Position.RestIt.Position);
if Has_Element_SeqOf (Position.RestIt.Position) then
Position.RestIt.Position := Position.RestIt.Next
(Position.RestIt.Position);
if Has_Element (Position.RestIt.Position) then
Position.Value.Data (2 .. Position.Length) :=
Position.RestIt.Position.Value.Data (1 .. Position.RestIt.Position.Value.Length);
Position.RestIt.Position.Value.Data
(1 .. Position.RestIt.Position.Value.Length);
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
Position.Value.Data (1) := P.Elem_Value (Position.FirstVal, Ptr_elem);
Position.Value.Data (1) :=
P.Element (Position.FirstVal, Ptr_elem);
Position.Value.Data (2 .. Position.Length) :=
Position.RestIt.Position.Value.Data (1 .. Position.RestIt.Position.Length);
Position.RestIt.Position.Value.Data
(1 .. Position.RestIt.Position.Length);
end if;
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.Elem_Value (Position.FirstVal, Ptr_elem);
Position.Value.Data (1) := P.Element (Position.FirstVal, Ptr_elem);
end if;
end if;
return Position;
......
......@@ -18,45 +18,47 @@ package ASN1_Iterators.Generic_Fixed_SeqOf is
end record;
type Cursor;
type ASN1_SeqOf_It;
type Iterator;
type ASN1_SeqOf (Size : Natural) is new Controlled
type ASN1_Container (Size : Natural) is new Controlled
with record
Length : Natural := Size;
Value : SeqOf (Size);
-- First value
FirstVal : P.Basic_ASN1_Iterator;
FirstVal : P.ASN1_Container;
FirstIt : P.Iterator;
-- The rest (recursive)
Rest : access ASN1_SeqOf;
RestIt : access ASN1_SeqOf_It;
Rest : access ASN1_Container;
RestIt : access Iterator;
end record
with Default_Iterator => Iterate,
Iterator_Element => SeqOf,
Constant_Indexing => Element_SeqOf_Value;
Constant_Indexing => Element;
type Cursor is access all ASN1_SeqOf;
type Cursor is access all ASN1_Container;
-- Constructor (called automatically)
procedure Initialize (Self : in out ASN1_SeqOf);
procedure Initialize (Container : in out ASN1_Container);
function Has_Element_SeqOf (Position : Cursor) return Boolean;
function Has_Element (Position : Cursor) return Boolean;
package Iterators_SeqOf is
new Ada.Iterator_Interfaces (Cursor, Has_Element_SeqOf);
package Iterators is
new Ada.Iterator_Interfaces (Cursor, Has_Element);
type ASN1_SeqOf_It is new Iterators_SeqOf.Forward_Iterator with record
type Iterator is new Iterators.Forward_Iterator with record
Position : Cursor;
end record;
overriding function First (Item : ASN1_SeqOf_It) return Cursor;
overriding function Next (Item : ASN1_SeqOf_It;
function Get_Cursor (Item : Iterator) return Cursor is (Item.Position);
overriding function First (Item : Iterator) return Cursor;
overriding function Next (Item : Iterator;
Position : Cursor) return Cursor;
function Iterate (self : ASN1_SeqOf)
return ASN1_SeqOf_It'Class;
function Iterate (Container : ASN1_Container)
return Iterator'Class;
function Element_SeqOf_Value (Self : ASN1_SeqOf;
Position : Cursor)
return SeqOf is (self.Value);
function Element (Container : ASN1_Container;
Position : Cursor)
return SeqOf is (Container.Value);
end ASN1_Iterators.Generic_Fixed_SeqOf;
......@@ -27,5 +27,5 @@ package ASN1_Iterators.Generic_Integer is
package It is new Generic_Basic (P => Signed_Integer);
subtype Instance is It.Basic_ASN1_Iterator;
subtype Instance is It.ASN1_Container;
end ASN1_Iterators.Generic_Integer;
package body ASN1_Iterators.Generic_Iterator is
-- procedure Initialize (Self: in out Generic_Iterator_Type) is
-- begin
-- Self.Item.Initialize;
-- Self.Item.Value := ASN1_Iterable.First(ASN1_Iterable.Iterable'Class(Self.Item));
-- end;
function First (Item : Iterator) return Cursor is
C: constant Cursor := Item.Position;
begin
C.Item.Value := ASN1_Iterable.First(ASN1_Iterable.Iterable'Class(Item.Position.all.Item));
return C;
end;
function Next (Item : Iterator;
Position : Cursor)
return Cursor is
C: constant Cursor := Item.Position;
begin
C.Item.Value := ASN1_Iterable.Next(ASN1_Iterable.Iterable'Class(Position.all.Item));
return C;
end;
function Iterate (self : Generic_Iterator_Type)
return Iterators.Forward_Iterator'Class is
begin
return I: Iterator do
I.Position := self'Unrestricted_Access;
end return;
end;
end;
with Ada.Iterator_Interfaces,
Ada.Finalization,
ASN1_Iterators.Iterable_Type;
use Ada.Finalization;
generic
type ASN1_Type is private;
with package ASN1_Iterable is new ASN1_Iterators.Iterable_Type (ASN1_Type);
type Actual_Iterable is new ASN1_Iterable.Iterable with private;
package ASN1_Iterators.Generic_Iterator is
type Generic_Iterator_Type is tagged --new Controlled with
record
Item: Actual_Iterable;
end record
with Default_Iterator => Iterate,
Iterator_Element => ASN1_Type,
Constant_Indexing => Elem;
type Cursor is access all Generic_Iterator_Type;
function Elem (Self : Generic_Iterator_Type; Position : Cursor)
return ASN1_Type is (Position.Item.Element);
function Has_Element (Position : Cursor) return Boolean is
(ASN1_Iterable.Has_Element(ASN1_Iterable.Iterable'Class(Position.all.Item)));
package Iterators is new Ada.Iterator_Interfaces (Cursor, Has_Element);
type Iterator is new Iterators.Forward_Iterator with record
Position : Cursor;
end record;
--overriding
--procedure Initialize (Self: in out Generic_Iterator_Type);
overriding
function First (Item : Iterator) return Cursor;
overriding
function Next (Item : Iterator;
Position : Cursor)
return Cursor;
function Iterate (self : Generic_Iterator_Type)
return Iterators.Forward_Iterator'Class;
end;
-- with Ada.Text_IO;
package body ASN1_Iterators.Generic_SeqOf is
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.Position := self.RestIt.First;
procedure Initialize (Container : in out ASN1_Container) is
begin
Container.LenIt := Length_Pkg.Iterator (Container.LenVal.Iterate);
Container.Value.Length := Container.Length;
if Container.Length >= 1 then
Container.RestVal := new P.ASN1_Container (Container.Length);
Container.RestIt :=
new P.Iterator'(P.Iterator (Container.RestVal.Iterate));
Container.RestIt.Position := Container.RestIt.First;
end if;
end;
end Initialize;
function Has_Element_Variable_SeqOf
(Position : Cursor)
return Boolean is
(Length_Pkg.Has_Element(Length_Pkg.Get_Cursor (Position.LenIt)));
function Has_Element (Position : Cursor) return Boolean is
Result : constant Boolean := (Length_Pkg.Has_Element
(Length_Pkg.Get_Cursor (Position.LenIt)));
begin
-- Ada.Text_IO.Put_Line ("Generic_SeqOF.Has_Element: " & Result'Img);
return Result;
end Has_element;
function Iterate (self : ASN1_Variable_SeqOf)
return Iterators_Variable_SeqOf.Forward_Iterator'Class is
begin
return I: ASN1_Variable_SeqOf_It do
I.Position := Self'Unrestricted_Access;
end return;
end;
function First (Item : ASN1_Variable_SeqOf_It)
return Cursor is
begin
-- Initialize the iterator (Compute first value)
Item.Position.LenIt :=
Length_Pkg.Iterator(Item.Position.LenVal.Iterate);
function Iterate (Container : ASN1_Container)
return Iterators.Forward_Iterator'Class is
begin
return I : Iterator do
I.Position := Container'Unrestricted_Access;
end return;
end Iterate;
function First (Item : Iterator) return Cursor is
unused_Cursor_len : Length_Pkg.Cursor := Item.Position.LenIt.First;
begin
-- Copy only the actual size, since the arrays may be different in size
Item.Position.Value.Data
(1 .. Item.Position.RestIt.Position.Value.Data'Length) :=
Item.Position.RestIt.Position.Value.Data;
return Item.Position;
end;
end;
function Next (Item : ASN1_Variable_SeqOf_It;
function Next (Item : Iterator;
Position : Cursor)
return Cursor
is
......@@ -46,8 +50,9 @@ package body ASN1_Iterators.Generic_SeqOf is
Position_elem : Length_Pkg.Cursor :=
Length_Pkg.Get_Cursor (Position.LenIt);
begin
Position.RestIt.Position := Position.RestIt.Next (Position.RestIt.Position);
if P.Has_Element_SeqOf (Position.RestIt.Position) then
Position.RestIt.Position :=
Position.RestIt.Next (Position.RestIt.Position);
if P.Has_Element (Position.RestIt.Position) then
Position.Value.Data
(1 .. Position.RestIt.Position.Value.Data'Length) :=
Position.RestIt.Position.Value.Data;
......@@ -58,10 +63,10 @@ package body ASN1_Iterators.Generic_SeqOf is
if Length_Pkg.Has_Element (Position_elem) then
Position.Value.Length := Integer (Position_Elem.Value.Value);
Position.Length := Position.Value.Length;
Position.RestVal := new P.ASN1_SeqOf(Position.Value.Length);
Position.RestVal :=
new P.ASN1_Container (Position.Value.Length);
Position.RestIt :=
new P.ASN1_SeqOf_It'(P.ASN1_SeqOf_It
(Position.RestVal.Iterate));
new P.Iterator'(P.Iterator (Position.RestVal.Iterate));
Position.RestIt.Position := Position.RestIt.First;
Position.Value.Data
(1 .. Position.RestIt.Position.Value.Data'Length) :=
......@@ -71,4 +76,3 @@ package body ASN1_Iterators.Generic_SeqOf is
return Position;
end;
end ASN1_Iterators.Generic_SeqOF;
......@@ -26,7 +26,7 @@ package ASN1_Iterators.Generic_SeqOf is
type Cursor is private;
subtype Sequence_Of is P.SeqOf (Max);
type ASN1_Variable_SeqOf is new Controlled
type ASN1_Container is new Controlled
with record
Length : Natural := Min;
Value : Sequence_Of;
......@@ -34,47 +34,42 @@ package ASN1_Iterators.Generic_SeqOf is
LenVal : Length_ty.Instance;
LenIt : Length_Pkg.Iterator;
-- And on the value
RestVal : access P.ASN1_SeqOf;
RestIt : access P.ASN1_SeqOf_It;
RestVal : access P.ASN1_Container;
RestIt : access P.Iterator;
end record
with Default_Iterator => Iterate,
Iterator_Element => Sequence_Of,
Constant_Indexing => Element_Variable_SeqOf_Value;
Constant_Indexing => Element;
-- Constructor (called automatically)
procedure Initialize (Self : in out ASN1_Variable_SeqOf);
procedure Initialize (Container : in out ASN1_Container);
function Has_Element (Position : Cursor) return Boolean;
package Iterators is new Ada.Iterator_Interfaces (Cursor, Has_Element);
function Has_Element_Variable_SeqOf (Position : Cursor)
return Boolean;
type Iterator is new Iterators.Forward_Iterator with record
Position : Cursor;
end record;
package Iterators_Variable_SeqOf is
new Ada.Iterator_Interfaces (Cursor,
Has_Element_Variable_SeqOf);
type ASN1_Variable_SeqOf_It
is new Iterators_Variable_SeqOf.Forward_Iterator with record
Position : Cursor;
end record;
function Get_Cursor (Item : Iterator) return Cursor is (Item.Position);
overriding
function First (Item : ASN1_Variable_SeqOf_It)
return Cursor;
function First (Item : Iterator) return Cursor;
overriding
function Next (Item : ASN1_Variable_SeqOf_It;
function Next (Item : Iterator;
Position : Cursor)
return Cursor;
function Iterate (self : ASN1_Variable_SeqOf)
return Iterators_Variable_SeqOf.Forward_Iterator'Class;
function Iterate (Container : ASN1_Container)
return Iterators.Forward_Iterator'Class;
function Element_Variable_SeqOf_Value (Self : ASN1_Variable_SeqOf;
Position : Cursor)
return Sequence_Of is (Self.Value);
function Element (Container : ASN1_Container;
Position : Cursor)
return Sequence_Of is (Container.Value);
subtype Instance is ASN1_Variable_SeqOf;
subtype Instance is ASN1_Container;
private
type Cursor is access all ASN1_Variable_SeqOf;
type Cursor is access all ASN1_Container;
end ASN1_Iterators.Generic_SeqOF;
......@@ -24,5 +24,5 @@ package ASN1_Iterators.Generic_Unsigned_Integer is
package It is new Generic_Basic (P => Unsigned_Type);
subtype Instance is It.Basic_ASN1_Iterator;
subtype Instance is It.ASN1_Container;
end ASN1_Iterators.Generic_Unsigned_Integer;
with Interfaces;
use Interfaces;
with ASN1_Iterators.Iterable_Type;
with ASN1_Iterators.Generic_Iterator;
generic
Min, Max: Integer_64;
package ASN1_Iterators.Iterable_Integer is
package Pkg is new ASN1_Iterators.Iterable_type (Integer_64);
type ASN1_Integer is new Pkg.Iterable with null record;
overriding
procedure Initialize (It: in out ASN1_Integer) is null;
overriding
function Has_Element (It: ASN1_Integer) return Boolean is
(It.Value <= Max);
overriding
function First (It: in out ASN1_Integer) return Integer_64 is
(Min);
overriding
function Next (It: ASN1_Integer) return Integer_64 is
(It.Value + 1);
package Custom_Iterator is new ASN1_Iterators.Generic_Iterator
(ASN1_Type => Integer_64,
ASN1_Iterable => Pkg,
Actual_Iterable => ASN1_Integer);
subtype Instance is Custom_Iterator.Generic_Iterator_Type;
-- If it is needed to iterate manually, provide Cursor and Iterator:
subtype Cursor is Custom_Iterator.Cursor;
subtype Iterator is Custom_Iterator.Iterators.Forward_Iterator'Class;
function Has_Element (Position : Cursor) return Boolean
renames Custom_Iterator.Has_Element;
end;
with Ada.Text_IO;
use Ada.Text_IO;
with Ada.Iterator_Interfaces;
package body ASN1_Iterators.Iterable_SeqOF is
procedure Initialize (It: in out ASN1_SequenceOf) is
begin
null;
-- deprecated
end;
function Has_Element (It: ASN1_SequenceOf) return Boolean is
begin
return False;
end;
function First (It: in out ASN1_SequenceOf) return Generic_SeqOf is
Ret : constant Generic_SeqOf := It.Value;
begin
It.Value.Length := It.Length;
Put_Line ("Computing first of length " & It.Length'Img);
-- Initialize the recursive structure (once)
if It.Length > 1 and then It.Rest = Null then
Put_Line ("Initialize Length " & It.Length'Img);
It.Rest := new Instance;
It.Rest.Item.Length := It.Length - 1;
It.Rest_It :=
new Cust_Iterator'(Custom_Iterator.Iterator (It.Rest.Iterate)
with others => <>);
It.Rest_It.Position := It.Rest_It.First;
end if;
return Ret;
end;
function Next (It: ASN1_SequenceOf) return Generic_SeqOf is
Temp : constant Generic_SeqOf := It.Value;
begin
return Temp;
end;
end;
with ASN1_Iterators.Iterable_Type,
ASN1_Iterators.Iterable_Integer,
ASN1_Iterators.Generic_Iterator,
Interfaces;
use Interfaces;
generic
Min, Max: Integer_64;
with package Element_Pkg is new ASN1_Iterators.Generic_Iterator (<>);
package ASN1_Iterators.Iterable_SeqOF is
type DataArray is array(Integer_64 range <>) of Element_Pkg.ASN1_Type;
type Generic_SeqOf is record
Length : Integer_64;
Data : DataArray (1..Max);
end record;
package SeqOf_Pkg is new ASN1_Iterators.Iterable_type (Generic_SeqOf);
package Len_Iterator is new ASN1_Iterators.Iterable_Integer (Min, Max);
type Instance;
type Cust_Iterator;
type ASN1_SequenceOf is new SeqOf_Pkg.Iterable
with record
Length : Integer_64 := Min;
-- Iterate on the length
LenVal : Len_Iterator.Instance;
LenIt : access Len_Iterator.Iterator;
-- And on the value
Rest : access Instance;
Rest_It : access Cust_Iterator;
end record;
overriding
procedure Initialize (It: in out ASN1_SequenceOf);
overriding
function Has_Element (It: ASN1_SequenceOf) return Boolean;
overriding
function First (It: in out ASN1_SequenceOf) return Generic_SeqOf;
overriding
function Next (It: ASN1_SequenceOf) return Generic_SeqOf;
package Custom_Iterator is new ASN1_Iterators.Generic_Iterator
(ASN1_Type => Generic_SeqOf,
ASN1_Iterable => SeqOf_Pkg,
Actual_Iterable => ASN1_SequenceOf);
-- If it is needed to iterate manually, provide Cursor and Iterator:
subtype Cursor is Custom_Iterator.Cursor;
type Instance is new Custom_Iterator.Generic_Iterator_Type with null record;
subtype Iterator is Custom_Iterator.Iterators.Forward_Iterator'Class;
type Cust_Iterator is new Custom_Iterator.Iterator with null record;
function Has_Element (Position : Cursor) return Boolean
renames Custom_Iterator.Has_Element;
end;
-- Set up a generic type that has a Value field, and member functions
-- Initialize, Element, Has_Element, First, and Next
generic
type Element_Type is private; --(<>);
package ASN1_Iterators.Iterable_Type is
type Iterable is abstract tagged -- Controlled
--with record
record
Value: Element_Type;
end record;
type Iterable_Cursor is access all Iterable;
procedure Initialize (It: in out Iterable) is abstract;
function Element (It : Iterable) return Element_Type
is (It.Value);
function Has_Element (It: Iterable) return boolean is abstract;
function First (It: in out Iterable) return Element_Type is abstract;
function Next (It: Iterable) return Element_Type is abstract;
end;
......@@ -64,6 +64,13 @@ def unsigned_int_adb_template (sort: str, minR: int, maxR: int) -> str:
To := From;
end To_ASN1;
function To_ASN1 (From : Interfaces.Unsigned_64) return asn1Scc{sort} is
Result : asn1Scc{sort};
begin
To_ASN1 (From, Result);
return Result;
end To_ASN1;
function Image (Elm : asn1Scc{sort}) return String is
(Ada.Strings.Fixed.Trim (Elm'Img, Both));
......@@ -79,6 +86,13 @@ def signed_int_adb_template (sort: str, minR: int, maxR: int) -> str:
To := From;
end To_ASN1;
function To_ASN1 (From : Interfaces.Integer_64) return asn1Scc{sort} is
Result : asn1Scc{sort};
begin
To_ASN1 (From, Result);
return Result;
end To_ASN1;
function Image (Elm : asn1Scc{sort}) return String is
(Ada.Strings.Fixed.Trim (Elm'Img, Both));
......@@ -97,6 +111,13 @@ def seq_of_adb_template (sort: str, inner: str, minR: int, maxR: int) -> str:
end loop;
end To_ASN1;
function To_ASN1 (From : Inner.Sequence_Of) return asn1Scc{sort} is
Result : asn1Scc{sort};
begin
To_ASN1 (From, Result);
return Result;
end To_ASN1;
function Image (Elm : asn1Scc{sort}) return String is
Res : Unbounded_String;
begin
......@@ -123,6 +144,13 @@ end {sort}_Pkg;'''
To.Length := From.Length;
end To_ASN1;
function To_ASN1 (From : Inner.Sequence_Of) return asn1Scc{sort} is
Result : asn1Scc{sort};
begin
To_ASN1 (From, Result);
return Result;
end To_ASN1;
function Image (Elm : asn1Scc{sort}) return String is
function Image_Rec (Elm : asn1Scc{sort}) return String is
(if Elm.Length > 0 then
......@@ -278,7 +306,7 @@ def top_ads_template(modules: List[str]) -> str:
{withs_str}
package ASN1_Ada_Iterators is
end;'''
end ASN1_Ada_Iterators;'''
def ads_template(packages: List[str]) -> str:
......@@ -315,6 +343,7 @@ def unsigned_int_ads_template (sort: str, minR: int, maxR: int) -> str:
package It renames Inner.It;
procedure To_ASN1 (From : Interfaces.Unsigned_64;
To : out asn1Scc{sort});
function To_ASN1 (From : Interfaces.Unsigned_64) return asn1Scc{sort};
subtype Instance is Inner.Instance;
function Image (Elm : asn1Scc{sort}) return String;
end {sort}_Pkg;'''
......@@ -328,6 +357,7 @@ def signed_int_ads_template (sort: str, minR: int, maxR: int) -> str:
package It renames Inner.It;
procedure To_ASN1 (From : Interfaces.Integer_64;
To : out asn1Scc{sort});
function To_ASN1 (From : Interfaces.Integer_64) return asn1Scc{sort};
subtype Instance is Inner.Instance;
function Image (Elm : asn1Scc{sort}) return String;
end {sort}_Pkg;'''
......@@ -340,8 +370,10 @@ def seq_of_ads_template (sort: str, inner: str, minR: int, maxR: int) -> str:
Max => {maxR},
Basic => {inner}_Pkg.It);
use {inner}_Pkg;
package It renames Inner;
procedure To_ASN1 (From : Inner.Sequence_Of;
To : out asn1Scc{sort});
function To_ASN1 (From : Inner.Sequence_Of) return asn1Scc{sort};
subtype Instance is Inner.Instance;
function Image (Elm : asn1Scc{sort}) return String;
end {sort}_Pkg;'''
......@@ -352,6 +384,7 @@ def enum_ads_template (sort: str) -> str:
return f'''package {sort}_Pkg is
package Inner is new Generic_Enumerated (Sort => asn1Scc{sort});
package It renames Inner.It;
function To_ASN1 (From : asn1Scc{sort}) return asn1Scc{sort} is (From);
subtype Instance is Inner.Instance;
function Image (Elm : asn1Scc{sort}) return String;
end {sort}_Pkg;'''
......@@ -371,7 +404,7 @@ def fields_ads_record (fields : dict) -> List [str]:
''' Declare the fields for iteration in an ASN.1 SEQUENCE type '''
result = []
for field in fields.keys():
result.append (f"{field}_val : P_{field}.Basic_ASN1_Iterator;")
result.append (f"{field}_val : P_{field}.ASN1_Container;")
result.append (f"{field}_it : P_{field}.Iterator;")
return result
......@@ -379,8 +412,8 @@ def fields_ads_record (fields : dict) -> List [str]:
def fields_ads_value (fields : dict) -> List [str]:
''' Code that return the value of an ASN.1 SEQUENCE type '''
result = []
for field in fields.keys():
result.append (f"{field} => Container.{field}_val.Elem_Value (Container.{field}_it.Position)")
for field, sort in fields.items():
result.append (f"{field} => {sort}_Pkg.To_ASN1 (Container.{field}_val.Element (Container.{field}_it.Position))")
return result
......@@ -422,6 +455,8 @@ def sequence_ads_template (sort: str, fields: dict) -> str:
Position : Cursor) return asn1Scc{sort} is
({indent(7, fields_ads_value(fields), sep=",")});
function To_ASN1 (From : asn1Scc{sort}) return asn1Scc{sort} is (From);
subtype Instance is {sort};
function Image (Elm : asn1Scc{sort}) return String;
end {sort}_Pkg;'''
......@@ -467,6 +502,8 @@ def parse_args():
def run(options):
asn1_files = options.files
out_folder = options.output if options.output else '.'
os.makedirs(out_folder, exist_ok=True)
if not asn1_files:
LOG.error ("You must specify at least one ASN.1 file")
return
......@@ -476,7 +513,10 @@ def run(options):
ast_version=asn1scc.ASN1.UniqueEnumeratedNames,
rename_policy=asn1scc.ASN1.NoRename,
flags=[asn1scc.ASN1.AstOnly],
pretty_print=False)
pretty_print=False,
extraflags=['-o', out_folder,
'-Ada',
'-typePrefix', 'asn1Scc'])
except (ImportError, NameError, TypeError) as err:
LOG.error(str(err))
LOG.error("ASN.1 Parsing error (run with -g for debug infomation)")
......@@ -543,8 +583,6 @@ def run(options):
adb = adb_template(packages_adb)
top_ads = top_ads_template(modules)
out_folder = options.output if options.output else '.'
os.makedirs(out_folder, exist_ok=True)
# Write the .ads
with open (f"{out_folder}/asn1_ada_iterators-iterators.ads", "wb") as source:
source.write(ads.encode('latin1'))
......
with ASN1_Iterators.Iterable_Integer,
ASN1_Iterators.Iterable_SeqOF,
Ada.Text_IO;
use ASN1_Iterators,
Ada.Text_IO;
procedure test_new_iterators is
package MyInt is new ASN1_Iterators.Iterable_Integer (5, 10);
It: MyInt.Instance;
Iter: MyInt.Iterator := It.Iterate;
C: MyInt.Cursor;
-- SEQUENCE OF
package MySeqOf is new ASN1_Iterators.Iterable_SeqOF (3, 5, MyInt.Custom_Iterator);
ItSO : MySeqOf.Instance;
IterSO : MySeqOf.Iterator := ItSO.Iterate;
CSO : MySeqOf.Cursor;
begin
Put_Line ("Hello");
Put_Line ("With 'for each of':");
for each of It loop
Put_Line (each'img);
end loop;
Put_Line ("With 'for each in':");
for each in It.Iterate loop
Put_Line (It.Elem (each)'Img);
end loop;
-- With manual iterators:
Put_Line ("With manual iterators:");
C := Iter.First;
while MyInt.Has_Element (C) loop
Put_Line (It.Elem (C)'Img);
C := Iter.Next (C);
end loop;
Put_Line ("SeqOF manual iterators:");
CSO := IterSO.First;
while MySeqOf.Has_Element (CSO) loop
Put_Line ("Element"); -- ItSO.Element (CSO)'Img);
CSO := IterSO.Next (CSO);
end loop;
end;
......@@ -16,6 +16,11 @@ MySeq ::= SEQUENCE {
b MyEnum
}
MySeqi2 ::= SEQUENCE {
a MyInteger,
b MySeqOf
}
--MyChoice ::= CHOICE {
-- choice-a MyInteger,
-- choice-b MySeqOf
......
......@@ -29,6 +29,7 @@ procedure test_generic is
use MyEnum_Pkg;
use MySeqOfEnum_Pkg;
use MySeq_Pkg;
use MySeqi2_Pkg;
-- Test cases
MyIt : MyInteger_Pkg.Instance;
......@@ -37,12 +38,14 @@ procedure test_generic is
Enum : MyEnum_Pkg.Instance;
SeqOfEnum : MySeqOfEnum_Pkg.Instance;
Seq : MySeq_Pkg.Instance;
Seq : MySeq_Pkg.Instance;
Seq2 : MySeqi2_Pkg.Instance;
SeqOfItm : asn1SccMySeqOf;
VarSeqOfItm : asn1SccMyVarSeqOf;
SeqOfEnumItm : asn1SccMySeqOfEnum;
i : Natural := 1;
count : Natural := 0;
begin
-- test: compute all possible values of the integer type
......@@ -89,10 +92,30 @@ begin
Put (Image (SeqOfEnumItm) & " ");
end loop;
New_Line;
New_Line;
Put_Line ("Sequence with 2 fields");
for Each of Seq loop
Put (Image (Each) & " ");
end loop;
New_Line;
New_Line;
Put_Line ("Sequence with a complex field");
i := 1;
count := 0;
for Each of Seq2 loop
count := count + 1;
Put (Image (Each) & " ");
i := (if i mod 6 = 0 then 1 else i + 1);
if i = 1 then
New_Line;
end if;
end loop;
New_Line;
Put_Line ("total: " & count'img & " values were computed");
New_Line;
end test_generic;