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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [gcc/] [ada/] [a-ststio.adb] - Blame information for rev 12

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 12 jlechner
------------------------------------------------------------------------------
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-2005, 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,  51  Franklin  Street,  Fifth  Floor, --
20
-- Boston, MA 02110-1301, 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
------------------------------------------------------------------------------
33
 
34
with Interfaces.C_Streams;      use Interfaces.C_Streams;
35
with System;                    use System;
36
with System.File_IO;
37
with System.Soft_Links;
38
with System.CRTL;
39
with Unchecked_Conversion;
40
with Unchecked_Deallocation;
41
 
42
package body Ada.Streams.Stream_IO is
43
 
44
   package FIO renames System.File_IO;
45
   package SSL renames System.Soft_Links;
46
 
47
   subtype AP is FCB.AFCB_Ptr;
48
 
49
   function To_FCB is new Unchecked_Conversion (File_Mode, FCB.File_Mode);
50
   function To_SIO is new Unchecked_Conversion (FCB.File_Mode, File_Mode);
51
   use type FCB.File_Mode;
52
   use type FCB.Shared_Status_Type;
53
 
54
   -----------------------
55
   -- Local Subprograms --
56
   -----------------------
57
 
58
   procedure Set_Position (File : in File_Type);
59
   --  Sets file position pointer according to value of current index
60
 
61
   -------------------
62
   -- AFCB_Allocate --
63
   -------------------
64
 
65
   function AFCB_Allocate (Control_Block : Stream_AFCB) return FCB.AFCB_Ptr is
66
      pragma Warnings (Off, Control_Block);
67
 
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 : access Stream_AFCB) is
79
      pragma Warnings (Off, File);
80
 
81
   begin
82
      null;
83
   end AFCB_Close;
84
 
85
   ---------------
86
   -- AFCB_Free --
87
   ---------------
88
 
89
   procedure AFCB_Free (File : access Stream_AFCB) is
90
      type FCB_Ptr is access all Stream_AFCB;
91
      FT : FCB_Ptr := FCB_Ptr (File);
92
 
93
      procedure Free is new Unchecked_Deallocation (Stream_AFCB, FCB_Ptr);
94
 
95
   begin
96
      Free (FT);
97
   end AFCB_Free;
98
 
99
   -----------
100
   -- Close --
101
   -----------
102
 
103
   procedure Close (File : in out File_Type) is
104
   begin
105
      FIO.Close (AP (File));
106
   end Close;
107
 
108
   ------------
109
   -- Create --
110
   ------------
111
 
112
   procedure Create
113
     (File : in out File_Type;
114
      Mode : in File_Mode := Out_File;
115
      Name : in String := "";
116
      Form : in String := "")
117
   is
118
      Dummy_File_Control_Block : Stream_AFCB;
119
      pragma Warnings (Off, Dummy_File_Control_Block);
120
      --  Yes, we know this is never assigned a value, only the tag
121
      --  is used for dispatching purposes, so that's expected.
122
 
123
   begin
124
      FIO.Open (File_Ptr  => AP (File),
125
                Dummy_FCB => Dummy_File_Control_Block,
126
                Mode      => To_FCB (Mode),
127
                Name      => Name,
128
                Form      => Form,
129
                Amethod   => 'S',
130
                Creat     => True,
131
                Text      => False);
132
      File.Last_Op := Op_Write;
133
   end Create;
134
 
135
   ------------
136
   -- Delete --
137
   ------------
138
 
139
   procedure Delete (File : in out File_Type) is
140
   begin
141
      FIO.Delete (AP (File));
142
   end Delete;
143
 
144
   -----------------
145
   -- End_Of_File --
146
   -----------------
147
 
148
   function End_Of_File (File : in File_Type) return Boolean is
149
   begin
150
      FIO.Check_Read_Status (AP (File));
151
      return Count (File.Index) > Size (File);
152
   end End_Of_File;
153
 
154
   -----------
155
   -- Flush --
156
   -----------
157
 
158
   procedure Flush (File : File_Type) is
159
   begin
160
      FIO.Flush (AP (File));
161
   end Flush;
162
 
163
   ----------
164
   -- Form --
165
   ----------
166
 
167
   function Form (File : in File_Type) return String is
168
   begin
169
      return FIO.Form (AP (File));
170
   end Form;
171
 
172
   -----------
173
   -- Index --
174
   -----------
175
 
176
   function Index (File : in File_Type) return Positive_Count is
177
   begin
178
      FIO.Check_File_Open (AP (File));
179
      return Count (File.Index);
180
   end Index;
181
 
182
   -------------
183
   -- Is_Open --
184
   -------------
185
 
186
   function Is_Open (File : in File_Type) return Boolean is
187
   begin
188
      return FIO.Is_Open (AP (File));
