fixed a buffer growth bug in Replace for Elastic_String

This commit is contained in:
2021-10-03 16:53:13 +00:00
parent 50760a4107
commit 4fd093da3e
4 changed files with 91 additions and 55 deletions

View File

@ -1,19 +1,23 @@
with Ada.Finalization;
generic
--type Character_Type is private;
type Character_Type is (<>);
Terminator: Character_Type;
--type Item_Type is private;
type Item_Type is (<>);
G_Terminator_Length: System_Zero_Or_One;
G_Terminator_Value: Item_Type;
package H3.Strings is
Terminator_Length: constant System_Zero_Or_One := G_Terminator_Length;
Terminator_Value: constant Item_Type := G_Terminator_Value;
type Elastic_String is private;
type Character_Array is array(System_Index range <>) of Character_Type;
--type Character_Array_Pointer is access all Character_Array;
type Item_Array is array(System_Index range <>) of Item_Type;
--type Item_Array_Pointer is access all Item_Array;
subtype Thin_Character_Array is Character_Array(System_Index'Range);
type Thin_Character_Array_Pointer is access Thin_Character_Array;
subtype Thin_Item_Array is Item_Array(System_Index'Range);
type Thin_Item_Array_Pointer is access Thin_Item_Array;
function To_Character_Array (Str: in Elastic_String) return Character_Array;
function To_Item_Array (Str: in Elastic_String) return Item_Array;
function Get_Capacity (Str: in Elastic_String) return System_Size;
pragma Inline (Get_Capacity);
@ -29,47 +33,48 @@ package H3.Strings is
function Get_Last_Index (Str: in Elastic_String) return System_Size;
pragma Inline (Get_Last_index);
function Get_Item (Str: in Elastic_String; Pos: in System_Index) return Character_Type;
function Get_Item (Str: in Elastic_String; Pos: in System_Index) return Item_Type;
pragma Inline (Get_Item);
-- unsafe
function Get_Slot_Pointer (Str: in Elastic_String) return Thin_Character_Array_Pointer;
function Get_Slot_Pointer (Str: in Elastic_String) return Thin_Item_Array_Pointer;
pragma Inline (Get_Slot_Pointer);
function Is_Shared(Str: in Elastic_String) return Standard.Boolean;
pragma Inline (Is_Shared);
procedure Purge (Str: in out Elastic_String);
procedure Clear (Str: in out Elastic_String);
procedure Purge (Str: in out Elastic_String); -- clear and reset the buffer to Empty_Buffer.
procedure Insert (Str: in out Elastic_String; Pos: in System_Index; V: in Character_Type; Repeat: in System_Size := 1);
procedure Insert (Str: in out Elastic_String; Pos: in System_Index; V: in Character_Array);
procedure Insert (Str: in out Elastic_String; Pos: in System_Index; V: in Item_Type; Repeat: in System_Size := 1);
procedure Insert (Str: in out Elastic_String; Pos: in System_Index; V: in Item_Array);
procedure Append (Str: in out Elastic_String; V: in Character_Type; Repeat: in System_Size := 1);
procedure Append (Str: in out Elastic_String; V: in Character_Array);
procedure Append (Str: in out Elastic_String; V: in Item_Type; Repeat: in System_Size := 1);
procedure Append (Str: in out Elastic_String; V: in Item_Array);
procedure Prepend (Str: in out Elastic_String; V: in Character_Type; Repeat: in System_Size := 1);
procedure Prepend (Str: in out Elastic_String; V: in Character_Array);
procedure Prepend (Str: in out Elastic_String; V: in Item_Type; Repeat: in System_Size := 1);
procedure Prepend (Str: in out Elastic_String; V: in Item_Array);
procedure Replace (Str: in out Elastic_String; From_Pos: in System_Index; To_Pos: in System_Size; V: in Character_Type; Repeat: in System_Size := 1);
procedure Replace (Str: in out Elastic_String; From_Pos: in System_Index; To_Pos: in System_Size; V: in Character_Array);
procedure Replace (Str: in out Elastic_String; From_Pos: in System_Index; To_Pos: in System_Size; V: in Item_Type; Repeat: in System_Size := 1);
procedure Replace (Str: in out Elastic_String; From_Pos: in System_Index; To_Pos: in System_Size; V: in Item_Array);
procedure Delete (Str: in out Elastic_String; From_Pos: in System_Index; To_Pos: in System_Size);
function "=" (Str: in Elastic_String; Str2: in Elastic_String) return Standard.Boolean;
function "=" (Str: in Elastic_String; Str2: in Character_Array) return Standard.Boolean;
function "=" (Str: in Elastic_String; Str2: in Item_Array) return Standard.Boolean;
private
type Buffer_Record(Capa: System_Size) is limited record
Refs: System_Size := 1;
Slot: Character_Array(1 .. Capa);
Slot: Item_Array(1 .. Capa) := (others => Terminator_Value);
Last: System_Size := 0;
end record;
type Buffer_Pointer is access all Buffer_Record;
--Empty_Buffer: aliased Buffer_Record(1);
Empty_Buffer: aliased Buffer_Record := (Capa => 1, Refs => 0, Slot => (1 => Terminator), Last => 0);
-- Use 1 slot to hold the terminator value regardless of th terminator length in Empty_Buffer.
Empty_Buffer: aliased Buffer_Record := (Capa => 1, Refs => 0, Slot => (1 => Terminator_Value), Last => 0);
type Elastic_String is new Ada.Finalization.Controlled with record
Buffer: Buffer_Pointer := Empty_Buffer'Access;