--------------------------------
-- Ivan Levashew aka OCTAGRAM --
--              Barnaul, 2009 --
--------------------------------

with Turbo_Private.Bits; use Turbo_Private.Bits;
with Turbo_Private.Atomic; use Turbo_Private.Atomic;
with System; use System;
with System.Storage_Elements;

with Turbo_Private.Memory; use Turbo_Private;
with Turbo_Private.Memory.Standard;

package body Turbo_Private.Strings is

   type String_Prefix is record
      Counter : aliased Atomic_Unsigned_32;
      Length  : Unsigned_32;
   end record;

   String_Prefix_Size : constant Unsigned_Addr := String_Prefix'Max_Size_In_Storage_Elements;

   ------------
   -- Adjust --
   ------------

   procedure Adjust (Object : in out String_8) is
   begin
      if Object.Item /= Null_Address then
         declare
            Prefix : String_Prefix;
            for Prefix'Address use Object.Item - String_Prefix_Size;
            pragma Import (Ada, Prefix);
         begin
            Inc (Prefix.Counter);
         end;
      end if;
   end Adjust;

   --------------
   -- Finalize --
   --------------

   procedure Finalize (Object : in out String_8) is
      Prefix_Address : Address;
      New_Counter_Value : Unsigned_32;
   begin
      if Object.Item /= Null_Address then
         Prefix_Address := Object.Item - String_Prefix_Size;
         declare
            Prefix : String_Prefix;
            for Prefix'Address use Prefix_Address;
            pragma Import (Ada, Prefix);
         begin
            New_Counter_Value := Dec_Get (Prefix.Counter'Access);
         end;
         if New_Counter_Value = 0 then
            Memory.Standard.Storage_Pool.Deallocate (Prefix_Address);
         end if;
      end if;
   end Finalize;



end Turbo_Private.Strings;
