Re: Affectation avec Standard_Output.

Ludovic Brenta <[email protected]>
Newsgroups gmane.comp.lang.ada.france
Message-ID <[email protected]>
Pascal <[email protected]> writes:
> Merci Ludovic pour ta solution.  Je ne suis pas familier des Streams
> vu que Text_IO me suffisait jusque là.
>
> Le problème : en fait suivant la nature du fichier de type Text, Write
> va écrire sur stdout, un fichier disque ou une fenêtre avec
> GTK.TextView.  Le nom me permet de faire l'aiguillage.

Pour écrire dans un GTK.Text_View il faut écrire dans le
Gtk.Text_Buffer, qui n'a aucun lien avec un quelconque File ni avec
Ada.Text_IO.  En fait, tu ne peux pas associer un File avec un
Gtk.Text_Buffer.  En revanche tu peux associer un Stream avec un
Gtk.Text_Buffer.  L'aiguillage se fait par dynamic dispatching et ne
peut pas se faire par le nom, puisque ni Standard_Output ni le
Text_Buffer n'ont de nom.

with Ada.Streams.Stream_IO;
with Ada.Strings.Unbounded;
package File_Stream is
   type T (<>) is new Ada.Streams.Root_Stream_Type with private;
   function Open (File_Name : in String) return T;
private
   type T is new Ada.Streams.Root_Stream_Type with record
      File : Ada.Streams.Stream_IO.File_Type;
      Name : Ada.Strings.Unbounded.Unbounded_String;
   end record;
end File_Stream;

package body File_Stream is
   function Open (File_Name : in String) return File_Stream is
   begin
      return Result : T do
         Ada.Streams.Stream_IO.Open (File => Result.File,
                                     Mode => Ada.Streams.Stream_IO.Out_File,
                                     Name => File_Name);
         Result.Name := Ada.Strings.Unbounded.To_Unbounded_String (File_Name);
      end;
   end Open;
end File_Stream;

with Ada.Streams;
with Gtk.Text_Buffer;
package Buffer_Stream is
   type T (<>) is new Ada.Streams.Root_Stream_Type with private;
   function Open (Buffer : in Gtk.Text_Buffer.Gtk_Text_Buffer) return T;
private
   type T is new Ada.Streams.Root_Stream_Type with record
      Buffer : Gtk.Text_Buffer.Gtk_Text_Buffer;
   end record;
   overriding procedure Read (Stream : in out T;
                              Item   : out Stream_Element_Array;
                              Last   : out Stream_Element_Offset);
   overriding procedure Write (Stream : in out T;
                               Item   : out Stream_Element_Array);
end Buffer_Stream;

package body Buffer_Stream is
   function Open (Buffer : in Gtk.Text_Buffer.Gtk_Text_Buffer)
     return T is
   begin
      return (Ada.Streams.Root_Stream_Type with Buffer => Buffer);
   end Open;

   overriding procedure Read (Stream : in out T;
                              Item   : out Stream_Element_Array;
                              Last   : out Stream_Element_Offset) is
   begin
      -- utiliser Gtk.Text_Buffer.Get_Text (Stream.Buffer, ...)
   end Read;

   overriding procedure Write (Stream : in out T;
                               Item   : in Stream_Element_Array) is
   begin
      -- utiliser Gtk.Text_Buffer.Insert (Stream.Buffer, ...)
   end Write;
end Buffer_Stream;

Et maintenant tout devient facile.  Tu crées un Stream_Access de l'une
des trois façons suivantes:

Stream_Access := Ada.Text_IO.Text_Streams.Stream (Ada.Text_IO.Current_Output); 

Stream := File_Stream.Open (File_Name => "toto.txt");
Stream_Access := Stream'Access;

Stream := Buffer_Stream.Open (Buffer => My_Text_Buffer);
Stream_Access := Stream'Access;

puis tu écris dedans très simplement avec:

String'Write (Stream_Access, Item => "coucou"); -- dynamic dispatch!
  
> Qqs questions : Conserver le champ File est-il utile (pas utilisé dans
> Write) ?

Il est absolument nécessaire que le File existe au moins aussi longtemps
qu'il existe un Stream vers lui (ARM A.12.1(36.1/1)).

> Donc le type record doit-il alors rester limited ?

Oui, s'il contient un File.  D'ailleurs, comme
Ada.Streams.Root_Stream_Type est lui-même limité, tous les types de ma
solution le sont aussi implicitement.

> Comment se fait la gestion des lignes Put_Line, New_Line,
> Get_Line... ?

Elle ne se fait pas : c'est précisément ce qui rend les Streams cent
fois plus rapides que Ada.Text_IO.  Tu lis et écris des ASCII.LF aux
bons endroits.  Note que les Streams ne sont pas limités au texte; tu
peux écrire absolument n'importe quoi dedans, d'ailleurs Gtk.Text_Buffer
accepte même les images.

-- 
Ludovic Brenta.
_______________________________________________
Site WWW de l'association Ada-France: http://www.ada-france.org/
[email protected]
http://www.ada-france.org/mailman/listinfo/ada-france
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.