Inspirel banner

Programming Distributed Systems with YAMI4

3.6.1 Ada

Reading existing entries of fundamental types is straightforward:

declare
   Ada : YAMI_Integer;
begin
   Age := Params.Get_Integer ("age");
   -- ...
end;

Strings and binary buffers can be similarly extracted with a single function call:

declare
   First_Name : String := Params.Get_String ("first_name");
   Song : Ada.Streams.Stream_Element_Array :=
     Params.Get_Binary ("favorite_song");

Extracting arrays of fundamental types involves the use of generics, as the index and array types are not enforced by the library.

Assuming that user-defined types are defined as before:

declare
   type My_Int_Type is new Integer;
   type My_Index_Type is new Positive;
   type My_Int_Array is array (My_Index_Type range <>)
      of My_Int_Type;

the following generic instantiation is needed to handle the extraction of the array entry:

   procedure My_Get_Integer_Array is new Get_Integer_Array
     (Integer_Type => My_Int_Type,
      Index_Type => My_Index_Type,
      Integer_Array_Type => My_Int_Array);

With the above instantiation the array can be read in the three-phase way, by first extracting the size of array, then allocating the array big enough to hold all the data and then copying the data to the user-provided buffer:

   Array_Length : Count_Type :=
      Params.Get_Integer_Array_Length ("favorite_numbers");

   My_Numbers : My_Int_Array (1 .. My_Index_Type (Array_Length));

begin
   My_Get_Integer_Array (Params, "favorite_numbers", My_Numbers);
end;

Arrays of long and double types are handled in the same way except that generic formal parameter names are different (they start with Long_Long_Integer_ and Long_Float_ instead of Integer_).

Arrays of boolean values are also handled in the same way, except that there is no Boolean_Type generic formal parameter and therefore the whole operation has two parameters instead of three.

Arrays of strings do not follow the same mold and somehow mirror the way they are created. In order to read the string array element, the name of the whole array and its index, starting from 1, need to be provided:

declare
   First_Friend : String :=
      Params.Get_String_In_Array ("friends", 1);
   Second_Friend : String :=
      Params.Get_String_In_Array ("friends", 2);
   Third_Friend : String :=
      Params.Get_String_In_Array ("friends", 3);

A separate function, Get_String_Array_Length, can be used to read the actual length of the array.

Arrays of binary values are handled in a similar way, with Get_Binary_Array_Length function for reading the array length.

Nested parameters can be extracted with a special constructor function that returns the already wrapped parameters object. The returned object references the named nested entry and is aware of its relation with the whole container, so that it does not invalidate the referenced entry during its own finalization:

declare
   Nested : Parameters_Collection :=
      Params.Get_Nested_Parameters ("address");

Care should be taken to ensure that such object does not live longer than the parameters object representing the whole container - it is recommended to use scoping to ensure proper lifetime management.

Note:

If the entry given by name does not exist, each of the reading operations will raise the Logic_Error exception defined in the package YAMI. Similarly, when the given entry exists but its type does not correspond to the expected type of the reading operation, the same exception will be raised. The reason for this exception choice is that such situations are considered to be programming errors. Code that needs to read entries that might not exist or with flexibility in type handling should use the methods described in later sections devoted to entry searches.