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