----------------------------------------------------------------------------- -- -- Onions Network Streams Library -- -- O N I O N S . O U T S T R E A M S . F I L E -- -- S p e c -- -- Copyright (C) 1997-1998 Regents of the University of California -- -- Onions is free software; you can redistribute it and/or modify it under -- the terms of the GNU General Public License as published by the Free -- Software Foundation, with or without the single exception listed below; -- either version 2, or (at your option) any later version. Onions is -- distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -- without even the implied warranty of MERCHANTABILITY or FITNESS FOR A -- PARTICULAR PURPOSE. See the GNU General Public License for more details. -- You should have received a copy of the GNU General Public License -- distributed with Onions; see the file COPYING. If not, write to the -- Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -- 02111-1307, USA. -- -- As a special exception, if other files instantiate generics from this -- library, or you link this library with other files to produce an -- executable, this library does not by itself cause the resulting -- executable to be covered by the GNU General Public License. This -- exception does not however invalidate any other reasons why the -- executable file might be covered by the GNU General Public License. -- -- Created in 1997 by Roy T. Fielding ----------------------------------------------------------------------------- -- -- The File Output Stream is a stream end that performs buffered writes -- on a filesystem descriptor. -- -- I'd be interested to see a performance comparison of this package -- versus Ada.Text_IO input files. -- with Ada.Streams; with Interfaces.C.Strings; with System.Storage_Elements; use System.Storage_Elements; with Onions.Constants; use Onions.Constants; with Onions.Thin; package Onions.Outstreams.File is type File_Output_Stream is new Output_Stream with private; type File_Output_Stream_Ptr is access all File_Output_Stream; -- Output_Mode is used with Open to control how the file is opened. -- Stdout => Associate the stream with the already open STDOUT -- Stderr => Associate the stream with the already open STDERR -- Append => Append to the file, creating it if necessary. -- Create => Create the file if it does not already exist -- Existing => Require that the file already exists -- Exclusive => Require that the file does not already exist -- type Output_Mode is (Stdout, Stderr, Append, Create, Existing, Exclusive); --------------------------------------------- -- Dispatching Stream Control Operations -- --------------------------------------------- -- Free the storage associated with a stream object. -- procedure Free (SP : in out File_Output_Stream_Ptr); -- Bind an already open descriptor to the stream. -- function Bind (Stream : in File_Output_Stream_Ptr; Filedes : in Thin.Descriptor) return Output_Pipe; -- Open the descriptor associated with a stream. If Name is "", the -- stream is associated with the already open STDOUT descriptor, -- otherwise the named file is opened for writing. Raises Device_Error -- if it is unable to open a descriptor for the named file. -- function Open (Stream : in File_Output_Stream_Ptr; Mode : in Output_Mode := Stdout; Perms : in Thin.mode_t := 0; Name : in String := "") return Output_Pipe; -- Close the descriptor associated with a stream. Note that this -- is different from a Close of an Output_Pipe in that it does not -- free the stream. I.e., the stream can be Open'd again. -- procedure Close (Stream : in out File_Output_Stream); -- Abort_Stream should only be used if a stream is interrupted -- by the user, or an error occurs that makes the whole stream bad. -- It forces the stream closed without a flush. -- procedure Abort_Stream (Stream : in out File_Output_Stream); -- Reset is like Close, but resets the stream to the state -- it would be in if it was just created. It flushes -- anything in its own buffers. -- procedure Reset (Stream : in out File_Output_Stream); -- The Flush method tells the stream to send any outbound buffered data -- downstream, but without taking down the stream. The stream decides -- whether or not it has buffered data to write. -- procedure Flush (Stream : in out File_Output_Stream); -- Get a file stream's write buffer size for max blocks. -- function Get_Max_Buffer_Blocksize (Stream : in File_Output_Stream) return Natural; -- Set a file stream's write buffer size for max blocks. -- A Num_Blocks of 0 will set it to unbuffered. -- procedure Set_Max_Buffer_Blocksize (Stream : in out File_Output_Stream; Num_Blocks : in Natural); -- Name returns a string containing the currently open file name. -- function Name (Stream : in File_Output_Stream) return String; ------------------------------------- -- Ada.Streams Dispatching Write -- ------------------------------------- -- Write places each of the elements of Item into Stream in order. This -- interface is defined by Ada.Streams for abstract stream operations. -- We won't use it much because it forces a full data copy when filtering. -- procedure Write (Stream : in out File_Output_Stream; Item : in Ada.Streams.Stream_Element_Array); ---------------------------------- -- Data Processing Operations -- ---------------------------------- -- Process does the magic necessary to move the data from then -- Unprocessed write queue to the File. If Everything, then process -- the entire Unprocessed buffer as if it were the end-of-stream. -- Raises Timeout_Exceeded if we have to wait longer than Stream.Timeout; -- Device_Error if anything else goes fatally wrong. -- procedure Process (Stream : in out File_Output_Stream; Everything : Boolean); private type File_Output_Stream is new Output_Stream with record -- Name of the open file -- Filename : C.Strings.chars_ptr := C.Strings.Null_Ptr; -- Fd is the file descriptor when associated with an open file -- Fd : Onions.Thin.Descriptor := Onions.Thin.Failure; -- Buffering thresholds -- if passed, write the data. -- Threshold_Bytes should be optimized to the kernel write buffer. -- Threshold_Buckets should depend on how many bucket allocations -- can be made before the memory needs to be freed. -- Setting either to zero will result in unbuffered output. -- Threshold_Bytes : Storage_Count := 8192; Threshold_Buckets : Natural := Natural'Min (IOV_MAX - 4, 20); end record; end Onions.Outstreams.File;