diff --git a/lib2/h3-arrays.adb b/lib2/h3-arrays.adb index c47b2e9..04a600b 100644 --- a/lib2/h3-arrays.adb +++ b/lib2/h3-arrays.adb @@ -3,8 +3,6 @@ with Ada.Unchecked_Deallocation; package body H3.Arrays is BUFFER_ALIGN: constant := 128; -- TODO: change it to a reasonably large value. - type Shift_Direction is (SHIFT_LEFT, SHIFT_RIGHT); - function To_Item_Array (Str: in Elastic_Array) return Item_Array is begin return Str.Buffer.Slot(Str.Buffer.Slot'First .. Str.Buffer.Last); @@ -128,7 +126,7 @@ package body H3.Arrays is end Prepare_Buffer; -- prepare the buffer for writing - procedure Prepare_Buffer (Str: in out Elastic_Array; Req_Hard_Capa: in System_Size; Shift_Pos: in System_Size := 0; Shift_Size: in System_Size := 0; Shift_Dir: in Shift_Direction := Shift_Right) is + procedure Prepare_Buffer (Str: in out Elastic_Array; Req_Hard_Capa: in System_Size; Shift_Pos: in System_Size := 0; Shift_Size: in System_Size := 0; Shift_Dir: in Direction := DIRECTION_FORWARD) is Tmp: Elastic_Array; First, Last: System_Size; Hard_Capa: System_Size; @@ -173,7 +171,7 @@ package body H3.Arrays is -- it is an internal function. perform no sanity check. -- if Shift_Pos or Shift_Size is beyond the allocated capacity, -- it will end up in an exception. - if Shift_Dir = SHIFT_LEFT then + if Shift_Dir = DIRECTION_BACKWARD then declare Mid: System_Size := Shift_Pos - Shift_Size; begin @@ -261,10 +259,10 @@ package body H3.Arrays is Repl_Len := Act_To_Pos - From_Pos + 1; if Repeat < Repl_Len then - Prepare_Buffer (Elastic_Array(Str), Get_Hard_Capacity(Str), Act_To_Pos, Repl_Len - Repeat, SHIFT_LEFT); + Prepare_Buffer (Elastic_Array(Str), Get_Hard_Capacity(Str), Act_To_Pos, Repl_Len - Repeat, DIRECTION_BACKWARD); Act_To_Pos := From_Pos + Repeat - 1; elsif Repeat > Repl_Len then - Prepare_Buffer (Elastic_Array(Str), Calc_Inc_Capa(Str, Repeat - Repl_Len), From_Pos, Repeat - Repl_Len, SHIFT_RIGHT); + Prepare_Buffer (Elastic_Array(Str), Calc_Inc_Capa(Str, Repeat - Repl_Len), From_Pos, Repeat - Repl_Len, DIRECTION_FORWARD); Act_To_Pos := From_Pos + Repeat - 1; else Prepare_Buffer (Elastic_Array(Str)); @@ -284,10 +282,10 @@ package body H3.Arrays is Repl_Len := Act_To_Pos - From_Pos + 1; if V'Length < Repl_Len then - Prepare_Buffer (Elastic_Array(Str), Get_Hard_Capacity(Str), Act_To_Pos, Repl_Len - V'Length, SHIFT_LEFT); + Prepare_Buffer (Elastic_Array(Str), Get_Hard_Capacity(Str), Act_To_Pos, Repl_Len - V'Length, DIRECTION_BACKWARD); Act_To_Pos := From_Pos + V'Length - 1; elsif V'Length > Repl_Len then - Prepare_Buffer (Elastic_Array(Str), Calc_Inc_Capa(Str, V'Length - Repl_Len), From_Pos, V'Length - Repl_Len, SHIFT_RIGHT); + Prepare_Buffer (Elastic_Array(Str), Calc_Inc_Capa(Str, V'Length - Repl_Len), From_Pos, V'Length - Repl_Len, DIRECTION_FORWARD); Act_To_Pos := From_Pos + V'Length - 1; else Prepare_Buffer (Elastic_Array(Str)); @@ -304,10 +302,35 @@ package body H3.Arrays is if Act_To_Pos > Str.Buffer.Last then Act_To_Pos := Str.Buffer.Last; end if; - Prepare_Buffer (Elastic_Array(Str), Get_Hard_Capacity(Str), Act_To_Pos, Act_To_Pos - From_Pos + 1, SHIFT_LEFT); + Prepare_Buffer (Elastic_Array(Str), Get_Hard_Capacity(Str), Act_To_Pos, Act_To_Pos - From_Pos + 1, DIRECTION_BACKWARD); end if; end Delete; + function Find (Str: in Elastic_Array; V: In Item_Type; Start_Pos: in System_Index; Find_Dir: in Direction := DIRECTION_FORWARD) return System_Size is + Act_Start_Pos: System_Index := Start_Pos; + begin + if Find_Dir = DIRECTION_FORWARD then + for i in Act_Start_Pos .. Get_Last_Index(Str) loop + if Get_Item(Str, i) = V then + return i; + end if; + end loop; + else + if Act_Start_Pos > Get_Last_Index(Str) then + Act_Start_Pos := Get_Last_Index(Str); + end if; + for i in reverse Get_First_Index(Str) .. Act_Start_Pos loop + if Get_Item(Str, i) = V then + return i; + end if; + end loop; + end if; + + return System_Size'First; + end Find; + --function Find (Str: in Elastic_Array; V: In Item_Array; From_Pos: in System_Index; Find_Dir: in Direction := DIRECTION_FORWARD); + + function "=" (Str: in Elastic_Array; Str2: in Elastic_Array) return Standard.Boolean is begin return Str.Buffer = Str2.Buffer or else Str.Buffer.Slot(Get_First_Index(Str) .. Get_Last_Index(Str)) = Str2.Buffer.Slot(Get_First_Index(Str2) .. Get_Last_Index(Str2)); diff --git a/lib2/h3-arrays.ads b/lib2/h3-arrays.ads index 602b376..b3a4e8a 100644 --- a/lib2/h3-arrays.ads +++ b/lib2/h3-arrays.ads @@ -10,6 +10,8 @@ package H3.Arrays is Terminator_Length: constant System_Zero_Or_One := G_Terminator_Length; Terminator_Value: constant Item_Type := G_Terminator_Value; + type Direction is (DIRECTION_BACKWARD, DIRECTION_FORWARD); + type Elastic_Array is tagged private; type Item_Array is array(System_Index range <>) of Item_Type; --type Item_Array_Pointer is access all Item_Array; @@ -60,6 +62,10 @@ package H3.Arrays is procedure Delete (Str: in out Elastic_Array; From_Pos: in System_Index; To_Pos: in System_Size); + + function Find (Str: in Elastic_Array; V: In Item_Type; Start_Pos: in System_Index; Find_Dir: in Direction := DIRECTION_FORWARD) return System_Size; + --function Find (Str: in Elastic_Array; V: In Item_Array; Start_Pos: in System_Index; Find_Dir: in Direction := DIRECTION_FORWARD); + function "=" (Str: in Elastic_Array; Str2: in Elastic_Array) return Standard.Boolean; function "=" (Str: in Elastic_Array; Str2: in Item_Array) return Standard.Boolean; diff --git a/lib2/hello.adb b/lib2/hello.adb index f01b450..47310db 100644 --- a/lib2/hello.adb +++ b/lib2/hello.adb @@ -378,12 +378,16 @@ begin Ada.Wide_Text_IO.Put_Line ("]"); end; + S.Clear (Str2); + print_string_info (Str2, "Str2"); + --declare -- arr: constant Standard.Wide_String := S.To_Item_Array(str); --begin -- Ada.Wide_Text_IO.Put_Line (arr); --end; SS := Str; + end; declare @@ -423,12 +427,17 @@ begin begin S_I.Append (t1, 20, 5); S_I.Prepend (t1, 30, 2); + S_I.Append (t1, 30, 5); Ada.Text_IO.Put_Line ("-------------------------------"); for i in S_I.Get_First_Index(t1) .. S_I.Get_Last_Index(t1) loop Ada.Text_IO.Put (" " & S_I.Get_Item(t1, i)'Img); end loop; Ada.Text_IO.Put_Line (""); + + Ada.Text_IO.Put_Line (t1.Find(30, t1.Get_Last_Index, S_I.DIRECTION_BACKWARD)'Img); + Ada.Text_IO.Put_Line (t1.Find(30, t1.Get_First_Index)'Img); + Ada.Text_IO.Put_Line (t1.Find(90, t1.Get_First_Index)'Img); end; end;