------------------------------------------------------------------------------
--                                                                          --
--                         GNAT RUNTIME COMPONENTS                          --
--                                                                          --
--           A D A . S T R I N G S . W I D E _ U N B O U N D E D            --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--                            $Revision: 1.14 $
--                                                                          --
--          Copyright (C) 1992-2001 Free Software Foundation, Inc.          --
--                                                                          --
-- GNAT is free software;  you can  redistribute it  and/or modify it under --
-- terms of the  GNU General Public License as published  by the Free Soft- --
-- ware  Foundation;  either version 2,  or (at your option) any later ver- --
-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
-- for  more details.  You should have  received  a copy of the GNU General --
-- Public License  distributed with GNAT;  see file COPYING.  If not, write --
-- to  the Free Software Foundation,  59 Temple Place - Suite 330,  Boston, --
-- MA 02111-1307, USA.                                                      --
--                                                                          --
-- As a special exception,  if other files  instantiate  generics from this --
-- unit, or you link  this unit with other files  to produce an executable, --
-- this  unit  does not  by itself cause  the resulting  executable  to  be --
-- covered  by the  GNU  General  Public  License.  This exception does not --
-- however invalidate  any other reasons why  the executable file  might be --
-- covered by the  GNU Public License.                                      --
--                                                                          --
-- GNAT was originally developed  by the GNAT team at  New York University. --
-- It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). --
--                                                                          --
------------------------------------------------------------------------------

with Ada.Strings.Wide_Fixed;
with Ada.Strings.Wide_Search;
with Ada.Unchecked_Deallocation;

