1 ------------------------------------------------------------------------------
3 -- GNAT RUNTIME COMPONENTS --
5 -- A D A . S T R I N G S . B O U N D E D --
9 -- Copyright (C) 1992-2001 Free Software Foundation, Inc. --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 2, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
17 -- for more details. You should have received a copy of the GNU General --
18 -- Public License distributed with GNAT; see file COPYING. If not, write --
19 -- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
20 -- MA 02111-1307, USA. --
22 -- As a special exception, if other files instantiate generics from this --
23 -- unit, or you link this unit with other files to produce an executable, --
24 -- this unit does not by itself cause the resulting executable to be --
25 -- covered by the GNU General Public License. This exception does not --
26 -- however invalidate any other reasons why the executable file might be --
27 -- covered by the GNU Public License. --
29 -- GNAT was originally developed by the GNAT team at New York University. --
30 -- Extensive contributions were provided by Ada Core Technologies Inc. --
32 ------------------------------------------------------------------------------
34 with Ada
.Strings
.Maps
; use Ada
.Strings
.Maps
;
35 with Ada
.Strings
.Search
;
37 package body Ada
.Strings
.Bounded
is
39 package body Generic_Bounded_Length
is
46 (Left
: in Bounded_String
;
47 Right
: in Bounded_String
)
50 Result
: Bounded_String
;
51 Llen
: constant Length_Range
:= Left
.Length
;
52 Rlen
: constant Length_Range
:= Right
.Length
;
53 Nlen
: constant Natural := Llen
+ Rlen
;
56 if Nlen
> Max_Length
then
57 raise Ada
.Strings
.Length_Error
;
59 Result
.Length
:= Nlen
;
60 Result
.Data
(1 .. Llen
) := Left
.Data
(1 .. Llen
);
61 Result
.Data
(Llen
+ 1 .. Nlen
) := Right
.Data
(1 .. Rlen
);
68 (Left
: in Bounded_String
;
72 Result
: Bounded_String
;
73 Llen
: constant Length_Range
:= Left
.Length
;
75 Nlen
: constant Natural := Llen
+ Right
'Length;
78 if Nlen
> Max_Length
then
79 raise Ada
.Strings
.Length_Error
;
81 Result
.Length
:= Nlen
;
82 Result
.Data
(1 .. Llen
) := Left
.Data
(1 .. Llen
);
83 Result
.Data
(Llen
+ 1 .. Nlen
) := Right
;
90 Right
: in Bounded_String
)
93 Result
: Bounded_String
;
94 Llen
: constant Length_Range
:= Left
'Length;
95 Rlen
: constant Length_Range
:= Right
.Length
;
96 Nlen
: constant Natural := Llen
+ Rlen
;
99 if Nlen
> Max_Length
then
100 raise Ada
.Strings
.Length_Error
;
102 Result
.Length
:= Nlen
;
103 Result
.Data
(1 .. Llen
) := Left
;
104 Result
.Data
(Llen
+ 1 .. Nlen
) := Right
.Data
(1 .. Rlen
);
111 (Left
: in Bounded_String
;
112 Right
: in Character)
113 return Bounded_String
115 Result
: Bounded_String
;
116 Llen
: constant Length_Range
:= Left
.Length
;
119 if Llen
= Max_Length
then
120 raise Ada
.Strings
.Length_Error
;
122 Result
.Length
:= Llen
+ 1;
123 Result
.Data
(1 .. Llen
) := Left
.Data
(1 .. Llen
);
124 Result
.Data
(Result
.Length
) := Right
;
131 (Left
: in Character;
132 Right
: in Bounded_String
)
133 return Bounded_String
135 Result
: Bounded_String
;
136 Rlen
: Length_Range
:= Right
.Length
;
139 if Rlen
= Max_Length
then
140 raise Ada
.Strings
.Length_Error
;
142 Result
.Length
:= Rlen
+ 1;
143 Result
.Data
(1) := Left
;
144 Result
.Data
(2 .. Result
.Length
) := Right
.Data
(1 .. Rlen
);
156 Right
: in Character)
157 return Bounded_String
159 Result
: Bounded_String
;
162 if Left
> Max_Length
then
163 raise Ada
.Strings
.Length_Error
;
165 Result
.Length
:= Left
;
167 for J
in 1 .. Left
loop
168 Result
.Data
(J
) := Right
;
178 return Bounded_String
180 Result
: Bounded_String
;
182 Rlen
: constant Natural := Right
'Length;
183 Nlen
: constant Natural := Left
* Rlen
;
186 if Nlen
> Max_Length
then
187 raise Ada
.Strings
.Index_Error
;
189 Result
.Length
:= Nlen
;
192 for J
in 1 .. Left
loop
193 Result
.Data
(Pos
.. Pos
+ Rlen
- 1) := Right
;
204 Right
: in Bounded_String
)
205 return Bounded_String
207 Result
: Bounded_String
;
209 Rlen
: constant Length_Range
:= Right
.Length
;
210 Nlen
: constant Natural := Left
* Rlen
;
213 if Nlen
> Max_Length
then
214 raise Ada
.Strings
.Length_Error
;
217 Result
.Length
:= Nlen
;
220 for J
in 1 .. Left
loop
221 Result
.Data
(Pos
.. Pos
+ Rlen
- 1) :=
222 Right
.Data
(1 .. Rlen
);
235 function "<" (Left
, Right
: in Bounded_String
) return Boolean is
237 return Left
.Data
(1 .. Left
.Length
) < Right
.Data
(1 .. Right
.Length
);
241 (Left
: in Bounded_String
;
246 return Left
.Data
(1 .. Left
.Length
) < Right
;
251 Right
: in Bounded_String
)
255 return Left
< Right
.Data
(1 .. Right
.Length
);
262 function "<=" (Left
, Right
: in Bounded_String
) return Boolean is
264 return Left
.Data
(1 .. Left
.Length
) <= Right
.Data
(1 .. Right
.Length
);
268 (Left
: in Bounded_String
;
273 return Left
.Data
(1 .. Left
.Length
) <= Right
;
278 Right
: in Bounded_String
)
282 return Left
<= Right
.Data
(1 .. Right
.Length
);
289 function "=" (Left
, Right
: in Bounded_String
) return Boolean is
291 return Left
.Length
= Right
.Length
292 and then Left
.Data
(1 .. Left
.Length
) =
293 Right
.Data
(1 .. Right
.Length
);
296 function "=" (Left
: in Bounded_String
; Right
: in String)
299 return Left
.Length
= Right
'Length
300 and then Left
.Data
(1 .. Left
.Length
) = Right
;
303 function "=" (Left
: in String; Right
: in Bounded_String
)
306 return Left
'Length = Right
.Length
307 and then Left
= Right
.Data
(1 .. Right
.Length
);
314 function ">" (Left
, Right
: in Bounded_String
) return Boolean is
316 return Left
.Data
(1 .. Left
.Length
) > Right
.Data
(1 .. Right
.Length
);
320 (Left
: in Bounded_String
;
325 return Left
.Data
(1 .. Left
.Length
) > Right
;
330 Right
: in Bounded_String
)
334 return Left
> Right
.Data
(1 .. Right
.Length
);
341 function ">=" (Left
, Right
: in Bounded_String
) return Boolean is
343 return Left
.Data
(1 .. Left
.Length
) >= Right
.Data
(1 .. Right
.Length
);
347 (Left
: in Bounded_String
;
352 return Left
.Data
(1 .. Left
.Length
) >= Right
;
357 Right
: in Bounded_String
)
361 return Left
>= Right
.Data
(1 .. Right
.Length
);
368 -- Case of Bounded_String and Bounded_String
371 (Left
, Right
: in Bounded_String
;
372 Drop
: in Strings
.Truncation
:= Strings
.Error
)
373 return Bounded_String
375 Result
: Bounded_String
;
376 Llen
: constant Length_Range
:= Left
.Length
;
377 Rlen
: constant Length_Range
:= Right
.Length
;
378 Nlen
: constant Natural := Llen
+ Rlen
;
381 if Nlen
<= Max_Length
then
382 Result
.Length
:= Nlen
;
383 Result
.Data
(1 .. Llen
) := Left
.Data
(1 .. Llen
);
384 Result
.Data
(Llen
+ 1 .. Nlen
) := Right
.Data
(1 .. Rlen
);
387 Result
.Length
:= Max_Length
;
390 when Strings
.Right
=>
391 if Llen
>= Max_Length
then -- only case is Llen = Max_Length
392 Result
.Data
:= Left
.Data
;
395 Result
.Data
(1 .. Llen
) := Left
.Data
(1 .. Llen
);
396 Result
.Data
(Llen
+ 1 .. Max_Length
) :=
397 Right
.Data
(1 .. Max_Length
- Llen
);
401 if Rlen
>= Max_Length
then -- only case is Rlen = Max_Length
402 Result
.Data
:= Right
.Data
;
405 Result
.Data
(1 .. Max_Length
- Rlen
) :=
406 Left
.Data
(Llen
- (Max_Length
- Rlen
- 1) .. Llen
);
407 Result
.Data
(Max_Length
- Rlen
+ 1 .. Max_Length
) :=
408 Right
.Data
(1 .. Rlen
);
411 when Strings
.Error
=>
412 raise Ada
.Strings
.Length_Error
;
420 (Source
: in out Bounded_String
;
421 New_Item
: in Bounded_String
;
422 Drop
: in Truncation
:= Error
)
424 Llen
: constant Length_Range
:= Source
.Length
;
425 Rlen
: constant Length_Range
:= New_Item
.Length
;
426 Nlen
: constant Natural := Llen
+ Rlen
;
429 if Nlen
<= Max_Length
then
430 Source
.Length
:= Nlen
;
431 Source
.Data
(Llen
+ 1 .. Nlen
) := New_Item
.Data
(1 .. Rlen
);
434 Source
.Length
:= Max_Length
;
437 when Strings
.Right
=>
438 if Llen
< Max_Length
then
439 Source
.Data
(Llen
+ 1 .. Max_Length
) :=
440 New_Item
.Data
(1 .. Max_Length
- Llen
);
444 if Rlen
>= Max_Length
then -- only case is Rlen = Max_Length
445 Source
.Data
:= New_Item
.Data
;
448 Source
.Data
(1 .. Max_Length
- Rlen
) :=
449 Source
.Data
(Llen
- (Max_Length
- Rlen
- 1) .. Llen
);
450 Source
.Data
(Max_Length
- Rlen
+ 1 .. Max_Length
) :=
451 New_Item
.Data
(1 .. Rlen
);
454 when Strings
.Error
=>
455 raise Ada
.Strings
.Length_Error
;
461 -- Case of Bounded_String and String
464 (Left
: in Bounded_String
;
466 Drop
: in Strings
.Truncation
:= Strings
.Error
)
467 return Bounded_String
469 Result
: Bounded_String
;
470 Llen
: constant Length_Range
:= Left
.Length
;
471 Rlen
: constant Length_Range
:= Right
'Length;
472 Nlen
: constant Natural := Llen
+ Rlen
;
475 if Nlen
<= Max_Length
then
476 Result
.Length
:= Nlen
;
477 Result
.Data
(1 .. Llen
) := Left
.Data
(1 .. Llen
);
478 Result
.Data
(Llen
+ 1 .. Nlen
) := Right
;
481 Result
.Length
:= Max_Length
;
484 when Strings
.Right
=>
485 if Llen
>= Max_Length
then -- only case is Llen = Max_Length
486 Result
.Data
:= Left
.Data
;
489 Result
.Data
(1 .. Llen
) := Left
.Data
(1 .. Llen
);
490 Result
.Data
(Llen
+ 1 .. Max_Length
) :=
491 Right
(Right
'First .. Right
'First - 1 +
497 if Rlen
>= Max_Length
then
498 Result
.Data
(1 .. Max_Length
) :=
499 Right
(Right
'Last - (Max_Length
- 1) .. Right
'Last);
502 Result
.Data
(1 .. Max_Length
- Rlen
) :=
503 Left
.Data
(Llen
- (Max_Length
- Rlen
- 1) .. Llen
);
504 Result
.Data
(Max_Length
- Rlen
+ 1 .. Max_Length
) :=
508 when Strings
.Error
=>
509 raise Ada
.Strings
.Length_Error
;
517 (Source
: in out Bounded_String
;
518 New_Item
: in String;
519 Drop
: in Truncation
:= Error
)
521 Llen
: constant Length_Range
:= Source
.Length
;
522 Rlen
: constant Length_Range
:= New_Item
'Length;
523 Nlen
: constant Natural := Llen
+ Rlen
;
526 if Nlen
<= Max_Length
then
527 Source
.Length
:= Nlen
;
528 Source
.Data
(Llen
+ 1 .. Nlen
) := New_Item
;
531 Source
.Length
:= Max_Length
;
534 when Strings
.Right
=>
535 if Llen
< Max_Length
then
536 Source
.Data
(Llen
+ 1 .. Max_Length
) :=
537 New_Item
(New_Item
'First ..
538 New_Item
'First - 1 + Max_Length
- Llen
);
542 if Rlen
>= Max_Length
then
543 Source
.Data
(1 .. Max_Length
) :=
544 New_Item
(New_Item
'Last - (Max_Length
- 1) ..
548 Source
.Data
(1 .. Max_Length
- Rlen
) :=
549 Source
.Data
(Llen
- (Max_Length
- Rlen
- 1) .. Llen
);
550 Source
.Data
(Max_Length
- Rlen
+ 1 .. Max_Length
) :=
554 when Strings
.Error
=>
555 raise Ada
.Strings
.Length_Error
;
561 -- Case of String and Bounded_String
565 Right
: in Bounded_String
;
566 Drop
: in Strings
.Truncation
:= Strings
.Error
)
567 return Bounded_String
569 Result
: Bounded_String
;
570 Llen
: constant Length_Range
:= Left
'Length;
571 Rlen
: constant Length_Range
:= Right
.Length
;
572 Nlen
: constant Natural := Llen
+ Rlen
;
575 if Nlen
<= Max_Length
then
576 Result
.Length
:= Nlen
;
577 Result
.Data
(1 .. Llen
) := Left
;
578 Result
.Data
(Llen
+ 1 .. Llen
+ Rlen
) := Right
.Data
(1 .. Rlen
);
581 Result
.Length
:= Max_Length
;
584 when Strings
.Right
=>
585 if Llen
>= Max_Length
then
586 Result
.Data
(1 .. Max_Length
) :=
587 Left
(Left
'First .. Left
'First + (Max_Length
- 1));
590 Result
.Data
(1 .. Llen
) := Left
;
591 Result
.Data
(Llen
+ 1 .. Max_Length
) :=
592 Right
.Data
(1 .. Max_Length
- Llen
);
596 if Rlen
>= Max_Length
then
597 Result
.Data
(1 .. Max_Length
) :=
598 Right
.Data
(Rlen
- (Max_Length
- 1) .. Rlen
);
601 Result
.Data
(1 .. Max_Length
- Rlen
) :=
602 Left
(Left
'Last - (Max_Length
- Rlen
- 1) .. Left
'Last);
603 Result
.Data
(Max_Length
- Rlen
+ 1 .. Max_Length
) :=
604 Right
.Data
(1 .. Rlen
);
607 when Strings
.Error
=>
608 raise Ada
.Strings
.Length_Error
;
615 -- Case of Bounded_String and Character
618 (Left
: in Bounded_String
;
619 Right
: in Character;
620 Drop
: in Strings
.Truncation
:= Strings
.Error
)
621 return Bounded_String
623 Result
: Bounded_String
;
624 Llen
: constant Length_Range
:= Left
.Length
;
627 if Llen
< Max_Length
then
628 Result
.Length
:= Llen
+ 1;
629 Result
.Data
(1 .. Llen
) := Left
.Data
(1 .. Llen
);
630 Result
.Data
(Llen
+ 1) := Right
;
635 when Strings
.Right
=>
639 Result
.Length
:= Max_Length
;
640 Result
.Data
(1 .. Max_Length
- 1) :=
641 Left
.Data
(2 .. Max_Length
);
642 Result
.Data
(Max_Length
) := Right
;
645 when Strings
.Error
=>
646 raise Ada
.Strings
.Length_Error
;
652 (Source
: in out Bounded_String
;
653 New_Item
: in Character;
654 Drop
: in Truncation
:= Error
)
656 Llen
: constant Length_Range
:= Source
.Length
;
659 if Llen
< Max_Length
then
660 Source
.Length
:= Llen
+ 1;
661 Source
.Data
(Llen
+ 1) := New_Item
;
664 Source
.Length
:= Max_Length
;
667 when Strings
.Right
=>
671 Source
.Data
(1 .. Max_Length
- 1) :=
672 Source
.Data
(2 .. Max_Length
);
673 Source
.Data
(Max_Length
) := New_Item
;
675 when Strings
.Error
=>
676 raise Ada
.Strings
.Length_Error
;
682 -- Case of Character and Bounded_String
685 (Left
: in Character;
686 Right
: in Bounded_String
;
687 Drop
: in Strings
.Truncation
:= Strings
.Error
)
688 return Bounded_String
690 Result
: Bounded_String
;
691 Rlen
: constant Length_Range
:= Right
.Length
;
694 if Rlen
< Max_Length
then
695 Result
.Length
:= Rlen
+ 1;
696 Result
.Data
(1) := Left
;
697 Result
.Data
(2 .. Rlen
+ 1) := Right
.Data
(1 .. Rlen
);
702 when Strings
.Right
=>
703 Result
.Length
:= Max_Length
;
704 Result
.Data
(1) := Left
;
705 Result
.Data
(2 .. Max_Length
) :=
706 Right
.Data
(1 .. Max_Length
- 1);
712 when Strings
.Error
=>
713 raise Ada
.Strings
.Length_Error
;
723 (Source
: in Bounded_String
;
725 Mapping
: in Maps
.Character_Mapping
:= Maps
.Identity
)
730 Search
.Count
(Source
.Data
(1 .. Source
.Length
), Pattern
, Mapping
);
734 (Source
: in Bounded_String
;
736 Mapping
: in Maps
.Character_Mapping_Function
)
741 Search
.Count
(Source
.Data
(1 .. Source
.Length
), Pattern
, Mapping
);
745 (Source
: in Bounded_String
;
746 Set
: in Maps
.Character_Set
)
750 return Search
.Count
(Source
.Data
(1 .. Source
.Length
), Set
);
758 (Source
: in Bounded_String
;
760 Through
: in Natural)
761 return Bounded_String
763 Slen
: constant Natural := Source
.Length
;
764 Num_Delete
: constant Integer := Through
- From
+ 1;
765 Result
: Bounded_String
;
768 if Num_Delete
<= 0 then
771 elsif From
> Slen
+ 1 then
772 raise Ada
.Strings
.Index_Error
;
774 elsif Through
>= Slen
then
775 Result
.Length
:= From
- 1;
776 Result
.Data
(1 .. From
- 1) := Source
.Data
(1 .. From
- 1);
780 Result
.Length
:= Slen
- Num_Delete
;
781 Result
.Data
(1 .. From
- 1) := Source
.Data
(1 .. From
- 1);
782 Result
.Data
(From
.. Result
.Length
) :=
783 Source
.Data
(Through
+ 1 .. Slen
);
789 (Source
: in out Bounded_String
;
791 Through
: in Natural)
793 Slen
: constant Natural := Source
.Length
;
794 Num_Delete
: constant Integer := Through
- From
+ 1;
797 if Num_Delete
<= 0 then
800 elsif From
> Slen
+ 1 then
801 raise Ada
.Strings
.Index_Error
;
803 elsif Through
>= Slen
then
804 Source
.Length
:= From
- 1;
807 Source
.Length
:= Slen
- Num_Delete
;
808 Source
.Data
(From
.. Source
.Length
) :=
809 Source
.Data
(Through
+ 1 .. Slen
);
818 (Source
: in Bounded_String
;
823 if Index
in 1 .. Source
.Length
then
824 return Source
.Data
(Index
);
826 raise Strings
.Index_Error
;
835 (Source
: in Bounded_String
;
836 Set
: in Maps
.Character_Set
;
837 Test
: in Strings
.Membership
;
838 First
: out Positive;
843 (Source
.Data
(1 .. Source
.Length
), Set
, Test
, First
, Last
);
852 (Source
: in Bounded_String
;
854 Pad
: in Character := Space
;
855 Drop
: in Strings
.Truncation
:= Strings
.Error
)
856 return Bounded_String
858 Result
: Bounded_String
;
859 Slen
: constant Natural := Source
.Length
;
860 Npad
: constant Integer := Count
- Slen
;
864 Result
.Length
:= Count
;
865 Result
.Data
(1 .. Count
) := Source
.Data
(1 .. Count
);
867 elsif Count
<= Max_Length
then
868 Result
.Length
:= Count
;
869 Result
.Data
(1 .. Slen
) := Source
.Data
(1 .. Slen
);
870 Result
.Data
(Slen
+ 1 .. Count
) := (others => Pad
);
873 Result
.Length
:= Max_Length
;
876 when Strings
.Right
=>
877 Result
.Data
(1 .. Slen
) := Source
.Data
(1 .. Slen
);
878 Result
.Data
(Slen
+ 1 .. Max_Length
) := (others => Pad
);
881 if Npad
>= Max_Length
then
882 Result
.Data
:= (others => Pad
);
885 Result
.Data
(1 .. Max_Length
- Npad
) :=
886 Source
.Data
(Count
- Max_Length
+ 1 .. Slen
);
887 Result
.Data
(Max_Length
- Npad
+ 1 .. Max_Length
) :=
891 when Strings
.Error
=>
892 raise Ada
.Strings
.Length_Error
;
900 (Source
: in out Bounded_String
;
902 Pad
: in Character := Space
;
903 Drop
: in Truncation
:= Error
)
905 Slen
: constant Natural := Source
.Length
;
906 Npad
: constant Integer := Count
- Slen
;
907 Temp
: String (1 .. Max_Length
);
911 Source
.Length
:= Count
;
913 elsif Count
<= Max_Length
then
914 Source
.Length
:= Count
;
915 Source
.Data
(Slen
+ 1 .. Count
) := (others => Pad
);
918 Source
.Length
:= Max_Length
;
921 when Strings
.Right
=>
922 Source
.Data
(Slen
+ 1 .. Max_Length
) := (others => Pad
);
925 if Npad
> Max_Length
then
926 Source
.Data
:= (others => Pad
);
930 Source
.Data
(1 .. Max_Length
- Npad
) :=
931 Temp
(Count
- Max_Length
+ 1 .. Slen
);
933 for J
in Max_Length
- Npad
+ 1 .. Max_Length
loop
934 Source
.Data
(J
) := Pad
;
938 when Strings
.Error
=>
939 raise Ada
.Strings
.Length_Error
;
950 (Source
: in Bounded_String
;
952 Going
: in Strings
.Direction
:= Strings
.Forward
;
953 Mapping
: in Maps
.Character_Mapping
:= Maps
.Identity
)
958 (Source
.Data
(1 .. Source
.Length
), Pattern
, Going
, Mapping
);
962 (Source
: in Bounded_String
;
964 Going
: in Direction
:= Forward
;
965 Mapping
: in Maps
.Character_Mapping_Function
)
970 (Source
.Data
(1 .. Source
.Length
), Pattern
, Going
, Mapping
);
974 (Source
: in Bounded_String
;
975 Set
: in Maps
.Character_Set
;
976 Test
: in Strings
.Membership
:= Strings
.Inside
;
977 Going
: in Strings
.Direction
:= Strings
.Forward
)
982 (Source
.Data
(1 .. Source
.Length
), Set
, Test
, Going
);
985 ---------------------
986 -- Index_Non_Blank --
987 ---------------------
989 function Index_Non_Blank
990 (Source
: in Bounded_String
;
991 Going
: in Strings
.Direction
:= Strings
.Forward
)
996 Search
.Index_Non_Blank
(Source
.Data
(1 .. Source
.Length
), Going
);
1004 (Source
: in Bounded_String
;
1005 Before
: in Positive;
1006 New_Item
: in String;
1007 Drop
: in Strings
.Truncation
:= Strings
.Error
)
1008 return Bounded_String
1010 Slen
: constant Natural := Source
.Length
;
1011 Nlen
: constant Natural := New_Item
'Length;
1012 Tlen
: constant Natural := Slen
+ Nlen
;
1013 Blen
: constant Natural := Before
- 1;
1014 Alen
: constant Integer := Slen
- Blen
;
1015 Droplen
: constant Integer := Tlen
- Max_Length
;
1016 Result
: Bounded_String
;
1018 -- Tlen is the length of the total string before possible truncation.
1019 -- Blen, Alen are the lengths of the before and after pieces of the
1024 raise Ada
.Strings
.Index_Error
;
1026 elsif Droplen
<= 0 then
1027 Result
.Length
:= Tlen
;
1028 Result
.Data
(1 .. Blen
) := Source
.Data
(1 .. Blen
);
1029 Result
.Data
(Before
.. Before
+ Nlen
- 1) := New_Item
;
1030 Result
.Data
(Before
+ Nlen
.. Tlen
) :=
1031 Source
.Data
(Before
.. Slen
);
1034 Result
.Length
:= Max_Length
;
1037 when Strings
.Right
=>
1038 Result
.Data
(1 .. Blen
) := Source
.Data
(1 .. Blen
);
1040 if Droplen
> Alen
then
1041 Result
.Data
(Before
.. Max_Length
) :=
1042 New_Item
(New_Item
'First
1043 .. New_Item
'First + Max_Length
- Before
);
1045 Result
.Data
(Before
.. Before
+ Nlen
- 1) := New_Item
;
1046 Result
.Data
(Before
+ Nlen
.. Max_Length
) :=
1047 Source
.Data
(Before
.. Slen
- Droplen
);
1050 when Strings
.Left
=>
1051 Result
.Data
(Max_Length
- (Alen
- 1) .. Max_Length
) :=
1052 Source
.Data
(Before
.. Slen
);
1054 if Droplen
>= Blen
then
1055 Result
.Data
(1 .. Max_Length
- Alen
) :=
1056 New_Item
(New_Item
'Last - (Max_Length
- Alen
) + 1
1060 (Blen
- Droplen
+ 1 .. Max_Length
- Alen
) :=
1062 Result
.Data
(1 .. Blen
- Droplen
) :=
1063 Source
.Data
(Droplen
+ 1 .. Blen
);
1066 when Strings
.Error
=>
1067 raise Ada
.Strings
.Length_Error
;
1075 (Source
: in out Bounded_String
;
1076 Before
: in Positive;
1077 New_Item
: in String;
1078 Drop
: in Strings
.Truncation
:= Strings
.Error
)
1081 -- We do a double copy here because this is one of the situations
1082 -- in which we move data to the right, and at least at the moment,
1083 -- GNAT is not handling such cases correctly ???
1085 Source
:= Insert
(Source
, Before
, New_Item
, Drop
);
1092 function Length
(Source
: in Bounded_String
) return Length_Range
is
1094 return Source
.Length
;
1102 (Source
: in Bounded_String
;
1103 Position
: in Positive;
1104 New_Item
: in String;
1105 Drop
: in Strings
.Truncation
:= Strings
.Error
)
1106 return Bounded_String
1108 Result
: Bounded_String
;
1109 Endpos
: constant Natural := Position
+ New_Item
'Length - 1;
1110 Slen
: constant Natural := Source
.Length
;
1114 if Position
> Slen
+ 1 then
1115 raise Ada
.Strings
.Index_Error
;
1117 elsif New_Item
'Length = 0 then
1120 elsif Endpos
<= Slen
then
1121 Result
.Length
:= Source
.Length
;
1122 Result
.Data
(1 .. Slen
) := Source
.Data
(1 .. Slen
);
1123 Result
.Data
(Position
.. Endpos
) := New_Item
;
1126 elsif Endpos
<= Max_Length
then
1127 Result
.Length
:= Endpos
;
1128 Result
.Data
(1 .. Position
- 1) := Source
.Data
(1 .. Position
- 1);
1129 Result
.Data
(Position
.. Endpos
) := New_Item
;
1133 Result
.Length
:= Max_Length
;
1134 Droplen
:= Endpos
- Max_Length
;
1137 when Strings
.Right
=>
1138 Result
.Data
(1 .. Position
- 1) :=
1139 Source
.Data
(1 .. Position
- 1);
1141 Result
.Data
(Position
.. Max_Length
) :=
1142 New_Item
(New_Item
'First .. New_Item
'Last - Droplen
);
1145 when Strings
.Left
=>
1146 if New_Item
'Length >= Max_Length
then
1147 Result
.Data
(1 .. Max_Length
) :=
1148 New_Item
(New_Item
'Last - Max_Length
+ 1 ..
1153 Result
.Data
(1 .. Max_Length
- New_Item
'Length) :=
1154 Source
.Data
(Droplen
+ 1 .. Position
- 1);
1156 (Max_Length
- New_Item
'Length + 1 .. Max_Length
) :=
1161 when Strings
.Error
=>
1162 raise Ada
.Strings
.Length_Error
;
1168 (Source
: in out Bounded_String
;
1169 Position
: in Positive;
1170 New_Item
: in String;
1171 Drop
: in Strings
.Truncation
:= Strings
.Error
)
1173 Endpos
: constant Positive := Position
+ New_Item
'Length - 1;
1174 Slen
: constant Natural := Source
.Length
;
1178 if Position
> Slen
+ 1 then
1179 raise Ada
.Strings
.Index_Error
;
1181 elsif Endpos
<= Slen
then
1182 Source
.Data
(Position
.. Endpos
) := New_Item
;
1184 elsif Endpos
<= Max_Length
then
1185 Source
.Data
(Position
.. Endpos
) := New_Item
;
1186 Source
.Length
:= Endpos
;
1189 Source
.Length
:= Max_Length
;
1190 Droplen
:= Endpos
- Max_Length
;
1193 when Strings
.Right
=>
1194 Source
.Data
(Position
.. Max_Length
) :=
1195 New_Item
(New_Item
'First .. New_Item
'Last - Droplen
);
1197 when Strings
.Left
=>
1198 if New_Item
'Length > Max_Length
then
1199 Source
.Data
(1 .. Max_Length
) :=
1200 New_Item
(New_Item
'Last - Max_Length
+ 1 ..
1204 Source
.Data
(1 .. Max_Length
- New_Item
'Length) :=
1205 Source
.Data
(Droplen
+ 1 .. Position
- 1);
1208 (Max_Length
- New_Item
'Length + 1 .. Max_Length
) :=
1212 when Strings
.Error
=>
1213 raise Ada
.Strings
.Length_Error
;
1218 ---------------------
1219 -- Replace_Element --
1220 ---------------------
1222 procedure Replace_Element
1223 (Source
: in out Bounded_String
;
1224 Index
: in Positive;
1228 if Index
<= Source
.Length
then
1229 Source
.Data
(Index
) := By
;
1231 raise Ada
.Strings
.Index_Error
;
1233 end Replace_Element
;
1239 function Replace_Slice
1240 (Source
: in Bounded_String
;
1244 Drop
: in Strings
.Truncation
:= Strings
.Error
)
1245 return Bounded_String
1247 Slen
: constant Natural := Source
.Length
;
1250 if Low
> Slen
+ 1 then
1251 raise Strings
.Index_Error
;
1253 elsif High
< Low
then
1254 return Insert
(Source
, Low
, By
, Drop
);
1258 Blen
: constant Natural := Natural'Max (0, Low
- 1);
1259 Alen
: constant Natural := Natural'Max (0, Slen
- High
);
1260 Tlen
: constant Natural := Blen
+ By
'Length + Alen
;
1261 Droplen
: constant Integer := Tlen
- Max_Length
;
1262 Result
: Bounded_String
;
1264 -- Tlen is the total length of the result string before any
1265 -- truncation. Blen and Alen are the lengths of the pieces
1266 -- of the original string that end up in the result string
1267 -- before and after the replaced slice.
1270 if Droplen
<= 0 then
1271 Result
.Length
:= Tlen
;
1272 Result
.Data
(1 .. Blen
) := Source
.Data
(1 .. Blen
);
1273 Result
.Data
(Low
.. Low
+ By
'Length - 1) := By
;
1274 Result
.Data
(Low
+ By
'Length .. Tlen
) :=
1275 Source
.Data
(High
+ 1 .. Slen
);
1278 Result
.Length
:= Max_Length
;
1281 when Strings
.Right
=>
1282 Result
.Data
(1 .. Blen
) := Source
.Data
(1 .. Blen
);
1284 if Droplen
> Alen
then
1285 Result
.Data
(Low
.. Max_Length
) :=
1286 By
(By
'First .. By
'First + Max_Length
- Low
);
1288 Result
.Data
(Low
.. Low
+ By
'Length - 1) := By
;
1289 Result
.Data
(Low
+ By
'Length .. Max_Length
) :=
1290 Source
.Data
(High
+ 1 .. Slen
- Droplen
);
1293 when Strings
.Left
=>
1294 Result
.Data
(Max_Length
- (Alen
- 1) .. Max_Length
) :=
1295 Source
.Data
(High
+ 1 .. Slen
);
1297 if Droplen
>= Blen
then
1298 Result
.Data
(1 .. Max_Length
- Alen
) :=
1299 By
(By
'Last - (Max_Length
- Alen
) + 1 .. By
'Last);
1302 (Blen
- Droplen
+ 1 .. Max_Length
- Alen
) := By
;
1303 Result
.Data
(1 .. Blen
- Droplen
) :=
1304 Source
.Data
(Droplen
+ 1 .. Blen
);
1307 when Strings
.Error
=>
1308 raise Ada
.Strings
.Length_Error
;
1317 procedure Replace_Slice
1318 (Source
: in out Bounded_String
;
1322 Drop
: in Strings
.Truncation
:= Strings
.Error
)
1325 -- We do a double copy here because this is one of the situations
1326 -- in which we move data to the right, and at least at the moment,
1327 -- GNAT is not handling such cases correctly ???
1329 Source
:= Replace_Slice
(Source
, Low
, High
, By
, Drop
);
1337 (Count
: in Natural;
1338 Item
: in Character;
1339 Drop
: in Strings
.Truncation
:= Strings
.Error
)
1340 return Bounded_String
1342 Result
: Bounded_String
;
1345 if Count
<= Max_Length
then
1346 Result
.Length
:= Count
;
1348 elsif Drop
= Strings
.Error
then
1349 raise Ada
.Strings
.Length_Error
;
1352 Result
.Length
:= Max_Length
;
1355 Result
.Data
(1 .. Result
.Length
) := (others => Item
);
1360 (Count
: in Natural;
1362 Drop
: in Strings
.Truncation
:= Strings
.Error
)
1363 return Bounded_String
1365 Length
: constant Integer := Count
* Item
'Length;
1366 Result
: Bounded_String
;
1370 if Length
<= Max_Length
then
1371 Result
.Length
:= Length
;
1376 for J
in 1 .. Count
loop
1377 Result
.Data
(Indx
.. Indx
+ Item
'Length - 1) := Item
;
1378 Indx
:= Indx
+ Item
'Length;
1383 Result
.Length
:= Max_Length
;
1386 when Strings
.Right
=>
1389 while Indx
+ Item
'Length <= Max_Length
+ 1 loop
1390 Result
.Data
(Indx
.. Indx
+ Item
'Length - 1) := Item
;
1391 Indx
:= Indx
+ Item
'Length;
1394 Result
.Data
(Indx
.. Max_Length
) :=
1395 Item
(Item
'First .. Item
'First + Max_Length
- Indx
);
1397 when Strings
.Left
=>
1400 while Indx
- Item
'Length >= 1 loop
1401 Result
.Data
(Indx
- (Item
'Length - 1) .. Indx
) := Item
;
1402 Indx
:= Indx
- Item
'Length;
1405 Result
.Data
(1 .. Indx
) :=
1406 Item
(Item
'Last - Indx
+ 1 .. Item
'Last);
1408 when Strings
.Error
=>
1409 raise Ada
.Strings
.Length_Error
;
1417 (Count
: in Natural;
1418 Item
: in Bounded_String
;
1419 Drop
: in Strings
.Truncation
:= Strings
.Error
)
1420 return Bounded_String
1423 return Replicate
(Count
, Item
.Data
(1 .. Item
.Length
), Drop
);
1431 (Source
: Bounded_String
;
1437 -- Note: test of High > Length is in accordance with AI95-00128
1439 if Low
> Source
.Length
+ 1 or else High
> Source
.Length
then
1442 return Source
.Data
(Low
.. High
);
1451 (Source
: in Bounded_String
;
1453 Pad
: in Character := Space
;
1454 Drop
: in Strings
.Truncation
:= Strings
.Error
)
1455 return Bounded_String
1457 Result
: Bounded_String
;
1458 Slen
: constant Natural := Source
.Length
;
1459 Npad
: constant Integer := Count
- Slen
;
1463 Result
.Length
:= Count
;
1464 Result
.Data
(1 .. Count
) :=
1465 Source
.Data
(Slen
- (Count
- 1) .. Slen
);
1467 elsif Count
<= Max_Length
then
1468 Result
.Length
:= Count
;
1469 Result
.Data
(1 .. Npad
) := (others => Pad
);
1470 Result
.Data
(Npad
+ 1 .. Count
) := Source
.Data
(1 .. Slen
);
1473 Result
.Length
:= Max_Length
;
1476 when Strings
.Right
=>
1477 if Npad
>= Max_Length
then
1478 Result
.Data
:= (others => Pad
);
1481 Result
.Data
(1 .. Npad
) := (others => Pad
);
1482 Result
.Data
(Npad
+ 1 .. Max_Length
) :=
1483 Source
.Data
(1 .. Max_Length
- Npad
);
1486 when Strings
.Left
=>
1487 Result
.Data
(1 .. Max_Length
- Slen
) := (others => Pad
);
1488 Result
.Data
(Max_Length
- Slen
+ 1 .. Max_Length
) :=
1489 Source
.Data
(1 .. Slen
);
1491 when Strings
.Error
=>
1492 raise Ada
.Strings
.Length_Error
;
1500 (Source
: in out Bounded_String
;
1502 Pad
: in Character := Space
;
1503 Drop
: in Truncation
:= Error
)
1505 Slen
: constant Natural := Source
.Length
;
1506 Npad
: constant Integer := Count
- Slen
;
1507 Temp
: String (1 .. Max_Length
) := Source
.Data
;
1511 Source
.Length
:= Count
;
1512 Source
.Data
(1 .. Count
) :=
1513 Temp
(Slen
- (Count
- 1) .. Slen
);
1515 elsif Count
<= Max_Length
then
1516 Source
.Length
:= Count
;
1517 Source
.Data
(1 .. Npad
) := (others => Pad
);
1518 Source
.Data
(Npad
+ 1 .. Count
) := Temp
(1 .. Slen
);
1521 Source
.Length
:= Max_Length
;
1524 when Strings
.Right
=>
1525 if Npad
>= Max_Length
then
1526 Source
.Data
:= (others => Pad
);
1529 Source
.Data
(1 .. Npad
) := (others => Pad
);
1530 Source
.Data
(Npad
+ 1 .. Max_Length
) :=
1531 Temp
(1 .. Max_Length
- Npad
);
1534 when Strings
.Left
=>
1535 for J
in 1 .. Max_Length
- Slen
loop
1536 Source
.Data
(J
) := Pad
;
1539 Source
.Data
(Max_Length
- Slen
+ 1 .. Max_Length
) :=
1542 when Strings
.Error
=>
1543 raise Ada
.Strings
.Length_Error
;
1549 -----------------------
1550 -- To_Bounded_String --
1551 -----------------------
1553 function To_Bounded_String
1554 (Source
: in String;
1555 Drop
: in Strings
.Truncation
:= Strings
.Error
)
1556 return Bounded_String
1558 Slen
: constant Natural := Source
'Length;
1559 Result
: Bounded_String
;
1562 if Slen
<= Max_Length
then
1563 Result
.Length
:= Slen
;
1564 Result
.Data
(1 .. Slen
) := Source
;
1568 when Strings
.Right
=>
1569 Result
.Length
:= Max_Length
;
1570 Result
.Data
(1 .. Max_Length
) :=
1571 Source
(Source
'First .. Source
'First - 1 + Max_Length
);
1573 when Strings
.Left
=>
1574 Result
.Length
:= Max_Length
;
1575 Result
.Data
(1 .. Max_Length
) :=
1576 Source
(Source
'Last - (Max_Length
- 1) .. Source
'Last);
1578 when Strings
.Error
=>
1579 raise Ada
.Strings
.Length_Error
;
1584 end To_Bounded_String
;
1590 function To_String
(Source
: in Bounded_String
) return String is
1592 return Source
.Data
(1 .. Source
.Length
);
1600 (Source
: in Bounded_String
;
1601 Mapping
: in Maps
.Character_Mapping
)
1602 return Bounded_String
1604 Result
: Bounded_String
;
1607 Result
.Length
:= Source
.Length
;
1609 for J
in 1 .. Source
.Length
loop
1610 Result
.Data
(J
) := Value
(Mapping
, Source
.Data
(J
));
1617 (Source
: in out Bounded_String
;
1618 Mapping
: in Maps
.Character_Mapping
)
1621 for J
in 1 .. Source
.Length
loop
1622 Source
.Data
(J
) := Value
(Mapping
, Source
.Data
(J
));
1627 (Source
: in Bounded_String
;
1628 Mapping
: in Maps
.Character_Mapping_Function
)
1629 return Bounded_String
1631 Result
: Bounded_String
;
1634 Result
.Length
:= Source
.Length
;
1636 for J
in 1 .. Source
.Length
loop
1637 Result
.Data
(J
) := Mapping
.all (Source
.Data
(J
));
1644 (Source
: in out Bounded_String
;
1645 Mapping
: in Maps
.Character_Mapping_Function
)
1648 for J
in 1 .. Source
.Length
loop
1649 Source
.Data
(J
) := Mapping
.all (Source
.Data
(J
));
1657 function Trim
(Source
: in Bounded_String
; Side
: in Trim_End
)
1658 return Bounded_String
1660 Result
: Bounded_String
;
1661 Last
: Natural := Source
.Length
;
1662 First
: Positive := 1;
1665 if Side
= Left
or else Side
= Both
then
1666 while First
<= Last
and then Source
.Data
(First
) = ' ' loop
1671 if Side
= Right
or else Side
= Both
then
1672 while Last
>= First
and then Source
.Data
(Last
) = ' ' loop
1677 Result
.Length
:= Last
- First
+ 1;
1678 Result
.Data
(1 .. Result
.Length
) := Source
.Data
(First
.. Last
);
1684 (Source
: in out Bounded_String
;
1687 Last
: Length_Range
:= Source
.Length
;
1688 First
: Positive := 1;
1689 Temp
: String (1 .. Max_Length
);
1692 Temp
(1 .. Last
) := Source
.Data
(1 .. Last
);
1694 if Side
= Left
or else Side
= Both
then
1695 while First
<= Last
and then Temp
(First
) = ' ' loop
1700 if Side
= Right
or else Side
= Both
then
1701 while Last
>= First
and then Temp
(Last
) = ' ' loop
1706 Source
:= Null_Bounded_String
;
1707 Source
.Length
:= Last
- First
+ 1;
1708 Source
.Data
(1 .. Source
.Length
) := Temp
(First
.. Last
);
1713 (Source
: in Bounded_String
;
1714 Left
: in Maps
.Character_Set
;
1715 Right
: in Maps
.Character_Set
)
1716 return Bounded_String
1718 Result
: Bounded_String
;
1721 for First
in 1 .. Source
.Length
loop
1722 if not Is_In
(Source
.Data
(First
), Left
) then
1723 for Last
in reverse First
.. Source
.Length
loop
1724 if not Is_In
(Source
.Data
(Last
), Right
) then
1725 Result
.Length
:= Last
- First
+ 1;
1726 Result
.Data
(1 .. Result
.Length
) :=
1727 Source
.Data
(First
.. Last
);
1739 (Source
: in out Bounded_String
;
1740 Left
: in Maps
.Character_Set
;
1741 Right
: in Maps
.Character_Set
)
1744 for First
in 1 .. Source
.Length
loop
1745 if not Is_In
(Source
.Data
(First
), Left
) then
1746 for Last
in reverse First
.. Source
.Length
loop
1747 if not Is_In
(Source
.Data
(Last
), Right
) then
1749 Source
.Length
:= Last
;
1752 Source
.Length
:= Last
- First
+ 1;
1753 Source
.Data
(1 .. Source
.Length
) :=
1754 Source
.Data
(First
.. Last
);
1756 for J
in Source
.Length
+ 1 .. Max_Length
loop
1757 Source
.Data
(J
) := ASCII
.NUL
;
1773 end Generic_Bounded_Length
;
1775 end Ada
.Strings
.Bounded
;