111
|
1 ------------------------------------------------------------------------------
|
|
2 -- --
|
|
3 -- GNAT RUN-TIME COMPONENTS --
|
|
4 -- --
|
|
5 -- A D A . S T R I N G S . W I D E _ U N B O U N D E D --
|
|
6 -- --
|
|
7 -- B o d y --
|
|
8 -- --
|
131
|
9 -- Copyright (C) 1992-2018, Free Software Foundation, Inc. --
|
111
|
10 -- --
|
|
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 3, 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. --
|
|
17 -- --
|
|
18 -- As a special exception under Section 7 of GPL version 3, you are granted --
|
|
19 -- additional permissions described in the GCC Runtime Library Exception, --
|
|
20 -- version 3.1, as published by the Free Software Foundation. --
|
|
21 -- --
|
|
22 -- You should have received a copy of the GNU General Public License and --
|
|
23 -- a copy of the GCC Runtime Library Exception along with this program; --
|
|
24 -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
|
|
25 -- <http://www.gnu.org/licenses/>. --
|
|
26 -- --
|
|
27 -- GNAT was originally developed by the GNAT team at New York University. --
|
|
28 -- Extensive contributions were provided by Ada Core Technologies Inc. --
|
|
29 -- --
|
|
30 ------------------------------------------------------------------------------
|
|
31
|
|
32 with Ada.Strings.Wide_Fixed;
|
|
33 with Ada.Strings.Wide_Search;
|
|
34 with Ada.Unchecked_Deallocation;
|
|
35
|
|
36 package body Ada.Strings.Wide_Unbounded is
|
|
37
|
|
38 ---------
|
|
39 -- "&" --
|
|
40 ---------
|
|
41
|
|
42 function "&"
|
|
43 (Left : Unbounded_Wide_String;
|
|
44 Right : Unbounded_Wide_String) return Unbounded_Wide_String
|
|
45 is
|
|
46 L_Length : constant Natural := Left.Last;
|
|
47 R_Length : constant Natural := Right.Last;
|
|
48 Result : Unbounded_Wide_String;
|
|
49
|
|
50 begin
|
|
51 Result.Last := L_Length + R_Length;
|
|
52
|
|
53 Result.Reference := new Wide_String (1 .. Result.Last);
|
|
54
|
|
55 Result.Reference (1 .. L_Length) :=
|
|
56 Left.Reference (1 .. Left.Last);
|
|
57 Result.Reference (L_Length + 1 .. Result.Last) :=
|
|
58 Right.Reference (1 .. Right.Last);
|
|
59
|
|
60 return Result;
|
|
61 end "&";
|
|
62
|
|
63 function "&"
|
|
64 (Left : Unbounded_Wide_String;
|
|
65 Right : Wide_String) return Unbounded_Wide_String
|
|
66 is
|
|
67 L_Length : constant Natural := Left.Last;
|
|
68 Result : Unbounded_Wide_String;
|
|
69
|
|
70 begin
|
|
71 Result.Last := L_Length + Right'Length;
|
|
72
|
|
73 Result.Reference := new Wide_String (1 .. Result.Last);
|
|
74
|
|
75 Result.Reference (1 .. L_Length) := Left.Reference (1 .. Left.Last);
|
|
76 Result.Reference (L_Length + 1 .. Result.Last) := Right;
|
|
77
|
|
78 return Result;
|
|
79 end "&";
|
|
80
|
|
81 function "&"
|
|
82 (Left : Wide_String;
|
|
83 Right : Unbounded_Wide_String) return Unbounded_Wide_String
|
|
84 is
|
|
85 R_Length : constant Natural := Right.Last;
|
|
86 Result : Unbounded_Wide_String;
|
|
87
|
|
88 begin
|
|
89 Result.Last := Left'Length + R_Length;
|
|
90
|
|
91 Result.Reference := new Wide_String (1 .. Result.Last);
|
|
92
|
|
93 Result.Reference (1 .. Left'Length) := Left;
|
|
94 Result.Reference (Left'Length + 1 .. Result.Last) :=
|
|
95 Right.Reference (1 .. Right.Last);
|
|
96
|
|
97 return Result;
|
|
98 end "&";
|
|
99
|
|
100 function "&"
|
|
101 (Left : Unbounded_Wide_String;
|
|
102 Right : Wide_Character) return Unbounded_Wide_String
|
|
103 is
|
|
104 Result : Unbounded_Wide_String;
|
|
105
|
|
106 begin
|
|
107 Result.Last := Left.Last + 1;
|
|
108
|
|
109 Result.Reference := new Wide_String (1 .. Result.Last);
|
|
110
|
|
111 Result.Reference (1 .. Result.Last - 1) :=
|
|
112 Left.Reference (1 .. Left.Last);
|
|
113 Result.Reference (Result.Last) := Right;
|
|
114
|
|
115 return Result;
|
|
116 end "&";
|
|
117
|
|
118 function "&"
|
|
119 (Left : Wide_Character;
|
|
120 Right : Unbounded_Wide_String) return Unbounded_Wide_String
|
|
121 is
|
|
122 Result : Unbounded_Wide_String;
|
|
123
|
|
124 begin
|
|
125 Result.Last := Right.Last + 1;
|
|
126
|
|
127 Result.Reference := new Wide_String (1 .. Result.Last);
|
|
128 Result.Reference (1) := Left;
|
|
129 Result.Reference (2 .. Result.Last) :=
|
|
130 Right.Reference (1 .. Right.Last);
|
|
131 return Result;
|
|
132 end "&";
|
|
133
|
|
134 ---------
|
|
135 -- "*" --
|
|
136 ---------
|
|
137
|
|
138 function "*"
|
|
139 (Left : Natural;
|
|
140 Right : Wide_Character) return Unbounded_Wide_String
|
|
141 is
|
|
142 Result : Unbounded_Wide_String;
|
|
143
|
|
144 begin
|
|
145 Result.Last := Left;
|
|
146
|
|
147 Result.Reference := new Wide_String (1 .. Left);
|
|
148 for J in Result.Reference'Range loop
|
|
149 Result.Reference (J) := Right;
|
|
150 end loop;
|
|
151
|
|
152 return Result;
|
|
153 end "*";
|
|
154
|
|
155 function "*"
|
|
156 (Left : Natural;
|
|
157 Right : Wide_String) return Unbounded_Wide_String
|
|
158 is
|
|
159 Len : constant Natural := Right'Length;
|
|
160 K : Positive;
|
|
161 Result : Unbounded_Wide_String;
|
|
162
|
|
163 begin
|
|
164 Result.Last := Left * Len;
|
|
165
|
|
166 Result.Reference := new Wide_String (1 .. Result.Last);
|
|
167
|
|
168 K := 1;
|
|
169 for J in 1 .. Left loop
|
|
170 Result.Reference (K .. K + Len - 1) := Right;
|
|
171 K := K + Len;
|
|
172 end loop;
|
|
173
|
|
174 return Result;
|
|
175 end "*";
|
|
176
|
|
177 function "*"
|
|
178 (Left : Natural;
|
|
179 Right : Unbounded_Wide_String) return Unbounded_Wide_String
|
|
180 is
|
|
181 Len : constant Natural := Right.Last;
|
|
182 K : Positive;
|
|
183 Result : Unbounded_Wide_String;
|
|
184
|
|
185 begin
|
|
186 Result.Last := Left * Len;
|
|
187
|
|
188 Result.Reference := new Wide_String (1 .. Result.Last);
|
|
189
|
|
190 K := 1;
|
|
191 for J in 1 .. Left loop
|
|
192 Result.Reference (K .. K + Len - 1) :=
|
|
193 Right.Reference (1 .. Right.Last);
|
|
194 K := K + Len;
|
|
195 end loop;
|
|
196
|
|
197 return Result;
|
|
198 end "*";
|
|
199
|
|
200 ---------
|
|
201 -- "<" --
|
|
202 ---------
|
|
203
|
|
204 function "<"
|
|
205 (Left : Unbounded_Wide_String;
|
|
206 Right : Unbounded_Wide_String) return Boolean
|
|
207 is
|
|
208 begin
|
|
209 return
|
|
210 Left.Reference (1 .. Left.Last) < Right.Reference (1 .. Right.Last);
|
|
211 end "<";
|
|
212
|
|
213 function "<"
|
|
214 (Left : Unbounded_Wide_String;
|
|
215 Right : Wide_String) return Boolean
|
|
216 is
|
|
217 begin
|
|
218 return Left.Reference (1 .. Left.Last) < Right;
|
|
219 end "<";
|
|
220
|
|
221 function "<"
|
|
222 (Left : Wide_String;
|
|
223 Right : Unbounded_Wide_String) return Boolean
|
|
224 is
|
|
225 begin
|
|
226 return Left < Right.Reference (1 .. Right.Last);
|
|
227 end "<";
|
|
228
|
|
229 ----------
|
|
230 -- "<=" --
|
|
231 ----------
|
|
232
|
|
233 function "<="
|
|
234 (Left : Unbounded_Wide_String;
|
|
235 Right : Unbounded_Wide_String) return Boolean
|
|
236 is
|
|
237 begin
|
|
238 return
|
|
239 Left.Reference (1 .. Left.Last) <= Right.Reference (1 .. Right.Last);
|
|
240 end "<=";
|
|
241
|
|
242 function "<="
|
|
243 (Left : Unbounded_Wide_String;
|
|
244 Right : Wide_String) return Boolean
|
|
245 is
|
|
246 begin
|
|
247 return Left.Reference (1 .. Left.Last) <= Right;
|
|
248 end "<=";
|
|
249
|
|
250 function "<="
|
|
251 (Left : Wide_String;
|
|
252 Right : Unbounded_Wide_String) return Boolean
|
|
253 is
|
|
254 begin
|
|
255 return Left <= Right.Reference (1 .. Right.Last);
|
|
256 end "<=";
|
|
257
|
|
258 ---------
|
|
259 -- "=" --
|
|
260 ---------
|
|
261
|
|
262 function "="
|
|
263 (Left : Unbounded_Wide_String;
|
|
264 Right : Unbounded_Wide_String) return Boolean
|
|
265 is
|
|
266 begin
|
|
267 return
|
|
268 Left.Reference (1 .. Left.Last) = Right.Reference (1 .. Right.Last);
|
|
269 end "=";
|
|
270
|
|
271 function "="
|
|
272 (Left : Unbounded_Wide_String;
|
|
273 Right : Wide_String) return Boolean
|
|
274 is
|
|
275 begin
|
|
276 return Left.Reference (1 .. Left.Last) = Right;
|
|
277 end "=";
|
|
278
|
|
279 function "="
|
|
280 (Left : Wide_String;
|
|
281 Right : Unbounded_Wide_String) return Boolean
|
|
282 is
|
|
283 begin
|
|
284 return Left = Right.Reference (1 .. Right.Last);
|
|
285 end "=";
|
|
286
|
|
287 ---------
|
|
288 -- ">" --
|
|
289 ---------
|
|
290
|
|
291 function ">"
|
|
292 (Left : Unbounded_Wide_String;
|
|
293 Right : Unbounded_Wide_String) return Boolean
|
|
294 is
|
|
295 begin
|
|
296 return
|
|
297 Left.Reference (1 .. Left.Last) > Right.Reference (1 .. Right.Last);
|
|
298 end ">";
|
|
299
|
|
300 function ">"
|
|
301 (Left : Unbounded_Wide_String;
|
|
302 Right : Wide_String) return Boolean
|
|
303 is
|
|
304 begin
|
|
305 return Left.Reference (1 .. Left.Last) > Right;
|
|
306 end ">";
|
|
307
|
|
308 function ">"
|
|
309 (Left : Wide_String;
|
|
310 Right : Unbounded_Wide_String) return Boolean
|
|
311 is
|
|
312 begin
|
|
313 return Left > Right.Reference (1 .. Right.Last);
|
|
314 end ">";
|
|
315
|
|
316 ----------
|
|
317 -- ">=" --
|
|
318 ----------
|
|
319
|
|
320 function ">="
|
|
321 (Left : Unbounded_Wide_String;
|
|
322 Right : Unbounded_Wide_String) return Boolean
|
|
323 is
|
|
324 begin
|
|
325 return
|
|
326 Left.Reference (1 .. Left.Last) >= Right.Reference (1 .. Right.Last);
|
|
327 end ">=";
|
|
328
|
|
329 function ">="
|
|
330 (Left : Unbounded_Wide_String;
|
|
331 Right : Wide_String) return Boolean
|
|
332 is
|
|
333 begin
|
|
334 return Left.Reference (1 .. Left.Last) >= Right;
|
|
335 end ">=";
|
|
336
|
|
337 function ">="
|
|
338 (Left : Wide_String;
|
|
339 Right : Unbounded_Wide_String) return Boolean
|
|
340 is
|
|
341 begin
|
|
342 return Left >= Right.Reference (1 .. Right.Last);
|
|
343 end ">=";
|
|
344
|
|
345 ------------
|
|
346 -- Adjust --
|
|
347 ------------
|
|
348
|
|
349 procedure Adjust (Object : in out Unbounded_Wide_String) is
|
|
350 begin
|
|
351 -- Copy string, except we do not copy the statically allocated null
|
|
352 -- string, since it can never be deallocated. Note that we do not copy
|
|
353 -- extra string room here to avoid dragging unused allocated memory.
|
|
354
|
|
355 if Object.Reference /= Null_Wide_String'Access then
|
|
356 Object.Reference :=
|
|
357 new Wide_String'(Object.Reference (1 .. Object.Last));
|
|
358 end if;
|
|
359 end Adjust;
|
|
360
|
|
361 ------------
|
|
362 -- Append --
|
|
363 ------------
|
|
364
|
|
365 procedure Append
|
|
366 (Source : in out Unbounded_Wide_String;
|
|
367 New_Item : Unbounded_Wide_String)
|
|
368 is
|
|
369 begin
|
|
370 Realloc_For_Chunk (Source, New_Item.Last);
|
|
371 Source.Reference (Source.Last + 1 .. Source.Last + New_Item.Last) :=
|
|
372 New_Item.Reference (1 .. New_Item.Last);
|
|
373 Source.Last := Source.Last + New_Item.Last;
|
|
374 end Append;
|
|
375
|
|
376 procedure Append
|
|
377 (Source : in out Unbounded_Wide_String;
|
|
378 New_Item : Wide_String)
|
|
379 is
|
|
380 begin
|
|
381 Realloc_For_Chunk (Source, New_Item'Length);
|
|
382 Source.Reference (Source.Last + 1 .. Source.Last + New_Item'Length) :=
|
|
383 New_Item;
|
|
384 Source.Last := Source.Last + New_Item'Length;
|
|
385 end Append;
|
|
386
|
|
387 procedure Append
|
|
388 (Source : in out Unbounded_Wide_String;
|
|
389 New_Item : Wide_Character)
|
|
390 is
|
|
391 begin
|
|
392 Realloc_For_Chunk (Source, 1);
|
|
393 Source.Reference (Source.Last + 1) := New_Item;
|
|
394 Source.Last := Source.Last + 1;
|
|
395 end Append;
|
|
396
|
|
397 -----------
|
|
398 -- Count --
|
|
399 -----------
|
|
400
|
|
401 function Count
|
|
402 (Source : Unbounded_Wide_String;
|
|
403 Pattern : Wide_String;
|
|
404 Mapping : Wide_Maps.Wide_Character_Mapping := Wide_Maps.Identity)
|
|
405 return Natural
|
|
406 is
|
|
407 begin
|
|
408 return
|
|
409 Wide_Search.Count
|
|
410 (Source.Reference (1 .. Source.Last), Pattern, Mapping);
|
|
411 end Count;
|
|
412
|
|
413 function Count
|
|
414 (Source : Unbounded_Wide_String;
|
|
415 Pattern : Wide_String;
|
|
416 Mapping : Wide_Maps.Wide_Character_Mapping_Function) return Natural
|
|
417 is
|
|
418 begin
|
|
419 return
|
|
420 Wide_Search.Count
|
|
421 (Source.Reference (1 .. Source.Last), Pattern, Mapping);
|
|
422 end Count;
|
|
423
|
|
424 function Count
|
|
425 (Source : Unbounded_Wide_String;
|
|
426 Set : Wide_Maps.Wide_Character_Set) return Natural
|
|
427 is
|
|
428 begin
|
|
429 return
|
|
430 Wide_Search.Count
|
|
431 (Source.Reference (1 .. Source.Last), Set);
|
|
432 end Count;
|
|
433
|
|
434 ------------
|
|
435 -- Delete --
|
|
436 ------------
|
|
437
|
|
438 function Delete
|
|
439 (Source : Unbounded_Wide_String;
|
|
440 From : Positive;
|
|
441 Through : Natural) return Unbounded_Wide_String
|
|
442 is
|
|
443 begin
|
|
444 return
|
|
445 To_Unbounded_Wide_String
|
|
446 (Wide_Fixed.Delete
|
|
447 (Source.Reference (1 .. Source.Last), From, Through));
|
|
448 end Delete;
|
|
449
|
|
450 procedure Delete
|
|
451 (Source : in out Unbounded_Wide_String;
|
|
452 From : Positive;
|
|
453 Through : Natural)
|
|
454 is
|
|
455 begin
|
|
456 if From > Through then
|
|
457 null;
|
|
458
|
|
459 elsif From < Source.Reference'First or else Through > Source.Last then
|
|
460 raise Index_Error;
|
|
461
|
|
462 else
|
|
463 declare
|
|
464 Len : constant Natural := Through - From + 1;
|
|
465
|
|
466 begin
|
|
467 Source.Reference (From .. Source.Last - Len) :=
|
|
468 Source.Reference (Through + 1 .. Source.Last);
|
|
469 Source.Last := Source.Last - Len;
|
|
470 end;
|
|
471 end if;
|
|
472 end Delete;
|
|
473
|
|
474 -------------
|
|
475 -- Element --
|
|
476 -------------
|
|
477
|
|
478 function Element
|
|
479 (Source : Unbounded_Wide_String;
|
|
480 Index : Positive) return Wide_Character
|
|
481 is
|
|
482 begin
|
|
483 if Index <= Source.Last then
|
|
484 return Source.Reference (Index);
|
|
485 else
|
|
486 raise Strings.Index_Error;
|
|
487 end if;
|
|
488 end Element;
|
|
489
|
|
490 --------------
|
|
491 -- Finalize --
|
|
492 --------------
|
|
493
|
|
494 procedure Finalize (Object : in out Unbounded_Wide_String) is
|
|
495 procedure Deallocate is
|
|
496 new Ada.Unchecked_Deallocation (Wide_String, Wide_String_Access);
|
|
497
|
|
498 begin
|
|
499 -- Note: Don't try to free statically allocated null string
|
|
500
|
|
501 if Object.Reference /= Null_Wide_String'Access then
|
|
502 Deallocate (Object.Reference);
|
|
503 Object.Reference := Null_Unbounded_Wide_String.Reference;
|
|
504 Object.Last := 0;
|
|
505 end if;
|
|
506 end Finalize;
|
|
507
|
|
508 ----------------
|
|
509 -- Find_Token --
|
|
510 ----------------
|
|
511
|
|
512 procedure Find_Token
|
|
513 (Source : Unbounded_Wide_String;
|
|
514 Set : Wide_Maps.Wide_Character_Set;
|
|
515 From : Positive;
|
|
516 Test : Strings.Membership;
|
|
517 First : out Positive;
|
|
518 Last : out Natural)
|
|
519 is
|
|
520 begin
|
|
521 Wide_Search.Find_Token
|
|
522 (Source.Reference (From .. Source.Last), Set, Test, First, Last);
|
|
523 end Find_Token;
|
|
524
|
|
525 procedure Find_Token
|
|
526 (Source : Unbounded_Wide_String;
|
|
527 Set : Wide_Maps.Wide_Character_Set;
|
|
528 Test : Strings.Membership;
|
|
529 First : out Positive;
|
|
530 Last : out Natural)
|
|
531 is
|
|
532 begin
|
|
533 Wide_Search.Find_Token
|
|
534 (Source.Reference (1 .. Source.Last), Set, Test, First, Last);
|
|
535 end Find_Token;
|
|
536
|
|
537 ----------
|
|
538 -- Free --
|
|
539 ----------
|
|
540
|
|
541 procedure Free (X : in out Wide_String_Access) is
|
|
542 procedure Deallocate is
|
|
543 new Ada.Unchecked_Deallocation (Wide_String, Wide_String_Access);
|
|
544
|
|
545 begin
|
|
546 -- Note: Do not try to free statically allocated null string
|
|
547
|
|
548 if X /= Null_Unbounded_Wide_String.Reference then
|
|
549 Deallocate (X);
|
|
550 end if;
|
|
551 end Free;
|
|
552
|
|
553 ----------
|
|
554 -- Head --
|
|
555 ----------
|
|
556
|
|
557 function Head
|
|
558 (Source : Unbounded_Wide_String;
|
|
559 Count : Natural;
|
|
560 Pad : Wide_Character := Wide_Space) return Unbounded_Wide_String
|
|
561 is
|
|
562 begin
|
|
563 return To_Unbounded_Wide_String
|
|
564 (Wide_Fixed.Head (Source.Reference (1 .. Source.Last), Count, Pad));
|
|
565 end Head;
|
|
566
|
|
567 procedure Head
|
|
568 (Source : in out Unbounded_Wide_String;
|
|
569 Count : Natural;
|
|
570 Pad : Wide_Character := Wide_Space)
|
|
571 is
|
|
572 Old : Wide_String_Access := Source.Reference;
|
|
573 begin
|
|
574 Source.Reference :=
|
|
575 new Wide_String'
|
|
576 (Wide_Fixed.Head (Source.Reference (1 .. Source.Last), Count, Pad));
|
|
577 Source.Last := Source.Reference'Length;
|
|
578 Free (Old);
|
|
579 end Head;
|
|
580
|
|
581 -----------
|
|
582 -- Index --
|
|
583 -----------
|
|
584
|
|
585 function Index
|
|
586 (Source : Unbounded_Wide_String;
|
|
587 Pattern : Wide_String;
|
|
588 Going : Strings.Direction := Strings.Forward;
|
|
589 Mapping : Wide_Maps.Wide_Character_Mapping := Wide_Maps.Identity)
|
|
590 return Natural
|
|
591 is
|
|
592 begin
|
|
593 return
|
|
594 Wide_Search.Index
|
|
595 (Source.Reference (1 .. Source.Last), Pattern, Going, Mapping);
|
|
596 end Index;
|
|
597
|
|
598 function Index
|
|
599 (Source : Unbounded_Wide_String;
|
|
600 Pattern : Wide_String;
|
|
601 Going : Direction := Forward;
|
|
602 Mapping : Wide_Maps.Wide_Character_Mapping_Function) return Natural
|
|
603 is
|
|
604 begin
|
|
605 return
|
|
606 Wide_Search.Index
|
|
607 (Source.Reference (1 .. Source.Last), Pattern, Going, Mapping);
|
|
608 end Index;
|
|
609
|
|
610 function Index
|
|
611 (Source : Unbounded_Wide_String;
|
|
612 Set : Wide_Maps.Wide_Character_Set;
|
|
613 Test : Strings.Membership := Strings.Inside;
|
|
614 Going : Strings.Direction := Strings.Forward) return Natural
|
|
615 is
|
|
616 begin
|
|
617 return Wide_Search.Index
|
|
618 (Source.Reference (1 .. Source.Last), Set, Test, Going);
|
|
619 end Index;
|
|
620
|
|
621 function Index
|
|
622 (Source : Unbounded_Wide_String;
|
|
623 Pattern : Wide_String;
|
|
624 From : Positive;
|
|
625 Going : Direction := Forward;
|
|
626 Mapping : Wide_Maps.Wide_Character_Mapping := Wide_Maps.Identity)
|
|
627 return Natural
|
|
628 is
|
|
629 begin
|
|
630 return
|
|
631 Wide_Search.Index
|
|
632 (Source.Reference (1 .. Source.Last), Pattern, From, Going, Mapping);
|
|
633 end Index;
|
|
634
|
|
635 function Index
|
|
636 (Source : Unbounded_Wide_String;
|
|
637 Pattern : Wide_String;
|
|
638 From : Positive;
|
|
639 Going : Direction := Forward;
|
|
640 Mapping : Wide_Maps.Wide_Character_Mapping_Function) return Natural
|
|
641 is
|
|
642 begin
|
|
643 return
|
|
644 Wide_Search.Index
|
|
645 (Source.Reference (1 .. Source.Last), Pattern, From, Going, Mapping);
|
|
646 end Index;
|
|
647
|
|
648 function Index
|
|
649 (Source : Unbounded_Wide_String;
|
|
650 Set : Wide_Maps.Wide_Character_Set;
|
|
651 From : Positive;
|
|
652 Test : Membership := Inside;
|
|
653 Going : Direction := Forward) return Natural
|
|
654 is
|
|
655 begin
|
|
656 return
|
|
657 Wide_Search.Index
|
|
658 (Source.Reference (1 .. Source.Last), Set, From, Test, Going);
|
|
659 end Index;
|
|
660
|
|
661 function Index_Non_Blank
|
|
662 (Source : Unbounded_Wide_String;
|
|
663 Going : Strings.Direction := Strings.Forward) return Natural
|
|
664 is
|
|
665 begin
|
|
666 return
|
|
667 Wide_Search.Index_Non_Blank
|
|
668 (Source.Reference (1 .. Source.Last), Going);
|
|
669 end Index_Non_Blank;
|
|
670
|
|
671 function Index_Non_Blank
|
|
672 (Source : Unbounded_Wide_String;
|
|
673 From : Positive;
|
|
674 Going : Direction := Forward) return Natural
|
|
675 is
|
|
676 begin
|
|
677 return
|
|
678 Wide_Search.Index_Non_Blank
|
|
679 (Source.Reference (1 .. Source.Last), From, Going);
|
|
680 end Index_Non_Blank;
|
|
681
|
|
682 ----------------
|
|
683 -- Initialize --
|
|
684 ----------------
|
|
685
|
|
686 procedure Initialize (Object : in out Unbounded_Wide_String) is
|
|
687 begin
|
|
688 Object.Reference := Null_Unbounded_Wide_String.Reference;
|
|
689 Object.Last := 0;
|
|
690 end Initialize;
|
|
691
|
|
692 ------------
|
|
693 -- Insert --
|
|
694 ------------
|
|
695
|
|
696 function Insert
|
|
697 (Source : Unbounded_Wide_String;
|
|
698 Before : Positive;
|
|
699 New_Item : Wide_String) return Unbounded_Wide_String
|
|
700 is
|
|
701 begin
|
|
702 return
|
|
703 To_Unbounded_Wide_String
|
|
704 (Wide_Fixed.Insert
|
|
705 (Source.Reference (1 .. Source.Last), Before, New_Item));
|
|
706 end Insert;
|
|
707
|
|
708 procedure Insert
|
|
709 (Source : in out Unbounded_Wide_String;
|
|
710 Before : Positive;
|
|
711 New_Item : Wide_String)
|
|
712 is
|
|
713 begin
|
|
714 if Before not in Source.Reference'First .. Source.Last + 1 then
|
|
715 raise Index_Error;
|
|
716 end if;
|
|
717
|
|
718 Realloc_For_Chunk (Source, New_Item'Length);
|
|
719
|
|
720 Source.Reference
|
|
721 (Before + New_Item'Length .. Source.Last + New_Item'Length) :=
|
|
722 Source.Reference (Before .. Source.Last);
|
|
723
|
|
724 Source.Reference (Before .. Before + New_Item'Length - 1) := New_Item;
|
|
725 Source.Last := Source.Last + New_Item'Length;
|
|
726 end Insert;
|
|
727
|
|
728 ------------
|
|
729 -- Length --
|
|
730 ------------
|
|
731
|
|
732 function Length (Source : Unbounded_Wide_String) return Natural is
|
|
733 begin
|
|
734 return Source.Last;
|
|
735 end Length;
|
|
736
|
|
737 ---------------
|
|
738 -- Overwrite --
|
|
739 ---------------
|
|
740
|
|
741 function Overwrite
|
|
742 (Source : Unbounded_Wide_String;
|
|
743 Position : Positive;
|
|
744 New_Item : Wide_String) return Unbounded_Wide_String
|
|
745 is
|
|
746 begin
|
|
747 return
|
|
748 To_Unbounded_Wide_String
|
|
749 (Wide_Fixed.Overwrite
|
|
750 (Source.Reference (1 .. Source.Last), Position, New_Item));
|
|
751 end Overwrite;
|
|
752
|
|
753 procedure Overwrite
|
|
754 (Source : in out Unbounded_Wide_String;
|
|
755 Position : Positive;
|
|
756 New_Item : Wide_String)
|
|
757 is
|
|
758 NL : constant Natural := New_Item'Length;
|
|
759 begin
|
|
760 if Position <= Source.Last - NL + 1 then
|
|
761 Source.Reference (Position .. Position + NL - 1) := New_Item;
|
|
762 else
|
|
763 declare
|
|
764 Old : Wide_String_Access := Source.Reference;
|
|
765 begin
|
|
766 Source.Reference := new Wide_String'
|
|
767 (Wide_Fixed.Overwrite
|
|
768 (Source.Reference (1 .. Source.Last), Position, New_Item));
|
|
769 Source.Last := Source.Reference'Length;
|
|
770 Free (Old);
|
|
771 end;
|
|
772 end if;
|
|
773 end Overwrite;
|
|
774
|
|
775 -----------------------
|
|
776 -- Realloc_For_Chunk --
|
|
777 -----------------------
|
|
778
|
|
779 procedure Realloc_For_Chunk
|
|
780 (Source : in out Unbounded_Wide_String;
|
|
781 Chunk_Size : Natural)
|
|
782 is
|
|
783 Growth_Factor : constant := 32;
|
|
784 -- The growth factor controls how much extra space is allocated when
|
|
785 -- we have to increase the size of an allocated unbounded string. By
|
|
786 -- allocating extra space, we avoid the need to reallocate on every
|
|
787 -- append, particularly important when a string is built up by repeated
|
|
788 -- append operations of small pieces. This is expressed as a factor so
|
|
789 -- 32 means add 1/32 of the length of the string as growth space.
|
|
790
|
|
791 Min_Mul_Alloc : constant := Standard'Maximum_Alignment;
|
|
792 -- Allocation will be done by a multiple of Min_Mul_Alloc This causes
|
|
793 -- no memory loss as most (all?) malloc implementations are obliged to
|
|
794 -- align the returned memory on the maximum alignment as malloc does not
|
|
795 -- know the target alignment.
|
|
796
|
|
797 S_Length : constant Natural := Source.Reference'Length;
|
|
798
|
|
799 begin
|
|
800 if Chunk_Size > S_Length - Source.Last then
|
|
801 declare
|
|
802 New_Size : constant Positive :=
|
|
803 S_Length + Chunk_Size + (S_Length / Growth_Factor);
|
|
804
|
|
805 New_Rounded_Up_Size : constant Positive :=
|
|
806 ((New_Size - 1) / Min_Mul_Alloc + 1) * Min_Mul_Alloc;
|
|
807
|
|
808 Tmp : constant Wide_String_Access :=
|
|
809 new Wide_String (1 .. New_Rounded_Up_Size);
|
|
810
|
|
811 begin
|
|
812 Tmp (1 .. Source.Last) := Source.Reference (1 .. Source.Last);
|
|
813 Free (Source.Reference);
|
|
814 Source.Reference := Tmp;
|
|
815 end;
|
|
816 end if;
|
|
817 end Realloc_For_Chunk;
|
|
818
|
|
819 ---------------------
|
|
820 -- Replace_Element --
|
|
821 ---------------------
|
|
822
|
|
823 procedure Replace_Element
|
|
824 (Source : in out Unbounded_Wide_String;
|
|
825 Index : Positive;
|
|
826 By : Wide_Character)
|
|
827 is
|
|
828 begin
|
|
829 if Index <= Source.Last then
|
|
830 Source.Reference (Index) := By;
|
|
831 else
|
|
832 raise Strings.Index_Error;
|
|
833 end if;
|
|
834 end Replace_Element;
|
|
835
|
|
836 -------------------
|
|
837 -- Replace_Slice --
|
|
838 -------------------
|
|
839
|
|
840 function Replace_Slice
|
|
841 (Source : Unbounded_Wide_String;
|
|
842 Low : Positive;
|
|
843 High : Natural;
|
|
844 By : Wide_String) return Unbounded_Wide_String
|
|
845 is
|
|
846 begin
|
|
847 return To_Unbounded_Wide_String
|
|
848 (Wide_Fixed.Replace_Slice
|
|
849 (Source.Reference (1 .. Source.Last), Low, High, By));
|
|
850 end Replace_Slice;
|
|
851
|
|
852 procedure Replace_Slice
|
|
853 (Source : in out Unbounded_Wide_String;
|
|
854 Low : Positive;
|
|
855 High : Natural;
|
|
856 By : Wide_String)
|
|
857 is
|
|
858 Old : Wide_String_Access := Source.Reference;
|
|
859 begin
|
|
860 Source.Reference := new Wide_String'
|
|
861 (Wide_Fixed.Replace_Slice
|
|
862 (Source.Reference (1 .. Source.Last), Low, High, By));
|
|
863 Source.Last := Source.Reference'Length;
|
|
864 Free (Old);
|
|
865 end Replace_Slice;
|
|
866
|
|
867 -------------------------------
|
|
868 -- Set_Unbounded_Wide_String --
|
|
869 -------------------------------
|
|
870
|
|
871 procedure Set_Unbounded_Wide_String
|
|
872 (Target : out Unbounded_Wide_String;
|
|
873 Source : Wide_String)
|
|
874 is
|
|
875 begin
|
|
876 Target.Last := Source'Length;
|
|
877 Target.Reference := new Wide_String (1 .. Source'Length);
|
|
878 Target.Reference.all := Source;
|
|
879 end Set_Unbounded_Wide_String;
|
|
880
|
|
881 -----------
|
|
882 -- Slice --
|
|
883 -----------
|
|
884
|
|
885 function Slice
|
|
886 (Source : Unbounded_Wide_String;
|
|
887 Low : Positive;
|
|
888 High : Natural) return Wide_String
|
|
889 is
|
|
890 begin
|
|
891 -- Note: test of High > Length is in accordance with AI95-00128
|
|
892
|
|
893 if Low > Source.Last + 1 or else High > Source.Last then
|
|
894 raise Index_Error;
|
|
895 else
|
|
896 return Source.Reference (Low .. High);
|
|
897 end if;
|
|
898 end Slice;
|
|
899
|
|
900 ----------
|
|
901 -- Tail --
|
|
902 ----------
|
|
903
|
|
904 function Tail
|
|
905 (Source : Unbounded_Wide_String;
|
|
906 Count : Natural;
|
|
907 Pad : Wide_Character := Wide_Space) return Unbounded_Wide_String is
|
|
908 begin
|
|
909 return To_Unbounded_Wide_String
|
|
910 (Wide_Fixed.Tail (Source.Reference (1 .. Source.Last), Count, Pad));
|
|
911 end Tail;
|
|
912
|
|
913 procedure Tail
|
|
914 (Source : in out Unbounded_Wide_String;
|
|
915 Count : Natural;
|
|
916 Pad : Wide_Character := Wide_Space)
|
|
917 is
|
|
918 Old : Wide_String_Access := Source.Reference;
|
|
919 begin
|
|
920 Source.Reference := new Wide_String'
|
|
921 (Wide_Fixed.Tail (Source.Reference (1 .. Source.Last), Count, Pad));
|
|
922 Source.Last := Source.Reference'Length;
|
|
923 Free (Old);
|
|
924 end Tail;
|
|
925
|
|
926 ------------------------------
|
|
927 -- To_Unbounded_Wide_String --
|
|
928 ------------------------------
|
|
929
|
|
930 function To_Unbounded_Wide_String
|
|
931 (Source : Wide_String)
|
|
932 return Unbounded_Wide_String
|
|
933 is
|
|
934 Result : Unbounded_Wide_String;
|
|
935 begin
|
|
936 Result.Last := Source'Length;
|
|
937 Result.Reference := new Wide_String (1 .. Source'Length);
|
|
938 Result.Reference.all := Source;
|
|
939 return Result;
|
|
940 end To_Unbounded_Wide_String;
|
|
941
|
|
942 function To_Unbounded_Wide_String
|
|
943 (Length : Natural) return Unbounded_Wide_String
|
|
944 is
|
|
945 Result : Unbounded_Wide_String;
|
|
946 begin
|
|
947 Result.Last := Length;
|
|
948 Result.Reference := new Wide_String (1 .. Length);
|
|
949 return Result;
|
|
950 end To_Unbounded_Wide_String;
|
|
951
|
|
952 -------------------
|
|
953 -- To_Wide_String --
|
|
954 --------------------
|
|
955
|
|
956 function To_Wide_String
|
|
957 (Source : Unbounded_Wide_String)
|
|
958 return Wide_String
|
|
959 is
|
|
960 begin
|
|
961 return Source.Reference (1 .. Source.Last);
|
|
962 end To_Wide_String;
|
|
963
|
|
964 ---------------
|
|
965 -- Translate --
|
|
966 ---------------
|
|
967
|
|
968 function Translate
|
|
969 (Source : Unbounded_Wide_String;
|
|
970 Mapping : Wide_Maps.Wide_Character_Mapping)
|
|
971 return Unbounded_Wide_String
|
|
972 is
|
|
973 begin
|
|
974 return
|
|
975 To_Unbounded_Wide_String
|
|
976 (Wide_Fixed.Translate
|
|
977 (Source.Reference (1 .. Source.Last), Mapping));
|
|
978 end Translate;
|
|
979
|
|
980 procedure Translate
|
|
981 (Source : in out Unbounded_Wide_String;
|
|
982 Mapping : Wide_Maps.Wide_Character_Mapping)
|
|
983 is
|
|
984 begin
|
|
985 Wide_Fixed.Translate (Source.Reference (1 .. Source.Last), Mapping);
|
|
986 end Translate;
|
|
987
|
|
988 function Translate
|
|
989 (Source : Unbounded_Wide_String;
|
|
990 Mapping : Wide_Maps.Wide_Character_Mapping_Function)
|
|
991 return Unbounded_Wide_String
|
|
992 is
|
|
993 begin
|
|
994 return
|
|
995 To_Unbounded_Wide_String
|
|
996 (Wide_Fixed.Translate
|
|
997 (Source.Reference (1 .. Source.Last), Mapping));
|
|
998 end Translate;
|
|
999
|
|
1000 procedure Translate
|
|
1001 (Source : in out Unbounded_Wide_String;
|
|
1002 Mapping : Wide_Maps.Wide_Character_Mapping_Function)
|
|
1003 is
|
|
1004 begin
|
|
1005 Wide_Fixed.Translate (Source.Reference (1 .. Source.Last), Mapping);
|
|
1006 end Translate;
|
|
1007
|
|
1008 ----------
|
|
1009 -- Trim --
|
|
1010 ----------
|
|
1011
|
|
1012 function Trim
|
|
1013 (Source : Unbounded_Wide_String;
|
|
1014 Side : Trim_End) return Unbounded_Wide_String
|
|
1015 is
|
|
1016 begin
|
|
1017 return
|
|
1018 To_Unbounded_Wide_String
|
|
1019 (Wide_Fixed.Trim (Source.Reference (1 .. Source.Last), Side));
|
|
1020 end Trim;
|
|
1021
|
|
1022 procedure Trim
|
|
1023 (Source : in out Unbounded_Wide_String;
|
|
1024 Side : Trim_End)
|
|
1025 is
|
|
1026 Old : Wide_String_Access := Source.Reference;
|
|
1027 begin
|
|
1028 Source.Reference :=
|
|
1029 new Wide_String'
|
|
1030 (Wide_Fixed.Trim (Source.Reference (1 .. Source.Last), Side));
|
|
1031 Source.Last := Source.Reference'Length;
|
|
1032 Free (Old);
|
|
1033 end Trim;
|
|
1034
|
|
1035 function Trim
|
|
1036 (Source : Unbounded_Wide_String;
|
|
1037 Left : Wide_Maps.Wide_Character_Set;
|
|
1038 Right : Wide_Maps.Wide_Character_Set)
|
|
1039 return Unbounded_Wide_String
|
|
1040 is
|
|
1041 begin
|
|
1042 return
|
|
1043 To_Unbounded_Wide_String
|
|
1044 (Wide_Fixed.Trim
|
|
1045 (Source.Reference (1 .. Source.Last), Left, Right));
|
|
1046 end Trim;
|
|
1047
|
|
1048 procedure Trim
|
|
1049 (Source : in out Unbounded_Wide_String;
|
|
1050 Left : Wide_Maps.Wide_Character_Set;
|
|
1051 Right : Wide_Maps.Wide_Character_Set)
|
|
1052 is
|
|
1053 Old : Wide_String_Access := Source.Reference;
|
|
1054 begin
|
|
1055 Source.Reference :=
|
|
1056 new Wide_String'
|
|
1057 (Wide_Fixed.Trim
|
|
1058 (Source.Reference (1 .. Source.Last), Left, Right));
|
|
1059 Source.Last := Source.Reference'Length;
|
|
1060 Free (Old);
|
|
1061 end Trim;
|
|
1062
|
|
1063 ---------------------
|
|
1064 -- Unbounded_Slice --
|
|
1065 ---------------------
|
|
1066
|
|
1067 function Unbounded_Slice
|
|
1068 (Source : Unbounded_Wide_String;
|
|
1069 Low : Positive;
|
|
1070 High : Natural) return Unbounded_Wide_String
|
|
1071 is
|
|
1072 begin
|
|
1073 if Low > Source.Last + 1 or else High > Source.Last then
|
|
1074 raise Index_Error;
|
|
1075 else
|
|
1076 return To_Unbounded_Wide_String (Source.Reference.all (Low .. High));
|
|
1077 end if;
|
|
1078 end Unbounded_Slice;
|
|
1079
|
|
1080 procedure Unbounded_Slice
|
|
1081 (Source : Unbounded_Wide_String;
|
|
1082 Target : out Unbounded_Wide_String;
|
|
1083 Low : Positive;
|
|
1084 High : Natural)
|
|
1085 is
|
|
1086 begin
|
|
1087 if Low > Source.Last + 1 or else High > Source.Last then
|
|
1088 raise Index_Error;
|
|
1089 else
|
|
1090 Target :=
|
|
1091 To_Unbounded_Wide_String (Source.Reference.all (Low .. High));
|
|
1092 end if;
|
|
1093 end Unbounded_Slice;
|
|
1094
|
|
1095 end Ada.Strings.Wide_Unbounded;
|