-
Notifications
You must be signed in to change notification settings - Fork 0
CryptAda.Lists
Linear lists are used in CryptAda mainly to standardize the parameter passing to algorithms and factories. A linear list is a linearly ordered set of data elements called list items. Each list item has an item value. A list item may also have an item name, in which case it is called a named item; if a list item has no item name, it is called an unnamed item.
There are three kinds of linear lists: empty lists, named lists, and unnamed lists. An empty list is a linear list that contains no items. Such a list is not considered to be either named or unnamed. A named list is a non-empty linear list that contains only named items; the names of distinct items in a named list must be distinct. An unnamed list is a non-empty linear list that contains only unnamed items. The values of type List_Kind
enumerate these three kinds of lists.
There are five basic kinds of list items, discriminated on the kind of values they can have: strings, integers, floating point numbers, identifiers and linear lists. The values of type Item_Kind
enumerate these five kinds of list items. The actual, internal types of list item values are not specified. The means to manipulate these internal values are provided by explicit, external types (or generic type parameters) used by the subprograms in this package and their children packages.
Identifier values of list items occur in three different forms which are represented by three different external types at the subprograms: an identifier form represented by the limited private type Identifier
, an identifier text form represented by the type Identifier_Text
(a subtype of String
restricted to the syntax of Ada identifiers) and an enumeration form represented by an Ada enumeration type.
The interfaces for manipulating identifier items using the identifier form and the identifier text form are defined in package CryptAda.Lists.Identifier_Item
. The interfaces for manipulating the identifier item values in an enumeration form are defined by the generic package CryptAda.Lists.Enumeration_Item
which must be instantiated with the enumeration type.
Lists are represented by the limited private type List
. Every List object includes a single, outermost linear list which may contain a nested list structure (list with list items containing list items, etc) and, in order to work with such a nested structure, each list object provides a 'current list' which may or may not be the same list as the outermost list. Most operations on lists are on the 'current list'.
The initial value of list objects is the empty list. When a list is empty, its outermost and current list are both empty.
The package CryptAda.Lists
provides interfaces for:
- extracting values of items in a linear list,
- extracting contiguous sequences of items from a linear list,
- replacing or changing values of items in a linear list, and
- inserting new items into a linear list.
They also include operations which change the designation of the current linear list of a List value, such as:
- making a nested sublist of the current linear list the (new) current linear list, and
- making the linear list containing the current linear list the (new) current linear list.
These two kinds of operations (linear list manipulations and current linear list designations) are independent in the following sense: linear list manipulations do not change the designation of the current linear list of a List value and current linear list designations applied to a List value do not change the nested list structure being represented.
For convenience, a String representation (restricted to strings with the syntax given below) is defined for linear lists.
list ::= empty_list | unnamed_list | named_list
empty_list ::= ()
unnamed_list ::= (item_value {,item_value})
named_list ::= (named_item {, named_item})
named_item ::= item_name => item_value
item_value ::= list | quoted_string | identifier | integer_literal | float_literal
Notes:
- Whitespace (' ' + HT .. CR) is allowed between any two given tokens, before the beginning of list token, and after the end of list token.
- Identifiers (either as names or values) must conform the Ada syntax rules for identifiers and must not be Ada reserved words.
- Identifier comparison is case unsensitive but identifiers, both as names or values preserve the case.
- Not two items with the same name are allowed in a named list.
- String values are quoted a quote character inside a string value must be escaped in the usual Ada way (by putting another '"' together).
- Numeric values must meet the Ada numeric value syntax. Numeric values are obtained by using the Get procedures of Ada.Text_IO.Float_IO and Ada.Text_IO.Integer_IO. If Data_Error is raised this procedure will propagate it as a CryptAda_Syntax_Error.
Examples:
declare
LT1 : constant String := " ( ) "; -- Empty list
LT2 : constant String := "(Antonio, Duran)"; -- Unnamed list (two identifier items).
LT3 : constant String := "(""Antonio"", ""Duran"")"; -- Unnamed list (two string items note double double quotes).
LT4 : constant String := "(Name => ""Antonio"", Age => 53, Height => 1.79, Languages => (Spanish, English))";
-- LT4 is a text representation of a named list containing a String item (Name), an integer item (Age), a float
-- item (Height) and a list item (Languages) which is an unnamed list with two items which are Identifiers.
begin
null;
end;
This packaga and all children packages are adapted from MIL-STD-1838A (CAIS-A) CAIS_List_Management package.
The package declares the next public constants that set the maximum number of items a linear list could contain and the maximum allowed identifier length. These values are arbitrary and could be changed if need arose:
List_Length : constant Positive := 4096;
Identifier_Max_Length : constant Positive := 256;
type List is tagged limited private;
This is the type that represent the lists. Is a limited private type so no equality tests are implicitly provided. The package contains subprograms to test List equality which is defined according the following rule:
Two linear lists are equal if and only if:
- both lists are of the same kind (i.e., named, unnamed or empty), and
- both lists contain the same number of list items, and
- in the case of named lists, for each position in the list, the names of the list items at this position are equal under identifier-equality, and
- for each position in the list, the values of the list items at this position are of the same kind and are equal according to the appropriate form of equality (as described above), i.e.:
- for identifier items, identifier equality of the identifier text forms and, in the case of two enumerated identifier items, equality of enumeration positions as well;
- for string items, string equality;
- for integer items, integer equality;
- for floating point items, floating point equality;
- for list items (whose values are in turn lists), list equality as defined in this rule.
Equality of lists involving floating point items should be applied with considerable caution and awareness of all the issues documented in [1815A], Section 4.5.7, regarding the accuracy of relational operations with real operands.
subtype List_Text is String;
Type for text representation of List objects.
type List_Size is new Natural range 0 .. List_Length;
Type for list size (number of items).
subtype Position_Count is List_Size range 1 .. List_Size'Last;
This type is used for accessing list items by position.
subtype Insert_Count is List_Size range 0 .. List_Size'Last - 1;
Insert_Count is used to set the insertion position of an item in Insert operations.
type List_Kind is (Empty, Unnamed, Named);
Enumeration that identifies the list kind:
- Empty. List that does not contain any item.
- Unnamed. List where items are not named and access to the items is by position.
- Named. List containing named items, access to those items is either by position or by name.
type Item_Kind is (
List_Item_Kind,
String_Item_Kind,
Float_Item_Kind,
Integer_Item_Kind,
Identifier_Item_Kind
);
Enumeration that identifies the different kinds of items a List can hold.
type Identifier is tagged limited private;
Identifier describes the values used to designate list identifiers. Listidentifiers name the values in named lists and could be also values by themselves (Identifier_Item_Kind).
Values of this type are used in different list subprograms to access elements in named lists or as values of enumerated types as elements of the lists.
Identifiers must conform the syntax for Ada identifiers:
- First character must be a letter.
- Next characters could be a sequence of letters, digits or underscore character provided that no two or more underscores in a row are allowed and the underscore must not be the last character of the identifier.
- Identifiers must not be Ada reserved words.
Since Identifier is a limited private type, there is no implicitly defined equality test. Identifier equality is case unsensitive.
subtype Identifier_Text is String;
This type is used in external representation of identifiers.
procedure Copy_List(
From : in List'Class;
To : in out List'Class);
Copies the items in From's current list to To. After copy, the current list in To is set to the outermost list. Subsequent modifications on either list will not affect the other list.
- From. Source list of the copy.
- To. Target list of the copy.
- CryptAda_Storage_Error if an error is raised when allocating space for the copied items.
procedure Make_Empty(
The_List : in out List'Class);
This procedure makes the outermost linear list (which becomes the current linear list) the empty list. The procedure frees the memory allocated for the list items.
- The_List. List to make empty.
None.
procedure Text_2_List(
From_Text : in List_Text;
To_List : in out List'Class);
This procedure converts the text representation of a list into the private list representation. It establishes the current (and outermost) linear list of To_List
to be a named, unnamed, or empty list. The individual list items are classified according to their text representation. Whitespace is allowed between syntactic elements in the value of the parameter From_Text
.
- From_Text. Text representation that is converted to list.
- To_List. The list, that after the conversion will hold the items in the text representation. Its current list will be the outermost list.
- CryptAda_Storage_Error if an error is raised when allocating space for the list items items.
-
CryptAda_Syntax_Error if
From_Text
is not a syntactically correct list text. -
CryptAda_Overflow_Error if
From_Text
exceeds the maximum number of items for a list.
declare
LT : constant List_Text := "(Hello => Hi, World => ""Earth"")";
L : List;
begin
Text_2_List(LT, L);
end;
function List_2_Text(
The_List : in List'Class)
return List_Text;
This function returns the text representation of The_List
current linear list.
- The_List. List whose current linear list text representation is to be returned.
List_Text value containing the text representation of The_List
current linear list.
None.
function Is_Equal(
Left : in List'Class;
Right : in List'Class)
return Boolean;
This function compares for equality the current linear lists of two list objects returning the result of the equality test.
Two linear lists are equal if and only if:
- both lists are of the same kind (i.e., named, unnamed or empty), and
- both lists contain the same number of list items, and
- in the case of named lists, for each position in the list, the names of the list items at this position are equal under identifier-equality, and
- for each position in the list, the values of the list items at this position are of the same kind and are equal according to the appropriate form of equality (as described above), i.e.:
- for identifier items, identifier equality of the identifier text forms and, in the case of two enumerated identifier items, equality of enumeration positions as well;
- for string items, string equality;
- for integer items, integer equality;
- for floating point items, floating point equality;
- for list items (whose values are in turn lists), list equality as defined in this rule.
Care should be taken when comparing lists containing floating point items.
- Left. First list object whose current linear list is to be compared.
- Right. Second list object whose current linear list is to be compared.
Boolean value indicating the result of the equality test.
None.
procedure Delete(
From_List : in out List'Class;
At_Position : in Position_Count);
procedure Delete(
From_List : in out List'Class;
Item_Name : in Identifier'Class);
procedure Delete(
From_List : in out List'Class;
Item_Name : in Identifier_Text);
Deletes a specified item from the current linear list of a list object.
Three overloaded procedures are provided that allow to identify the item to delete by position (for both named and unnamed lists) or by name (for named lists) by using either an Identifier
object or an Identifier_Text
value.
- From_List. List object from which the designated item is to be deleted.
- At_Position. (First overloaded form) Position_Count value that specifies the position of the item to delete.
- Item_Name. (Second overloaded form) Identifier object with the name of the item to delete.
- Item_Name. (Third overloaded form) Identifier_Text value with the name of the item to delete.
-
CryptAda_List_Kind_Error if
From_List
current list is Empty. -
CryptAda_Index_Error if
At_Position
is not a valid position inFrom_List
. - CryptAda_Syntax_Error if the Identifier_Text (third overloaded form) does not conform the syntax for identifiers.
- CryptAda_Identifier_Error if the identifier (second overloaded form) is a null identifier.
-
CryptAda_Named_List_Error (second or third overloaded forms) if
From_List
current list is an unnamed list. -
CryptAda_Item_Not_Found_Error (second or third overloaded forms) if
From_List
current list does not contain an item withItem_Name
.
function Get_List_Kind(
Of_List : in List'Class)
return List_Kind;
This function returns the kind of list of a the current linear list of a given List
object.
- Of_List. List object whose current linear list kind is to be returned.
List_Kind enumeration value that identifies the kind of the current linear list Of_List
.
None.
function Get_Item_Kind(
In_List : in List'Class;
At_Position : in Position_Count)
return Item_Kind;
function Get_Item_Kind(
In_List : in List'Class;
Item_Name : in Identifier'Class)
return Item_Kind;
function Get_Item_Kind(
In_List : in List'Class;
Item_Name : in Identifier_Text)
return Item_Kind;
These functions return the kind of a specified item that belongs to the current linear list of a given List
object.
Three overloaded functions are provided that allow to query the kind of the item by position (for both named and unnamed lists) or by name (for named lists) by using either an Identifier
object or an Identifier_Text
value.
- In_List. List object whose current linear list contains the item whose kind is to be returned.
- At_Position. (First overloaded form) Position_Count value that specifies the position of the item.
- Item_Name. (Second overloaded form) Identifier object with the name of the item.
- Item_Name. (Third overloaded form) Identifier_Text value with the name of the item.
Item_Kind enumeration value that identifies the kind of the item.
-
CryptAda_List_Kind_Error if
In_List
current list is Empty. -
CryptAda_Index_Error if
At_Position
is not a valid position inIn_List
. - CryptAda_Syntax_Error if the Identifier_Text (third overloaded form) does not conform the syntax for identifiers.
- CryptAda_Identifier_Error if the identifier (second overloaded form) is a null identifier.
-
CryptAda_Named_List_Error (second or third overloaded forms) if
In_List
current list is an unnamed list. -
CryptAda_Item_Not_Found_Error (second or third overloaded forms) if
In_List
current list does not contain an item withItem_Name
.
procedure Splice(
In_List : in out List'Class;
At_Position : in Insert_Count;
The_List : in List'Class);
Inserts all the items from the current list of a list object at a specific position in the current list of another list object. Inserted items will preserve the order and after the insertion, modifications on either list do not affect the other.
- In_List. List object in whose current linear list the items will be inserted.
- At_Position. Insert_Count value that specifies the position where the insertion will take place (0 means before the first item).
- The_List. List whose current linear list items will be inserted In_List.
-
CryptAda_List_Kind_Error if current lists
In_List
andThe_List
are not of the same kind and neither of them is empty. -
CryptAda_Index_Error if
At_Position
is not a valid insertion position inIn_List
. -
CryptAda_Named_List_Error if current list of
In_List
andThe_List
are both named and contain an item with the same name. -
CryptAda_Overflow_Error if, after the insertion,
In_List
becomes larger than the maximum size allowed for lists.
procedure Concatenate(
Front : in List'Class;
Back : in List'Class;
Result : in out List'Class);
This procedure concatenates the current list of Back
at the end of the current list of Front
returning the resulting list in Result
whose current and outermost list will become the result of concatenation. Front
and Back
are not changed by the operation and any subsequent change in any of the lists will affect the others.
Front
and Back
current lists must be of the same kind or one of them must be empty.
- Front. List object in whose current linear list will be the front part of the concatenated list.
- Back. List object in whose current linear list will be the back part of the concatenated list.
- Result. List object which will contain the concatenation result.
-
CryptAda_List_Kind_Error if current lists of
Front
andBack
are not of the same kind and neither of them is empty. -
CryptAda_Named_List_Error if current lists of
Front
andBack
are both named and contain an item with the same name. - CryptAda_Overflow_Error if the concatenation result will exceed the maximum number of items allowed for a List object.
procedure Extract_List(
From_List : in List'Class;
Start_Position : in Position_Count;
End_Position : in Position_Count;
Result : in out List'Class);
This procedure extracts a sequence of items from the current list of From_List
, forming a new list from them. The items to be extracted are those in the positions from Start_Position
through End_Position
inclusive. The procedure copies the items From_List
to Result
leaving From_List
unmodified. Subsequent modifications to the value of From_List
or Result
will not affect either of the other (unmodified) lists.
- From_List. List object from whose current linear list the items are to be extracted.
- Start_Position. Position of the first item to extract.
- End_Position. Position of the last item to extract.
- Result. List object which will contain the extract result.
-
CryptAda_Index_Error if
Start_Position
orEnd_Position
are greater than the number of items inFrom_List
or ifStart_Position
is greater thanEnd_Position
.
function Number_Of_Items(
In_List : in List'Class)
return List_Size;
Returns the number of items in the current linear list of In_List
.
- In_List. List object to query for the number of items in its current list.
List_Size
value with the number of items in the current list of In_List
.
None.
function Position_Of_Current_List(
In_List : in List'Class)
return Position_Count;
Returns the position that current list of In_List
occupies in its parent list.
- In_List. List object to query for the position of its current list.
Position_Count
value with the position of the the current list of In_List
within its parent list.
-
CryptAda_Index_Error if
In_List
current list is the outermost list.
function Current_List_Is_Outermost(
Of_List : in List'Class)
return Boolean;
Checks whether or not the current list of Of_List
is the outermost list.
- Of_List. List object to query.
Boolean
value that indicates whether or not the current list Of_List
is the outermost list.
None.
procedure Make_Containing_List_Current(
In_List : in out List'Class);
This procedure causes the innermost list containing the current linear list of In_List
to become the (new) current linear list.
- In_List. List object to change its current linear list.
-
CryptAda_Index_Error if current linear list in
In_List
is the outermost list.
procedure Make_List_Item_Current(
In_List : in out List'Class;
At_Position : in Position_Count);
procedure Make_List_Item_Current(
In_List : in out List'Class;
Item_Name : in Identifier'Class);
procedure Make_List_Item_Current(
In_List : in out List'Class;
Item_Name : in Identifier_Text);
This procedure causes the list value of an item in the current linear list of LIST to become the (new) current linear list.
Three overloaded procedures are provided that allow to identify the list item to make current by position (for both named and unnamed lists) or by name (for named lists) by using either an Identifier
object or an Identifier_Text
value.
- In_List. List object.
- At_Position. (First overloaded form) Position_Count value that specifies the position of the list item that will become the new current list.
- Item_Name. (Second overloaded form) Identifier object with the name of the list item that will become the new current list.
- Item_Name. (Third overloaded form) Identifier_Text value with the name of the list item that will become the new current list.
-
CryptAda_List_Kind_Error if
In_List
current list is Empty. -
CryptAda_Index_Error if
At_Position
is not a valid position inIn_List
current list. - CryptAda_Syntax_Error if the Identifier_Text (third overloaded form) does not conform the syntax for identifiers.
- CryptAda_Identifier_Error if the identifier (second overloaded form) is a null identifier.
-
CryptAda_Named_List_Error (second or third overloaded forms) if
In_List
current list is an unnamed list. - CryptAda_Item_Kind_Error if the designated item is not a list item.
-
CryptAda_Item_Not_Found_Error (second or third overloaded forms) if
In_List
current list does not contain an item withItem_Name
name.
procedure Get_Item_Name(
In_List : in List'Class;
At_Position : in Position_Count;
Name : in out Identifier'Class);
Gets the name of a list item given its position.
- In_List. List object to query.
- At_Position. Position of the item whose name is to be obtained.
- Name. Identifier with the item name returned by the procedure.
-
CryptAda_List_Kind_Error if
In_List
current list is Unnamed. -
CryptAda_Index_Error if
At_Position
is not a valid position inIn_List
current list.
function Get_Item_Position(
In_List : in List'Class;
With_Name : in Identifier'Class)
return Position_Count;
function Get_Item_Position(
In_List : in List'Class;
With_Name : in Identifier_Text)
return Position_Count;
Gets the position of a item within the current list of a list given its name.
Two overloaded forms are provided that allow to provide the item name either as an Identifier object or as an Identifier_Text value.
- In_List. List object to query.
- With_Name. (First overloaded form) Identifier with the name of the item to obtain the position.
- With_Name. (Second overloaded form) Identifier_Text with the name of the item to obtain the position.
Returns a Position_Count
value with the position that the item occupies In_List
current list.
-
CryptAda_List_Kind_Error if
In_List
current list is Empty. -
CryptAda_Syntax_Error (Second overloaded form) if
With_Name
is not a syntactically valid identifier. -
CryptAda_Identifier_Error (First overloaded form) if
With_Name
is a null identifier. -
CryptAda_Named_List_Error if
In_List
current list is Unnamed. -
CryptAda_Item_Not_Found_Error if
In_List
current list does not contain an item withWith_Name
name.
function Contains_Item(
The_List : in List'Class;
With_Name : in Identifier'Class)
return Boolean;
function Contains_Item(
The_List : in List'Class;
With_Name : in Identifier_Text)
return Boolean;
Checks if the current list of a list object contains an item given its name.
Two overloaded forms are provided that allow to provide the item name either as an Identifier object or as an Identifier_Text value.
- The_List. List object to query.
- With_Name. (First overloaded form) Identifier with the name of the item to check for existence.
- With_Name. (Second overloaded form) Identifier_Text with the name of the item to check for existence.
Returns a Boolean
value that indicates whether or not The_List current list contains an item with With_Name
name.
-
CryptAda_List_Kind_Error if
The_List
current list is Empty. -
CryptAda_Syntax_Error (Second overloaded form) if
With_Name
is not a syntactically valid identifier. -
CryptAda_Identifier_Error (First overloaded form) if
With_Name
is a null identifier. -
CryptAda_Named_List_Error if
The_List
current list is Unnamed.