OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [ada/] [s-direio.adb] - Blame information for rev 706

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 706 jeremybenn
------------------------------------------------------------------------------
2
--                                                                          --
3
--                         GNAT RUN-TIME COMPONENTS                         --
4
--                                                                          --
5
--                     S Y S T E M . D I R E C T _ I O                      --
6
--                                                                          --
7
--                                 B o d y                                  --
8
--                                                                          --
9
--          Copyright (C) 1992-2010, 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 3,  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.                                     --
17
--                                                                          --
18
-- As a special exception under Section 7 of GPL version 3, you are granted --
19
-- additional permissions described in the GCC Runtime Library Exception,   --
20
-- version 3.1, as published by the Free Software Foundation.               --
21
--                                                                          --
22
-- You should have received a copy of the GNU General Public License and    --
23
-- a copy of the GCC Runtime Library Exception along with this program;     --
24
-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
25
-- <http://www.gnu.org/licenses/>.                                          --
26
--                                                                          --
27
-- GNAT was originally developed  by the GNAT team at  New York University. --
28
-- Extensive contributions were provided by Ada Core Technologies Inc.      --
29
--                                                                          --
30
------------------------------------------------------------------------------
31
 
32
with Ada.IO_Exceptions;      use Ada.IO_Exceptions;
33
with Interfaces.C_Streams;   use Interfaces.C_Streams;
34
with System;                 use System;
35
with System.CRTL;
36
with System.File_IO;
37
with System.Soft_Links;
38
with Ada.Unchecked_Deallocation;
39
 
40
package body System.Direct_IO is
41
 
42
   package FIO renames System.File_IO;
43
   package SSL renames System.Soft_Links;
44
 
45
   subtype AP is FCB.AFCB_Ptr;
46
   use type FCB.Shared_Status_Type;
47
 
48
   use type System.CRTL.long;
49
   use type System.CRTL.size_t;
50
 
51
   -----------------------
52
   -- Local Subprograms --
53
   -----------------------
54
 
55
   procedure Set_Position (File : File_Type);
56
   --  Sets file position pointer according to value of current index
57
 
58
   -------------------
59
   -- AFCB_Allocate --
60
   -------------------
61
 
62
   function AFCB_Allocate (Control_Block : Direct_AFCB) return FCB.AFCB_Ptr is
63
      pragma Unreferenced (Control_Block);
64
   begin
65
      return new Direct_AFCB;
66
   end AFCB_Allocate;
67
 
68
   ----------------
69
   -- AFCB_Close --
70
   ----------------
71
 
72
   --  No special processing required for Direct_IO close
73
 
74
   procedure AFCB_Close (File : not null access Direct_AFCB) is
75
      pragma Unreferenced (File);
76
   begin
77
      null;
78
   end AFCB_Close;
79
 
80
   ---------------
81
   -- AFCB_Free --
82
   ---------------
83
 
84
   procedure AFCB_Free (File : not null access Direct_AFCB) is
85
 
86
      type FCB_Ptr is access all Direct_AFCB;
87
 
88
      FT : FCB_Ptr := FCB_Ptr (File);
89
 
90
      procedure Free is new
91
        Ada.Unchecked_Deallocation (Direct_AFCB, FCB_Ptr);
92
 
93
   begin
94
      Free (FT);
95
   end AFCB_Free;
96
 
97
   ------------
98
   -- Create --
99
   ------------
100
 
101
   procedure Create
102
     (File : in out File_Type;
103
      Mode : FCB.File_Mode := FCB.Inout_File;
104
      Name : String := "";
105
      Form : String := "")
106
   is
107
      Dummy_File_Control_Block : Direct_AFCB;
108
      pragma Warnings (Off, Dummy_File_Control_Block);
109
      --  Yes, we know this is never assigned a value, only the tag is used for
110
      --  dispatching purposes, so that's expected.
111
 
112
   begin
113
      FIO.Open (File_Ptr  => AP (File),
114
                Dummy_FCB => Dummy_File_Control_Block,
115
                Mode      => Mode,
116
                Name      => Name,
117
                Form      => Form,
118
                Amethod   => 'D',
119
                Creat     => True,
120
                Text      => False);
121
   end Create;
122
 
123
   -----------------
