1 ------------------------------------------------------------------------------
3 -- GNAT RUNTIME 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 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.Superbounded is
48 Result : Super_String (Left.Max_Length);
49 Llen : constant Natural := Left.Current_Length;
50 Rlen : constant Natural := Right.Current_Length;
51 Nlen : constant Natural := Llen + Rlen;
54 if Nlen > Left.Max_Length then
55 raise Ada.Strings.Length_Error;
57 Result.Current_Length := Nlen;
58 Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
59 Result.Data (Llen + 1 .. Nlen) := Right.Data (1 .. Rlen);
70 Result : Super_String (Left.Max_Length);
71 Llen : constant Natural := Left.Current_Length;
73 Nlen : constant Natural := Llen + Right'Length;
76 if Nlen > Left.Max_Length then
77 raise Ada.Strings.Length_Error;
79 Result.Current_Length := Nlen;
80 Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
81 Result.Data (Llen + 1 .. Nlen) := Right;
91 Result : Super_String (Right.Max_Length);
92 Llen : constant Natural := Left'Length;
93 Rlen : constant Natural := Right.Current_Length;
94 Nlen : constant Natural := Llen + Rlen;
97 if Nlen > Right.Max_Length then
98 raise Ada.Strings.Length_Error;
100 Result.Current_Length := Nlen;
101 Result.Data (1 .. Llen) := Left;
102 Result.Data (Llen + 1 .. Nlen) := Right.Data (1 .. Rlen);
109 (Left : Super_String;
113 Result : Super_String (Left.Max_Length);
114 Llen : constant Natural := Left.Current_Length;
117 if Llen = Left.Max_Length then
118 raise Ada.Strings.Length_Error;
120 Result.Current_Length := Llen + 1;
121 Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
122 Result.Data (Result.Current_Length) := Right;
130 Right : Super_String)
133 Result : Super_String (Right.Max_Length);
134 Rlen : constant Natural := Right.Current_Length;
137 if Rlen = Right.Max_Length then
138 raise Ada.Strings.Length_Error;
140 Result.Current_Length := Rlen + 1;
141 Result.Data (1) := Left;
142 Result.Data (2 .. Result.Current_Length) := Right.Data (1 .. Rlen);
152 function "=" (Left, Right : Super_String) return Boolean is
154 return Left.Current_Length = Right.Current_Length
155 and then Left.Data (1 .. Left.Current_Length) =
156 Right.Data (1 .. Right.Current_Length);
159 function Equal (Left : Super_String; Right : String)
162 return Left.Current_Length = Right'Length
163 and then Left.Data (1 .. Left.Current_Length) = Right;
166 function Equal (Left : String; Right : Super_String)
169 return Left'Length = Right.Current_Length
170 and then Left = Right.Data (1 .. Right.Current_Length);
177 function Greater (Left, Right : Super_String) return Boolean is
179 return Left.Data (1 .. Left.Current_Length) >
180 Right.Data (1 .. Right.Current_Length);
184 (Left : Super_String;
189 return Left.Data (1 .. Left.Current_Length) > Right;
194 Right : Super_String)
198 return Left > Right.Data (1 .. Right.Current_Length);
201 ----------------------
202 -- Greater_Or_Equal --
203 ----------------------
205 function Greater_Or_Equal (Left, Right : Super_String) return Boolean is
207 return Left.Data (1 .. Left.Current_Length) >=
208 Right.Data (1 .. Right.Current_Length);
209 end Greater_Or_Equal;
211 function Greater_Or_Equal
212 (Left : Super_String;
217 return Left.Data (1 .. Left.Current_Length) >= Right;
218 end Greater_Or_Equal;
220 function Greater_Or_Equal
222 Right : Super_String)
226 return Left >= Right.Data (1 .. Right.Current_Length);
227 end Greater_Or_Equal;
233 function Less (Left, Right : Super_String) return Boolean is
235 return Left.Data (1 .. Left.Current_Length) <
236 Right.Data (1 .. Right.Current_Length);
240 (Left : Super_String;
245 return Left.Data (1 .. Left.Current_Length) < Right;
250 Right : Super_String)
254 return Left < Right.Data (1 .. Right.Current_Length);
261 function Less_Or_Equal (Left, Right : Super_String) return Boolean is
263 return Left.Data (1 .. Left.Current_Length) <=
264 Right.Data (1 .. Right.Current_Length);
267 function Less_Or_Equal
268 (Left : Super_String;
273 return Left.Data (1 .. Left.Current_Length) <= Right;
276 function Less_Or_Equal
278 Right : Super_String)
282 return Left <= Right.Data (1 .. Right.Current_Length);
289 -- Case of Super_String and Super_String
291 function Super_Append
292 (Left, Right : Super_String;
293 Drop : Strings.Truncation := Strings.Error)
296 Max_Length : constant Positive := Left.Max_Length;
297 Result : Super_String (Max_Length);
298 Llen : constant Natural := Left.Current_Length;
299 Rlen : constant Natural := Right.Current_Length;
300 Nlen : constant Natural := Llen + Rlen;
303 if Nlen <= Max_Length then
304 Result.Current_Length := Nlen;
305 Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
306 Result.Data (Llen + 1 .. Nlen) := Right.Data (1 .. Rlen);
309 Result.Current_Length := Max_Length;
312 when Strings.Right =>
313 if Llen >= Max_Length then -- only case is Llen = Max_Length
314 Result.Data := Left.Data;
317 Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
318 Result.Data (Llen + 1 .. Max_Length) :=
319 Right.Data (1 .. Max_Length - Llen);
323 if Rlen >= Max_Length then -- only case is Rlen = Max_Length
324 Result.Data := Right.Data;
327 Result.Data (1 .. Max_Length - Rlen) :=
328 Left.Data (Llen - (Max_Length - Rlen - 1) .. Llen);
329 Result.Data (Max_Length - Rlen + 1 .. Max_Length) :=
330 Right.Data (1 .. Rlen);
333 when Strings.Error =>
334 raise Ada.Strings.Length_Error;
341 procedure Super_Append
342 (Source : in out Super_String;
343 New_Item : Super_String;
344 Drop : Truncation := Error)
346 Max_Length : constant Positive := Source.Max_Length;
347 Llen : constant Natural := Source.Current_Length;
348 Rlen : constant Natural := New_Item.Current_Length;
349 Nlen : constant Natural := Llen + Rlen;
352 if Nlen <= Max_Length then
353 Source.Current_Length := Nlen;
354 Source.Data (Llen + 1 .. Nlen) := New_Item.Data (1 .. Rlen);
357 Source.Current_Length := Max_Length;
360 when Strings.Right =>
361 if Llen < Max_Length then
362 Source.Data (Llen + 1 .. Max_Length) :=
363 New_Item.Data (1 .. Max_Length - Llen);
367 if Rlen >= Max_Length then -- only case is Rlen = Max_Length
368 Source.Data := New_Item.Data;
371 Source.Data (1 .. Max_Length - Rlen) :=
372 Source.Data (Llen - (Max_Length - Rlen - 1) .. Llen);
373 Source.Data (Max_Length - Rlen + 1 .. Max_Length) :=
374 New_Item.Data (1 .. Rlen);
377 when Strings.Error =>
378 raise Ada.Strings.Length_Error;
384 -- Case of Super_String and String
386 function Super_Append
387 (Left : Super_String;
389 Drop : Strings.Truncation := Strings.Error)
392 Max_Length : constant Positive := Left.Max_Length;
393 Result : Super_String (Max_Length);
394 Llen : constant Natural := Left.Current_Length;
395 Rlen : constant Natural := Right'Length;
396 Nlen : constant Natural := Llen + Rlen;
399 if Nlen <= Max_Length then
400 Result.Current_Length := Nlen;
401 Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
402 Result.Data (Llen + 1 .. Nlen) := Right;
405 Result.Current_Length := Max_Length;
408 when Strings.Right =>
409 if Llen >= Max_Length then -- only case is Llen = Max_Length
410 Result.Data := Left.Data;
413 Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
414 Result.Data (Llen + 1 .. Max_Length) :=
415 Right (Right'First .. Right'First - 1 +
421 if Rlen >= Max_Length then
422 Result.Data (1 .. Max_Length) :=
423 Right (Right'Last - (Max_Length - 1) .. Right'Last);
426 Result.Data (1 .. Max_Length - Rlen) :=
427 Left.Data (Llen - (Max_Length - Rlen - 1) .. Llen);
428 Result.Data (Max_Length - Rlen + 1 .. Max_Length) :=
432 when Strings.Error =>
433 raise Ada.Strings.Length_Error;
440 procedure Super_Append
441 (Source : in out Super_String;
443 Drop : Truncation := Error)
445 Max_Length : constant Positive := Source.Max_Length;
446 Llen : constant Natural := Source.Current_Length;
447 Rlen : constant Natural := New_Item'Length;
448 Nlen : constant Natural := Llen + Rlen;
451 if Nlen <= Max_Length then
452 Source.Current_Length := Nlen;
453 Source.Data (Llen + 1 .. Nlen) := New_Item;
456 Source.Current_Length := Max_Length;
459 when Strings.Right =>
460 if Llen < Max_Length then
461 Source.Data (Llen + 1 .. Max_Length) :=
462 New_Item (New_Item'First ..
463 New_Item'First - 1 + Max_Length - Llen);
467 if Rlen >= Max_Length then
468 Source.Data (1 .. Max_Length) :=
469 New_Item (New_Item'Last - (Max_Length - 1) ..
473 Source.Data (1 .. Max_Length - Rlen) :=
474 Source.Data (Llen - (Max_Length - Rlen - 1) .. Llen);
475 Source.Data (Max_Length - Rlen + 1 .. Max_Length) :=
479 when Strings.Error =>
480 raise Ada.Strings.Length_Error;
486 -- Case of String and Super_String
488 function Super_Append
490 Right : Super_String;
491 Drop : Strings.Truncation := Strings.Error)
494 Max_Length : constant Positive := Right.Max_Length;
495 Result : Super_String (Max_Length);
496 Llen : constant Natural := Left'Length;
497 Rlen : constant Natural := Right.Current_Length;
498 Nlen : constant Natural := Llen + Rlen;
501 if Nlen <= Max_Length then
502 Result.Current_Length := Nlen;
503 Result.Data (1 .. Llen) := Left;
504 Result.Data (Llen + 1 .. Llen + Rlen) := Right.Data (1 .. Rlen);
507 Result.Current_Length := Max_Length;
510 when Strings.Right =>
511 if Llen >= Max_Length then
512 Result.Data (1 .. Max_Length) :=
513 Left (Left'First .. Left'First + (Max_Length - 1));
516 Result.Data (1 .. Llen) := Left;
517 Result.Data (Llen + 1 .. Max_Length) :=
518 Right.Data (1 .. Max_Length - Llen);
522 if Rlen >= Max_Length then
523 Result.Data (1 .. Max_Length) :=
524 Right.Data (Rlen - (Max_Length - 1) .. Rlen);
527 Result.Data (1 .. Max_Length - Rlen) :=
528 Left (Left'Last - (Max_Length - Rlen - 1) .. Left'Last);
529 Result.Data (Max_Length - Rlen + 1 .. Max_Length) :=
530 Right.Data (1 .. Rlen);
533 when Strings.Error =>
534 raise Ada.Strings.Length_Error;
541 -- Case of Super_String and Character
543 function Super_Append
544 (Left : Super_String;
546 Drop : Strings.Truncation := Strings.Error)
549 Max_Length : constant Positive := Left.Max_Length;
550 Result : Super_String (Max_Length);
551 Llen : constant Natural := Left.Current_Length;
554 if Llen < Max_Length then
555 Result.Current_Length := Llen + 1;
556 Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
557 Result.Data (Llen + 1) := Right;
562 when Strings.Right =>
566 Result.Current_Length := Max_Length;
567 Result.Data (1 .. Max_Length - 1) :=
568 Left.Data (2 .. Max_Length);
569 Result.Data (Max_Length) := Right;
572 when Strings.Error =>
573 raise Ada.Strings.Length_Error;
578 procedure Super_Append
579 (Source : in out Super_String;
580 New_Item : Character;
581 Drop : Truncation := Error)
583 Max_Length : constant Positive := Source.Max_Length;
584 Llen : constant Natural := Source.Current_Length;
587 if Llen < Max_Length then
588 Source.Current_Length := Llen + 1;
589 Source.Data (Llen + 1) := New_Item;
592 Source.Current_Length := Max_Length;
595 when Strings.Right =>
599 Source.Data (1 .. Max_Length - 1) :=
600 Source.Data (2 .. Max_Length);
601 Source.Data (Max_Length) := New_Item;
603 when Strings.Error =>
604 raise Ada.Strings.Length_Error;
610 -- Case of Character and Super_String
612 function Super_Append
614 Right : Super_String;
615 Drop : Strings.Truncation := Strings.Error)
618 Max_Length : constant Positive := Right.Max_Length;
619 Result : Super_String (Max_Length);
620 Rlen : constant Natural := Right.Current_Length;
623 if Rlen < Max_Length then
624 Result.Current_Length := Rlen + 1;
625 Result.Data (1) := Left;
626 Result.Data (2 .. Rlen + 1) := Right.Data (1 .. Rlen);
631 when Strings.Right =>
632 Result.Current_Length := Max_Length;
633 Result.Data (1) := Left;
634 Result.Data (2 .. Max_Length) :=
635 Right.Data (1 .. Max_Length - 1);
641 when Strings.Error =>
642 raise Ada.Strings.Length_Error;
652 (Source : Super_String;
654 Mapping : Maps.Character_Mapping := Maps.Identity)
660 (Source.Data (1 .. Source.Current_Length), Pattern, Mapping);
664 (Source : Super_String;
666 Mapping : Maps.Character_Mapping_Function)
672 (Source.Data (1 .. Source.Current_Length), Pattern, Mapping);
676 (Source : Super_String;
677 Set : Maps.Character_Set)
681 return Search.Count (Source.Data (1 .. Source.Current_Length), Set);
688 function Super_Delete
689 (Source : Super_String;
694 Result : Super_String (Source.Max_Length);
695 Slen : constant Natural := Source.Current_Length;
696 Num_Delete : constant Integer := Through - From + 1;
699 if Num_Delete <= 0 then
702 elsif From > Slen + 1 then
703 raise Ada.Strings.Index_Error;
705 elsif Through >= Slen then
706 Result.Current_Length := From - 1;
707 Result.Data (1 .. From - 1) := Source.Data (1 .. From - 1);
711 Result.Current_Length := Slen - Num_Delete;
712 Result.Data (1 .. From - 1) := Source.Data (1 .. From - 1);
713 Result.Data (From .. Result.Current_Length) :=
714 Source.Data (Through + 1 .. Slen);
719 procedure Super_Delete
720 (Source : in out Super_String;
724 Slen : constant Natural := Source.Current_Length;
725 Num_Delete : constant Integer := Through - From + 1;
728 if Num_Delete <= 0 then
731 elsif From > Slen + 1 then
732 raise Ada.Strings.Index_Error;
734 elsif Through >= Slen then
735 Source.Current_Length := From - 1;
738 Source.Current_Length := Slen - Num_Delete;
739 Source.Data (From .. Source.Current_Length) :=
740 Source.Data (Through + 1 .. Slen);
748 function Super_Element
749 (Source : Super_String;
754 if Index in 1 .. Source.Current_Length then
755 return Source.Data (Index);
757 raise Strings.Index_Error;
761 ----------------------
762 -- Super_Find_Token --
763 ----------------------
765 procedure Super_Find_Token
766 (Source : Super_String;
767 Set : Maps.Character_Set;
768 Test : Strings.Membership;
769 First : out Positive;
774 (Source.Data (1 .. Source.Current_Length), Set, Test, First, Last);
775 end Super_Find_Token;
782 (Source : Super_String;
784 Pad : Character := Space;
785 Drop : Strings.Truncation := Strings.Error)
788 Max_Length : constant Positive := Source.Max_Length;
789 Result : Super_String (Max_Length);
790 Slen : constant Natural := Source.Current_Length;
791 Npad : constant Integer := Count - Slen;
795 Result.Current_Length := Count;
796 Result.Data (1 .. Count) := Source.Data (1 .. Count);
798 elsif Count <= Max_Length then
799 Result.Current_Length := Count;
800 Result.Data (1 .. Slen) := Source.Data (1 .. Slen);
801 Result.Data (Slen + 1 .. Count) := (others => Pad);
804 Result.Current_Length := Max_Length;
807 when Strings.Right =>
808 Result.Data (1 .. Slen) := Source.Data (1 .. Slen);
809 Result.Data (Slen + 1 .. Max_Length) := (others => Pad);
812 if Npad >= Max_Length then
813 Result.Data := (others => Pad);
816 Result.Data (1 .. Max_Length - Npad) :=
817 Source.Data (Count - Max_Length + 1 .. Slen);
818 Result.Data (Max_Length - Npad + 1 .. Max_Length) :=
822 when Strings.Error =>
823 raise Ada.Strings.Length_Error;
831 (Source : in out Super_String;
833 Pad : Character := Space;
834 Drop : Truncation := Error)
836 Max_Length : constant Positive := Source.Max_Length;
837 Slen : constant Natural := Source.Current_Length;
838 Npad : constant Integer := Count - Slen;
839 Temp : String (1 .. Max_Length);
843 Source.Current_Length := Count;
845 elsif Count <= Max_Length then
846 Source.Current_Length := Count;
847 Source.Data (Slen + 1 .. Count) := (others => Pad);
850 Source.Current_Length := Max_Length;
853 when Strings.Right =>
854 Source.Data (Slen + 1 .. Max_Length) := (others => Pad);
857 if Npad > Max_Length then
858 Source.Data := (others => Pad);
862 Source.Data (1 .. Max_Length - Npad) :=
863 Temp (Count - Max_Length + 1 .. Slen);
865 for J in Max_Length - Npad + 1 .. Max_Length loop
866 Source.Data (J) := Pad;
870 when Strings.Error =>
871 raise Ada.Strings.Length_Error;
881 (Source : Super_String;
883 Going : Strings.Direction := Strings.Forward;
884 Mapping : Maps.Character_Mapping := Maps.Identity)
889 (Source.Data (1 .. Source.Current_Length), Pattern, Going, Mapping);
893 (Source : Super_String;
895 Going : Direction := Forward;
896 Mapping : Maps.Character_Mapping_Function)
901 (Source.Data (1 .. Source.Current_Length), Pattern, Going, Mapping);
905 (Source : Super_String;
906 Set : Maps.Character_Set;
907 Test : Strings.Membership := Strings.Inside;
908 Going : Strings.Direction := Strings.Forward)
913 (Source.Data (1 .. Source.Current_Length), Set, Test, Going);
916 ---------------------------
917 -- Super_Index_Non_Blank --
918 ---------------------------
920 function Super_Index_Non_Blank
921 (Source : Super_String;
922 Going : Strings.Direction := Strings.Forward)
927 Search.Index_Non_Blank
928 (Source.Data (1 .. Source.Current_Length), Going);
929 end Super_Index_Non_Blank;
935 function Super_Insert
936 (Source : Super_String;
939 Drop : Strings.Truncation := Strings.Error)
942 Max_Length : constant Positive := Source.Max_Length;
943 Result : Super_String (Max_Length);
944 Slen : constant Natural := Source.Current_Length;
945 Nlen : constant Natural := New_Item'Length;
946 Tlen : constant Natural := Slen + Nlen;
947 Blen : constant Natural := Before - 1;
948 Alen : constant Integer := Slen - Blen;
949 Droplen : constant Integer := Tlen - Max_Length;
951 -- Tlen is the length of the total string before possible truncation.
952 -- Blen, Alen are the lengths of the before and after pieces of the
957 raise Ada.Strings.Index_Error;
959 elsif Droplen <= 0 then
960 Result.Current_Length := Tlen;
961 Result.Data (1 .. Blen) := Source.Data (1 .. Blen);
962 Result.Data (Before .. Before + Nlen - 1) := New_Item;
963 Result.Data (Before + Nlen .. Tlen) :=
964 Source.Data (Before .. Slen);
967 Result.Current_Length := Max_Length;
970 when Strings.Right =>
971 Result.Data (1 .. Blen) := Source.Data (1 .. Blen);
973 if Droplen > Alen then
974 Result.Data (Before .. Max_Length) :=
975 New_Item (New_Item'First
976 .. New_Item'First + Max_Length - Before);
978 Result.Data (Before .. Before + Nlen - 1) := New_Item;
979 Result.Data (Before + Nlen .. Max_Length) :=
980 Source.Data (Before .. Slen - Droplen);
984 Result.Data (Max_Length - (Alen - 1) .. Max_Length) :=
985 Source.Data (Before .. Slen);
987 if Droplen >= Blen then
988 Result.Data (1 .. Max_Length - Alen) :=
989 New_Item (New_Item'Last - (Max_Length - Alen) + 1
993 (Blen - Droplen + 1 .. Max_Length - Alen) :=
995 Result.Data (1 .. Blen - Droplen) :=
996 Source.Data (Droplen + 1 .. Blen);
999 when Strings.Error =>
1000 raise Ada.Strings.Length_Error;
1007 procedure Super_Insert
1008 (Source : in out Super_String;
1011 Drop : Strings.Truncation := Strings.Error)
1014 -- We do a double copy here because this is one of the situations
1015 -- in which we move data to the right, and at least at the moment,
1016 -- GNAT is not handling such cases correctly ???
1018 Source := Super_Insert (Source, Before, New_Item, Drop);
1025 function Super_Length (Source : Super_String) return Natural is
1027 return Source.Current_Length;
1030 ---------------------
1031 -- Super_Overwrite --
1032 ---------------------
1034 function Super_Overwrite
1035 (Source : Super_String;
1036 Position : Positive;
1038 Drop : Strings.Truncation := Strings.Error)
1041 Max_Length : constant Positive := Source.Max_Length;
1042 Result : Super_String (Max_Length);
1043 Endpos : constant Natural := Position + New_Item'Length - 1;
1044 Slen : constant Natural := Source.Current_Length;
1048 if Position > Slen + 1 then
1049 raise Ada.Strings.Index_Error;
1051 elsif New_Item'Length = 0 then
1054 elsif Endpos <= Slen then
1055 Result.Current_Length := Source.Current_Length;
1056 Result.Data (1 .. Slen) := Source.Data (1 .. Slen);
1057 Result.Data (Position .. Endpos) := New_Item;
1060 elsif Endpos <= Max_Length then
1061 Result.Current_Length := Endpos;
1062 Result.Data (1 .. Position - 1) := Source.Data (1 .. Position - 1);
1063 Result.Data (Position .. Endpos) := New_Item;
1067 Result.Current_Length := Max_Length;
1068 Droplen := Endpos - Max_Length;
1071 when Strings.Right =>
1072 Result.Data (1 .. Position - 1) :=
1073 Source.Data (1 .. Position - 1);
1075 Result.Data (Position .. Max_Length) :=
1076 New_Item (New_Item'First .. New_Item'Last - Droplen);
1079 when Strings.Left =>
1080 if New_Item'Length >= Max_Length then
1081 Result.Data (1 .. Max_Length) :=
1082 New_Item (New_Item'Last - Max_Length + 1 ..
1087 Result.Data (1 .. Max_Length - New_Item'Length) :=
1088 Source.Data (Droplen + 1 .. Position - 1);
1090 (Max_Length - New_Item'Length + 1 .. Max_Length) :=
1095 when Strings.Error =>
1096 raise Ada.Strings.Length_Error;
1099 end Super_Overwrite;
1101 procedure Super_Overwrite
1102 (Source : in out Super_String;
1103 Position : Positive;
1105 Drop : Strings.Truncation := Strings.Error)
1107 Max_Length : constant Positive := Source.Max_Length;
1108 Endpos : constant Positive := Position + New_Item'Length - 1;
1109 Slen : constant Natural := Source.Current_Length;
1113 if Position > Slen + 1 then
1114 raise Ada.Strings.Index_Error;
1116 elsif Endpos <= Slen then
1117 Source.Data (Position .. Endpos) := New_Item;
1119 elsif Endpos <= Max_Length then
1120 Source.Data (Position .. Endpos) := New_Item;
1121 Source.Current_Length := Endpos;
1124 Source.Current_Length := Max_Length;
1125 Droplen := Endpos - Max_Length;
1128 when Strings.Right =>
1129 Source.Data (Position .. Max_Length) :=
1130 New_Item (New_Item'First .. New_Item'Last - Droplen);
1132 when Strings.Left =>
1133 if New_Item'Length > Max_Length then
1134 Source.Data (1 .. Max_Length) :=
1135 New_Item (New_Item'Last - Max_Length + 1 ..
1139 Source.Data (1 .. Max_Length - New_Item'Length) :=
1140 Source.Data (Droplen + 1 .. Position - 1);
1143 (Max_Length - New_Item'Length + 1 .. Max_Length) :=
1147 when Strings.Error =>
1148 raise Ada.Strings.Length_Error;
1151 end Super_Overwrite;
1153 ---------------------------
1154 -- Super_Replace_Element --
1155 ---------------------------
1157 procedure Super_Replace_Element
1158 (Source : in out Super_String;
1163 if Index <= Source.Current_Length then
1164 Source.Data (Index) := By;
1166 raise Ada.Strings.Index_Error;
1168 end Super_Replace_Element;
1170 -------------------------
1171 -- Super_Replace_Slice --
1172 -------------------------
1174 function Super_Replace_Slice
1175 (Source : Super_String;
1179 Drop : Strings.Truncation := Strings.Error)
1182 Max_Length : constant Positive := Source.Max_Length;
1183 Slen : constant Natural := Source.Current_Length;
1186 if Low > Slen + 1 then
1187 raise Strings.Index_Error;
1189 elsif High < Low then
1190 return Super_Insert (Source, Low, By, Drop);
1194 Blen : constant Natural := Natural'Max (0, Low - 1);
1195 Alen : constant Natural := Natural'Max (0, Slen - High);
1196 Tlen : constant Natural := Blen + By'Length + Alen;
1197 Droplen : constant Integer := Tlen - Max_Length;
1198 Result : Super_String (Max_Length);
1200 -- Tlen is the total length of the result string before any
1201 -- truncation. Blen and Alen are the lengths of the pieces
1202 -- of the original string that end up in the result string
1203 -- before and after the replaced slice.
1206 if Droplen <= 0 then
1207 Result.Current_Length := Tlen;
1208 Result.Data (1 .. Blen) := Source.Data (1 .. Blen);
1209 Result.Data (Low .. Low + By'Length - 1) := By;
1210 Result.Data (Low + By'Length .. Tlen) :=
1211 Source.Data (High + 1 .. Slen);
1214 Result.Current_Length := Max_Length;
1217 when Strings.Right =>
1218 Result.Data (1 .. Blen) := Source.Data (1 .. Blen);
1220 if Droplen > Alen then
1221 Result.Data (Low .. Max_Length) :=
1222 By (By'First .. By'First + Max_Length - Low);
1224 Result.Data (Low .. Low + By'Length - 1) := By;
1225 Result.Data (Low + By'Length .. Max_Length) :=
1226 Source.Data (High + 1 .. Slen - Droplen);
1229 when Strings.Left =>
1230 Result.Data (Max_Length - (Alen - 1) .. Max_Length) :=
1231 Source.Data (High + 1 .. Slen);
1233 if Droplen >= Blen then
1234 Result.Data (1 .. Max_Length - Alen) :=
1235 By (By'Last - (Max_Length - Alen) + 1 .. By'Last);
1238 (Blen - Droplen + 1 .. Max_Length - Alen) := By;
1239 Result.Data (1 .. Blen - Droplen) :=
1240 Source.Data (Droplen + 1 .. Blen);
1243 when Strings.Error =>
1244 raise Ada.Strings.Length_Error;
1251 end Super_Replace_Slice;
1253 procedure Super_Replace_Slice
1254 (Source : in out Super_String;
1258 Drop : Strings.Truncation := Strings.Error)
1261 -- We do a double copy here because this is one of the situations
1262 -- in which we move data to the right, and at least at the moment,
1263 -- GNAT is not handling such cases correctly ???
1265 Source := Super_Replace_Slice (Source, Low, High, By, Drop);
1266 end Super_Replace_Slice;
1268 ---------------------
1269 -- Super_Replicate --
1270 ---------------------
1272 function Super_Replicate
1275 Drop : Truncation := Error;
1276 Max_Length : Positive)
1279 Result : Super_String (Max_Length);
1282 if Count <= Max_Length then
1283 Result.Current_Length := Count;
1285 elsif Drop = Strings.Error then
1286 raise Ada.Strings.Length_Error;
1289 Result.Current_Length := Max_Length;
1292 Result.Data (1 .. Result.Current_Length) := (others => Item);
1294 end Super_Replicate;
1296 function Super_Replicate
1299 Drop : Truncation := Error;
1300 Max_Length : Positive)
1303 Length : constant Integer := Count * Item'Length;
1304 Result : Super_String (Max_Length);
1308 if Length <= Max_Length then
1309 Result.Current_Length := Length;
1314 for J in 1 .. Count loop
1315 Result.Data (Indx .. Indx + Item'Length - 1) := Item;
1316 Indx := Indx + Item'Length;
1321 Result.Current_Length := Max_Length;
1324 when Strings.Right =>
1327 while Indx + Item'Length <= Max_Length + 1 loop
1328 Result.Data (Indx .. Indx + Item'Length - 1) := Item;
1329 Indx := Indx + Item'Length;
1332 Result.Data (Indx .. Max_Length) :=
1333 Item (Item'First .. Item'First + Max_Length - Indx);
1335 when Strings.Left =>
1338 while Indx - Item'Length >= 1 loop
1339 Result.Data (Indx - (Item'Length - 1) .. Indx) := Item;
1340 Indx := Indx - Item'Length;
1343 Result.Data (1 .. Indx) :=
1344 Item (Item'Last - Indx + 1 .. Item'Last);
1346 when Strings.Error =>
1347 raise Ada.Strings.Length_Error;
1352 end Super_Replicate;
1354 function Super_Replicate
1356 Item : Super_String;
1357 Drop : Strings.Truncation := Strings.Error)
1364 Item.Data (1 .. Item.Current_Length),
1367 end Super_Replicate;
1373 function Super_Slice
1374 (Source : Super_String;
1380 -- Note: test of High > Length is in accordance with AI95-00128
1382 if Low > Source.Current_Length + 1
1383 or else High > Source.Current_Length
1387 return Source.Data (Low .. High);
1396 (Source : Super_String;
1398 Pad : Character := Space;
1399 Drop : Strings.Truncation := Strings.Error)
1402 Max_Length : constant Positive := Source.Max_Length;
1403 Result : Super_String (Max_Length);
1404 Slen : constant Natural := Source.Current_Length;
1405 Npad : constant Integer := Count - Slen;
1409 Result.Current_Length := Count;
1410 Result.Data (1 .. Count) :=
1411 Source.Data (Slen - (Count - 1) .. Slen);
1413 elsif Count <= Max_Length then
1414 Result.Current_Length := Count;
1415 Result.Data (1 .. Npad) := (others => Pad);
1416 Result.Data (Npad + 1 .. Count) := Source.Data (1 .. Slen);
1419 Result.Current_Length := Max_Length;
1422 when Strings.Right =>
1423 if Npad >= Max_Length then
1424 Result.Data := (others => Pad);
1427 Result.Data (1 .. Npad) := (others => Pad);
1428 Result.Data (Npad + 1 .. Max_Length) :=
1429 Source.Data (1 .. Max_Length - Npad);
1432 when Strings.Left =>
1433 Result.Data (1 .. Max_Length - Slen) := (others => Pad);
1434 Result.Data (Max_Length - Slen + 1 .. Max_Length) :=
1435 Source.Data (1 .. Slen);
1437 when Strings.Error =>
1438 raise Ada.Strings.Length_Error;
1445 procedure Super_Tail
1446 (Source : in out Super_String;
1448 Pad : Character := Space;
1449 Drop : Truncation := Error)
1451 Max_Length : constant Positive := Source.Max_Length;
1452 Slen : constant Natural := Source.Current_Length;
1453 Npad : constant Integer := Count - Slen;
1455 Temp : constant String (1 .. Max_Length) := Source.Data;
1459 Source.Current_Length := Count;
1460 Source.Data (1 .. Count) :=
1461 Temp (Slen - (Count - 1) .. Slen);
1463 elsif Count <= Max_Length then
1464 Source.Current_Length := Count;
1465 Source.Data (1 .. Npad) := (others => Pad);
1466 Source.Data (Npad + 1 .. Count) := Temp (1 .. Slen);
1469 Source.Current_Length := Max_Length;
1472 when Strings.Right =>
1473 if Npad >= Max_Length then
1474 Source.Data := (others => Pad);
1477 Source.Data (1 .. Npad) := (others => Pad);
1478 Source.Data (Npad + 1 .. Max_Length) :=
1479 Temp (1 .. Max_Length - Npad);
1482 when Strings.Left =>
1483 for J in 1 .. Max_Length - Slen loop
1484 Source.Data (J) := Pad;
1487 Source.Data (Max_Length - Slen + 1 .. Max_Length) :=
1490 when Strings.Error =>
1491 raise Ada.Strings.Length_Error;
1496 ---------------------
1497 -- Super_To_String --
1498 ---------------------
1500 function Super_To_String (Source : in Super_String) return String is
1502 return Source.Data (1 .. Source.Current_Length);
1503 end Super_To_String;
1505 ---------------------
1506 -- Super_Translate --
1507 ---------------------
1509 function Super_Translate
1510 (Source : Super_String;
1511 Mapping : Maps.Character_Mapping)
1514 Result : Super_String (Source.Max_Length);
1517 Result.Current_Length := Source.Current_Length;
1519 for J in 1 .. Source.Current_Length loop
1520 Result.Data (J) := Value (Mapping, Source.Data (J));
1524 end Super_Translate;
1526 procedure Super_Translate
1527 (Source : in out Super_String;
1528 Mapping : Maps.Character_Mapping)
1531 for J in 1 .. Source.Current_Length loop
1532 Source.Data (J) := Value (Mapping, Source.Data (J));
1534 end Super_Translate;
1536 function Super_Translate
1537 (Source : Super_String;
1538 Mapping : Maps.Character_Mapping_Function)
1541 Result : Super_String (Source.Max_Length);
1544 Result.Current_Length := Source.Current_Length;
1546 for J in 1 .. Source.Current_Length loop
1547 Result.Data (J) := Mapping.all (Source.Data (J));
1551 end Super_Translate;
1553 procedure Super_Translate
1554 (Source : in out Super_String;
1555 Mapping : Maps.Character_Mapping_Function)
1558 for J in 1 .. Source.Current_Length loop
1559 Source.Data (J) := Mapping.all (Source.Data (J));
1561 end Super_Translate;
1567 function Super_Trim (Source : Super_String; Side : Trim_End)
1570 Result : Super_String (Source.Max_Length);
1571 Last : Natural := Source.Current_Length;
1572 First : Positive := 1;
1575 if Side = Left or else Side = Both then
1576 while First <= Last and then Source.Data (First) = ' ' loop
1581 if Side = Right or else Side = Both then
1582 while Last >= First and then Source.Data (Last) = ' ' loop
1587 Result.Current_Length := Last - First + 1;
1588 Result.Data (1 .. Result.Current_Length) := Source.Data (First .. Last);
1592 procedure Super_Trim
1593 (Source : in out Super_String;
1596 Max_Length : constant Positive := Source.Max_Length;
1597 Last : Natural := Source.Current_Length;
1598 First : Positive := 1;
1599 Temp : String (1 .. Max_Length);
1602 Temp (1 .. Last) := Source.Data (1 .. Last);
1604 if Side = Left or else Side = Both then
1605 while First <= Last and then Temp (First) = ' ' loop
1610 if Side = Right or else Side = Both then
1611 while Last >= First and then Temp (Last) = ' ' loop
1616 Source.Data := (others => ASCII.NUL);
1617 Source.Current_Length := Last - First + 1;
1618 Source.Data (1 .. Source.Current_Length) := Temp (First .. Last);
1622 (Source : Super_String;
1623 Left : Maps.Character_Set;
1624 Right : Maps.Character_Set)
1627 Result : Super_String (Source.Max_Length);
1630 for First in 1 .. Source.Current_Length loop
1631 if not Is_In (Source.Data (First), Left) then
1632 for Last in reverse First .. Source.Current_Length loop
1633 if not Is_In (Source.Data (Last), Right) then
1634 Result.Current_Length := Last - First + 1;
1635 Result.Data (1 .. Result.Current_Length) :=
1636 Source.Data (First .. Last);
1643 Result.Current_Length := 0;
1647 procedure Super_Trim
1648 (Source : in out Super_String;
1649 Left : Maps.Character_Set;
1650 Right : Maps.Character_Set)
1653 for First in 1 .. Source.Current_Length loop
1654 if not Is_In (Source.Data (First), Left) then
1655 for Last in reverse First .. Source.Current_Length loop
1656 if not Is_In (Source.Data (Last), Right) then
1658 Source.Current_Length := Last;
1661 Source.Current_Length := Last - First + 1;
1662 Source.Data (1 .. Source.Current_Length) :=
1663 Source.Data (First .. Last);
1665 for J in Source.Current_Length + 1 ..
1668 Source.Data (J) := ASCII.NUL;
1676 Source.Current_Length := 0;
1681 Source.Current_Length := 0;
1691 Max_Length : Positive)
1694 Result : Super_String (Max_Length);
1697 if Left > Max_Length then
1698 raise Ada.Strings.Length_Error;
1701 Result.Current_Length := Left;
1703 for J in 1 .. Left loop
1704 Result.Data (J) := Right;
1714 Max_Length : Positive)
1717 Result : Super_String (Max_Length);
1718 Pos : Positive := 1;
1719 Rlen : constant Natural := Right'Length;
1720 Nlen : constant Natural := Left * Rlen;
1723 if Nlen > Max_Length then
1724 raise Ada.Strings.Index_Error;
1727 Result.Current_Length := Nlen;
1730 for J in 1 .. Left loop
1731 Result.Data (Pos .. Pos + Rlen - 1) := Right;
1742 Right : Super_String)
1745 Result : Super_String (Right.Max_Length);
1746 Pos : Positive := 1;
1747 Rlen : constant Natural := Right.Current_Length;
1748 Nlen : constant Natural := Left * Rlen;
1751 if Nlen > Right.Max_Length then
1752 raise Ada.Strings.Length_Error;
1755 Result.Current_Length := Nlen;
1758 for J in 1 .. Left loop
1759 Result.Data (Pos .. Pos + Rlen - 1) :=
1760 Right.Data (1 .. Rlen);
1769 ---------------------
1770 -- To_Super_String --
1771 ---------------------
1773 function To_Super_String
1775 Max_Length : Natural;
1776 Drop : Truncation := Error)
1779 Result : Super_String (Max_Length);
1780 Slen : constant Natural := Source'Length;
1783 if Slen <= Max_Length then
1784 Result.Current_Length := Slen;
1785 Result.Data (1 .. Slen) := Source;
1789 when Strings.Right =>
1790 Result.Current_Length := Max_Length;
1791 Result.Data (1 .. Max_Length) :=
1792 Source (Source'First .. Source'First - 1 + Max_Length);
1794 when Strings.Left =>
1795 Result.Current_Length := Max_Length;
1796 Result.Data (1 .. Max_Length) :=
1797 Source (Source'Last - (Max_Length - 1) .. Source'Last);
1799 when Strings.Error =>
1800 raise Ada.Strings.Length_Error;
1805 end To_Super_String;
1807 end Ada.Strings.Superbounded;