blob: 480ce39cf147ec0bb36f581c7cd4bc63157bc8e1 [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
26 Pre => Is_Mounted (State),
27 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
76 Dynamic_Predicate => Inode_Index.Offset <= Directory_Record_Offset'Last;
Nico Hubercc960f22024-01-29 01:13:45 +010077 type Inode_Length is range 0 .. FSBlock_Count'Last * FSBlock_Size;
78
79 type Mount_State is record
80 Part_Len : Partition_Length := 0;
81 Root_Inode : Inode_Index := (others => <>);
82 end record;
83
84 type Extent is record
85 Start : FSBlock := 0;
86 Count : FSBlock_Count := 0;
87 end record;
88
89 type Extent_Range is range 0 .. 0; -- Linux allows 100 "file sections"
90 type Extents is array (Extent_Range) of Extent;
91
92 type Inode_Info is record
93 I : Inode_Index := (others => <>);
94 Mode : File_Type := File_Type'First;
95 Size : Inode_Length := 0;
96 Extents : ISO9660.Extents := (Extent_Range => (others => <>));
97 end record;
98
99 type T is record
100 Static : Mount_State := (others => <>);
101 S : State;
102 Inode : Inode_Info := (others => <>);
103 Cur_Dir : Inode_Index := (others => <>);
104 end record;
105
106end FILO.FS.ISO9660;