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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [ada/] [a-ststio.adb] - Blame information for rev 729

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 706 jeremybenn
------------------------------------------------------------------------------
2
--                                                                          --
3
--                         GNAT RUN-TIME 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
--                                                                          --
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 Interfaces.C_Streams; use Interfaces.C_Streams;
33
 
34
with System;               use System;
35
with System.Communication; use System.Communication;
36
with System.File_IO;
37
with System.Soft_Links;
38
with System.CRTL;
39
 
40
with Ada.Unchecked_Conversion;
41
with Ada.Unchecked_Deallocation;
42
 
43
package body Ada.Streams.Stream_IO is
44
 
45
   package FIO renames System.File_IO;
46
   package SSL renames System.Soft_Links;
47
 
48
   subtype AP is FCB.AFCB_Ptr;
49
 
50
   function To_FCB is new Ada.Unchecked_Conversion (File_Mode, FCB.File_Mode);
51
   function To_SIO is new Ada.Unchecked_Conversion (FCB.File_Mode, File_Mode);
52
   use type FCB.File_Mode;
53
   use type FCB.Shared_Status_Type;
54
 
55
   -----------------------
56
   -- Local Subprograms --
57
   -----------------------
58
 
59
   procedure Set_Position (File : File_Type);
60
   --  Sets file position pointer according to value of current index
61
 
62
   -------------------
63
   -- AFCB_Allocate --
64
   -------------------
65
 
66
   function AFCB_Allocate (Control_Block : Stream_AFCB) return FCB.AFCB_Ptr is
67
      pragma Warnings (Off, Control_Block);
68
   begin
69
      return new Stream_AFCB;
70
   end AFCB_Allocate;
71
 
72
   ----------------
73
   -- AFCB_Close --
74
   ----------------
75
 
76
   --  No special processing required for closing Stream_IO file
77
 
78
   procedure AFCB_Close (File : not null access Stream_AFCB) is
79
      pragma Warnings (Off, File);
80
   begin
81
      null;
82
   end AFCB_Close;
83
 
84
   ---------------
85
   -- AFCB_Free --
86
   ---------------
87
 
88
   procedure AFCB_Free (File : not null 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 Ada.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)'Unrestricted_Access);
105
   end Close;
106
 
107
   ------------
108
   -- Create --
109
   ------------
110
 
111
   procedure Create
112
     (File : in out File_Type;
113
      Mode : File_Mode := Out_File;
114
      Name : String := "";
115
      Form : String := "")
116
   is
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.
121
 
122
   begin
123
      FIO.Open (File_Ptr  => AP (File),
124
                Dummy_FCB => Dummy_File_Control_Block,
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)'Unrestricted_Access);
141
   end Delete;
142
 
143
   -----------------
144
   -- End_Of_File --
145
   -----------------
146
 
147
   function End_Of_File (File : File_Type) return Boolean is
148
   begin
149
      FIO.Check_Read_Status (AP (File));
150
      return File.Index > Size (File);
151
   end End_Of_File;
152
 
153
   -----------
154
   -- Flush --
155
   -----------
156
 
157
   procedure Flush (File : File_Type) is
158
   begin
159
      FIO.Flush (AP (File));
160
   end Flush;
161
 
162
   ----------
163
   -- Form --
164
   ----------
165
 
166
   function Form (File : 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 : File_Type) return Positive_Count is
176
   begin
177
      FIO.Check_File_Open (AP (File));
178
      return File.Index;
179
   end Index;
180
 
181
   -------------
182
   -- Is_Open --
183
   -------------
184
 
185
   function Is_Open (File : 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 : 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 : 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 : File_Mode;
215
      Name : String;
216
      Form : String := "")
217
   is
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.
222
 
223
   begin
