1 ------------------------------------------------------------------------------
3 -- GNAT RUNTIME COMPONENTS --
5 -- A D A . S T R I N G S . B O U N D E D --
10 -- Copyright (C) 1992-2001 Free Software Foundation, Inc. --
12 -- GNAT is free software; you can redistribute it and/or modify it under --
13 -- terms of the GNU General Public License as published by the Free Soft- --
14 -- ware Foundation; either version 2, or (at your option) any later ver- --
15 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
16 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
17 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
18 -- for more details. You should have received a copy of the GNU General --
19 -- Public License distributed with GNAT; see file COPYING. If not, write --
20 -- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
21 -- MA 02111-1307, USA. --
23 -- As a special exception, if other files instantiate generics from this --
24 -- unit, or you link this unit with other files to produce an executable, --
25 -- this unit does not by itself cause the resulting executable to be --
26 -- covered by the GNU General Public License. This exception does not --
27 -- however invalidate any other reasons why the executable file might be --
28 -- covered by the GNU Public License. --
30 -- GNAT was originally developed by the GNAT team at New York University. --
31 -- It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). --
33 ------------------------------------------------------------------------------
35 with Ada.Strings.Maps; use Ada.Strings.Maps;
36 with Ada.Strings.Search;
38 package body Ada.Strings.Bounded is
40 package body Generic_Bounded_Length is
47 (Left : in Bounded_String;
48 Right : in Bounded_String)
51 Result : Bounded_String;
52 Llen : constant Length_Range := Left.Length;
53 Rlen : constant Length_Range := Right.Length;
54 Nlen : constant Natural := Llen + Rlen;
57 if Nlen > Max_Length then
58 raise Ada.Strings.Length_Error;
60 Result.Length := Nlen;
61 Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
62 Result.Data (Llen + 1 .. Nlen) := Right.Data (1 .. Rlen);
69 (Left : in Bounded_String;
73 Result : Bounded_String;
74 Llen : constant Length_Range := Left.Length;
76 Nlen : constant Natural := Llen + Right'Length;
79 if Nlen > Max_Length then
80 raise Ada.Strings.Length_Error;
82 Result.Length := Nlen;
83 Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
84 Result.Data (Llen + 1 .. Nlen) := Right;
91 Right : in Bounded_String)
94 Result : Bounded_String;
95 Llen : constant Length_Range := Left'Length;
96 Rlen : constant Length_Range := Right.Length;
97 Nlen : constant Natural := Llen + Rlen;
100 if Nlen > Max_Length then
101 raise Ada.Strings.Length_Error;
103 Result.Length := Nlen;
104 Result.Data (1 .. Llen) := Left;
105 Result.Data (Llen + 1 .. Nlen) := Right.Data (1 .. Rlen);
112 (Left : in Bounded_String;
113 Right : in Character)
114 return Bounded_String
116 Result : Bounded_String;
117 Llen : constant Length_Range := Left.Length;
120 if Llen = Max_Length then
121 raise Ada.Strings.Length_Error;
123 Result.Length := Llen + 1;
124 Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
125 Result.Data (Result.Length) := Right;
132 (Left : in Character;
133 Right : in Bounded_String)
134 return Bounded_String
136 Result : Bounded_String;
137 Rlen : Length_Range := Right.Length;
140 if Rlen = Max_Length then
141 raise Ada.Strings.Length_Error;
143 Result.Length := Rlen + 1;
144 Result.Data (1) := Left;
145 Result.Data (2 .. Result.Length) := Right.Data (1 .. Rlen);
157 Right : in Character)
158 return Bounded_String
160 Result : Bounded_String;
163 if Left > Max_Length then
164 raise Ada.Strings.Length_Error;
166 Result.Length := Left;
168 for J in 1 .. Left loop
169 Result.Data (J) := Right;
179 return Bounded_String
181 Result : Bounded_String;
183 Rlen : constant Natural := Right'Length;
184 Nlen : constant Natural := Left * Rlen;
187 if Nlen > Max_Length then
188 raise Ada.Strings.Index_Error;
190 Result.Length := Nlen;
193 for J in 1 .. Left loop
194 Result.Data (Pos .. Pos + Rlen - 1) := Right;
205 Right : in Bounded_String)
206 return Bounded_String
208 Result : Bounded_String;
210 Rlen : constant Length_Range := Right.Length;
211 Nlen : constant Natural := Left * Rlen;
214 if Nlen > Max_Length then
215 raise Ada.Strings.Length_Error;
218 Result.Length := Nlen;
221 for J in 1 .. Left loop
222 Result.Data (Pos .. Pos + Rlen - 1) :=
223 Right.Data (1 .. Rlen);
236 function "<" (Left, Right : in Bounded_String) return Boolean is
238 return Left.Data (1 .. Left.Length) < Right.Data (1 .. Right.Length);
242 (Left : in Bounded_String;
247 return Left.Data (1 .. Left.Length) < Right;
252 Right : in Bounded_String)
256 return Left < Right.Data (1 .. Right.Length);
263 function "<=" (Left, Right : in Bounded_String) return Boolean is
265 return Left.Data (1 .. Left.Length) <= Right.Data (1 .. Right.Length);
269 (Left : in Bounded_String;
274 return Left.Data (1 .. Left.Length) <= Right;
279 Right : in Bounded_String)
283 return Left <= Right.Data (1 .. Right.Length);
290 function "=" (Left, Right : in Bounded_String) return Boolean is
292 return Left.Length = Right.Length
293 and then Left.Data (1 .. Left.Length) =
294 Right.Data (1 .. Right.Length);
297 function "=" (Left : in Bounded_String; Right : in String)
300 return Left.Length = Right'Length
301 and then Left.Data (1 .. Left.Length) = Right;
304 function "=" (Left : in String; Right : in Bounded_String)
307 return Left'Length = Right.Length
308 and then Left = Right.Data (1 .. Right.Length);
315 function ">" (Left, Right : in Bounded_String) return Boolean is
317 return Left.Data (1 .. Left.Length) > Right.Data (1 .. Right.Length);
321 (Left : in Bounded_String;
326 return Left.Data (1 .. Left.Length) > Right;
331 Right : in Bounded_String)
335 return Left > Right.Data (1 .. Right.Length);
342 function ">=" (Left, Right : in Bounded_String) return Boolean is
344 return Left.Data (1 .. Left.Length) >= Right.Data (1 .. Right.Length);
348 (Left : in Bounded_String;
353 return Left.Data (1 .. Left.Length) >= Right;
358 Right : in Bounded_String)
362 return Left >= Right.Data (1 .. Right.Length);
369 -- Case of Bounded_String and Bounded_String
372 (Left, Right : in Bounded_String;
373 Drop : in Strings.Truncation := Strings.Error)
374 return Bounded_String
376 Result : Bounded_String;
377 Llen : constant Length_Range := Left.Length;
378 Rlen : constant Length_Range := Right.Length;
379 Nlen : constant Natural := Llen + Rlen;
382 if Nlen <= Max_Length then
383 Result.Length := Nlen;
384 Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
385 Result.Data (Llen + 1 .. Nlen) := Right.Data (1 .. Rlen);
388 Result.Length := Max_Length;
391 when Strings.Right =>
392 if Llen >= Max_Length then -- only case is Llen = Max_Length
393 Result.Data := Left.Data;
396 Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
397 Result.Data (Llen + 1 .. Max_Length) :=
398 Right.Data (1 .. Max_Length - Llen);
402 if Rlen >= Max_Length then -- only case is Rlen = Max_Length
403 Result.Data := Right.Data;
406 Result.Data (1 .. Max_Length - Rlen) :=
407 Left.Data (Llen - (Max_Length - Rlen - 1) .. Llen);
408 Result.Data (Max_Length - Rlen + 1 .. Max_Length) :=
409 Right.Data (1 .. Rlen);
412 when Strings.Error =>
413 raise Ada.Strings.Length_Error;
421 (Source : in out Bounded_String;
422 New_Item : in Bounded_String;
423 Drop : in Truncation := Error)
425 Llen : constant Length_Range := Source.Length;
426 Rlen : constant Length_Range := New_Item.Length;
427 Nlen : constant Natural := Llen + Rlen;
430 if Nlen <= Max_Length then
431 Source.Length := Nlen;
432 Source.Data (Llen + 1 .. Nlen) := New_Item.Data (1 .. Rlen);
435 Source.Length := Max_Length;
438 when Strings.Right =>
439 if Llen < Max_Length then
440 Source.Data (Llen + 1 .. Max_Length) :=
441 New_Item.Data (1 .. Max_Length - Llen);
445 if Rlen >= Max_Length then -- only case is Rlen = Max_Length
446 Source.Data := New_Item.Data;
449 Source.Data (1 .. Max_Length - Rlen) :=
450 Source.Data (Llen - (Max_Length - Rlen - 1) .. Llen);
451 Source.Data (Max_Length - Rlen + 1 .. Max_Length) :=
452 New_Item.Data (1 .. Rlen);
455 when Strings.Error =>
456 raise Ada.Strings.Length_Error;
462 -- Case of Bounded_String and String
465 (Left : in Bounded_String;
467 Drop : in Strings.Truncation := Strings.Error)
468 return Bounded_String
470 Result : Bounded_String;
471 Llen : constant Length_Range := Left.Length;
472 Rlen : constant Length_Range := Right'Length;
473 Nlen : constant Natural := Llen + Rlen;
476 if Nlen <= Max_Length then
477 Result.Length := Nlen;
478 Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
479 Result.Data (Llen + 1 .. Nlen) := Right;
482 Result.Length := Max_Length;
485 when Strings.Right =>
486 if Llen >= Max_Length then -- only case is Llen = Max_Length
487 Result.Data := Left.Data;
490 Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
491 Result.Data (Llen + 1 .. Max_Length) :=
492 Right (Right'First .. Right'First - 1 +
498 if Rlen >= Max_Length then
499 Result.Data (1 .. Max_Length) :=
500 Right (Right'Last - (Max_Length - 1) .. Right'Last);
503 Result.Data (1 .. Max_Length - Rlen) :=
504 Left.Data (Llen - (Max_Length - Rlen - 1) .. Llen);
505 Result.Data (Max_Length - Rlen + 1 .. Max_Length) :=
509 when Strings.Error =>
510 raise Ada.Strings.Length_Error;
518 (Source : in out Bounded_String;
519 New_Item : in String;
520 Drop : in Truncation := Error)
522 Llen : constant Length_Range := Source.Length;
523 Rlen : constant Length_Range := New_Item'Length;
524 Nlen : constant Natural := Llen + Rlen;
527 if Nlen <= Max_Length then
528 Source.Length := Nlen;
529 Source.Data (Llen + 1 .. Nlen) := New_Item;
532 Source.Length := Max_Length;
535 when Strings.Right =>
536 if Llen < Max_Length then
537 Source.Data (Llen + 1 .. Max_Length) :=
538 New_Item (New_Item'First ..
539 New_Item'First - 1 + Max_Length - Llen);
543 if Rlen >= Max_Length then
544 Source.Data (1 .. Max_Length) :=
545 New_Item (New_Item'Last - (Max_Length - 1) ..
549 Source.Data (1 .. Max_Length - Rlen) :=
550 Source.Data (Llen - (Max_Length - Rlen - 1) .. Llen);
551 Source.Data (Max_Length - Rlen + 1 .. Max_Length) :=
555 when Strings.Error =>
556 raise Ada.Strings.Length_Error;
562 -- Case of String and Bounded_String
566 Right : in Bounded_String;
567 Drop : in Strings.Truncation := Strings.Error)
568 return Bounded_String
570 Result : Bounded_String;
571 Llen : constant Length_Range := Left'Length;
572 Rlen : constant Length_Range := Right.Length;
573 Nlen : constant Natural := Llen + Rlen;
576 if Nlen <= Max_Length then
577 Result.Length := Nlen;
578 Result.Data (1 .. Llen) := Left;
579 Result.Data (Llen + 1 .. Llen + Rlen) := Right.Data (1 .. Rlen);
582 Result.Length := Max_Length;
585 when Strings.Right =>
586 if Llen >= Max_Length then
587 Result.Data (1 .. Max_Length) :=
588 Left (Left'First .. Left'First + (Max_Length - 1));
591 Result.Data (1 .. Llen) := Left;
592 Result.Data (Llen + 1 .. Max_Length) :=
593 Right.Data (1 .. Max_Length - Llen);
597 if Rlen >= Max_Length then
598 Result.Data (1 .. Max_Length) :=
599 Right.Data (Rlen - (Max_Length - 1) .. Rlen);
602 Result.Data (1 .. Max_Length - Rlen) :=
603 Left (Left'Last - (Max_Length - Rlen - 1) .. Left'Last);
604 Result.Data (Max_Length - Rlen + 1 .. Max_Length) :=
605 Right.Data (1 .. Rlen);
608 when Strings.Error =>
609 raise Ada.Strings.Length_Error;
616 -- Case of Bounded_String and Character
619 (Left : in Bounded_String;
620 Right : in Character;
621 Drop : in Strings.Truncation := Strings.Error)
622 return Bounded_String
624 Result : Bounded_String;
625 Llen : constant Length_Range := Left.Length;
628 if Llen < Max_Length then
629 Result.Length := Llen + 1;
630 Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
631 Result.Data (Llen + 1) := Right;
636 when Strings.Right =>
640 Result.Length := Max_Length;
641 Result.Data (1 .. Max_Length - 1) :=
642 Left.Data (2 .. Max_Length);
643 Result.Data (Max_Length) := Right;
646 when Strings.Error =>
647 raise Ada.Strings.Length_Error;
653 (Source : in out Bounded_String;
654 New_Item : in Character;
655 Drop : in Truncation := Error)
657 Llen : constant Length_Range := Source.Length;
660 if Llen < Max_Length then
661 Source.Length := Llen + 1;
662 Source.Data (Llen + 1) := New_Item;
665 Source.Length := Max_Length;
668 when Strings.Right =>
672 Source.Data (1 .. Max_Length - 1) :=
673 Source.Data (2 .. Max_Length);
674 Source.Data (Max_Length) := New_Item;
676 when Strings.Error =>
677 raise Ada.Strings.Length_Error;
683 -- Case of Character and Bounded_String
686 (Left : in Character;
687 Right : in Bounded_String;
688 Drop : in Strings.Truncation := Strings.Error)
689 return Bounded_String
691 Result : Bounded_String;
692 Rlen : constant Length_Range := Right.Length;
695 if Rlen < Max_Length then
696 Result.Length := Rlen + 1;
697 Result.Data (1) := Left;
698 Result.Data (2 .. Rlen + 1) := Right.Data (1 .. Rlen);
703 when Strings.Right =>
704 Result.Length := Max_Length;
705 Result.Data (1) := Left;
706 Result.Data (2 .. Max_Length) :=
707 Right.Data (1 .. Max_Length - 1);
713 when Strings.Error =>
714 raise Ada.Strings.Length_Error;
724 (Source : in Bounded_String;
726 Mapping : in Maps.Character_Mapping := Maps.Identity)
731 Search.Count (Source.Data (1 .. Source.Length), Pattern, Mapping);
735 (Source : in Bounded_String;
737 Mapping : in Maps.Character_Mapping_Function)
742 Search.Count (Source.Data (1 .. Source.Length), Pattern, Mapping);
746 (Source : in Bounded_String;
747 Set : in Maps.Character_Set)
751 return Search.Count (Source.Data (1 .. Source.Length), Set);
759 (Source : in Bounded_String;
761 Through : in Natural)
762 return Bounded_String
764 Slen : constant Natural := Source.Length;
765 Num_Delete : constant Integer := Through - From + 1;
766 Result : Bounded_String;
769 if Num_Delete <= 0 then
772 elsif From > Slen + 1 then
773 raise Ada.Strings.Index_Error;
775 elsif Through >= Slen then
776 Result.Length := From - 1;
777 Result.Data (1 .. From - 1) := Source.Data (1 .. From - 1);
781 Result.Length := Slen - Num_Delete;
782 Result.Data (1 .. From - 1) := Source.Data (1 .. From - 1);
783 Result.Data (From .. Result.Length) :=
784 Source.Data (Through + 1 .. Slen);
790 (Source : in out Bounded_String;
792 Through : in Natural)
794 Slen : constant Natural := Source.Length;
795 Num_Delete : constant Integer := Through - From + 1;
798 if Num_Delete <= 0 then
801 elsif From > Slen + 1 then
802 raise Ada.Strings.Index_Error;
804 elsif Through >= Slen then
805 Source.Length := From - 1;
808 Source.Length := Slen - Num_Delete;
809 Source.Data (From .. Source.Length) :=
810 Source.Data (Through + 1 .. Slen);
819 (Source : in Bounded_String;
824 if Index in 1 .. Source.Length then
825 return Source.Data (Index);
827 raise Strings.Index_Error;
836 (Source : in Bounded_String;
837 Set : in Maps.Character_Set;
838 Test : in Strings.Membership;
839 First : out Positive;
844 (Source.Data (1 .. Source.Length), Set, Test, First, Last);
853 (Source : in Bounded_String;
855 Pad : in Character := Space;
856 Drop : in Strings.Truncation := Strings.Error)
857 return Bounded_String
859 Result : Bounded_String;
860 Slen : constant Natural := Source.Length;
861 Npad : constant Integer := Count - Slen;
865 Result.Length := Count;
866 Result.Data (1 .. Count) := Source.Data (1 .. Count);
868 elsif Count <= Max_Length then
869 Result.Length := Count;
870 Result.Data (1 .. Slen) := Source.Data (1 .. Slen);
871 Result.Data (Slen + 1 .. Count) := (others => Pad);
874 Result.Length := Max_Length;
877 when Strings.Right =>
878 Result.Data (1 .. Slen) := Source.Data (1 .. Slen);
879 Result.Data (Slen + 1 .. Max_Length) := (others => Pad);
882 if Npad >= Max_Length then
883 Result.Data := (others => Pad);
886 Result.Data (1 .. Max_Length - Npad) :=
887 Source.Data (Count - Max_Length + 1 .. Slen);
888 Result.Data (Max_Length - Npad + 1 .. Max_Length) :=
892 when Strings.Error =>
893 raise Ada.Strings.Length_Error;
901 (Source : in out Bounded_String;
903 Pad : in Character := Space;
904 Drop : in Truncation := Error)
906 Slen : constant Natural := Source.Length;
907 Npad : constant Integer := Count - Slen;
908 Temp : String (1 .. Max_Length);
912 Source.Length := Count;
914 elsif Count <= Max_Length then
915 Source.Length := Count;
916 Source.Data (Slen + 1 .. Count) := (others => Pad);
919 Source.Length := Max_Length;
922 when Strings.Right =>
923 Source.Data (Slen + 1 .. Max_Length) := (others => Pad);
926 if Npad > Max_Length then
927 Source.Data := (others => Pad);
931 Source.Data (1 .. Max_Length - Npad) :=
932 Temp (Count - Max_Length + 1 .. Slen);
934 for J in Max_Length - Npad + 1 .. Max_Length loop
935 Source.Data (J) := Pad;
939 when Strings.Error =>
940 raise Ada.Strings.Length_Error;
951 (Source : in Bounded_String;
953 Going : in Strings.Direction := Strings.Forward;
954 Mapping : in Maps.Character_Mapping := Maps.Identity)
959 (Source.Data (1 .. Source.Length), Pattern, Going, Mapping);
963 (Source : in Bounded_String;
965 Going : in Direction := Forward;
966 Mapping : in Maps.Character_Mapping_Function)
971 (Source.Data (1 .. Source.Length), Pattern, Going, Mapping);
975 (Source : in Bounded_String;
976 Set : in Maps.Character_Set;
977 Test : in Strings.Membership := Strings.Inside;
978 Going : in Strings.Direction := Strings.Forward)
983 (Source.Data (1 .. Source.Length), Set, Test, Going);
986 ---------------------
987 -- Index_Non_Blank --
988 ---------------------
990 function Index_Non_Blank
991 (Source : in Bounded_String;
992 Going : in Strings.Direction := Strings.Forward)
997 Search.Index_Non_Blank (Source.Data (1 .. Source.Length), Going);
1005 (Source : in Bounded_String;
1006 Before : in Positive;
1007 New_Item : in String;
1008 Drop : in Strings.Truncation := Strings.Error)
1009 return Bounded_String
1011 Slen : constant Natural := Source.Length;
1012 Nlen : constant Natural := New_Item'Length;
1013 Tlen : constant Natural := Slen + Nlen;
1014 Blen : constant Natural := Before - 1;
1015 Alen : constant Integer := Slen - Blen;
1016 Droplen : constant Integer := Tlen - Max_Length;
1017 Result : Bounded_String;
1019 -- Tlen is the length of the total string before possible truncation.
1020 -- Blen, Alen are the lengths of the before and after pieces of the
1025 raise Ada.Strings.Index_Error;
1027 elsif Droplen <= 0 then
1028 Result.Length := Tlen;
1029 Result.Data (1 .. Blen) := Source.Data (1 .. Blen);
1030 Result.Data (Before .. Before + Nlen - 1) := New_Item;
1031 Result.Data (Before + Nlen .. Tlen) :=
1032 Source.Data (Before .. Slen);
1035 Result.Length := Max_Length;
1038 when Strings.Right =>
1039 Result.Data (1 .. Blen) := Source.Data (1 .. Blen);
1041 if Droplen > Alen then
1042 Result.Data (Before .. Max_Length) :=
1043 New_Item (New_Item'First
1044 .. New_Item'First + Max_Length - Before);
1046 Result.Data (Before .. Before + Nlen - 1) := New_Item;
1047 Result.Data (Before + Nlen .. Max_Length) :=
1048 Source.Data (Before .. Slen - Droplen);
1051 when Strings.Left =>
1052 Result.Data (Max_Length - (Alen - 1) .. Max_Length) :=
1053 Source.Data (Before .. Slen);
1055 if Droplen >= Blen then
1056 Result.Data (1 .. Max_Length - Alen) :=
1057 New_Item (New_Item'Last - (Max_Length - Alen) + 1
1061 (Blen - Droplen + 1 .. Max_Length - Alen) :=
1063 Result.Data (1 .. Blen - Droplen) :=
1064 Source.Data (Droplen + 1 .. Blen);
1067 when Strings.Error =>
1068 raise Ada.Strings.Length_Error;
1076 (Source : in out Bounded_String;
1077 Before : in Positive;
1078 New_Item : in String;
1079 Drop : in Strings.Truncation := Strings.Error)
1082 -- We do a double copy here because this is one of the situations
1083 -- in which we move data to the right, and at least at the moment,
1084 -- GNAT is not handling such cases correctly ???
1086 Source := Insert (Source, Before, New_Item, Drop);
1093 function Length (Source : in Bounded_String) return Length_Range is
1095 return Source.Length;
1103 (Source : in Bounded_String;
1104 Position : in Positive;
1105 New_Item : in String;
1106 Drop : in Strings.Truncation := Strings.Error)
1107 return Bounded_String
1109 Result : Bounded_String;
1110 Endpos : constant Natural := Position + New_Item'Length - 1;
1111 Slen : constant Natural := Source.Length;
1115 if Position > Slen + 1 then
1116 raise Ada.Strings.Index_Error;
1118 elsif New_Item'Length = 0 then
1121 elsif Endpos <= Slen then
1122 Result.Length := Source.Length;
1123 Result.Data (1 .. Slen) := Source.Data (1 .. Slen);
1124 Result.Data (Position .. Endpos) := New_Item;
1127 elsif Endpos <= Max_Length then
1128 Result.Length := Endpos;
1129 Result.Data (1 .. Position - 1) := Source.Data (1 .. Position - 1);
1130 Result.Data (Position .. Endpos) := New_Item;
1134 Result.Length := Max_Length;
1135 Droplen := Endpos - Max_Length;
1138 when Strings.Right =>
1139 Result.Data (1 .. Position - 1) :=
1140 Source.Data (1 .. Position - 1);
1142 Result.Data (Position .. Max_Length) :=
1143 New_Item (New_Item'First .. New_Item'Last - Droplen);
1146 when Strings.Left =>
1147 if New_Item'Length >= Max_Length then
1148 Result.Data (1 .. Max_Length) :=
1149 New_Item (New_Item'Last - Max_Length + 1 ..
1154 Result.Data (1 .. Max_Length - New_Item'Length) :=
1155 Source.Data (Droplen + 1 .. Position - 1);
1157 (Max_Length - New_Item'Length + 1 .. Max_Length) :=
1162 when Strings.Error =>
1163 raise Ada.Strings.Length_Error;
1169 (Source : in out Bounded_String;
1170 Position : in Positive;
1171 New_Item : in String;
1172 Drop : in Strings.Truncation := Strings.Error)
1174 Endpos : constant Positive := Position + New_Item'Length - 1;
1175 Slen : constant Natural := Source.Length;
1179 if Position > Slen + 1 then
1180 raise Ada.Strings.Index_Error;
1182 elsif Endpos <= Slen then
1183 Source.Data (Position .. Endpos) := New_Item;
1185 elsif Endpos <= Max_Length then
1186 Source.Data (Position .. Endpos) := New_Item;
1187 Source.Length := Endpos;
1190 Source.Length := Max_Length;
1191 Droplen := Endpos - Max_Length;
1194 when Strings.Right =>
1195 Source.Data (Position .. Max_Length) :=
1196 New_Item (New_Item'First .. New_Item'Last - Droplen);
1198 when Strings.Left =>
1199 if New_Item'Length > Max_Length then
1200 Source.Data (1 .. Max_Length) :=
1201 New_Item (New_Item'Last - Max_Length + 1 ..
1205 Source.Data (1 .. Max_Length - New_Item'Length) :=
1206 Source.Data (Droplen + 1 .. Position - 1);
1209 (Max_Length - New_Item'Length + 1 .. Max_Length) :=
1213 when Strings.Error =>
1214 raise Ada.Strings.Length_Error;
1219 ---------------------
1220 -- Replace_Element --
1221 ---------------------
1223 procedure Replace_Element
1224 (Source : in out Bounded_String;
1225 Index : in Positive;
1229 if Index <= Source.Length then
1230 Source.Data (Index) := By;
1232 raise Ada.Strings.Index_Error;
1234 end Replace_Element;
1240 function Replace_Slice
1241 (Source : in Bounded_String;
1245 Drop : in Strings.Truncation := Strings.Error)
1246 return Bounded_String
1248 Slen : constant Natural := Source.Length;
1251 if Low > Slen + 1 then
1252 raise Strings.Index_Error;
1254 elsif High < Low then
1255 return Insert (Source, Low, By, Drop);
1259 Blen : constant Natural := Natural'Max (0, Low - 1);
1260 Alen : constant Natural := Natural'Max (0, Slen - High);
1261 Tlen : constant Natural := Blen + By'Length + Alen;
1262 Droplen : constant Integer := Tlen - Max_Length;
1263 Result : Bounded_String;
1265 -- Tlen is the total length of the result string before any
1266 -- truncation. Blen and Alen are the lengths of the pieces
1267 -- of the original string that end up in the result string
1268 -- before and after the replaced slice.
1271 if Droplen <= 0 then
1272 Result.Length := Tlen;
1273 Result.Data (1 .. Blen) := Source.Data (1 .. Blen);
1274 Result.Data (Low .. Low + By'Length - 1) := By;
1275 Result.Data (Low + By'Length .. Tlen) :=
1276 Source.Data (High + 1 .. Slen);
1279 Result.Length := Max_Length;
1282 when Strings.Right =>
1283 Result.Data (1 .. Blen) := Source.Data (1 .. Blen);
1285 if Droplen > Alen then
1286 Result.Data (Low .. Max_Length) :=
1287 By (By'First .. By'First + Max_Length - Low);
1289 Result.Data (Low .. Low + By'Length - 1) := By;
1290 Result.Data (Low + By'Length .. Max_Length) :=
1291 Source.Data (High + 1 .. Slen - Droplen);
1294 when Strings.Left =>
1295 Result.Data (Max_Length - (Alen - 1) .. Max_Length) :=
1296 Source.Data (High + 1 .. Slen);
1298 if Droplen >= Blen then
1299 Result.Data (1 .. Max_Length - Alen) :=
1300 By (By'Last - (Max_Length - Alen) + 1 .. By'Last);
1303 (Blen - Droplen + 1 .. Max_Length - Alen) := By;
1304 Result.Data (1 .. Blen - Droplen) :=
1305 Source.Data (Droplen + 1 .. Blen);
1308 when Strings.Error =>
1309 raise Ada.Strings.Length_Error;
1318 procedure Replace_Slice
1319 (Source : in out Bounded_String;
1323 Drop : in Strings.Truncation := Strings.Error)
1326 -- We do a double copy here because this is one of the situations
1327 -- in which we move data to the right, and at least at the moment,
1328 -- GNAT is not handling such cases correctly ???
1330 Source := Replace_Slice (Source, Low, High, By, Drop);
1338 (Count : in Natural;
1339 Item : in Character;
1340 Drop : in Strings.Truncation := Strings.Error)
1341 return Bounded_String
1343 Result : Bounded_String;
1346 if Count <= Max_Length then
1347 Result.Length := Count;
1349 elsif Drop = Strings.Error then
1350 raise Ada.Strings.Length_Error;
1353 Result.Length := Max_Length;
1356 Result.Data (1 .. Result.Length) := (others => Item);
1361 (Count : in Natural;
1363 Drop : in Strings.Truncation := Strings.Error)
1364 return Bounded_String
1366 Length : constant Integer := Count * Item'Length;
1367 Result : Bounded_String;
1371 if Length <= Max_Length then
1372 Result.Length := Length;
1377 for J in 1 .. Count loop
1378 Result.Data (Indx .. Indx + Item'Length - 1) := Item;
1379 Indx := Indx + Item'Length;
1384 Result.Length := Max_Length;
1387 when Strings.Right =>
1390 while Indx + Item'Length <= Max_Length + 1 loop
1391 Result.Data (Indx .. Indx + Item'Length - 1) := Item;
1392 Indx := Indx + Item'Length;
1395 Result.Data (Indx .. Max_Length) :=
1396 Item (Item'First .. Item'First + Max_Length - Indx);
1398 when Strings.Left =>
1401 while Indx - Item'Length >= 1 loop
1402 Result.Data (Indx - (Item'Length - 1) .. Indx) := Item;
1403 Indx := Indx - Item'Length;
1406 Result.Data (1 .. Indx) :=
1407 Item (Item'Last - Indx + 1 .. Item'Last);
1409 when Strings.Error =>
1410 raise Ada.Strings.Length_Error;
1418 (Count : in Natural;
1419 Item : in Bounded_String;
1420 Drop : in Strings.Truncation := Strings.Error)
1421 return Bounded_String
1424 return Replicate (Count, Item.Data (1 .. Item.Length), Drop);
1432 (Source : Bounded_String;
1438 -- Note: test of High > Length is in accordance with AI95-00128
1440 if Low > Source.Length + 1 or else High > Source.Length then
1443 return Source.Data (Low .. High);
1452 (Source : in Bounded_String;
1454 Pad : in Character := Space;
1455 Drop : in Strings.Truncation := Strings.Error)
1456 return Bounded_String
1458 Result : Bounded_String;
1459 Slen : constant Natural := Source.Length;
1460 Npad : constant Integer := Count - Slen;
1464 Result.Length := Count;
1465 Result.Data (1 .. Count) :=
1466 Source.Data (Slen - (Count - 1) .. Slen);
1468 elsif Count <= Max_Length then
1469 Result.Length := Count;
1470 Result.Data (1 .. Npad) := (others => Pad);
1471 Result.Data (Npad + 1 .. Count) := Source.Data (1 .. Slen);
1474 Result.Length := Max_Length;
1477 when Strings.Right =>
1478 if Npad >= Max_Length then
1479 Result.Data := (others => Pad);
1482 Result.Data (1 .. Npad) := (others => Pad);
1483 Result.Data (Npad + 1 .. Max_Length) :=
1484 Source.Data (1 .. Max_Length - Npad);
1487 when Strings.Left =>
1488 Result.Data (1 .. Max_Length - Slen) := (others => Pad);
1489 Result.Data (Max_Length - Slen + 1 .. Max_Length) :=
1490 Source.Data (1 .. Slen);
1492 when Strings.Error =>
1493 raise Ada.Strings.Length_Error;
1501 (Source : in out Bounded_String;
1503 Pad : in Character := Space;
1504 Drop : in Truncation := Error)
1506 Slen : constant Natural := Source.Length;
1507 Npad : constant Integer := Count - Slen;
1508 Temp : String (1 .. Max_Length) := Source.Data;
1512 Source.Length := Count;
1513 Source.Data (1 .. Count) :=
1514 Temp (Slen - (Count - 1) .. Slen);
1516 elsif Count <= Max_Length then
1517 Source.Length := Count;
1518 Source.Data (1 .. Npad) := (others => Pad);
1519 Source.Data (Npad + 1 .. Count) := Temp (1 .. Slen);
1522 Source.Length := Max_Length;
1525 when Strings.Right =>
1526 if Npad >= Max_Length then
1527 Source.Data := (others => Pad);
1530 Source.Data (1 .. Npad) := (others => Pad);
1531 Source.Data (Npad + 1 .. Max_Length) :=
1532 Temp (1 .. Max_Length - Npad);
1535 when Strings.Left =>
1536 for J in 1 .. Max_Length - Slen loop
1537 Source.Data (J) := Pad;
1540 Source.Data (Max_Length - Slen + 1 .. Max_Length) :=
1543 when Strings.Error =>
1544 raise Ada.Strings.Length_Error;
1550 -----------------------
1551 -- To_Bounded_String --
1552 -----------------------
1554 function To_Bounded_String
1555 (Source : in String;
1556 Drop : in Strings.Truncation := Strings.Error)
1557 return Bounded_String
1559 Slen : constant Natural := Source'Length;
1560 Result : Bounded_String;
1563 if Slen <= Max_Length then
1564 Result.Length := Slen;
1565 Result.Data (1 .. Slen) := Source;
1569 when Strings.Right =>
1570 Result.Length := Max_Length;
1571 Result.Data (1 .. Max_Length) :=
1572 Source (Source'First .. Source'First - 1 + Max_Length);
1574 when Strings.Left =>
1575 Result.Length := Max_Length;
1576 Result.Data (1 .. Max_Length) :=
1577 Source (Source'Last - (Max_Length - 1) .. Source'Last);
1579 when Strings.Error =>
1580 raise Ada.Strings.Length_Error;
1585 end To_Bounded_String;
1591 function To_String (Source : in Bounded_String) return String is
1593 return Source.Data (1 .. Source.Length);
1601 (Source : in Bounded_String;
1602 Mapping : in Maps.Character_Mapping)
1603 return Bounded_String
1605 Result : Bounded_String;
1608 Result.Length := Source.Length;
1610 for J in 1 .. Source.Length loop
1611 Result.Data (J) := Value (Mapping, Source.Data (J));
1618 (Source : in out Bounded_String;
1619 Mapping : in Maps.Character_Mapping)
1622 for J in 1 .. Source.Length loop
1623 Source.Data (J) := Value (Mapping, Source.Data (J));
1628 (Source : in Bounded_String;
1629 Mapping : in Maps.Character_Mapping_Function)
1630 return Bounded_String
1632 Result : Bounded_String;
1635 Result.Length := Source.Length;
1637 for J in 1 .. Source.Length loop
1638 Result.Data (J) := Mapping.all (Source.Data (J));
1645 (Source : in out Bounded_String;
1646 Mapping : in Maps.Character_Mapping_Function)
1649 for J in 1 .. Source.Length loop
1650 Source.Data (J) := Mapping.all (Source.Data (J));
1658 function Trim (Source : in Bounded_String; Side : in Trim_End)
1659 return Bounded_String
1661 Result : Bounded_String;
1662 Last : Natural := Source.Length;
1663 First : Positive := 1;
1666 if Side = Left or else Side = Both then
1667 while First <= Last and then Source.Data (First) = ' ' loop
1672 if Side = Right or else Side = Both then
1673 while Last >= First and then Source.Data (Last) = ' ' loop
1678 Result.Length := Last - First + 1;
1679 Result.Data (1 .. Result.Length) := Source.Data (First .. Last);
1685 (Source : in out Bounded_String;
1688 Last : Length_Range := Source.Length;
1689 First : Positive := 1;
1690 Temp : String (1 .. Max_Length);
1693 Temp (1 .. Last) := Source.Data (1 .. Last);
1695 if Side = Left or else Side = Both then
1696 while First <= Last and then Temp (First) = ' ' loop
1701 if Side = Right or else Side = Both then
1702 while Last >= First and then Temp (Last) = ' ' loop
1707 Source := Null_Bounded_String;
1708 Source.Length := Last - First + 1;
1709 Source.Data (1 .. Source.Length) := Temp (First .. Last);
1714 (Source : in Bounded_String;
1715 Left : in Maps.Character_Set;
1716 Right : in Maps.Character_Set)
1717 return Bounded_String
1719 Result : Bounded_String;
1722 for First in 1 .. Source.Length loop
1723 if not Is_In (Source.Data (First), Left) then
1724 for Last in reverse First .. Source.Length loop
1725 if not Is_In (Source.Data (Last), Right) then
1726 Result.Length := Last - First + 1;
1727 Result.Data (1 .. Result.Length) :=
1728 Source.Data (First .. Last);
1740 (Source : in out Bounded_String;
1741 Left : in Maps.Character_Set;
1742 Right : in Maps.Character_Set)
1745 for First in 1 .. Source.Length loop
1746 if not Is_In (Source.Data (First), Left) then
1747 for Last in reverse First .. Source.Length loop
1748 if not Is_In (Source.Data (Last), Right) then
1750 Source.Length := Last;
1753 Source.Length := Last - First + 1;
1754 Source.Data (1 .. Source.Length) :=
1755 Source.Data (First .. Last);
1757 for J in Source.Length + 1 .. Max_Length loop
1758 Source.Data (J) := ASCII.NUL;
1774 end Generic_Bounded_Length;
1776 end Ada.Strings.Bounded;