Ada Type Interchange Generator

Technical Specification

The main function of the Ada Type-Interchange Generator (ATIG) is to create and maintain interchange subprograms (Ada procedures) that:


This mechanism can be used to transmit data values (messages) between heterogeneous computers running code compiled by different compilation systems. The message sender can call an interchange subprogram for the message's type to write its current value into a byte string. The sender will then transmit the byte string over some communication medium to a receiver that will read its value into a local data structure by calling the corresponding interchange procedure. Agreed-upon formats for predefined type values (that is, integers, reals, and bytes) are used to ensure that the receiver gets a data value identical to that of the sender even if the layout used by each local compiler is different. This mechanism is similar to the stream-oriented attributes in Ada 95. It is implemented, however, in Ada 83 and is fully portable.

ATIG subprograms write composite data structures into the byte string one component at a time. The byte representation for each component is constructed by the write procedure for the component type. Nested structures are thus "flattened" into a sequence of predefined leaf values through a sequence of calls to write subprograms. The read process is analogous. Byte sequences are converted into values and stored in the components of the local data structure. ATIG attempts to minimize the number of bytes in each type's representation, especially for unconstrained types.

Automated generation and consistency checking of interchange subprograms is provided by ATIG for the following kinds of types:

See the section titled "Subprogram Interchange Formats" for detailed information on interchange formats for each type. Note that automatic generation of interchange subprograms for access, protected, and task types is not supported by ATIG.

Several transfer formats for the predefined leaf values can be defined to serve diverse purposes:

The user can change formats by substituting a different implementation (body) for the package providing interchange of the predefined types.

ATIG Commands

General Capabilities

Two user commands are defined by ATIG. They can be invoked at the UNIX shell with a command line or via the GUI menu selection and dialog box. These commands provide the capability to:

All generated interchange subprograms can be created inline or as subunits. The name of the type and any packages in which the type is nested are used to create the name for the interchange subprogram. This is done to ensure unique subunit names as required by Ada. Automated checkout, checkin, and recompilation of units is performed as required.

A log will report all work attempted and any problems that occur during processing. Warnings include unit access problems, missing interchange subprograms, and/or missing unit bodies. Warnings will also be generated for unsupported types or types whose bounds are too large to fit in the predefined leaf types. Some errors terminate processing of a specific type (see the section titled "Restrictions" below).

Detailed Command Descriptions

command For_Specific_Type
atig for_specific_type

-For_Type
-Recursive
-Recursive_Only_Within_Local_View
-Force_Overwrite
-Compile_After_Updates
-Use_Configuration [string-expression, default= ""]
Description This command generates (or replaces as necessary) interchange subprograms for a specified type. The type declaration can be specified with any valid naming string. Subprogram specifications are added only if they do not already exist. The body of the interchange subprogram is updated only if it is inconsistent with the current type definition or if the Force_Overwrite option is set to True.

Options

This command is best executed by selecting a type declaration in an Ada unit and selecting the ATIG command on the Control menu. Note that this menu selection may appear in another location at your site. Check with the installer to determine the exact menu configuration. This will create a dialog box with the following sections:

Of_Type: This section appears at the top of the dialog box and is used to specify the pathname of the type declaration to process. Selection of an Ada type will automatically fill this section with the pathname of that type.
Non-operable Locator: This is a standard Apex file locator but it is not used by this command.

Configuration: The configuration section is used to specify whether import closure or a named configuration file should be used during analysis to resolve references. The default is to use the import closure of the units selected in the Objects locator. If the user desires another configuration, the Use configuration radio button can be selected and a pathname of .cfg file entered.

Report Name: This section is not used by ATIG.

Options: The section appears at the bottom left of the dialog box and contains Boolean options that can be selected by the user. The boolean options for this command are Recursive, Force_Overwrite, and Compile_After_Updates.

command For_Types_In_Units
atig for_types_in_units

-Recursive
-Recursive_Only_Within_Local_View
-Only_Required_Types
-Effort_Only
-Compile_After_Updates
-Use_Configuration [string-expression, default= ""] 
Description

