blob: 20d29898f2caf1d40def380dcf9c5cda455057d9 [file] [log] [blame]
Nico Hubercc960f22024-01-29 01:13:45 +01001package FILO.FS.ISO9660 is
2
3 type T is private;
4
5 function Is_Mounted (State : T) return Boolean;
6 function Is_Open (State : T) return Boolean
7 with
8 Post => (if Is_Open'Result then Is_Mounted (State));
9
10 procedure Mount
11 (State : in out T;
12 Part_Len : in Partition_Length;
13 Success : out Boolean)
14 with
15 Pre => not Is_Mounted (State),
16 Post => Success = Is_Mounted (State);
17
18 procedure Open
19 (State : in out T;
20 File_Len : out File_Length;
21 File_Type : out FS.File_Type;
22 File_Name : in String;
23 In_Root : in Boolean;
24 Success : out Boolean)
25 with
Nico Huber8e4b9f82024-02-12 01:13:51 +010026 Pre => Is_Mounted (State) and File_Name'Length <= Natural'Last - 3,
Nico Hubercc960f22024-01-29 01:13:45 +010027 Post => (if Success then Is_Open (State) else Is_Mounted (State));
28
29 procedure Close (State : in out T)
30 with
31 Pre => Is_Open (State),
32 Post => Is_Mounted (State);
33
Nico Huber4210fcc2024-01-29 16:33:47 +010034 pragma Warnings
35 (GNATprove, Off, """State"" is not modified*",
36 Reason => "It's `in out' to fulfill common interface.");
Nico Hubercc960f22024-01-29 01:13:45 +010037 procedure Read
38 (State : in out T;
39 File_Pos : in out File_Offset;
40 Buf : out Buffer_Type;
41 Len : out Natural)
42 with
Nico Huber4210fcc2024-01-29 16:33:47 +010043 Relaxed_Initialization => Buf,
Nico Hubercc960f22024-01-29 01:13:45 +010044 Pre => Is_Open (State) and Buf'Length > 0,
Nico Huber4210fcc2024-01-29 16:33:47 +010045 Post => Is_Open (State) and Buf'Initialized;
46 pragma Warnings (GNATprove, On, """State"" is not modified*");
Nico Hubercc960f22024-01-29 01:13:45 +010047
48private
49 type State is (Unmounted, Mounted, File_Opened);
50
51 FSBlock_Size : constant := 2048;
Nico Huber666da672024-02-08 15:30:20 +010052 subtype FSBlock_Length is Index_Type range 0 .. FSBlock_Size;
Nico Hubercc960f22024-01-29 01:13:45 +010053 subtype FSBlock_Index is Index_Type range 0 .. FSBlock_Size - 1;
54
55 type FSBlock_Count is range 0 .. 2 ** 32 - 1;
56 subtype FSBlock is FSBlock_Count range 0 .. FSBlock_Count'Last - 1;
57 type FSBlock_Logical is new FSBlock;
58
Nico Huber666da672024-02-08 15:30:20 +010059 type FS_Record is record
60 Block : FSBlock := 0;
61 Offset : FSBlock_Length := 0;
62 Size : FSBlock_Length := 0;
63 end record
64 with
65 Dynamic_Predicate =>
66 Size <= FSBlock_Size - Offset;
67
Nico Hubercc960f22024-01-29 01:13:45 +010068 subtype Directory_Record_Range is Index_Type range 0 .. 32;
69 subtype Directory_Record is Buffer_Type (Directory_Record_Range);
Nico Huber4210fcc2024-01-29 16:33:47 +010070 subtype Directory_Record_Offset is FSBlock_Index
71 range 0 .. FSBlock_Size - Directory_Record'Length;
Nico Hubercc960f22024-01-29 01:13:45 +010072
73 -- We'll use the absolute position of the dir record
Nico Huber666da672024-02-08 15:30:20 +010074 subtype Inode_Index is FS_Record
75 with
Nico Huber8e4b9f82024-02-12 01:13:51 +010076 Dynamic_Predicate =>
77 Inode_Index.Size >= Directory_Record'Length;
Nico Hubercc960f22024-01-29 01:13:45 +010078 type Inode_Length is range 0 .. FSBlock_Count'Last * FSBlock_Size;
79
80 type Mount_State is record
81 Part_Len : Partition_Length := 0;
Nico Huber8e4b9f82024-02-12 01:13:51 +010082 Root_Inode : Inode_Index := (Size => Directory_Record'Length, others => <>);
Nico Hubercc960f22024-01-29 01:13:45 +010083 end record;
84
85 type Extent is record
86 Start : FSBlock := 0;
87 Count : FSBlock_Count := 0;
Nico Huber8e4b9f82024-02-12 01:13:51 +010088 end record
89 with
90 Dynamic_Predicate =>
91 Start <= FSBlock_Count'Last - Count;
Nico Hubercc960f22024-01-29 01:13:45 +010092
93 type Extent_Range is range 0 .. 0; -- Linux allows 100 "file sections"
94 type Extents is array (Extent_Range) of Extent;
95
96 type Inode_Info is record
Nico Huber8e4b9f82024-02-12 01:13:51 +010097 I : Inode_Index := (Size => Directory_Record'Length, others => <>);
Nico Hubercc960f22024-01-29 01:13:45 +010098 Mode : File_Type := File_Type'First;
99 Size : Inode_Length := 0;
100 Extents : ISO9660.Extents := (Extent_Range => (others => <>));
101 end record;
102
103 type T is record
104 Static : Mount_State := (others => <>);
105 S : State;
106 Inode : Inode_Info := (others => <>);
Nico Huber8e4b9f82024-02-12 01:13:51 +0100107 Cur_Dir : Inode_Index := (Size => Directory_Record'Length, others => <>);
Nico Hubercc960f22024-01-29 01:13:45 +0100108 end record;
109
110end FILO.FS.ISO9660;