diff options
Diffstat (limited to 'gcc/ada/s-mmap.adb')
-rw-r--r-- | gcc/ada/s-mmap.adb | 576 |
1 files changed, 0 insertions, 576 deletions
diff --git a/gcc/ada/s-mmap.adb b/gcc/ada/s-mmap.adb deleted file mode 100644 index aee0ebeaad0..00000000000 --- a/gcc/ada/s-mmap.adb +++ /dev/null @@ -1,576 +0,0 @@ ------------------------------------------------------------------------------- --- -- --- GNAT RUN-TIME COMPONENTS -- --- -- --- S Y S T E M . M M A P -- --- -- --- B o d y -- --- -- --- Copyright (C) 2007-2016, AdaCore -- --- -- --- This library is free software; you can redistribute it and/or modify it -- --- under terms of the GNU General Public License as published by the Free -- --- Software Foundation; either version 3, or (at your option) any later -- --- version. This library is distributed in the hope that it will be useful, -- --- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- --- TABILITY or FITNESS FOR A PARTICULAR PURPOSE. -- --- -- --- As a special exception under Section 7 of GPL version 3, you are granted -- --- additional permissions described in the GCC Runtime Library Exception, -- --- version 3.1, as published by the Free Software Foundation. -- --- -- --- You should have received a copy of the GNU General Public License and -- --- a copy of the GCC Runtime Library Exception along with this program; -- --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- --- <http://www.gnu.org/licenses/>. -- --- -- --- GNAT was originally developed by the GNAT team at New York University. -- --- Extensive contributions were provided by Ada Core Technologies Inc. -- --- -- ------------------------------------------------------------------------------- - -with Ada.IO_Exceptions; -with Ada.Unchecked_Conversion; -with Ada.Unchecked_Deallocation; - -with System.Strings; use System.Strings; - -with System.Mmap.OS_Interface; use System.Mmap.OS_Interface; - -package body System.Mmap is - - type Mapped_File_Record is record - Current_Region : Mapped_Region; - -- The legacy API enables only one region to be mapped, directly - -- associated with the mapped file. This references this region. - - File : System_File; - -- Underlying OS-level file - end record; - - type Mapped_Region_Record is record - File : Mapped_File; - -- The file this region comes from. Be careful: for reading file, it is - -- valid to have it closed before one of its regions is free'd. - - Write : Boolean; - -- Whether the file this region comes from is open for writing. - - Data : Str_Access; - -- Unbounded access to the mapped content. - - System_Offset : File_Size; - -- Position in the file of the first byte actually mapped in memory - - User_Offset : File_Size; - -- Position in the file of the first byte requested by the user - - System_Size : File_Size; - -- Size of the region actually mapped in memory - - User_Size : File_Size; - -- Size of the region requested by the user - - Mapped : Boolean; - -- Whether this region is actually memory mapped - - Mutable : Boolean; - -- If the file is opened for reading, wheter this region is writable - - Buffer : System.Strings.String_Access; - -- When this region is not actually memory mapped, contains the - -- requested bytes. - - Mapping : System_Mapping; - -- Underlying OS-level data for the mapping, if any - end record; - - Invalid_Mapped_Region_Record : constant Mapped_Region_Record := - (null, False, null, 0, 0, 0, 0, False, False, null, - Invalid_System_Mapping); - Invalid_Mapped_File_Record : constant Mapped_File_Record := - (Invalid_Mapped_Region, Invalid_System_File); - - Empty_String : constant String := ""; - -- Used to provide a valid empty Data for empty files, for instanc. - - procedure Dispose is new Ada.Unchecked_Deallocation - (Mapped_File_Record, Mapped_File); - procedure Dispose is new Ada.Unchecked_Deallocation - (Mapped_Region_Record, Mapped_Region); - - function Convert is new Ada.Unchecked_Conversion - (Standard.System.Address, Str_Access); - - procedure Compute_Data (Region : Mapped_Region); - -- Fill the Data field according to system and user offsets. The region - -- must actually be mapped or bufferized. - - procedure From_Disk (Region : Mapped_Region); - -- Read a region of some file from the disk - - procedure To_Disk (Region : Mapped_Region); - -- Write the region of the file back to disk if necessary, and free memory - - ---------------------------- - -- Open_Read_No_Exception -- - ---------------------------- - - function Open_Read_No_Exception - (Filename : String; - Use_Mmap_If_Available : Boolean := True) return Mapped_File - is - File : constant System_File := - Open_Read (Filename, Use_Mmap_If_Available); - begin - if File = Invalid_System_File then - return Invalid_Mapped_File; - end if; - - return new Mapped_File_Record' - (Current_Region => Invalid_Mapped_Region, - File => File); - end Open_Read_No_Exception; - - --------------- - -- Open_Read -- - --------------- - - function Open_Read - (Filename : String; - Use_Mmap_If_Available : Boolean := True) return Mapped_File - is - Res : constant Mapped_File := - Open_Read_No_Exception (Filename, Use_Mmap_If_Available); - begin - if Res = Invalid_Mapped_File then - raise Ada.IO_Exceptions.Name_Error - with "Cannot open " & Filename; - else - return Res; - end if; - end Open_Read; - - ---------------- - -- Open_Write -- - ---------------- - - function Open_Write - (Filename : String; - Use_Mmap_If_Available : Boolean := True) return Mapped_File - is - File : constant System_File := - Open_Write (Filename, Use_Mmap_If_Available); - begin - if File = Invalid_System_File then - raise Ada.IO_Exceptions.Name_Error - with "Cannot open " & Filename; - else - return new Mapped_File_Record' - (Current_Region => Invalid_Mapped_Region, - File => File); - end if; - end Open_Write; - - ----------- - -- Close -- - ----------- - - procedure Close (File : in out Mapped_File) is - begin - -- Closing a closed file is allowed and should do nothing - - if File = Invalid_Mapped_File then - return; - end if; - - if File.Current_Region /= null then - Free (File.Current_Region); - end if; - - if File.File /= Invalid_System_File then - Close (File.File); - end if; - - Dispose (File); - end Close; - - ---------- - -- Free -- - ---------- - - procedure Free (Region : in out Mapped_Region) is - Ignored : Integer; - pragma Unreferenced (Ignored); - begin - -- Freeing an already free'd file is allowed and should do nothing - - if Region = Invalid_Mapped_Region then - return; - end if; - - if Region.Mapping /= Invalid_System_Mapping then - Dispose_Mapping (Region.Mapping); - end if; - To_Disk (Region); - Dispose (Region); - end Free; - - ---------- - -- Read -- - ---------- - - procedure Read - (File : Mapped_File; - Region : in out Mapped_Region; - Offset : File_Size := 0; - Length : File_Size := 0; - Mutable : Boolean := False) - is - File_Length : constant File_Size := Mmap.Length (File); - - Req_Offset : constant File_Size := Offset; - Req_Length : File_Size := Length; - -- Offset and Length of the region to map, used to adjust mapping - -- bounds, reflecting what the user will see. - - Region_Allocated : Boolean := False; - begin - -- If this region comes from another file, or simply if the file is - -- writeable, we cannot re-use this mapping: free it first. - - if Region /= Invalid_Mapped_Region - and then - (Region.File /= File or else File.File.Write) - then - Free (Region); - end if; - - if Region = Invalid_Mapped_Region then - Region := new Mapped_Region_Record'(Invalid_Mapped_Region_Record); - Region_Allocated := True; - end if; - - Region.File := File; - - if Req_Offset >= File_Length then - -- If the requested offset goes beyond file size, map nothing - - Req_Length := 0; - - elsif Length = 0 - or else - Length > File_Length - Req_Offset - then - -- If Length is 0 or goes beyond file size, map till end of file - - Req_Length := File_Length - Req_Offset; - - else - Req_Length := Length; - end if; - - -- Past this point, the offset/length the user will see is fixed. On the - -- other hand, the system offset/length is either already defined, from - -- a previous mapping, or it is set to 0. In the latter case, the next - -- step will set them according to the mapping. - - Region.User_Offset := Req_Offset; - Region.User_Size := Req_Length; - - -- If the requested region is inside an already mapped region, adjust - -- user-requested data and do nothing else. - - if (File.File.Write or else Region.Mutable = Mutable) - and then - Req_Offset >= Region.System_Offset - and then - (Req_Offset + Req_Length - <= Region.System_Offset + Region.System_Size) - then - Region.User_Offset := Req_Offset; - Compute_Data (Region); - return; - - elsif Region.Buffer /= null then - -- Otherwise, as we are not going to re-use the buffer, free it - - System.Strings.Free (Region.Buffer); - Region.Buffer := null; - - elsif Region.Mapping /= Invalid_System_Mapping then - -- Otherwise, there is a memory mapping that we need to unmap. - Dispose_Mapping (Region.Mapping); - end if; - - -- mmap() will sometimes return NULL when the file exists but is empty, - -- which is not what we want, so in the case of a zero length file we - -- fall back to read(2)/write(2)-based mode. - - if File_Length > 0 and then File.File.Mapped then - - Region.System_Offset := Req_Offset; - Region.System_Size := Req_Length; - Create_Mapping - (File.File, - Region.System_Offset, Region.System_Size, - Mutable, - Region.Mapping); - Region.Mapped := True; - Region.Mutable := Mutable; - - else - -- There is no alignment requirement when manually reading the file. - - Region.System_Offset := Req_Offset; - Region.System_Size := Req_Length; - Region.Mapped := False; - Region.Mutable := True; - From_Disk (Region); - end if; - - Region.Write := File.File.Write; - Compute_Data (Region); - - exception - when others => - -- Before propagating any exception, free any region we allocated - -- here. - - if Region_Allocated then - Dispose (Region); - end if; - raise; - end Read; - - ---------- - -- Read -- - ---------- - - procedure Read - (File : Mapped_File; - Offset : File_Size := 0; - Length : File_Size := 0; - Mutable : Boolean := False) - is - begin - Read (File, File.Current_Region, Offset, Length, Mutable); - end Read; - - ---------- - -- Read -- - ---------- - - function Read - (File : Mapped_File; - Offset : File_Size := 0; - Length : File_Size := 0; - Mutable : Boolean := False) return Mapped_Region - is - Region : Mapped_Region := Invalid_Mapped_Region; - begin - Read (File, Region, Offset, Length, Mutable); - return Region; - end Read; - - ------------ - -- Length -- - ------------ - - function Length (File : Mapped_File) return File_Size is - begin - return File.File.Length; - end Length; - - ------------ - -- Offset -- - ------------ - - function Offset (Region : Mapped_Region) return File_Size is - begin - return Region.User_Offset; - end Offset; - - ------------ - -- Offset -- - ------------ - - function Offset (File : Mapped_File) return File_Size is - begin - return Offset (File.Current_Region); - end Offset; - - ---------- - -- Last -- - ---------- - - function Last (Region : Mapped_Region) return Integer is - begin - return Integer (Region.User_Size); - end Last; - - ---------- - -- Last -- - ---------- - - function Last (File : Mapped_File) return Integer is - begin - return Last (File.Current_Region); - end Last; - - ------------------- - -- To_Str_Access -- - ------------------- - - function To_Str_Access - (Str : System.Strings.String_Access) return Str_Access is - begin - if Str = null then - return null; - else - return Convert (Str.all'Address); - end if; - end To_Str_Access; - - ---------- - -- Data -- - ---------- - - function Data (Region : Mapped_Region) return Str_Access is - begin - return Region.Data; - end Data; - - ---------- - -- Data -- - ---------- - - function Data (File : Mapped_File) return Str_Access is - begin - return Data (File.Current_Region); - end Data; - - ---------------- - -- Is_Mutable -- - ---------------- - - function Is_Mutable (Region : Mapped_Region) return Boolean is - begin - return Region.Mutable or Region.Write; - end Is_Mutable; - - ---------------- - -- Is_Mmapped -- - ---------------- - - function Is_Mmapped (File : Mapped_File) return Boolean is - begin - return File.File.Mapped; - end Is_Mmapped; - - ------------------- - -- Get_Page_Size -- - ------------------- - - function Get_Page_Size return Integer is - Result : constant File_Size := Get_Page_Size; - begin - return Integer (Result); - end Get_Page_Size; - - --------------------- - -- Read_Whole_File -- - --------------------- - - function Read_Whole_File - (Filename : String; - Empty_If_Not_Found : Boolean := False) - return System.Strings.String_Access - is - File : Mapped_File := Open_Read (Filename); - Region : Mapped_Region renames File.Current_Region; - Result : String_Access; - begin - Read (File); - - if Region.Data /= null then - Result := new String'(String - (Region.Data (1 .. Last (Region)))); - - elsif Region.Buffer /= null then - Result := Region.Buffer; - Region.Buffer := null; -- So that it is not deallocated - end if; - - Close (File); - - return Result; - - exception - when Ada.IO_Exceptions.Name_Error => - if Empty_If_Not_Found then - return new String'(""); - else - return null; - end if; - - when others => - Close (File); - return null; - end Read_Whole_File; - - --------------- - -- From_Disk -- - --------------- - - procedure From_Disk (Region : Mapped_Region) is - begin - pragma Assert (Region.File.all /= Invalid_Mapped_File_Record); - pragma Assert (Region.Buffer = null); - - Region.Buffer := Read_From_Disk - (Region.File.File, Region.User_Offset, Region.User_Size); - Region.Mapped := False; - end From_Disk; - - ------------- - -- To_Disk -- - ------------- - - procedure To_Disk (Region : Mapped_Region) is - begin - if Region.Write and then Region.Buffer /= null then - pragma Assert (Region.File.all /= Invalid_Mapped_File_Record); - Write_To_Disk - (Region.File.File, - Region.User_Offset, Region.User_Size, - Region.Buffer); - end if; - - System.Strings.Free (Region.Buffer); - Region.Buffer := null; - end To_Disk; - - ------------------ - -- Compute_Data -- - ------------------ - - procedure Compute_Data (Region : Mapped_Region) is - Base_Data : Str_Access; - -- Address of the first byte actually mapped in memory - - Data_Shift : constant Integer := - Integer (Region.User_Offset - Region.System_Offset); - begin - if Region.User_Size = 0 then - Region.Data := Convert (Empty_String'Address); - return; - elsif Region.Mapped then - Base_Data := Convert (Region.Mapping.Address); - else - Base_Data := Convert (Region.Buffer.all'Address); - end if; - Region.Data := Convert (Base_Data (Data_Shift + 1)'Address); - end Compute_Data; - -end System.Mmap; |