Implement Ext2.Read()
diff --git a/src/filo-fs-ext2.adb b/src/filo-fs-ext2.adb
index 06909c0..ace8c6a 100644
--- a/src/filo-fs-ext2.adb
+++ b/src/filo-fs-ext2.adb
@@ -756,9 +756,73 @@
Buf : out Buffer_Type;
Len : out Natural)
is
+ Pos : Natural;
begin
- Buf := (others => 0);
+ if State.Inode.Mode = Fast_Link then
+ if File_Len > State.Inode.Inline'Length or
+ File_Pos >= File_Len then
+ Len := 0;
+ else
+ Len := Natural'Min (Buf'Length, Natural (File_Len - File_Pos));
+ end if;
+ Buf (Buf'First .. Buf'First + Len - 1) :=
+ State.Inode.Inline (Natural (File_Pos) .. Natural (File_Pos) + Len - 1);
+ Buf (Buf'First + Len .. Buf'Last) := (others => 16#00#);
+ File_Pos := File_Pos + File_Length (Len);
+ return;
+ end if;
+
Len := 0;
+ Pos := Buf'First;
+ while Pos <= Buf'Last and Inode_Length (File_Pos) < State.Inode.Size loop
+ declare
+ Block_Size : constant File_Length := 2 ** State.Block_Size_Bits;
+ In_Block : constant Max_Block_Index := Natural (File_Pos mod Block_Size);
+ Logical : constant FSBlock_Logical := FSBlock_Logical (File_Pos / Block_Size);
+ In_Block_Space : constant Natural := Natural (Block_Size) - In_Block;
+ In_File_Space : constant Natural := Natural (File_Len - File_Pos);
+ In_Buf_Space : constant Natural := Buf'Last - Pos + 1;
+ Len_Here : Natural;
+ begin
+ Len_Here := In_Block_Space;
+ if In_File_Space < Len_Here then
+ Len_Here := In_File_Space;
+ end if;
+ if In_Buf_Space < Len_Here then
+ Len_Here := In_Buf_Space;
+ end if;
+
+ declare
+ Last : constant Index_Type := Pos + Len_Here - 1;
+ Cache_Start, Cache_End : Max_Block_Index;
+ Physical : FSBlock_Offset;
+ Success : Boolean;
+ begin
+ if State.Inode.Use_Extents then
+ Extent_Block_Map (State, Logical, Physical, Success);
+ else
+ Ext2_Block_Map (State, Logical, Physical, Success);
+ end if;
+ if Success then
+ Cache_FSBlock
+ (State => State,
+ Phys => Physical,
+ Level => Block_Cache_Index'Last,
+ Cache_Start => Cache_Start,
+ Cache_End => Cache_End,
+ Success => Success);
+ end if;
+ exit when not Success;
+
+ Buf (Pos .. Last) := State.Block_Cache (
+ Cache_Start + In_Block .. Cache_Start + In_Block + Len_Here - 1);
+ File_Pos := File_Pos + File_Length (Len_Here);
+ Pos := Pos + Len_Here;
+ Len := Len + Len_Here;
+ end;
+ end;
+ end loop;
+ Buf (Pos .. Buf'Last) := (others => 16#00#);
end Read;
--------------------------------------------------------------------------