1 ------------------------------------------------------------------------------
3 -- GNAT RUN-TIME COMPONENTS --
5 -- A D A . S T R I N G S . S U P E R B O U N D E D --
9 -- Copyright (C) 2003-2007, 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, 51 Franklin Street, Fifth Floor, --
20 -- Boston, MA 02110-1301, 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.Superbounded is
45 Right : Super_String) return Super_String
47 Result : Super_String (Left.Max_Length);
48 Llen : constant Natural := Left.Current_Length;
49 Rlen : constant Natural := Right.Current_Length;
50 Nlen : constant Natural := Llen + Rlen;
53 if Nlen > Left.Max_Length then
54 raise Ada.Strings.Length_Error;
56 Result.Current_Length := Nlen;
57 Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
58 Result.Data (Llen + 1 .. Nlen) := Right.Data (1 .. Rlen);
66 Right : String) return Super_String
68 Result : Super_String (Left.Max_Length);
69 Llen : constant Natural := Left.Current_Length;
71 Nlen : constant Natural := Llen + Right'Length;
74 if Nlen > Left.Max_Length then
75 raise Ada.Strings.Length_Error;
77 Result.Current_Length := Nlen;
78 Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
79 Result.Data (Llen + 1 .. Nlen) := Right;
86 Right : Super_String) return Super_String
88 Result : Super_String (Right.Max_Length);
89 Llen : constant Natural := Left'Length;
90 Rlen : constant Natural := Right.Current_Length;
91 Nlen : constant Natural := Llen + Rlen;
94 if Nlen > Right.Max_Length then
95 raise Ada.Strings.Length_Error;
97 Result.Current_Length := Nlen;
98 Result.Data (1 .. Llen) := Left;
99 Result.Data (Llen + 1 .. Nlen) := Right.Data (1 .. Rlen);
106 (Left : Super_String;
107 Right : Character) return Super_String
109 Result : Super_String (Left.Max_Length);
110 Llen : constant Natural := Left.Current_Length;
113 if Llen = Left.Max_Length then
114 raise Ada.Strings.Length_Error;
116 Result.Current_Length := Llen + 1;
117 Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
118 Result.Data (Result.Current_Length) := Right;
126 Right : Super_String) return Super_String
128 Result : Super_String (Right.Max_Length);
129 Rlen : constant Natural := Right.Current_Length;
132 if Rlen = Right.Max_Length then
133 raise Ada.Strings.Length_Error;
135 Result.Current_Length := Rlen + 1;
136 Result.Data (1) := Left;
137 Result.Data (2 .. Result.Current_Length) := Right.Data (1 .. Rlen);
148 (Left : Super_String;
149 Right : Super_String) return Boolean
152 return Left.Current_Length = Right.Current_Length
153 and then Left.Data (1 .. Left.Current_Length) =
154 Right.Data (1 .. Right.Current_Length);
158 (Left : Super_String;
159 Right : String) return Boolean
162 return Left.Current_Length = Right'Length
163 and then Left.Data (1 .. Left.Current_Length) = Right;
168 Right : Super_String) return Boolean
171 return Left'Length = Right.Current_Length
172 and then Left = Right.Data (1 .. Right.Current_Length);
180 (Left : Super_String;
181 Right : Super_String) return Boolean
184 return Left.Data (1 .. Left.Current_Length) >
185 Right.Data (1 .. Right.Current_Length);
189 (Left : Super_String;
190 Right : String) return Boolean
193 return Left.Data (1 .. Left.Current_Length) > Right;
198 Right : Super_String) return Boolean
201 return Left > Right.Data (1 .. Right.Current_Length);
204 ----------------------
205 -- Greater_Or_Equal --
206 ----------------------
208 function Greater_Or_Equal
209 (Left : Super_String;
210 Right : Super_String) return Boolean
213 return Left.Data (1 .. Left.Current_Length) >=
214 Right.Data (1 .. Right.Current_Length);
215 end Greater_Or_Equal;
217 function Greater_Or_Equal
218 (Left : Super_String;
219 Right : String) return Boolean
222 return Left.Data (1 .. Left.Current_Length) >= Right;
223 end Greater_Or_Equal;
225 function Greater_Or_Equal
227 Right : Super_String) return Boolean
230 return Left >= Right.Data (1 .. Right.Current_Length);
231 end Greater_Or_Equal;
238 (Left : Super_String;
239 Right : Super_String) return Boolean
242 return Left.Data (1 .. Left.Current_Length) <
243 Right.Data (1 .. Right.Current_Length);
247 (Left : Super_String;
248 Right : String) return Boolean
251 return Left.Data (1 .. Left.Current_Length) < Right;
256 Right : Super_String) return Boolean
259 return Left < Right.Data (1 .. Right.Current_Length);
266 function Less_Or_Equal
267 (Left : Super_String;
268 Right : Super_String) return Boolean
271 return Left.Data (1 .. Left.Current_Length) <=
272 Right.Data (1 .. Right.Current_Length);
275 function Less_Or_Equal
276 (Left : Super_String;
277 Right : String) return Boolean
280 return Left.Data (1 .. Left.Current_Length) <= Right;
283 function Less_Or_Equal
285 Right : Super_String) return Boolean
288 return Left <= Right.Data (1 .. Right.Current_Length);
291 ----------------------
292 -- Set_Super_String --
293 ----------------------
295 procedure Set_Super_String
296 (Target : out Super_String;
298 Drop : Truncation := Error)
300 Slen : constant Natural := Source'Length;
301 Max_Length : constant Positive := Target.Max_Length;
304 if Slen <= Max_Length then
305 Target.Current_Length := Slen;
306 Target.Data (1 .. Slen) := Source;
310 when Strings.Right =>
311 Target.Current_Length := Max_Length;
312 Target.Data (1 .. Max_Length) :=
313 Source (Source'First .. Source'First - 1 + Max_Length);
316 Target.Current_Length := Max_Length;
317 Target.Data (1 .. Max_Length) :=
318 Source (Source'Last - (Max_Length - 1) .. Source'Last);
320 when Strings.Error =>
321 raise Ada.Strings.Length_Error;
324 end Set_Super_String;
330 -- Case of Super_String and Super_String
332 function Super_Append
333 (Left : Super_String;
334 Right : Super_String;
335 Drop : Truncation := Error) return Super_String
337 Max_Length : constant Positive := Left.Max_Length;
338 Result : Super_String (Max_Length);
339 Llen : constant Natural := Left.Current_Length;
340 Rlen : constant Natural := Right.Current_Length;
341 Nlen : constant Natural := Llen + Rlen;
344 if Nlen <= Max_Length then
345 Result.Current_Length := Nlen;
346 Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
347 Result.Data (Llen + 1 .. Nlen) := Right.Data (1 .. Rlen);
350 Result.Current_Length := Max_Length;
353 when Strings.Right =>
354 if Llen >= Max_Length then -- only case is Llen = Max_Length
355 Result.Data := Left.Data;
358 Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
359 Result.Data (Llen + 1 .. Max_Length) :=
360 Right.Data (1 .. Max_Length - Llen);
364 if Rlen >= Max_Length then -- only case is Rlen = Max_Length
365 Result.Data := Right.Data;
368 Result.Data (1 .. Max_Length - Rlen) :=
369 Left.Data (Llen - (Max_Length - Rlen - 1) .. Llen);
370 Result.Data (Max_Length - Rlen + 1 .. Max_Length) :=
371 Right.Data (1 .. Rlen);
374 when Strings.Error =>
375 raise Ada.Strings.Length_Error;
382 procedure Super_Append
383 (Source : in out Super_String;
384 New_Item : Super_String;
385 Drop : Truncation := Error)
387 Max_Length : constant Positive := Source.Max_Length;
388 Llen : constant Natural := Source.Current_Length;
389 Rlen : constant Natural := New_Item.Current_Length;
390 Nlen : constant Natural := Llen + Rlen;
393 if Nlen <= Max_Length then
394 Source.Current_Length := Nlen;
395 Source.Data (Llen + 1 .. Nlen) := New_Item.Data (1 .. Rlen);
398 Source.Current_Length := Max_Length;
401 when Strings.Right =>
402 if Llen < Max_Length then
403 Source.Data (Llen + 1 .. Max_Length) :=
404 New_Item.Data (1 .. Max_Length - Llen);
408 if Rlen >= Max_Length then -- only case is Rlen = Max_Length
409 Source.Data := New_Item.Data;
412 Source.Data (1 .. Max_Length - Rlen) :=
413 Source.Data (Llen - (Max_Length - Rlen - 1) .. Llen);
414 Source.Data (Max_Length - Rlen + 1 .. Max_Length) :=
415 New_Item.Data (1 .. Rlen);
418 when Strings.Error =>
419 raise Ada.Strings.Length_Error;
425 -- Case of Super_String and String
427 function Super_Append
428 (Left : Super_String;
430 Drop : Strings.Truncation := Strings.Error) return Super_String
432 Max_Length : constant Positive := Left.Max_Length;
433 Result : Super_String (Max_Length);
434 Llen : constant Natural := Left.Current_Length;
435 Rlen : constant Natural := Right'Length;
436 Nlen : constant Natural := Llen + Rlen;
439 if Nlen <= Max_Length then
440 Result.Current_Length := Nlen;
441 Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
442 Result.Data (Llen + 1 .. Nlen) := Right;
445 Result.Current_Length := Max_Length;
448 when Strings.Right =>
449 if Llen >= Max_Length then -- only case is Llen = Max_Length
450 Result.Data := Left.Data;
453 Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
454 Result.Data (Llen + 1 .. Max_Length) :=
455 Right (Right'First .. Right'First - 1 +
461 if Rlen >= Max_Length then
462 Result.Data (1 .. Max_Length) :=
463 Right (Right'Last - (Max_Length - 1) .. Right'Last);
466 Result.Data (1 .. Max_Length - Rlen) :=
467 Left.Data (Llen - (Max_Length - Rlen - 1) .. Llen);
468 Result.Data (Max_Length - Rlen + 1 .. Max_Length) :=
472 when Strings.Error =>
473 raise Ada.Strings.Length_Error;
480 procedure Super_Append
481 (Source : in out Super_String;
483 Drop : Truncation := Error)
485 Max_Length : constant Positive := Source.Max_Length;
486 Llen : constant Natural := Source.Current_Length;
487 Rlen : constant Natural := New_Item'Length;
488 Nlen : constant Natural := Llen + Rlen;
491 if Nlen <= Max_Length then
492 Source.Current_Length := Nlen;
493 Source.Data (Llen + 1 .. Nlen) := New_Item;
496 Source.Current_Length := Max_Length;
499 when Strings.Right =>
500 if Llen < Max_Length then
501 Source.Data (Llen + 1 .. Max_Length) :=
502 New_Item (New_Item'First ..
503 New_Item'First - 1 + Max_Length - Llen);
507 if Rlen >= Max_Length then
508 Source.Data (1 .. Max_Length) :=
509 New_Item (New_Item'Last - (Max_Length - 1) ..
513 Source.Data (1 .. Max_Length - Rlen) :=
514 Source.Data (Llen - (Max_Length - Rlen - 1) .. Llen);
515 Source.Data (Max_Length - Rlen + 1 .. Max_Length) :=
519 when Strings.Error =>
520 raise Ada.Strings.Length_Error;
526 -- Case of String and Super_String
528 function Super_Append
530 Right : Super_String;
531 Drop : Strings.Truncation := Strings.Error) return Super_String
533 Max_Length : constant Positive := Right.Max_Length;
534 Result : Super_String (Max_Length);
535 Llen : constant Natural := Left'Length;
536 Rlen : constant Natural := Right.Current_Length;
537 Nlen : constant Natural := Llen + Rlen;
540 if Nlen <= Max_Length then
541 Result.Current_Length := Nlen;
542 Result.Data (1 .. Llen) := Left;
543 Result.Data (Llen + 1 .. Llen + Rlen) := Right.Data (1 .. Rlen);
546 Result.Current_Length := Max_Length;
549 when Strings.Right =>
550 if Llen >= Max_Length then
551 Result.Data (1 .. Max_Length) :=
552 Left (Left'First .. Left'First + (Max_Length - 1));
555 Result.Data (1 .. Llen) := Left;
556 Result.Data (Llen + 1 .. Max_Length) :=
557 Right.Data (1 .. Max_Length - Llen);
561 if Rlen >= Max_Length then
562 Result.Data (1 .. Max_Length) :=
563 Right.Data (Rlen - (Max_Length - 1) .. Rlen);
566 Result.Data (1 .. Max_Length - Rlen) :=
567 Left (Left'Last - (Max_Length - Rlen - 1) .. Left'Last);
568 Result.Data (Max_Length - Rlen + 1 .. Max_Length) :=
569 Right.Data (1 .. Rlen);
572 when Strings.Error =>
573 raise Ada.Strings.Length_Error;
580 -- Case of Super_String and Character
582 function Super_Append
583 (Left : Super_String;
585 Drop : Strings.Truncation := Strings.Error) return Super_String
587 Max_Length : constant Positive := Left.Max_Length;
588 Result : Super_String (Max_Length);
589 Llen : constant Natural := Left.Current_Length;
592 if Llen < Max_Length then
593 Result.Current_Length := Llen + 1;
594 Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
595 Result.Data (Llen + 1) := Right;
600 when Strings.Right =>
604 Result.Current_Length := Max_Length;
605 Result.Data (1 .. Max_Length - 1) :=
606 Left.Data (2 .. Max_Length);
607 Result.Data (Max_Length) := Right;
610 when Strings.Error =>
611 raise Ada.Strings.Length_Error;
616 procedure Super_Append
617 (Source : in out Super_String;
618 New_Item : Character;
619 Drop : Truncation := Error)
621 Max_Length : constant Positive := Source.Max_Length;
622 Llen : constant Natural := Source.Current_Length;
625 if Llen < Max_Length then
626 Source.Current_Length := Llen + 1;
627 Source.Data (Llen + 1) := New_Item;
630 Source.Current_Length := Max_Length;
633 when Strings.Right =>
637 Source.Data (1 .. Max_Length - 1) :=
638 Source.Data (2 .. Max_Length);
639 Source.Data (Max_Length) := New_Item;
641 when Strings.Error =>
642 raise Ada.Strings.Length_Error;
648 -- Case of Character and Super_String
650 function Super_Append
652 Right : Super_String;
653 Drop : Strings.Truncation := Strings.Error) return Super_String
655 Max_Length : constant Positive := Right.Max_Length;
656 Result : Super_String (Max_Length);
657 Rlen : constant Natural := Right.Current_Length;
660 if Rlen < Max_Length then
661 Result.Current_Length := Rlen + 1;
662 Result.Data (1) := Left;
663 Result.Data (2 .. Rlen + 1) := Right.Data (1 .. Rlen);
668 when Strings.Right =>
669 Result.Current_Length := Max_Length;
670 Result.Data (1) := Left;
671 Result.Data (2 .. Max_Length) :=
672 Right.Data (1 .. Max_Length - 1);
678 when Strings.Error =>
679 raise Ada.Strings.Length_Error;
689 (Source : Super_String;
691 Mapping : Maps.Character_Mapping := Maps.Identity) return Natural
696 (Source.Data (1 .. Source.Current_Length), Pattern, Mapping);
700 (Source : Super_String;
702 Mapping : Maps.Character_Mapping_Function) return Natural
707 (Source.Data (1 .. Source.Current_Length), Pattern, Mapping);
711 (Source : Super_String;
712 Set : Maps.Character_Set) return Natural
715 return Search.Count (Source.Data (1 .. Source.Current_Length), Set);
722 function Super_Delete
723 (Source : Super_String;
725 Through : Natural) return Super_String
727 Result : Super_String (Source.Max_Length);
728 Slen : constant Natural := Source.Current_Length;
729 Num_Delete : constant Integer := Through - From + 1;
732 if Num_Delete <= 0 then
735 elsif From > Slen + 1 then
736 raise Ada.Strings.Index_Error;
738 elsif Through >= Slen then
739 Result.Current_Length := From - 1;
740 Result.Data (1 .. From - 1) := Source.Data (1 .. From - 1);
744 Result.Current_Length := Slen - Num_Delete;
745 Result.Data (1 .. From - 1) := Source.Data (1 .. From - 1);
746 Result.Data (From .. Result.Current_Length) :=
747 Source.Data (Through + 1 .. Slen);
752 procedure Super_Delete
753 (Source : in out Super_String;
757 Slen : constant Natural := Source.Current_Length;
758 Num_Delete : constant Integer := Through - From + 1;
761 if Num_Delete <= 0 then
764 elsif From > Slen + 1 then
765 raise Ada.Strings.Index_Error;
767 elsif Through >= Slen then
768 Source.Current_Length := From - 1;
771 Source.Current_Length := Slen - Num_Delete;
772 Source.Data (From .. Source.Current_Length) :=
773 Source.Data (Through + 1 .. Slen);
781 function Super_Element
782 (Source : Super_String;
783 Index : Positive) return Character
786 if Index <= Source.Current_Length then
787 return Source.Data (Index);
789 raise Strings.Index_Error;
793 ----------------------
794 -- Super_Find_Token --
795 ----------------------
797 procedure Super_Find_Token
798 (Source : Super_String;
799 Set : Maps.Character_Set;
800 Test : Strings.Membership;
801 First : out Positive;
806 (Source.Data (1 .. Source.Current_Length), Set, Test, First, Last);
807 end Super_Find_Token;
814 (Source : Super_String;
816 Pad : Character := Space;
817 Drop : Strings.Truncation := Strings.Error) return Super_String
819 Max_Length : constant Positive := Source.Max_Length;
820 Result : Super_String (Max_Length);
821 Slen : constant Natural := Source.Current_Length;
822 Npad : constant Integer := Count - Slen;
826 Result.Current_Length := Count;
827 Result.Data (1 .. Count) := Source.Data (1 .. Count);
829 elsif Count <= Max_Length then
830 Result.Current_Length := Count;
831 Result.Data (1 .. Slen) := Source.Data (1 .. Slen);
832 Result.Data (Slen + 1 .. Count) := (others => Pad);
835 Result.Current_Length := Max_Length;
838 when Strings.Right =>
839 Result.Data (1 .. Slen) := Source.Data (1 .. Slen);
840 Result.Data (Slen + 1 .. Max_Length) := (others => Pad);
843 if Npad >= Max_Length then
844 Result.Data := (others => Pad);
847 Result.Data (1 .. Max_Length - Npad) :=
848 Source.Data (Count - Max_Length + 1 .. Slen);
849 Result.Data (Max_Length - Npad + 1 .. Max_Length) :=
853 when Strings.Error =>
854 raise Ada.Strings.Length_Error;
862 (Source : in out Super_String;
864 Pad : Character := Space;
865 Drop : Truncation := Error)
867 Max_Length : constant Positive := Source.Max_Length;
868 Slen : constant Natural := Source.Current_Length;
869 Npad : constant Integer := Count - Slen;
870 Temp : String (1 .. Max_Length);
874 Source.Current_Length := Count;
876 elsif Count <= Max_Length then
877 Source.Current_Length := Count;
878 Source.Data (Slen + 1 .. Count) := (others => Pad);
881 Source.Current_Length := Max_Length;
884 when Strings.Right =>
885 Source.Data (Slen + 1 .. Max_Length) := (others => Pad);
888 if Npad > Max_Length then
889 Source.Data := (others => Pad);
893 Source.Data (1 .. Max_Length - Npad) :=
894 Temp (Count - Max_Length + 1 .. Slen);
896 for J in Max_Length - Npad + 1 .. Max_Length loop
897 Source.Data (J) := Pad;
901 when Strings.Error =>
902 raise Ada.Strings.Length_Error;
912 (Source : Super_String;
914 Going : Strings.Direction := Strings.Forward;
915 Mapping : Maps.Character_Mapping := Maps.Identity) return Natural
919 (Source.Data (1 .. Source.Current_Length), Pattern, Going, Mapping);
923 (Source : Super_String;
925 Going : Direction := Forward;
926 Mapping : Maps.Character_Mapping_Function) return Natural
930 (Source.Data (1 .. Source.Current_Length), Pattern, Going, Mapping);
934 (Source : Super_String;
935 Set : Maps.Character_Set;
936 Test : Strings.Membership := Strings.Inside;
937 Going : Strings.Direction := Strings.Forward) return Natural
941 (Source.Data (1 .. Source.Current_Length), Set, Test, Going);
945 (Source : Super_String;
948 Going : Direction := Forward;
949 Mapping : Maps.Character_Mapping := Maps.Identity) return Natural
953 (Source.Data (1 .. Source.Current_Length),
954 Pattern, From, Going, Mapping);
958 (Source : Super_String;
961 Going : Direction := Forward;
962 Mapping : Maps.Character_Mapping_Function) return Natural
966 (Source.Data (1 .. Source.Current_Length),
967 Pattern, From, Going, Mapping);
971 (Source : Super_String;
972 Set : Maps.Character_Set;
974 Test : Membership := Inside;
975 Going : Direction := Forward) return Natural
979 (Source.Data (1 .. Source.Current_Length), Set, From, Test, Going);
982 ---------------------------
983 -- Super_Index_Non_Blank --
984 ---------------------------
986 function Super_Index_Non_Blank
987 (Source : Super_String;
988 Going : Strings.Direction := Strings.Forward) return Natural
992 Search.Index_Non_Blank
993 (Source.Data (1 .. Source.Current_Length), Going);
994 end Super_Index_Non_Blank;
996 function Super_Index_Non_Blank
997 (Source : Super_String;
999 Going : Direction := Forward) return Natural
1003 Search.Index_Non_Blank
1004 (Source.Data (1 .. Source.Current_Length), From, Going);
1005 end Super_Index_Non_Blank;
1011 function Super_Insert
1012 (Source : Super_String;
1015 Drop : Strings.Truncation := Strings.Error) return Super_String
1017 Max_Length : constant Positive := Source.Max_Length;
1018 Result : Super_String (Max_Length);
1019 Slen : constant Natural := Source.Current_Length;
1020 Nlen : constant Natural := New_Item'Length;
1021 Tlen : constant Natural := Slen + Nlen;
1022 Blen : constant Natural := Before - 1;
1023 Alen : constant Integer := Slen - Blen;
1024 Droplen : constant Integer := Tlen - Max_Length;
1026 -- Tlen is the length of the total string before possible truncation.
1027 -- Blen, Alen are the lengths of the before and after pieces of the
1032 raise Ada.Strings.Index_Error;
1034 elsif Droplen <= 0 then
1035 Result.Current_Length := Tlen;
1036 Result.Data (1 .. Blen) := Source.Data (1 .. Blen);
1037 Result.Data (Before .. Before + Nlen - 1) := New_Item;
1038 Result.Data (Before + Nlen .. Tlen) :=
1039 Source.Data (Before .. Slen);
1042 Result.Current_Length := Max_Length;
1045 when Strings.Right =>
1046 Result.Data (1 .. Blen) := Source.Data (1 .. Blen);
1048 if Droplen > Alen then
1049 Result.Data (Before .. Max_Length) :=
1050 New_Item (New_Item'First
1051 .. New_Item'First + Max_Length - Before);
1053 Result.Data (Before .. Before + Nlen - 1) := New_Item;
1054 Result.Data (Before + Nlen .. Max_Length) :=
1055 Source.Data (Before .. Slen - Droplen);
1058 when Strings.Left =>
1059 Result.Data (Max_Length - (Alen - 1) .. Max_Length) :=
1060 Source.Data (Before .. Slen);
1062 if Droplen >= Blen then
1063 Result.Data (1 .. Max_Length - Alen) :=
1064 New_Item (New_Item'Last - (Max_Length - Alen) + 1
1068 (Blen - Droplen + 1 .. Max_Length - Alen) :=
1070 Result.Data (1 .. Blen - Droplen) :=
1071 Source.Data (Droplen + 1 .. Blen);
1074 when Strings.Error =>
1075 raise Ada.Strings.Length_Error;
1082 procedure Super_Insert
1083 (Source : in out Super_String;
1086 Drop : Strings.Truncation := Strings.Error)
1089 -- We do a double copy here because this is one of the situations
1090 -- in which we move data to the right, and at least at the moment,
1091 -- GNAT is not handling such cases correctly ???
1093 Source := Super_Insert (Source, Before, New_Item, Drop);
1100 function Super_Length (Source : Super_String) return Natural is
1102 return Source.Current_Length;
1105 ---------------------
1106 -- Super_Overwrite --
1107 ---------------------
1109 function Super_Overwrite
1110 (Source : Super_String;
1111 Position : Positive;
1113 Drop : Strings.Truncation := Strings.Error) return Super_String
1115 Max_Length : constant Positive := Source.Max_Length;
1116 Result : Super_String (Max_Length);
1117 Endpos : constant Natural := Position + New_Item'Length - 1;
1118 Slen : constant Natural := Source.Current_Length;
1122 if Position > Slen + 1 then
1123 raise Ada.Strings.Index_Error;
1125 elsif New_Item'Length = 0 then
1128 elsif Endpos <= Slen then
1129 Result.Current_Length := Source.Current_Length;
1130 Result.Data (1 .. Slen) := Source.Data (1 .. Slen);
1131 Result.Data (Position .. Endpos) := New_Item;
1134 elsif Endpos <= Max_Length then
1135 Result.Current_Length := Endpos;
1136 Result.Data (1 .. Position - 1) := Source.Data (1 .. Position - 1);
1137 Result.Data (Position .. Endpos) := New_Item;
1141 Result.Current_Length := Max_Length;
1142 Droplen := Endpos - Max_Length;
1145 when Strings.Right =>
1146 Result.Data (1 .. Position - 1) :=
1147 Source.Data (1 .. Position - 1);
1149 Result.Data (Position .. Max_Length) :=
1150 New_Item (New_Item'First .. New_Item'Last - Droplen);
1153 when Strings.Left =>
1154 if New_Item'Length >= Max_Length then
1155 Result.Data (1 .. Max_Length) :=
1156 New_Item (New_Item'Last - Max_Length + 1 ..
1161 Result.Data (1 .. Max_Length - New_Item'Length) :=
1162 Source.Data (Droplen + 1 .. Position - 1);
1164 (Max_Length - New_Item'Length + 1 .. Max_Length) :=
1169 when Strings.Error =>
1170 raise Ada.Strings.Length_Error;
1173 end Super_Overwrite;
1175 procedure Super_Overwrite
1176 (Source : in out Super_String;
1177 Position : Positive;
1179 Drop : Strings.Truncation := Strings.Error)
1181 Max_Length : constant Positive := Source.Max_Length;
1182 Endpos : constant Positive := Position + New_Item'Length - 1;
1183 Slen : constant Natural := Source.Current_Length;
1187 if Position > Slen + 1 then
1188 raise Ada.Strings.Index_Error;
1190 elsif Endpos <= Slen then
1191 Source.Data (Position .. Endpos) := New_Item;
1193 elsif Endpos <= Max_Length then
1194 Source.Data (Position .. Endpos) := New_Item;
1195 Source.Current_Length := Endpos;
1198 Source.Current_Length := Max_Length;
1199 Droplen := Endpos - Max_Length;
1202 when Strings.Right =>
1203 Source.Data (Position .. Max_Length) :=
1204 New_Item (New_Item'First .. New_Item'Last - Droplen);
1206 when Strings.Left =>
1207 if New_Item'Length > Max_Length then
1208 Source.Data (1 .. Max_Length) :=
1209 New_Item (New_Item'Last - Max_Length + 1 ..
1213 Source.Data (1 .. Max_Length - New_Item'Length) :=
1214 Source.Data (Droplen + 1 .. Position - 1);
1217 (Max_Length - New_Item'Length + 1 .. Max_Length) :=
1221 when Strings.Error =>
1222 raise Ada.Strings.Length_Error;
1225 end Super_Overwrite;
1227 ---------------------------
1228 -- Super_Replace_Element --
1229 ---------------------------
1231 procedure Super_Replace_Element
1232 (Source : in out Super_String;
1237 if Index <= Source.Current_Length then
1238 Source.Data (Index) := By;
1240 raise Ada.Strings.Index_Error;
1242 end Super_Replace_Element;
1244 -------------------------
1245 -- Super_Replace_Slice --
1246 -------------------------
1248 function Super_Replace_Slice
1249 (Source : Super_String;
1253 Drop : Strings.Truncation := Strings.Error) return Super_String
1255 Max_Length : constant Positive := Source.Max_Length;
1256 Slen : constant Natural := Source.Current_Length;
1259 if Low > Slen + 1 then
1260 raise Strings.Index_Error;
1262 elsif High < Low then
1263 return Super_Insert (Source, Low, By, Drop);
1267 Blen : constant Natural := Natural'Max (0, Low - 1);
1268 Alen : constant Natural := Natural'Max (0, Slen - High);
1269 Tlen : constant Natural := Blen + By'Length + Alen;
1270 Droplen : constant Integer := Tlen - Max_Length;
1271 Result : Super_String (Max_Length);
1273 -- Tlen is the total length of the result string before any
1274 -- truncation. Blen and Alen are the lengths of the pieces
1275 -- of the original string that end up in the result string
1276 -- before and after the replaced slice.
1279 if Droplen <= 0 then
1280 Result.Current_Length := Tlen;
1281 Result.Data (1 .. Blen) := Source.Data (1 .. Blen);
1282 Result.Data (Low .. Low + By'Length - 1) := By;
1283 Result.Data (Low + By'Length .. Tlen) :=
1284 Source.Data (High + 1 .. Slen);
1287 Result.Current_Length := Max_Length;
1290 when Strings.Right =>
1291 Result.Data (1 .. Blen) := Source.Data (1 .. Blen);
1293 if Droplen > Alen then
1294 Result.Data (Low .. Max_Length) :=
1295 By (By'First .. By'First + Max_Length - Low);
1297 Result.Data (Low .. Low + By'Length - 1) := By;
1298 Result.Data (Low + By'Length .. Max_Length) :=
1299 Source.Data (High + 1 .. Slen - Droplen);
1302 when Strings.Left =>
1303 Result.Data (Max_Length - (Alen - 1) .. Max_Length) :=
1304 Source.Data (High + 1 .. Slen);
1306 if Droplen >= Blen then
1307 Result.Data (1 .. Max_Length - Alen) :=
1308 By (By'Last - (Max_Length - Alen) + 1 .. By'Last);
1311 (Blen - Droplen + 1 .. Max_Length - Alen) := By;
1312 Result.Data (1 .. Blen - Droplen) :=
1313 Source.Data (Droplen + 1 .. Blen);
1316 when Strings.Error =>
1317 raise Ada.Strings.Length_Error;
1324 end Super_Replace_Slice;
1326 procedure Super_Replace_Slice
1327 (Source : in out Super_String;
1331 Drop : Strings.Truncation := Strings.Error)
1334 -- We do a double copy here because this is one of the situations
1335 -- in which we move data to the right, and at least at the moment,
1336 -- GNAT is not handling such cases correctly ???
1338 Source := Super_Replace_Slice (Source, Low, High, By, Drop);
1339 end Super_Replace_Slice;
1341 ---------------------
1342 -- Super_Replicate --
1343 ---------------------
1345 function Super_Replicate
1348 Drop : Truncation := Error;
1349 Max_Length : Positive) return Super_String
1351 Result : Super_String (Max_Length);
1354 if Count <= Max_Length then
1355 Result.Current_Length := Count;
1357 elsif Drop = Strings.Error then
1358 raise Ada.Strings.Length_Error;
1361 Result.Current_Length := Max_Length;
1364 Result.Data (1 .. Result.Current_Length) := (others => Item);
1366 end Super_Replicate;
1368 function Super_Replicate
1371 Drop : Truncation := Error;
1372 Max_Length : Positive) return Super_String
1374 Length : constant Integer := Count * Item'Length;
1375 Result : Super_String (Max_Length);
1379 if Length <= Max_Length then
1380 Result.Current_Length := Length;
1385 for J in 1 .. Count loop
1386 Result.Data (Indx .. Indx + Item'Length - 1) := Item;
1387 Indx := Indx + Item'Length;
1392 Result.Current_Length := Max_Length;
1395 when Strings.Right =>
1398 while Indx + Item'Length <= Max_Length + 1 loop
1399 Result.Data (Indx .. Indx + Item'Length - 1) := Item;
1400 Indx := Indx + Item'Length;
1403 Result.Data (Indx .. Max_Length) :=
1404 Item (Item'First .. Item'First + Max_Length - Indx);
1406 when Strings.Left =>
1409 while Indx - Item'Length >= 1 loop
1410 Result.Data (Indx - (Item'Length - 1) .. Indx) := Item;
1411 Indx := Indx - Item'Length;
1414 Result.Data (1 .. Indx) :=
1415 Item (Item'Last - Indx + 1 .. Item'Last);
1417 when Strings.Error =>
1418 raise Ada.Strings.Length_Error;
1423 end Super_Replicate;
1425 function Super_Replicate
1427 Item : Super_String;
1428 Drop : Strings.Truncation := Strings.Error) return Super_String
1434 Item.Data (1 .. Item.Current_Length),
1437 end Super_Replicate;
1443 function Super_Slice
1444 (Source : Super_String;
1446 High : Natural) return String
1449 -- Note: test of High > Length is in accordance with AI95-00128
1451 if Low > Source.Current_Length + 1
1452 or else High > Source.Current_Length
1456 return Source.Data (Low .. High);
1460 function Super_Slice
1461 (Source : Super_String;
1463 High : Natural) return Super_String
1465 Result : Super_String (Source.Max_Length);
1468 if Low > Source.Current_Length + 1
1469 or else High > Source.Current_Length
1473 Result.Current_Length := High - Low + 1;
1474 Result.Data (1 .. Result.Current_Length) := Source.Data (Low .. High);
1480 procedure Super_Slice
1481 (Source : Super_String;
1482 Target : out Super_String;
1487 if Low > Source.Current_Length + 1
1488 or else High > Source.Current_Length
1492 Target.Current_Length := High - Low + 1;
1493 Target.Data (1 .. Target.Current_Length) := Source.Data (Low .. High);
1502 (Source : Super_String;
1504 Pad : Character := Space;
1505 Drop : Strings.Truncation := Strings.Error) return Super_String
1507 Max_Length : constant Positive := Source.Max_Length;
1508 Result : Super_String (Max_Length);
1509 Slen : constant Natural := Source.Current_Length;
1510 Npad : constant Integer := Count - Slen;
1514 Result.Current_Length := Count;
1515 Result.Data (1 .. Count) :=
1516 Source.Data (Slen - (Count - 1) .. Slen);
1518 elsif Count <= Max_Length then
1519 Result.Current_Length := Count;
1520 Result.Data (1 .. Npad) := (others => Pad);
1521 Result.Data (Npad + 1 .. Count) := Source.Data (1 .. Slen);
1524 Result.Current_Length := Max_Length;
1527 when Strings.Right =>
1528 if Npad >= Max_Length then
1529 Result.Data := (others => Pad);
1532 Result.Data (1 .. Npad) := (others => Pad);
1533 Result.Data (Npad + 1 .. Max_Length) :=
1534 Source.Data (1 .. Max_Length - Npad);
1537 when Strings.Left =>
1538 Result.Data (1 .. Max_Length - Slen) := (others => Pad);
1539 Result.Data (Max_Length - Slen + 1 .. Max_Length) :=
1540 Source.Data (1 .. Slen);
1542 when Strings.Error =>
1543 raise Ada.Strings.Length_Error;
1550 procedure Super_Tail
1551 (Source : in out Super_String;
1553 Pad : Character := Space;
1554 Drop : Truncation := Error)
1556 Max_Length : constant Positive := Source.Max_Length;
1557 Slen : constant Natural := Source.Current_Length;
1558 Npad : constant Integer := Count - Slen;
1560 Temp : constant String (1 .. Max_Length) := Source.Data;
1564 Source.Current_Length := Count;
1565 Source.Data (1 .. Count) :=
1566 Temp (Slen - (Count - 1) .. Slen);
1568 elsif Count <= Max_Length then
1569 Source.Current_Length := Count;
1570 Source.Data (1 .. Npad) := (others => Pad);
1571 Source.Data (Npad + 1 .. Count) := Temp (1 .. Slen);
1574 Source.Current_Length := Max_Length;
1577 when Strings.Right =>
1578 if Npad >= Max_Length then
1579 Source.Data := (others => Pad);
1582 Source.Data (1 .. Npad) := (others => Pad);
1583 Source.Data (Npad + 1 .. Max_Length) :=
1584 Temp (1 .. Max_Length - Npad);
1587 when Strings.Left =>
1588 for J in 1 .. Max_Length - Slen loop
1589 Source.Data (J) := Pad;
1592 Source.Data (Max_Length - Slen + 1 .. Max_Length) :=
1595 when Strings.Error =>
1596 raise Ada.Strings.Length_Error;
1601 ---------------------
1602 -- Super_To_String --
1603 ---------------------
1605 function Super_To_String (Source : Super_String) return String is
1607 return Source.Data (1 .. Source.Current_Length);
1608 end Super_To_String;
1610 ---------------------
1611 -- Super_Translate --
1612 ---------------------
1614 function Super_Translate
1615 (Source : Super_String;
1616 Mapping : Maps.Character_Mapping) return Super_String
1618 Result : Super_String (Source.Max_Length);
1621 Result.Current_Length := Source.Current_Length;
1623 for J in 1 .. Source.Current_Length loop
1624 Result.Data (J) := Value (Mapping, Source.Data (J));
1628 end Super_Translate;
1630 procedure Super_Translate
1631 (Source : in out Super_String;
1632 Mapping : Maps.Character_Mapping)
1635 for J in 1 .. Source.Current_Length loop
1636 Source.Data (J) := Value (Mapping, Source.Data (J));
1638 end Super_Translate;
1640 function Super_Translate
1641 (Source : Super_String;
1642 Mapping : Maps.Character_Mapping_Function) return Super_String
1644 Result : Super_String (Source.Max_Length);
1647 Result.Current_Length := Source.Current_Length;
1649 for J in 1 .. Source.Current_Length loop
1650 Result.Data (J) := Mapping.all (Source.Data (J));
1654 end Super_Translate;
1656 procedure Super_Translate
1657 (Source : in out Super_String;
1658 Mapping : Maps.Character_Mapping_Function)
1661 for J in 1 .. Source.Current_Length loop
1662 Source.Data (J) := Mapping.all (Source.Data (J));
1664 end Super_Translate;
1671 (Source : Super_String;
1672 Side : Trim_End) return Super_String
1674 Result : Super_String (Source.Max_Length);
1675 Last : Natural := Source.Current_Length;
1676 First : Positive := 1;
1679 if Side = Left or else Side = Both then
1680 while First <= Last and then Source.Data (First) = ' ' loop
1685 if Side = Right or else Side = Both then
1686 while Last >= First and then Source.Data (Last) = ' ' loop
1691 Result.Current_Length := Last - First + 1;
1692 Result.Data (1 .. Result.Current_Length) := Source.Data (First .. Last);
1696 procedure Super_Trim
1697 (Source : in out Super_String;
1700 Max_Length : constant Positive := Source.Max_Length;
1701 Last : Natural := Source.Current_Length;
1702 First : Positive := 1;
1703 Temp : String (1 .. Max_Length);
1706 Temp (1 .. Last) := Source.Data (1 .. Last);
1708 if Side = Left or else Side = Both then
1709 while First <= Last and then Temp (First) = ' ' loop
1714 if Side = Right or else Side = Both then
1715 while Last >= First and then Temp (Last) = ' ' loop
1720 Source.Data := (others => ASCII.NUL);
1721 Source.Current_Length := Last - First + 1;
1722 Source.Data (1 .. Source.Current_Length) := Temp (First .. Last);
1726 (Source : Super_String;
1727 Left : Maps.Character_Set;
1728 Right : Maps.Character_Set) return Super_String
1730 Result : Super_String (Source.Max_Length);
1733 for First in 1 .. Source.Current_Length loop
1734 if not Is_In (Source.Data (First), Left) then
1735 for Last in reverse First .. Source.Current_Length loop
1736 if not Is_In (Source.Data (Last), Right) then
1737 Result.Current_Length := Last - First + 1;
1738 Result.Data (1 .. Result.Current_Length) :=
1739 Source.Data (First .. Last);
1746 Result.Current_Length := 0;
1750 procedure Super_Trim
1751 (Source : in out Super_String;
1752 Left : Maps.Character_Set;
1753 Right : Maps.Character_Set)
1756 for First in 1 .. Source.Current_Length loop
1757 if not Is_In (Source.Data (First), Left) then
1758 for Last in reverse First .. Source.Current_Length loop
1759 if not Is_In (Source.Data (Last), Right) then
1761 Source.Current_Length := Last;
1764 Source.Current_Length := Last - First + 1;
1765 Source.Data (1 .. Source.Current_Length) :=
1766 Source.Data (First .. Last);
1768 for J in Source.Current_Length + 1 ..
1771 Source.Data (J) := ASCII.NUL;
1779 Source.Current_Length := 0;
1784 Source.Current_Length := 0;
1794 Max_Length : Positive) return Super_String
1796 Result : Super_String (Max_Length);
1799 if Left > Max_Length then
1800 raise Ada.Strings.Length_Error;
1803 Result.Current_Length := Left;
1805 for J in 1 .. Left loop
1806 Result.Data (J) := Right;
1816 Max_Length : Positive) return Super_String
1818 Result : Super_String (Max_Length);
1819 Pos : Positive := 1;
1820 Rlen : constant Natural := Right'Length;
1821 Nlen : constant Natural := Left * Rlen;
1824 if Nlen > Max_Length then
1825 raise Ada.Strings.Index_Error;
1828 Result.Current_Length := Nlen;
1831 for J in 1 .. Left loop
1832 Result.Data (Pos .. Pos + Rlen - 1) := Right;
1843 Right : Super_String) return Super_String
1845 Result : Super_String (Right.Max_Length);
1846 Pos : Positive := 1;
1847 Rlen : constant Natural := Right.Current_Length;
1848 Nlen : constant Natural := Left * Rlen;
1851 if Nlen > Right.Max_Length then
1852 raise Ada.Strings.Length_Error;
1855 Result.Current_Length := Nlen;
1858 for J in 1 .. Left loop
1859 Result.Data (Pos .. Pos + Rlen - 1) :=
1860 Right.Data (1 .. Rlen);
1869 ---------------------
1870 -- To_Super_String --
1871 ---------------------
1873 function To_Super_String
1875 Max_Length : Natural;
1876 Drop : Truncation := Error) return Super_String
1878 Result : Super_String (Max_Length);
1879 Slen : constant Natural := Source'Length;
1882 if Slen <= Max_Length then
1883 Result.Current_Length := Slen;
1884 Result.Data (1 .. Slen) := Source;
1888 when Strings.Right =>
1889 Result.Current_Length := Max_Length;
1890 Result.Data (1 .. Max_Length) :=
1891 Source (Source'First .. Source'First - 1 + Max_Length);
1893 when Strings.Left =>
1894 Result.Current_Length := Max_Length;
1895 Result.Data (1 .. Max_Length) :=
1896 Source (Source'Last - (Max_Length - 1) .. Source'Last);
1898 when Strings.Error =>
1899 raise Ada.Strings.Length_Error;
1904 end To_Super_String;
1906 end Ada.Strings.Superbounded;