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