with Interfaces.C;            use Interfaces.C;
with Interfaces.C.Strings;    use Interfaces.C.Strings;

with System;                  use System;
with System.Storage_Elements; use System.Storage_Elements;

with System.Address_To_Access_Conversions;

package body Jwa.Strings is

   type String_8_Internal_1 (Length : size_t) is record
      Contents : char_array (1 .. Length);
      Zero_Char : char;
   end record;
   pragma Pack (String_8_Internal_1);

   type String_8_Internal_2 is record
      Reference_Counter : Integer := 0;
      pragma Volatile (Reference_Counter);
      CReference_Counter : Integer := 0;
      pragma Volatile (CReference_Counter);
   end record;

   package A2A_Internal is new System.Address_To_Access_Conversions
     (String_8_Internal_2);

   subtype String_8_Internal_2_Ptr is A2A_Internal.Object_Pointer;

   function Get_Internal (p : Address) return String_8_Internal_2_Ptr is
      Internal_Start : constant Address := p -
        String_8_Internal_2'Max_Size_In_Storage_Elements;
      Internal_Start_As_Ptr : constant String_8_Internal_2_Ptr :=
        A2A_Internal.To_Pointer (Internal_Start);
   begin
      return Internal_Start_As_Ptr;
   end Get_Internal;

   ---------------------
   -- String_8.Adjust --
   ---------------------

   procedure Adjust (Object : in out String_8) is
   begin
      if Object.p /= null then
         declare
            Ptr : String_8_Internal_2_Ptr :=
              Get_Internal (Object.p.all'Address);
            RC : Integer renames Ptr.Reference_Counter;
         begin
            RC := RC + 1;
         end;
      end if;
   end Adjust;

   -----------------------
   -- String_8.Finalize --
   -----------------------

   procedure Finalize (Object : in out String_8) is
   begin
      null;
   end Finalize;

end Jwa.Strings;