189
   end Is_Open;
190
 
191
   ----------
192
   -- Mode --
193
   ----------
194
 
195
   function Mode (File : in File_Type) return File_Mode is
196
   begin
197
      return To_SIO (FIO.Mode (AP (File)));
198
   end Mode;
199
 
200
   ----------
201
   -- Name --
202
   ----------
203
 
204
   function Name (File : in File_Type) return String is
205
   begin
206
      return FIO.Name (AP (File));
207
   end Name;
208
 
209
   ----------
210
   -- Open --
211
   ----------
212
 
213
   procedure Open
214
     (File : in out File_Type;
215
      Mode : in File_Mode;
216
      Name : in String;
217
      Form : in String := "")
218
   is
219
      Dummy_File_Control_Block : Stream_AFCB;
220
      pragma Warnings (Off, Dummy_File_Control_Block);
221
      --  Yes, we know this is never assigned a value, only the tag
222
      --  is used for dispatching purposes, so that's expected.
223
 
224
   begin
225
      FIO.Open (File_Ptr  => AP (File),
226
                Dummy_FCB => Dummy_File_Control_Block,
227
                Mode      => To_FCB (Mode),
228
                Name      => Name,
229
                Form      => Form,
230
                Amethod   => 'S',
231
                Creat     => False,
232
                Text      => False);
233
 
234
      --  Ensure that the stream index is set properly (e.g., for Append_File)
235
 
236
      Reset (File, Mode);
237
 
238
      --  Set last operation. The purpose here is to ensure proper handling
239
      --  of the initial operation. In general, a write after a read requires
240
      --  resetting and doing a seek, so we set the last operation as Read
241
      --  for an In_Out file, but for an Out file we set the last operation
242
      --  to Op_Write, since in this case it is not necessary to do a seek
