1 ------------------------------------------------------------------------------
3 -- GNAT RUNTIME COMPONENTS --
5 -- A D A . S T R E A M S . S T R E A M _ I O --
10 -- Copyright (C) 1992-2001, Free Software Foundation, Inc. --
12 -- GNAT is free software; you can redistribute it and/or modify it under --
13 -- terms of the GNU General Public License as published by the Free Soft- --
14 -- ware Foundation; either version 2, or (at your option) any later ver- --
15 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
16 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
17 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
18 -- for more details. You should have received a copy of the GNU General --
19 -- Public License distributed with GNAT; see file COPYING. If not, write --
20 -- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
21 -- MA 02111-1307, USA. --
23 -- As a special exception, if other files instantiate generics from this --
24 -- unit, or you link this unit with other files to produce an executable, --
25 -- this unit does not by itself cause the resulting executable to be --
26 -- covered by the GNU General Public License. This exception does not --
27 -- however invalidate any other reasons why the executable file might be --
28 -- covered by the GNU Public License. --
30 -- GNAT was originally developed by the GNAT team at New York University. --
31 -- Extensive contributions were provided by Ada Core Technologies Inc. --
33 ------------------------------------------------------------------------------
35 with Interfaces
.C_Streams
; use Interfaces
.C_Streams
;
36 with System
; use System
;
38 with System
.Soft_Links
;
39 with Unchecked_Conversion
;
40 with Unchecked_Deallocation
;
42 package body Ada
.Streams
.Stream_IO
is
44 package FIO
renames System
.File_IO
;
45 package SSL
renames System
.Soft_Links
;
47 subtype AP
is FCB
.AFCB_Ptr
;
49 function To_FCB
is new Unchecked_Conversion
(File_Mode
, FCB
.File_Mode
);
50 function To_SIO
is new Unchecked_Conversion
(FCB
.File_Mode
, File_Mode
);
51 use type FCB
.File_Mode
;
52 use type FCB
.Shared_Status_Type
;
54 -----------------------
55 -- Local Subprograms --
56 -----------------------
58 procedure Set_Position
(File
: in File_Type
);
59 -- Sets file position pointer according to value of current index
65 function AFCB_Allocate
(Control_Block
: Stream_AFCB
) return FCB
.AFCB_Ptr
is
66 pragma Warnings
(Off
, Control_Block
);
69 return new Stream_AFCB
;
76 -- No special processing required for closing Stream_IO file
78 procedure AFCB_Close
(File
: access Stream_AFCB
) is
79 pragma Warnings
(Off
, File
);
89 procedure AFCB_Free
(File
: access Stream_AFCB
) is
90 type FCB_Ptr
is access all Stream_AFCB
;
91 FT
: FCB_Ptr
:= FCB_Ptr
(File
);
93 procedure Free
is new Unchecked_Deallocation
(Stream_AFCB
, FCB_Ptr
);
103 procedure Close
(File
: in out File_Type
) is
105 FIO
.Close
(AP
(File
));
113 (File
: in out File_Type
;
114 Mode
: in File_Mode
:= Out_File
;
115 Name
: in String := "";
116 Form
: in String := "")
118 File_Control_Block
: Stream_AFCB
;
121 FIO
.Open
(File_Ptr
=> AP
(File
),
122 Dummy_FCB
=> File_Control_Block
,
123 Mode
=> To_FCB
(Mode
),
129 File
.Last_Op
:= Op_Write
;
136 procedure Delete
(File
: in out File_Type
) is
138 FIO
.Delete
(AP
(File
));
145 function End_Of_File
(File
: in File_Type
) return Boolean is
147 FIO
.Check_Read_Status
(AP
(File
));
148 return Count
(File
.Index
) > Size
(File
);
155 procedure Flush
(File
: File_Type
) is
157 FIO
.Flush
(AP
(File
));
164 function Form
(File
: in File_Type
) return String is
166 return FIO
.Form
(AP
(File
));
173 function Index
(File
: in File_Type
) return Positive_Count
is
175 FIO
.Check_File_Open
(AP
(File
));
176 return Count
(File
.Index
);
183 function Is_Open
(File
: in File_Type
) return Boolean is
185 return FIO
.Is_Open
(AP
(File
));
192 function Mode
(File
: in File_Type
) return File_Mode
is
194 return To_SIO
(FIO
.Mode
(AP
(File
)));
201 function Name
(File
: in File_Type
) return String is
203 return FIO
.Name
(AP
(File
));
211 (File
: in out File_Type
;
214 Form
: in String := "")
216 File_Control_Block
: Stream_AFCB
;
219 FIO
.Open
(File_Ptr
=> AP
(File
),
220 Dummy_FCB
=> File_Control_Block
,
221 Mode
=> To_FCB
(Mode
),
228 -- Ensure that the stream index is set properly (e.g., for Append_File)
232 File
.Last_Op
:= Op_Read
;
240 (File
: in File_Type
;
241 Item
: out Stream_Element_Array
;
242 Last
: out Stream_Element_Offset
;
243 From
: in Positive_Count
)
246 Set_Index
(File
, From
);
247 Read
(File
, Item
, Last
);
251 (File
: in File_Type
;
252 Item
: out Stream_Element_Array
;
253 Last
: out Stream_Element_Offset
)
258 FIO
.Check_Read_Status
(AP
(File
));
260 -- If last operation was not a read, or if in file sharing mode,
261 -- then reset the physical pointer of the file to match the index
262 -- We lock out task access over the two operations in this case.
264 if File
.Last_Op
/= Op_Read
265 or else File
.Shared_Status
= FCB
.Yes
267 Locked_Processing
: begin
270 FIO
.Read_Buf
(AP
(File
), Item
'Address, Item
'Length, Nread
);
277 end Locked_Processing
;
280 FIO
.Read_Buf
(AP
(File
), Item
'Address, Item
'Length, Nread
);
283 File
.Index
:= File
.Index
+ Count
(Nread
);
284 Last
:= Item
'First + Stream_Element_Offset
(Nread
) - 1;
285 File
.Last_Op
:= Op_Read
;
288 -- This version of Read is the primitive operation on the underlying
289 -- Stream type, used when a Stream_IO file is treated as a Stream
292 (File
: in out Stream_AFCB
;
293 Item
: out Ada
.Streams
.Stream_Element_Array
;
294 Last
: out Ada
.Streams
.Stream_Element_Offset
)
297 Read
(File
'Unchecked_Access, Item
, Last
);
304 procedure Reset
(File
: in out File_Type
; Mode
: in File_Mode
) is
306 FIO
.Check_File_Open
(AP
(File
));
308 -- Reset file index to start of file for read/write cases. For
309 -- the append case, the Set_Mode call repositions the index.
312 Set_Mode
(File
, Mode
);
315 procedure Reset
(File
: in out File_Type
) is
317 Reset
(File
, To_SIO
(File
.Mode
));
324 procedure Set_Index
(File
: in File_Type
; To
: in Positive_Count
) is
326 FIO
.Check_File_Open
(AP
(File
));
327 File
.Index
:= Count
(To
);
328 File
.Last_Op
:= Op_Other
;
335 procedure Set_Mode
(File
: in out File_Type
; Mode
: in File_Mode
) is
337 FIO
.Check_File_Open
(AP
(File
));
339 -- If we are switching from read to write, or vice versa, and
340 -- we are not already open in update mode, then reopen in update
341 -- mode now. Note that we can use Inout_File as the mode for the
342 -- call since File_IO handles all modes for all file types.
344 if ((File
.Mode
= FCB
.In_File
) /= (Mode
= In_File
))
345 and then not File
.Update_Mode
347 FIO
.Reset
(AP
(File
), FCB
.Inout_File
);
348 File
.Update_Mode
:= True;
351 -- Set required mode and position to end of file if append mode
353 File
.Mode
:= To_FCB
(Mode
);
354 FIO
.Append_Set
(AP
(File
));
356 if File
.Mode
= FCB
.Append_File
then
357 File
.Index
:= Count
(ftell
(File
.Stream
)) + 1;
360 File
.Last_Op
:= Op_Other
;
367 procedure Set_Position
(File
: in File_Type
) is
369 if fseek
(File
.Stream
, long
(File
.Index
) - 1, SEEK_SET
) /= 0 then
378 function Size
(File
: in File_Type
) return Count
is
380 FIO
.Check_File_Open
(AP
(File
));
382 if File
.File_Size
= -1 then
383 File
.Last_Op
:= Op_Other
;
385 if fseek
(File
.Stream
, 0, SEEK_END
) /= 0 then
389 File
.File_Size
:= Stream_Element_Offset
(ftell
(File
.Stream
));
392 return Count
(File
.File_Size
);
399 function Stream
(File
: in File_Type
) return Stream_Access
is
401 FIO
.Check_File_Open
(AP
(File
));
402 return Stream_Access
(File
);
410 (File
: in File_Type
;
411 Item
: in Stream_Element_Array
;
412 To
: in Positive_Count
)
415 Set_Index
(File
, To
);
419 procedure Write
(File
: in File_Type
; Item
: in Stream_Element_Array
) is
421 FIO
.Check_Write_Status
(AP
(File
));
423 -- If last operation was not a write, or if in file sharing mode,
424 -- then reset the physical pointer of the file to match the index
425 -- We lock out task access over the two operations in this case.
427 if File
.Last_Op
/= Op_Write
428 or else File
.Shared_Status
= FCB
.Yes
430 Locked_Processing
: begin
433 FIO
.Write_Buf
(AP
(File
), Item
'Address, Item
'Length);
440 end Locked_Processing
;
443 FIO
.Write_Buf
(AP
(File
), Item
'Address, Item
'Length);
446 File
.Index
:= File
.Index
+ Item
'Length;
447 File
.Last_Op
:= Op_Write
;
448 File
.File_Size
:= -1;
451 -- This version of Write is the primitive operation on the underlying
452 -- Stream type, used when a Stream_IO file is treated as a Stream
455 (File
: in out Stream_AFCB
;
456 Item
: in Ada
.Streams
.Stream_Element_Array
)
459 Write
(File
'Unchecked_Access, Item
);
462 end Ada
.Streams
.Stream_IO
;