Ada Resource Association
News and resources for the Ada programming language
Ada Reference ManualLegal Information
Contents   Index   References   Search   Previous   Next 

13.13.2 Stream-Oriented Attributes

1/1
The operational attributes Write, Read, Output, and Input convert values to a stream of elements and reconstruct values from a stream. 

Static Semantics

1.1/2
  For every subtype S of an elementary type T, the following representation attribute is defined: 
1.2/2
  S'Stream_Size

Denotes the number of bits occupied in a stream by items of subtype S. Hence, the number of stream elements required per item of elementary type T is:
1.3/2
T'Stream_Size / Ada.Streams.Stream_Element'Size
1.4/2
The value of this attribute is of type universal_integer and is a multiple of Stream_Element'Size.
1.5/2
Stream_Size may be specified for first subtypes via an attribute_definition_clause; the expression of such a clause shall be static, nonnegative, and a multiple of Stream_Element'Size.

Implementation Advice

1.6/2
  If not specified, the value of Stream_Size for an elementary type should be the number of bits that corresponds to the minimum number of stream elements required by the first subtype of the type, rounded up to the nearest factor or multiple of the word size that is also a multiple of the stream element size. 
1.7/2
  The recommended level of support for the Stream_Size attribute is: 
1.8/2





Static Semantics

2
For every subtype S of a specific type T, the following attributes are defined. 
3
S'Write
S'Write denotes a procedure with the following specification: 
4/2
procedure S'Write(
   Stream : not null access Ada.Streams.Root_Stream_Type'Class;
   Item : in T)
5
S'Write writes the value of Item to Stream.
6
S'Read
S'Read denotes a procedure with the following specification: 
7/2
procedure S'Read(
   Stream : not null access Ada.Streams.Root_Stream_Type'Class;
   Item : out T)
8
S'Read reads the value of Item from Stream
8.1/2
  For an untagged derived type, the Write (resp. Read) attribute is inherited according to the rules given in 13.1 if the attribute is available for the parent type at the point where T is declared. For a tagged derived type, these attributes are not inherited, but rather the default implementations are used.
8.2/2
  The default implementations of the Write and Read attributes, where available, execute as follows:
9/2
For elementary types, Read reads (and Write writes) the number of stream elements implied by the Stream_Size for the type T; the representation of those stream elements is implementation defined. For composite types, the Write or Read attribute for each component is called in canonical order, which is last dimension varying fastest for an array, and positional aggregate order for a record. Bounds are not included in the stream if T is an array type. If T is a discriminated type, discriminants are included only if they have defaults. If T is a tagged type, the tag is not included. For type extensions, the Write or Read attribute for the parent type is called, followed by the Write or Read attribute of each component of the extension part, in canonical order. For a limited type extension, if the attribute of the parent type or any progenitor type of T is available anywhere within the immediate scope of T, and the attribute of the parent type or the type of any of the extension components is not available at the freezing point of T, then the attribute of T shall be directly specified.
9.1/2
  Constraint_Error is raised by the predefined Write attribute if the value of the elementary item is outside the range of values representable using Stream_Size bits. For a signed integer type, an enumeration type, or a fixed point type, the range is unsigned only if the integer code for the lower bound of the first subtype is nonnegative, and a (symmetric) signed range that covers all values of the first subtype would require more than Stream_Size bits; otherwise the range is signed.
