]> gcc.gnu.org Git - gcc.git/blame - gcc/ada/a-ststio.adb
3psoccon.ads, [...]: Files added.
[gcc.git] / gcc / ada / a-ststio.adb
CommitLineData
d23b8f57
RK
1------------------------------------------------------------------------------
2-- --
3-- GNAT RUNTIME COMPONENTS --
4-- --
5-- A D A . S T R E A M S . S T R E A M _ I O --
6-- --
7-- B o d y --
8-- --
fbf5a39b 9-- Copyright (C) 1992-2003, Free Software Foundation, Inc. --
d23b8f57
RK
10-- --
11-- GNAT is free software; you can redistribute it and/or modify it under --
12-- terms of the GNU General Public License as published by the Free Soft- --
13-- ware Foundation; either version 2, or (at your option) any later ver- --
14-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
17-- for more details. You should have received a copy of the GNU General --
18-- Public License distributed with GNAT; see file COPYING. If not, write --
19-- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
20-- MA 02111-1307, USA. --
21-- --
22-- As a special exception, if other files instantiate generics from this --
23-- unit, or you link this unit with other files to produce an executable, --
24-- this unit does not by itself cause the resulting executable to be --
25-- covered by the GNU General Public License. This exception does not --
26-- however invalidate any other reasons why the executable file might be --
27-- covered by the GNU Public License. --
28-- --
29-- GNAT was originally developed by the GNAT team at New York University. --
71ff80dc 30-- Extensive contributions were provided by Ada Core Technologies Inc. --
d23b8f57
RK
31-- --
32------------------------------------------------------------------------------
33
34with Interfaces.C_Streams; use Interfaces.C_Streams;
35with System; use System;
36with System.File_IO;
37with System.Soft_Links;
38with Unchecked_Conversion;
39with Unchecked_Deallocation;
40
41package body Ada.Streams.Stream_IO is
42
43 package FIO renames System.File_IO;
44 package SSL renames System.Soft_Links;
45
46 subtype AP is FCB.AFCB_Ptr;
47
48 function To_FCB is new Unchecked_Conversion (File_Mode, FCB.File_Mode);
49 function To_SIO is new Unchecked_Conversion (FCB.File_Mode, File_Mode);
50 use type FCB.File_Mode;
51 use type FCB.Shared_Status_Type;
52
53 -----------------------
54 -- Local Subprograms --
55 -----------------------
56
57 procedure Set_Position (File : in File_Type);
58 -- Sets file position pointer according to value of current index
59
60 -------------------
61 -- AFCB_Allocate --
62 -------------------
63
64 function AFCB_Allocate (Control_Block : Stream_AFCB) return FCB.AFCB_Ptr is
07fc65c4
GB
65 pragma Warnings (Off, Control_Block);
66
d23b8f57
RK
67 begin
68 return new Stream_AFCB;
69 end AFCB_Allocate;
70
71 ----------------
72 -- AFCB_Close --
73 ----------------
74
75 -- No special processing required for closing Stream_IO file
76
77 procedure AFCB_Close (File : access Stream_AFCB) is
07fc65c4
GB
78 pragma Warnings (Off, File);
79
d23b8f57
RK
80 begin
81 null;
82 end AFCB_Close;
83
84 ---------------
85 -- AFCB_Free --
86 ---------------
87
88 procedure AFCB_Free (File : access Stream_AFCB) is
89 type FCB_Ptr is access all Stream_AFCB;
90 FT : FCB_Ptr := FCB_Ptr (File);
91
92 procedure Free is new Unchecked_Deallocation (Stream_AFCB, FCB_Ptr);
93
94 begin
95 Free (FT);
96 end AFCB_Free;
97
98 -----------
99 -- Close --
100 -----------
101
102 procedure Close (File : in out File_Type) is
103 begin
104 FIO.Close (AP (File));
105 end Close;
106
107 ------------
108 -- Create --
109 ------------
110
111 procedure Create
112 (File : in out File_Type;
113 Mode : in File_Mode := Out_File;
114 Name : in String := "";
115 Form : in String := "")
116 is
fbf5a39b
AC
117 Dummy_File_Control_Block : Stream_AFCB;
118 pragma Warnings (Off, Dummy_File_Control_Block);
119 -- Yes, we know this is never assigned a value, only the tag
120 -- is used for dispatching purposes, so that's expected.
d23b8f57
RK
121
122 begin
123 FIO.Open (File_Ptr => AP (File),
fbf5a39b 124 Dummy_FCB => Dummy_File_Control_Block,
d23b8f57
RK
125 Mode => To_FCB (Mode),
126 Name => Name,
127 Form => Form,
128 Amethod => 'S',
129 Creat => True,
130 Text => False);
131 File.Last_Op := Op_Write;
132 end Create;
133
134 ------------
135 -- Delete --
136 ------------
137
138 procedure Delete (File : in out File_Type) is
139 begin
140 FIO.Delete (AP (File));
141 end Delete;
142
143 -----------------
144 -- End_Of_File --
145 -----------------
146
147 function End_Of_File (File : in File_Type) return Boolean is
148 begin
149 FIO.Check_Read_Status (AP (File));
150 return Count (File.Index) > Size (File);
151 end End_Of_File;
152
153 -----------
154 -- Flush --
155 -----------
156
07fc65c4 157 procedure Flush (File : File_Type) is
d23b8f57
RK
158 begin
159 FIO.Flush (AP (File));
160 end Flush;
161
162 ----------
163 -- Form --
164 ----------
165
166 function Form (File : in File_Type) return String is
167 begin
168 return FIO.Form (AP (File));
169 end Form;
170
171 -----------
172 -- Index --
173 -----------
174
175 function Index (File : in File_Type) return Positive_Count is
176 begin
177 FIO.Check_File_Open (AP (File));
178 return Count (File.Index);
179 end Index;
180
181 -------------
182 -- Is_Open --
183 -------------
184
185 function Is_Open (File : in File_Type) return Boolean is
186 begin
187 return FIO.Is_Open (AP (File));
188 end Is_Open;
189
190 ----------
191 -- Mode --
192 ----------
193
194 function Mode (File : in File_Type) return File_Mode is
195 begin
196 return To_SIO (FIO.Mode (AP (File)));
197 end Mode;
198
199 ----------
200 -- Name --
201 ----------
202
203 function Name (File : in File_Type) return String is
204 begin
205 return FIO.Name (AP (File));
206 end Name;
207
208 ----------
209 -- Open --
210 ----------
211
212 procedure Open
213 (File : in out File_Type;
214 Mode : in File_Mode;
215 Name : in String;
216 Form : in String := "")
217 is
fbf5a39b
AC
218 Dummy_File_Control_Block : Stream_AFCB;
219 pragma Warnings (Off, Dummy_File_Control_Block);
220 -- Yes, we know this is never assigned a value, only the tag
221 -- is used for dispatching purposes, so that's expected.
d23b8f57
RK
222
223 begin
224 FIO.Open (File_Ptr => AP (File),
fbf5a39b 225 Dummy_FCB => Dummy_File_Control_Block,
d23b8f57
RK
226 Mode => To_FCB (Mode),
227 Name => Name,
228 Form => Form,
229 Amethod => 'S',
230 Creat => False,
231 Text => False);
232
233 -- Ensure that the stream index is set properly (e.g., for Append_File)
234
235 Reset (File, Mode);
236
fbf5a39b
AC
237 -- Set last operation. The purpose here is to ensure proper handling
238 -- of the initial operation. In general, a write after a read requires
239 -- resetting and doing a seek, so we set the last operation as Read
240 -- for an In_Out file, but for an Out file we set the last operation
241 -- to Op_Write, since in this case it is not necessary to do a seek
242 -- (and furthermore there are situations (such as the case of writing
243 -- a sequential Posix FIFO file) where the lseek would cause problems.
244
245 if Mode = Out_File then
246 File.Last_Op := Op_Write;
247 else
248 File.Last_Op := Op_Read;
249 end if;
d23b8f57
RK
250 end Open;
251
252 ----------
253 -- Read --
254 ----------
255
256 procedure Read
257 (File : in File_Type;
258 Item : out Stream_Element_Array;
259 Last : out Stream_Element_Offset;
260 From : in Positive_Count)
261 is
262 begin
263 Set_Index (File, From);
264 Read (File, Item, Last);
265 end Read;
266
267 procedure Read
268 (File : in File_Type;
269 Item : out Stream_Element_Array;
270 Last : out Stream_Element_Offset)
271 is
272 Nread : size_t;
273
274 begin
275 FIO.Check_Read_Status (AP (File));
276
277 -- If last operation was not a read, or if in file sharing mode,
278 -- then reset the physical pointer of the file to match the index
279 -- We lock out task access over the two operations in this case.
280
281 if File.Last_Op /= Op_Read
282 or else File.Shared_Status = FCB.Yes
283 then
d23b8f57
RK
284 Locked_Processing : begin
285 SSL.Lock_Task.all;
286 Set_Position (File);
287 FIO.Read_Buf (AP (File), Item'Address, Item'Length, Nread);
288 SSL.Unlock_Task.all;
289
290 exception
291 when others =>
292 SSL.Unlock_Task.all;
293 raise;
294 end Locked_Processing;
295
296 else
297 FIO.Read_Buf (AP (File), Item'Address, Item'Length, Nread);
298 end if;
299
300 File.Index := File.Index + Count (Nread);
301 Last := Item'First + Stream_Element_Offset (Nread) - 1;
302 File.Last_Op := Op_Read;
303 end Read;
304
305 -- This version of Read is the primitive operation on the underlying
306 -- Stream type, used when a Stream_IO file is treated as a Stream
307
308 procedure Read
309 (File : in out Stream_AFCB;
310 Item : out Ada.Streams.Stream_Element_Array;
311 Last : out Ada.Streams.Stream_Element_Offset)
312 is
313 begin
314 Read (File'Unchecked_Access, Item, Last);
315 end Read;
316
317 -----------
318 -- Reset --
319 -----------
320
321 procedure Reset (File : in out File_Type; Mode : in File_Mode) is
322 begin
323 FIO.Check_File_Open (AP (File));
324
325 -- Reset file index to start of file for read/write cases. For
326 -- the append case, the Set_Mode call repositions the index.
327
328 File.Index := 1;
329 Set_Mode (File, Mode);
330 end Reset;
331
332 procedure Reset (File : in out File_Type) is
333 begin
334 Reset (File, To_SIO (File.Mode));
335 end Reset;
336
337 ---------------
338 -- Set_Index --
339 ---------------
340
341 procedure Set_Index (File : in File_Type; To : in Positive_Count) is
342 begin
343 FIO.Check_File_Open (AP (File));
344 File.Index := Count (To);
345 File.Last_Op := Op_Other;
346 end Set_Index;
347
348 --------------
349 -- Set_Mode --
350 --------------
351
352 procedure Set_Mode (File : in out File_Type; Mode : in File_Mode) is
353 begin
354 FIO.Check_File_Open (AP (File));
355
356 -- If we are switching from read to write, or vice versa, and
357 -- we are not already open in update mode, then reopen in update
358 -- mode now. Note that we can use Inout_File as the mode for the
359 -- call since File_IO handles all modes for all file types.
360
361 if ((File.Mode = FCB.In_File) /= (Mode = In_File))
362 and then not File.Update_Mode
363 then
364 FIO.Reset (AP (File), FCB.Inout_File);
365 File.Update_Mode := True;
366 end if;
367
368 -- Set required mode and position to end of file if append mode
369
370 File.Mode := To_FCB (Mode);
371 FIO.Append_Set (AP (File));
372
373 if File.Mode = FCB.Append_File then
374 File.Index := Count (ftell (File.Stream)) + 1;
375 end if;
376
377 File.Last_Op := Op_Other;
378 end Set_Mode;
379
380 ------------------
381 -- Set_Position --
382 ------------------
383
384 procedure Set_Position (File : in File_Type) is
385 begin
386 if fseek (File.Stream, long (File.Index) - 1, SEEK_SET) /= 0 then
387 raise Use_Error;
388 end if;
389 end Set_Position;
390
391 ----------
392 -- Size --
393 ----------
394
395 function Size (File : in File_Type) return Count is
396 begin
397 FIO.Check_File_Open (AP (File));
398
399 if File.File_Size = -1 then
400 File.Last_Op := Op_Other;
401
402 if fseek (File.Stream, 0, SEEK_END) /= 0 then
403 raise Device_Error;
404 end if;
405
406 File.File_Size := Stream_Element_Offset (ftell (File.Stream));
407 end if;
408
409 return Count (File.File_Size);
410 end Size;
411
412 ------------
413 -- Stream --
414 ------------
415
416 function Stream (File : in File_Type) return Stream_Access is
417 begin
418 FIO.Check_File_Open (AP (File));
419 return Stream_Access (File);
420 end Stream;
421
422 -----------
423 -- Write --
424 -----------
425
426 procedure Write
427 (File : in File_Type;
428 Item : in Stream_Element_Array;
429 To : in Positive_Count)
430 is
431 begin
432 Set_Index (File, To);
433 Write (File, Item);
434 end Write;
435
436 procedure Write (File : in File_Type; Item : in Stream_Element_Array) is
437 begin
438 FIO.Check_Write_Status (AP (File));
439
440 -- If last operation was not a write, or if in file sharing mode,
441 -- then reset the physical pointer of the file to match the index
442 -- We lock out task access over the two operations in this case.
443
444 if File.Last_Op /= Op_Write
445 or else File.Shared_Status = FCB.Yes
446 then
447 Locked_Processing : begin
448 SSL.Lock_Task.all;
449 Set_Position (File);
450 FIO.Write_Buf (AP (File), Item'Address, Item'Length);
451 SSL.Unlock_Task.all;
452
453 exception
454 when others =>
455 SSL.Unlock_Task.all;
456 raise;
457 end Locked_Processing;
458
459 else
460 FIO.Write_Buf (AP (File), Item'Address, Item'Length);
461 end if;
462
463 File.Index := File.Index + Item'Length;
464 File.Last_Op := Op_Write;
465 File.File_Size := -1;
466 end Write;
467
468 -- This version of Write is the primitive operation on the underlying
469 -- Stream type, used when a Stream_IO file is treated as a Stream
470
471 procedure Write
472 (File : in out Stream_AFCB;
473 Item : in Ada.Streams.Stream_Element_Array)
474 is
475 begin
476 Write (File'Unchecked_Access, Item);
477 end Write;
478
479end Ada.Streams.Stream_IO;
This page took 0.434782 seconds and 5 git commands to generate.