243
      --  (and furthermore there are situations (such as the case of writing
244
      --  a sequential Posix FIFO file) where the lseek would cause problems.
245
 
246
      if Mode = Out_File then
247
         File.Last_Op := Op_Write;
248
      else
249
         File.Last_Op := Op_Read;
250
      end if;
251
   end Open;
252
 
253
   ----------
254
   -- Read --
255
   ----------
256
 
257
   procedure Read
258
     (File : in File_Type;
259
      Item : out Stream_Element_Array;
260
      Last : out Stream_Element_Offset;
261
      From : in Positive_Count)
262
   is
263
   begin
264
      Set_Index (File, From);
265
      Read (File, Item, Last);
266
   end Read;
267
 
268
   procedure Read
269
     (File : in File_Type;
270
      Item : out Stream_Element_Array;
271
      Last : out Stream_Element_Offset)
272
   is
273
      Nread : size_t;
274
 
275
   begin
276
      FIO.Check_Read_Status (AP (File));
277
 
278
      --  If last operation was not a read, or if in file sharing mode,
279
      --  then reset the physical pointer of the file to match the index
280
      --  We lock out task access over the two operations in this case.
281
 
282
      if File.Last_Op /= Op_Read
283
        or else File.Shared_Status = FCB.Yes
284
      then
285
         Locked_Processing : begin
286
            SSL.Lock_Task.all;
287
            Set_Position (File);
288
            FIO.Read_Buf (AP (File), Item'Address, Item'Length, Nread);
289
            SSL.Unlock_Task.all;
290
 
291
         exception
292
            when others =>
293
               SSL.Unlock_Task.all;
294
               raise;
295
         end Locked_Processing;
296
 
297
      else
298
         FIO.Read_Buf (AP (File), Item'Address, Item'Length, Nread);
299
      end if;
300
 
301
      File.Index := File.Index + Count (Nread);
302
      Last := Item'First + Stream_Element_Offset (Nread) - 1;
303
      File.Last_Op := Op_Read;
304
   end Read;
305
 
306
   --  This version of Read is the primitive operation on the underlying
307
   --  Stream type, used when a Stream_IO file is treated as a Stream
308
 
309
   procedure Read
310
     (File : in out Stream_AFCB;
311
      Item : out Ada.Streams.Stream_Element_Array;
312
      Last : out Ada.Streams.Stream_Element_Offset)
313
   is
314
   begin
315
      Read (File'Unchecked_Access, Item, Last);
316
   end Read;
317
 
318
   -----------
319
   -- Reset --
320
   -----------
321
 
322
   procedure Reset (File : in out File_Type; Mode : in File_Mode) is
323
   begin
324
      FIO.Check_File_Open (AP (File));
325
 
326
      --  Reset file index to start of file for read/write cases. For
327
      --  the append case, the Set_Mode call repositions the index.
328
 
329
      File.Index := 1;
330
      Set_Mode (File, Mode);
331
   end Reset;
332
 
333
   procedure Reset (File : in out File_Type) is
334
   begin
335
      Reset (File, To_SIO (File.Mode));
336
   end Reset;
337
 
338
   ---------------
339
   -- Set_Index --
340
   ---------------
341
 
342
   procedure Set_Index (File : in File_Type; To : in Positive_Count) is
343
   begin
344
      FIO.Check_File_Open (AP (File));
345
      File.Index := Count (To);
346
      File.Last_Op := Op_Other;
347
   end Set_Index;
348
 
349
   --------------
350
   -- Set_Mode --
351
   --------------
352
 
353
   procedure Set_Mode (File : in out File_Type; Mode : in File_Mode) is
354
   begin
355
      FIO.Check_File_Open (AP (File));
356
 
357
      --  If we are switching from read to write, or vice versa, and
358
      --  we are not already open in update mode, then reopen in update
359
      --  mode now. Note that we can use Inout_File as the mode for the
360
      --  call since File_IO handles all modes for all file types.
361
 
362
      if ((File.Mode = FCB.In_File) /= (Mode = In_File))
363
        and then not File.Update_Mode
364
      then
365
         FIO.Reset (AP (File), FCB.Inout_File);
366
         File.Update_Mode := True;
367
      end if;
368
 
369
      --  Set required mode and position to end of file if append mode
370
 
371
      File.Mode := To_FCB (Mode);
372
      FIO.Append_Set (AP (File));
373
 
374
      if File.Mode = FCB.Append_File then
375
         File.Index := Count (ftell (File.Stream)) + 1;
376
      end if;
377
 
378
      File.Last_Op := Op_Other;
379
   end Set_Mode;
380
 
381
   ------------------
382
   -- Set_Position --
383
   ------------------
384
 
385
   procedure Set_Position (File : in File_Type) is
386
      use type System.CRTL.long;
387
   begin
388
      if fseek (File.Stream,
389
                System.CRTL.long (File.Index) - 1, SEEK_SET) /= 0
390
      then
391
         raise Use_Error;
392
      end if;
393
   end Set_Position;
394
 
395
   ----------
396
   -- Size --
397
   ----------
398
 
399
   function Size (File : in File_Type) return Count is
400
   begin
401
      FIO.Check_File_Open (AP (File));
402
 
403
      if File.File_Size = -1 then
404
         File.Last_Op := Op_Other;
405
 
406
         if fseek (File.Stream, 0, SEEK_END) /= 0 then
407
            raise Device_Error;
408
         end if;
409
 
410
         File.File_Size := Stream_Element_Offset (ftell (File.Stream));
411
      end if;
412
 
413
      return Count (File.File_Size);
414
   end Size;
415
 
416
   ------------
417
   -- Stream --
418
   ------------
419
 
420
   function Stream (File : in File_Type) return Stream_Access is
421
   begin
422
      FIO.Check_File_Open (AP (File));
423
      return Stream_Access (File);
424
   end Stream;
425
 
426
   -----------
427
   -- Write --
428
   -----------
429
 
430
   procedure Write
431
     (File : in File_Type;
432
      Item : in Stream_Element_Array;
433
      To   : in Positive_Count)
434
   is
435
   begin
436
      Set_Index (File, To);
437
      Write (File, Item);
438
   end Write;
439
 
440
   procedure Write (File : in File_Type; Item : in Stream_Element_Array) is
441
   begin
442
      FIO.Check_Write_Status (AP (File));
443
 
444
      --  If last operation was not a write, or if in file sharing mode,
445
      --  then reset the physical pointer of the file to match the index
446
      --  We lock out task access over the two operations in this case.
447
 
448
      if File.Last_Op /= Op_Write
449
        or else File.Shared_Status = FCB.Yes
450
      then
451
         Locked_Processing : begin
452
            SSL.Lock_Task.all;
453
            Set_Position (File);
454
            FIO.Write_Buf (AP (File), Item'Address, Item'Length);
455
            SSL.Unlock_Task.all;
456
 
457
         exception
458
            when others =>
459
               SSL.Unlock_Task.all;
460
               raise;
461
         end Locked_Processing;
462
 
463
      else
464
         FIO.Write_Buf (AP (File), Item'Address, Item'Length);
465
      end if;
466
 
467
      File.Index := File.Index + Item'Length;
468
      File.Last_Op := Op_Write;
469
      File.File_Size := -1;
470
   end Write;
471
 
472
   --  This version of Write is the primitive operation on the underlying
473
   --  Stream type, used when a Stream_IO file is treated as a Stream
474
 
475
   procedure Write
476
     (File : in out Stream_AFCB;
477
      Item : in Ada.Streams.Stream_Element_Array)
478
   is
479
   begin
480
      Write (File'Unchecked_Access, Item);
481
   end Write;
482
 
483
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.