blob: 0a28cc2efae8264becab93b23dbe9cc517845fd5 [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;
52 subtype FSBlock_Index is Index_Type range 0 .. FSBlock_Size - 1;
53
54 type FSBlock_Count is range 0 .. 2 ** 32 - 1;
55 subtype FSBlock is FSBlock_Count range 0 .. FSBlock_Count'Last - 1;
56 type FSBlock_Logical is new FSBlock;
57
58 subtype Directory_Record_Range is Index_Type range 0 .. 32;
59 subtype Directory_Record is Buffer_Type (Directory_Record_Range);
Nico Huber4210fcc2024-01-29 16:33:47 +010060 subtype Directory_Record_Offset is FSBlock_Index
61 range 0 .. FSBlock_Size - Directory_Record'Length;
Nico Hubercc960f22024-01-29 01:13:45 +010062
63 -- We'll use the absolute position of the dir record
64 type Inode_Index is record
65 Block : FSBlock := 0;
Nico Huber4210fcc2024-01-29 16:33:47 +010066 Offset : Directory_Record_Offset := 0;
Nico Hubercc960f22024-01-29 01:13:45 +010067 end record;
68 type Inode_Length is range 0 .. FSBlock_Count'Last * FSBlock_Size;
69
70 type Mount_State is record
71 Part_Len : Partition_Length := 0;
72 Root_Inode : Inode_Index := (others => <>);
73 end record;
74
75 type Extent is record
76 Start : FSBlock := 0;
77 Count : FSBlock_Count := 0;
78 end record;
79
80 type Extent_Range is range 0 .. 0; -- Linux allows 100 "file sections"
81 type Extents is array (Extent_Range) of Extent;
82
83 type Inode_Info is record
84 I : Inode_Index := (others => <>);
85 Mode : File_Type := File_Type'First;
86 Size : Inode_Length := 0;
87 Extents : ISO9660.Extents := (Extent_Range => (others => <>));
88 end record;
89
90 type T is record
91 Static : Mount_State := (others => <>);
92 S : State;
93 Inode : Inode_Info := (others => <>);
94 Cur_Dir : Inode_Index := (others => <>);
95 end record;
96
97end FILO.FS.ISO9660;