2002-04-02 David S. Miller <davem@redhat.com>
[official-gcc.git] / gcc / ada / a-sequio.adb
blob1aed60168229b62e2b29bfdc78750f7f3fcb9e26
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT RUNTIME COMPONENTS --
4 -- --
5 -- A D A . S E Q U E N T I A L _ I O --
6 -- --
7 -- B o d y --
8 -- --
9 -- --
10 -- Copyright (C) 1992-1999, Free Software Foundation, Inc. --
11 -- --
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. --
22 -- --
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. --
29 -- --
30 -- GNAT was originally developed by the GNAT team at New York University. --
31 -- It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). --
32 -- --
33 ------------------------------------------------------------------------------
35 -- This is the generic template for Sequential_IO, i.e. the code that gets
36 -- duplicated. We absolutely minimize this code by either calling routines
37 -- in System.File_IO (for common file functions), or in System.Sequential_IO
38 -- (for specialized Sequential_IO functions)
40 with Interfaces.C_Streams; use Interfaces.C_Streams;
41 with System;
42 with System.File_Control_Block;
43 with System.File_IO;
44 with System.Storage_Elements;
45 with Unchecked_Conversion;
47 package body Ada.Sequential_IO is
49 package FIO renames System.File_IO;
50 package FCB renames System.File_Control_Block;
51 package SIO renames System.Sequential_IO;
52 package SSE renames System.Storage_Elements;
54 SU : constant := System.Storage_Unit;
56 subtype AP is FCB.AFCB_Ptr;
57 subtype FP is SIO.File_Type;
59 function To_FCB is new Unchecked_Conversion (File_Mode, FCB.File_Mode);
60 function To_SIO is new Unchecked_Conversion (FCB.File_Mode, File_Mode);
62 -----------
63 -- Close --
64 -----------
66 procedure Close (File : in out File_Type) is
67 begin
68 FIO.Close (AP (File));
69 end Close;
71 ------------
72 -- Create --
73 ------------
75 procedure Create
76 (File : in out File_Type;
77 Mode : in File_Mode := Out_File;
78 Name : in String := "";
79 Form : in String := "")
81 begin
82 SIO.Create (FP (File), To_FCB (Mode), Name, Form);
83 end Create;
85 ------------
86 -- Delete --
87 ------------
89 procedure Delete (File : in out File_Type) is
90 begin
91 FIO.Delete (AP (File));
92 end Delete;
94 -----------------
95 -- End_Of_File --
96 -----------------
98 function End_Of_File (File : in File_Type) return Boolean is
99 begin
100 return FIO.End_Of_File (AP (File));
101 end End_Of_File;
103 ----------
104 -- Form --
105 ----------
107 function Form (File : in File_Type) return String is
108 begin
109 return FIO.Form (AP (File));
110 end Form;
112 -------------
113 -- Is_Open --
114 -------------
116 function Is_Open (File : in File_Type) return Boolean is
117 begin
118 return FIO.Is_Open (AP (File));
119 end Is_Open;
121 ----------
122 -- Mode --
123 ----------
125 function Mode (File : in File_Type) return File_Mode is
126 begin
127 return To_SIO (FIO.Mode (AP (File)));
128 end Mode;
130 ----------
131 -- Name --
132 ----------
134 function Name (File : in File_Type) return String is
135 begin
136 return FIO.Name (AP (File));
137 end Name;
139 ----------
140 -- Open --
141 ----------
143 procedure Open
144 (File : in out File_Type;
145 Mode : in File_Mode;
146 Name : in String;
147 Form : in String := "")
149 begin
150 SIO.Open (FP (File), To_FCB (Mode), Name, Form);
151 end Open;
153 ----------
154 -- Read --
155 ----------
157 procedure Read (File : in File_Type; Item : out Element_Type) is
158 Siz : constant size_t := (Item'Size + SU - 1) / SU;
159 Rsiz : size_t;
161 begin
162 FIO.Check_Read_Status (AP (File));
164 -- For non-definite type or type with discriminants, read size and
165 -- raise Program_Error if it is larger than the size of the item.
167 if not Element_Type'Definite
168 or else Element_Type'Has_Discriminants
169 then
170 FIO.Read_Buf
171 (AP (File), Rsiz'Address, size_t'Size / System.Storage_Unit);
173 -- For a type with discriminants, we have to read into a temporary
174 -- buffer if Item is constrained, to check that the discriminants
175 -- are correct.
177 pragma Extensions_Allowed (On);
178 -- Needed to allow Constrained reference here
180 if Element_Type'Has_Discriminants
181 and then Item'Constrained
182 then
183 declare
184 RsizS : constant SSE.Storage_Offset :=
185 SSE.Storage_Offset (Rsiz - 1);
187 subtype SA is SSE.Storage_Array (0 .. RsizS);
188 type SAP is access all SA;
189 type ItemP is access all Element_Type;
191 pragma Warnings (Off);
192 -- We have to turn warnings off for this function, because
193 -- it gets analyzed for all types, including ones which
194 -- can't possibly come this way, and for which the size
195 -- of the access types differs.
197 function To_ItemP is new Unchecked_Conversion (SAP, ItemP);
199 pragma Warnings (On);
201 Buffer : aliased SA;
203 pragma Unsuppress (Discriminant_Check);
205 begin
206 FIO.Read_Buf (AP (File), Buffer'Address, Rsiz);
207 Item := To_ItemP (Buffer'Access).all;
208 return;
209 end;
210 end if;
212 -- In the case of a non-definite type, make sure the length is OK.
213 -- We can't do this in the variant record case, because the size is
214 -- based on the current discriminant, so may be apparently wrong.
216 if not Element_Type'Has_Discriminants and then Rsiz > Siz then
217 raise Program_Error;
218 end if;
220 FIO.Read_Buf (AP (File), Item'Address, Rsiz);
222 -- For definite type without discriminants, use actual size of item
224 else
225 FIO.Read_Buf (AP (File), Item'Address, Siz);
226 end if;
227 end Read;
229 -----------
230 -- Reset --
231 -----------
233 procedure Reset (File : in out File_Type; Mode : in File_Mode) is
234 begin
235 FIO.Reset (AP (File), To_FCB (Mode));
236 end Reset;
238 procedure Reset (File : in out File_Type) is
239 begin
240 FIO.Reset (AP (File));
241 end Reset;
243 -----------
244 -- Write --
245 -----------
247 procedure Write (File : in File_Type; Item : in Element_Type) is
248 Siz : constant size_t := (Item'Size + SU - 1) / SU;
250 begin
251 FIO.Check_Write_Status (AP (File));
253 -- For non-definite types or types with discriminants, write the size
255 if not Element_Type'Definite
256 or else Element_Type'Has_Discriminants
257 then
258 FIO.Write_Buf
259 (AP (File), Siz'Address, size_t'Size / System.Storage_Unit);
260 end if;
262 FIO.Write_Buf (AP (File), Item'Address, Siz);
263 end Write;
265 end Ada.Sequential_IO;