package body Ada.Strings.Wide_Unbounded is

   use Ada.Finalization;

   ---------
   -- "&" --
   ---------

   function "&"
     (Left  : Unbounded_Wide_String;
      Right : Unbounded_Wide_String)
      return  Unbounded_Wide_String
   is
      L_Length : constant Integer := Left.Reference.all'Length;
      R_Length : constant Integer := Right.Reference.all'Length;
      Length   : constant Integer := L_Length + R_Length;
      Result   : Unbounded_Wide_String;

   begin
      Result.Reference := new Wide_String (1 .. Length);
      Result.Reference.all (1 .. L_Length)          := Left.Reference.all;
      Result.Reference.all (L_Length + 1 .. Length) := Right.Reference.all;
      return Result;
   end "&";

   function "&"
     (Left  : Unbounded_Wide_String;
      Right : Wide_String)
      return  Unbounded_Wide_String
   is
      L_Length : constant Integer := Left.Reference.all'Length;
      Length   : constant Integer := L_Length +  Right'Length;
      Result   : Unbounded_Wide_String;

   begin
      Result.Reference := new Wide_String (1 .. Length);
      Result.Reference.all (1 .. L_Length)          := Left.Reference.all;
      Result.Reference.all (L_Length + 1 .. Length) := Right;
      return Result;
   end "&";

   function "&"
     (Left  : Wide_String;
      Right : Unbounded_Wide_String)
      return  Unbounded_Wide_String
   is
      R_Length : constant Integer := Right.Reference.all'Length;
      Length   : constant Integer := Left'Length + R_Length;
      Result   : Unbounded_Wide_String;

   begin
      Result.Reference := new Wide_String (1 .. Length);
      Result.Reference.all (1 .. Left'Length)          := Left;
      Result.Reference.all (Left'Length + 1 .. Length) := Right.Reference.all;
      return Result;
   end "&";

   function "&"
     (Left  : Unbounded_Wide_String;
      Right : Wide_Character)
      return  Unbounded_Wide_String
   is
      Length : constant Integer := Left.Reference.all'Length + 1;
      Result : Unbounded_Wide_String;

   begin
      Result.Reference := new Wide_String (1 .. Length);
      Result.Reference.all (1 .. Length - 1) := Left.Reference.all;
      Result.Reference.all (Length)          := Right;
      return Result;
   end "&";

   function "&"
     (Left  : Wide_Character;
      Right : Unbounded_Wide_String)
      return  Unbounded_Wide_String
   is
      Length : constant Integer      := Right.Reference.all'Length + 1;
      Result : Unbounded_Wide_String;

   begin
      Result.Reference := new Wide_String (1 .. Length);
      Result.Reference.all (1)           := Left;
      Result.Reference.all (2 .. Length) := Right.Reference.all;
      return Result;
   end "&";

   ---------
   -- "*" --
   ---------

   function "*"
     (Left  : Natural;
      Right : Wide_Character)
      return  Unbounded_Wide_String
   is
      Result : Unbounded_Wide_String;

   begin
      Result.Reference := new Wide_String (1 .. Left);
      for J in Result.Reference'Range loop
         Result.Reference (J) := Right;
      end loop;

      return Result;
   end "*";

   function "*"
     (Left   : Natural;
      Right  : Wide_String)
      return   Unbounded_Wide_String
   is
      Result : Unbounded_Wide_String;

   begin
      Result.Reference := new Wide_String (1 .. Left * Right'Length);

      for J in 1 .. Left loop
         Result.Reference.all
           (Right'Length * J - Right'Length + 1 .. Right'Length * J) := Right;
      end loop;

      return Result;
   end "*";

   function "*"
     (Left  : Natural;
      Right : Unbounded_Wide_String)
      return  Unbounded_Wide_String
   is
      R_Length : constant Integer := Right.Reference.all'Length;
      Result   : Unbounded_Wide_String;

   begin
      Result.Reference := new Wide_String (1 .. Left * R_Length);

      for I in 1 .. Left loop
         Result.Reference.all (R_Length * I - R_Length + 1 .. R_Length * I) :=
           Right.Reference.all;
      end loop;

      return Result;
   end "*";

   ---------
   -- "<" --
   ---------

   function "<"
     (Left  : in Unbounded_Wide_String;
      Right : in Unbounded_Wide_String)
      return  Boolean
   is
   begin
      return Left.Reference.all < Right.Reference.all;
   end "<";

   function "<"
     (Left  : in Unbounded_Wide_String;
      Right : in Wide_String)
      return  Boolean
   is
   begin
      return Left.Reference.all < Right;
   end "<";

   function "<"
     (Left  : in Wide_String;
      Right : in Unbounded_Wide_String)
      return  Boolean
   is
   begin
      return Left < Right.Reference.all;
   end "<";

   ----------
   -- "<=" --
   ----------

   function "<="
     (Left  : in Unbounded_Wide_String;
      Right : in Unbounded_Wide_String)
      return  Boolean
   is
   begin
      return Left.Reference.all <= Right.Reference.all;
   end "<=";

   function "<="
     (Left  : in Unbounded_Wide_String;
      Right : in Wide_String)
      return  Boolean
   is
   begin
      return Left.Reference.all <= Right;
   end "<=";

   function "<="
     (Left  : in Wide_String;
      Right : in Unbounded_Wide_String)
      return  Boolean
   is
   begin
      return Left <= Right.Reference.all;
   end "<=";

   ---------
   -- "=" --
   ---------

   function "="
     (Left  : in Unbounded_Wide_String;
      Right : in Unbounded_Wide_String)
      return  Boolean
   is
   begin
      return Left.Reference.all = Right.Reference.all;
   end "=";

   function "="
     (Left  : in Unbounded_Wide_String;
      Right : in Wide_String)
      return  Boolean
   is
   begin
      return Left.Reference.all = Right;
   end "=";

   function "="
     (Left  : in Wide_String;
      Right : in Unbounded_Wide_String)
      return  Boolean
   is
   begin
      return Left = Right.Reference.all;
   end "=";

   ---------
   -- ">" --
   ---------

   function ">"
     (Left  : in Unbounded_Wide_String;
      Right : in Unbounded_Wide_String)
      return  Boolean
   is
   begin
      return Left.Reference.all > Right.Reference.all;
   end ">";

   function ">"
     (Left  : in Unbounded_Wide_String;
      Right : in Wide_String)
      return  Boolean
   is
   begin
      return Left.Reference.all > Right;
   end ">";

   function ">"
     (Left  : in Wide_String;
      Right : in Unbounded_Wide_String)
      return  Boolean
   is
   begin
      return Left > Right.Reference.all;
   end ">";

   ----------
   -- ">=" --
   ----------

   function ">="
     (Left  : in Unbounded_Wide_String;
      Right : in Unbounded_Wide_String)
      return  Boolean
   is
   begin
      return Left.Reference.all >= Right.Reference.all;
   end ">=";

   function ">="
     (Left  : in Unbounded_Wide_String;
      Right : in Wide_String)
      return  Boolean
   is
   begin
      return Left.Reference.all >= Right;
   end ">=";

   function ">="
     (Left  : in Wide_String;
      Right : in Unbounded_Wide_String)
      return  Boolean
   is
   begin
      return Left >= Right.Reference.all;
   end ">=";

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

   procedure Adjust (Object : in out Unbounded_Wide_String) is
   begin
      --  Copy string, except we do not copy the statically allocated
      --  null string, since it can never be deallocated.

      if Object.Reference /= Null_Wide_String'Access then
         Object.Reference := new Wide_String'(Object.Reference.all);
      end if;
   end Adjust;

   ------------
   -- Append --
   ------------

   procedure Append
     (Source   : in out Unbounded_Wide_String;
      New_Item : in Unbounded_Wide_String)
   is
      S_Length : constant Integer := Source.Reference.all'Length;
      Length   : constant Integer := S_Length + New_Item.Reference.all'Length;
      Temp     : Wide_String_Access := Source.Reference;

   begin
      if Source.Reference = Null_Wide_String'Access then
         Source := To_Unbounded_Wide_String (New_Item.Reference.all);
         return;
      end if;

      Source.Reference := new Wide_String (1 .. Length);

      Source.Reference.all (1 .. S_Length) := Temp.all;
      Source.Reference.all (S_Length + 1 .. Length) := New_Item.Reference.all;
      Free (Temp);
   end Append;

   procedure Append
     (Source   : in out Unbounded_Wide_String;
      New_Item : in Wide_String)
   is
      S_Length : constant Integer := Source.Reference.all'Length;
      Length   : constant Integer := S_Length + New_Item'Length;
      Temp     : Wide_String_Access := Source.Reference;

   begin
      if Source.Reference = Null_Wide_String'Access then
         Source := To_Unbounded_Wide_String (New_Item);
         return;
      end if;

      Source.Reference := new Wide_String (1 .. Length);
      Source.Reference.all (1 .. S_Length) := Temp.all;
      Source.Reference.all (S_Length + 1 .. Length) := New_Item;
      Free (Temp);
   end Append;

   procedure Append
     (Source   : in out Unbounded_Wide_String;
      New_Item : in Wide_Character)
   is
      S_Length : constant Integer := Source.Reference.all'Length;
      Length   : constant Integer := S_Length + 1;
      Temp     : Wide_String_Access := Source.Reference;

   begin
      if Source.Reference = Null_Wide_String'Access then
         Source := To_Unbounded_Wide_String ("" & New_Item);
         return;
      end if;

      Source.Reference := new Wide_String (1 .. Length);
      Source.Reference.all (1 .. S_Length) := Temp.all;
      Source.Reference.all (S_Length + 1) := New_Item;
      Free (Temp);
   end Append;

   -----------
   -- Count --
   -----------

   function Count
     (Source   : Unbounded_Wide_String;
      Pattern  : Wide_String;
      Mapping  : Wide_Maps.Wide_Character_Mapping :=
                        Wide_Maps.Identity)
      return     Natural
   is
   begin
      return Wide_Search.Count (Source.Reference.all, Pattern, Mapping);
   end Count;

   function Count
     (Source   : in Unbounded_Wide_String;
      Pattern  : in Wide_String;
      Mapping  : in Wide_Maps.Wide_Character_Mapping_Function)
      return     Natural
   is
   begin
      return Wide_Search.Count (Source.Reference.all, Pattern, Mapping);
   end Count;

   function Count
     (Source   : Unbounded_Wide_String;
      Set      : Wide_Maps.Wide_Character_Set)
      return     Natural
   is
   begin
      return Wide_Search.Count (Source.Reference.all, Set);
   end Count;

   ------------
   -- Delete --
   ------------

   function Delete
     (Source  : Unbounded_Wide_String;
      From    : Positive;
      Through : Natural)
      return    Unbounded_Wide_String
   is
   begin
      return
        To_Unbounded_Wide_String
          (Wide_Fixed.Delete (Source.Reference.all, From, Through));
   end Delete;

   procedure Delete
     (Source  : in out Unbounded_Wide_String;
      From    : in Positive;
      Through : in Natural)
   is
      Temp : Wide_String_Access := Source.Reference;
   begin
      Source := To_Unbounded_Wide_String
        (Wide_Fixed.Delete (Temp.all, From, Through));
   end Delete;

   -------------
   -- Element --
   -------------

   function Element
     (Source : Unbounded_Wide_String;
      Index  : Positive)
      return   Wide_Character
   is
   begin
      if Index <= Source.Reference.all'Last then
         return Source.Reference.all (Index);
      else
         raise Strings.Index_Error;
      end if;
   end Element;

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

   procedure Finalize (Object : in out Unbounded_Wide_String) is
      procedure Deallocate is
        new Ada.Unchecked_Deallocation (Wide_String, Wide_String_Access);

   begin
      --  Note: Don't try to free statically allocated null string

      if Object.Reference /= Null_Wide_String'Access then
         Deallocate (Object.Reference);
         Object.Reference := Null_Unbounded_Wide_String.Reference;
      end if;
   end Finalize;

   ----------------
   -- Find_Token --
   ----------------

   procedure Find_Token
     (Source : Unbounded_Wide_String;
      Set    : Wide_Maps.Wide_Character_Set;
      Test   : Strings.Membership;
      First  : out Positive;
      Last   : out Natural)
   is
   begin
      Wide_Search.Find_Token (Source.Reference.all, Set, Test, First, Last);
   end Find_Token;

   ----------
   -- Free --
   ----------

   procedure Free (X : in out Wide_String_Access) is
      procedure Deallocate is
         new Ada.Unchecked_Deallocation (Wide_String, Wide_String_Access);
   begin
      Deallocate (X);
   end Free;

   ----------
   -- Head --
   ----------

   function Head
     (Source : Unbounded_Wide_String;
      Count  : Natural;
      Pad    : Wide_Character := Wide_Space)
      return   Unbounded_Wide_String
   is
   begin
      return
        To_Unbounded_Wide_String
          (Wide_Fixed.Head (Source.Reference.all, Count, Pad));
   end Head;

   procedure Head
     (Source : in out Unbounded_Wide_String;
      Count  : in Natural;
      Pad    : in Wide_Character := Wide_Space)
   is
   begin
      Source := To_Unbounded_Wide_String
        (Wide_Fixed.Head (Source.Reference.all, Count, Pad));
   end Head;

   -----------
   -- Index --
   -----------

   function Index
     (Source   : Unbounded_Wide_String;
      Pattern  : Wide_String;
      Going    : Strings.Direction := Strings.Forward;
      Mapping  : Wide_Maps.Wide_Character_Mapping :=
                        Wide_Maps.Identity)
      return     Natural
   is
   begin
      return
        Wide_Search.Index (Source.Reference.all, Pattern, Going, Mapping);
   end Index;

   function Index
     (Source   : in Unbounded_Wide_String;
      Pattern  : in Wide_String;
      Going    : in Direction := Forward;
      Mapping  : in Wide_Maps.Wide_Character_Mapping_Function)
      return Natural
   is
   begin
      return
        Wide_Search.Index (Source.Reference.all, Pattern, Going, Mapping);
   end Index;

   function Index
     (Source : Unbounded_Wide_String;
      Set    : Wide_Maps.Wide_Character_Set;
      Test   : Strings.Membership := Strings.Inside;
      Going  : Strings.Direction  := Strings.Forward)
      return   Natural
   is
   begin
      return Wide_Search.Index (Source.Reference.all, Set, Test, Going);
   end Index;

   function Index_Non_Blank
     (Source : Unbounded_Wide_String;
      Going  : Strings.Direction := Strings.Forward)
      return   Natural
   is
   begin
      return Wide_Search.Index_Non_Blank (Source.Reference.all, Going);
   end Index_Non_Blank;

   ----------------
   -- Initialize --
   ----------------

   procedure Initialize (Object : in out Unbounded_Wide_String) is
   begin
      Object.Reference := Null_Unbounded_Wide_String.Reference;
   end Initialize;

   ------------
   -- Insert --
   ------------

   function Insert
     (Source   : Unbounded_Wide_String;
      Before   : Positive;
      New_Item : Wide_String)
      return     Unbounded_Wide_String
   is
   begin
      return
        To_Unbounded_Wide_String
          (Wide_Fixed.Insert (Source.Reference.all, Before, New_Item));
   end Insert;

   procedure Insert
     (Source   : in out Unbounded_Wide_String;
      Before   : in Positive;
      New_Item : in Wide_String)
   is
   begin
      Source := To_Unbounded_Wide_String
        (Wide_Fixed.Insert (Source.Reference.all, Before, New_Item));
   end Insert;

   ------------
   -- Length --
   ------------

   function Length (Source : Unbounded_Wide_String) return Natural is
   begin
      return Source.Reference.all'Length;
   end Length;

   ---------------
   -- Overwrite --
   ---------------

   function Overwrite
     (Source    : Unbounded_Wide_String;
      Position  : Positive;
      New_Item  : Wide_String)
      return      Unbounded_Wide_String is

   begin
      return To_Unbounded_Wide_String
        (Wide_Fixed.Overwrite (Source.Reference.all, Position, New_Item));
   end Overwrite;

   procedure Overwrite
     (Source    : in out Unbounded_Wide_String;
      Position  : in Positive;
      New_Item  : in Wide_String)
   is
      Temp : Wide_String_Access := Source.Reference;
   begin
      Source := To_Unbounded_Wide_String
        (Wide_Fixed.Overwrite (Temp.all, Position, New_Item));
   end Overwrite;

   ---------------------
   -- Replace_Element --
   ---------------------

   procedure Replace_Element
     (Source : in out Unbounded_Wide_String;
      Index  : Positive;
      By     : Wide_Character)
   is
   begin
      if Index <= Source.Reference.all'Last then
         Source.Reference.all (Index) := By;
      else
         raise Strings.Index_Error;
      end if;
   end Replace_Element;

   -------------------
   -- Replace_Slice --
   -------------------

   function Replace_Slice
     (Source   : Unbounded_Wide_String;
      Low      : Positive;
      High     : Natural;
      By       : Wide_String)
      return     Unbounded_Wide_String
   is
   begin
      return
        To_Unbounded_Wide_String
          (Wide_Fixed.Replace_Slice (Source.Reference.all, Low, High, By));
   end Replace_Slice;

   procedure Replace_Slice
     (Source   : in out Unbounded_Wide_String;
      Low      : in Positive;
      High     : in Natural;
      By       : in Wide_String)
   is
      Temp : Wide_String_Access := Source.Reference;
   begin
      Source := To_Unbounded_Wide_String
        (Wide_Fixed.Replace_Slice (Temp.all, Low, High, By));
   end Replace_Slice;

   -----------
   -- Slice --
   -----------

   function Slice
     (Source : Unbounded_Wide_String;
      Low    : Positive;
      High   : Natural)
      return   Wide_String
   is
      Length : constant Natural := Source.Reference'Length;

   begin
      --  Note: test of High > Length is in accordance with AI95-00128

      if Low > Length + 1 or else High > Length then
         raise Index_Error;

      else
         declare
            Result : Wide_String (1 .. High - Low + 1);

         begin
            Result := Source.Reference.all (Low .. High);
            return Result;
         end;
      end if;
   end Slice;

   ----------
   -- Tail --
   ----------

   function Tail
     (Source : Unbounded_Wide_String;
      Count  : Natural;
      Pad    : Wide_Character := Wide_Space)
      return   Unbounded_Wide_String is

   begin
      return
        To_Unbounded_Wide_String
          (Wide_Fixed.Tail (Source.Reference.all, Count, Pad));
   end Tail;

   procedure Tail
     (Source : in out Unbounded_Wide_String;
      Count  : in Natural;
      Pad    : in Wide_Character := Wide_Space)
   is
      Temp : Wide_String_Access := Source.Reference;

   begin
      Source := To_Unbounded_Wide_String
        (Wide_Fixed.Tail (Temp.all, Count, Pad));
   end Tail;

   ------------------------------
   -- To_Unbounded_Wide_String --
   ------------------------------

   function To_Unbounded_Wide_String
     (Source : Wide_String)
      return   Unbounded_Wide_String
   is
      Result : Unbounded_Wide_String;

   begin
      Result.Reference := new Wide_String (1 .. Source'Length);
      Result.Reference.all := Source;
      return Result;
   end To_Unbounded_Wide_String;

   function To_Unbounded_Wide_String (Length : in Natural)
      return Unbounded_Wide_String
   is
      Result : Unbounded_Wide_String;

   begin
      Result.Reference := new Wide_String (1 .. Length);
      return Result;
   end To_Unbounded_Wide_String;

   --------------------
   -- To_Wide_String --
   --------------------

   function To_Wide_String
     (Source : Unbounded_Wide_String)
      return   Wide_String
   is
   begin
      return Source.Reference.all;
   end To_Wide_String;

   ---------------
   -- Translate --
   ---------------

   function Translate
     (Source  : Unbounded_Wide_String;
      Mapping : Wide_Maps.Wide_Character_Mapping)
      return    Unbounded_Wide_String
   is
   begin
      return
        To_Unbounded_Wide_String
          (Wide_Fixed.Translate (Source.Reference.all, Mapping));
   end Translate;

   procedure Translate
     (Source  : in out Unbounded_Wide_String;
      Mapping : Wide_Maps.Wide_Character_Mapping)
   is
   begin
      Wide_Fixed.Translate (Source.Reference.all, Mapping);
   end Translate;

   function Translate
     (Source  : in Unbounded_Wide_String;
      Mapping : in Wide_Maps.Wide_Character_Mapping_Function)
      return    Unbounded_Wide_String
   is
   begin
      return
        To_Unbounded_Wide_String
          (Wide_Fixed.Translate (Source.Reference.all, Mapping));
   end Translate;

   procedure Translate
     (Source  : in out Unbounded_Wide_String;
      Mapping : in Wide_Maps.Wide_Character_Mapping_Function)
   is
   begin
      Wide_Fixed.Translate (Source.Reference.all, Mapping);
   end Translate;

   ----------
   -- Trim --
   ----------

   function Trim
     (Source : in Unbounded_Wide_String;
      Side   : in Trim_End)
      return   Unbounded_Wide_String
   is
   begin
      return
        To_Unbounded_Wide_String
          (Wide_Fixed.Trim (Source.Reference.all, Side));
   end Trim;

   procedure Trim
     (Source : in out Unbounded_Wide_String;
      Side   : in Trim_End)
   is
      Old : Wide_String_Access := Source.Reference;
   begin
      Source.Reference := new Wide_String'(Wide_Fixed.Trim (Old.all, Side));
      Free (Old);
   end Trim;

   function Trim
     (Source : in Unbounded_Wide_String;
      Left   : in Wide_Maps.Wide_Character_Set;
      Right  : in Wide_Maps.Wide_Character_Set)
      return   Unbounded_Wide_String
   is
   begin
      return
        To_Unbounded_Wide_String
          (Wide_Fixed.Trim (Source.Reference.all, Left, Right));
   end Trim;

   procedure Trim
     (Source : in out Unbounded_Wide_String;
      Left   : in Wide_Maps.Wide_Character_Set;
      Right  : in Wide_Maps.Wide_Character_Set)
   is
      Old : Wide_String_Access := Source.Reference;

   begin
      Source.Reference :=
        new Wide_String'(Wide_Fixed.Trim (Old.all, Left, Right));
      Free (Old);
   end Trim;

end Ada.Strings.Wide_Unbounded;