This command traverses all compiled Ada units specified by the to locate type declarations. Each located type declaration is checked to validate that the required interchange subprograms exist and that their implementations are up to date. All missing items are created. All out-of-date interchange implementations are replaced. The Effort-_Only option can be used to check and report the status of all types without actually doing any work.
Note that the comment annotation, "-- No Interchange Necessary" (this is customizable; see section titled "Customization" below) can be attached to those types in a package for which no interchange subprograms are desired. The annotation "-- Nonvisible Interchange" (also customizable) can be attached to type declarations for which interchange is required, but only for local use. The interchange specs will be placed in the body for these types.

Options

This command is best executed by selecting a set of Ada units in a directory image and selecting the ATIG command on the Control menu. Note that this menu selection may appear in another location at your site. Check with the installer to determine the exact menu configuration. This will create a dialog box with the following sections:

Objects: This is a standard Apex file locator and is used to specify which Ada units should be analyzed by a command. Objects selected within the window where the command menu item was invoked will appear as initial values in the right side of the locator. Configuration files, views, directories, and Ada objects can be added or removed from the right side as required to specify the desired list of Ada units to analyze.

Configuration: The configuration section is used to specify whether import closure or a named configuration file should be used during analysis to resolve references. The default is to use the import closure of the units selected in the Objects locator. If the user desires another configuration, the Use configuration radio button can be selected and a pathname of .cfg file entered.

Report Name: This section is not used by ATIG.

Options: The section appears at the bottom left of the dialog box and contains Boolean options that can be selected by the user. The boolean options for this command are Recursive, Only_Required_Types, Effort_Only, and Compile_After_Updates.

Special Capabilities

The exact text of all annotations in this section is customizable (see section titled 3Customization2 below). To be recognized by ATIG, all comment annotations must appear immediately before the type declaration to which they apply. Annotations are not case sensitive.

"No Interchange Necessary" Annotation

The annotation "-- No Interchange Necessary" can be used to specify that no interchange subprograms should be generated for a particular type. This is especially useful in conjunction with the For_Types_In_Units command when interchange is not required for every type within a set of packages.

"Nonvisible Interchange" Annotation

The annotation "-- Nonvisible Interchange" can be used to specify that the interchange subprograms for a particular type should be located in the body of the package in which the type is declared. This mechanism can be used when a composite type references other local types in the package. For correct creation of the interchange subprogram for the composite type, interchange subprograms must be available for all referenced types, but they need not be made visible if all references are local. If external references to the type exist, then visible interchange routines are required. In this case, a message to this effect is placed in the log, and the interchange subprograms for types with external references will not compile. The user must manually make the required subprogram specifications visible or delete the annotation, remove all existing interchange subprograms for that type, and start fresh with the ATIG For_Specific_Type command.

"Hand-Generated Interchange" Annotation

The annotation "-- Hand-Generated Interchange" can be used to specify that the interchange subprograms for a particular type have been written by hand and that they should not be replaced by any command. ATIG commands will add required interchange specifications and subunit stubs if they do not exist, but they will not replace any subunit implementations.

"Message Id" Annotation

The annotation "-- Message Id: >>Id String<<" can be added before any type declaration to assign a string ID to that type. This could be added to the message byte string through a call in the body of the interchange write procedures. Reading this field would then be the responsibility of the receiver of this message. Note that this capability is not fully deÞned for this version of ATIG. This mechanism is currently designed as a placeholder for subsequent versions of this tool.

Read Interchange Functions for Unconstrainted Types

The procedural form of read is often inconvenient because the caller must know the discriminant and/or index constraints before calling the procedure. Although less efficient, a functional form of read allows the constraints to be read and set within the function. The return value can be assigned to a constant, avoiding the need for the caller to know the constraints in advance. A Boolean customization function specifies whether to create read functions for unconstrained types in addition to read procedures. See the section titled "Customization" at the end of this user's guide for more information.

Two conditions must be met in order to use this capability:

1. The Byte_Stream type in the Byte_Stream_Support package must be an access type. This allows it to be passed into the function as an in parameter even though the data (byte stream) that it points to will be updated by the read.

2. This capability cannot be used in conjunction with the creation of subunit conversion subprograms since the name of the functional read and procedural read are identical and will conflict.

Restrictions

Packages without Bodies