124
   -- End_Of_File --
125
   -----------------
126
 
127
   function End_Of_File (File : File_Type) return Boolean is
128
   begin
129
      FIO.Check_Read_Status (AP (File));
130
      return File.Index > Size (File);
131
   end End_Of_File;
132
 
133
   -----------
134
   -- Index --
135
   -----------
136
 
137
   function Index (File : File_Type) return Positive_Count is
138
   begin
139
      FIO.Check_File_Open (AP (File));
140
      return File.Index;
141
   end Index;
142
 
143
   ----------
144
   -- Open --
145
   ----------
146
 
147
   procedure Open
148
     (File : in out File_Type;
149
      Mode : FCB.File_Mode;
150
      Name : String;
151
      Form : String := "")
152
   is
153
      Dummy_File_Control_Block : Direct_AFCB;
154
      pragma Warnings (Off, Dummy_File_Control_Block);
155
      --  Yes, we know this is never assigned a value, only the tag is used for
156
      --  dispatching purposes, so that's expected.
157
 
158
   begin
159
      FIO.Open (File_Ptr  => AP (File),
160
                Dummy_FCB => Dummy_File_Control_Block,
161
                Mode      => Mode,
162
                Name      => Name,
163
                Form      => Form,
164
                Amethod   => 'D',
165
                Creat     => False,
166
                Text      => False);
167
   end Open;
168
 
169
   ----------
170
   -- Read --
171
   ----------
172
 
173
   procedure Read
174
     (File : File_Type;
175
      Item : Address;
176
      Size : Interfaces.C_Streams.size_t;
177
      From : Positive_Count)
178
   is
179
   begin
180
      Set_Index (File, From);
181
      Read (File, Item, Size);
182
   end Read;
183
 
184
   procedure Read
185
     (File : File_Type;
186
      Item : Address;
187
      Size : Interfaces.C_Streams.size_t)
188
   is
189
   begin
190
      FIO.Check_Read_Status (AP (File));
191
 
192
      --  If last operation was not a read, or if in file sharing mode,
193
      --  then reset the physical pointer of the file to match the index
194
      --  We lock out task access over the two operations in this case.
195
 
196
      if File.Last_Op /= Op_Read
197
        or else File.Shared_Status = FCB.Yes
198
      then
199
         if End_Of_File (File) then
200
            raise End_Error;
201
         end if;
202
 
203
         Locked_Processing : begin
204
            SSL.Lock_Task.all;
205
            Set_Position (File);
206
            FIO.Read_Buf (AP (File), Item, Size);
207
            SSL.Unlock_Task.all;
208
 
209
         exception
210
            when others =>
211
               SSL.Unlock_Task.all;
212
               raise;
213
         end Locked_Processing;
214
 
215
      else
216
         FIO.Read_Buf (AP (File), Item, Size);
217
      end if;
218
 
219
      File.Index := File.Index + 1;
220
 
221
      --  Set last operation to read, unless we did not read a full record
222
      --  (happens with the variant record case) in which case we set the
223
      --  last operation as other, to force the file position to be reset
224
      --  on the next read.
225
 
226
      File.Last_Op := (if File.Bytes = Size then Op_Read else Op_Other);
227
   end Read;
228
 
229
   --  The following is the required overriding for Stream.Read, which is
230
   --  not used, since we do not do Stream operations on Direct_IO files.
231
 
232
   procedure Read
233
     (File : in out Direct_AFCB;
234
      Item : out Ada.Streams.Stream_Element_Array;
235
      Last : out Ada.Streams.Stream_Element_Offset)
236
   is
237
   begin
238
      raise Program_Error;
239
   end Read;
240
 
241
   -----------
242
   -- Reset --
243
   -----------
244
 
245
   procedure Reset (File : in out File_Type; Mode : FCB.File_Mode) is
246
      pragma Warnings (Off, File);
247
      --  File is actually modified via Unrestricted_Access below, but
248
      --  GNAT will generate a warning anyway.
249
      --
250
      --  Note that we do not use pragma Unmodified here, since in -gnatc mode,
251
      --  GNAT will complain that File is modified for "File.Index := 1;"
252
   begin