10
For every subtype S'Class of a class-wide type T'Class: 
11
S'Class'Write
S'Class'Write denotes a procedure with the following specification: 
12/2
procedure S'Class'Write(
   Stream : not null access Ada.Streams.Root_Stream_Type'Class;
   Item   : in T'Class)
13
Dispatches to the subprogram denoted by the Write attribute of the specific type identified by the tag of Item.
14
S'Class'Read
S'Class'Read denotes a procedure with the following specification: 
15/2
procedure S'Class'Read(
   Stream : not null access Ada.Streams.Root_Stream_Type'Class;
   Item : out T'Class)
16
Dispatches to the subprogram denoted by the Read attribute of the specific type identified by the tag of Item. 

Implementation Advice

17/2
 This paragraph was deleted.

Static Semantics

18
For every subtype S of a specific type T, the following attributes are defined. 
19
S'Output
S'Output denotes a procedure with the following specification: 
20/2
procedure S'Output(
   Stream : not null access Ada.Streams.Root_Stream_Type'Class;
   Item : in T)
21
S'Output writes the value of Item to Stream, including any bounds or discriminants. 
22
S'Input
S'Input denotes a function with the following specification: 
23/2
function S'Input(
   Stream : not null access Ada.Streams.Root_Stream_Type'Class)
   return T
24
S'Input reads and returns one value from Stream, using any bounds or discriminants written by a corresponding S'Output to determine how much to read. 
25/2
 For an untagged derived type, the Output (resp. Input) attribute is inherited according to the rules given in 13.1 if the attribute is available for the parent type at the point where T is declared. For a tagged derived type, these attributes are not inherited, but rather the default implementations are used.
25.1/2
   The default implementations of the Output and Input attributes, where available, execute as follows:
26
27/2
27.1/2
   If T is an abstract type, then S'Input is an abstract function.
28
For every subtype S'Class of a class-wide type T'Class: 
29
S'Class'Output

S'Class'Output denotes a procedure with the following specification: 
30/2
procedure S'Class'Output(
   Stream : not null access Ada.Streams.Root_Stream_Type'Class;
   Item   : in T'Class)
31/2
First writes the external tag of Item to Stream (by calling String'Output(Stream, Tags.External_Tag(Item'Tag)) — see 3.9) and then dispatches to the subprogram denoted by the Output attribute of the specific type identified by the tag. Tag_Error is raised if the tag of Item identifies a type declared at an accessibility level deeper than that of S. 
32
S'Class'Input
S'Class'Input denotes a function with the following specification: 
33/2
function S'Class'Input(
   Stream : not null access Ada.Streams.Root_Stream_Type'Class)
   return T'Class
34/2
First reads the external tag from Stream and determines the corresponding internal tag (by calling Tags.Descendant_Tag(String'Input(Stream), S'Tag) which might raise Tag_Error — see 3.9) and then dispatches to the subprogram denoted by the Input attribute of the specific type identified by the internal tag; returns that result. If the specific type identified by the internal tag is not covered by T'Class or is abstract, Constraint_Error is raised. 
35/2
 In the default implementation of Read and Input for a composite type, for each scalar component that is a discriminant or whose component_declaration includes a default_expression, a check is made that the value returned by Read for the component belongs to its subtype. Constraint_Error is raised if this check fails. For other scalar components, no check is made. For each component that is of an access type, if the implementation can detect that the value returned by Read for the component is not a value of its subtype, Constraint_Error is raised. If the value is not a value of its subtype and this error is not detected, the component has an abnormal value, and erroneous execution can result (see 13.9.1). In the default implementation of Read for a composite type with defaulted discriminants, if the actual parameter of Read is constrained, a check is made that the discriminants read from the stream are equal to those of the actual parameter. Constraint_Error is raised if this check fails.
36/2
 It is unspecified at which point and in which order these checks are performed. In particular, if Constraint_Error is raised due to the failure of one of these checks, it is unspecified how many stream elements have been read from the stream.
37/1
 In the default implementation of Read and Input for a type, End_Error is raised if the end of the stream is reached before the reading of a value of the type is completed.
38/2
 The stream-oriented attributes may be specified for any type via an attribute_definition_clause. The subprogram name given in such a clause shall not denote an abstract subprogram. Furthermore, if a stream-oriented attribute is specified for an interface type by an attribute_definition_clause, the subprogram name given in the clause shall statically denote a null procedure. 
39/2
 A stream-oriented attribute for a subtype of a specific type T is available at places where one of the following conditions is true:
40/2
41/2
42/2
43/2
44/2
45/2
 A stream-oriented attribute for a subtype of a class-wide type T'Class is available at places where one of the following conditions is true:
46/2
47/2
48/2
49/2
 An attribute_reference for one of the stream-oriented attributes is illegal unless the attribute is available at the place of the attribute_reference. Furthermore, an attribute_reference for T'Input is illegal if T is an abstract type.
50/2
 In the parameter_and_result_profiles for the stream-oriented attributes, the subtype of the Item parameter is the base subtype of T if T is a scalar type, and the first subtype otherwise. The same rule applies to the result of the Input attribute.
51/2
 For an attribute_definition_clause specifying one of these attributes, the subtype of the Item parameter shall be the base subtype if scalar, and the first subtype otherwise. The same rule applies to the result of the Input function.
52/2
 A type is said to support external streaming if Read and Write attributes are provided for sending values of such a type between active partitions, with Write marshalling the representation, and Read unmarshalling the representation. A limited type supports external streaming only if it has available Read and Write attributes. A type with a part that is of an access type supports external streaming only if that access type or the type of some part that includes the access type component, has Read and Write attributes that have been specified via an attribute_definition_clause, and that attribute_definition_clause is visible. An anonymous access type does not support external streaming. All other types support external streaming.

Erroneous Execution

53/2
 If the internal tag returned by Descendant_Tag to T'Class'Input identifies a type that is not library-level and whose tag has not been created, or does not exist in the partition at the time of the call, execution is erroneous. 

Implementation Requirements

54/1
 For every subtype S of a language-defined nonlimited specific type T, the output generated by S'Output or S'Write shall be readable by S'Input or S'Read, respectively. This rule applies across partitions if the implementation conforms to the Distributed Systems Annex.
55/2
 If Constraint_Error is raised during a call to Read because of failure of one the above checks, the implementation must ensure that the discriminants of the actual parameter of Read are not modified.

Implementation Permissions

56/2
 The number of calls performed by the predefined implementation of the stream-oriented attributes on the Read and Write operations of the stream type is unspecified. An implementation may take advantage of this permission to perform internal buffering. However, all the calls on the Read and Write operations of the stream type needed to implement an explicit invocation of a stream-oriented attribute must take place before this invocation returns. An explicit invocation is one appearing explicitly in the program text, possibly through a generic instantiation (see 12.3). 
NOTES
57
33  For a definite subtype S of a type T, only T'Write and T'Read are needed to pass an arbitrary value of the subtype through a stream. For an indefinite subtype S of a type T, T'Output and T'Input will normally be needed, since T'Write and T'Read do not pass bounds, discriminants, or tags.
58
34  User-specified attributes of S'Class are not inherited by other class-wide types descended from S. 

Examples

59
Example of user-defined Write attribute: 
60/2
procedure My_Write(
  Stream : not null access Ada.Streams.Root_Stream_Type'Class;
  Item   : My_Integer'Base);
for My_Integer'Write use My_Write;

Contents   Index   References   Search   Previous   Next 
Ada-Europe Sponsored by Ada-Europe