!standard 13.13.2 (31) 01-02-13 AI95-00260/00
!standard 13.13.2 (34)
!class amendment 01-02-13
!status received 01-02-13
!priority Low
!difficulty Medium
!subject How to replace S'Class'Input with custom versions
!summary
!problem
S'Class'Output writes the tag of an item with String'Output. This routine
cannot be replaced, so it is not possible to write the tag in an arbitrary
user-defined format (to match an external standard, for example).
A more general problem is that the dispatching accomplished by S'Class'Input
cannot be duplicated in normal user code. (If it could, that mechanism could
be used to eliminate the problem above by overridding the appropriate
operations).
!proposal
(* Ideas needed *)
!discussion
A significant annoyance.
!example
!ACATS test
!appendix
From: Pascal Obry
Sent: Wednesday, January 31, 2001 3:00 PM
Hello,
I have a comment/question about an Ada feature. The current implementation
for S'Class'Output seems to be not flexible enough for some job. Let's look at
the definition for 'Class'Ouput:
<<
29. S'Class'Output
S'Class'Output denotes a procedure with the following
specification:
30. procedure S'Class'Output(
Stream : access Ada.Streams.Root_Stream_Type'Class;
Item : in T'Class)
31. First writes the external tag of Item to Stream (by calling
String'Output(Tags.External_Tag(Item'Tag) - *Note 3.9::.) and
then dispatches to the subprogram denoted by the Output
attribute of the specific type identified by the tag.
>>
The problem here is the way the tag is written using String'Output.
My goal was to write (on disk using streams) objects in XML. But this is not
possible because the tag is written with the string's bounds (String'Output) !
So there is some binary data dumped into the XML file !!!
Of course it is possible to write the tag myself, but then it will be just
impossible to read back the object from the disk...
To summarize:
It is possible to stream an object to disk only in binary format.
It would be nice to be able to control the way the tag is written. I don't
have a proposal for this right now...
I have talked about this issue with my ACT support and we came to the
conclusion that it is just impossible to do what I wanted!
Please let me know if this is clear enough or if you need some more info.
****************************************************************
From: Tucker Taft
Sent: Wednesday, January 31, 2001 5:40 PM
It is definitely frustrating that the dispatching performed by
S'Class'Input cannot be duplicated by "normal" user code. Essentially
one wants to be able to dispatch using an (internal) tag rather
than an object. Alternatively, one wants to be able to construct
an object with default initialization given a tag.
Some kind of "magic" generic might be defined to provide this
capability, or something similar. This definitely will require
some head-scratching.
****************************************************************
From: Pascal Obry
Sent: Saturday, March 17, 2001 2:57 PM
Hello,
Please have a look at this first proposal. I have tried to write something but
this is the very first time I do something like that. I'm not sure the wording
is correct, not talking about my english :) Can you told me if this all this
makes sense to you or if it is just not the right way to approach the
problem. I have tried to follow current AI structure.
<<
!summary
The stream input/output attributes are not flexible enough. The problem is for
the tag handling of tagged object. With the current implementation it is not
possible for example to redefine the 'Read and 'Write to have the object
streamed as an XML object. We propose a solution to solve this problem.
!problem
The problem is for the tag handling of tagged object. With the current
implementation it is not possible for example to redefine the 'Read and 'Write
to have the object streamed as an XML object. Indeed the tag is defined as a
string. It is possible to change the tag string value by using Ada.Tags
facilities. But the tag will always be a string : an unbounded object. Each
time the tagged object will be streamed the tag string value will be written
preceded by the string bound which are binary data. There is no way to avoid
these binary data to be sent. In other word, there is no way to stream an
object with a plain text representation.
!proposal
Have the possibility to set the way the 'Class'Output and 'Class'Input handle
the tag with the new attribute 'Tag_Format. Values for this attributes is of
type Ada.Tags.Tag_Output:
type Tag_Ouput is (Constrained, Unconstrained);
'Tag_Format
is set to Unconstrained by default. This is the current behavior. In this
mode 'Class'Output will call String'Output on the tag string to output the
tag. And 'Class'Input will call String'Input to read the tag. So with
Unconstrained the tag's bounds are used. If it is set to Constrained then
the tag will be written using String'Write (and read using String'Read). In
this case the tag's bounds are not used.
The definition for S'Class'Input and S'Class'Output must be changed
accordingly.
!discussion
We could find some other ways to implement this feature. This is certainly the
lightest one as it requires only one new attributes on tagged record. Another
solution would have been to define two new attributes 'Read_Tag and 'Write_Tag
for reading and writing a tag value. These attributes would have the current
default and could have been overridden by users. It would have been possible to
solve the problem described here with this mechanism. Something like:
procedure Write_Tag (S : access Streams.Root_Stream_Type'Class; O : Object);
for Object'Write_Tag use Write_Tag;
procedure Read_Tag (S : access Streams.Root_Stream_Type'Class; O : Object);
for Object'Read_Tag use Read_Tag;
!example
Here is an example that show the problem. Let's say that we want to stream an
object with an XML encoding:
with Ada.Streams;
package Class is
use Ada;
type Object is tagged record
V : Integer := 2;
end record;
procedure Write (S : access Streams.Root_Stream_Type'Class; O : Object);
for Object'Write use Write;
for Object'External_Tag use "");
end Write;
end Class;
with Ada.Text_IO.Text_Streams;
with Class;
procedure Main is
use Ada;
O : Class.Object;
begin
Class.Object'Class'Output
(Text_IO.Text_Streams.Stream (Text_IO.Current_Output), O);
end Main;
This program output will be something like:
^A^@^@^@^H^@^@^@
The 8 first characters are binary representation for the tag bound. This is no
way to bypass that, so there is no way to stream an object with an XML
representation.
Using the new 'Tag_Format attributes it is possible to control the tag
output. By changing the Class spec to read:
with Ada.Streams;
package Class is
use Ada;
type Object is tagged record
V : Integer := 2;
end record;
procedure Write (S : access Streams.Root_Stream_Type'Class; O : Object);
for Object'Write use Write;
for Object'External_Tag use "