Commit 4aeaa78f authored by Maxime Perrotin's avatar Maxime Perrotin

Add iterators for enumerated types

parent 7797eab0
...@@ -5,7 +5,9 @@ all: ...@@ -5,7 +5,9 @@ all:
@echo A testcase can be build from source with "make test" @echo A testcase can be build from source with "make test"
install: uninstall install: uninstall
mkdir -p obj && sed 's,$$PREFIX,$(PREFIX),g' src/taste-asn1-iterators > obj/taste-asn1-iterators && chmod +x obj/taste-asn1-iterators mkdir -p obj && rm -f obj/taste-asn1-iterators && \
sed 's,$$PREFIX,$(PREFIX),g' src/taste-asn1-iterators > obj/taste-asn1-iterators && \
chmod +x obj/taste-asn1-iterators
gprbuild -p asn1_iterators.gpr gprbuild -p asn1_iterators.gpr
gprinstall -p -XLIBRARY_TYPE=dynamic --build-name=shared --prefix=$(PREFIX) asn1_iterators.gpr gprinstall -p -XLIBRARY_TYPE=dynamic --build-name=shared --prefix=$(PREFIX) asn1_iterators.gpr
@echo Do not forget to export ADA_PROJECT_PATH=$(PREFIX)/share/gpr @echo Do not forget to export ADA_PROJECT_PATH=$(PREFIX)/share/gpr
......
package body ASN1_Iterators.Generic_Enumerated is
function Elem_Init return Sort is
begin
Is_Last := (Sort'First = Sort'Last);
return Sort'First;
end Elem_Init;
function Has_Elem (Value: Sort) return Boolean is
Result : constant Boolean := (not Is_Last and Value <= Sort'Last);
begin
if Value = Sort'Last then
Is_Last := True;
end if;
return Result;
end Has_Elem;
end;
with ASN1_Iterators.SimpleTypes,
ASN1_Iterators.Generic_Basic;
with Interfaces;
use Interfaces;
generic
type Sort is (<>); -- a discrete type, such as enumerated
package ASN1_Iterators.Generic_Enumerated is
Is_Last : Boolean := False;
-- function Elem_Init return Sort is (Sort'First);
function Elem_Init return Sort;
function Has_Elem (Value: Sort) return Boolean;
-- function Has_Elem (Value: Sort) return Boolean is (Value <= Sort'Last);
function Elem_First return Sort is (Sort'First);
function Elem_Next (Value: Sort) return Sort is
(if Is_Last then Sort'Last else Sort'Succ (Value));
package Discrete_Type is new SimpleTypes (Element => Sort,
Elem_Init => Elem_Init,
Has_Elem => Has_Elem,
Elem_First => Elem_First,
Elem_Next => Elem_Next);
package It is new Generic_Basic (P => Discrete_Type);
subtype Instance is It.Basic_ASN1_Iterator;
end;
...@@ -67,11 +67,11 @@ $sSubType$ ...@@ -67,11 +67,11 @@ $sSubType$
sName may be Generic_Integer or Generic_Real sName may be Generic_Integer or Generic_Real
*/ */
MinMaxType(sName, sMin, sMax, bFixedSize, bIsUnsigned, bIsRealType) ::= << MinMaxType(sName, sMin, sMax, bFixedSize, bIsUnsigned, bIsRealType) ::= <<
function Image(Elm: ASN1_Type) return String is (Elm'Img); function Image (Elm : ASN1_Type) return String is (Elm'Img);
procedure To_ASN1(from: Interfaces.$if(bIsUnsigned)$Unsigned_64$else$$if(bIsRealType)$Long_Float$else$Integer_64$endif$$endif$; to: out ASN1_Type) is procedure To_ASN1 (From : Interfaces.$if(bIsUnsigned)$Unsigned_64$else$$if(bIsRealType)$Long_Float$else$Integer_64$endif$$endif$; To : out ASN1_Type) is
begin begin
to := from; To := From;
>> >>
...@@ -98,7 +98,6 @@ IA5StringType () ::= "IA5StringType" ...@@ -98,7 +98,6 @@ IA5StringType () ::= "IA5StringType"
NumericStringType () ::= "NumericStringType" NumericStringType () ::= "NumericStringType"
AssigOpNormalType () ::= "=" AssigOpNormalType () ::= "="
AssigOpSpecialType () ::= "::" AssigOpSpecialType () ::= "::"
...@@ -115,17 +114,12 @@ AssigOpSpecialType () ::= "::" ...@@ -115,17 +114,12 @@ AssigOpSpecialType () ::= "::"
nVal is the integer value of the enumerated, use it if needed nVal is the integer value of the enumerated, use it if needed
*/ */
EnumItem (sName, sCName, nVal, nLine, nPos, sCID) ::= << EnumItem (sName, sCName, nVal, nLine, nPos, sCID) ::= <<
"$sName$": type("$sCID$", (object,), {
"IntValue": $nVal$, "Line": $nLine$, "CharPositionInLine": $nPos$, "EnumID": "$sCID$"
})
>> >>
/* Enumerated type: arrsItems is an array of EnumItem */ /* Enumerated type: arrsItems is an array of EnumItem */
EnumType(arrsItems) ::= << EnumType(arrsItems) ::= <<
"kind": "EnumeratedType", "Extensible": "False", "ValuesAutoCalculated": "False", "EnumValues": { function Image (Elm : ASN1_Type) return String is (Elm'Img);
$arrsItems;separator=",\n"$
}
>> >>
...@@ -139,44 +133,33 @@ EnumType(arrsItems) ::= << ...@@ -139,44 +133,33 @@ EnumType(arrsItems) ::= <<
sNamePresent is an unambiguous name to access the field sNamePresent is an unambiguous name to access the field
*/ */
ChoiceChild(sName, sCName, nLine, nPos, sChildContent, sNamePresent ) ::= << ChoiceChild(sName, sCName, nLine, nPos, sChildContent, sNamePresent ) ::= <<
"$sName$": type("$sNamePresent$", (object,), {
"Line": $nLine$, "CharPositionInLine": $nPos$, "EnumID": "$sNamePresent$", "type": type("$sNamePresent$_type", (object,), {
$sChildContent$
})
})
>> >>
ChoiceType(arrsChildren) ::= << ChoiceType(arrsChildren) ::= <<
"kind": "ChoiceType", "Children": { -- $arrsChildren;separator=",\n"$
$arrsChildren;separator=",\n"$
} }
>> >>
/* Sequence (record) field. May be optional and may have a default value */ /* Sequence (record) field. May be optional and may have a default value */
SequenceChild(sName, sCName, bOptional, sDefVal, nLine, nPos, sChildContent ) ::= << SequenceChild(sName, sCName, bOptional, sDefVal, nLine, nPos, sChildContent ) ::= <<
"$sName$": type("$sName$", (object,), {
"Optional": "$bOptional$"$if(sDefVal)$, "DefaultValue": "$sDefVal$"$endif$, "Line": $nLine$, "CharPositionInLine": $nPos$, "type": type("$sName$_type", (object,), {
$sChildContent$
})
})
>> >>
/* Full sequence (record) type */ /* Full sequence (record) type */
SequenceType(arrsChildren) ::= << SequenceType(arrsChildren) ::= <<
$arrsChildren;separator=",\n"$ -- $arrsChildren;separator=",\n"$
} }
>> >>
/* Sequence of (array) */ /* Sequence of (array) */
SequenceOfType(sMin, sMax, sChild, bFixedSize) ::= << SequenceOfType(sMin, sMax, sChild, bFixedSize) ::= <<
procedure To_ASN1(from: Inner.MySeqOf; to: out ASN1_Type) is procedure To_ASN1(From: Inner.MySeqOf; to: out ASN1_Type) is
begin begin
for idx in 1..from.length loop for Idx in 1 .. From.Length loop
to.data(idx) := from.data(idx); To.Data (Idx) := From.Data (Idx);
end loop; end loop;
>> >>
...@@ -204,36 +187,37 @@ end; ...@@ -204,36 +187,37 @@ end;
// SeqOF may have fixed size, in that case there is no Length field // SeqOF may have fixed size, in that case there is no Length field
ContractExprSize(sPattern, sMin, sMax, bFixedSize) ::= << ContractExprSize(sPattern, sMin, sMax, bFixedSize) ::= <<
$if(!bFixedSize)$ $if(!bFixedSize)$
to.length := from.length; To.Length := From.Length;
$endif$ $endif$
end; end;
function Image(Elm: ASN1_Type) return String is function Image (Elm : ASN1_Type) return String is
$if(bFixedSize)$ $if(bFixedSize)$
Res : Unbounded_String; Res : Unbounded_String;
begin begin
if Elm.Data'Length >= 1 then if Elm.Data'Length >= 1 then
Res := To_Unbounded_String(Image(Elm.Data(1))); Res := To_Unbounded_String (Image (Elm.Data (1)));
end if; end if;
if Elm.Data'Length > 1 then if Elm.Data'Length > 1 then
for idx in 2..Elm.Data'Length loop for Idx in 2 .. Elm.Data'Length loop
Res := Res & "," & Image(Elm.Data(Idx)); Res := Res & "," & Image (Elm.Data (Idx));
end loop; end loop;
end if; end if;
return To_String("{" & Res & " }"); return To_String ("{" & Res & " }");
end; end;
$else$ $else$
function Image_rec(Elm: ASN1_Type) return String is function Image_Rec (Elm : ASN1_Type) return String is
(if Elm.Length > 0 then (if Elm.Length > 0 then
(Image(Elm.Data(1)) & (if Elm.Length > 1 then "," & (Image (Elm.Data (1))
Image_Rec(ASN1_Type'(Length => Elm.Length-1, & (if Elm.Length > 1 then ","
Data => Elm.Data(2..Elm.Length) & & Image_Rec (ASN1_Type'(Length => Elm.Length-1,
Elm.Data(1..Elm.Data'Length-Elm.Length+1))) Data => Elm.Data(2 .. Elm.Length) &
Elm.Data(1 .. Elm.Data'Length - Elm.Length + 1)))
else "")) else ""))
else ""); else "");
begin begin
return "{" & Image_rec(Elm) & " }"; return "{" & Image_Rec (Elm) & " }";
end; end;
$endif$ $endif$
>> >>
......
...@@ -21,6 +21,7 @@ RootXml(arrsFiles) ::= << ...@@ -21,6 +21,7 @@ RootXml(arrsFiles) ::= <<
with ASN1_Ada_Iterators, with ASN1_Ada_Iterators,
ASN1_Iterators.Generic_Integer, ASN1_Iterators.Generic_Integer,
ASN1_Iterators.Generic_Unsigned_Integer, ASN1_Iterators.Generic_Unsigned_Integer,
ASN1_Iterators.Generic_Enumerated,
ASN1_Iterators.Generic_SeqOf, ASN1_Iterators.Generic_SeqOf,
Interfaces, Interfaces,
Ada.Strings.Unbounded; Ada.Strings.Unbounded;
...@@ -71,7 +72,7 @@ package $sCName$_pkg is ...@@ -71,7 +72,7 @@ package $sCName$_pkg is
subtype ASN1_Type is asn1Scc$sCName$; subtype ASN1_Type is asn1Scc$sCName$;
package Inner is new $sType$ package Inner is new $sType$
subtype Instance is Inner.Instance; subtype Instance is Inner.Instance;
function Image(Elm: ASN1_Type) return String; function Image (Elm : ASN1_Type) return String;
end; end;
>> >>
...@@ -92,14 +93,14 @@ $sSubType$ ...@@ -92,14 +93,14 @@ $sSubType$
MinMaxType(sName, sMin, sMax, bFixedSize, bIsUnsigned, bIsRealType) ::= << MinMaxType(sName, sMin, sMax, bFixedSize, bIsUnsigned, bIsRealType) ::= <<
Generic_$if(bIsUnsigned)$Unsigned_$endif$$sName$ (Min => $sMin$, Max => $sMax$); Generic_$if(bIsUnsigned)$Unsigned_$endif$$sName$ (Min => $sMin$, Max => $sMax$);
package It renames Inner.It; package It renames Inner.It;
procedure To_ASN1(from: Interfaces.$if(bIsUnsigned)$Unsigned_64$else$$if(bIsRealType)$Long_Float$else$Integer_64$endif$$endif$; to: out ASN1_Type); procedure To_ASN1(From : Interfaces.$if(bIsUnsigned)$Unsigned_64$else$$if(bIsRealType)$Long_Float$else$Integer_64$endif$$endif$; To : out ASN1_Type);
>> >>
/* String types with size constraint: Bitstring, Octetstring, Ia5String, /* String types with size constraint: Bitstring, Octetstring, Ia5String,
NumericString */ NumericString */
MinMaxType2(sName, sMin, sMax, bFixedSize) ::= << MinMaxType2(sName, sMin, sMax, bFixedSize) ::= <<
"kind": "$sName$", "Min": "$sMin$", "Max": "$sMax$" -- "kind": "$sName$", "Min": "$sMin$", "Max": "$sMax$"
>> >>
BooleanType () ::= "Generic_Boolean" BooleanType () ::= "Generic_Boolean"
...@@ -136,17 +137,12 @@ AssigOpSpecialType () ::= "::" ...@@ -136,17 +137,12 @@ AssigOpSpecialType () ::= "::"
nVal is the integer value of the enumerated, use it if needed nVal is the integer value of the enumerated, use it if needed
*/ */
EnumItem (sName, sCName, nVal, nLine, nPos, sCID) ::= << EnumItem (sName, sCName, nVal, nLine, nPos, sCID) ::= <<
"$sName$": type("$sCID$", (object,), {
"IntValue": $nVal$, "Line": $nLine$, "CharPositionInLine": $nPos$, "EnumID": "$sCID$"
})
>> >>
/* Enumerated type: arrsItems is an array of EnumItem */ /* Enumerated type: arrsItems is an array of EnumItem */
EnumType(arrsItems) ::= << EnumType(arrsItems) ::= <<
"kind": "EnumeratedType", "Extensible": "False", "ValuesAutoCalculated": "False", "EnumValues": { Generic_Enumerated (Sort => ASN1_Type);
$arrsItems;separator=",\n"$
}
>> >>
...@@ -160,33 +156,20 @@ EnumType(arrsItems) ::= << ...@@ -160,33 +156,20 @@ EnumType(arrsItems) ::= <<
sNamePresent is an unambiguous name to access the field sNamePresent is an unambiguous name to access the field
*/ */
ChoiceChild(sName, sCName, nLine, nPos, sChildContent, sNamePresent ) ::= << ChoiceChild(sName, sCName, nLine, nPos, sChildContent, sNamePresent ) ::= <<
"$sName$": type("$sNamePresent$", (object,), {
"Line": $nLine$, "CharPositionInLine": $nPos$, "EnumID": "$sNamePresent$", "type": type("$sNamePresent$_type", (object,), {
$sChildContent$
})
})
>> >>
ChoiceType(arrsChildren) ::= << ChoiceType(arrsChildren) ::= <<
"kind": "ChoiceType", "Children": {
$arrsChildren;separator=",\n"$
}
>> >>
/* Sequence (record) field. May be optional and may have a default value */ /* Sequence (record) field. May be optional and may have a default value */
SequenceChild(sName, sCName, bOptional, sDefVal, nLine, nPos, sChildContent ) ::= << SequenceChild(sName, sCName, bOptional, sDefVal, nLine, nPos, sChildContent ) ::= <<
"$sName$": type("$sName$", (object,), {
"Optional": "$bOptional$"$if(sDefVal)$, "DefaultValue": "$sDefVal$"$endif$, "Line": $nLine$, "CharPositionInLine": $nPos$, "type": type("$sName$_type", (object,), {
$sChildContent$
})
})
>> >>
/* Full sequence (record) type */ /* Full sequence (record) type */
SequenceType(arrsChildren) ::= << SequenceType(arrsChildren) ::= <<
$arrsChildren;separator=",\n"$ -- $arrsChildren;separator=",\n"$
} }
>> >>
...@@ -195,7 +178,7 @@ SequenceType(arrsChildren) ::= << ...@@ -195,7 +178,7 @@ SequenceType(arrsChildren) ::= <<
SequenceOfType(sMin, sMax, sChild, bFixedSize) ::= << SequenceOfType(sMin, sMax, sChild, bFixedSize) ::= <<
Generic_SeqOf (Min => $sMin$, Max => $sMax$, Basic => $sChild$_Pkg.It); Generic_SeqOf (Min => $sMin$, Max => $sMax$, Basic => $sChild$_Pkg.It);
use $sChild$_Pkg; use $sChild$_Pkg;
procedure To_ASN1(from: Inner.MySeqOf; to: out ASN1_Type); procedure To_ASN1 (From : Inner.MySeqOf; To : out ASN1_Type);
>> >>
......
...@@ -7,6 +7,8 @@ MySeqOf ::= SEQUENCE (SIZE (3)) OF MyInteger ...@@ -7,6 +7,8 @@ MySeqOf ::= SEQUENCE (SIZE (3)) OF MyInteger
MyVarSeqOf ::= SEQUENCE (SIZE (1..4)) OF MyInteger MyVarSeqOf ::= SEQUENCE (SIZE (1..4)) OF MyInteger
MyEnum ::= ENUMERATED { hello, world, how-are-you }
--MyChoice ::= CHOICE { --MyChoice ::= CHOICE {
-- choice-a MyInteger, -- choice-a MyInteger,
-- choice-b MySeqOf -- choice-b MySeqOf
......
with ASN1_Ada_Iterators.iterators; -- Generated by asn1scc using custom stg file with ASN1_Ada_Iterators.iterators; -- Generated by asn1scc using custom stg file
use ASN1_Ada_Iterators.iterators; use ASN1_Ada_Iterators.iterators;
with TASTE_DataView; with TASTE_DataView;
use TASTE_DataView; use TASTE_DataView;
with ada.text_io; with ada.text_io;
use ada.text_io; use ada.text_io;
...@@ -25,46 +26,52 @@ procedure test_generic is ...@@ -25,46 +26,52 @@ procedure test_generic is
use MyInteger_Pkg; use MyInteger_Pkg;
use MySeqOf_Pkg; use MySeqOf_Pkg;
use MyVarSeqOf_Pkg; use MyVarSeqOf_Pkg;
use MyEnum_Pkg;
-- Test cases -- Test cases
MyIt : MyInteger_Pkg.Instance; MyIt : MyInteger_Pkg.Instance;
Fixed_SeqOf : MySeqOf_Pkg.Instance; Fixed_SeqOf : MySeqOf_Pkg.Instance;
Var_SeqOf : MyVarSeqOf_Pkg.Instance; Var_SeqOf : MyVarSeqOf_Pkg.Instance;
Enum : MyEnum_Pkg.Instance;
SeqOfItm : asn1SccMySeqOf; SeqOfItm : asn1SccMySeqOf;
VarSeqOfItm : asn1SccMyVarSeqOf; VarSeqOfItm : asn1SccMyVarSeqOf;
i: natural := 1; i : Natural := 1;
begin begin
-- test: compute all possible values of the integer type -- test: compute all possible values of the integer type
-- (equivalent to "for each in 1..3 loop put_line(each'img); end loop;") -- (equivalent to "for each in 1..3 loop put_line(each'img); end loop;")
for each of MyIt loop for each of MyIt loop
--Put_Line(each'img); --Put_Line(each'img);
Put_Line(Image(each)); Put_Line(Image(each));
end loop; end loop;
-- test: compute all combinations of values for the fixed-size array -- test: compute all combinations of values for the fixed-size array
Put_Line ("Variable-size array:"); Put_Line ("Variable-size array:");
for each of Var_SeqOf loop for each of Var_SeqOf loop
To_ASN1 (From => each, To => VarSeqOfItm); To_ASN1 (From => each, To => VarSeqOfItm);
Put(Image(VarSeqOfItm)); Put(Image(VarSeqOfItm));
i := (if i mod 10 = 0 then 1 else i + 1); i := (if i mod 10 = 0 then 1 else i + 1);
if i = 1 then if i = 1 then
new_line; New_Line;
end if; end if;
end loop; end loop;
-- test: compute all combination of values for the variable-size array -- test: compute all combination of values for the variable-size array
New_Line; New_Line;
Put_Line ("Fixed-size array:"); Put_Line ("Fixed-size array:");
i := 1; i := 1;
for each of Fixed_SeqOf loop for each of Fixed_SeqOf loop
To_ASN1 (From => each, To => SeqOfItm); To_ASN1 (From => each, To => SeqOfItm);
Put(Image(SeqOfItm)); Put(Image(SeqOfItm));
i := (if i mod 10 = 0 then 1 else i + 1); i := (if i mod 10 = 0 then 1 else i + 1);
if i = 1 then if i = 1 then
new_line; New_Line;
end if; end if;
end loop; end loop;
New_Line; New_Line;
Put_Line ("Enumerated type");
for Each of Enum loop
Put_Line (Image (Each));
end loop;
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