ATIG requires that packages containing types have both a spec and a body. A body is necessary to contain the interchange subprograms. ATIG will recognize and report when a package body is missing and not attempt to create interchange subprograms for that type. The body must be created by the user and then ATIG can be re-executed.

Controlled Objects

When the unit containing a type declaration requires checkout and is not the latest generation, no processing of this type will be performed. In this case, the unit may be changed by CMVC when the latest generation is automatically accepted on checkout. For objects that are not the latest generation, the user must manually check out the unit and recompile it before ATIG will process it.

Generic Units

Types declared in generic packages will often reference types declared as formal parameters of the generic. If this is the case, read and write interchange subprograms must be present as formal parameters of the generic. See the section titled "Subprogram Interchange Formats" for requirements for the naming of these subprograms and their parameters. ATIG can add these required generic formal parameters but all instantiations of this generic will need to be updated by hand. Without restriction, the hierarchical traversal commands can validate generic formal subprogram consistency and replace interchange implementations as necessary.

Types Declared in Nested Packages

If a type is declared in a package that is nested one or more levels within the library-level package, the body of that package must be a subunit if the customization specifies that ATIG should create subunits.

Composite Types with Limited Private Components

Since the read interchange subprogram returns a value of the type through an out parameter, limited types cannot be used as components of any composite type used as the type mark of the parameter (see LRM 7.4.4 (4)). This is a restriction since assignment is not available for limited types and the out parameter cannot be set without it. If a type with this characteristic is encountered, an error message is generated and no interchange subprograms are generated.

Error and Warning Messages

Error messages may be generated for the following instances:

Warning messages may be generated for the following instances:

Testing

Test input is provided for all types listed above in the section titled "Overview." An attempt has been made to provide test input for all casesÐthat is, every form of type that is supported by ATIG. These are located in the atig_testing.ss subsystem of the ATIG release directory. The results of automatic generation by ATIG are also included in the release. The interchange subunits generated by ATIG provide examples of the format generated for each kind of type. If local customizations are made to ATIG, these input type definitions can also be used to test that ATIG is functioning correctly.

Base Interfaces

The interchange of leaf types is based on definitions in the following abbreviated specifications. Note that the names of the packages can be changed with the customization package of ATIG (see below). It is also possible to change the types actually supported and their names.

System_Types
package System_Types is
type Integer8 is range -2 ** 7 .. 2 ** 7 - 1;
subtype Positive8 is Integer8 range 1 .. Integer8'Last;
subtype Natural8 is Integer8 range 0 .. Integer8'Last;
type Integer16 is range -2 ** 15 .. 2 ** 15 - 1;
subtypePositive16 is Integer16 range 1 .. Integer16'Last;
subtype Natural16 is Integer16 range 0 .. Integer16'Last;
type Integer32 is range -2 ** 31 .. 2 ** 31 - 1;
subtype Positive32 is Integer32 range 1 .. Integer32'Last;
Tsubtype Natural32 is Integer32 range 0 .. Integer32'Last;
type Local_String is array (Positive16 range <>) of Character;
type Float6 is digits 6;
type Float9 is digits 9;
type Float13 is digits 13;

end System_Types;

Interchange of these predefined types is provided by the following package.

Byte_Stream_Support
with Calendar;
with System_Types;
package Byte_Stream_Support is
type Byte_Stream is implementation defined;
procedure Integer8_Read (From : in out Byte_Stream;
Into : out System_Types.Integer8);
procedure Integer16_Read (From : in out Byte_Stream;
Into : out System_Types.Integer16);
procedure Integer32_Read (From : in out Byte_Stream;
Into : out System_Types.Integer32);
procedure Character_Read (From : in out Byte_Stream;
Into : out Character);
procedure String_Read (From : in out Byte_Stream;
Into : out String);
procedure Local_String_Read (From : in out Byte_Stream;
Into : out System_Types.Local_String);
procedure Float6_Read (From : in out Byte_Stream;
Into : out System_Types.Float6);
procedure Float9_Read (From : in out Byte_Stream;
Into : out System_Types.Float9);
procedure Float13_Read (From : in out Byte_Stream;
Into : out System_Types.Float13);
procedure Duration_Read (From : in out Byte_Stream;
Into : out Duration);
procedure Time_Read (From : in out Byte_Stream;
Into : out Calendar.Time);
procedure Integer8_Write (From : in System_Types.Integer8;
Into : in out Byte_Stream);
procedure Integer16_Write (From : in System_Types.Integer16;
Into : in out Byte_Stream);
procedure Integer32_Write (From : in System_Types.Integer32;
Into : in out Byte_Stream);
procedure Character_Write (From : in Character;
Into : in out Byte_Stream);
procedure String_Write (From : in String;
Into : in out Byte_Stream);
procedure Local_String_Write (From : in System_Types.Local_String;
Into : in out Byte_Stream);
procedure Float6_Write (From : in System_Types.Float6;
Into : in out Byte_Stream);
procedure Float9_Write (From : in System_Types.Float9;
Into : in out Byte_Stream);
procedure Float13_Write (From : in System_Types.Float13;
Into : in out Byte_Stream);
procedure Duration_Write (From : in Duration;
Into : in out Byte_Stream);
procedure Time_Write (From : in Calendar.Time;
Into : in out Byte_Stream);
end Byte_Stream_Support;

