1 ------------------------------------------------------------------------------
3 -- GNAT RUNTIME COMPONENTS --
5 -- A D A . S T R I N G S . B O U N D E D --
11 -- Copyright (C) 1992-2001 Free Software Foundation, Inc. --
13 -- GNAT is free software; you can redistribute it and/or modify it under --
14 -- terms of the GNU General Public License as published by the Free Soft- --
15 -- ware Foundation; either version 2, or (at your option) any later ver- --
16 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
17 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
18 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
19 -- for more details. You should have received a copy of the GNU General --
20 -- Public License distributed with GNAT; see file COPYING. If not, write --
21 -- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
22 -- MA 02111-1307, USA. --
24 -- As a special exception, if other files instantiate generics from this --
25 -- unit, or you link this unit with other files to produce an executable, --
26 -- this unit does not by itself cause the resulting executable to be --
27 -- covered by the GNU General Public License. This exception does not --
28 -- however invalidate any other reasons why the executable file might be --
29 -- covered by the GNU Public License. --
31 -- GNAT was originally developed by the GNAT team at New York University. --
32 -- It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). --
34 ------------------------------------------------------------------------------
36 with Ada
.Strings
.Maps
; use Ada
.Strings
.Maps
;
37 with Ada
.Strings
.Search
;
39 package body Ada
.Strings
.Bounded
is
41 package body Generic_Bounded_Length
is
48 (Left
: in Bounded_String
;
49 Right
: in Bounded_String
)
52 Result
: Bounded_String
;
53 Llen
: constant Length_Range
:= Left
.Length
;
54 Rlen
: constant Length_Range
:= Right
.Length
;
55 Nlen
: constant Natural := Llen
+ Rlen
;
58 if Nlen
> Max_Length
then
59 raise Ada
.Strings
.Length_Error
;
61 Result
.Length
:= Nlen
;
62 Result
.Data
(1 .. Llen
) := Left
.Data
(1 .. Llen
);
63 Result
.Data
(Llen
+ 1 .. Nlen
) := Right
.Data
(1 .. Rlen
);
70 (Left
: in Bounded_String
;
74 Result
: Bounded_String
;
75 Llen
: constant Length_Range
:= Left
.Length
;
77 Nlen
: constant Natural := Llen
+ Right
'Length;
80 if Nlen
> Max_Length
then
81 raise Ada
.Strings
.Length_Error
;
83 Result
.Length
:= Nlen
;
84 Result
.Data
(1 .. Llen
) := Left
.Data
(1 .. Llen
);
85 Result
.Data
(Llen
+ 1 .. Nlen
) := Right
;
92 Right
: in Bounded_String
)
95 Result
: Bounded_String
;
96 Llen
: constant Length_Range
:= Left
'Length;
97 Rlen
: constant Length_Range
:= Right
.Length
;
98 Nlen
: constant Natural := Llen
+ Rlen
;
101 if Nlen
> Max_Length
then
102 raise Ada
.Strings
.Length_Error
;
104 Result
.Length
:= Nlen
;
105 Result
.Data
(1 .. Llen
) := Left
;
106 Result
.Data
(Llen
+ 1 .. Nlen
) := Right
.Data
(1 .. Rlen
);
113 (Left
: in Bounded_String
;
114 Right
: in Character)
115 return Bounded_String
117 Result
: Bounded_String
;
118 Llen
: constant Length_Range
:= Left
.Length
;
121 if Llen
= Max_Length
then
122 raise Ada
.Strings
.Length_Error
;
124 Result
.Length
:= Llen
+ 1;
125 Result
.Data
(1 .. Llen
) := Left
.Data
(1 .. Llen
);
126 Result
.Data
(Result
.Length
) := Right
;
133 (Left
: in Character;
134 Right
: in Bounded_String
)
135 return Bounded_String
137 Result
: Bounded_String
;
138 Rlen
: Length_Range
:= Right
.Length
;
141 if Rlen
= Max_Length
then
142 raise Ada
.Strings
.Length_Error
;
144 Result
.Length
:= Rlen
+ 1;
145 Result
.Data
(1) := Left
;
146 Result
.Data
(2 .. Result
.Length
) := Right
.Data
(1 .. Rlen
);
158 Right
: in Character)
159 return Bounded_String
161 Result
: Bounded_String
;
164 if Left
> Max_Length
then
165 raise Ada
.Strings
.Length_Error
;
167 Result
.Length
:= Left
;
169 for J
in 1 .. Left
loop
170 Result
.Data
(J
) := Right
;
180 return Bounded_String
182 Result
: Bounded_String
;
184 Rlen
: constant Natural := Right
'Length;
185 Nlen
: constant Natural := Left
* Rlen
;
188 if Nlen
> Max_Length
then
189 raise Ada
.Strings
.Index_Error
;
191 Result
.Length
:= Nlen
;
194 for J
in 1 .. Left
loop
195 Result
.Data
(Pos
.. Pos
+ Rlen
- 1) := Right
;
206 Right
: in Bounded_String
)
207 return Bounded_String
209 Result
: Bounded_String
;
211 Rlen
: constant Length_Range
:= Right
.Length
;
212 Nlen
: constant Natural := Left
* Rlen
;
215 if Nlen
> Max_Length
then
216 raise Ada
.Strings
.Length_Error
;
219 Result
.Length
:= Nlen
;
222 for J
in 1 .. Left
loop
223 Result
.Data
(Pos
.. Pos
+ Rlen
- 1) :=
224 Right
.Data
(1 .. Rlen
);
237 function "<" (Left
, Right
: in Bounded_String
) return Boolean is
239 return Left
.Data
(1 .. Left
.Length
) < Right
.Data
(1 .. Right
.Length
);
243 (Left
: in Bounded_String
;
248 return Left
.Data
(1 .. Left
.Length
) < Right
;
253 Right
: in Bounded_String
)
257 return Left
< Right
.Data
(1 .. Right
.Length
);
264 function "<=" (Left
, Right
: in Bounded_String
) return Boolean is
266 return Left
.Data
(1 .. Left
.Length
) <= Right
.Data
(1 .. Right
.Length
);
270 (Left
: in Bounded_String
;
275 return Left
.Data
(1 .. Left
.Length
) <= Right
;
280 Right
: in Bounded_String
)
284 return Left
<= Right
.Data
(1 .. Right
.Length
);
291 function "=" (Left
, Right
: in Bounded_String
) return Boolean is
293 return Left
.Length
= Right
.Length
294 and then Left
.Data
(1 .. Left
.Length
) =
295 Right
.Data
(1 .. Right
.Length
);
298 function "=" (Left
: in Bounded_String
; Right
: in String)
301 return Left
.Length
= Right
'Length
302 and then Left
.Data
(1 .. Left
.Length
) = Right
;
305 function "=" (Left
: in String; Right
: in Bounded_String
)
308 return Left
'Length = Right
.Length
309 and then Left
= Right
.Data
(1 .. Right
.Length
);
316 function ">" (Left
, Right
: in Bounded_String
) return Boolean is
318 return Left
.Data
(1 .. Left
.Length
) > Right
.Data
(1 .. Right
.Length
);
322 (Left
: in Bounded_String
;
327 return Left
.Data
(1 .. Left
.Length
) > Right
;
332 Right
: in Bounded_String
)
336 return Left
> Right
.Data
(1 .. Right
.Length
);
343 function ">=" (Left
, Right
: in Bounded_String
) return Boolean is
345 return Left
.Data
(1 .. Left
.Length
) >= Right
.Data
(1 .. Right
.Length
);
349 (Left
: in Bounded_String
;
354 return Left
.Data
(1 .. Left
.Length
) >= Right
;
359 Right
: in Bounded_String
)
363 return Left
>= Right
.Data
(1 .. Right
.Length
);
370 -- Case of Bounded_String and Bounded_String
373 (Left
, Right
: in Bounded_String
;
374 Drop
: in Strings
.Truncation
:= Strings
.Error
)
375 return Bounded_String
377 Result
: Bounded_String
;
378 Llen
: constant Length_Range
:= Left
.Length
;
379 Rlen
: constant Length_Range
:= Right
.Length
;
380 Nlen
: constant Natural := Llen
+ Rlen
;
383 if Nlen
<= Max_Length
then
384 Result
.Length
:= Nlen
;
385 Result
.Data
(1 .. Llen
) := Left
.Data
(1 .. Llen
);
386 Result
.Data
(Llen
+ 1 .. Nlen
) := Right
.Data
(1 .. Rlen
);
389 Result
.Length
:= Max_Length
;
392 when Strings
.Right
=>
393 if Llen
>= Max_Length
then -- only case is Llen = Max_Length
394 Result
.Data
:= Left
.Data
;
397 Result
.Data
(1 .. Llen
) := Left
.Data
(1 .. Llen
);
398 Result
.Data
(Llen
+ 1 .. Max_Length
) :=
399 Right
.Data
(1 .. Max_Length
- Llen
);
403 if Rlen
>= Max_Length
then -- only case is Rlen = Max_Length
404 Result
.Data
:= Right
.Data
;
407 Result
.Data
(1 .. Max_Length
- Rlen
) :=
408 Left
.Data
(Llen
- (Max_Length
- Rlen
- 1) .. Llen
);
409 Result
.Data
(Max_Length
- Rlen
+ 1 .. Max_Length
) :=
410 Right
.Data
(1 .. Rlen
);
413 when Strings
.Error
=>
414 raise Ada
.Strings
.Length_Error
;
422 (Source
: in out Bounded_String
;
423 New_Item
: in Bounded_String
;
424 Drop
: in Truncation
:= Error
)
426 Llen
: constant Length_Range
:= Source
.Length
;
427 Rlen
: constant Length_Range
:= New_Item
.Length
;
428 Nlen
: constant Natural := Llen
+ Rlen
;
431 if Nlen
<= Max_Length
then
432 Source
.Length
:= Nlen
;
433 Source
.Data
(Llen
+ 1 .. Nlen
) := New_Item
.Data
(1 .. Rlen
);
436 Source
.Length
:= Max_Length
;
439 when Strings
.Right
=>
440 if Llen
< Max_Length
then
441 Source
.Data
(Llen
+ 1 .. Max_Length
) :=
442 New_Item
.Data
(1 .. Max_Length
- Llen
);
446 if Rlen
>= Max_Length
then -- only case is Rlen = Max_Length
447 Source
.Data
:= New_Item
.Data
;
450 Source
.Data
(1 .. Max_Length
- Rlen
) :=
451 Source
.Data
(Llen
- (Max_Length
- Rlen
- 1) .. Llen
);
452 Source
.Data
(Max_Length
- Rlen
+ 1 .. Max_Length
) :=
453 New_Item
.Data
(1 .. Rlen
);
456 when Strings
.Error
=>
457 raise Ada
.Strings
.Length_Error
;
463 -- Case of Bounded_String and String
466 (Left
: in Bounded_String
;
468 Drop
: in Strings
.Truncation
:= Strings
.Error
)
469 return Bounded_String
471 Result
: Bounded_String
;
472 Llen
: constant Length_Range
:= Left
.Length
;
473 Rlen
: constant Length_Range
:= Right
'Length;
474 Nlen
: constant Natural := Llen
+ Rlen
;
477 if Nlen
<= Max_Length
then
478 Result
.Length
:= Nlen
;
479 Result
.Data
(1 .. Llen
) := Left
.Data
(1 .. Llen
);
480 Result
.Data
(Llen
+ 1 .. Nlen
) := Right
;
483 Result
.Length
:= Max_Length
;
486 when Strings
.Right
=>
487 if Llen
>= Max_Length
then -- only case is Llen = Max_Length
488 Result
.Data
:= Left
.Data
;
491 Result
.Data
(1 .. Llen
) := Left
.Data
(1 .. Llen
);
492 Result
.Data
(Llen
+ 1 .. Max_Length
) :=
493 Right
(Right
'First .. Right
'First - 1 +
499 if Rlen
>= Max_Length
then
500 Result
.Data
(1 .. Max_Length
) :=
501 Right
(Right
'Last - (Max_Length
- 1) .. Right
'Last);
504 Result
.Data
(1 .. Max_Length
- Rlen
) :=
505 Left
.Data
(Llen
- (Max_Length
- Rlen
- 1) .. Llen
);
506 Result
.Data
(Max_Length
- Rlen
+ 1 .. Max_Length
) :=
510 when Strings
.Error
=>
511 raise Ada
.Strings
.Length_Error
;
519 (Source
: in out Bounded_String
;
520 New_Item
: in String;
521 Drop
: in Truncation
:= Error
)
523 Llen
: constant Length_Range
:= Source
.Length
;
524 Rlen
: constant Length_Range
:= New_Item
'Length;
525 Nlen
: constant Natural := Llen
+ Rlen
;
528 if Nlen
<= Max_Length
then
529 Source
.Length
:= Nlen
;
530 Source
.Data
(Llen
+ 1 .. Nlen
) := New_Item
;
533 Source
.Length
:= Max_Length
;
536 when Strings
.Right
=>
537 if Llen
< Max_Length
then
538 Source
.Data
(Llen
+ 1 .. Max_Length
) :=
539 New_Item
(New_Item
'First ..
540 New_Item
'First - 1 + Max_Length
- Llen
);
544 if Rlen
>= Max_Length
then
545 Source
.Data
(1 .. Max_Length
) :=
546 New_Item
(New_Item
'Last - (Max_Length
- 1) ..
550 Source
.Data
(1 .. Max_Length
- Rlen
) :=
551 Source
.Data
(Llen
- (Max_Length
- Rlen
- 1) .. Llen
);
552 Source
.Data
(Max_Length
- Rlen
+ 1 .. Max_Length
) :=
556 when Strings
.Error
=>
557 raise Ada
.Strings
.Length_Error
;
563 -- Case of String and Bounded_String
567 Right
: in Bounded_String
;
568 Drop
: in Strings
.Truncation
:= Strings
.Error
)
569 return Bounded_String
571 Result
: Bounded_String
;
572 Llen
: constant Length_Range
:= Left
'Length;
573 Rlen
: constant Length_Range
:= Right
.Length
;
574 Nlen
: constant Natural := Llen
+ Rlen
;
577 if Nlen
<= Max_Length
then
578 Result
.Length
:= Nlen
;
579 Result
.Data
(1 .. Llen
) := Left
;
580 Result
.Data
(Llen
+ 1 .. Llen
+ Rlen
) := Right
.Data
(1 .. Rlen
);
583 Result
.Length
:= Max_Length
;
586 when Strings
.Right
=>
587 if Llen
>= Max_Length
then
588 Result
.Data
(1 .. Max_Length
) :=
589 Left
(Left
'First .. Left
'First + (Max_Length
- 1));
592 Result
.Data
(1 .. Llen
) := Left
;
593 Result
.Data
(Llen
+ 1 .. Max_Length
) :=
594 Right
.Data
(1 .. Max_Length
- Llen
);
598 if Rlen
>= Max_Length
then
599 Result
.Data
(1 .. Max_Length
) :=
600 Right
.Data
(Rlen
- (Max_Length
- 1) .. Rlen
);
603 Result
.Data
(1 .. Max_Length
- Rlen
) :=
604 Left
(Left
'Last - (Max_Length
- Rlen
- 1) .. Left
'Last);
605 Result
.Data
(Max_Length
- Rlen
+ 1 .. Max_Length
) :=
606 Right
.Data
(1 .. Rlen
);
609 when Strings
.Error
=>
610 raise Ada
.Strings
.Length_Error
;
617 -- Case of Bounded_String and Character
620 (Left
: in Bounded_String
;
621 Right
: in Character;
622 Drop
: in Strings
.Truncation
:= Strings
.Error
)
623 return Bounded_String
625 Result
: Bounded_String
;
626 Llen
: constant Length_Range
:= Left
.Length
;
629 if Llen
< Max_Length
then
630 Result
.Length
:= Llen
+ 1;
631 Result
.Data
(1 .. Llen
) := Left
.Data
(1 .. Llen
);
632 Result
.Data
(Llen
+ 1) := Right
;
637 when Strings
.Right
=>
641 Result
.Length
:= Max_Length
;
642 Result
.Data
(1 .. Max_Length
- 1) :=
643 Left
.Data
(2 .. Max_Length
);
644 Result
.Data
(Max_Length
) := Right
;
647 when Strings
.Error
=>
648 raise Ada
.Strings
.Length_Error
;
654 (Source
: in out Bounded_String
;
655 New_Item
: in Character;
656 Drop
: in Truncation
:= Error
)
658 Llen
: constant Length_Range
:= Source
.Length
;
661 if Llen
< Max_Length
then
662 Source
.Length
:= Llen
+ 1;
663 Source
.Data
(Llen
+ 1) := New_Item
;
666 Source
.Length
:= Max_Length
;
669 when Strings
.Right
=>
673 Source
.Data
(1 .. Max_Length
- 1) :=
674 Source
.Data
(2 .. Max_Length
);
675 Source
.Data
(Max_Length
) := New_Item
;
677 when Strings
.Error
=>
678 raise Ada
.Strings
.Length_Error
;
684 -- Case of Character and Bounded_String
687 (Left
: in Character;
688 Right
: in Bounded_String
;
689 Drop
: in Strings
.Truncation
:= Strings
.Error
)
690 return Bounded_String
692 Result
: Bounded_String
;
693 Rlen
: constant Length_Range
:= Right
.Length
;
696 if Rlen
< Max_Length
then
697 Result
.Length
:= Rlen
+ 1;
698 Result
.Data
(1) := Left
;
699 Result
.Data
(2 .. Rlen
+ 1) := Right
.Data
(1 .. Rlen
);
704 when Strings
.Right
=>
705 Result
.Length
:= Max_Length
;
706 Result
.Data
(1) := Left
;
707 Result
.Data
(2 .. Max_Length
) :=
708 Right
.Data
(1 .. Max_Length
- 1);
714 when Strings
.Error
=>
715 raise Ada
.Strings
.Length_Error
;
725 (Source
: in Bounded_String
;
727 Mapping
: in Maps
.Character_Mapping
:= Maps
.Identity
)
732 Search
.Count
(Source
.Data
(1 .. Source
.Length
), Pattern
, Mapping
);
736 (Source
: in Bounded_String
;
738 Mapping
: in Maps
.Character_Mapping_Function
)
743 Search
.Count
(Source
.Data
(1 .. Source
.Length
), Pattern
, Mapping
);
747 (Source
: in Bounded_String
;
748 Set
: in Maps
.Character_Set
)
752 return Search
.Count
(Source
.Data
(1 .. Source
.Length
), Set
);
760 (Source
: in Bounded_String
;
762 Through
: in Natural)
763 return Bounded_String
765 Slen
: constant Natural := Source
.Length
;
766 Num_Delete
: constant Integer := Through
- From
+ 1;
767 Result
: Bounded_String
;
770 if Num_Delete
<= 0 then
773 elsif From
> Slen
+ 1 then
774 raise Ada
.Strings
.Index_Error
;
776 elsif Through
>= Slen
then
777 Result
.Length
:= From
- 1;
778 Result
.Data
(1 .. From
- 1) := Source
.Data
(1 .. From
- 1);
782 Result
.Length
:= Slen
- Num_Delete
;
783 Result
.Data
(1 .. From
- 1) := Source
.Data
(1 .. From
- 1);
784 Result
.Data
(From
.. Result
.Length
) :=
785 Source
.Data
(Through
+ 1 .. Slen
);
791 (Source
: in out Bounded_String
;
793 Through
: in Natural)
795 Slen
: constant Natural := Source
.Length
;
796 Num_Delete
: constant Integer := Through
- From
+ 1;
799 if Num_Delete
<= 0 then
802 elsif From
> Slen
+ 1 then
803 raise Ada
.Strings
.Index_Error
;
805 elsif Through
>= Slen
then
806 Source
.Length
:= From
- 1;
809 Source
.Length
:= Slen
- Num_Delete
;
810 Source
.Data
(From
.. Source
.Length
) :=
811 Source
.Data
(Through
+ 1 .. Slen
);
820 (Source
: in Bounded_String
;
825 if Index
in 1 .. Source
.Length
then
826 return Source
.Data
(Index
);
828 raise Strings
.Index_Error
;
837 (Source
: in Bounded_String
;
838 Set
: in Maps
.Character_Set
;
839 Test
: in Strings
.Membership
;
840 First
: out Positive;
845 (Source
.Data
(1 .. Source
.Length
), Set
, Test
, First
, Last
);
854 (Source
: in Bounded_String
;
856 Pad
: in Character := Space
;
857 Drop
: in Strings
.Truncation
:= Strings
.Error
)
858 return Bounded_String
860 Result
: Bounded_String
;
861 Slen
: constant Natural := Source
.Length
;
862 Npad
: constant Integer := Count
- Slen
;
866 Result
.Length
:= Count
;
867 Result
.Data
(1 .. Count
) := Source
.Data
(1 .. Count
);
869 elsif Count
<= Max_Length
then
870 Result
.Length
:= Count
;
871 Result
.Data
(1 .. Slen
) := Source
.Data
(1 .. Slen
);
872 Result
.Data
(Slen
+ 1 .. Count
) := (others => Pad
);
875 Result
.Length
:= Max_Length
;
878 when Strings
.Right
=>
879 Result
.Data
(1 .. Slen
) := Source
.Data
(1 .. Slen
);
880 Result
.Data
(Slen
+ 1 .. Max_Length
) := (others => Pad
);
883 if Npad
>= Max_Length
then
884 Result
.Data
:= (others => Pad
);
887 Result
.Data
(1 .. Max_Length
- Npad
) :=
888 Source
.Data
(Count
- Max_Length
+ 1 .. Slen
);
889 Result
.Data
(Max_Length
- Npad
+ 1 .. Max_Length
) :=
893 when Strings
.Error
=>
894 raise Ada
.Strings
.Length_Error
;
902 (Source
: in out Bounded_String
;
904 Pad
: in Character := Space
;
905 Drop
: in Truncation
:= Error
)
907 Slen
: constant Natural := Source
.Length
;
908 Npad
: constant Integer := Count
- Slen
;
909 Temp
: String (1 .. Max_Length
);
913 Source
.Length
:= Count
;
915 elsif Count
<= Max_Length
then
916 Source
.Length
:= Count
;
917 Source
.Data
(Slen
+ 1 .. Count
) := (others => Pad
);
920 Source
.Length
:= Max_Length
;
923 when Strings
.Right
=>
924 Source
.Data
(Slen
+ 1 .. Max_Length
) := (others => Pad
);
927 if Npad
> Max_Length
then
928 Source
.Data
:= (others => Pad
);
932 Source
.Data
(1 .. Max_Length
- Npad
) :=
933 Temp
(Count
- Max_Length
+ 1 .. Slen
);
935 for J
in Max_Length
- Npad
+ 1 .. Max_Length
loop
936 Source
.Data
(J
) := Pad
;
940 when Strings
.Error
=>
941 raise Ada
.Strings
.Length_Error
;
952 (Source
: in Bounded_String
;
954 Going
: in Strings
.Direction
:= Strings
.Forward
;
955 Mapping
: in Maps
.Character_Mapping
:= Maps
.Identity
)
960 (Source
.Data
(1 .. Source
.Length
), Pattern
, Going
, Mapping
);
964 (Source
: in Bounded_String
;
966 Going
: in Direction
:= Forward
;
967 Mapping
: in Maps
.Character_Mapping_Function
)
972 (Source
.Data
(1 .. Source
.Length
), Pattern
, Going
, Mapping
);
976 (Source
: in Bounded_String
;
977 Set
: in Maps
.Character_Set
;
978 Test
: in Strings
.Membership
:= Strings
.Inside
;
979 Going
: in Strings
.Direction
:= Strings
.Forward
)
984 (Source
.Data
(1 .. Source
.Length
), Set
, Test
, Going
);
987 ---------------------
988 -- Index_Non_Blank --
989 ---------------------
991 function Index_Non_Blank
992 (Source
: in Bounded_String
;
993 Going
: in Strings
.Direction
:= Strings
.Forward
)
998 Search
.Index_Non_Blank
(Source
.Data
(1 .. Source
.Length
), Going
);
1006 (Source
: in Bounded_String
;
1007 Before
: in Positive;
1008 New_Item
: in String;
1009 Drop
: in Strings
.Truncation
:= Strings
.Error
)
1010 return Bounded_String
1012 Slen
: constant Natural := Source
.Length
;
1013 Nlen
: constant Natural := New_Item
'Length;
1014 Tlen
: constant Natural := Slen
+ Nlen
;
1015 Blen
: constant Natural := Before
- 1;
1016 Alen
: constant Integer := Slen
- Blen
;
1017 Droplen
: constant Integer := Tlen
- Max_Length
;
1018 Result
: Bounded_String
;
1020 -- Tlen is the length of the total string before possible truncation.
1021 -- Blen, Alen are the lengths of the before and after pieces of the
1026 raise Ada
.Strings
.Index_Error
;
1028 elsif Droplen
<= 0 then
1029 Result
.Length
:= Tlen
;
1030 Result
.Data
(1 .. Blen
) := Source
.Data
(1 .. Blen
);
1031 Result
.Data
(Before
.. Before
+ Nlen
- 1) := New_Item
;
1032 Result
.Data
(Before
+ Nlen
.. Tlen
) :=
1033 Source
.Data
(Before
.. Slen
);
1036 Result
.Length
:= Max_Length
;
1039 when Strings
.Right
=>
1040 Result
.Data
(1 .. Blen
) := Source
.Data
(1 .. Blen
);
1042 if Droplen
> Alen
then
1043 Result
.Data
(Before
.. Max_Length
) :=
1044 New_Item
(New_Item
'First
1045 .. New_Item
'First + Max_Length
- Before
);
1047 Result
.Data
(Before
.. Before
+ Nlen
- 1) := New_Item
;
1048 Result
.Data
(Before
+ Nlen
.. Max_Length
) :=
1049 Source
.Data
(Before
.. Slen
- Droplen
);
1052 when Strings
.Left
=>
1053 Result
.Data
(Max_Length
- (Alen
- 1) .. Max_Length
) :=
1054 Source
.Data
(Before
.. Slen
);
1056 if Droplen
>= Blen
then
1057 Result
.Data
(1 .. Max_Length
- Alen
) :=
1058 New_Item
(New_Item
'Last - (Max_Length
- Alen
) + 1
1062 (Blen
- Droplen
+ 1 .. Max_Length
- Alen
) :=
1064 Result
.Data
(1 .. Blen
- Droplen
) :=
1065 Source
.Data
(Droplen
+ 1 .. Blen
);
1068 when Strings
.Error
=>
1069 raise Ada
.Strings
.Length_Error
;
1077 (Source
: in out Bounded_String
;
1078 Before
: in Positive;
1079 New_Item
: in String;
1080 Drop
: in Strings
.Truncation
:= Strings
.Error
)
1083 -- We do a double copy here because this is one of the situations
1084 -- in which we move data to the right, and at least at the moment,
1085 -- GNAT is not handling such cases correctly ???
1087 Source
:= Insert
(Source
, Before
, New_Item
, Drop
);
1094 function Length
(Source
: in Bounded_String
) return Length_Range
is
1096 return Source
.Length
;
1104 (Source
: in Bounded_String
;
1105 Position
: in Positive;
1106 New_Item
: in String;
1107 Drop
: in Strings
.Truncation
:= Strings
.Error
)
1108 return Bounded_String
1110 Result
: Bounded_String
;
1111 Endpos
: constant Natural := Position
+ New_Item
'Length - 1;
1112 Slen
: constant Natural := Source
.Length
;
1116 if Position
> Slen
+ 1 then
1117 raise Ada
.Strings
.Index_Error
;
1119 elsif New_Item
'Length = 0 then
1122 elsif Endpos
<= Slen
then
1123 Result
.Length
:= Source
.Length
;
1124 Result
.Data
(1 .. Slen
) := Source
.Data
(1 .. Slen
);
1125 Result
.Data
(Position
.. Endpos
) := New_Item
;
1128 elsif Endpos
<= Max_Length
then
1129 Result
.Length
:= Endpos
;
1130 Result
.Data
(1 .. Position
- 1) := Source
.Data
(1 .. Position
- 1);
1131 Result
.Data
(Position
.. Endpos
) := New_Item
;
1135 Result
.Length
:= Max_Length
;
1136 Droplen
:= Endpos
- Max_Length
;
1139 when Strings
.Right
=>
1140 Result
.Data
(1 .. Position
- 1) :=
1141 Source
.Data
(1 .. Position
- 1);
1143 Result
.Data
(Position
.. Max_Length
) :=
1144 New_Item
(New_Item
'First .. New_Item
'Last - Droplen
);
1147 when Strings
.Left
=>
1148 if New_Item
'Length >= Max_Length
then
1149 Result
.Data
(1 .. Max_Length
) :=
1150 New_Item
(New_Item
'Last - Max_Length
+ 1 ..
1155 Result
.Data
(1 .. Max_Length
- New_Item
'Length) :=
1156 Source
.Data
(Droplen
+ 1 .. Position
- 1);
1158 (Max_Length
- New_Item
'Length + 1 .. Max_Length
) :=
1163 when Strings
.Error
=>
1164 raise Ada
.Strings
.Length_Error
;
1170 (Source
: in out Bounded_String
;
1171 Position
: in Positive;
1172 New_Item
: in String;
1173 Drop
: in Strings
.Truncation
:= Strings
.Error
)
1175 Endpos
: constant Positive := Position
+ New_Item
'Length - 1;
1176 Slen
: constant Natural := Source
.Length
;
1180 if Position
> Slen
+ 1 then
1181 raise Ada
.Strings
.Index_Error
;
1183 elsif Endpos
<= Slen
then
1184 Source
.Data
(Position
.. Endpos
) := New_Item
;
1186 elsif Endpos
<= Max_Length
then
1187 Source
.Data
(Position
.. Endpos
) := New_Item
;
1188 Source
.Length
:= Endpos
;
1191 Source
.Length
:= Max_Length
;
1192 Droplen
:= Endpos
- Max_Length
;
1195 when Strings
.Right
=>
1196 Source
.Data
(Position
.. Max_Length
) :=
1197 New_Item
(New_Item
'First .. New_Item
'Last - Droplen
);
1199 when Strings
.Left
=>
1200 if New_Item
'Length > Max_Length
then
1201 Source
.Data
(1 .. Max_Length
) :=
1202 New_Item
(New_Item
'Last - Max_Length
+ 1 ..
1206 Source
.Data
(1 .. Max_Length
- New_Item
'Length) :=
1207 Source
.Data
(Droplen
+ 1 .. Position
- 1);
1210 (Max_Length
- New_Item
'Length + 1 .. Max_Length
) :=
1214 when Strings
.Error
=>
1215 raise Ada
.Strings
.Length_Error
;
1220 ---------------------
1221 -- Replace_Element --
1222 ---------------------
1224 procedure Replace_Element
1225 (Source
: in out Bounded_String
;
1226 Index
: in Positive;
1230 if Index
<= Source
.Length
then
1231 Source
.Data
(Index
) := By
;
1233 raise Ada
.Strings
.Index_Error
;
1235 end Replace_Element
;
1241 function Replace_Slice
1242 (Source
: in Bounded_String
;
1246 Drop
: in Strings
.Truncation
:= Strings
.Error
)
1247 return Bounded_String
1249 Slen
: constant Natural := Source
.Length
;
1252 if Low
> Slen
+ 1 then
1253 raise Strings
.Index_Error
;
1255 elsif High
< Low
then
1256 return Insert
(Source
, Low
, By
, Drop
);
1260 Blen
: constant Natural := Natural'Max (0, Low
- 1);
1261 Alen
: constant Natural := Natural'Max (0, Slen
- High
);
1262 Tlen
: constant Natural := Blen
+ By
'Length + Alen
;
1263 Droplen
: constant Integer := Tlen
- Max_Length
;
1264 Result
: Bounded_String
;
1266 -- Tlen is the total length of the result string before any
1267 -- truncation. Blen and Alen are the lengths of the pieces
1268 -- of the original string that end up in the result string
1269 -- before and after the replaced slice.
1272 if Droplen
<= 0 then
1273 Result
.Length
:= Tlen
;
1274 Result
.Data
(1 .. Blen
) := Source
.Data
(1 .. Blen
);
1275 Result
.Data
(Low
.. Low
+ By
'Length - 1) := By
;
1276 Result
.Data
(Low
+ By
'Length .. Tlen
) :=
1277 Source
.Data
(High
+ 1 .. Slen
);
1280 Result
.Length
:= Max_Length
;
1283 when Strings
.Right
=>
1284 Result
.Data
(1 .. Blen
) := Source
.Data
(1 .. Blen
);
1286 if Droplen
> Alen
then
1287 Result
.Data
(Low
.. Max_Length
) :=
1288 By
(By
'First .. By
'First + Max_Length
- Low
);
1290 Result
.Data
(Low
.. Low
+ By
'Length - 1) := By
;
1291 Result
.Data
(Low
+ By
'Length .. Max_Length
) :=
1292 Source
.Data
(High
+ 1 .. Slen
- Droplen
);
1295 when Strings
.Left
=>
1296 Result
.Data
(Max_Length
- (Alen
- 1) .. Max_Length
) :=
1297 Source
.Data
(High
+ 1 .. Slen
);
1299 if Droplen
>= Blen
then
1300 Result
.Data
(1 .. Max_Length
- Alen
) :=
1301 By
(By
'Last - (Max_Length
- Alen
) + 1 .. By
'Last);
1304 (Blen
- Droplen
+ 1 .. Max_Length
- Alen
) := By
;
1305 Result
.Data
(1 .. Blen
- Droplen
) :=
1306 Source
.Data
(Droplen
+ 1 .. Blen
);
1309 when Strings
.Error
=>
1310 raise Ada
.Strings
.Length_Error
;
1319 procedure Replace_Slice
1320 (Source
: in out Bounded_String
;
1324 Drop
: in Strings
.Truncation
:= Strings
.Error
)
1327 -- We do a double copy here because this is one of the situations
1328 -- in which we move data to the right, and at least at the moment,
1329 -- GNAT is not handling such cases correctly ???
1331 Source
:= Replace_Slice
(Source
, Low
, High
, By
, Drop
);
1339 (Count
: in Natural;
1340 Item
: in Character;
1341 Drop
: in Strings
.Truncation
:= Strings
.Error
)
1342 return Bounded_String
1344 Result
: Bounded_String
;
1347 if Count
<= Max_Length
then
1348 Result
.Length
:= Count
;
1350 elsif Drop
= Strings
.Error
then
1351 raise Ada
.Strings
.Length_Error
;
1354 Result
.Length
:= Max_Length
;
1357 Result
.Data
(1 .. Result
.Length
) := (others => Item
);
1362 (Count
: in Natural;
1364 Drop
: in Strings
.Truncation
:= Strings
.Error
)
1365 return Bounded_String
1367 Length
: constant Integer := Count
* Item
'Length;
1368 Result
: Bounded_String
;
1372 if Length
<= Max_Length
then
1373 Result
.Length
:= Length
;
1378 for J
in 1 .. Count
loop
1379 Result
.Data
(Indx
.. Indx
+ Item
'Length - 1) := Item
;
1380 Indx
:= Indx
+ Item
'Length;
1385 Result
.Length
:= Max_Length
;
1388 when Strings
.Right
=>
1391 while Indx
+ Item
'Length <= Max_Length
+ 1 loop
1392 Result
.Data
(Indx
.. Indx
+ Item
'Length - 1) := Item
;
1393 Indx
:= Indx
+ Item
'Length;
1396 Result
.Data
(Indx
.. Max_Length
) :=
1397 Item
(Item
'First .. Item
'First + Max_Length
- Indx
);
1399 when Strings
.Left
=>
1402 while Indx
- Item
'Length >= 1 loop
1403 Result
.Data
(Indx
- (Item
'Length - 1) .. Indx
) := Item
;
1404 Indx
:= Indx
- Item
'Length;
1407 Result
.Data
(1 .. Indx
) :=
1408 Item
(Item
'Last - Indx
+ 1 .. Item
'Last);
1410 when Strings
.Error
=>
1411 raise Ada
.Strings
.Length_Error
;
1419 (Count
: in Natural;
1420 Item
: in Bounded_String
;
1421 Drop
: in Strings
.Truncation
:= Strings
.Error
)
1422 return Bounded_String
1425 return Replicate
(Count
, Item
.Data
(1 .. Item
.Length
), Drop
);
1433 (Source
: Bounded_String
;
1439 -- Note: test of High > Length is in accordance with AI95-00128
1441 if Low
> Source
.Length
+ 1 or else High
> Source
.Length
then
1444 return Source
.Data
(Low
.. High
);
1453 (Source
: in Bounded_String
;
1455 Pad
: in Character := Space
;
1456 Drop
: in Strings
.Truncation
:= Strings
.Error
)
1457 return Bounded_String
1459 Result
: Bounded_String
;
1460 Slen
: constant Natural := Source
.Length
;
1461 Npad
: constant Integer := Count
- Slen
;
1465 Result
.Length
:= Count
;
1466 Result
.Data
(1 .. Count
) :=
1467 Source
.Data
(Slen
- (Count
- 1) .. Slen
);
1469 elsif Count
<= Max_Length
then
1470 Result
.Length
:= Count
;
1471 Result
.Data
(1 .. Npad
) := (others => Pad
);
1472 Result
.Data
(Npad
+ 1 .. Count
) := Source
.Data
(1 .. Slen
);
1475 Result
.Length
:= Max_Length
;
1478 when Strings
.Right
=>
1479 if Npad
>= Max_Length
then
1480 Result
.Data
:= (others => Pad
);
1483 Result
.Data
(1 .. Npad
) := (others => Pad
);
1484 Result
.Data
(Npad
+ 1 .. Max_Length
) :=
1485 Source
.Data
(1 .. Max_Length
- Npad
);
1488 when Strings
.Left
=>
1489 Result
.Data
(1 .. Max_Length
- Slen
) := (others => Pad
);
1490 Result
.Data
(Max_Length
- Slen
+ 1 .. Max_Length
) :=
1491 Source
.Data
(1 .. Slen
);
1493 when Strings
.Error
=>
1494 raise Ada
.Strings
.Length_Error
;
1502 (Source
: in out Bounded_String
;
1504 Pad
: in Character := Space
;
1505 Drop
: in Truncation
:= Error
)
1507 Slen
: constant Natural := Source
.Length
;
1508 Npad
: constant Integer := Count
- Slen
;
1509 Temp
: String (1 .. Max_Length
) := Source
.Data
;
1513 Source
.Length
:= Count
;
1514 Source
.Data
(1 .. Count
) :=
1515 Temp
(Slen
- (Count
- 1) .. Slen
);
1517 elsif Count
<= Max_Length
then
1518 Source
.Length
:= Count
;
1519 Source
.Data
(1 .. Npad
) := (others => Pad
);
1520 Source
.Data
(Npad
+ 1 .. Count
) := Temp
(1 .. Slen
);
1523 Source
.Length
:= Max_Length
;
1526 when Strings
.Right
=>
1527 if Npad
>= Max_Length
then
1528 Source
.Data
:= (others => Pad
);
1531 Source
.Data
(1 .. Npad
) := (others => Pad
);
1532 Source
.Data
(Npad
+ 1 .. Max_Length
) :=
1533 Temp
(1 .. Max_Length
- Npad
);
1536 when Strings
.Left
=>
1537 for J
in 1 .. Max_Length
- Slen
loop
1538 Source
.Data
(J
) := Pad
;
1541 Source
.Data
(Max_Length
- Slen
+ 1 .. Max_Length
) :=
1544 when Strings
.Error
=>
1545 raise Ada
.Strings
.Length_Error
;
1551 -----------------------
1552 -- To_Bounded_String --
1553 -----------------------
1555 function To_Bounded_String
1556 (Source
: in String;
1557 Drop
: in Strings
.Truncation
:= Strings
.Error
)
1558 return Bounded_String
1560 Slen
: constant Natural := Source
'Length;
1561 Result
: Bounded_String
;
1564 if Slen
<= Max_Length
then
1565 Result
.Length
:= Slen
;
1566 Result
.Data
(1 .. Slen
) := Source
;
1570 when Strings
.Right
=>
1571 Result
.Length
:= Max_Length
;
1572 Result
.Data
(1 .. Max_Length
) :=
1573 Source
(Source
'First .. Source
'First - 1 + Max_Length
);
1575 when Strings
.Left
=>
1576 Result
.Length
:= Max_Length
;
1577 Result
.Data
(1 .. Max_Length
) :=
1578 Source
(Source
'Last - (Max_Length
- 1) .. Source
'Last);
1580 when Strings
.Error
=>
1581 raise Ada
.Strings
.Length_Error
;
1586 end To_Bounded_String
;
1592 function To_String
(Source
: in Bounded_String
) return String is
1594 return Source
.Data
(1 .. Source
.Length
);
1602 (Source
: in Bounded_String
;
1603 Mapping
: in Maps
.Character_Mapping
)
1604 return Bounded_String
1606 Result
: Bounded_String
;
1609 Result
.Length
:= Source
.Length
;
1611 for J
in 1 .. Source
.Length
loop
1612 Result
.Data
(J
) := Value
(Mapping
, Source
.Data
(J
));
1619 (Source
: in out Bounded_String
;
1620 Mapping
: in Maps
.Character_Mapping
)
1623 for J
in 1 .. Source
.Length
loop
1624 Source
.Data
(J
) := Value
(Mapping
, Source
.Data
(J
));
1629 (Source
: in Bounded_String
;
1630 Mapping
: in Maps
.Character_Mapping_Function
)
1631 return Bounded_String
1633 Result
: Bounded_String
;
1636 Result
.Length
:= Source
.Length
;
1638 for J
in 1 .. Source
.Length
loop
1639 Result
.Data
(J
) := Mapping
.all (Source
.Data
(J
));
1646 (Source
: in out Bounded_String
;
1647 Mapping
: in Maps
.Character_Mapping_Function
)
1650 for J
in 1 .. Source
.Length
loop
1651 Source
.Data
(J
) := Mapping
.all (Source
.Data
(J
));
1659 function Trim
(Source
: in Bounded_String
; Side
: in Trim_End
)
1660 return Bounded_String
1662 Result
: Bounded_String
;
1663 Last
: Natural := Source
.Length
;
1664 First
: Positive := 1;
1667 if Side
= Left
or else Side
= Both
then
1668 while First
<= Last
and then Source
.Data
(First
) = ' ' loop
1673 if Side
= Right
or else Side
= Both
then
1674 while Last
>= First
and then Source
.Data
(Last
) = ' ' loop
1679 Result
.Length
:= Last
- First
+ 1;
1680 Result
.Data
(1 .. Result
.Length
) := Source
.Data
(First
.. Last
);
1686 (Source
: in out Bounded_String
;
1689 Last
: Length_Range
:= Source
.Length
;
1690 First
: Positive := 1;
1691 Temp
: String (1 .. Max_Length
);
1694 Temp
(1 .. Last
) := Source
.Data
(1 .. Last
);
1696 if Side
= Left
or else Side
= Both
then
1697 while First
<= Last
and then Temp
(First
) = ' ' loop
1702 if Side
= Right
or else Side
= Both
then
1703 while Last
>= First
and then Temp
(Last
) = ' ' loop
1708 Source
:= Null_Bounded_String
;
1709 Source
.Length
:= Last
- First
+ 1;
1710 Source
.Data
(1 .. Source
.Length
) := Temp
(First
.. Last
);
1715 (Source
: in Bounded_String
;
1716 Left
: in Maps
.Character_Set
;
1717 Right
: in Maps
.Character_Set
)
1718 return Bounded_String
1720 Result
: Bounded_String
;
1723 for First
in 1 .. Source
.Length
loop
1724 if not Is_In
(Source
.Data
(First
), Left
) then
1725 for Last
in reverse First
.. Source
.Length
loop
1726 if not Is_In
(Source
.Data
(Last
), Right
) then
1727 Result
.Length
:= Last
- First
+ 1;
1728 Result
.Data
(1 .. Result
.Length
) :=
1729 Source
.Data
(First
.. Last
);
1741 (Source
: in out Bounded_String
;
1742 Left
: in Maps
.Character_Set
;
1743 Right
: in Maps
.Character_Set
)
1746 for First
in 1 .. Source
.Length
loop
1747 if not Is_In
(Source
.Data
(First
), Left
) then
1748 for Last
in reverse First
.. Source
.Length
loop
1749 if not Is_In
(Source
.Data
(Last
), Right
) then
1751 Source
.Length
:= Last
;
1754 Source
.Length
:= Last
- First
+ 1;
1755 Source
.Data
(1 .. Source
.Length
) :=
1756 Source
.Data
(First
.. Last
);
1758 for J
in Source
.Length
+ 1 .. Max_Length
loop
1759 Source
.Data
(J
) := ASCII
.NUL
;
1775 end Generic_Bounded_Length
;
1777 end Ada
.Strings
.Bounded
;