1 ------------------------------------------------------------------------------
3 -- GNAT RUNTIME COMPONENTS --
5 -- A D A . S T R I N G S . B O U N D E D --
9 -- Copyright (C) 1992-2001 Free Software Foundation, Inc. --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 2, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
17 -- for more details. You should have received a copy of the GNU General --
18 -- Public License distributed with GNAT; see file COPYING. If not, write --
19 -- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
20 -- MA 02111-1307, USA. --
22 -- As a special exception, if other files instantiate generics from this --
23 -- unit, or you link this unit with other files to produce an executable, --
24 -- this unit does not by itself cause the resulting executable to be --
25 -- covered by the GNU General Public License. This exception does not --
26 -- however invalidate any other reasons why the executable file might be --
27 -- covered by the GNU Public License. --
29 -- GNAT was originally developed by the GNAT team at New York University. --
30 -- Extensive contributions were provided by Ada Core Technologies Inc. --
32 ------------------------------------------------------------------------------
34 with Ada.Strings.Maps; use Ada.Strings.Maps;
35 with Ada.Strings.Search;
37 package body Ada.Strings.Bounded is
39 package body Generic_Bounded_Length is
46 (Left : in Bounded_String;
47 Right : in Bounded_String)
50 Result : Bounded_String;
51 Llen : constant Length_Range := Left.Length;
52 Rlen : constant Length_Range := Right.Length;
53 Nlen : constant Natural := Llen + Rlen;
56 if Nlen > Max_Length then
57 raise Ada.Strings.Length_Error;
59 Result.Length := Nlen;
60 Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
61 Result.Data (Llen + 1 .. Nlen) := Right.Data (1 .. Rlen);
68 (Left : in Bounded_String;
72 Result : Bounded_String;
73 Llen : constant Length_Range := Left.Length;
75 Nlen : constant Natural := Llen + Right'Length;
78 if Nlen > Max_Length then
79 raise Ada.Strings.Length_Error;
81 Result.Length := Nlen;
82 Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
83 Result.Data (Llen + 1 .. Nlen) := Right;
90 Right : in Bounded_String)
93 Result : Bounded_String;
94 Llen : constant Length_Range := Left'Length;
95 Rlen : constant Length_Range := Right.Length;
96 Nlen : constant Natural := Llen + Rlen;
99 if Nlen > Max_Length then
100 raise Ada.Strings.Length_Error;
102 Result.Length := Nlen;
103 Result.Data (1 .. Llen) := Left;
104 Result.Data (Llen + 1 .. Nlen) := Right.Data (1 .. Rlen);
111 (Left : in Bounded_String;
112 Right : in Character)
113 return Bounded_String
115 Result : Bounded_String;
116 Llen : constant Length_Range := Left.Length;
119 if Llen = Max_Length then
120 raise Ada.Strings.Length_Error;
122 Result.Length := Llen + 1;
123 Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
124 Result.Data (Result.Length) := Right;
131 (Left : in Character;
132 Right : in Bounded_String)
133 return Bounded_String
135 Result : Bounded_String;
136 Rlen : Length_Range := Right.Length;
139 if Rlen = Max_Length then
140 raise Ada.Strings.Length_Error;
142 Result.Length := Rlen + 1;
143 Result.Data (1) := Left;
144 Result.Data (2 .. Result.Length) := Right.Data (1 .. Rlen);
156 Right : in Character)
157 return Bounded_String
159 Result : Bounded_String;
162 if Left > Max_Length then
163 raise Ada.Strings.Length_Error;
165 Result.Length := Left;
167 for J in 1 .. Left loop
168 Result.Data (J) := Right;
178 return Bounded_String
180 Result : Bounded_String;
182 Rlen : constant Natural := Right'Length;
183 Nlen : constant Natural := Left * Rlen;
186 if Nlen > Max_Length then
187 raise Ada.Strings.Index_Error;
189 Result.Length := Nlen;
192 for J in 1 .. Left loop
193 Result.Data (Pos .. Pos + Rlen - 1) := Right;
204 Right : in Bounded_String)
205 return Bounded_String
207 Result : Bounded_String;
209 Rlen : constant Length_Range := Right.Length;
210 Nlen : constant Natural := Left * Rlen;
213 if Nlen > Max_Length then
214 raise Ada.Strings.Length_Error;
217 Result.Length := Nlen;
220 for J in 1 .. Left loop
221 Result.Data (Pos .. Pos + Rlen - 1) :=
222 Right.Data (1 .. Rlen);
235 function "<" (Left, Right : in Bounded_String) return Boolean is
237 return Left.Data (1 .. Left.Length) < Right.Data (1 .. Right.Length);
241 (Left : in Bounded_String;
246 return Left.Data (1 .. Left.Length) < Right;
251 Right : in Bounded_String)
255 return Left < Right.Data (1 .. Right.Length);
262 function "<=" (Left, Right : in Bounded_String) return Boolean is
264 return Left.Data (1 .. Left.Length) <= Right.Data (1 .. Right.Length);
268 (Left : in Bounded_String;
273 return Left.Data (1 .. Left.Length) <= Right;
278 Right : in Bounded_String)
282 return Left <= Right.Data (1 .. Right.Length);
289 function "=" (Left, Right : in Bounded_String) return Boolean is
291 return Left.Length = Right.Length
292 and then Left.Data (1 .. Left.Length) =
293 Right.Data (1 .. Right.Length);
296 function "=" (Left : in Bounded_String; Right : in String)
299 return Left.Length = Right'Length
300 and then Left.Data (1 .. Left.Length) = Right;
303 function "=" (Left : in String; Right : in Bounded_String)
306 return Left'Length = Right.Length
307 and then Left = Right.Data (1 .. Right.Length);
314 function ">" (Left, Right : in Bounded_String) return Boolean is
316 return Left.Data (1 .. Left.Length) > Right.Data (1 .. Right.Length);
320 (Left : in Bounded_String;
325 return Left.Data (1 .. Left.Length) > Right;
330 Right : in Bounded_String)
334 return Left > Right.Data (1 .. Right.Length);
341 function ">=" (Left, Right : in Bounded_String) return Boolean is
343 return Left.Data (1 .. Left.Length) >= Right.Data (1 .. Right.Length);
347 (Left : in Bounded_String;
352 return Left.Data (1 .. Left.Length) >= Right;
357 Right : in Bounded_String)
361 return Left >= Right.Data (1 .. Right.Length);
368 -- Case of Bounded_String and Bounded_String
371 (Left, Right : in Bounded_String;
372 Drop : in Strings.Truncation := Strings.Error)
373 return Bounded_String
375 Result : Bounded_String;
376 Llen : constant Length_Range := Left.Length;
377 Rlen : constant Length_Range := Right.Length;
378 Nlen : constant Natural := Llen + Rlen;
381 if Nlen <= Max_Length then
382 Result.Length := Nlen;
383 Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
384 Result.Data (Llen + 1 .. Nlen) := Right.Data (1 .. Rlen);
387 Result.Length := Max_Length;
390 when Strings.Right =>
391 if Llen >= Max_Length then -- only case is Llen = Max_Length
392 Result.Data := Left.Data;
395 Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
396 Result.Data (Llen + 1 .. Max_Length) :=
397 Right.Data (1 .. Max_Length - Llen);
401 if Rlen >= Max_Length then -- only case is Rlen = Max_Length
402 Result.Data := Right.Data;
405 Result.Data (1 .. Max_Length - Rlen) :=
406 Left.Data (Llen - (Max_Length - Rlen - 1) .. Llen);
407 Result.Data (Max_Length - Rlen + 1 .. Max_Length) :=
408 Right.Data (1 .. Rlen);
411 when Strings.Error =>
412 raise Ada.Strings.Length_Error;
420 (Source : in out Bounded_String;
421 New_Item : in Bounded_String;
422 Drop : in Truncation := Error)
424 Llen : constant Length_Range := Source.Length;
425 Rlen : constant Length_Range := New_Item.Length;
426 Nlen : constant Natural := Llen + Rlen;
429 if Nlen <= Max_Length then
430 Source.Length := Nlen;
431 Source.Data (Llen + 1 .. Nlen) := New_Item.Data (1 .. Rlen);
434 Source.Length := Max_Length;
437 when Strings.Right =>
438 if Llen < Max_Length then
439 Source.Data (Llen + 1 .. Max_Length) :=
440 New_Item.Data (1 .. Max_Length - Llen);
444 if Rlen >= Max_Length then -- only case is Rlen = Max_Length
445 Source.Data := New_Item.Data;
448 Source.Data (1 .. Max_Length - Rlen) :=
449 Source.Data (Llen - (Max_Length - Rlen - 1) .. Llen);
450 Source.Data (Max_Length - Rlen + 1 .. Max_Length) :=
451 New_Item.Data (1 .. Rlen);
454 when Strings.Error =>
455 raise Ada.Strings.Length_Error;
461 -- Case of Bounded_String and String
464 (Left : in Bounded_String;
466 Drop : in Strings.Truncation := Strings.Error)
467 return Bounded_String
469 Result : Bounded_String;
470 Llen : constant Length_Range := Left.Length;
471 Rlen : constant Length_Range := Right'Length;
472 Nlen : constant Natural := Llen + Rlen;
475 if Nlen <= Max_Length then
476 Result.Length := Nlen;
477 Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
478 Result.Data (Llen + 1 .. Nlen) := Right;
481 Result.Length := Max_Length;
484 when Strings.Right =>
485 if Llen >= Max_Length then -- only case is Llen = Max_Length
486 Result.Data := Left.Data;
489 Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
490 Result.Data (Llen + 1 .. Max_Length) :=
491 Right (Right'First .. Right'First - 1 +
497 if Rlen >= Max_Length then
498 Result.Data (1 .. Max_Length) :=
499 Right (Right'Last - (Max_Length - 1) .. Right'Last);
502 Result.Data (1 .. Max_Length - Rlen) :=
503 Left.Data (Llen - (Max_Length - Rlen - 1) .. Llen);
504 Result.Data (Max_Length - Rlen + 1 .. Max_Length) :=
508 when Strings.Error =>
509 raise Ada.Strings.Length_Error;
517 (Source : in out Bounded_String;
518 New_Item : in String;
519 Drop : in Truncation := Error)
521 Llen : constant Length_Range := Source.Length;
522 Rlen : constant Length_Range := New_Item'Length;
523 Nlen : constant Natural := Llen + Rlen;
526 if Nlen <= Max_Length then
527 Source.Length := Nlen;
528 Source.Data (Llen + 1 .. Nlen) := New_Item;
531 Source.Length := Max_Length;
534 when Strings.Right =>
535 if Llen < Max_Length then
536 Source.Data (Llen + 1 .. Max_Length) :=
537 New_Item (New_Item'First ..
538 New_Item'First - 1 + Max_Length - Llen);
542 if Rlen >= Max_Length then
543 Source.Data (1 .. Max_Length) :=
544 New_Item (New_Item'Last - (Max_Length - 1) ..
548 Source.Data (1 .. Max_Length - Rlen) :=
549 Source.Data (Llen - (Max_Length - Rlen - 1) .. Llen);
550 Source.Data (Max_Length - Rlen + 1 .. Max_Length) :=
554 when Strings.Error =>
555 raise Ada.Strings.Length_Error;
561 -- Case of String and Bounded_String
565 Right : in Bounded_String;
566 Drop : in Strings.Truncation := Strings.Error)
567 return Bounded_String
569 Result : Bounded_String;
570 Llen : constant Length_Range := Left'Length;
571 Rlen : constant Length_Range := Right.Length;
572 Nlen : constant Natural := Llen + Rlen;
575 if Nlen <= Max_Length then
576 Result.Length := Nlen;
577 Result.Data (1 .. Llen) := Left;
578 Result.Data (Llen + 1 .. Llen + Rlen) := Right.Data (1 .. Rlen);
581 Result.Length := Max_Length;
584 when Strings.Right =>
585 if Llen >= Max_Length then
586 Result.Data (1 .. Max_Length) :=
587 Left (Left'First .. Left'First + (Max_Length - 1));
590 Result.Data (1 .. Llen) := Left;
591 Result.Data (Llen + 1 .. Max_Length) :=
592 Right.Data (1 .. Max_Length - Llen);
596 if Rlen >= Max_Length then
597 Result.Data (1 .. Max_Length) :=
598 Right.Data (Rlen - (Max_Length - 1) .. Rlen);
601 Result.Data (1 .. Max_Length - Rlen) :=
602 Left (Left'Last - (Max_Length - Rlen - 1) .. Left'Last);
603 Result.Data (Max_Length - Rlen + 1 .. Max_Length) :=
604 Right.Data (1 .. Rlen);
607 when Strings.Error =>
608 raise Ada.Strings.Length_Error;
615 -- Case of Bounded_String and Character
618 (Left : in Bounded_String;
619 Right : in Character;
620 Drop : in Strings.Truncation := Strings.Error)
621 return Bounded_String
623 Result : Bounded_String;
624 Llen : constant Length_Range := Left.Length;
627 if Llen < Max_Length then
628 Result.Length := Llen + 1;
629 Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
630 Result.Data (Llen + 1) := Right;
635 when Strings.Right =>
639 Result.Length := Max_Length;
640 Result.Data (1 .. Max_Length - 1) :=
641 Left.Data (2 .. Max_Length);
642 Result.Data (Max_Length) := Right;
645 when Strings.Error =>
646 raise Ada.Strings.Length_Error;
652 (Source : in out Bounded_String;
653 New_Item : in Character;
654 Drop : in Truncation := Error)
656 Llen : constant Length_Range := Source.Length;
659 if Llen < Max_Length then
660 Source.Length := Llen + 1;
661 Source.Data (Llen + 1) := New_Item;
664 Source.Length := Max_Length;
667 when Strings.Right =>
671 Source.Data (1 .. Max_Length - 1) :=
672 Source.Data (2 .. Max_Length);
673 Source.Data (Max_Length) := New_Item;
675 when Strings.Error =>
676 raise Ada.Strings.Length_Error;
682 -- Case of Character and Bounded_String
685 (Left : in Character;
686 Right : in Bounded_String;
687 Drop : in Strings.Truncation := Strings.Error)
688 return Bounded_String
690 Result : Bounded_String;
691 Rlen : constant Length_Range := Right.Length;
694 if Rlen < Max_Length then
695 Result.Length := Rlen + 1;
696 Result.Data (1) := Left;
697 Result.Data (2 .. Rlen + 1) := Right.Data (1 .. Rlen);
702 when Strings.Right =>
703 Result.Length := Max_Length;
704 Result.Data (1) := Left;
705 Result.Data (2 .. Max_Length) :=
706 Right.Data (1 .. Max_Length - 1);
712 when Strings.Error =>
713 raise Ada.Strings.Length_Error;
723 (Source : in Bounded_String;
725 Mapping : in Maps.Character_Mapping := Maps.Identity)
730 Search.Count (Source.Data (1 .. Source.Length), Pattern, Mapping);
734 (Source : in Bounded_String;
736 Mapping : in Maps.Character_Mapping_Function)
741 Search.Count (Source.Data (1 .. Source.Length), Pattern, Mapping);
745 (Source : in Bounded_String;
746 Set : in Maps.Character_Set)
750 return Search.Count (Source.Data (1 .. Source.Length), Set);
758 (Source : in Bounded_String;
760 Through : in Natural)
761 return Bounded_String
763 Slen : constant Natural := Source.Length;
764 Num_Delete : constant Integer := Through - From + 1;
765 Result : Bounded_String;
768 if Num_Delete <= 0 then
771 elsif From > Slen + 1 then
772 raise Ada.Strings.Index_Error;
774 elsif Through >= Slen then
775 Result.Length := From - 1;
776 Result.Data (1 .. From - 1) := Source.Data (1 .. From - 1);
780 Result.Length := Slen - Num_Delete;
781 Result.Data (1 .. From - 1) := Source.Data (1 .. From - 1);
782 Result.Data (From .. Result.Length) :=
783 Source.Data (Through + 1 .. Slen);
789 (Source : in out Bounded_String;
791 Through : in Natural)
793 Slen : constant Natural := Source.Length;
794 Num_Delete : constant Integer := Through - From + 1;
797 if Num_Delete <= 0 then
800 elsif From > Slen + 1 then
801 raise Ada.Strings.Index_Error;
803 elsif Through >= Slen then
804 Source.Length := From - 1;
807 Source.Length := Slen - Num_Delete;
808 Source.Data (From .. Source.Length) :=
809 Source.Data (Through + 1 .. Slen);
818 (Source : in Bounded_String;
823 if Index in 1 .. Source.Length then
824 return Source.Data (Index);
826 raise Strings.Index_Error;
835 (Source : in Bounded_String;
836 Set : in Maps.Character_Set;
837 Test : in Strings.Membership;
838 First : out Positive;
843 (Source.Data (1 .. Source.Length), Set, Test, First, Last);
852 (Source : in Bounded_String;
854 Pad : in Character := Space;
855 Drop : in Strings.Truncation := Strings.Error)
856 return Bounded_String
858 Result : Bounded_String;
859 Slen : constant Natural := Source.Length;
860 Npad : constant Integer := Count - Slen;
864 Result.Length := Count;
865 Result.Data (1 .. Count) := Source.Data (1 .. Count);
867 elsif Count <= Max_Length then
868 Result.Length := Count;
869 Result.Data (1 .. Slen) := Source.Data (1 .. Slen);
870 Result.Data (Slen + 1 .. Count) := (others => Pad);
873 Result.Length := Max_Length;
876 when Strings.Right =>
877 Result.Data (1 .. Slen) := Source.Data (1 .. Slen);
878 Result.Data (Slen + 1 .. Max_Length) := (others => Pad);
881 if Npad >= Max_Length then
882 Result.Data := (others => Pad);
885 Result.Data (1 .. Max_Length - Npad) :=
886 Source.Data (Count - Max_Length + 1 .. Slen);
887 Result.Data (Max_Length - Npad + 1 .. Max_Length) :=
891 when Strings.Error =>
892 raise Ada.Strings.Length_Error;
900 (Source : in out Bounded_String;
902 Pad : in Character := Space;
903 Drop : in Truncation := Error)
905 Slen : constant Natural := Source.Length;
906 Npad : constant Integer := Count - Slen;
907 Temp : String (1 .. Max_Length);
911 Source.Length := Count;
913 elsif Count <= Max_Length then
914 Source.Length := Count;
915 Source.Data (Slen + 1 .. Count) := (others => Pad);
918 Source.Length := Max_Length;
921 when Strings.Right =>
922 Source.Data (Slen + 1 .. Max_Length) := (others => Pad);
925 if Npad > Max_Length then
926 Source.Data := (others => Pad);
930 Source.Data (1 .. Max_Length - Npad) :=
931 Temp (Count - Max_Length + 1 .. Slen);
933 for J in Max_Length - Npad + 1 .. Max_Length loop
934 Source.Data (J) := Pad;
938 when Strings.Error =>
939 raise Ada.Strings.Length_Error;
950 (Source : in Bounded_String;
952 Going : in Strings.Direction := Strings.Forward;
953 Mapping : in Maps.Character_Mapping := Maps.Identity)
958 (Source.Data (1 .. Source.Length), Pattern, Going, Mapping);
962 (Source : in Bounded_String;
964 Going : in Direction := Forward;
965 Mapping : in Maps.Character_Mapping_Function)
970 (Source.Data (1 .. Source.Length), Pattern, Going, Mapping);
974 (Source : in Bounded_String;
975 Set : in Maps.Character_Set;
976 Test : in Strings.Membership := Strings.Inside;
977 Going : in Strings.Direction := Strings.Forward)
982 (Source.Data (1 .. Source.Length), Set, Test, Going);
985 ---------------------
986 -- Index_Non_Blank --
987 ---------------------
989 function Index_Non_Blank
990 (Source : in Bounded_String;
991 Going : in Strings.Direction := Strings.Forward)
996 Search.Index_Non_Blank (Source.Data (1 .. Source.Length), Going);
1004 (Source : in Bounded_String;
1005 Before : in Positive;
1006 New_Item : in String;
1007 Drop : in Strings.Truncation := Strings.Error)
1008 return Bounded_String
1010 Slen : constant Natural := Source.Length;
1011 Nlen : constant Natural := New_Item'Length;
1012 Tlen : constant Natural := Slen + Nlen;
1013 Blen : constant Natural := Before - 1;
1014 Alen : constant Integer := Slen - Blen;
1015 Droplen : constant Integer := Tlen - Max_Length;
1016 Result : Bounded_String;
1018 -- Tlen is the length of the total string before possible truncation.
1019 -- Blen, Alen are the lengths of the before and after pieces of the
1024 raise Ada.Strings.Index_Error;
1026 elsif Droplen <= 0 then
1027 Result.Length := Tlen;
1028 Result.Data (1 .. Blen) := Source.Data (1 .. Blen);
1029 Result.Data (Before .. Before + Nlen - 1) := New_Item;
1030 Result.Data (Before + Nlen .. Tlen) :=
1031 Source.Data (Before .. Slen);
1034 Result.Length := Max_Length;
1037 when Strings.Right =>
1038 Result.Data (1 .. Blen) := Source.Data (1 .. Blen);
1040 if Droplen > Alen then
1041 Result.Data (Before .. Max_Length) :=
1042 New_Item (New_Item'First
1043 .. New_Item'First + Max_Length - Before);
1045 Result.Data (Before .. Before + Nlen - 1) := New_Item;
1046 Result.Data (Before + Nlen .. Max_Length) :=
1047 Source.Data (Before .. Slen - Droplen);
1050 when Strings.Left =>
1051 Result.Data (Max_Length - (Alen - 1) .. Max_Length) :=
1052 Source.Data (Before .. Slen);
1054 if Droplen >= Blen then
1055 Result.Data (1 .. Max_Length - Alen) :=
1056 New_Item (New_Item'Last - (Max_Length - Alen) + 1
1060 (Blen - Droplen + 1 .. Max_Length - Alen) :=
1062 Result.Data (1 .. Blen - Droplen) :=
1063 Source.Data (Droplen + 1 .. Blen);
1066 when Strings.Error =>
1067 raise Ada.Strings.Length_Error;
1075 (Source : in out Bounded_String;
1076 Before : in Positive;
1077 New_Item : in String;
1078 Drop : in Strings.Truncation := Strings.Error)
1081 -- We do a double copy here because this is one of the situations
1082 -- in which we move data to the right, and at least at the moment,
1083 -- GNAT is not handling such cases correctly ???
1085 Source := Insert (Source, Before, New_Item, Drop);
1092 function Length (Source : in Bounded_String) return Length_Range is
1094 return Source.Length;
1102 (Source : in Bounded_String;
1103 Position : in Positive;
1104 New_Item : in String;
1105 Drop : in Strings.Truncation := Strings.Error)
1106 return Bounded_String
1108 Result : Bounded_String;
1109 Endpos : constant Natural := Position + New_Item'Length - 1;
1110 Slen : constant Natural := Source.Length;
1114 if Position > Slen + 1 then
1115 raise Ada.Strings.Index_Error;
1117 elsif New_Item'Length = 0 then
1120 elsif Endpos <= Slen then
1121 Result.Length := Source.Length;
1122 Result.Data (1 .. Slen) := Source.Data (1 .. Slen);
1123 Result.Data (Position .. Endpos) := New_Item;
1126 elsif Endpos <= Max_Length then
1127 Result.Length := Endpos;
1128 Result.Data (1 .. Position - 1) := Source.Data (1 .. Position - 1);
1129 Result.Data (Position .. Endpos) := New_Item;
1133 Result.Length := Max_Length;
1134 Droplen := Endpos - Max_Length;
1137 when Strings.Right =>
1138 Result.Data (1 .. Position - 1) :=
1139 Source.Data (1 .. Position - 1);
1141 Result.Data (Position .. Max_Length) :=
1142 New_Item (New_Item'First .. New_Item'Last - Droplen);
1145 when Strings.Left =>
1146 if New_Item'Length >= Max_Length then
1147 Result.Data (1 .. Max_Length) :=
1148 New_Item (New_Item'Last - Max_Length + 1 ..
1153 Result.Data (1 .. Max_Length - New_Item'Length) :=
1154 Source.Data (Droplen + 1 .. Position - 1);
1156 (Max_Length - New_Item'Length + 1 .. Max_Length) :=
1161 when Strings.Error =>
1162 raise Ada.Strings.Length_Error;
1168 (Source : in out Bounded_String;
1169 Position : in Positive;
1170 New_Item : in String;
1171 Drop : in Strings.Truncation := Strings.Error)
1173 Endpos : constant Positive := Position + New_Item'Length - 1;
1174 Slen : constant Natural := Source.Length;
1178 if Position > Slen + 1 then
1179 raise Ada.Strings.Index_Error;
1181 elsif Endpos <= Slen then
1182 Source.Data (Position .. Endpos) := New_Item;
1184 elsif Endpos <= Max_Length then
1185 Source.Data (Position .. Endpos) := New_Item;
1186 Source.Length := Endpos;
1189 Source.Length := Max_Length;
1190 Droplen := Endpos - Max_Length;
1193 when Strings.Right =>
1194 Source.Data (Position .. Max_Length) :=
1195 New_Item (New_Item'First .. New_Item'Last - Droplen);
1197 when Strings.Left =>
1198 if New_Item'Length > Max_Length then
1199 Source.Data (1 .. Max_Length) :=
1200 New_Item (New_Item'Last - Max_Length + 1 ..
1204 Source.Data (1 .. Max_Length - New_Item'Length) :=
1205 Source.Data (Droplen + 1 .. Position - 1);
1208 (Max_Length - New_Item'Length + 1 .. Max_Length) :=
1212 when Strings.Error =>
1213 raise Ada.Strings.Length_Error;
1218 ---------------------
1219 -- Replace_Element --
1220 ---------------------
1222 procedure Replace_Element
1223 (Source : in out Bounded_String;
1224 Index : in Positive;
1228 if Index <= Source.Length then
1229 Source.Data (Index) := By;
1231 raise Ada.Strings.Index_Error;
1233 end Replace_Element;
1239 function Replace_Slice
1240 (Source : in Bounded_String;
1244 Drop : in Strings.Truncation := Strings.Error)
1245 return Bounded_String
1247 Slen : constant Natural := Source.Length;
1250 if Low > Slen + 1 then
1251 raise Strings.Index_Error;
1253 elsif High < Low then
1254 return Insert (Source, Low, By, Drop);
1258 Blen : constant Natural := Natural'Max (0, Low - 1);
1259 Alen : constant Natural := Natural'Max (0, Slen - High);
1260 Tlen : constant Natural := Blen + By'Length + Alen;
1261 Droplen : constant Integer := Tlen - Max_Length;
1262 Result : Bounded_String;
1264 -- Tlen is the total length of the result string before any
1265 -- truncation. Blen and Alen are the lengths of the pieces
1266 -- of the original string that end up in the result string
1267 -- before and after the replaced slice.
1270 if Droplen <= 0 then
1271 Result.Length := Tlen;
1272 Result.Data (1 .. Blen) := Source.Data (1 .. Blen);
1273 Result.Data (Low .. Low + By'Length - 1) := By;
1274 Result.Data (Low + By'Length .. Tlen) :=
1275 Source.Data (High + 1 .. Slen);
1278 Result.Length := Max_Length;
1281 when Strings.Right =>
1282 Result.Data (1 .. Blen) := Source.Data (1 .. Blen);
1284 if Droplen > Alen then
1285 Result.Data (Low .. Max_Length) :=
1286 By (By'First .. By'First + Max_Length - Low);
1288 Result.Data (Low .. Low + By'Length - 1) := By;
1289 Result.Data (Low + By'Length .. Max_Length) :=
1290 Source.Data (High + 1 .. Slen - Droplen);
1293 when Strings.Left =>
1294 Result.Data (Max_Length - (Alen - 1) .. Max_Length) :=
1295 Source.Data (High + 1 .. Slen);
1297 if Droplen >= Blen then
1298 Result.Data (1 .. Max_Length - Alen) :=
1299 By (By'Last - (Max_Length - Alen) + 1 .. By'Last);
1302 (Blen - Droplen + 1 .. Max_Length - Alen) := By;
1303 Result.Data (1 .. Blen - Droplen) :=
1304 Source.Data (Droplen + 1 .. Blen);
1307 when Strings.Error =>
1308 raise Ada.Strings.Length_Error;
1317 procedure Replace_Slice
1318 (Source : in out Bounded_String;
1322 Drop : in Strings.Truncation := Strings.Error)
1325 -- We do a double copy here because this is one of the situations
1326 -- in which we move data to the right, and at least at the moment,
1327 -- GNAT is not handling such cases correctly ???
1329 Source := Replace_Slice (Source, Low, High, By, Drop);
1337 (Count : in Natural;
1338 Item : in Character;
1339 Drop : in Strings.Truncation := Strings.Error)
1340 return Bounded_String
1342 Result : Bounded_String;
1345 if Count <= Max_Length then
1346 Result.Length := Count;
1348 elsif Drop = Strings.Error then
1349 raise Ada.Strings.Length_Error;
1352 Result.Length := Max_Length;
1355 Result.Data (1 .. Result.Length) := (others => Item);
1360 (Count : in Natural;
1362 Drop : in Strings.Truncation := Strings.Error)
1363 return Bounded_String
1365 Length : constant Integer := Count * Item'Length;
1366 Result : Bounded_String;
1370 if Length <= Max_Length then
1371 Result.Length := Length;
1376 for J in 1 .. Count loop
1377 Result.Data (Indx .. Indx + Item'Length - 1) := Item;
1378 Indx := Indx + Item'Length;
1383 Result.Length := Max_Length;
1386 when Strings.Right =>
1389 while Indx + Item'Length <= Max_Length + 1 loop
1390 Result.Data (Indx .. Indx + Item'Length - 1) := Item;
1391 Indx := Indx + Item'Length;
1394 Result.Data (Indx .. Max_Length) :=
1395 Item (Item'First .. Item'First + Max_Length - Indx);
1397 when Strings.Left =>
1400 while Indx - Item'Length >= 1 loop
1401 Result.Data (Indx - (Item'Length - 1) .. Indx) := Item;
1402 Indx := Indx - Item'Length;
1405 Result.Data (1 .. Indx) :=
1406 Item (Item'Last - Indx + 1 .. Item'Last);
1408 when Strings.Error =>
1409 raise Ada.Strings.Length_Error;
1417 (Count : in Natural;
1418 Item : in Bounded_String;
1419 Drop : in Strings.Truncation := Strings.Error)
1420 return Bounded_String
1423 return Replicate (Count, Item.Data (1 .. Item.Length), Drop);
1431 (Source : Bounded_String;
1437 -- Note: test of High > Length is in accordance with AI95-00128
1439 if Low > Source.Length + 1 or else High > Source.Length then
1442 return Source.Data (Low .. High);
1451 (Source : in Bounded_String;
1453 Pad : in Character := Space;
1454 Drop : in Strings.Truncation := Strings.Error)
1455 return Bounded_String
1457 Result : Bounded_String;
1458 Slen : constant Natural := Source.Length;
1459 Npad : constant Integer := Count - Slen;
1463 Result.Length := Count;
1464 Result.Data (1 .. Count) :=
1465 Source.Data (Slen - (Count - 1) .. Slen);
1467 elsif Count <= Max_Length then
1468 Result.Length := Count;
1469 Result.Data (1 .. Npad) := (others => Pad);
1470 Result.Data (Npad + 1 .. Count) := Source.Data (1 .. Slen);
1473 Result.Length := Max_Length;
1476 when Strings.Right =>
1477 if Npad >= Max_Length then
1478 Result.Data := (others => Pad);
1481 Result.Data (1 .. Npad) := (others => Pad);
1482 Result.Data (Npad + 1 .. Max_Length) :=
1483 Source.Data (1 .. Max_Length - Npad);
1486 when Strings.Left =>
1487 Result.Data (1 .. Max_Length - Slen) := (others => Pad);
1488 Result.Data (Max_Length - Slen + 1 .. Max_Length) :=
1489 Source.Data (1 .. Slen);
1491 when Strings.Error =>
1492 raise Ada.Strings.Length_Error;
1500 (Source : in out Bounded_String;
1502 Pad : in Character := Space;
1503 Drop : in Truncation := Error)
1505 Slen : constant Natural := Source.Length;
1506 Npad : constant Integer := Count - Slen;
1507 Temp : String (1 .. Max_Length) := Source.Data;
1511 Source.Length := Count;
1512 Source.Data (1 .. Count) :=
1513 Temp (Slen - (Count - 1) .. Slen);
1515 elsif Count <= Max_Length then
1516 Source.Length := Count;
1517 Source.Data (1 .. Npad) := (others => Pad);
1518 Source.Data (Npad + 1 .. Count) := Temp (1 .. Slen);
1521 Source.Length := Max_Length;
1524 when Strings.Right =>
1525 if Npad >= Max_Length then
1526 Source.Data := (others => Pad);
1529 Source.Data (1 .. Npad) := (others => Pad);
1530 Source.Data (Npad + 1 .. Max_Length) :=
1531 Temp (1 .. Max_Length - Npad);
1534 when Strings.Left =>
1535 for J in 1 .. Max_Length - Slen loop
1536 Source.Data (J) := Pad;
1539 Source.Data (Max_Length - Slen + 1 .. Max_Length) :=
1542 when Strings.Error =>
1543 raise Ada.Strings.Length_Error;
1549 -----------------------
1550 -- To_Bounded_String --
1551 -----------------------
1553 function To_Bounded_String
1554 (Source : in String;
1555 Drop : in Strings.Truncation := Strings.Error)
1556 return Bounded_String
1558 Slen : constant Natural := Source'Length;
1559 Result : Bounded_String;
1562 if Slen <= Max_Length then
1563 Result.Length := Slen;
1564 Result.Data (1 .. Slen) := Source;
1568 when Strings.Right =>
1569 Result.Length := Max_Length;
1570 Result.Data (1 .. Max_Length) :=
1571 Source (Source'First .. Source'First - 1 + Max_Length);
1573 when Strings.Left =>
1574 Result.Length := Max_Length;
1575 Result.Data (1 .. Max_Length) :=
1576 Source (Source'Last - (Max_Length - 1) .. Source'Last);
1578 when Strings.Error =>
1579 raise Ada.Strings.Length_Error;
1584 end To_Bounded_String;
1590 function To_String (Source : in Bounded_String) return String is
1592 return Source.Data (1 .. Source.Length);
1600 (Source : in Bounded_String;
1601 Mapping : in Maps.Character_Mapping)
1602 return Bounded_String
1604 Result : Bounded_String;
1607 Result.Length := Source.Length;
1609 for J in 1 .. Source.Length loop
1610 Result.Data (J) := Value (Mapping, Source.Data (J));
1617 (Source : in out Bounded_String;
1618 Mapping : in Maps.Character_Mapping)
1621 for J in 1 .. Source.Length loop
1622 Source.Data (J) := Value (Mapping, Source.Data (J));
1627 (Source : in Bounded_String;
1628 Mapping : in Maps.Character_Mapping_Function)
1629 return Bounded_String
1631 Result : Bounded_String;
1634 Result.Length := Source.Length;
1636 for J in 1 .. Source.Length loop
1637 Result.Data (J) := Mapping.all (Source.Data (J));
1644 (Source : in out Bounded_String;
1645 Mapping : in Maps.Character_Mapping_Function)
1648 for J in 1 .. Source.Length loop
1649 Source.Data (J) := Mapping.all (Source.Data (J));
1657 function Trim (Source : in Bounded_String; Side : in Trim_End)
1658 return Bounded_String
1660 Result : Bounded_String;
1661 Last : Natural := Source.Length;
1662 First : Positive := 1;
1665 if Side = Left or else Side = Both then
1666 while First <= Last and then Source.Data (First) = ' ' loop
1671 if Side = Right or else Side = Both then
1672 while Last >= First and then Source.Data (Last) = ' ' loop
1677 Result.Length := Last - First + 1;
1678 Result.Data (1 .. Result.Length) := Source.Data (First .. Last);
1684 (Source : in out Bounded_String;
1687 Last : Length_Range := Source.Length;
1688 First : Positive := 1;
1689 Temp : String (1 .. Max_Length);
1692 Temp (1 .. Last) := Source.Data (1 .. Last);
1694 if Side = Left or else Side = Both then
1695 while First <= Last and then Temp (First) = ' ' loop
1700 if Side = Right or else Side = Both then
1701 while Last >= First and then Temp (Last) = ' ' loop
1706 Source := Null_Bounded_String;
1707 Source.Length := Last - First + 1;
1708 Source.Data (1 .. Source.Length) := Temp (First .. Last);
1713 (Source : in Bounded_String;
1714 Left : in Maps.Character_Set;
1715 Right : in Maps.Character_Set)
1716 return Bounded_String
1718 Result : Bounded_String;
1721 for First in 1 .. Source.Length loop
1722 if not Is_In (Source.Data (First), Left) then
1723 for Last in reverse First .. Source.Length loop
1724 if not Is_In (Source.Data (Last), Right) then
1725 Result.Length := Last - First + 1;
1726 Result.Data (1 .. Result.Length) :=
1727 Source.Data (First .. Last);
1739 (Source : in out Bounded_String;
1740 Left : in Maps.Character_Set;
1741 Right : in Maps.Character_Set)
1744 for First in 1 .. Source.Length loop
1745 if not Is_In (Source.Data (First), Left) then
1746 for Last in reverse First .. Source.Length loop
1747 if not Is_In (Source.Data (Last), Right) then
1749 Source.Length := Last;
1752 Source.Length := Last - First + 1;
1753 Source.Data (1 .. Source.Length) :=
1754 Source.Data (First .. Last);
1756 for J in Source.Length + 1 .. Max_Length loop
1757 Source.Data (J) := ASCII.NUL;
1773 end Generic_Bounded_Length;
1775 end Ada.Strings.Bounded;