An implementation (body) of this package is provided for execution on the release hardware platform. This is located in the base_interfaces subdirectory of the atig_testing.ss subsystem. These packages or their equivalent should be moved into an application subsystem since they will in fact be part of the executable application. It is expected that users will write alternative implementations of the body to support different formats and optimizations and to provide support for specific compilation systems.

Note: Before any attempt is made to generate interchange programs with ATIG, the subsystems containing these packages must be imported into any application subsystem containing software to be updated with ATIG. This is necessary because the generated subprograms will reference these specifications.

Subprogram Interchange Formats

For each supported type, two interchange procedures, Read and Write, are created in the same declarative part as the type.
type T is ;
procedure T_Write (From : in T;
Into : in out Byte_Stream_Support.Byte_Stream);
procedure T_Read (From : in out Byte_Stream_Support.Byte_Stream;
Into : out T);

The Write procedure converts a value of the type to a sequence of bytes and appends it to a specified byte stream. The Read procedure removes a sequence of bytes from the specified stream, converts it to a value of the type, and returns it in an object of the type. It expects the next sequence of bytes from the stream to have the form written by the corresponding Write; if the elements do not have that form, or do not satisfy the constraints of the actual out parameter, then the Constraint_Error exception will be raised.

It is possible for users to manually add specifications and subunit stubs and to create subunit implementations for any type that requires interchange. It is required that users manually add subprogram formal parameters to generics whose formal parameter specification contains types requiring interchange. Manually added specifications must have the exact parameter profile shown in the example above. The name of the subprogram is constructed as follows:

Each nested package name (except the outermost library-unit name) is prefixed to the subprogram name as in the following example:

Nested Package Example

The same process is used to construct the names for generic formal parameters. The simple name of the formal type parameter and any nested package names are used in the same way.

Note: It is possible to change the names "Read" and "Write" to any other string names desired by the user of ATIG. If these names are changed with the customization options described below, then they must be used consistently in all interchange subprograms. Formats for Specific Types

The following list describes the interchange-subprogram format for each supported type.

Note: Mutable discriminant records that are limited private require special handling because the discriminant cannot be set externally. In this case, the package declaring the type must offer a procedure Initialize with an in out parameter for the type and the exact set of discriminants.

Customization

The following items are customizable by updating the body of the Customization package. The specification of the Customization package defines a list of abstract predefined types that could be supported by the application. Any subset of these types can be supported by the application and customized with their actual names, bounds, and accuracy constraints.


The following items describe ATIG parameters that are customizable and their default values.

References

1. Ada 95 Reference Manual, ISO standard 8652, 1995.

2. Ada Semantic Interface Specification (ASIS)

3. XDR: External Data Representation Standard, RFC 104, Sun Microsystems, 1987.

4. Basic Encoding Rules for Abstract Syntax Notation One (ASN.1), ISO standard 8825, 1987.

5. Philippe Kruchten: Byte Streams: A proposed solution to the problem of data transfer in a heterogeneous network, CAATS Architecture Note #47, Hughes Canada, April 1993.


products

atig data sheet | atig pdf (140K)

ada analyzer | ada repair | ada analyzer/ ada repair

little tree home | about little tree | technical articles | email