2003-05-31 Bud Davis <bdavis9659@comcast.net>
[official-gcc.git] / gcc / ada / a-sequio.adb
blobeedcbaad685dbac54df3b4c72c5c068337b2887e
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 -- Copyright (C) 1992-1999, Free Software Foundation, Inc. --
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. --
30 -- Extensive contributions were provided by Ada Core Technologies Inc. --
31 -- --
32 ------------------------------------------------------------------------------
34 -- This is the generic template for Sequential_IO, i.e. the code that gets
35 -- duplicated. We absolutely minimize this code by either calling routines
36 -- in System.File_IO (for common file functions), or in System.Sequential_IO
37 -- (for specialized Sequential_IO functions)
39 with Interfaces.C_Streams; use Interfaces.C_Streams;
40 with System;
41 with System.File_Control_Block;
42 with System.File_IO;
43 with System.Storage_Elements;
44 with Unchecked_Conversion;
46 package body Ada.Sequential_IO is
48 package FIO renames System.File_IO;
49 package FCB renames System.File_Control_Block;
50 package SIO renames System.Sequential_IO;
51 package SSE renames System.Storage_Elements;
53 SU : constant := System.Storage_Unit;
55 subtype AP is FCB.AFCB_Ptr;
56 subtype FP is SIO.File_Type;
58 function To_FCB is new Unchecked_Conversion (File_Mode, FCB.File_Mode);
59 function To_SIO is new Unchecked_Conversion (FCB.File_Mode, File_Mode);
61 -----------
62 -- Close --
63 -----------
65 procedure Close (File : in out File_Type) is
66 begin
67 FIO.Close (AP (File));
68 end Close;
70 ------------
71 -- Create --
72 ------------
74 procedure Create
75 (File : in out File_Type;
76 Mode : in File_Mode := Out_File;
77 Name : in String := "";
78 Form : in String := "")
80 begin
81 SIO.Create (FP (File), To_FCB (Mode), Name, Form);
82 end Create;
84 ------------
85 -- Delete --
86 ------------
88 procedure Delete (File : in out File_Type) is
89 begin
90 FIO.Delete (AP (File));
91 end Delete;
93 -----------------
94 -- End_Of_File --
95 -----------------
97 function End_Of_File (File : in File_Type) return Boolean is
98 begin
99 return FIO.End_Of_File (AP (File));
100 end End_Of_File;
102 ----------
103 -- Form --
104 ----------
106 function Form (File : in File_Type) return String is
107 begin
108 return FIO.Form (AP (File));
109 end Form;
111 -------------
112 -- Is_Open --
113 -------------
115 function Is_Open (File : in File_Type) return Boolean is
116 begin
117 return FIO.Is_Open (AP (File));
118 end Is_Open;
120 ----------
121 -- Mode --
122 ----------
124 function Mode (File : in File_Type) return File_Mode is
125 begin
126 return To_SIO (FIO.Mode (AP (File)));
127 end Mode;
129 ----------
130 -- Name --
131 ----------
133 function Name (File : in File_Type) return String is
134 begin
135 return FIO.Name (AP (File));
136 end Name;
138 ----------
139 -- Open --
140 ----------
142 procedure Open
143 (File : in out File_Type;
144 Mode : in File_Mode;
145 Name : in String;
146 Form : in String := "")
148 begin
149 SIO.Open (FP (File), To_FCB (Mode), Name, Form);
150 end Open;
152 ----------
153 -- Read --
154 ----------
156 procedure Read (File : in File_Type; Item : out Element_Type) is
157 Siz : constant size_t := (Item'Size + SU - 1) / SU;
158 Rsiz : size_t;
160 begin
161 FIO.Check_Read_Status (AP (File));
163 -- For non-definite type or type with discriminants, read size and
164 -- raise Program_Error if it is larger than the size of the item.
166 if not Element_Type'Definite
167 or else Element_Type'Has_Discriminants
168 then
169 FIO.Read_Buf
170 (AP (File), Rsiz'Address, size_t'Size / System.Storage_Unit);
172 -- For a type with discriminants, we have to read into a temporary
173 -- buffer if Item is constrained, to check that the discriminants
174 -- are correct.
176 pragma Extensions_Allowed (On);
177 -- Needed to allow Constrained reference here
179 if Element_Type'Has_Discriminants
180 and then Item'Constrained
181 then
182 declare
183 RsizS : constant SSE.Storage_Offset :=
184 SSE.Storage_Offset (Rsiz - 1);
186 subtype SA is SSE.Storage_Array (0 .. RsizS);
187 type SAP is access all SA;
188 type ItemP is access all Element_Type;
190 pragma Warnings (Off);
191 -- We have to turn warnings off for this function, because
192 -- it gets analyzed for all types, including ones which
193 -- can't possibly come this way, and for which the size
194 -- of the access types differs.
196 function To_ItemP is new Unchecked_Conversion (SAP, ItemP);
198 pragma Warnings (On);
200 Buffer : aliased SA;
202 pragma Unsuppress (Discriminant_Check);
204 begin
205 FIO.Read_Buf (AP (File), Buffer'Address, Rsiz);
206 Item := To_ItemP (Buffer'Access).all;
207 return;
208 end;
209 end if;
211 -- In the case of a non-definite type, make sure the length is OK.
212 -- We can't do this in the variant record case, because the size is
213 -- based on the current discriminant, so may be apparently wrong.
215 if not Element_Type'Has_Discriminants and then Rsiz > Siz then
216 raise Program_Error;
217 end if;
219 FIO.Read_Buf (AP (File), Item'Address, Rsiz);
221 -- For definite type without discriminants, use actual size of item
223 else
224 FIO.Read_Buf (AP (File), Item'Address, Siz);
225 end if;
226 end Read;
228 -----------
229 -- Reset --
230 -----------
232 procedure Reset (File : in out File_Type; Mode : in File_Mode) is
233 begin
234 FIO.Reset (AP (File), To_FCB (Mode));
235 end Reset;
237 procedure Reset (File : in out File_Type) is
238 begin
239 FIO.Reset (AP (File));
240 end Reset;
242 -----------
243 -- Write --
244 -----------
246 procedure Write (File : in File_Type; Item : in Element_Type) is
247 Siz : constant size_t := (Item'Size + SU - 1) / SU;
249 begin
250 FIO.Check_Write_Status (AP (File));
252 -- For non-definite types or types with discriminants, write the size
254 if not Element_Type'Definite
255 or else Element_Type'Has_Discriminants
256 then
257 FIO.Write_Buf
258 (AP (File), Siz'Address, size_t'Size / System.Storage_Unit);
259 end if;
261 FIO.Write_Buf (AP (File), Item'Address, Siz);
262 end Write;
264 end Ada.Sequential_IO;