/[eiffelstudio]/FreeELKS/tags/EiffelSoftware/Eiffel_72/library/kernel/string_8.e
ViewVC logotype

Contents of /FreeELKS/tags/EiffelSoftware/Eiffel_72/library/kernel/string_8.e

Parent Directory Parent Directory | Revision Log Revision Log


Revision 92171 - (show annotations)
Thu Feb 7 20:27:54 2013 UTC (6 years, 10 months ago) by manus_eiffel
File size: 45550 byte(s)
Merged from rev#747:
Added `item' to READABLE_STRING_GENERAL and proper definition in READABLE_STRING_8 descendans. So that it is easier to migrate from compatible to regular mode.

1 note
2 description: "[
3 Sequences of 8-bit characters, accessible through integer indices
4 in a contiguous range.
5 ]"
6 library: "Free implementation of ELKS library"
7 copyright: "Copyright (c) 1986-2010, Eiffel Software and others"
8 license: "Eiffel Forum License v2 (see forum.txt)"
9 date: "$Date$"
10 revision: "$Revision$"
11
12 class
13 STRING_8
14
15 inherit
16 READABLE_STRING_8
17 export
18 {ANY} make, make_empty, make_filled, make_from_c, make_from_string, fill_character
19 redefine
20 item, at, area
21 end
22
23 STRING_GENERAL
24 rename
25 append as append_string_general,
26 prepend as prepend_string_general,
27 same_string as same_string_general,
28 plus as plus_string_general,
29 item as character_32_item
30 undefine
31 copy, is_equal, out
32 redefine
33 append_string_general,
34 prepend_string_general
35 end
36
37 INDEXABLE [CHARACTER_8, INTEGER]
38 undefine
39 copy, is_equal, out
40 redefine
41 prune_all,
42 changeable_comparison_criterion
43 end
44
45 RESIZABLE [CHARACTER_8]
46 undefine
47 copy, is_equal, out
48 redefine
49 changeable_comparison_criterion
50 end
51
52 TO_SPECIAL [CHARACTER_8]
53 undefine
54 copy, is_equal, out, item, at, put, valid_index
55 redefine
56 area
57 end
58
59 MISMATCH_CORRECTOR
60 undefine
61 copy, is_equal, out
62 redefine
63 correct_mismatch
64 end
65
66 create
67 make,
68 make_empty,
69 make_filled,
70 make_from_string,
71 make_from_c,
72 make_from_c_pointer,
73 make_from_cil
74
75 convert
76 to_cil: {SYSTEM_STRING},
77 make_from_cil ({SYSTEM_STRING}),
78 as_string_32: {READABLE_STRING_32, STRING_32}
79
80 feature -- Initialization
81
82 make_from_cil (a_system_string: detachable SYSTEM_STRING)
83 -- Initialize Current with `a_system_string'.
84 local
85 l_count: INTEGER
86 do
87 if a_system_string /= Void then
88 l_count := a_system_string.length
89 end
90 make (l_count)
91 if l_count > 0 and then a_system_string /= Void then
92 set_count (l_count)
93 dotnet_convertor.read_system_string_into (a_system_string, Current)
94 end
95 end
96
97 from_c (c_string: POINTER)
98 -- Reset contents of string from contents of `c_string',
99 -- a string created by some C function.
100 require
101 c_string_exists: c_string /= default_pointer
102 local
103 l_count: INTEGER
104 do
105 c_string_provider.set_shared_from_pointer (c_string)
106 -- Resize string in case it is not big enough
107 l_count := c_string_provider.count
108 resize (l_count + 1)
109 count := l_count
110 internal_hash_code := 0
111 c_string_provider.read_string_into (Current)
112 ensure
113 no_zero_byte: not has ('%/0/')
114 -- characters: for all i in 1..count, item (i) equals
115 -- ASCII character at address c_string + (i - 1)
116 -- correct_count: the ASCII character at address c_string + count
117 -- is NULL
118 end
119
120 from_c_substring (c_string: POINTER; start_pos, end_pos: INTEGER)
121 -- Reset contents of string from substring of `c_string',
122 -- a string created by some C function.
123 require
124 c_string_exists: c_string /= default_pointer
125 start_position_big_enough: start_pos >= 1
126 end_position_big_enough: start_pos <= end_pos + 1
127 local
128 l_count: INTEGER
129 do
130 l_count := end_pos - start_pos + 1
131 c_string_provider.set_shared_from_pointer_and_count (c_string + (start_pos - 1), l_count)
132 -- Resize string in case it is not big enough
133 resize (l_count + 1)
134 count := l_count
135 internal_hash_code := 0
136 c_string_provider.read_substring_into (Current, 1, l_count)
137 ensure
138 valid_count: count = end_pos - start_pos + 1
139 -- characters: for all i in 1..count, item (i) equals
140 -- ASCII character at address c_string + (i - 1)
141 end
142
143 adapt (s: STRING_8): like Current
144 -- Object of a type conforming to the type of `s',
145 -- initialized with attributes from `s'
146 do
147 Result := new_string (0)
148 Result.share (s)
149 ensure
150 adapt_not_void: Result /= Void
151 shared_implementation: Result.shared_with (s)
152 end
153
154 remake (n: INTEGER)
155 -- Allocate space for at least `n' characters.
156 obsolete
157 "Use `make' instead"
158 require
159 non_negative_size: n >= 0
160 do
161 make (n)
162 ensure
163 empty_string: count = 0
164 area_allocated: capacity >= n
165 end
166
167 feature -- Access
168
169 item alias "[]", at alias "@" (i: INTEGER): CHARACTER_8 assign put
170 -- Character at position `i'
171 do
172 Result := area.item (i - 1)
173 end
174
175 area: SPECIAL [CHARACTER_8]
176 -- Storage for characters
177
178 feature -- Status report
179
180 extendible: BOOLEAN = True
181 -- May new items be added? (Answer: yes.)
182
183 prunable: BOOLEAN
184 -- May items be removed? (Answer: yes.)
185 do
186 Result := True
187 end
188
189 changeable_comparison_criterion: BOOLEAN = False
190
191 feature -- Element change
192
193 set (t: like Current; n1, n2: INTEGER)
194 -- Set current string to substring of `t' from indices `n1'
195 -- to `n2', or to empty string if no such substring.
196 require
197 argument_not_void: t /= Void
198 local
199 s: STRING
200 do
201 s := t.substring (n1, n2)
202 area := s.area
203 count := s.count
204 internal_hash_code := 0
205 ensure
206 is_substring: Current ~ (t.substring (n1, n2))
207 end
208
209 subcopy (other: READABLE_STRING_8; start_pos, end_pos, index_pos: INTEGER)
210 -- Copy characters of `other' within bounds `start_pos' and
211 -- `end_pos' to current string starting at index `index_pos'.
212 require
213 other_not_void: other /= Void
214 valid_start_pos: other.valid_index (start_pos)
215 valid_end_pos: other.valid_index (end_pos)
216 valid_bounds: (start_pos <= end_pos) or (start_pos = end_pos + 1)
217 valid_index_pos: valid_index (index_pos)
218 enough_space: (count - index_pos) >= (end_pos - start_pos)
219 local
220 l_other_area, l_area: like area
221 do
222 l_other_area := other.area
223 l_area := area
224 if end_pos >= start_pos then
225 if l_area /= l_other_area then
226 l_area.copy_data (l_other_area, start_pos - 1, index_pos - 1,
227 end_pos - start_pos + 1)
228 else
229 l_area.overlapping_move (start_pos - 1, index_pos - 1,
230 end_pos - start_pos + 1)
231 end
232 internal_hash_code := 0
233 end
234 ensure
235 same_count: count = old count
236 copied: elks_checking implies
237 (Current ~ (old substring (1, index_pos - 1) +
238 old other.substring (start_pos, end_pos) +
239 old substring (index_pos + (end_pos - start_pos + 1), count)))
240 end
241
242 replace_substring (s: READABLE_STRING_8; start_index, end_index: INTEGER)
243 -- Replace characters from `start_index' to `end_index' with `s'.
244 require
245 string_not_void: s /= Void
246 valid_start_index: 1 <= start_index
247 valid_end_index: end_index <= count
248 meaningfull_interval: start_index <= end_index + 1
249 local
250 new_size: INTEGER
251 diff: INTEGER
252 l_area: like area
253 s_count: INTEGER
254 old_count: INTEGER
255 do
256 s_count := s.count
257 old_count := count
258 diff := s_count - (end_index - start_index + 1)
259 new_size := diff + old_count
260 if diff > 0 then
261 -- We need to resize the string.
262 grow (new_size)
263 end
264
265 l_area := area
266 --| We move the end of the string forward (if diff is > 0), backward (if diff < 0),
267 --| and nothing otherwise.
268 if diff /= 0 then
269 l_area.overlapping_move (end_index, end_index + diff, old_count - end_index)
270 end
271 --| Set new count
272 set_count (new_size)
273 --| We copy the substring.
274 l_area.copy_data (s.area, s.area_lower, start_index - 1, s_count)
275 ensure
276 new_count: count = old count + old s.count - end_index + start_index - 1
277 replaced: elks_checking implies
278 (Current ~ (old (substring (1, start_index - 1) +
279 s + substring (end_index + 1, count))))
280 end
281
282 replace_substring_all (original, new: READABLE_STRING_8)
283 -- Replace every occurrence of `original' with `new'.
284 require
285 original_exists: original /= Void
286 new_exists: new /= Void
287 original_not_empty: not original.is_empty
288 local
289 l_first_pos, l_next_pos: INTEGER
290 l_orig_count, l_new_count, l_new_lower, l_count: INTEGER
291 l_area, l_new_area: like area
292 l_offset: INTEGER
293 l_string_searcher: like string_searcher
294 do
295 if not is_empty then
296 l_count := count
297 l_string_searcher := string_searcher
298 l_string_searcher.initialize_deltas (original)
299 l_first_pos := l_string_searcher.substring_index_with_deltas (Current, original, 1, l_count)
300 if l_first_pos > 0 then
301 l_orig_count := original.count
302 l_new_count := new.count
303 if l_orig_count = l_new_count then
304 -- String will not be resized, simply perform character substitution
305 from
306 l_area := area
307 l_new_area := new.area
308 l_new_lower := new.area_lower
309 until
310 l_first_pos = 0
311 loop
312 l_area.copy_data (l_new_area, l_new_lower, l_first_pos - 1, l_new_count)
313 if l_first_pos + l_new_count <= l_count then
314 l_first_pos := l_string_searcher.substring_index_with_deltas (Current, original, l_first_pos + l_new_count, l_count)
315 else
316 l_first_pos := 0
317 end
318 end
319 elseif l_orig_count > l_new_count then
320 -- New string is smaller than previous string, we can optimize
321 -- substitution by only moving block between two occurrences of `orginal'.
322 from
323 l_next_pos := l_string_searcher.substring_index_with_deltas (Current, original, l_first_pos + l_orig_count, l_count)
324 l_area := area
325 l_new_area := new.area
326 l_new_lower := new.area_lower
327 until
328 l_next_pos = 0
329 loop
330 -- Copy new string into Current
331 l_area.copy_data (l_new_area, l_new_lower, l_first_pos - 1 - l_offset, l_new_count)
332 -- Shift characters between `l_first_pos' and `l_next_pos'
333 l_area.overlapping_move (l_first_pos + l_orig_count - 1,
334 l_first_pos + l_new_count - 1 - l_offset, l_next_pos - l_first_pos - l_orig_count)
335 l_first_pos := l_next_pos
336 l_offset := l_offset + (l_orig_count - l_new_count)
337 if l_first_pos + l_new_count <= l_count then
338 l_next_pos := l_string_searcher.substring_index_with_deltas (Current, original, l_first_pos + l_orig_count, l_count)
339 else
340 l_next_pos := 0
341 end
342 end
343 -- Perform final substitution:
344 -- Copy new string into Current
345 l_area.copy_data (l_new_area, l_new_lower, l_first_pos - 1 - l_offset, l_new_count)
346 -- Shift characters between `l_first_pos' and the end of the string
347 l_area.overlapping_move (l_first_pos + l_orig_count - 1,
348 l_first_pos + l_new_count - 1 - l_offset, l_count + 1 - l_first_pos - l_orig_count)
349 -- Perform last substitution
350 l_offset := l_offset + (l_orig_count - l_new_count)
351
352 -- Update `count'
353 set_count (l_count - l_offset)
354 else
355 -- Optimization is harder as we don't know how many times we need to resize
356 -- the string. For now, we do like we did in our previous implementation
357 from
358 until
359 l_first_pos = 0
360 loop
361 replace_substring (new, l_first_pos, l_first_pos + l_orig_count - 1)
362 l_count := count
363 if l_first_pos + l_new_count <= l_count then
364 l_first_pos := l_string_searcher.substring_index_with_deltas (Current, original, l_first_pos + l_new_count, l_count)
365 else
366 l_first_pos := 0
367 end
368 end
369 end
370 internal_hash_code := 0
371 end
372 end
373 end
374
375 replace_blank
376 -- Replace all current characters with blanks.
377 do
378 fill_with (' ')
379 ensure
380 same_size: (count = old count) and (capacity = old capacity)
381 all_blank: elks_checking implies occurrences (' ') = count
382 end
383
384 fill_blank
385 -- Fill with `capacity' blank characters.
386 do
387 fill_character (' ')
388 ensure
389 filled: full
390 same_size: (count = capacity) and (capacity = old capacity)
391 -- all_blank: For every `i' in `count'..`capacity', `item' (`i') = `Blank'
392 end
393
394 fill_with (c: CHARACTER_8)
395 -- Replace every character with `c'.
396 local
397 l_count: INTEGER
398 do
399 l_count := count
400 if l_count /= 0 then
401 area.fill_with (c, 0, l_count - 1)
402 internal_hash_code := 0
403 end
404 ensure
405 same_count: (count = old count) and (capacity = old capacity)
406 filled: elks_checking implies occurrences (c) = count
407 end
408
409 replace_character (c: CHARACTER_8)
410 -- Replace every character with `c'.
411 obsolete
412 "ELKS 2001: use `fill_with' instead'"
413 do
414 fill_with (c)
415 ensure
416 same_count: (count = old count) and (capacity = old capacity)
417 filled: elks_checking implies occurrences (c) = count
418 end
419
420 head (n: INTEGER)
421 -- Remove all characters except for the first `n';
422 -- do nothing if `n' >= `count'.
423 obsolete
424 "ELKS 2001: use `keep_head' instead'"
425 require
426 non_negative_argument: n >= 0
427 do
428 keep_head (n)
429 ensure
430 new_count: count = n.min (old count)
431 kept: elks_checking implies Current ~ (old substring (1, n.min (count)))
432 end
433
434 keep_head (n: INTEGER)
435 -- Remove all characters except for the first `n';
436 -- do nothing if `n' >= `count'.
437 do
438 if n < count then
439 count := n
440 internal_hash_code := 0
441 end
442 end
443
444 tail (n: INTEGER)
445 -- Remove all characters except for the last `n';
446 -- do nothing if `n' >= `count'.
447 obsolete
448 "ELKS 2001: use `keep_tail' instead'"
449 require
450 non_negative_argument: n >= 0
451 do
452 keep_tail (n)
453 ensure
454 new_count: count = n.min (old count)
455 kept: elks_checking implies Current ~ (old substring (count - n.min(count) + 1, count))
456 end
457
458 keep_tail (n: INTEGER)
459 -- Remove all characters except for the last `n';
460 -- do nothing if `n' >= `count'.
461 local
462 nb: like count
463 do
464 nb := count
465 if n < nb then
466 area.overlapping_move (nb - n, 0, n)
467 count := n
468 internal_hash_code := 0
469 end
470 end
471
472 left_adjust
473 -- Remove leading whitespace.
474 local
475 nb, nb_space: INTEGER
476 l_area: like area
477 do
478 -- Compute number of spaces at the left of current string.
479 from
480 nb := count - 1
481 l_area := area
482 until
483 nb_space > nb or else not l_area.item (nb_space).is_space
484 loop
485 nb_space := nb_space + 1
486 end
487
488 if nb_space > 0 then
489 -- Set new count value.
490 nb := nb + 1 - nb_space
491 -- Shift characters to the left.
492 l_area.overlapping_move (nb_space, 0, nb)
493 -- Set new count.
494 count := nb
495 internal_hash_code := 0
496 end
497 ensure
498 valid_count: count <= old count
499 new_count: not is_empty implies not item (1).is_space
500 kept: elks_checking implies Current ~ ((old twin).substring (old count - count + 1, old count))
501 end
502
503 right_adjust
504 -- Remove trailing whitespace.
505 local
506 i, nb: INTEGER
507 nb_space: INTEGER
508 l_area: like area
509 do
510 -- Compute number of spaces at the right of current string.
511 from
512 nb := count - 1
513 i := nb
514 l_area := area
515 until
516 i < 0 or else not l_area.item (i).is_space
517 loop
518 nb_space := nb_space + 1
519 i := i - 1
520 end
521
522 if nb_space > 0 then
523 -- Set new count.
524 count := nb + 1 - nb_space
525 internal_hash_code := 0
526 end
527 ensure
528 valid_count: count <= old count
529 new_count: (count /= 0) implies
530 ((item (count) /= ' ') and
531 (item (count) /= '%T') and
532 (item (count) /= '%R') and
533 (item (count) /= '%N'))
534 kept: elks_checking implies Current ~ ((old twin).substring (1, count))
535 end
536
537 share (other: STRING_8)
538 -- Make current string share the text of `other'.
539 -- Subsequent changes to the characters of current string
540 -- will also affect `other', and conversely.
541 require
542 argument_not_void: other /= Void
543 do
544 area := other.area
545 count := other.count
546 internal_hash_code := 0
547 ensure
548 shared_count: other.count = count
549 shared_area: other.area = area
550 end
551
552 put (c: CHARACTER_8; i: INTEGER)
553 -- Replace character at position `i' by `c'.
554 do
555 area.put (c, i - 1)
556 internal_hash_code := 0
557 ensure then
558 stable_count: count = old count
559 stable_before_i: elks_checking implies substring (1, i - 1) ~ (old substring (1, i - 1))
560 stable_after_i: elks_checking implies substring (i + 1, count) ~ (old substring (i + 1, count))
561 end
562
563 put_code (v: NATURAL_32; i: INTEGER)
564 -- Replace character at position `i' by character of code `v'.
565 do
566 area.put (v.to_character_8, i - 1)
567 internal_hash_code := 0
568 end
569
570 precede, prepend_character (c: CHARACTER_8)
571 -- Add `c' at front.
572 local
573 l_area: like area
574 do
575 if count = capacity then
576 resize (count + additional_space)
577 end
578 l_area := area
579 l_area.overlapping_move (0, 1, count)
580 l_area.put (c, 0)
581 count := count + 1
582 internal_hash_code := 0
583 ensure
584 new_count: count = old count + 1
585 end
586
587 prepend_string_general (s: READABLE_STRING_GENERAL)
588 -- Prepend a copy of `s' at front.
589 do
590 if attached {READABLE_STRING_8} s as l_s8 then
591 prepend (l_s8)
592 else
593 Precursor {STRING_GENERAL} (s)
594 end
595 end
596
597 prepend (s: READABLE_STRING_8)
598 -- Prepend a copy of `s' at front.
599 require
600 argument_not_void: s /= Void
601 do
602 insert_string (s, 1)
603 ensure
604 new_count: count = old (count + s.count)
605 inserted: elks_checking implies string ~ (old (s.twin.as_string_8) + old substring (1, count))
606 end
607
608 prepend_substring (s: READABLE_STRING_8; start_index, end_index: INTEGER)
609 -- Prepend characters of `s.substring (start_index, end_index)' at front.
610 require
611 argument_not_void: s /= Void
612 start_index_valid: start_index >= 1
613 end_index_valid: end_index <= s.count
614 valid_bounds: start_index <= end_index + 1
615 local
616 new_size: INTEGER
617 l_s_count: INTEGER
618 l_area: like area
619 do
620 -- Insert `s' if `s' is not empty, otherwise is useless.
621 l_s_count := end_index - start_index + 1
622 if l_s_count > 0 then
623 -- Resize Current if necessary.
624 new_size := l_s_count + count
625 if new_size > capacity then
626 resize (new_size + additional_space)
627 end
628
629 -- Perform all operations using a zero based arrays.
630 l_area := area
631
632 -- First shift from `s.count' position all characters of current.
633 l_area.overlapping_move (0, l_s_count, count)
634
635 -- Copy string `s' at beginning.
636 l_area.copy_data (s.area, s.area_lower + start_index - 1, 0, l_s_count)
637
638 count := new_size
639 internal_hash_code := 0
640 end
641 ensure
642 new_count: count = old count + end_index - start_index + 1
643 inserted: elks_checking implies same_string (old (s.substring (start_index, end_index) + Current))
644 end
645
646 prepend_boolean (b: BOOLEAN)
647 -- Prepend the string representation of `b' at front.
648 do
649 prepend (b.out)
650 end
651
652 prepend_double (d: DOUBLE)
653 -- Prepend the string representation of `d' at front.
654 do
655 prepend (d.out)
656 end
657
658 prepend_integer (i: INTEGER)
659 -- Prepend the string representation of `i' at front.
660 do
661 prepend (i.out)
662 end
663
664 prepend_real (r: REAL)
665 -- Prepend the string representation of `r' at front.
666 do
667 prepend (r.out)
668 end
669
670 prepend_string (s: detachable READABLE_STRING_8)
671 -- Prepend a copy of `s', if not void, at front.
672 do
673 if s /= Void then
674 prepend (s)
675 end
676 end
677
678 append_string_general (s: READABLE_STRING_GENERAL)
679 -- Append a copy of `s' at end.
680 do
681 if attached {READABLE_STRING_8} s as l_s8 then
682 append (l_s8)
683 else
684 Precursor {STRING_GENERAL} (s)
685 end
686 end
687
688 append (s: READABLE_STRING_8)
689 -- Append a copy of `s' at end.
690 require
691 argument_not_void: s /= Void
692 local
693 l_count, l_s_count, l_new_size: INTEGER
694 do
695 l_s_count := s.count
696 if l_s_count > 0 then
697 l_count := count
698 l_new_size := l_s_count + l_count
699 if l_new_size > capacity then
700 resize (l_new_size + additional_space)
701 end
702 area.copy_data (s.area, s.area_lower, l_count, l_s_count)
703 count := l_new_size
704 internal_hash_code := 0
705 end
706 ensure
707 new_count: count = old count + old s.count
708 appended: elks_checking implies Current ~ (old twin + old s.twin)
709 end
710
711 append_substring (s: READABLE_STRING_8; start_index, end_index: INTEGER)
712 -- Append characters of `s.substring (start_index, end_index)' at end.
713 require
714 argument_not_void: s /= Void
715 start_index_valid: start_index >= 1
716 end_index_valid: end_index <= s.count
717 valid_bounds: start_index <= end_index + 1
718 local
719 l_count, l_s_count, l_new_size: INTEGER
720 do
721 l_s_count := end_index - start_index + 1
722 if l_s_count > 0 then
723 l_count := count
724 l_new_size := l_s_count + l_count
725 if l_new_size > capacity then
726 resize (l_new_size + additional_space)
727 end
728 area.copy_data (s.area, s.area_lower + start_index - 1, l_count, l_s_count)
729 count := l_new_size
730 internal_hash_code := 0
731 end
732 ensure
733 new_count: count = old count + (end_index - start_index + 1)
734 appended: elks_checking implies same_string (old (Current + s.substring (start_index, end_index)))
735 end
736
737 plus alias "+" (s: READABLE_STRING_8): like Current
738 -- Append a copy of `s' at the end of a copy of Current,
739 -- Then return the Result.
740 do
741 Result := new_string (count + s.count)
742 Result.append (Current)
743 Result.append (s)
744 end
745
746 plus_string_general (s: READABLE_STRING_GENERAL): like Current
747 -- <Precursor>
748 do
749 Result := new_string (count + s.count)
750 Result.append (Current)
751 Result.append_string_general (s)
752 end
753
754 append_string (s: detachable READABLE_STRING_8)
755 -- Append a copy of `s', if not void, at end.
756 do
757 if s /= Void then
758 append (s)
759 end
760 ensure
761 appended: s /= Void implies
762 (elks_checking implies Current ~ (old twin + old s.twin))
763 end
764
765 append_integer (i: INTEGER)
766 -- Append the string representation of `i' at end.
767 local
768 l_value: INTEGER
769 l_starting_index, l_ending_index: INTEGER
770 l_temp: CHARACTER_8
771 l_area: like area
772 do
773 if i = 0 then
774 append_character ('0')
775 else
776 -- Extract integer value digit by digit from right to left.
777 from
778 l_starting_index := count
779 if i < 0 then
780 append_character ('-')
781 l_starting_index := l_starting_index + 1
782 -- Special case for minimum integer value as negating it
783 -- as no effect.
784 if i = {INTEGER}.Min_value then
785 append_character ('8')
786 l_value := -(i // 10)
787 else
788 l_value := -i
789 end
790 else
791 l_value := i
792 end
793 until
794 l_value = 0
795 loop
796 append_character (((l_value \\ 10)+ 48).to_character_8)
797 l_value := l_value // 10
798 end
799
800 -- Now put digits in correct order from left to right.
801 from
802 l_ending_index := count - 1
803 l_area := area
804 until
805 l_starting_index >= l_ending_index
806 loop
807 l_temp := l_area.item (l_starting_index)
808 l_area.put (l_area.item (l_ending_index), l_starting_index)
809 l_area.put (l_temp, l_ending_index)
810 l_ending_index := l_ending_index - 1
811 l_starting_index := l_starting_index + 1
812 end
813 end
814 end
815
816 append_integer_8 (i: INTEGER_8)
817 -- Append the string representation of `i' at end.
818 local
819 l_value: INTEGER_8
820 l_starting_index, l_ending_index: INTEGER
821 l_temp: CHARACTER_8
822 l_area: like area
823 do
824 if i = 0 then
825 append_character ('0')
826 else
827 -- Extract integer value digit by digit from right to left.
828 from
829 l_starting_index := count
830 if i < 0 then
831 append_character ('-')
832 l_starting_index := l_starting_index + 1
833 -- Special case for minimum integer value as negating it
834 -- as no effect.
835 if i = {INTEGER_8}.Min_value then
836 append_character ('8')
837 l_value := -(i // 10)
838 else
839 l_value := -i
840 end
841 else
842 l_value := i
843 end
844 until
845 l_value = 0
846 loop
847 append_character (((l_value \\ 10)+ 48).to_character_8)
848 l_value := l_value // 10
849 end
850
851 -- Now put digits in correct order from left to right.
852 from
853 l_ending_index := count - 1
854 l_area := area
855 until
856 l_starting_index >= l_ending_index
857 loop
858 l_temp := l_area.item (l_starting_index)
859 l_area.put (l_area.item (l_ending_index), l_starting_index)
860 l_area.put (l_temp, l_ending_index)
861 l_ending_index := l_ending_index - 1
862 l_starting_index := l_starting_index + 1
863 end
864 end
865 end
866
867 append_integer_16 (i: INTEGER_16)
868 -- Append the string representation of `i' at end.
869 local
870 l_value: INTEGER_16
871 l_starting_index, l_ending_index: INTEGER
872 l_temp: CHARACTER_8
873 l_area: like area
874 do
875 if i = 0 then
876 append_character ('0')
877 else
878 -- Extract integer value digit by digit from right to left.
879 from
880 l_starting_index := count
881 if i < 0 then
882 append_character ('-')
883 l_starting_index := l_starting_index + 1
884 -- Special case for minimum integer value as negating it
885 -- as no effect.
886 if i = {INTEGER_16}.Min_value then
887 append_character ('8')
888 l_value := -(i // 10)
889 else
890 l_value := -i
891 end
892 else
893 l_value := i
894 end
895 until
896 l_value = 0
897 loop
898 append_character (((l_value \\ 10)+ 48).to_character_8)
899 l_value := l_value // 10
900 end
901
902 -- Now put digits in correct order from left to right.
903 from
904 l_ending_index := count - 1
905 l_area := area
906 until
907 l_starting_index >= l_ending_index
908 loop
909 l_temp := l_area.item (l_starting_index)
910 l_area.put (l_area.item (l_ending_index), l_starting_index)
911 l_area.put (l_temp, l_ending_index)
912 l_ending_index := l_ending_index - 1
913 l_starting_index := l_starting_index + 1
914 end
915 end
916 end
917
918 append_integer_64 (i: INTEGER_64)
919 -- Append the string representation of `i' at end.
920 local
921 l_value: INTEGER_64
922 l_starting_index, l_ending_index: INTEGER
923 l_temp: CHARACTER_8
924 l_area: like area
925 do
926 if i = 0 then
927 append_character ('0')
928 else
929 -- Extract integer value digit by digit from right to left.
930 from
931 l_starting_index := count
932 if i < 0 then
933 append_character ('-')
934 l_starting_index := l_starting_index + 1
935 -- Special case for minimum integer value as negating it
936 -- as no effect.
937 if i = {INTEGER_64}.Min_value then
938 append_character ('8')
939 l_value := -(i // 10)
940 else
941 l_value := -i
942 end
943 else
944 l_value := i
945 end
946 until
947 l_value = 0
948 loop
949 append_character (((l_value \\ 10)+ 48).to_character_8)
950 l_value := l_value // 10
951 end
952
953 -- Now put digits in correct order from left to right.
954 from
955 l_ending_index := count - 1
956 l_area := area
957 until
958 l_starting_index >= l_ending_index
959 loop
960 l_temp := l_area.item (l_starting_index)
961 l_area.put (l_area.item (l_ending_index), l_starting_index)
962 l_area.put (l_temp, l_ending_index)
963 l_ending_index := l_ending_index - 1
964 l_starting_index := l_starting_index + 1
965 end
966 end
967 end
968
969 append_natural_8 (i: NATURAL_8)
970 -- Append the string representation of `i' at end.
971 local
972 l_value: NATURAL_8
973 l_starting_index, l_ending_index: INTEGER
974 l_temp: CHARACTER_8
975 l_area: like area
976 do
977 if i = 0 then
978 append_character ('0')
979 else
980 -- Extract integer value digit by digit from right to left.
981 from
982 l_starting_index := count
983 l_value := i
984 until
985 l_value = 0
986 loop
987 append_character (((l_value \\ 10)+ 48).to_character_8)
988 l_value := l_value // 10
989 end
990
991 -- Now put digits in correct order from left to right.
992 from
993 l_ending_index := count - 1
994 l_area := area
995 until
996 l_starting_index >= l_ending_index
997 loop
998 l_temp := l_area.item (l_starting_index)
999 l_area.put (l_area.item (l_ending_index), l_starting_index)
1000 l_area.put (l_temp, l_ending_index)
1001 l_ending_index := l_ending_index - 1
1002 l_starting_index := l_starting_index + 1
1003 end
1004 end
1005 end
1006
1007 append_natural_16 (i: NATURAL_16)
1008 -- Append the string representation of `i' at end.
1009 local
1010 l_value: NATURAL_16
1011 l_starting_index, l_ending_index: INTEGER
1012 l_temp: CHARACTER_8
1013 l_area: like area
1014 do
1015 if i = 0 then
1016 append_character ('0')
1017 else
1018 -- Extract integer value digit by digit from right to left.
1019 from
1020 l_starting_index := count
1021 l_value := i
1022 until
1023 l_value = 0
1024 loop
1025 append_character (((l_value \\ 10)+ 48).to_character_8)
1026 l_value := l_value // 10
1027 end
1028
1029 -- Now put digits in correct order from left to right.
1030 from
1031 l_ending_index := count - 1
1032 l_area := area
1033 until
1034 l_starting_index >= l_ending_index
1035 loop
1036 l_temp := l_area.item (l_starting_index)
1037 l_area.put (l_area.item (l_ending_index), l_starting_index)
1038 l_area.put (l_temp, l_ending_index)
1039 l_ending_index := l_ending_index - 1
1040 l_starting_index := l_starting_index + 1
1041 end
1042 end
1043 end
1044
1045 append_natural_32 (i: NATURAL_32)
1046 -- Append the string representation of `i' at end.
1047 local
1048 l_value: NATURAL_32
1049 l_starting_index, l_ending_index: INTEGER
1050 l_temp: CHARACTER_8
1051 l_area: like area
1052 do
1053 if i = 0 then
1054 append_character ('0')
1055 else
1056 -- Extract integer value digit by digit from right to left.
1057 from
1058 l_starting_index := count
1059 l_value := i
1060 until
1061 l_value = 0
1062 loop
1063 append_character (((l_value \\ 10)+ 48).to_character_8)
1064 l_value := l_value // 10
1065 end
1066
1067 -- Now put digits in correct order from left to right.
1068 from
1069 l_ending_index := count - 1
1070 l_area := area
1071 until
1072 l_starting_index >= l_ending_index
1073 loop
1074 l_temp := l_area.item (l_starting_index)
1075 l_area.put (l_area.item (l_ending_index), l_starting_index)
1076 l_area.put (l_temp, l_ending_index)
1077 l_ending_index := l_ending_index - 1
1078 l_starting_index := l_starting_index + 1
1079 end
1080 end
1081 end
1082
1083 append_natural_64 (i: NATURAL_64)
1084 -- Append the string representation of `i' at end.
1085 local
1086 l_value: NATURAL_64
1087 l_starting_index, l_ending_index: INTEGER
1088 l_temp: CHARACTER_8
1089 l_area: like area
1090 do
1091 if i = 0 then
1092 append_character ('0')
1093 else
1094 -- Extract integer value digit by digit from right to left.
1095 from
1096 l_starting_index := count
1097 l_value := i
1098 until
1099 l_value = 0
1100 loop
1101 append_character (((l_value \\ 10)+ 48).to_character_8)
1102 l_value := l_value // 10
1103 end
1104
1105 -- Now put digits in correct order from left to right.
1106 from
1107 l_ending_index := count - 1
1108 l_area := area
1109 until
1110 l_starting_index >= l_ending_index
1111 loop
1112 l_temp := l_area.item (l_starting_index)
1113 l_area.put (l_area.item (l_ending_index), l_starting_index)
1114 l_area.put (l_temp, l_ending_index)
1115 l_ending_index := l_ending_index - 1
1116 l_starting_index := l_starting_index + 1
1117 end
1118 end
1119 end
1120
1121 append_real (r: REAL)
1122 -- Append the string representation of `r' at end.
1123 do
1124 append (r.out)
1125 end
1126
1127 append_double (d: DOUBLE)
1128 -- Append the string representation of `d' at end.
1129 do
1130 append (d.out)
1131 end
1132
1133 append_character, extend (c: CHARACTER_8)
1134 -- Append `c' at end.
1135 local
1136 current_count: INTEGER
1137 do
1138 current_count := count
1139 if current_count = capacity then
1140 resize (current_count + additional_space)
1141 end
1142 area.put (c, current_count)
1143 count := current_count + 1
1144 internal_hash_code := 0
1145 ensure then
1146 item_inserted: item (count) = c
1147 new_count: count = old count + 1
1148 stable_before: elks_checking implies substring (1, count - 1) ~ (old twin)
1149 end
1150
1151 append_boolean (b: BOOLEAN)
1152 -- Append the string representation of `b' at end.
1153 do
1154 append (b.out)
1155 end
1156
1157 insert (s: READABLE_STRING_8; i: INTEGER)
1158 -- Add `s' to left of position `i' in current string.
1159 obsolete
1160 "ELKS 2001: use `insert_string' instead"
1161 require
1162 string_exists: s /= Void
1163 index_small_enough: i <= count + 1
1164 index_large_enough: i > 0
1165 do
1166 insert_string (s, i)
1167 ensure
1168 inserted: elks_checking implies
1169 (Current ~ (old substring (1, i - 1) + old (s.twin) + old substring (i, count)))
1170 end
1171
1172 insert_string (s: READABLE_STRING_8; i: INTEGER)
1173 -- Insert `s' at index `i', shifting characters between ranks
1174 -- `i' and `count' rightwards.
1175 require
1176 string_exists: s /= Void
1177 valid_insertion_index: 1 <= i and i <= count + 1
1178 local
1179 pos, new_size: INTEGER
1180 l_s_count: INTEGER
1181 l_area: like area
1182 do
1183 -- Insert `s' if `s' is not empty, otherwise is useless.
1184 l_s_count := s.count
1185 if l_s_count /= 0 then
1186 -- Resize Current if necessary.
1187 new_size := l_s_count + count
1188 if new_size > capacity then
1189 resize (new_size + additional_space)
1190 end
1191
1192 -- Perform all operations using a zero based arrays.
1193 l_area := area
1194 pos := i - 1
1195
1196 -- First shift from `s.count' position all characters starting at index `pos'.
1197 l_area.overlapping_move (pos, pos + l_s_count, count - pos)
1198
1199 -- Copy string `s' at index `pos'.
1200 l_area.copy_data (s.area, s.area_lower, pos, l_s_count)
1201
1202 count := new_size
1203 internal_hash_code := 0
1204 end
1205 ensure
1206 inserted: elks_checking implies (Current ~ (old substring (1, i - 1) + old (s.twin) + old substring (i, count)))
1207 end
1208
1209 insert_character (c: CHARACTER_8; i: INTEGER)
1210 -- Insert `c' at index `i', shifting characters between ranks
1211 -- `i' and `count' rightwards.
1212 require
1213 valid_insertion_index: 1 <= i and i <= count + 1
1214 local
1215 pos, new_size: INTEGER
1216 l_area: like area
1217 do
1218 -- Resize Current if necessary.
1219 new_size := 1 + count
1220 if new_size > capacity then
1221 resize (new_size + additional_space)
1222 end
1223
1224 -- Perform all operations using a zero based arrays.
1225 pos := i - 1
1226 l_area := area
1227
1228 -- First shift from `s.count' position all characters starting at index `pos'.
1229 l_area.overlapping_move (pos, pos + 1, count - pos)
1230
1231 -- Insert new character
1232 l_area.put (c, pos)
1233
1234 count := new_size
1235 internal_hash_code := 0
1236 ensure
1237 one_more_character: count = old count + 1
1238 inserted: item (i) = c
1239 stable_before_i: elks_checking implies substring (1, i - 1) ~ (old substring (1, i - 1))
1240 stable_after_i: elks_checking implies substring (i + 1, count) ~ (old substring (i, count))
1241 end
1242
1243 feature -- Removal
1244
1245 remove (i: INTEGER)
1246 -- Remove `i'-th character.
1247 local
1248 l_count: INTEGER
1249 do
1250 l_count := count
1251 -- Shift characters to the left.
1252 area.overlapping_move (i, i - 1, l_count - i)
1253 -- Update content.
1254 count := l_count - 1
1255 internal_hash_code := 0
1256 end
1257
1258 remove_head (n: INTEGER)
1259 -- Remove first `n' characters;
1260 -- if `n' > `count', remove all.
1261 require
1262 n_non_negative: n >= 0
1263 do
1264 if n > count then
1265 count := 0
1266 internal_hash_code := 0
1267 else
1268 keep_tail (count - n)
1269 end
1270 ensure
1271 removed: elks_checking implies Current ~ (old substring (n.min (count) + 1, count))
1272 end
1273
1274 remove_substring (start_index, end_index: INTEGER)
1275 -- Remove all characters from `start_index'
1276 -- to `end_index' inclusive.
1277 require
1278 valid_start_index: 1 <= start_index
1279 valid_end_index: end_index <= count
1280 meaningful_interval: start_index <= end_index + 1
1281 local
1282 l_count, nb_removed: INTEGER
1283 do
1284 nb_removed := end_index - start_index + 1
1285 if nb_removed > 0 then
1286 l_count := count
1287 area.overlapping_move (start_index + nb_removed - 1, start_index - 1, l_count - end_index)
1288 count := l_count - nb_removed
1289 internal_hash_code := 0
1290 end
1291 ensure
1292 removed: elks_checking implies Current ~ (old substring (1, start_index - 1) + old substring (end_index + 1, count))
1293 end
1294
1295 remove_tail (n: INTEGER)
1296 -- Remove last `n' characters;
1297 -- if `n' > `count', remove all.
1298 require
1299 n_non_negative: n >= 0
1300 local
1301 l_count: INTEGER
1302 do
1303 l_count := count
1304 if n > l_count then
1305 count := 0
1306 internal_hash_code := 0
1307 else
1308 keep_head (l_count - n)
1309 end
1310 ensure
1311 removed: elks_checking implies Current ~ (old substring (1, count - n.min (count)))
1312 end
1313
1314 prune (c: CHARACTER_8)
1315 -- Remove first occurrence of `c', if any.
1316 require else
1317 True
1318 local
1319 counter: INTEGER
1320 do
1321 from
1322 counter := 1
1323 until
1324 counter > count or else (item (counter) = c)
1325 loop
1326 counter := counter + 1
1327 end
1328 if counter <= count then
1329 remove (counter)
1330 end
1331 end
1332
1333 prune_all (c: CHARACTER_8)
1334 -- Remove all occurrences of `c'.
1335 require else
1336 True
1337 local
1338 i, j, nb: INTEGER
1339 l_area: like area
1340 l_char: CHARACTER_8
1341 do
1342 -- Traverse string and shift characters to the left
1343 -- each time we find an occurrence of `c'.
1344 from
1345 l_area := area
1346 nb := count
1347 until
1348 i = nb
1349 loop
1350 l_char := l_area.item (i)
1351 if l_char /= c then
1352 l_area.put (l_char, j)
1353 j := j + 1
1354 end
1355 i := i + 1
1356 end
1357 count := j
1358 internal_hash_code := 0
1359 ensure then
1360 changed_count: count = (old count) - (old occurrences (c))
1361 -- removed: For every `i' in 1..`count', `item' (`i') /= `c'
1362 end
1363
1364 prune_all_leading (c: CHARACTER_8)
1365 -- Remove all leading occurrences of `c'.
1366 do
1367 from
1368 until
1369 is_empty or else item (1) /= c
1370 loop
1371 remove (1)
1372 end
1373 end
1374
1375 prune_all_trailing (c: CHARACTER_8)
1376 -- Remove all trailing occurrences of `c'.
1377 do
1378 from
1379 until
1380 is_empty or else item (count) /= c
1381 loop
1382 remove (count)
1383 end
1384 end
1385
1386 wipe_out
1387 -- Remove all characters.
1388 do
1389 create area.make (1)
1390 count := 0
1391 internal_hash_code := 0
1392 ensure then
1393 is_empty: count = 0
1394 empty_capacity: capacity = 0
1395 end
1396
1397 clear_all
1398 -- Reset all characters.
1399 do
1400 count := 0
1401 internal_hash_code := 0
1402 ensure
1403 is_empty: count = 0
1404 same_capacity: capacity = old capacity
1405 end
1406
1407 feature -- Resizing
1408
1409 adapt_size
1410 -- Adapt the size to accommodate `count' characters.
1411 do
1412 resize (count)
1413 end
1414
1415 resize (newsize: INTEGER)
1416 -- Rearrange string so that it can accommodate
1417 -- at least `newsize' characters.
1418 -- Do not lose any previously entered character.
1419 local
1420 area_count: INTEGER
1421 do
1422 area_count := area.count
1423 if newsize >= area_count then
1424 area := area.aliased_resized_area (newsize + 1)
1425 end
1426 end
1427
1428 grow (newsize: INTEGER)
1429 -- Ensure that the capacity is at least `newsize'.
1430 do
1431 if newsize > capacity then
1432 resize (newsize)
1433 end
1434 end
1435
1436 trim
1437 -- <Precursor>
1438 local
1439 n: like count
1440 do
1441 n := count
1442 if n < capacity then
1443 area := area.resized_area (n)
1444 end
1445 ensure then
1446 same_string: same_string (old twin)
1447 end
1448
1449 feature -- Conversion
1450
1451 as_lower: like Current
1452 -- New object with all letters in lower case.
1453 do
1454 Result := twin
1455 Result.to_lower
1456 end
1457
1458 as_upper: like Current
1459 -- New object with all letters in upper case
1460 do
1461 Result := twin
1462 Result.to_upper
1463 end
1464
1465 left_justify
1466 -- Left justify Current using `count' as witdth.
1467 local
1468 i, nb: INTEGER
1469 l_area: like area
1470 do
1471 -- Remove leading white spaces.
1472 nb := count
1473 left_adjust
1474
1475 -- Get new count
1476 i := count
1477 if i < nb then
1478 -- `left_adjust' did remove some characters, so we need to add
1479 -- some white spaces at the end of the string.
1480 from
1481 l_area := area
1482 until
1483 i = nb
1484 loop
1485 l_area.put (' ', i)
1486 i := i + 1
1487 end
1488 -- Restore `count'
1489 count := nb
1490 internal_hash_code := 0
1491 end
1492 end
1493
1494 center_justify
1495 -- Center justify Current using `count' as width.
1496 local
1497 i, nb, l_offset: INTEGER
1498 left_nb_space, right_nb_space: INTEGER
1499 l_area: like area
1500 do
1501 -- Compute number of spaces at the left of current string.
1502 from
1503 nb := count
1504 l_area := area
1505 until
1506 left_nb_space = nb or else not l_area.item (left_nb_space).is_space
1507 loop
1508 left_nb_space := left_nb_space + 1
1509 end
1510
1511 -- Compute number of spaces at the right of current string.
1512 from
1513 i := nb - 1
1514 l_area := area
1515 until
1516 i = -1 or else not l_area.item (i).is_space
1517 loop
1518 right_nb_space := right_nb_space + 1
1519 i := i - 1
1520 end
1521
1522 -- We encourage that more spaces will be put to the left, when
1523 -- number of spaces is not even.
1524 l_offset := left_nb_space + right_nb_space
1525 if l_offset \\ 2 = 0 then
1526 l_offset := left_nb_space - l_offset // 2
1527 else
1528 l_offset := left_nb_space - l_offset // 2 - 1
1529 end
1530 if l_offset = 0 then
1531 -- Nothing to be done.
1532 else
1533 -- Shift characters to the right or left (depending on sign of
1534 -- `l_offset' by `l_offset' position.
1535 l_area.move_data (left_nb_space, left_nb_space - l_offset,
1536 nb - left_nb_space - right_nb_space)
1537
1538 if l_offset < 0 then
1539 -- Fill left part with spaces.
1540 l_area.fill_with (' ', left_nb_space, left_nb_space - l_offset - 1)
1541 else
1542 -- Fill right part with spaces.
1543 l_area.fill_with (' ', nb - right_nb_space - l_offset, nb - 1)
1544 end
1545 internal_hash_code := 0
1546 end
1547 end
1548
1549 right_justify
1550 -- Right justify Current using `count' as width.
1551 local
1552 i, nb: INTEGER
1553 nb_space: INTEGER
1554 l_area: like area
1555 do
1556 nb := count
1557 right_adjust
1558 i := count
1559 nb_space := nb - i
1560 if nb_space > 0 then
1561 -- Shift characters to the right.
1562 from
1563 l_area := area
1564 until
1565 i = 0
1566 loop
1567 i := i - 1
1568 l_area.put (l_area.item (i), i + nb_space)
1569 variant
1570 i + 1
1571 end
1572
1573 -- Fill left part with spaces.
1574 from
1575 until
1576 nb_space = 0
1577 loop
1578 nb_space := nb_space - 1
1579 l_area.put (' ', nb_space)
1580 variant
1581 nb_space + 1
1582 end
1583 -- Restore `count'
1584 count := nb
1585 internal_hash_code := 0
1586 end
1587 ensure
1588 same_count: count = old count
1589 end
1590
1591 character_justify (pivot: CHARACTER_8; position: INTEGER)
1592 -- Justify a string based on a `pivot'
1593 -- and the `position' it needs to be in
1594 -- the final string.
1595 -- This will grow the string if necessary
1596 -- to get the pivot in the correct place.
1597 require
1598 valid_position: position <= capacity
1599 positive_position: position >= 1
1600 pivot_not_space: pivot /= ' '
1601 not_empty: not is_empty
1602 local
1603 l_index_of_pivot, l_new_size: INTEGER
1604 l_area: like area
1605 do
1606 l_index_of_pivot := index_of (pivot, 1)
1607 if l_index_of_pivot /= 0 then
1608 if l_index_of_pivot < position then
1609 -- We need to resize Current so that we can shift Current by
1610 -- `l_index_of_pivot - position'.
1611 l_new_size := count + position - l_index_of_pivot
1612 grow (l_new_size)
1613 l_area := area
1614 l_area.move_data (0, position - l_index_of_pivot, count)
1615 l_area.fill_with (' ', 0, position - l_index_of_pivot - 1)
1616 count := l_new_size
1617 else
1618 -- Simply shift content to the left and reset trailing with spaces.
1619 l_area := area
1620 l_area.move_data (l_index_of_pivot - position, 0, count - l_index_of_pivot + position)
1621 l_area.fill_with (' ', count - l_index_of_pivot + position, count - 1)
1622 end
1623 internal_hash_code := 0
1624 end
1625 end
1626
1627 to_lower
1628 -- Convert to lower case.
1629 do
1630 to_lower_area (area, 0, count - 1)
1631 internal_hash_code := 0
1632 ensure
1633 length_and_content: elks_checking implies Current ~ (old as_lower)
1634 end
1635
1636 to_upper
1637 -- Convert to upper case.
1638 do
1639 to_upper_area (area, 0, count - 1)
1640 internal_hash_code := 0
1641 ensure
1642 length_and_content: elks_checking implies Current ~ (old as_upper)
1643 end
1644
1645 linear_representation: LINEAR [CHARACTER_8]
1646 -- Representation as a linear structure
1647 local
1648 temp: ARRAYED_LIST [CHARACTER_8]
1649 i: INTEGER
1650 do
1651 create temp.make (capacity)
1652 from
1653 i := 1
1654 until
1655 i > count
1656 loop
1657 temp.extend (item (i))
1658 i := i + 1
1659 end
1660 Result := temp
1661 end
1662
1663 frozen to_c: ANY
1664 -- A reference to a C form of current string.
1665 -- Useful only for interfacing with C software.
1666 require
1667 not_is_dotnet: not {PLATFORM}.is_dotnet
1668 local
1669 l_area: like area
1670 do
1671 l_area := area
1672 l_area.put ('%U', count)
1673 Result := l_area
1674 end
1675
1676 mirrored: like Current
1677 -- Mirror image of string;
1678 -- Result for "Hello world" is "dlrow olleH".
1679 do
1680 Result := twin
1681 if count > 0 then
1682 Result.mirror
1683 end
1684 end
1685
1686 mirror
1687 -- Reverse the order of characters.
1688 -- "Hello world" -> "dlrow olleH".
1689 local
1690 a: like area
1691 c: CHARACTER_8
1692 i, j: INTEGER
1693 do
1694 if count > 0 then
1695 from
1696 i := count - 1
1697 a := area
1698 until
1699 i <= j
1700 loop
1701 c := a.item (i)
1702 a.put (a.item (j), i)
1703 a.put (c, j)
1704 i := i - 1
1705 j := j + 1
1706 end
1707 internal_hash_code := 0
1708 end
1709 ensure
1710 same_count: count = old count
1711 -- reversed: For every `i' in 1..`count', `item' (`i') = old `item' (`count'+1-`i')
1712 end
1713
1714 feature -- Duplication
1715
1716 substring (start_index, end_index: INTEGER): like Current
1717 -- Copy of substring containing all characters at indices
1718 -- between `start_index' and `end_index'
1719 do
1720 if (1 <= start_index) and (start_index <= end_index) and (end_index <= count) then
1721 Result := new_string (end_index - start_index + 1)
1722 Result.area.copy_data (area, start_index - 1, 0, end_index - start_index + 1)
1723 Result.set_count (end_index - start_index + 1)
1724 else
1725 Result := new_string (0)
1726 end
1727 end
1728
1729 multiply (n: INTEGER)
1730 -- Duplicate a string within itself
1731 -- ("hello").multiply(3) => "hellohellohello"
1732 require
1733 meaningful_multiplier: n >= 1
1734 local
1735 s: like Current
1736 i: INTEGER
1737 do
1738 s := twin
1739 grow (n * count)
1740 from
1741 i := n
1742 until
1743 i = 1
1744 loop
1745 append (s)
1746 i := i - 1
1747 end
1748 end
1749
1750 feature {STRING_HANDLER} -- Implementation
1751
1752 frozen set_count (number: INTEGER)
1753 -- Set `count' to `number' of characters.
1754 do
1755 count := number
1756 internal_hash_code := 0
1757 end
1758
1759 feature {NONE} -- Implementation
1760
1761 new_string (n: INTEGER): like Current
1762 -- New instance of current with space for at least `n' characters.
1763 do
1764 create Result.make (n)
1765 end
1766
1767 feature -- Transformation
1768
1769 correct_mismatch
1770 -- Attempt to correct object mismatch during retrieve using `mismatch_information'.
1771 do
1772 -- Nothing to be done because we only added `internal_hash_code' that will
1773 -- be recomputed next time we query `hash_code'.
1774 end
1775
1776 feature {NONE} -- Implementation
1777
1778 empty_area: SPECIAL [CHARACTER_8]
1779 -- Empty `area' to avoid useless creation of empty areas when wiping out a STRING.
1780 obsolete
1781 "Simply create `area' directly."
1782 do
1783 create Result.make (1)
1784 ensure
1785 empty_area_not_void: Result /= Void
1786 end
1787
1788 invariant
1789 extendible: extendible
1790 compare_character: not object_comparison
1791
1792 end

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision
svn:mergeinfo /FreeELKS/trunk/void_safe/library/kernel/string_8.e:91826

  ViewVC Help
Powered by ViewVC 1.1.23