home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / adav313.zip / gnat-3_13p-os2-bin-20010916.zip / emx / gnatlib / a-stwibo.adb < prev    next >
Text File  |  2000-07-19  |  57KB  |  1,813 lines

  1. ------------------------------------------------------------------------------
  2. --                                                                          --
  3. --                         GNAT RUNTIME COMPONENTS                          --
  4. --                                                                          --
  5. --             A D A . S T R I N G S . W I D E _ B O U N D E D              --
  6. --                                                                          --
  7. --                                 B o d y                                  --
  8. --                                                                          --
  9. --                            $Revision: 1.15 $                             --
  10. --                                                                          --
  11. --          Copyright (C) 1992-1997 Free Software Foundation, Inc.          --
  12. --                                                                          --
  13. -- GNAT is free software;  you can  redistribute it  and/or modify it under --
  14. -- terms of the  GNU General Public License as published  by the Free Soft- --
  15. -- ware  Foundation;  either version 2,  or (at your option) any later ver- --
  16. -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
  17. -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
  18. -- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
  19. -- for  more details.  You should have  received  a copy of the GNU General --
  20. -- Public License  distributed with GNAT;  see file COPYING.  If not, write --
  21. -- to  the Free Software Foundation,  59 Temple Place - Suite 330,  Boston, --
  22. -- MA 02111-1307, USA.                                                      --
  23. --                                                                          --
  24. -- As a special exception,  if other files  instantiate  generics from this --
  25. -- unit, or you link  this unit with other files  to produce an executable, --
  26. -- this  unit  does not  by itself cause  the resulting  executable  to  be --
  27. -- covered  by the  GNU  General  Public  License.  This exception does not --
  28. -- however invalidate  any other reasons why  the executable file  might be --
  29. -- covered by the  GNU Public License.                                      --
  30. --                                                                          --
  31. -- GNAT was originally developed  by the GNAT team at  New York University. --
  32. -- It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). --
  33. --                                                                          --
  34. ------------------------------------------------------------------------------
  35.  
  36. with Ada.Strings.Wide_Maps;   use Ada.Strings.Wide_Maps;
  37. with Ada.Strings.Wide_Search;
  38.  
  39. package body Ada.Strings.Wide_Bounded is
  40.  
  41.    package body Generic_Bounded_Length is
  42.  
  43.       ---------
  44.       -- "=" --
  45.       ---------
  46.  
  47.       function "="
  48.         (Left  : in Bounded_Wide_String;
  49.          Right : in Bounded_Wide_String)
  50.          return  Boolean
  51.       is
  52.       begin
  53.          return Left.Length = Right.Length
  54.            and then Left.Data (1 .. Left.Length) =
  55.                     Right.Data (1 .. Right.Length);
  56.       end "=";
  57.  
  58.       function "="
  59.         (Left  : in Bounded_Wide_String;
  60.          Right : in Wide_String)
  61.          return  Boolean
  62.       is
  63.       begin
  64.          return Left.Length = Right'Length
  65.            and then Left.Data (1 .. Left.Length) = Right;
  66.       end "=";
  67.  
  68.       function "="
  69.         (Left  : in Wide_String;
  70.          Right : in Bounded_Wide_String)
  71.          return  Boolean
  72.       is
  73.       begin
  74.          return Left'Length = Right.Length
  75.            and then Left = Right.Data (1 .. Right.Length);
  76.       end "=";
  77.  
  78.       ---------
  79.       -- "<" --
  80.       ---------
  81.  
  82.       function "<"
  83.         (Left  : in Bounded_Wide_String;
  84.          Right : in Bounded_Wide_String)
  85.          return  Boolean
  86.       is
  87.       begin
  88.          return Left.Data (1 .. Left.Length) < Right.Data (1 .. Right.Length);
  89.       end "<";
  90.  
  91.       function "<"
  92.         (Left  : in Bounded_Wide_String;
  93.          Right : in Wide_String)
  94.          return  Boolean
  95.       is
  96.       begin
  97.          return Left.Data (1 .. Left.Length) < Right;
  98.       end "<";
  99.  
  100.       function "<"
  101.         (Left  : in Wide_String;
  102.          Right : in Bounded_Wide_String)
  103.          return  Boolean
  104.       is
  105.       begin
  106.          return Left < Right.Data (1 .. Right.Length);
  107.       end "<";
  108.  
  109.       ----------
  110.       -- "<=" --
  111.       ----------
  112.  
  113.       function "<="
  114.         (Left  : in Bounded_Wide_String;
  115.          Right : in Bounded_Wide_String)
  116.          return  Boolean
  117.       is
  118.       begin
  119.          return Left.Data (1 .. Left.Length) <= Right.Data (1 .. Right.Length);
  120.       end "<=";
  121.  
  122.       function "<="
  123.         (Left  : in Bounded_Wide_String;
  124.          Right : in Wide_String)
  125.          return  Boolean
  126.       is
  127.       begin
  128.          return Left.Data (1 .. Left.Length) <= Right;
  129.       end "<=";
  130.  
  131.       function "<="
  132.         (Left  : in Wide_String;
  133.          Right : in Bounded_Wide_String)
  134.          return  Boolean
  135.       is
  136.       begin
  137.          return Left <= Right.Data (1 .. Right.Length);
  138.       end "<=";
  139.  
  140.       ---------
  141.       -- ">" --
  142.       ---------
  143.  
  144.       function ">"
  145.         (Left  : in Bounded_Wide_String;
  146.          Right : in Bounded_Wide_String)
  147.          return  Boolean
  148.       is
  149.       begin
  150.          return Left.Data (1 .. Left.Length) > Right.Data (1 .. Right.Length);
  151.       end ">";
  152.  
  153.       function ">"
  154.         (Left  : in Bounded_Wide_String;
  155.          Right : in Wide_String)
  156.          return  Boolean
  157.       is
  158.       begin
  159.          return Left.Data (1 .. Left.Length) > Right;
  160.       end ">";
  161.  
  162.       function ">"
  163.         (Left  : in Wide_String;
  164.          Right : in Bounded_Wide_String)
  165.          return  Boolean
  166.       is
  167.       begin
  168.          return Left > Right.Data (1 .. Right.Length);
  169.       end ">";
  170.  
  171.       ----------
  172.       -- ">=" --
  173.       ----------
  174.  
  175.       function ">="
  176.         (Left  : in Bounded_Wide_String;
  177.          Right : in Bounded_Wide_String)
  178.          return  Boolean
  179.       is
  180.       begin
  181.          return Left.Data (1 .. Left.Length) >= Right.Data (1 .. Right.Length);
  182.       end ">=";
  183.  
  184.       function ">="
  185.         (Left  : in Bounded_Wide_String;
  186.          Right : in Wide_String)
  187.          return  Boolean
  188.       is
  189.       begin
  190.          return Left.Data (1 .. Left.Length) >= Right;
  191.       end ">=";
  192.  
  193.       function ">="
  194.         (Left  : in Wide_String;
  195.          Right : in Bounded_Wide_String)
  196.          return  Boolean
  197.       is
  198.       begin
  199.          return Left >= Right.Data (1 .. Right.Length);
  200.       end ">=";
  201.  
  202.       ---------
  203.       -- "*" --
  204.       ---------
  205.  
  206.       function "*"
  207.         (Left  : in Natural;
  208.          Right : in Wide_Character)
  209.          return  Bounded_Wide_String
  210.       is
  211.          Result : Bounded_Wide_String;
  212.  
  213.       begin
  214.          if Left > Max_Length then
  215.             raise Ada.Strings.Length_Error;
  216.          else
  217.             Result.Length := Left;
  218.  
  219.             for J in 1 .. Left loop
  220.                Result.Data (J) := Right;
  221.             end loop;
  222.          end if;
  223.  
  224.          return Result;
  225.       end "*";
  226.  
  227.       function "*"
  228.         (Left  : in Natural;
  229.          Right : in Wide_String)
  230.          return  Bounded_Wide_String
  231.       is
  232.          Result : Bounded_Wide_String;
  233.          Pos    : Positive         := 1;
  234.          Rlen   : constant Natural := Right'Length;
  235.          Nlen   : constant Natural := Left * Rlen;
  236.  
  237.       begin
  238.          if Nlen > Max_Length then
  239.             raise Ada.Strings.Index_Error;
  240.          else
  241.             Result.Length := Nlen;
  242.  
  243.             if Nlen > 0 then
  244.                for J in 1 .. Left loop
  245.                   Result.Data (Pos .. Pos + Rlen - 1) := Right;
  246.                   Pos := Pos + Rlen;
  247.                end loop;
  248.             end if;
  249.          end if;
  250.  
  251.          return Result;
  252.       end "*";
  253.  
  254.       function "*"
  255.         (Left  : in Natural;
  256.          Right : in Bounded_Wide_String)
  257.          return  Bounded_Wide_String
  258.       is
  259.          Result : Bounded_Wide_String;
  260.          Pos    : Positive := 1;
  261.          Rlen   : constant Length_Range := Right.Length;
  262.          Nlen   : constant Natural      := Left * Rlen;
  263.  
  264.       begin
  265.          if Nlen > Max_Length then
  266.             raise Ada.Strings.Length_Error;
  267.  
  268.          else
  269.             Result.Length := Nlen;
  270.  
  271.             if Nlen > 0 then
  272.                for J in 1 .. Left loop
  273.                   Result.Data (Pos .. Pos + Rlen - 1) :=
  274.                     Right.Data (1 .. Rlen);
  275.                   Pos := Pos + Rlen;
  276.                end loop;
  277.             end if;
  278.          end if;
  279.  
  280.          return Result;
  281.       end "*";
  282.  
  283.       ---------
  284.       -- "&" --
  285.       ---------
  286.  
  287.       function "&"
  288.         (Left  : in Bounded_Wide_String;
  289.          Right : in Bounded_Wide_String)
  290.          return  Bounded_Wide_String
  291.       is
  292.          Result : Bounded_Wide_String;
  293.          Llen   : constant Length_Range := Left.Length;
  294.          Rlen   : constant Length_Range := Right.Length;
  295.          Nlen   : constant Natural      := Llen + Rlen;
  296.  
  297.       begin
  298.          if Nlen > Max_Length then
  299.             raise Ada.Strings.Length_Error;
  300.          else
  301.             Result.Length := Nlen;
  302.             Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
  303.             Result.Data (Llen + 1 .. Nlen) := Right.Data (1 .. Rlen);
  304.          end if;
  305.  
  306.          return Result;
  307.       end "&";
  308.  
  309.       function "&"
  310.         (Left  : in Bounded_Wide_String;
  311.          Right : in Wide_String)
  312.          return  Bounded_Wide_String
  313.       is
  314.          Result : Bounded_Wide_String;
  315.          Llen   : constant Length_Range := Left.Length;
  316.  
  317.          Nlen   : constant Natural      := Llen + Right'Length;
  318.  
  319.       begin
  320.          if Nlen > Max_Length then
  321.             raise Ada.Strings.Length_Error;
  322.          else
  323.             Result.Length := Nlen;
  324.             Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
  325.             Result.Data (Llen + 1 .. Nlen) := Right;
  326.          end if;
  327.          return Result;
  328.       end "&";
  329.  
  330.       function "&"
  331.         (Left  : in Wide_String;
  332.          Right : in Bounded_Wide_String)
  333.          return  Bounded_Wide_String
  334.       is
  335.          Result : Bounded_Wide_String;
  336.          Llen   : constant Length_Range := Left'Length;
  337.          Rlen   : constant Length_Range := Right.Length;
  338.          Nlen   : constant Natural      := Llen + Rlen;
  339.  
  340.       begin
  341.          if Nlen > Max_Length then
  342.             raise Ada.Strings.Length_Error;
  343.          else
  344.             Result.Length := Nlen;
  345.             Result.Data (1 .. Llen) := Left;
  346.             Result.Data (Llen + 1 .. Nlen) := Right.Data (1 .. Rlen);
  347.          end if;
  348.  
  349.          return Result;
  350.       end "&";
  351.  
  352.       function "&"
  353.         (Left  : in Bounded_Wide_String;
  354.          Right : in Wide_Character)
  355.          return  Bounded_Wide_String
  356.       is
  357.          Result : Bounded_Wide_String;
  358.          Llen   : constant Length_Range := Left.Length;
  359.  
  360.       begin
  361.          if Llen = Max_Length then
  362.             raise Ada.Strings.Length_Error;
  363.          else
  364.             Result.Length := Llen + 1;
  365.             Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
  366.             Result.Data (Result.Length) := Right;
  367.          end if;
  368.  
  369.          return Result;
  370.       end "&";
  371.  
  372.       function "&"
  373.         (Left  : in Wide_Character;
  374.          Right : in Bounded_Wide_String)
  375.          return  Bounded_Wide_String
  376.       is
  377.          Result : Bounded_Wide_String;
  378.          Rlen   : Length_Range := Right.Length;
  379.  
  380.       begin
  381.          if Rlen = Max_Length then
  382.             raise Ada.Strings.Length_Error;
  383.          else
  384.             Result.Length := Rlen + 1;
  385.             Result.Data (1) := Left;
  386.             Result.Data (2 .. Result.Length) := Right.Data (1 .. Rlen);
  387.          end if;
  388.  
  389.          return Result;
  390.       end "&";
  391.  
  392.       ------------
  393.       -- Append --
  394.       ------------
  395.  
  396.       --  Case of Bounded_Wide_String and Bounded_Wide_String
  397.  
  398.       function Append
  399.         (Left, Right : in Bounded_Wide_String;
  400.          Drop        : in Strings.Truncation  := Strings.Error)
  401.          return        Bounded_Wide_String
  402.       is
  403.          Result : Bounded_Wide_String;
  404.          Llen   : constant Length_Range := Left.Length;
  405.          Rlen   : constant Length_Range := Right.Length;
  406.          Nlen   : constant Natural      := Llen + Rlen;
  407.  
  408.       begin
  409.          if Nlen <= Max_Length then
  410.             Result.Length := Nlen;
  411.             Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
  412.             Result.Data (Llen + 1 .. Nlen) := Right.Data (1 .. Rlen);
  413.  
  414.          else
  415.             Result.Length := Max_Length;
  416.  
  417.             case Drop is
  418.                when Strings.Right =>
  419.                   if Llen >= Max_Length then -- only case is Llen = Max_Length
  420.                      Result.Data := Right.Data;
  421.  
  422.                   else
  423.                      Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
  424.                      Result.Data (Llen + 1 .. Max_Length) :=
  425.                        Right.Data (1 .. Max_Length - Llen);
  426.                   end if;
  427.  
  428.                when Strings.Left =>
  429.                   if Rlen >= Max_Length then -- only case is Rlen = Max_Length
  430.                      Result.Data := Right.Data;
  431.  
  432.                   else
  433.                      Result.Data (1 .. Max_Length - Rlen) :=
  434.                        Left.Data (Llen - (Max_Length - Rlen - 1) .. Llen);
  435.                      Result.Data (Max_Length - Rlen + 1 .. Max_Length) :=
  436.                        Right.Data (1 .. Rlen);
  437.                   end if;
  438.  
  439.                when Strings.Error =>
  440.                   raise Ada.Strings.Length_Error;
  441.             end case;
  442.          end if;
  443.  
  444.          return Result;
  445.       end Append;
  446.  
  447.       procedure Append
  448.         (Source   : in out Bounded_Wide_String;
  449.          New_Item : in Bounded_Wide_String;
  450.          Drop     : in Truncation  := Error)
  451.       is
  452.          Llen   : constant Length_Range := Source.Length;
  453.          Rlen   : constant Length_Range := New_Item.Length;
  454.          Nlen   : constant Natural      := Llen + Rlen;
  455.  
  456.       begin
  457.          if Nlen <= Max_Length then
  458.             Source.Length := Nlen;
  459.             Source.Data (Llen + 1 .. Nlen) := New_Item.Data (1 .. Rlen);
  460.  
  461.          else
  462.             Source.Length := Max_Length;
  463.  
  464.             case Drop is
  465.                when Strings.Right =>
  466.                   if Llen < Max_Length then
  467.                      Source.Data (Llen + 1 .. Max_Length) :=
  468.                        New_Item.Data (1 .. Max_Length - Llen);
  469.                   end if;
  470.  
  471.                when Strings.Left =>
  472.                   if Rlen >= Max_Length then -- only case is Rlen = Max_Length
  473.                      Source.Data := New_Item.Data;
  474.  
  475.                   else
  476.                      Source.Data (1 .. Max_Length - Rlen) :=
  477.                        Source.Data (Llen - (Max_Length - Rlen - 1) .. Llen);
  478.                      Source.Data (Max_Length - Rlen + 1 .. Max_Length) :=
  479.                        New_Item.Data (1 .. Rlen);
  480.                   end if;
  481.  
  482.                when Strings.Error =>
  483.                   raise Ada.Strings.Length_Error;
  484.             end case;
  485.          end if;
  486.  
  487.       end Append;
  488.  
  489.       --  Case of Bounded_Wide_String and Wide_String
  490.  
  491.       function Append
  492.         (Left  : in Bounded_Wide_String;
  493.          Right : in Wide_String;
  494.          Drop  : in Strings.Truncation := Strings.Error)
  495.          return  Bounded_Wide_String
  496.       is
  497.          Result : Bounded_Wide_String;
  498.          Llen   : constant Length_Range := Left.Length;
  499.          Rlen   : constant Length_Range := Right'Length;
  500.          Nlen   : constant Natural      := Llen + Rlen;
  501.  
  502.       begin
  503.          if Nlen <= Max_Length then
  504.             Result.Length := Nlen;
  505.             Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
  506.             Result.Data (Llen + 1 .. Nlen) := Right;
  507.  
  508.          else
  509.             Result.Length := Max_Length;
  510.  
  511.             case Drop is
  512.                when Strings.Right =>
  513.                   if Llen >= Max_Length then -- only case is Llen = Max_Length
  514.                      Result.Data := Left.Data;
  515.  
  516.                   else
  517.                      Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
  518.                      Result.Data (Llen + 1 .. Max_Length) :=
  519.                        Right (Right'First .. Right'First - 1 +
  520.                                               Max_Length - Llen);
  521.  
  522.                   end if;
  523.  
  524.                when Strings.Left =>
  525.                   if Rlen >= Max_Length then
  526.                      Result.Data (1 .. Max_Length) :=
  527.                        Right (Right'Last - (Max_Length - 1) .. Right'Last);
  528.  
  529.                   else
  530.                      Result.Data (1 .. Max_Length - Rlen) :=
  531.                        Left.Data (Llen - (Max_Length - Rlen - 1) .. Llen);
  532.                      Result.Data (Max_Length - Rlen + 1 .. Max_Length) :=
  533.                        Right;
  534.                   end if;
  535.  
  536.                when Strings.Error =>
  537.                   raise Ada.Strings.Length_Error;
  538.             end case;
  539.          end if;
  540.  
  541.          return Result;
  542.       end Append;
  543.  
  544.       procedure Append
  545.         (Source   : in out Bounded_Wide_String;
  546.          New_Item : in Wide_String;
  547.          Drop     : in Truncation  := Error)
  548.       is
  549.          Llen   : constant Length_Range := Source.Length;
  550.          Rlen   : constant Length_Range := New_Item'Length;
  551.          Nlen   : constant Natural      := Llen + Rlen;
  552.  
  553.       begin
  554.          if Nlen <= Max_Length then
  555.             Source.Length := Nlen;
  556.             Source.Data (Llen + 1 .. Nlen) := New_Item;
  557.  
  558.          else
  559.             Source.Length := Max_Length;
  560.  
  561.             case Drop is
  562.                when Strings.Right =>
  563.                   if Llen < Max_Length then
  564.                      Source.Data (Llen + 1 .. Max_Length) :=
  565.                        New_Item (New_Item'First ..
  566.                                        New_Item'First - 1 + Max_Length - Llen);
  567.                   end if;
  568.  
  569.                when Strings.Left =>
  570.                   if Rlen >= Max_Length then
  571.                      Source.Data (1 .. Max_Length) :=
  572.                        New_Item (New_Item'Last - (Max_Length - 1) ..
  573.                                                                 New_Item'Last);
  574.  
  575.                   else
  576.                      Source.Data (1 .. Max_Length - Rlen) :=
  577.                        Source.Data (Llen - (Max_Length - Rlen - 1) .. Llen);
  578.                      Source.Data (Max_Length - Rlen + 1 .. Max_Length) :=
  579.                        New_Item;
  580.                   end if;
  581.  
  582.                when Strings.Error =>
  583.                   raise Ada.Strings.Length_Error;
  584.             end case;
  585.          end if;
  586.  
  587.       end Append;
  588.  
  589.       --  Case of Wide_String and Bounded_Wide_String
  590.  
  591.       function Append
  592.         (Left  : in Wide_String;
  593.          Right : in Bounded_Wide_String;
  594.          Drop  : in Strings.Truncation := Strings.Error)
  595.          return  Bounded_Wide_String
  596.       is
  597.          Result : Bounded_Wide_String;
  598.          Llen   : constant Length_Range := Left'Length;
  599.          Rlen   : constant Length_Range := Right.Length;
  600.          Nlen   : constant Natural      := Llen + Rlen;
  601.  
  602.       begin
  603.          if Nlen <= Max_Length then
  604.             Result.Length := Nlen;
  605.             Result.Data (1 .. Llen) := Left;
  606.             Result.Data (Llen + 1 .. Llen + Rlen) := Right.Data (1 .. Rlen);
  607.  
  608.          else
  609.             Result.Length := Max_Length;
  610.  
  611.             case Drop is
  612.                when Strings.Right =>
  613.                   if Llen >= Max_Length then
  614.                      Result.Data (1 .. Max_Length) :=
  615.                         Left (Left'First .. Left'First + (Max_Length - 1));
  616.  
  617.                   else
  618.                      Result.Data (1 .. Llen) := Left;
  619.                      Result.Data (Llen + 1 .. Max_Length) :=
  620.                        Right.Data (1 .. Max_Length - Llen);
  621.                   end if;
  622.  
  623.                when Strings.Left =>
  624.                   if Rlen >= Max_Length then
  625.                      Result.Data (1 .. Max_Length) :=
  626.                        Right.Data (Rlen - (Max_Length - 1) .. Rlen);
  627.  
  628.                   else
  629.                      Result.Data (1 .. Max_Length - Rlen) :=
  630.                        Left (Left'Last - (Max_Length - Rlen - 1) .. Left'Last);
  631.                      Result.Data (Max_Length - Rlen + 1 .. Max_Length) :=
  632.                        Right.Data (1 .. Rlen);
  633.                   end if;
  634.  
  635.                when Strings.Error =>
  636.                   raise Ada.Strings.Length_Error;
  637.             end case;
  638.          end if;
  639.  
  640.          return Result;
  641.       end Append;
  642.  
  643.       --  Case of Bounded_Wide_String and Wide_Character
  644.  
  645.       function Append
  646.         (Left  : in Bounded_Wide_String;
  647.          Right : in Wide_Character;
  648.          Drop  : in Strings.Truncation := Strings.Error)
  649.          return  Bounded_Wide_String
  650.       is
  651.          Result : Bounded_Wide_String;
  652.          Llen   : constant Length_Range := Left.Length;
  653.  
  654.       begin
  655.          if Llen  < Max_Length then
  656.             Result.Length := Llen + 1;
  657.             Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
  658.             Result.Data (Llen + 1) := Right;
  659.             return Result;
  660.  
  661.          else
  662.             case Drop is
  663.                when Strings.Right =>
  664.                   return Left;
  665.  
  666.                when Strings.Left =>
  667.                   Result.Length := Max_Length;
  668.                   Result.Data (1 .. Max_Length - 1) :=
  669.                     Left.Data (2 .. Max_Length);
  670.                   Result.Data (Max_Length) := Right;
  671.                   return Result;
  672.  
  673.                when Strings.Error =>
  674.                   raise Ada.Strings.Length_Error;
  675.             end case;
  676.          end if;
  677.       end Append;
  678.  
  679.       procedure Append
  680.         (Source   : in out Bounded_Wide_String;
  681.          New_Item : in Wide_Character;
  682.          Drop     : in Truncation  := Error)
  683.       is
  684.          Llen   : constant Length_Range := Source.Length;
  685.  
  686.       begin
  687.          if Llen  < Max_Length then
  688.             Source.Length := Llen + 1;
  689.             Source.Data (Llen + 1) := New_Item;
  690.  
  691.          else
  692.             Source.Length := Max_Length;
  693.  
  694.             case Drop is
  695.                when Strings.Right =>
  696.                   null;
  697.  
  698.                when Strings.Left =>
  699.                   Source.Data (1 .. Max_Length - 1) :=
  700.                     Source.Data (2 .. Max_Length);
  701.                   Source.Data (Max_Length) := New_Item;
  702.  
  703.                when Strings.Error =>
  704.                   raise Ada.Strings.Length_Error;
  705.             end case;
  706.          end if;
  707.  
  708.       end Append;
  709.  
  710.       --  Case of Wide_Character and Bounded_Wide_String
  711.  
  712.       function Append
  713.         (Left  : in Wide_Character;
  714.          Right : in Bounded_Wide_String;
  715.          Drop  : in Strings.Truncation := Strings.Error)
  716.          return  Bounded_Wide_String
  717.       is
  718.          Result : Bounded_Wide_String;
  719.          Rlen   : constant Length_Range := Right.Length;
  720.  
  721.       begin
  722.          if Rlen < Max_Length then
  723.             Result.Length := Rlen + 1;
  724.             Result.Data (1) := Left;
  725.             Result.Data (2 .. Rlen + 1) := Right.Data (1 .. Rlen);
  726.             return Result;
  727.  
  728.          else
  729.             case Drop is
  730.                when Strings.Right =>
  731.                   Result.Length := Max_Length;
  732.                   Result.Data (1) := Left;
  733.                   Result.Data (2 .. Max_Length) :=
  734.                     Right.Data (1 .. Max_Length - 1);
  735.                   return Result;
  736.  
  737.                when Strings.Left =>
  738.                   return Right;
  739.  
  740.                when Strings.Error =>
  741.                   raise Ada.Strings.Length_Error;
  742.             end case;
  743.          end if;
  744.       end Append;
  745.  
  746.       -----------
  747.       -- Count --
  748.       -----------
  749.  
  750.       function Count
  751.         (Source  : in Bounded_Wide_String;
  752.          Pattern : in Wide_String;
  753.          Mapping : in Wide_Maps.Wide_Character_Mapping := Wide_Maps.Identity)
  754.          return    Natural
  755.       is
  756.       begin
  757.          return
  758.            Wide_Search.Count
  759.              (Source.Data (1 .. Source.Length), Pattern, Mapping);
  760.       end Count;
  761.  
  762.       function Count
  763.         (Source  : in Bounded_Wide_String;
  764.          Pattern : in Wide_String;
  765.          Mapping : in Wide_Maps.Wide_Character_Mapping_Function)
  766.          return    Natural
  767.       is
  768.       begin
  769.          return
  770.            Wide_Search.Count
  771.              (Source.Data (1 .. Source.Length), Pattern, Mapping);
  772.       end Count;
  773.  
  774.       function Count
  775.         (Source : in Bounded_Wide_String;
  776.          Set    : in Wide_Maps.Wide_Character_Set)
  777.          return   Natural
  778.       is
  779.       begin
  780.          return Wide_Search.Count (Source.Data (1 .. Source.Length), Set);
  781.       end Count;
  782.  
  783.       ------------
  784.       -- Delete --
  785.       ------------
  786.  
  787.       function Delete
  788.         (Source  : in Bounded_Wide_String;
  789.          From    : in Positive;
  790.          Through : in Natural)
  791.          return    Bounded_Wide_String
  792.       is
  793.          Slen       : constant Natural := Source.Length;
  794.          Num_Delete : constant Integer := Through - From + 1;
  795.          Result     : Bounded_Wide_String;
  796.  
  797.       begin
  798.          if Num_Delete <= 0 then
  799.             return Source;
  800.  
  801.          elsif From > Slen + 1 then
  802.             raise Ada.Strings.Index_Error;
  803.  
  804.          elsif Through >= Slen then
  805.             Result.Length := From - 1;
  806.             Result.Data (1 .. From - 1) := Source.Data (1 .. From - 1);
  807.             return Result;
  808.  
  809.          else
  810.             Result.Length := Slen - Num_Delete;
  811.             Result.Data (1 .. From - 1) := Source.Data (1 .. From - 1);
  812.             Result.Data (From .. Result.Length) :=
  813.               Source.Data (Through + 1 .. Slen);
  814.             return Result;
  815.          end if;
  816.       end Delete;
  817.  
  818.       procedure Delete
  819.         (Source  : in out Bounded_Wide_String;
  820.          From    : in Positive;
  821.          Through : in Natural)
  822.       is
  823.          Slen       : constant Natural := Source.Length;
  824.          Num_Delete : constant Integer := Through - From + 1;
  825.  
  826.       begin
  827.          if Num_Delete <= 0 then
  828.             return;
  829.  
  830.          elsif From > Slen + 1 then
  831.             raise Ada.Strings.Index_Error;
  832.  
  833.          elsif Through >= Slen then
  834.             Source.Length := From - 1;
  835.  
  836.          else
  837.             Source.Length := Slen - Num_Delete;
  838.             Source.Data (From .. Source.Length) :=
  839.               Source.Data (Through + 1 .. Slen);
  840.          end if;
  841.       end Delete;
  842.  
  843.       -------------
  844.       -- Element --
  845.       -------------
  846.  
  847.       function Element
  848.         (Source : in Bounded_Wide_String;
  849.          Index  : in Positive)
  850.          return   Wide_Character
  851.       is
  852.       begin
  853.          if Index in 1 .. Source.Length then
  854.             return Source.Data (Index);
  855.          else
  856.             raise Strings.Index_Error;
  857.          end if;
  858.       end Element;
  859.  
  860.       ----------------
  861.       -- Find_Token --
  862.       ----------------
  863.  
  864.       procedure Find_Token
  865.         (Source : in Bounded_Wide_String;
  866.          Set    : in Wide_Maps.Wide_Character_Set;
  867.          Test   : in Strings.Membership;
  868.          First  : out Positive;
  869.          Last   : out Natural)
  870.       is
  871.       begin
  872.          Wide_Search.Find_Token
  873.            (Source.Data (1 .. Source.Length), Set, Test, First, Last);
  874.       end Find_Token;
  875.  
  876.  
  877.       ----------
  878.       -- Head --
  879.       ----------
  880.  
  881.       function Head
  882.         (Source : in Bounded_Wide_String;
  883.          Count  : in Natural;
  884.          Pad    : in Wide_Character := Wide_Space;
  885.          Drop   : in Strings.Truncation := Strings.Error)
  886.          return   Bounded_Wide_String
  887.       is
  888.          Result : Bounded_Wide_String;
  889.          Slen   : constant Natural := Source.Length;
  890.          Npad   : constant Integer := Count - Slen;
  891.  
  892.       begin
  893.          if Npad <= 0 then
  894.             Result.Length := Count;
  895.             Result.Data (1 .. Count) := Source.Data (1 .. Count);
  896.  
  897.          elsif Count <= Max_Length then
  898.             Result.Length := Count;
  899.             Result.Data (1 .. Slen) := Source.Data (1 .. Slen);
  900.             Result.Data (Slen + 1 .. Count) := (others => Pad);
  901.  
  902.          else
  903.             Result.Length := Max_Length;
  904.  
  905.             case Drop is
  906.                when Strings.Right =>
  907.                   Result.Data (1 .. Slen) := Source.Data (1 .. Slen);
  908.                   Result.Data (Slen + 1 .. Max_Length) := (others => Pad);
  909.  
  910.                when Strings.Left =>
  911.                   if Npad >= Max_Length then
  912.                      Result.Data := (others => Pad);
  913.  
  914.                   else
  915.                      Result.Data (1 .. Max_Length - Npad) :=
  916.                        Source.Data (Count - Max_Length + 1 .. Slen);
  917.                      Result.Data (Max_Length - Npad + 1 .. Max_Length) :=
  918.                        (others => Pad);
  919.                   end if;
  920.  
  921.                when Strings.Error =>
  922.                   raise Ada.Strings.Length_Error;
  923.             end case;
  924.          end if;
  925.  
  926.          return Result;
  927.       end Head;
  928.  
  929.       procedure Head
  930.         (Source : in out Bounded_Wide_String;
  931.          Count  : in Natural;
  932.          Pad    : in Wide_Character  := Wide_Space;
  933.          Drop   : in Truncation := Error)
  934.       is
  935.          Slen   : constant Natural := Source.Length;
  936.          Npad   : constant Integer := Count - Slen;
  937.          Temp   : Wide_String (1 .. Max_Length);
  938.  
  939.       begin
  940.          if Npad <= 0 then
  941.             Source.Length := Count;
  942.  
  943.          elsif Count <= Max_Length then
  944.             Source.Length := Count;
  945.             Source.Data (Slen + 1 .. Count) := (others => Pad);
  946.  
  947.          else
  948.             Source.Length := Max_Length;
  949.  
  950.             case Drop is
  951.                when Strings.Right =>
  952.                   Source.Data (Slen + 1 .. Max_Length) := (others => Pad);
  953.  
  954.                when Strings.Left =>
  955.                   if Npad > Max_Length then
  956.                      Source.Data := (others => Pad);
  957.  
  958.                   else
  959.                      Temp := Source.Data;
  960.                      Source.Data (1 .. Max_Length - Npad) :=
  961.                        Temp (Count - Max_Length + 1 .. Slen);
  962.  
  963.                      for J in Max_Length - Npad + 1 .. Max_Length loop
  964.                         Source.Data (J) := Pad;
  965.                      end loop;
  966.                   end if;
  967.  
  968.                when Strings.Error =>
  969.                   raise Ada.Strings.Length_Error;
  970.             end case;
  971.          end if;
  972.  
  973.       end Head;
  974.  
  975.       -----------
  976.       -- Index --
  977.       -----------
  978.  
  979.       function Index
  980.         (Source  : in Bounded_Wide_String;
  981.          Pattern : in Wide_String;
  982.          Going   : in Strings.Direction := Strings.Forward;
  983.          Mapping : in Wide_Maps.Wide_Character_Mapping := Wide_Maps.Identity)
  984.          return    Natural
  985.       is
  986.       begin
  987.          return Wide_Search.Index
  988.            (Source.Data (1 .. Source.Length), Pattern, Going, Mapping);
  989.       end Index;
  990.  
  991.       function Index
  992.         (Source  : in Bounded_Wide_String;
  993.          Pattern : in Wide_String;
  994.          Going   : in Direction := Forward;
  995.          Mapping : in Wide_Maps.Wide_Character_Mapping_Function)
  996.          return    Natural
  997.       is
  998.       begin
  999.          return Wide_Search.Index
  1000.            (Source.Data (1 .. Source.Length), Pattern, Going, Mapping);
  1001.       end Index;
  1002.  
  1003.       function Index
  1004.         (Source : in Bounded_Wide_String;
  1005.          Set    : in Wide_Maps.Wide_Character_Set;
  1006.          Test   : in Strings.Membership := Strings.Inside;
  1007.          Going  : in Strings.Direction  := Strings.Forward)
  1008.          return   Natural
  1009.       is
  1010.       begin
  1011.          return Wide_Search.Index
  1012.            (Source.Data (1 .. Source.Length), Set, Test, Going);
  1013.       end Index;
  1014.  
  1015.       ---------------------
  1016.       -- Index_Non_Blank --
  1017.       ---------------------
  1018.  
  1019.       function Index_Non_Blank
  1020.         (Source : in Bounded_Wide_String;
  1021.          Going  : in Strings.Direction := Strings.Forward)
  1022.          return   Natural
  1023.       is
  1024.       begin
  1025.          return
  1026.            Wide_Search.Index_Non_Blank
  1027.              (Source.Data (1 .. Source.Length), Going);
  1028.       end Index_Non_Blank;
  1029.  
  1030.       ------------
  1031.       -- Insert --
  1032.       ------------
  1033.  
  1034.       function Insert
  1035.         (Source   : in Bounded_Wide_String;
  1036.          Before   : in Positive;
  1037.          New_Item : in Wide_String;
  1038.          Drop     : in Strings.Truncation := Strings.Error)
  1039.          return     Bounded_Wide_String
  1040.       is
  1041.          Slen    : constant Natural := Source.Length;
  1042.          Nlen    : constant Natural := New_Item'Length;
  1043.          Tlen    : constant Natural := Slen + Nlen;
  1044.          Blen    : constant Natural := Before - 1;
  1045.          Alen    : constant Integer := Slen - Blen;
  1046.          Droplen : constant Integer := Tlen - Max_Length;
  1047.          Result  : Bounded_Wide_String;
  1048.  
  1049.          --  Tlen is the length of the total string before possible truncation.
  1050.          --  Blen, Alen are the lengths of the before and after pieces of the
  1051.          --  source string.
  1052.  
  1053.       begin
  1054.          if Alen < 0 then
  1055.             raise Ada.Strings.Index_Error;
  1056.  
  1057.          elsif Droplen <= 0 then
  1058.             Result.Length := Tlen;
  1059.             Result.Data (1 .. Blen) := Source.Data (1 .. Blen);
  1060.             Result.Data (Before .. Before + Nlen - 1) := New_Item;
  1061.             Result.Data (Before + Nlen .. Tlen) :=
  1062.               Source.Data (Before .. Slen);
  1063.  
  1064.          else
  1065.             Result.Length := Max_Length;
  1066.  
  1067.             case Drop is
  1068.                when Strings.Right =>
  1069.                   Result.Data (1 .. Blen) := Source.Data (1 .. Blen);
  1070.  
  1071.                   if Droplen > Alen then
  1072.                      Result.Data (Before .. Max_Length) :=
  1073.                        New_Item (New_Item'First
  1074.                                    .. New_Item'First + Max_Length - Before);
  1075.                   else
  1076.                      Result.Data (Before .. Before + Nlen - 1) := New_Item;
  1077.                      Result.Data (Before + Nlen .. Max_Length) :=
  1078.                        Source.Data (Before .. Slen - Droplen);
  1079.                   end if;
  1080.  
  1081.                when Strings.Left =>
  1082.                   Result.Data (Max_Length - (Alen - 1) .. Max_Length) :=
  1083.                     Source.Data (Before .. Slen);
  1084.  
  1085.                   if Droplen >= Blen then
  1086.                      Result.Data (1 .. Max_Length - Alen) :=
  1087.                        New_Item (New_Item'Last - (Max_Length - Alen) + 1
  1088.                                    .. New_Item'Last);
  1089.                   else
  1090.                      Result.Data
  1091.                        (Blen - Droplen + 1 .. Max_Length - Alen) :=
  1092.                          New_Item;
  1093.                      Result.Data (1 .. Blen - Droplen) :=
  1094.                        Source.Data (Droplen + 1 .. Blen);
  1095.                   end if;
  1096.  
  1097.                when Strings.Error =>
  1098.                   raise Ada.Strings.Length_Error;
  1099.             end case;
  1100.          end if;
  1101.  
  1102.          return Result;
  1103.       end Insert;
  1104.  
  1105.       procedure Insert
  1106.         (Source   : in out Bounded_Wide_String;
  1107.          Before   : in Positive;
  1108.          New_Item : in Wide_String;
  1109.          Drop     : in Strings.Truncation := Strings.Error)
  1110.       is
  1111.       begin
  1112.          --  We do a double copy here because this is one of the situations
  1113.          --  in which we move data to the right, and at least at the moment,
  1114.          --  GNAT is not handling such cases correctly ???
  1115.  
  1116.          Source := Insert (Source, Before, New_Item, Drop);
  1117.       end Insert;
  1118.  
  1119.       ------------
  1120.       -- Length --
  1121.       ------------
  1122.  
  1123.       function Length (Source : in Bounded_Wide_String) return Length_Range is
  1124.       begin
  1125.          return Source.Length;
  1126.       end Length;
  1127.  
  1128.       ---------------
  1129.       -- Overwrite --
  1130.       ---------------
  1131.  
  1132.       function Overwrite
  1133.         (Source    : in Bounded_Wide_String;
  1134.          Position  : in Positive;
  1135.          New_Item  : in Wide_String;
  1136.          Drop      : in Strings.Truncation := Strings.Error)
  1137.          return      Bounded_Wide_String
  1138.       is
  1139.          Result  : Bounded_Wide_String;
  1140.          Endpos  : constant Natural  := Position + New_Item'Length - 1;
  1141.          Slen    : constant Natural  := Source.Length;
  1142.          Droplen : Natural;
  1143.  
  1144.       begin
  1145.          if Position > Slen + 1 then
  1146.             raise Ada.Strings.Index_Error;
  1147.  
  1148.          elsif New_Item'Length = 0 then
  1149.             return Source;
  1150.  
  1151.          elsif Endpos <= Slen then
  1152.             Result.Length := Source.Length;
  1153.             Result.Data (1 .. Slen) := Source.Data (1 .. Slen);
  1154.             Result.Data (Position .. Endpos) := New_Item;
  1155.             return Result;
  1156.  
  1157.          elsif Endpos <= Max_Length then
  1158.             Result.Length := Endpos;
  1159.             Result.Data (1 .. Position - 1) := Source.Data (1 .. Position - 1);
  1160.             Result.Data (Position .. Endpos) := New_Item;
  1161.             return Result;
  1162.  
  1163.          else
  1164.             Result.Length := Max_Length;
  1165.             Droplen := Endpos - Max_Length;
  1166.  
  1167.             case Drop is
  1168.                when Strings.Right =>
  1169.                   Result.Data (1 .. Position - 1) :=
  1170.                     Source.Data (1 .. Position - 1);
  1171.  
  1172.                   Result.Data (Position .. Max_Length) :=
  1173.                     New_Item (New_Item'First .. New_Item'Last - Droplen);
  1174.                   return Result;
  1175.  
  1176.                when Strings.Left =>
  1177.                   if New_Item'Length >= Max_Length then
  1178.                      Result.Data (1 .. Max_Length) :=
  1179.                         New_Item (New_Item'Last - Max_Length + 1 ..
  1180.                                   New_Item'Last);
  1181.                      return Result;
  1182.  
  1183.                   else
  1184.                      Result.Data (1 .. Max_Length - New_Item'Length) :=
  1185.                        Source.Data (Droplen + 1 .. Position - 1);
  1186.                      Result.Data
  1187.                        (Max_Length - New_Item'Length + 1 .. Max_Length) :=
  1188.                          New_Item;
  1189.                      return Result;
  1190.                   end if;
  1191.  
  1192.                when Strings.Error =>
  1193.                   raise Ada.Strings.Length_Error;
  1194.             end case;
  1195.          end if;
  1196.       end Overwrite;
  1197.  
  1198.       procedure Overwrite
  1199.         (Source    : in out Bounded_Wide_String;
  1200.          Position  : in Positive;
  1201.          New_Item  : in Wide_String;
  1202.          Drop      : in Strings.Truncation := Strings.Error)
  1203.       is
  1204.          Endpos  : constant Positive := Position + New_Item'Length - 1;
  1205.          Slen    : constant Natural  := Source.Length;
  1206.          Droplen : Natural;
  1207.  
  1208.       begin
  1209.          if Position > Slen + 1 then
  1210.             raise Ada.Strings.Index_Error;
  1211.  
  1212.          elsif Endpos <= Slen then
  1213.             Source.Data (Position .. Endpos) := New_Item;
  1214.  
  1215.          elsif Endpos <= Max_Length then
  1216.             Source.Data (Position .. Endpos) := New_Item;
  1217.             Source.Length := Endpos;
  1218.  
  1219.          else
  1220.             Source.Length := Max_Length;
  1221.             Droplen := Endpos - Max_Length;
  1222.  
  1223.             case Drop is
  1224.                when Strings.Right =>
  1225.                   Source.Data (Position .. Max_Length) :=
  1226.                     New_Item (New_Item'First .. New_Item'Last - Droplen);
  1227.  
  1228.                when Strings.Left =>
  1229.                   if New_Item'Length > Max_Length then
  1230.                      Source.Data (1 .. Max_Length) :=
  1231.                         New_Item (New_Item'Last - Max_Length + 1 ..
  1232.                                   New_Item'Last);
  1233.  
  1234.                   else
  1235.                      Source.Data (1 .. Max_Length - New_Item'Length) :=
  1236.                        Source.Data (Droplen + 1 .. Position - 1);
  1237.  
  1238.                      Source.Data
  1239.                        (Max_Length - New_Item'Length + 1 .. Max_Length) :=
  1240.                          New_Item;
  1241.                   end if;
  1242.  
  1243.                when Strings.Error =>
  1244.                   raise Ada.Strings.Length_Error;
  1245.             end case;
  1246.          end if;
  1247.       end Overwrite;
  1248.  
  1249.       ---------------------
  1250.       -- Replace_Element --
  1251.       ---------------------
  1252.  
  1253.       procedure Replace_Element
  1254.         (Source : in out Bounded_Wide_String;
  1255.          Index  : in Positive;
  1256.          By     : in Wide_Character)
  1257.       is
  1258.       begin
  1259.          if Index <= Source.Length then
  1260.             Source.Data (Index) := By;
  1261.          else
  1262.             raise Ada.Strings.Index_Error;
  1263.          end if;
  1264.       end Replace_Element;
  1265.  
  1266.       -------------------
  1267.       -- Replace_Slice --
  1268.       -------------------
  1269.  
  1270.       function Replace_Slice
  1271.         (Source   : in Bounded_Wide_String;
  1272.          Low      : in Positive;
  1273.          High     : in Natural;
  1274.          By       : in Wide_String;
  1275.          Drop     : in Strings.Truncation := Strings.Error)
  1276.          return     Bounded_Wide_String
  1277.       is
  1278.          Slen : constant Natural := Source.Length;
  1279.  
  1280.       begin
  1281.          if Low > Slen + 1 then
  1282.             raise Strings.Index_Error;
  1283.  
  1284.          elsif High < Low then
  1285.             return Insert (Source, Low, By, Drop);
  1286.  
  1287.          else
  1288.             declare
  1289.                Blen    : constant Natural := Natural'Max (0, Low - 1);
  1290.                Alen    : constant Natural := Natural'Max (0, Slen - High);
  1291.                Tlen    : constant Natural := Blen + By'Length + Alen;
  1292.                Droplen : constant Integer := Tlen - Max_Length;
  1293.                Result  : Bounded_Wide_String;
  1294.  
  1295.                --  Tlen is the total length of the result string before any
  1296.                --  truncation. Blen and Alen are the lengths of the pieces
  1297.                --  of the original string that end up in the result string
  1298.                --  before and after the replaced slice.
  1299.  
  1300.             begin
  1301.                if Droplen <= 0 then
  1302.                   Result.Length := Tlen;
  1303.                   Result.Data (1 .. Blen) := Source.Data (1 .. Blen);
  1304.                   Result.Data (Low .. Low + By'Length - 1) := By;
  1305.                   Result.Data (Low + By'Length .. Tlen) :=
  1306.                     Source.Data (High + 1 .. Slen);
  1307.  
  1308.                else
  1309.                   Result.Length := Max_Length;
  1310.  
  1311.                   case Drop is
  1312.                      when Strings.Right =>
  1313.                         Result.Data (1 .. Blen) := Source.Data (1 .. Blen);
  1314.  
  1315.                         if Droplen > Alen then
  1316.                            Result.Data (Low .. Max_Length) :=
  1317.                              By (By'First .. By'First + Max_Length - Low);
  1318.                         else
  1319.                            Result.Data (Low .. Low + By'Length - 1) := By;
  1320.                            Result.Data (Low + By'Length .. Max_Length) :=
  1321.                              Source.Data (High + 1 .. Slen - Droplen);
  1322.                         end if;
  1323.  
  1324.                      when Strings.Left =>
  1325.                         Result.Data (Max_Length - (Alen - 1) .. Max_Length) :=
  1326.                           Source.Data (High + 1 .. Slen);
  1327.  
  1328.                         if Droplen >= Blen then
  1329.                            Result.Data (1 .. Max_Length - Alen) :=
  1330.                              By (By'Last - (Max_Length - Alen) + 1 .. By'Last);
  1331.                         else
  1332.                            Result.Data
  1333.                              (Blen - Droplen + 1 .. Max_Length - Alen) := By;
  1334.                            Result.Data (1 .. Blen - Droplen) :=
  1335.                              Source.Data (Droplen + 1 .. Blen);
  1336.                         end if;
  1337.  
  1338.                      when Strings.Error =>
  1339.                         raise Ada.Strings.Length_Error;
  1340.                   end case;
  1341.                end if;
  1342.  
  1343.                return Result;
  1344.             end;
  1345.          end if;
  1346.       end Replace_Slice;
  1347.  
  1348.       procedure Replace_Slice
  1349.         (Source   : in out Bounded_Wide_String;
  1350.          Low      : in Positive;
  1351.          High     : in Natural;
  1352.          By       : in Wide_String;
  1353.          Drop     : in Strings.Truncation := Strings.Error)
  1354.       is
  1355.       begin
  1356.          --  We do a double copy here because this is one of the situations
  1357.          --  in which we move data to the right, and at least at the moment,
  1358.          --  GNAT is not handling such cases correctly ???
  1359.  
  1360.          Source := Replace_Slice (Source, Low, High, By, Drop);
  1361.       end Replace_Slice;
  1362.  
  1363.       ---------------
  1364.       -- Replicate --
  1365.       ---------------
  1366.  
  1367.       function Replicate
  1368.         (Count : in Natural;
  1369.          Item  : in Wide_Character;
  1370.          Drop  : in Strings.Truncation := Strings.Error)
  1371.          return  Bounded_Wide_String
  1372.       is
  1373.          Result : Bounded_Wide_String;
  1374.  
  1375.       begin
  1376.          if Count <= Max_Length then
  1377.             Result.Length := Count;
  1378.  
  1379.          elsif Drop = Strings.Error then
  1380.             raise Ada.Strings.Length_Error;
  1381.  
  1382.          else
  1383.             Result.Length := Max_Length;
  1384.          end if;
  1385.  
  1386.          Result.Data (1 .. Result.Length) := (others => Item);
  1387.          return Result;
  1388.       end Replicate;
  1389.  
  1390.       function Replicate
  1391.         (Count : in Natural;
  1392.          Item  : in Wide_String;
  1393.          Drop  : in Strings.Truncation := Strings.Error)
  1394.          return  Bounded_Wide_String
  1395.       is
  1396.          Length : constant Integer := Count * Item'Length;
  1397.          Result : Bounded_Wide_String;
  1398.          Indx   : Positive;
  1399.  
  1400.       begin
  1401.          if Length <= Max_Length then
  1402.             Result.Length := Length;
  1403.  
  1404.             if Length > 0 then
  1405.                Indx := 1;
  1406.  
  1407.                for J in 1 .. Count loop
  1408.                   Result.Data (Indx .. Indx + Item'Length - 1) := Item;
  1409.                   Indx := Indx + Item'Length;
  1410.                end loop;
  1411.             end if;
  1412.  
  1413.          else
  1414.             Result.Length := Max_Length;
  1415.  
  1416.             case Drop is
  1417.                when Strings.Right =>
  1418.                   Indx := 1;
  1419.  
  1420.                   while Indx + Item'Length <= Max_Length + 1 loop
  1421.                      Result.Data (Indx .. Indx + Item'Length - 1) := Item;
  1422.                      Indx := Indx + Item'Length;
  1423.                   end loop;
  1424.  
  1425.                   Result.Data (Indx .. Max_Length) :=
  1426.                     Item (Item'First .. Item'First + Max_Length - Indx);
  1427.  
  1428.                when Strings.Left =>
  1429.                   Indx := Max_Length;
  1430.  
  1431.                   while Indx - Item'Length >= 1 loop
  1432.                      Result.Data (Indx - (Item'Length - 1) .. Indx) := Item;
  1433.                      Indx := Indx - Item'Length;
  1434.                   end loop;
  1435.  
  1436.                   Result.Data (1 .. Indx) :=
  1437.                     Item (Item'Last - Indx + 1 .. Item'Last);
  1438.  
  1439.                when Strings.Error =>
  1440.                   raise Ada.Strings.Length_Error;
  1441.             end case;
  1442.          end if;
  1443.  
  1444.          return Result;
  1445.       end Replicate;
  1446.  
  1447.       function Replicate
  1448.         (Count : in Natural;
  1449.          Item  : in Bounded_Wide_String;
  1450.          Drop  : in Strings.Truncation := Strings.Error)
  1451.          return  Bounded_Wide_String
  1452.       is
  1453.       begin
  1454.          return Replicate (Count, Item.Data (1 .. Item.Length), Drop);
  1455.       end Replicate;
  1456.  
  1457.       -----------
  1458.       -- Slice --
  1459.       -----------
  1460.  
  1461.       function Slice
  1462.         (Source : Bounded_Wide_String;
  1463.          Low    : Positive;
  1464.          High   : Natural)
  1465.          return   Wide_String
  1466.       is
  1467.       begin
  1468.          --  Note: test of High > Length is in accordance with AI95-00128
  1469.  
  1470.          if Low > Source.Length + 1 or else High > Source.Length then
  1471.             raise Index_Error;
  1472.  
  1473.          else
  1474.             declare
  1475.                Result : Wide_String (1 .. High - Low + 1);
  1476.  
  1477.             begin
  1478.                Result := Source.Data (Low .. High);
  1479.                return Result;
  1480.             end;
  1481.          end if;
  1482.       end Slice;
  1483.  
  1484.       ----------
  1485.       -- Tail --
  1486.       ----------
  1487.  
  1488.       function Tail
  1489.         (Source : in Bounded_Wide_String;
  1490.          Count  : in Natural;
  1491.          Pad    : in Wide_Character := Wide_Space;
  1492.          Drop   : in Strings.Truncation := Strings.Error)
  1493.          return   Bounded_Wide_String
  1494.       is
  1495.          Result : Bounded_Wide_String;
  1496.          Slen   : constant Natural := Source.Length;
  1497.          Npad   : constant Integer := Count - Slen;
  1498.  
  1499.       begin
  1500.          if Npad <= 0 then
  1501.             Result.Length := Count;
  1502.             Result.Data (1 .. Count) :=
  1503.               Source.Data (Slen - (Count - 1) .. Slen);
  1504.  
  1505.          elsif Count <= Max_Length then
  1506.             Result.Length := Count;
  1507.             Result.Data (1 .. Npad) := (others => Pad);
  1508.             Result.Data (Npad + 1 .. Count) := Source.Data (1 .. Slen);
  1509.  
  1510.          else
  1511.             Result.Length := Max_Length;
  1512.  
  1513.             case Drop is
  1514.                when Strings.Right =>
  1515.                   if Npad >= Max_Length then
  1516.                      Result.Data := (others => Pad);
  1517.  
  1518.                   else
  1519.                      Result.Data (1 .. Npad) := (others => Pad);
  1520.                      Result.Data (Npad + 1 .. Max_Length) :=
  1521.                        Source.Data (1 .. Max_Length - Npad);
  1522.                   end if;
  1523.  
  1524.                when Strings.Left =>
  1525.                   Result.Data (1 .. Max_Length - Slen) := (others => Pad);
  1526.                   Result.Data (Max_Length - Slen + 1 .. Max_Length) :=
  1527.                     Source.Data (1 .. Slen);
  1528.  
  1529.                when Strings.Error =>
  1530.                   raise Ada.Strings.Length_Error;
  1531.             end case;
  1532.          end if;
  1533.  
  1534.          return Result;
  1535.       end Tail;
  1536.  
  1537.       procedure Tail
  1538.         (Source : in out Bounded_Wide_String;
  1539.          Count  : in Natural;
  1540.          Pad    : in Wide_Character  := Wide_Space;
  1541.          Drop   : in Truncation := Error)
  1542.       is
  1543.          Slen   : constant Natural := Source.Length;
  1544.          Npad   : constant Integer := Count - Slen;
  1545.          Temp   : Wide_String (1 .. Max_Length) := Source.Data;
  1546.  
  1547.       begin
  1548.          if Npad <= 0 then
  1549.             Source.Length := Count;
  1550.             Source.Data (1 .. Count) :=
  1551.               Temp (Slen - (Count - 1) .. Slen);
  1552.  
  1553.          elsif Count <= Max_Length then
  1554.             Source.Length := Count;
  1555.             Source.Data (1 .. Npad) := (others => Pad);
  1556.             Source.Data (Npad + 1 .. Count) := Temp (1 .. Slen);
  1557.  
  1558.          else
  1559.             Source.Length := Max_Length;
  1560.  
  1561.             case Drop is
  1562.                when Strings.Right =>
  1563.                   if Npad >= Max_Length then
  1564.                      Source.Data := (others => Pad);
  1565.  
  1566.                   else
  1567.                      Source.Data (1 .. Npad) := (others => Pad);
  1568.                      Source.Data (Npad + 1 .. Max_Length) :=
  1569.                        Temp (1 .. Max_Length - Npad);
  1570.                   end if;
  1571.  
  1572.                when Strings.Left =>
  1573.                   for J in 1 .. Max_Length - Slen loop
  1574.                      Source.Data (J) := Pad;
  1575.                   end loop;
  1576.  
  1577.                   Source.Data (Max_Length - Slen + 1 .. Max_Length) :=
  1578.                     Temp (1 .. Slen);
  1579.  
  1580.                when Strings.Error =>
  1581.                   raise Ada.Strings.Length_Error;
  1582.             end case;
  1583.          end if;
  1584.  
  1585.       end Tail;
  1586.  
  1587.       ----------------------------
  1588.       -- To_Bounded_Wide_String --
  1589.       ----------------------------
  1590.  
  1591.       function To_Bounded_Wide_String
  1592.         (Source : in Wide_String;
  1593.          Drop   : in Strings.Truncation := Strings.Error)
  1594.          return   Bounded_Wide_String
  1595.       is
  1596.          Slen   : constant Natural := Source'Length;
  1597.          Result : Bounded_Wide_String;
  1598.  
  1599.       begin
  1600.          if Slen <= Max_Length then
  1601.             Result.Length := Slen;
  1602.             Result.Data (1 .. Slen) := Source;
  1603.  
  1604.          else
  1605.             case Drop is
  1606.                when Strings.Right =>
  1607.                   Result.Length := Max_Length;
  1608.                   Result.Data (1 .. Max_Length) :=
  1609.                     Source (Source'First .. Source'First - 1 + Max_Length);
  1610.  
  1611.                when Strings.Left =>
  1612.                   Result.Length := Max_Length;
  1613.                   Result.Data (1 .. Max_Length) :=
  1614.                     Source (Source'Last - (Max_Length - 1) .. Source'Last);
  1615.  
  1616.                when Strings.Error =>
  1617.                   raise Ada.Strings.Length_Error;
  1618.             end case;
  1619.          end if;
  1620.  
  1621.          return Result;
  1622.       end To_Bounded_Wide_String;
  1623.  
  1624.       --------------------
  1625.       -- To_Wide_String --
  1626.       --------------------
  1627.  
  1628.       function To_Wide_String
  1629.         (Source : in Bounded_Wide_String)
  1630.          return   Wide_String
  1631.       is
  1632.       begin
  1633.          return Source.Data (1 .. Source.Length);
  1634.       end To_Wide_String;
  1635.  
  1636.       ---------------
  1637.       -- Translate --
  1638.       ---------------
  1639.  
  1640.       function Translate
  1641.         (Source  : in Bounded_Wide_String;
  1642.          Mapping : in Wide_Maps.Wide_Character_Mapping)
  1643.          return    Bounded_Wide_String
  1644.       is
  1645.          Result : Bounded_Wide_String;
  1646.  
  1647.       begin
  1648.          Result.Length := Source.Length;
  1649.  
  1650.          for J in 1 .. Source.Length loop
  1651.             Result.Data (J) := Value (Mapping, Source.Data (J));
  1652.          end loop;
  1653.  
  1654.          return Result;
  1655.       end Translate;
  1656.  
  1657.       procedure Translate
  1658.         (Source   : in out Bounded_Wide_String;
  1659.          Mapping  : in Wide_Maps.Wide_Character_Mapping)
  1660.       is
  1661.       begin
  1662.          for J in 1 .. Source.Length loop
  1663.             Source.Data (J) := Value (Mapping, Source.Data (J));
  1664.          end loop;
  1665.       end Translate;
  1666.  
  1667.       function Translate
  1668.         (Source  : in Bounded_Wide_String;
  1669.          Mapping : in Wide_Maps.Wide_Character_Mapping_Function)
  1670.          return    Bounded_Wide_String
  1671.       is
  1672.          Result : Bounded_Wide_String;
  1673.  
  1674.       begin
  1675.          Result.Length := Source.Length;
  1676.  
  1677.          for J in 1 .. Source.Length loop
  1678.             Result.Data (J) := Mapping.all (Source.Data (J));
  1679.          end loop;
  1680.  
  1681.          return Result;
  1682.       end Translate;
  1683.  
  1684.       procedure Translate
  1685.         (Source  : in out Bounded_Wide_String;
  1686.          Mapping : in Wide_Maps.Wide_Character_Mapping_Function)
  1687.       is
  1688.       begin
  1689.          for J in 1 .. Source.Length loop
  1690.             Source.Data (J) := Mapping.all (Source.Data (J));
  1691.          end loop;
  1692.       end Translate;
  1693.  
  1694.       ----------
  1695.       -- Trim --
  1696.       ----------
  1697.  
  1698.       function Trim
  1699.         (Source : in Bounded_Wide_String;
  1700.          Side   : in Trim_End)
  1701.          return   Bounded_Wide_String
  1702.       is
  1703.          Result : Bounded_Wide_String;
  1704.          Last   : Natural := Source.Length;
  1705.          First  : Positive := 1;
  1706.  
  1707.       begin
  1708.          if Side = Left or else Side = Both then
  1709.             while First <= Last and then Source.Data (First) = ' ' loop
  1710.                First := First + 1;
  1711.             end loop;
  1712.          end if;
  1713.  
  1714.          if Side = Right or else Side = Both then
  1715.             while Last >= First and then Source.Data (Last) = ' ' loop
  1716.                Last := Last - 1;
  1717.             end loop;
  1718.          end if;
  1719.  
  1720.          Result.Length := Last - First + 1;
  1721.          Result.Data (1 .. Result.Length) := Source.Data (First .. Last);
  1722.          return Result;
  1723.  
  1724.       end Trim;
  1725.  
  1726.       procedure Trim
  1727.         (Source : in out Bounded_Wide_String;
  1728.          Side   : in Trim_End)
  1729.       is
  1730.          Last   : Length_Range := Source.Length;
  1731.          First  : Positive     := 1;
  1732.          Temp   : Wide_String (1 .. Max_Length);
  1733.  
  1734.       begin
  1735.          Temp (1 .. Last) := Source.Data (1 .. Last);
  1736.  
  1737.          if Side = Left or else Side = Both then
  1738.             while First <= Last and then Temp (First) = ' ' loop
  1739.                First := First + 1;
  1740.             end loop;
  1741.          end if;
  1742.  
  1743.          if Side = Right or else Side = Both then
  1744.             while Last >= First and then Temp (Last) = ' ' loop
  1745.                Last := Last - 1;
  1746.             end loop;
  1747.          end if;
  1748.  
  1749.          Source.Length := Last - First + 1;
  1750.          Source.Data (1 .. Source.Length) := Temp (First .. Last);
  1751.  
  1752.       end Trim;
  1753.  
  1754.       function Trim
  1755.         (Source : in Bounded_Wide_String;
  1756.          Left   : in Wide_Maps.Wide_Character_Set;
  1757.          Right  : in Wide_Maps.Wide_Character_Set)
  1758.          return   Bounded_Wide_String
  1759.       is
  1760.          Result : Bounded_Wide_String;
  1761.  
  1762.       begin
  1763.          for First in 1 .. Source.Length loop
  1764.             if not Is_In (Source.Data (First), Left) then
  1765.                for Last in reverse First .. Source.Length loop
  1766.                   if not Is_In (Source.Data (Last), Right) then
  1767.                      Result.Length := Last - First + 1;
  1768.                      Result.Data (1 .. Result.Length) :=
  1769.                         Source.Data (First .. Last);
  1770.                      return Result;
  1771.                   end if;
  1772.                end loop;
  1773.             end if;
  1774.          end loop;
  1775.  
  1776.          Result.Length := 0;
  1777.          return Result;
  1778.       end Trim;
  1779.  
  1780.       procedure Trim
  1781.         (Source : in out Bounded_Wide_String;
  1782.          Left   : in Wide_Maps.Wide_Character_Set;
  1783.          Right  : in Wide_Maps.Wide_Character_Set)
  1784.       is
  1785.       begin
  1786.          for First in 1 .. Source.Length loop
  1787.             if not Is_In (Source.Data (First), Left) then
  1788.                for Last in reverse First .. Source.Length loop
  1789.                   if not Is_In (Source.Data (Last), Right) then
  1790.                      if First = 1 then
  1791.                         Source.Length := Last;
  1792.                         return;
  1793.                      else
  1794.                         Source.Length := Last - First + 1;
  1795.                         Source.Data (1 .. Source.Length) :=
  1796.                           Source.Data (First .. Last);
  1797.                         return;
  1798.                      end if;
  1799.                   end if;
  1800.                end loop;
  1801.  
  1802.                Source.Length := 0;
  1803.                return;
  1804.             end if;
  1805.          end loop;
  1806.  
  1807.          Source.Length := 0;
  1808.       end Trim;
  1809.  
  1810.    end Generic_Bounded_Length;
  1811.  
  1812. end Ada.Strings.Wide_Bounded;
  1813.