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