253
      FIO.Reset (AP (File)'Unrestricted_Access, Mode);
254
      File.Index := 1;
255
      File.Last_Op := Op_Read;
256
   end Reset;
257
 
258
   procedure Reset (File : in out File_Type) is
259
      pragma Warnings (Off, File);
260
      --  See above (other Reset procedure) for explanations on this pragma
261
   begin
262
      FIO.Reset (AP (File)'Unrestricted_Access);
263
      File.Index := 1;
264
      File.Last_Op := Op_Read;
265
   end Reset;
266
 
267
   ---------------
268
   -- Set_Index --
269
   ---------------
270
 
271
   procedure Set_Index (File : File_Type; To : Positive_Count) is
272
   begin
273
      FIO.Check_File_Open (AP (File));
274
      File.Index := Count (To);
275
      File.Last_Op := Op_Other;
276
   end Set_Index;
277
 
278
   ------------------
279
   -- Set_Position --
280
   ------------------
281
 
282
   procedure Set_Position (File : File_Type) is
283
   begin
284
      if fseek
285
           (File.Stream, long (File.Bytes) *
286
              long (File.Index - 1), SEEK_SET) /= 0
287
      then
288
         raise Use_Error;
289
      end if;
290
   end Set_Position;
291
 
292
   ----------
293
   -- Size --
294
   ----------
295
 
296
   function Size (File : File_Type) return Count is
297
   begin
298
      FIO.Check_File_Open (AP (File));
299
      File.Last_Op := Op_Other;
300
 
301
      if fseek (File.Stream, 0, SEEK_END) /= 0 then
302
         raise Device_Error;
303
      end if;
304
 
305
      return Count (ftell (File.Stream) / long (File.Bytes));
306
   end Size;
307
 
308
   -----------
309
   -- Write --
310
   -----------
311
 
312
   procedure Write
313
     (File   : File_Type;
314
      Item   : Address;
315
      Size   : Interfaces.C_Streams.size_t;
316
      Zeroes : System.Storage_Elements.Storage_Array)
317
 
318
   is
319
      procedure Do_Write;
320
      --  Do the actual write
321
 
322
      --------------
323
      -- Do_Write --
324
      --------------
325
 
326
      procedure Do_Write is
327
      begin
328
         FIO.Write_Buf (AP (File), Item, Size);
329
 
330
         --  If we did not write the whole record (happens with the variant
331
         --  record case), then fill out the rest of the record with zeroes.
332
         --  This is cleaner in any case, and is required for the last
333
         --  record, since otherwise the length of the file is wrong.
334
 
335
         if File.Bytes > Size then
336
            FIO.Write_Buf (AP (File), Zeroes'Address, File.Bytes - Size);
337
         end if;
338
      end Do_Write;
339
 
340
   --  Start of processing for Write
341
 
342
   begin
343
      FIO.Check_Write_Status (AP (File));
344
 
345
      --  If last operation was not a write, or if in file sharing mode,
346
      --  then reset the physical pointer of the file to match the index
347
      --  We lock out task access over the two operations in this case.
348
 
349
      if File.Last_Op /= Op_Write
350
        or else File.Shared_Status = FCB.Yes
351
      then
352
         Locked_Processing : begin
353
            SSL.Lock_Task.all;
354
            Set_Position (File);
355
            Do_Write;
356
            SSL.Unlock_Task.all;
357
 
358
         exception
359
            when others =>
360
               SSL.Unlock_Task.all;
361
               raise;
362
         end Locked_Processing;
363
 
364
      else
365
         Do_Write;
366
      end if;
367
 
368
      File.Index := File.Index + 1;
369
 
370
      --  Set last operation to write, unless we did not read a full record
371
      --  (happens with the variant record case) in which case we set the
372
      --  last operation as other, to force the file position to be reset
373
      --  on the next write.
374
 
375
      File.Last_Op := (if File.Bytes = Size then Op_Write else Op_Other);
376
   end Write;
377
 
378
   --  The following is the required overriding for Stream.Write, which is
379
   --  not used, since we do not do Stream operations on Direct_IO files.
380
 
381
   procedure Write
382
     (File : in out Direct_AFCB;
383
      Item : Ada.Streams.Stream_Element_Array)
384
   is
385
   begin
386
      raise Program_Error;
387
   end Write;
388
 
389
end System.Direct_IO;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.