Make VFS wrapper state aware
diff --git a/src/fs-filo-vfs.adb b/src/fs-filo-vfs.adb
index 30f1bca..660a1cf 100644
--- a/src/fs-filo-vfs.adb
+++ b/src/fs-filo-vfs.adb
@@ -9,21 +9,39 @@
Convention => C
is
+ State : T := Initial;
+
function C_Mount return int
is
Success : Boolean;
begin
- Mount (Success);
+ if not Is_Mounted (State) then
+ State := Initial; -- Work around not having an unmount in FILO.
+ end if;
+ Mount (State, Part_Len, Success);
return (if Success then 1 else 0);
end C_Mount;
function C_Open (File_Path : Strings.chars_ptr) return int
is
+ File_Len : File_Length;
Success : Boolean;
begin
- Open (Strings.Value (File_Path), Success);
+ if Is_Mounted (State) and not Is_Open (State) then
+ Open (State, File_Len, Strings.Value (File_Path), Success);
+ Set_File_Max (File_Len);
+ else
+ Success := False;
+ end if;
return (if Success then 1 else 0);
end C_Open;
+
+ procedure C_Close is
+ begin
+ if Is_Open (State) then
+ Close (State);
+ end if;
+ end C_Close;
function C_Read (Buf : System.Address; Len : int) return int
is
@@ -33,9 +51,15 @@
Convention => C,
Address => Buf;
+ File_Pos : File_Offset := FILO.File_Pos;
Read_Len : Natural;
begin
- Read (Buffer, Read_Len);
+ if Is_Open (State) then
+ Read (State, File_Max, File_Pos, Buffer, Read_Len);
+ Set_File_Pos (File_Pos);
+ else
+ Read_Len := 0;
+ end if;
return int (Read_Len);
end C_Read;
diff --git a/src/fs-filo-vfs.ads b/src/fs-filo-vfs.ads
index 6115554..2b6dd52 100644
--- a/src/fs-filo-vfs.ads
+++ b/src/fs-filo-vfs.ads
@@ -6,19 +6,53 @@
generic
- with procedure Mount (Success : out Boolean);
+ type T (<>) is private;
- with procedure Open (File_Path : String; Success : out Boolean);
- with procedure Close with Convention => C;
+ with function Is_Mounted (State : T) return Boolean;
+ with function Is_Open (State : T) return Boolean
+ with
+ Post => (if Is_Open'Result then Is_Mounted (State));
- with procedure Read (Buf : out Buffer_Type; Len : out Natural);
+ Initial : T;
+
+ with procedure Mount
+ (State : in out T;
+ Part_Len : in Partition_Length;
+ Success : out Boolean)
+ with
+ Pre => not Is_Mounted (State),
+ Post => Success = Is_Mounted (State);
+
+ with procedure Open
+ (State : in out T;
+ File_Len : out File_Length;
+ File_Path : in String;
+ Success : out Boolean)
+ with
+ Pre => Is_Mounted (State) and not Is_Open (State),
+ Post => Success = Is_Open (State);
+
+ with procedure Close (State : in out T)
+ with
+ Pre => Is_Open (State),
+ Post => Is_Mounted (State);
+
+ with procedure Read
+ (State : in out T;
+ File_Len : in File_Length;
+ File_Pos : in out File_Offset;
+ Buf : out Buffer_Type;
+ Len : out Natural)
+ with
+ Pre => Is_Open (State),
+ Post => Is_Open (State);
package FS.FILO.VFS is
function C_Mount return int;
function C_Open (File_Path : Strings.chars_ptr) return int;
- procedure C_Close renames Close;
+ procedure C_Close;
function C_Read (Buf : System.Address; Len : int) return int;
diff --git a/src/fs-filo.adb b/src/fs-filo.adb
index f92455e..20162fc 100644
--- a/src/fs-filo.adb
+++ b/src/fs-filo.adb
@@ -22,7 +22,7 @@
Convention => C,
External_Name => "filepos";
- function Part_Length return Partition_Length is (Partition_Length (C_Part_Length));
+ function Part_Len return Partition_Length is (Partition_Length (C_Part_Length));
function File_Max return File_Length is
begin
diff --git a/src/fs-filo.ads b/src/fs-filo.ads
index b9e5742..fb836fc 100644
--- a/src/fs-filo.ads
+++ b/src/fs-filo.ads
@@ -5,14 +5,14 @@
package FS.FILO is
-private
type Partition_Length is range 0 .. Interfaces.Unsigned_64'Last;
- function Part_Length return Partition_Length;
-
type File_Length is range 0 .. int'Last; -- Should be higher, fix FILO first
subtype File_Offset is File_Length range 0 .. File_Length'Last - 1;
+private
+ function Part_Len return Partition_Length;
+
function File_Max return File_Length;
procedure Set_File_Max (Len : File_Length);