1 ------------------------------------------------------------------------------
3 -- GNAT RUN-TIME COMPONENTS --
5 -- A D A . S T R I N G S . W I D E _ 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.Wide_Maps; use Ada.Strings.Wide_Maps;
35 with Ada.Strings.Wide_Search;
37 package body Ada.Strings.Wide_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 : Wide_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 : Wide_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;
125 (Left : Wide_Character;
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 : Wide_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 : Wide_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 : Wide_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 : Wide_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 : Wide_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;
297 Source : Wide_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 : Strings.Truncation := Strings.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 Wide_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;
482 New_Item : Wide_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 Wide_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 Wide_Character
582 function Super_Append
583 (Left : Super_String;
584 Right : Wide_Character;
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 : Wide_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 Wide_Character and Super_String
650 function Super_Append
651 (Left : Wide_Character;
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;
690 Pattern : Wide_String;
691 Mapping : Wide_Maps.Wide_Character_Mapping := Wide_Maps.Identity)
697 (Source.Data (1 .. Source.Current_Length), Pattern, Mapping);
701 (Source : Super_String;
702 Pattern : Wide_String;
703 Mapping : Wide_Maps.Wide_Character_Mapping_Function) return Natural
708 (Source.Data (1 .. Source.Current_Length), Pattern, Mapping);
712 (Source : Super_String;
713 Set : Wide_Maps.Wide_Character_Set) return Natural
716 return Wide_Search.Count (Source.Data (1 .. Source.Current_Length), Set);
723 function Super_Delete
724 (Source : Super_String;
726 Through : Natural) return Super_String
728 Result : Super_String (Source.Max_Length);
729 Slen : constant Natural := Source.Current_Length;
730 Num_Delete : constant Integer := Through - From + 1;
733 if Num_Delete <= 0 then
736 elsif From > Slen + 1 then
737 raise Ada.Strings.Index_Error;
739 elsif Through >= Slen then
740 Result.Current_Length := From - 1;
741 Result.Data (1 .. From - 1) := Source.Data (1 .. From - 1);
745 Result.Current_Length := Slen - Num_Delete;
746 Result.Data (1 .. From - 1) := Source.Data (1 .. From - 1);
747 Result.Data (From .. Result.Current_Length) :=
748 Source.Data (Through + 1 .. Slen);
753 procedure Super_Delete
754 (Source : in out Super_String;
758 Slen : constant Natural := Source.Current_Length;
759 Num_Delete : constant Integer := Through - From + 1;
762 if Num_Delete <= 0 then
765 elsif From > Slen + 1 then
766 raise Ada.Strings.Index_Error;
768 elsif Through >= Slen then
769 Source.Current_Length := From - 1;
772 Source.Current_Length := Slen - Num_Delete;
773 Source.Data (From .. Source.Current_Length) :=
774 Source.Data (Through + 1 .. Slen);
782 function Super_Element
783 (Source : Super_String;
784 Index : Positive) return Wide_Character
787 if Index <= Source.Current_Length then
788 return Source.Data (Index);
790 raise Strings.Index_Error;
794 ----------------------
795 -- Super_Find_Token --
796 ----------------------
798 procedure Super_Find_Token
799 (Source : Super_String;
800 Set : Wide_Maps.Wide_Character_Set;
801 Test : Strings.Membership;
802 First : out Positive;
806 Wide_Search.Find_Token
807 (Source.Data (1 .. Source.Current_Length), Set, Test, First, Last);
808 end Super_Find_Token;
815 (Source : Super_String;
817 Pad : Wide_Character := Wide_Space;
818 Drop : Strings.Truncation := Strings.Error) return Super_String
820 Max_Length : constant Positive := Source.Max_Length;
821 Result : Super_String (Max_Length);
822 Slen : constant Natural := Source.Current_Length;
823 Npad : constant Integer := Count - Slen;
827 Result.Current_Length := Count;
828 Result.Data (1 .. Count) := Source.Data (1 .. Count);
830 elsif Count <= Max_Length then
831 Result.Current_Length := Count;
832 Result.Data (1 .. Slen) := Source.Data (1 .. Slen);
833 Result.Data (Slen + 1 .. Count) := (others => Pad);
836 Result.Current_Length := Max_Length;
839 when Strings.Right =>
840 Result.Data (1 .. Slen) := Source.Data (1 .. Slen);
841 Result.Data (Slen + 1 .. Max_Length) := (others => Pad);
844 if Npad >= Max_Length then
845 Result.Data := (others => Pad);
848 Result.Data (1 .. Max_Length - Npad) :=
849 Source.Data (Count - Max_Length + 1 .. Slen);
850 Result.Data (Max_Length - Npad + 1 .. Max_Length) :=
854 when Strings.Error =>
855 raise Ada.Strings.Length_Error;
863 (Source : in out Super_String;
865 Pad : Wide_Character := Wide_Space;
866 Drop : Truncation := Error)
868 Max_Length : constant Positive := Source.Max_Length;
869 Slen : constant Natural := Source.Current_Length;
870 Npad : constant Integer := Count - Slen;
871 Temp : Wide_String (1 .. Max_Length);
875 Source.Current_Length := Count;
877 elsif Count <= Max_Length then
878 Source.Current_Length := Count;
879 Source.Data (Slen + 1 .. Count) := (others => Pad);
882 Source.Current_Length := Max_Length;
885 when Strings.Right =>
886 Source.Data (Slen + 1 .. Max_Length) := (others => Pad);
889 if Npad > Max_Length then
890 Source.Data := (others => Pad);
894 Source.Data (1 .. Max_Length - Npad) :=
895 Temp (Count - Max_Length + 1 .. Slen);
897 for J in Max_Length - Npad + 1 .. Max_Length loop
898 Source.Data (J) := Pad;
902 when Strings.Error =>
903 raise Ada.Strings.Length_Error;
913 (Source : Super_String;
914 Pattern : Wide_String;
915 Going : Strings.Direction := Strings.Forward;
916 Mapping : Wide_Maps.Wide_Character_Mapping := Wide_Maps.Identity)
920 return Wide_Search.Index
921 (Source.Data (1 .. Source.Current_Length), Pattern, Going, Mapping);
925 (Source : Super_String;
926 Pattern : Wide_String;
927 Going : Direction := Forward;
928 Mapping : Wide_Maps.Wide_Character_Mapping_Function) return Natural
931 return Wide_Search.Index
932 (Source.Data (1 .. Source.Current_Length), Pattern, Going, Mapping);
936 (Source : Super_String;
937 Set : Wide_Maps.Wide_Character_Set;
938 Test : Strings.Membership := Strings.Inside;
939 Going : Strings.Direction := Strings.Forward) return Natural
942 return Wide_Search.Index
943 (Source.Data (1 .. Source.Current_Length), Set, Test, Going);
947 (Source : Super_String;
948 Pattern : Wide_String;
950 Going : Direction := Forward;
951 Mapping : Wide_Maps.Wide_Character_Mapping := Wide_Maps.Identity)
955 return Wide_Search.Index
956 (Source.Data (1 .. Source.Current_Length),
957 Pattern, From, Going, Mapping);
961 (Source : Super_String;
962 Pattern : Wide_String;
964 Going : Direction := Forward;
965 Mapping : Wide_Maps.Wide_Character_Mapping_Function) return Natural
968 return Wide_Search.Index
969 (Source.Data (1 .. Source.Current_Length),
970 Pattern, From, Going, Mapping);
974 (Source : Super_String;
975 Set : Wide_Maps.Wide_Character_Set;
977 Test : Membership := Inside;
978 Going : Direction := Forward) return Natural
981 return Wide_Search.Index
982 (Source.Data (1 .. Source.Current_Length), Set, From, Test, Going);
985 ---------------------------
986 -- Super_Index_Non_Blank --
987 ---------------------------
989 function Super_Index_Non_Blank
990 (Source : Super_String;
991 Going : Strings.Direction := Strings.Forward) return Natural
995 Wide_Search.Index_Non_Blank
996 (Source.Data (1 .. Source.Current_Length), Going);
997 end Super_Index_Non_Blank;
999 function Super_Index_Non_Blank
1000 (Source : Super_String;
1002 Going : Direction := Forward) return Natural
1006 Wide_Search.Index_Non_Blank
1007 (Source.Data (1 .. Source.Current_Length), From, Going);
1008 end Super_Index_Non_Blank;
1014 function Super_Insert
1015 (Source : Super_String;
1017 New_Item : Wide_String;
1018 Drop : Strings.Truncation := Strings.Error) return Super_String
1020 Max_Length : constant Positive := Source.Max_Length;
1021 Result : Super_String (Max_Length);
1022 Slen : constant Natural := Source.Current_Length;
1023 Nlen : constant Natural := New_Item'Length;
1024 Tlen : constant Natural := Slen + Nlen;
1025 Blen : constant Natural := Before - 1;
1026 Alen : constant Integer := Slen - Blen;
1027 Droplen : constant Integer := Tlen - Max_Length;
1029 -- Tlen is the length of the total string before possible truncation.
1030 -- Blen, Alen are the lengths of the before and after pieces of the
1035 raise Ada.Strings.Index_Error;
1037 elsif Droplen <= 0 then
1038 Result.Current_Length := Tlen;
1039 Result.Data (1 .. Blen) := Source.Data (1 .. Blen);
1040 Result.Data (Before .. Before + Nlen - 1) := New_Item;
1041 Result.Data (Before + Nlen .. Tlen) :=
1042 Source.Data (Before .. Slen);
1045 Result.Current_Length := Max_Length;
1048 when Strings.Right =>
1049 Result.Data (1 .. Blen) := Source.Data (1 .. Blen);
1051 if Droplen > Alen then
1052 Result.Data (Before .. Max_Length) :=
1053 New_Item (New_Item'First
1054 .. New_Item'First + Max_Length - Before);
1056 Result.Data (Before .. Before + Nlen - 1) := New_Item;
1057 Result.Data (Before + Nlen .. Max_Length) :=
1058 Source.Data (Before .. Slen - Droplen);
1061 when Strings.Left =>
1062 Result.Data (Max_Length - (Alen - 1) .. Max_Length) :=
1063 Source.Data (Before .. Slen);
1065 if Droplen >= Blen then
1066 Result.Data (1 .. Max_Length - Alen) :=
1067 New_Item (New_Item'Last - (Max_Length - Alen) + 1
1071 (Blen - Droplen + 1 .. Max_Length - Alen) :=
1073 Result.Data (1 .. Blen - Droplen) :=
1074 Source.Data (Droplen + 1 .. Blen);
1077 when Strings.Error =>
1078 raise Ada.Strings.Length_Error;
1085 procedure Super_Insert
1086 (Source : in out Super_String;
1088 New_Item : Wide_String;
1089 Drop : Strings.Truncation := Strings.Error)
1092 -- We do a double copy here because this is one of the situations
1093 -- in which we move data to the right, and at least at the moment,
1094 -- GNAT is not handling such cases correctly ???
1096 Source := Super_Insert (Source, Before, New_Item, Drop);
1103 function Super_Length (Source : Super_String) return Natural is
1105 return Source.Current_Length;
1108 ---------------------
1109 -- Super_Overwrite --
1110 ---------------------
1112 function Super_Overwrite
1113 (Source : Super_String;
1114 Position : Positive;
1115 New_Item : Wide_String;
1116 Drop : Strings.Truncation := Strings.Error) return Super_String
1118 Max_Length : constant Positive := Source.Max_Length;
1119 Result : Super_String (Max_Length);
1120 Endpos : constant Natural := Position + New_Item'Length - 1;
1121 Slen : constant Natural := Source.Current_Length;
1125 if Position > Slen + 1 then
1126 raise Ada.Strings.Index_Error;
1128 elsif New_Item'Length = 0 then
1131 elsif Endpos <= Slen then
1132 Result.Current_Length := Source.Current_Length;
1133 Result.Data (1 .. Slen) := Source.Data (1 .. Slen);
1134 Result.Data (Position .. Endpos) := New_Item;
1137 elsif Endpos <= Max_Length then
1138 Result.Current_Length := Endpos;
1139 Result.Data (1 .. Position - 1) := Source.Data (1 .. Position - 1);
1140 Result.Data (Position .. Endpos) := New_Item;
1144 Result.Current_Length := Max_Length;
1145 Droplen := Endpos - Max_Length;
1148 when Strings.Right =>
1149 Result.Data (1 .. Position - 1) :=
1150 Source.Data (1 .. Position - 1);
1152 Result.Data (Position .. Max_Length) :=
1153 New_Item (New_Item'First .. New_Item'Last - Droplen);
1156 when Strings.Left =>
1157 if New_Item'Length >= Max_Length then
1158 Result.Data (1 .. Max_Length) :=
1159 New_Item (New_Item'Last - Max_Length + 1 ..
1164 Result.Data (1 .. Max_Length - New_Item'Length) :=
1165 Source.Data (Droplen + 1 .. Position - 1);
1167 (Max_Length - New_Item'Length + 1 .. Max_Length) :=
1172 when Strings.Error =>
1173 raise Ada.Strings.Length_Error;
1176 end Super_Overwrite;
1178 procedure Super_Overwrite
1179 (Source : in out Super_String;
1180 Position : Positive;
1181 New_Item : Wide_String;
1182 Drop : Strings.Truncation := Strings.Error)
1184 Max_Length : constant Positive := Source.Max_Length;
1185 Endpos : constant Positive := Position + New_Item'Length - 1;
1186 Slen : constant Natural := Source.Current_Length;
1190 if Position > Slen + 1 then
1191 raise Ada.Strings.Index_Error;
1193 elsif Endpos <= Slen then
1194 Source.Data (Position .. Endpos) := New_Item;
1196 elsif Endpos <= Max_Length then
1197 Source.Data (Position .. Endpos) := New_Item;
1198 Source.Current_Length := Endpos;
1201 Source.Current_Length := Max_Length;
1202 Droplen := Endpos - Max_Length;
1205 when Strings.Right =>
1206 Source.Data (Position .. Max_Length) :=
1207 New_Item (New_Item'First .. New_Item'Last - Droplen);
1209 when Strings.Left =>
1210 if New_Item'Length > Max_Length then
1211 Source.Data (1 .. Max_Length) :=
1212 New_Item (New_Item'Last - Max_Length + 1 ..
1216 Source.Data (1 .. Max_Length - New_Item'Length) :=
1217 Source.Data (Droplen + 1 .. Position - 1);
1220 (Max_Length - New_Item'Length + 1 .. Max_Length) :=
1224 when Strings.Error =>
1225 raise Ada.Strings.Length_Error;
1228 end Super_Overwrite;
1230 ---------------------------
1231 -- Super_Replace_Element --
1232 ---------------------------
1234 procedure Super_Replace_Element
1235 (Source : in out Super_String;
1237 By : Wide_Character)
1240 if Index <= Source.Current_Length then
1241 Source.Data (Index) := By;
1243 raise Ada.Strings.Index_Error;
1245 end Super_Replace_Element;
1247 -------------------------
1248 -- Super_Replace_Slice --
1249 -------------------------
1251 function Super_Replace_Slice
1252 (Source : Super_String;
1256 Drop : Strings.Truncation := Strings.Error) return Super_String
1258 Max_Length : constant Positive := Source.Max_Length;
1259 Slen : constant Natural := Source.Current_Length;
1262 if Low > Slen + 1 then
1263 raise Strings.Index_Error;
1265 elsif High < Low then
1266 return Super_Insert (Source, Low, By, Drop);
1270 Blen : constant Natural := Natural'Max (0, Low - 1);
1271 Alen : constant Natural := Natural'Max (0, Slen - High);
1272 Tlen : constant Natural := Blen + By'Length + Alen;
1273 Droplen : constant Integer := Tlen - Max_Length;
1274 Result : Super_String (Max_Length);
1276 -- Tlen is the total length of the result string before any
1277 -- truncation. Blen and Alen are the lengths of the pieces
1278 -- of the original string that end up in the result string
1279 -- before and after the replaced slice.
1282 if Droplen <= 0 then
1283 Result.Current_Length := Tlen;
1284 Result.Data (1 .. Blen) := Source.Data (1 .. Blen);
1285 Result.Data (Low .. Low + By'Length - 1) := By;
1286 Result.Data (Low + By'Length .. Tlen) :=
1287 Source.Data (High + 1 .. Slen);
1290 Result.Current_Length := Max_Length;
1293 when Strings.Right =>
1294 Result.Data (1 .. Blen) := Source.Data (1 .. Blen);
1296 if Droplen > Alen then
1297 Result.Data (Low .. Max_Length) :=
1298 By (By'First .. By'First + Max_Length - Low);
1300 Result.Data (Low .. Low + By'Length - 1) := By;
1301 Result.Data (Low + By'Length .. Max_Length) :=
1302 Source.Data (High + 1 .. Slen - Droplen);
1305 when Strings.Left =>
1306 Result.Data (Max_Length - (Alen - 1) .. Max_Length) :=
1307 Source.Data (High + 1 .. Slen);
1309 if Droplen >= Blen then
1310 Result.Data (1 .. Max_Length - Alen) :=
1311 By (By'Last - (Max_Length - Alen) + 1 .. By'Last);
1314 (Blen - Droplen + 1 .. Max_Length - Alen) := By;
1315 Result.Data (1 .. Blen - Droplen) :=
1316 Source.Data (Droplen + 1 .. Blen);
1319 when Strings.Error =>
1320 raise Ada.Strings.Length_Error;
1327 end Super_Replace_Slice;
1329 procedure Super_Replace_Slice
1330 (Source : in out Super_String;
1334 Drop : Strings.Truncation := Strings.Error)
1337 -- We do a double copy here because this is one of the situations
1338 -- in which we move data to the right, and at least at the moment,
1339 -- GNAT is not handling such cases correctly ???
1341 Source := Super_Replace_Slice (Source, Low, High, By, Drop);
1342 end Super_Replace_Slice;
1344 ---------------------
1345 -- Super_Replicate --
1346 ---------------------
1348 function Super_Replicate
1350 Item : Wide_Character;
1351 Drop : Truncation := Error;
1352 Max_Length : Positive) return Super_String
1354 Result : Super_String (Max_Length);
1357 if Count <= Max_Length then
1358 Result.Current_Length := Count;
1360 elsif Drop = Strings.Error then
1361 raise Ada.Strings.Length_Error;
1364 Result.Current_Length := Max_Length;
1367 Result.Data (1 .. Result.Current_Length) := (others => Item);
1369 end Super_Replicate;
1371 function Super_Replicate
1374 Drop : Truncation := Error;
1375 Max_Length : Positive) return Super_String
1377 Length : constant Integer := Count * Item'Length;
1378 Result : Super_String (Max_Length);
1382 if Length <= Max_Length then
1383 Result.Current_Length := Length;
1388 for J in 1 .. Count loop
1389 Result.Data (Indx .. Indx + Item'Length - 1) := Item;
1390 Indx := Indx + Item'Length;
1395 Result.Current_Length := Max_Length;
1398 when Strings.Right =>
1401 while Indx + Item'Length <= Max_Length + 1 loop
1402 Result.Data (Indx .. Indx + Item'Length - 1) := Item;
1403 Indx := Indx + Item'Length;
1406 Result.Data (Indx .. Max_Length) :=
1407 Item (Item'First .. Item'First + Max_Length - Indx);
1409 when Strings.Left =>
1412 while Indx - Item'Length >= 1 loop
1413 Result.Data (Indx - (Item'Length - 1) .. Indx) := Item;
1414 Indx := Indx - Item'Length;
1417 Result.Data (1 .. Indx) :=
1418 Item (Item'Last - Indx + 1 .. Item'Last);
1420 when Strings.Error =>
1421 raise Ada.Strings.Length_Error;
1426 end Super_Replicate;
1428 function Super_Replicate
1430 Item : Super_String;
1431 Drop : Strings.Truncation := Strings.Error) return Super_String
1437 Item.Data (1 .. Item.Current_Length),
1440 end Super_Replicate;
1446 function Super_Slice
1447 (Source : Super_String;
1449 High : Natural) return Wide_String
1452 -- Note: test of High > Length is in accordance with AI95-00128
1454 if Low > Source.Current_Length + 1
1455 or else High > Source.Current_Length
1459 return Source.Data (Low .. High);
1463 function Super_Slice
1464 (Source : Super_String;
1466 High : Natural) return Super_String
1468 Result : Super_String (Source.Max_Length);
1471 if Low > Source.Current_Length + 1
1472 or else High > Source.Current_Length
1476 Result.Current_Length := High - Low + 1;
1477 Result.Data (1 .. Result.Current_Length) := Source.Data (Low .. High);
1483 procedure Super_Slice
1484 (Source : Super_String;
1485 Target : out Super_String;
1490 if Low > Source.Current_Length + 1
1491 or else High > Source.Current_Length
1495 Target.Current_Length := High - Low + 1;
1496 Target.Data (1 .. Target.Current_Length) := Source.Data (Low .. High);
1505 (Source : Super_String;
1507 Pad : Wide_Character := Wide_Space;
1508 Drop : Strings.Truncation := Strings.Error) return Super_String
1510 Max_Length : constant Positive := Source.Max_Length;
1511 Result : Super_String (Max_Length);
1512 Slen : constant Natural := Source.Current_Length;
1513 Npad : constant Integer := Count - Slen;
1517 Result.Current_Length := Count;
1518 Result.Data (1 .. Count) :=
1519 Source.Data (Slen - (Count - 1) .. Slen);
1521 elsif Count <= Max_Length then
1522 Result.Current_Length := Count;
1523 Result.Data (1 .. Npad) := (others => Pad);
1524 Result.Data (Npad + 1 .. Count) := Source.Data (1 .. Slen);
1527 Result.Current_Length := Max_Length;
1530 when Strings.Right =>
1531 if Npad >= Max_Length then
1532 Result.Data := (others => Pad);
1535 Result.Data (1 .. Npad) := (others => Pad);
1536 Result.Data (Npad + 1 .. Max_Length) :=
1537 Source.Data (1 .. Max_Length - Npad);
1540 when Strings.Left =>
1541 Result.Data (1 .. Max_Length - Slen) := (others => Pad);
1542 Result.Data (Max_Length - Slen + 1 .. Max_Length) :=
1543 Source.Data (1 .. Slen);
1545 when Strings.Error =>
1546 raise Ada.Strings.Length_Error;
1553 procedure Super_Tail
1554 (Source : in out Super_String;
1556 Pad : Wide_Character := Wide_Space;
1557 Drop : Truncation := Error)
1559 Max_Length : constant Positive := Source.Max_Length;
1560 Slen : constant Natural := Source.Current_Length;
1561 Npad : constant Integer := Count - Slen;
1563 Temp : constant Wide_String (1 .. Max_Length) := Source.Data;
1567 Source.Current_Length := Count;
1568 Source.Data (1 .. Count) :=
1569 Temp (Slen - (Count - 1) .. Slen);
1571 elsif Count <= Max_Length then
1572 Source.Current_Length := Count;
1573 Source.Data (1 .. Npad) := (others => Pad);
1574 Source.Data (Npad + 1 .. Count) := Temp (1 .. Slen);
1577 Source.Current_Length := Max_Length;
1580 when Strings.Right =>
1581 if Npad >= Max_Length then
1582 Source.Data := (others => Pad);
1585 Source.Data (1 .. Npad) := (others => Pad);
1586 Source.Data (Npad + 1 .. Max_Length) :=
1587 Temp (1 .. Max_Length - Npad);
1590 when Strings.Left =>
1591 for J in 1 .. Max_Length - Slen loop
1592 Source.Data (J) := Pad;
1595 Source.Data (Max_Length - Slen + 1 .. Max_Length) :=
1598 when Strings.Error =>
1599 raise Ada.Strings.Length_Error;
1604 ---------------------
1605 -- Super_To_String --
1606 ---------------------
1608 function Super_To_String (Source : Super_String) return Wide_String is
1610 return Source.Data (1 .. Source.Current_Length);
1611 end Super_To_String;
1613 ---------------------
1614 -- Super_Translate --
1615 ---------------------
1617 function Super_Translate
1618 (Source : Super_String;
1619 Mapping : Wide_Maps.Wide_Character_Mapping) return Super_String
1621 Result : Super_String (Source.Max_Length);
1624 Result.Current_Length := Source.Current_Length;
1626 for J in 1 .. Source.Current_Length loop
1627 Result.Data (J) := Value (Mapping, Source.Data (J));
1631 end Super_Translate;
1633 procedure Super_Translate
1634 (Source : in out Super_String;
1635 Mapping : Wide_Maps.Wide_Character_Mapping)
1638 for J in 1 .. Source.Current_Length loop
1639 Source.Data (J) := Value (Mapping, Source.Data (J));
1641 end Super_Translate;
1643 function Super_Translate
1644 (Source : Super_String;
1645 Mapping : Wide_Maps.Wide_Character_Mapping_Function) return Super_String
1647 Result : Super_String (Source.Max_Length);
1650 Result.Current_Length := Source.Current_Length;
1652 for J in 1 .. Source.Current_Length loop
1653 Result.Data (J) := Mapping.all (Source.Data (J));
1657 end Super_Translate;
1659 procedure Super_Translate
1660 (Source : in out Super_String;
1661 Mapping : Wide_Maps.Wide_Character_Mapping_Function)
1664 for J in 1 .. Source.Current_Length loop
1665 Source.Data (J) := Mapping.all (Source.Data (J));
1667 end Super_Translate;
1674 (Source : Super_String;
1675 Side : Trim_End) return Super_String
1677 Result : Super_String (Source.Max_Length);
1678 Last : Natural := Source.Current_Length;
1679 First : Positive := 1;
1682 if Side = Left or else Side = Both then
1683 while First <= Last and then Source.Data (First) = ' ' loop
1688 if Side = Right or else Side = Both then
1689 while Last >= First and then Source.Data (Last) = ' ' loop
1694 Result.Current_Length := Last - First + 1;
1695 Result.Data (1 .. Result.Current_Length) := Source.Data (First .. Last);
1699 procedure Super_Trim
1700 (Source : in out Super_String;
1703 Max_Length : constant Positive := Source.Max_Length;
1704 Last : Natural := Source.Current_Length;
1705 First : Positive := 1;
1706 Temp : Wide_String (1 .. Max_Length);
1709 Temp (1 .. Last) := Source.Data (1 .. Last);
1711 if Side = Left or else Side = Both then
1712 while First <= Last and then Temp (First) = ' ' loop
1717 if Side = Right or else Side = Both then
1718 while Last >= First and then Temp (Last) = ' ' loop
1723 Source.Data := (others => Wide_NUL);
1724 Source.Current_Length := Last - First + 1;
1725 Source.Data (1 .. Source.Current_Length) := Temp (First .. Last);
1729 (Source : Super_String;
1730 Left : Wide_Maps.Wide_Character_Set;
1731 Right : Wide_Maps.Wide_Character_Set) return Super_String
1733 Result : Super_String (Source.Max_Length);
1736 for First in 1 .. Source.Current_Length loop
1737 if not Is_In (Source.Data (First), Left) then
1738 for Last in reverse First .. Source.Current_Length loop
1739 if not Is_In (Source.Data (Last), Right) then
1740 Result.Current_Length := Last - First + 1;
1741 Result.Data (1 .. Result.Current_Length) :=
1742 Source.Data (First .. Last);
1749 Result.Current_Length := 0;
1753 procedure Super_Trim
1754 (Source : in out Super_String;
1755 Left : Wide_Maps.Wide_Character_Set;
1756 Right : Wide_Maps.Wide_Character_Set)
1759 for First in 1 .. Source.Current_Length loop
1760 if not Is_In (Source.Data (First), Left) then
1761 for Last in reverse First .. Source.Current_Length loop
1762 if not Is_In (Source.Data (Last), Right) then
1764 Source.Current_Length := Last;
1767 Source.Current_Length := Last - First + 1;
1768 Source.Data (1 .. Source.Current_Length) :=
1769 Source.Data (First .. Last);
1771 for J in Source.Current_Length + 1 ..
1774 Source.Data (J) := Wide_NUL;
1782 Source.Current_Length := 0;
1787 Source.Current_Length := 0;
1796 Right : Wide_Character;
1797 Max_Length : Positive) return Super_String
1799 Result : Super_String (Max_Length);
1802 if Left > Max_Length then
1803 raise Ada.Strings.Length_Error;
1806 Result.Current_Length := Left;
1808 for J in 1 .. Left loop
1809 Result.Data (J) := Right;
1818 Right : Wide_String;
1819 Max_Length : Positive) return Super_String
1821 Result : Super_String (Max_Length);
1822 Pos : Positive := 1;
1823 Rlen : constant Natural := Right'Length;
1824 Nlen : constant Natural := Left * Rlen;
1827 if Nlen > Max_Length then
1828 raise Ada.Strings.Index_Error;
1831 Result.Current_Length := Nlen;
1834 for J in 1 .. Left loop
1835 Result.Data (Pos .. Pos + Rlen - 1) := Right;
1846 Right : Super_String) return Super_String
1848 Result : Super_String (Right.Max_Length);
1849 Pos : Positive := 1;
1850 Rlen : constant Natural := Right.Current_Length;
1851 Nlen : constant Natural := Left * Rlen;
1854 if Nlen > Right.Max_Length then
1855 raise Ada.Strings.Length_Error;
1858 Result.Current_Length := Nlen;
1861 for J in 1 .. Left loop
1862 Result.Data (Pos .. Pos + Rlen - 1) :=
1863 Right.Data (1 .. Rlen);
1872 ---------------------
1873 -- To_Super_String --
1874 ---------------------
1876 function To_Super_String
1877 (Source : Wide_String;
1878 Max_Length : Natural;
1879 Drop : Truncation := Error) return Super_String
1881 Result : Super_String (Max_Length);
1882 Slen : constant Natural := Source'Length;
1885 if Slen <= Max_Length then
1886 Result.Current_Length := Slen;
1887 Result.Data (1 .. Slen) := Source;
1891 when Strings.Right =>
1892 Result.Current_Length := Max_Length;
1893 Result.Data (1 .. Max_Length) :=
1894 Source (Source'First .. Source'First - 1 + Max_Length);
1896 when Strings.Left =>
1897 Result.Current_Length := Max_Length;
1898 Result.Data (1 .. Max_Length) :=
1899 Source (Source'Last - (Max_Length - 1) .. Source'Last);
1901 when Strings.Error =>
1902 raise Ada.Strings.Length_Error;
1907 end To_Super_String;
1909 end Ada.Strings.Wide_Superbounded;