224
      FIO.Open (File_Ptr  => AP (File),
225
                Dummy_FCB => Dummy_File_Control_Block,
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
 
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
      File.Last_Op := (if Mode = Out_File then Op_Write else Op_Read);
246
   end Open;
247
 
248
   ----------
249
   -- Read --
250
   ----------
251
 
252
   procedure Read
253
     (File : File_Type;
254
      Item : out Stream_Element_Array;
255
      Last : out Stream_Element_Offset;
256
      From : Positive_Count)
257
   is
258
   begin
259
      Set_Index (File, From);
260
      Read (File, Item, Last);
261
   end Read;
262
 
263
   procedure Read
264
     (File : File_Type;
265
      Item : out Stream_Element_Array;
266
      Last : out Stream_Element_Offset)
267
   is
268
      Nread : size_t;
269
 
270
   begin
271
      FIO.Check_Read_Status (AP (File));
272
 
273
      --  If last operation was not a read, or if in file sharing mode,
274
      --  then reset the physical pointer of the file to match the index
275
      --  We lock out task access over the two operations in this case.
276
 
277
      if File.Last_Op /= Op_Read
278
        or else File.Shared_Status = FCB.Yes
279
      then
280
         Locked_Processing : begin
281
            SSL.Lock_Task.all;
282
            Set_Position (File);
283
            FIO.Read_Buf (AP (File), Item'Address, Item'Length, Nread);
284
            SSL.Unlock_Task.all;
285
 
286
         exception
287
            when others =>
288
               SSL.Unlock_Task.all;
289
               raise;
290
         end Locked_Processing;
291
 
292
      else
293
         FIO.Read_Buf (AP (File), Item'Address, Item'Length, Nread);
294
      end if;
295
 
296
      File.Index := File.Index + Count (Nread);
297
      File.Last_Op := Op_Read;
298
      Last := Last_Index (Item'First, Nread);
299
   end Read;
300
 
301
   --  This version of Read is the primitive operation on the underlying
302
   --  Stream type, used when a Stream_IO file is treated as a Stream
303
 
304
   procedure Read
305
     (File : in out Stream_AFCB;
306
      Item : out Ada.Streams.Stream_Element_Array;
307
      Last : out Ada.Streams.Stream_Element_Offset)
308
   is
309
   begin
310
      Read (File'Unchecked_Access, Item, Last);
311
   end Read;
312
 
313
   -----------
314
   -- Reset --
315
   -----------
316
 
317
   procedure Reset (File : in out File_Type; Mode : File_Mode) is
318
   begin
319
      FIO.Check_File_Open (AP (File));
320
 
321
      --  Reset file index to start of file for read/write cases. For
322
      --  the append case, the Set_Mode call repositions the index.
323
 
324
      File.Index := 1;
325
      Set_Mode (File, Mode);
326
   end Reset;
327
 
328
   procedure Reset (File : in out File_Type) is
329
   begin
330
      Reset (File, To_SIO (File.Mode));
331
   end Reset;
332
 
333
   ---------------
334
   -- Set_Index --
335
   ---------------
336
 
337
   procedure Set_Index (File : File_Type; To : Positive_Count) is
338
   begin
339
      FIO.Check_File_Open (AP (File));
340
      File.Index := Count (To);
341
      File.Last_Op := Op_Other;
342
   end Set_Index;
343
 
344
   --------------
345
   -- Set_Mode --
346
   --------------
347
 
348
   procedure Set_Mode (File : in out File_Type; Mode : File_Mode) is
349
   begin
350
      FIO.Check_File_Open (AP (File));
351
 
352
      --  If we are switching from read to write, or vice versa, and
353
      --  we are not already open in update mode, then reopen in update
354
      --  mode now. Note that we can use Inout_File as the mode for the
355
      --  call since File_IO handles all modes for all file types.
356
 
357
      if ((File.Mode = FCB.In_File) /= (Mode = In_File))
358
        and then not File.Update_Mode
359
      then
360
         FIO.Reset (AP (File)'Unrestricted_Access, FCB.Inout_File);
361
         File.Update_Mode := True;
362
      end if;
363
 
364
      --  Set required mode and position to end of file if append mode
365
 
366
      File.Mode := To_FCB (Mode);
367
      FIO.Append_Set (AP (File));
368
 
369
      if File.Mode = FCB.Append_File then
370
         File.Index := Count (ftell (File.Stream)) + 1;
371
      end if;
372
 
373
      File.Last_Op := Op_Other;
374
   end Set_Mode;
375
 
376
   ------------------
377
   -- Set_Position --
378
   ------------------
379
 
380
   procedure Set_Position (File : File_Type) is
381
      use type System.CRTL.long;
382
   begin
383
      if fseek (File.Stream,
384
                System.CRTL.long (File.Index) - 1, SEEK_SET) /= 0
385
      then
386
         raise Use_Error;
387
      end if;
388
   end Set_Position;
389
 
390
   ----------
391
   -- Size --
392
   ----------
393
 
394
   function Size (File : File_Type) return Count is
395
   begin
396
      FIO.Check_File_Open (AP (File));
397
 
398
      if File.File_Size = -1 then
399
         File.Last_Op := Op_Other;
400
 
401
         if fseek (File.Stream, 0, SEEK_END) /= 0 then
402
            raise Device_Error;
403
         end if;
404
 
405
         File.File_Size := Stream_Element_Offset (ftell (File.Stream));
406
      end if;
407
 
408
      return Count (File.File_Size);
409
   end Size;
410
 
411
   ------------
412
   -- Stream --
413
   ------------
414
 
415
   function Stream (File : File_Type) return Stream_Access is
416
   begin
417
      FIO.Check_File_Open (AP (File));
418
      return Stream_Access (File);
419
   end Stream;
420
 
421
   -----------
422
   -- Write --
423
   -----------
424
 
425
   procedure Write
426
     (File : File_Type;
427
      Item : Stream_Element_Array;
428
      To   : Positive_Count)
429
   is
430
   begin
431
      Set_Index (File, To);
432
      Write (File, Item);
433
   end Write;
434
 
435
   procedure Write
436
     (File : File_Type;
437
      Item : Stream_Element_Array)
438
   is
439
   begin
440
      FIO.Check_Write_Status (AP (File));
441
 
442
      --  If last operation was not a write, or if in file sharing mode,
443
      --  then reset the physical pointer of the file to match the index
444
      --  We lock out task access over the two operations in this case.
445
 
446
      if File.Last_Op /= Op_Write
447
        or else File.Shared_Status = FCB.Yes
448
      then
449
         Locked_Processing : begin
450
            SSL.Lock_Task.all;
451
            Set_Position (File);
452
            FIO.Write_Buf (AP (File), Item'Address, Item'Length);
453
            SSL.Unlock_Task.all;
454
 
455
         exception
456
            when others =>
457
               SSL.Unlock_Task.all;
458
               raise;
459
         end Locked_Processing;
460
 
461
      else
462
         FIO.Write_Buf (AP (File), Item'Address, Item'Length);
463
      end if;
464
 
465
      File.Index := File.Index + Item'Length;
466
      File.Last_Op := Op_Write;
467
      File.File_Size := -1;
468
   end Write;
469
 
470
   --  This version of Write is the primitive operation on the underlying
471
   --  Stream type, used when a Stream_IO file is treated as a Stream
472
 
473
   procedure Write
474
     (File : in out Stream_AFCB;
475
      Item : Ada.Streams.Stream_Element_Array)
476
   is
477
   begin
478
      Write (File'Unchecked_Access, Item);
479
   end Write;
480
 
481
end Ada.Streams.Stream_IO;

powered by: WebSVN 2.1.0

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