Re: I/O streaming with custom data transport



Alex R. Mosteo wrote:

I'm looking for something like this in Ada.

The basic I/O facilities in the standard library don't seem to provide
anything like this.
I hoped that Ada.Streams allows this by subclassing Root_Stream_Type and
providing some overriding operations, but unfortunately I cannot even
find the specification of Root_Stream_Type (looks like there isn't any
and this type is just a name placeholder in ARM).

I think you haven't looked right.

Indeed - it's in 13.13.1.

That's precisely how it's done.

And you do this just as you say: you extend
Ada.Streams.Root_Stream_Type and provide the read/write subprograms.

And I actually managed to do this.
Consider the following example of custom stream that for the sake of presentation is bound to standard IO and just converts characters to uppercase when writing (the point is that if I can do *this*, I can do anything else):

-- file my_streams.ads:
with Ada.Streams;
package My_Streams is
use Ada.Streams;

type My_Stream is new Root_Stream_Type with null record;

procedure Read(Stream : in out My_Stream;
Item : out Stream_Element_Array;
Last : out Stream_Element_Offset);

procedure Write(Stream : in out My_Stream;
Item : in Stream_Element_Array);
end My_Streams;

-- file my_streams.adb:
with Ada.Text_IO.Text_Streams;
with Ada.Characters.Handling;
package body My_Streams is
use Ada.Text_IO;
use Ada.Text_IO.Text_Streams;

Std_Stream : Stream_Access := Stream(Current_Output);

procedure Read(Stream : in out My_Stream;
Item : out Stream_Element_Array;
Last : out Stream_Element_Offset) is
begin
-- forward to standard streams:
Read(Std_Stream.all, Item, Last);
end Read;

procedure Write(Stream : in out My_Stream;
Item : in Stream_Element_Array) is
Item_Uppercase : Stream_Element_Array := Item;
C : Character;
begin
for I in Item_Uppercase'Range loop
C := Character'Val(Item_Uppercase(I));
C := Ada.Characters.Handling.To_Upper(C);
Item_Uppercase(I) := Stream_Element(Character'Pos(C));
end loop;

-- forward to standard streams:
Write(Std_Stream.all, Item_Uppercase);
end Write;
end My_Streams;

-- file hello.adb:
with Ada.Text_IO.Text_Streams;
with My_Streams;

procedure Hello is
use Ada.Text_IO;
use Ada.Text_IO.Text_Streams;
use My_Streams;

procedure Write_Hello(Stream : in out Stream_Access) is
begin
String'Write(Stream, "Hello");
end Write_Hello;

S1 : Stream_Access := Stream(Current_Output);
S2 : Stream_Access := new My_Stream;
begin
Write_Hello(S1);
New_Line;
Write_Hello(S2);
New_Line;
end Hello;

The result is:

$ ./hello
Hello
HELLO
$

The point here is that the Write_Hello procedure can be reused with various streams, just like my foo functions in C++ (from initial post).

Is the code above correct? Any traps or problems that I don't see at the moment?


--
Maciej Sobczak : http://www.msobczak.com/
Programming : http://www.msobczak.com/prog/
.



Relevant Pages

  • Re: differance between binary file and ascii file
    ... this aspect of the language as far as the standard file descriptors go. ... since I think it's fair to say that most redirected input to ... The Standard refers to the standard streams as "standard text ...
    (comp.lang.c)
  • Re: Initial status of feof(stdin)
    ... Are their EOF and ... > error indicators initially cleared, or in an unspecified or indeterminate ... The three standard streams are preopened, ...
    (comp.std.c)
  • Re: 4-20mA Analouge input
    ... Im sure there is a standard im meant to be following but im not sure ... between field sensors and process control ... electronics in the control house. ... loop voltage also 'powers' the field sensor device. ...
    (sci.electronics.design)
  • Re: Jump to multiple loop termination line
    ... The standard also "agrees" with this preference in that the practice is obsolescent in the standard. ... That place is inside the outer loop, ... (And the one compiler writer that I referred to before didn't realize it was an extension). ... I have also seen compilers that don't detect the error, but give various "strange" results from it. ...
    (comp.lang.fortran)
  • Re: How do I exit a for loop in C#
    ... AND DONT TRY TO INJECT THEM AS NORM OR STANDARD OR AS ... steadfastly refuse - to make a proof for a generalized statement based on ... supportable, based as a style guide - you dictate the style guide, and I'll ... > while loop than my for loop. ...
    (microsoft.public.dotnet.languages.csharp)