/[eiffelstudio]/FreeELKS/trunk/library/kernel/readable_string_32.e
ViewVC logotype

Contents of /FreeELKS/trunk/library/kernel/readable_string_32.e

Parent Directory Parent Directory | Revision Log Revision Log


Revision 91639 - (show annotations)
Thu Nov 6 13:22:41 2008 UTC (11 years, 2 months ago) by kwaxer
File size: 33077 byte(s)
Added new features to separate creation of an object and its modification that allows to avoid errors related to initialization of attributes in void-safe mode.
1 indexing
2 description: "[
3 Sequences of 32-bit characters, accessible through integer indices
4 in a contiguous range. Read-only interface.
5 ]"
6 library: "Free implementation of ELKS library"
7 copyright: "Copyright (c) 1986-2008, Eiffel Software and others"
8 license: "Eiffel Forum License v2 (see forum.txt)"
9 date: "$Date$"
10 revision: "$Revision$"
11
12 deferred class
13 READABLE_STRING_32
14
15 inherit
16 READABLE_STRING_GENERAL
17 rename
18 same_string as same_string_general
19 redefine
20 copy, is_equal, out
21 end
22
23 convert
24 to_cil: {SYSTEM_STRING},
25 as_string_8: {READABLE_STRING_8, STRING_8},
26 as_string_32: {STRING_32}
27
28 feature {NONE} -- Initialization
29
30 make (n: INTEGER)
31 -- Allocate space for at least `n' characters.
32 require
33 non_negative_size: n >= 0
34 do
35 count := 0
36 internal_hash_code := 0
37 create area.make (n + 1)
38 ensure
39 empty_string: count = 0
40 area_allocated: capacity >= n
41 end
42
43 make_empty
44 -- Create empty string.
45 do
46 make (0)
47 ensure
48 empty: count = 0
49 area_allocated: capacity >= 0
50 end
51
52 make_filled (c: CHARACTER_32; n: INTEGER)
53 -- Create string of length `n' filled with `c'.
54 require
55 valid_count: n >= 0
56 do
57 make (n)
58 fill_character (c)
59 ensure
60 count_set: count = n
61 area_allocated: capacity >= n
62 filled: occurrences (c) = count
63 end
64
65 make_from_string (s: READABLE_STRING_32)
66 -- Initialize from the characters of `s'.
67 -- obsolete
68 -- "Use `make_from_other_string' to create object and `copy' to modify it."
69 require
70 string_exists: s /= Void
71 do
72 if Current /= s then
73 area := s.area.twin
74 count := s.count
75 internal_hash_code := 0
76 end
77 ensure
78 not_shared_implementation: Current /= s implies not shared_with (s)
79 initialized: same_string (s)
80 end
81
82 make_from_c (c_string: POINTER)
83 -- Initialize from contents of `c_string',
84 -- a string created by some C function
85 -- obsolete
86 -- "Use `make_from_c_pointer' to create object and `from_c' to modify it."
87 require
88 c_string_exists: c_string /= default_pointer
89 local
90 l_count: INTEGER
91 do
92 c_string_provider.set_shared_from_pointer (c_string)
93 l_count := c_string_provider.count
94 if area = Void then
95 create area.make (l_count + 1)
96 elseif l_count >= area.count then
97 area := area.aliased_resized_area (l_count + 1)
98 end
99 count := l_count
100 internal_hash_code := 0
101 c_string_provider.read_substring_into_character_32_area (area, 1, l_count)
102 end
103
104 make_from_other_string (s: READABLE_STRING_32)
105 -- Create new instance from the characters of `s'.
106 require
107 string_exists: s /= Void
108 do
109 area := s.area.twin
110 count := s.count
111 internal_hash_code := 0
112 ensure
113 not_shared_implementation: Current /= s implies not shared_with (s)
114 initialized: same_string (s)
115 end
116
117 make_from_c_pointer (c_string: POINTER)
118 -- Create new instance from contents of `c_string',
119 -- a string created by some C function
120 require
121 c_string_exists: c_string /= default_pointer
122 local
123 l_count: INTEGER
124 do
125 c_string_provider.set_shared_from_pointer (c_string)
126 l_count := c_string_provider.count
127 create area.make (l_count + 1)
128 count := l_count
129 internal_hash_code := 0
130 c_string_provider.read_substring_into_character_32_area (area, 1, l_count)
131 end
132
133 make_from_cil (a_system_string: SYSTEM_STRING)
134 -- Initialize Current with `a_system_string'.
135 require
136 is_dotnet: {PLATFORM}.is_dotnet
137 deferred
138 end
139
140 feature -- Access
141
142 item, infix "@" (i: INTEGER): CHARACTER_32
143 -- Character at position `i'
144 do
145 Result := area.item (i - 1)
146 end
147
148 code (i: INTEGER): NATURAL_32
149 -- Numeric code of character at position `i'
150 do
151 Result := area.item (i - 1).code.to_natural_32
152 end
153
154 item_code (i: INTEGER): INTEGER
155 -- Numeric code of character at position `i'
156 require
157 index_small_enough: i <= count
158 index_large_enough: i > 0
159 do
160 Result := area.item (i - 1).code
161 end
162
163 hash_code: INTEGER
164 -- Hash code value
165 local
166 i, nb: INTEGER
167 l_area: like area
168 do
169 Result := internal_hash_code
170 if Result = 0 then
171 -- The magic number `8388593' below is the greatest prime lower than
172 -- 2^23 so that this magic number shifted to the left does not exceed 2^31.
173 from
174 i := 0
175 nb := count
176 l_area := area
177 until
178 i = nb
179 loop
180 Result := ((Result \\ 8388593) |<< 8) + l_area.item (i).code
181 i := i + 1
182 end
183 internal_hash_code := Result
184 end
185 end
186
187 false_constant: STRING_8 = "false"
188 -- Constant string "false"
189
190 true_constant: STRING_8 = "true"
191 -- Constant string "true"
192
193 shared_with (other: READABLE_STRING_32): BOOLEAN
194 -- Does string share the text of `other'?
195 do
196 Result := (other /= Void) and then (area = other.area)
197 end
198
199 index_of (c: CHARACTER_32; start_index: INTEGER): INTEGER
200 -- Position of first occurrence of `c' at or after `start_index';
201 -- 0 if none.
202 require
203 start_large_enough: start_index >= 1
204 start_small_enough: start_index <= count + 1
205 local
206 a: like area
207 i, nb: INTEGER
208 do
209 nb := count
210 if start_index <= nb then
211 from
212 i := start_index - 1
213 a := area
214 until
215 i = nb or else a.item (i) = c
216 loop
217 i := i + 1
218 end
219 if i < nb then
220 -- We add +1 due to the area starting at 0 and not at 1.
221 Result := i + 1
222 end
223 end
224 ensure
225 valid_result: Result = 0 or (start_index <= Result and Result <= count)
226 zero_if_absent: (Result = 0) = not substring (start_index, count).has (c)
227 found_if_present: substring (start_index, count).has (c) implies item (Result) = c
228 none_before: substring (start_index, count).has (c) implies
229 not substring (start_index, Result - 1).has (c)
230 end
231
232 last_index_of (c: CHARACTER_32; start_index_from_end: INTEGER): INTEGER
233 -- Position of last occurrence of `c'.
234 -- 0 if none
235 require
236 start_index_small_enough: start_index_from_end <= count
237 start_index_large_enough: start_index_from_end >= 1
238 local
239 a: like area
240 i: INTEGER
241 do
242 from
243 i := start_index_from_end - 1
244 a := area
245 until
246 i < 0 or else a.item (i) = c
247 loop
248 i := i - 1
249 end
250 -- We add +1 due to the area starting at 0 and not at 1.
251 Result := i + 1
252 ensure
253 last_index_of_non_negative: Result >= 0
254 correct_place: Result > 0 implies item (Result) = c
255 -- forall x : Result..last, item (x) /= c
256 end
257
258 substring_index_in_bounds (other: READABLE_STRING_32; start_pos, end_pos: INTEGER): INTEGER
259 -- Position of first occurrence of `other' at or after `start_pos'
260 -- and to or before `end_pos';
261 -- 0 if none.
262 require
263 other_nonvoid: other /= Void
264 other_valid_string_8: other.is_valid_as_string_8
265 other_notempty: not other.is_empty
266 start_pos_large_enough: start_pos >= 1
267 start_pos_small_enough: start_pos <= count
268 end_pos_large_enough: end_pos >= start_pos
269 end_pos_small_enough: end_pos <= count
270 do
271 Result := string_searcher.substring_index (Current, other, start_pos, end_pos)
272 ensure
273 correct_place: Result > 0 implies
274 other.is_equal (substring (Result, Result + other.count - 1))
275 -- forall x : start_pos..Result
276 -- not substring (x, x+other.count -1).is_equal (other)
277 end
278
279 string: STRING_32
280 -- New STRING_32 having same character sequence as `Current'.
281 do
282 create Result.make_from_other_string (Current)
283 ensure
284 string_not_void: Result /= Void
285 string_type: Result.same_type (create {STRING_32}.make_empty)
286 first_item: count > 0 implies Result.item (1) = item (1)
287 recurse: count > 1 implies Result.substring (2, count).is_equal (
288 substring (2, count).string)
289 end
290
291 string_representation: STRING_32
292 -- Similar to `string' but only create a new object if `Current' is not of dynamic type {STRING_32}
293 do
294 if same_type (create {STRING_32}.make_empty) and then {l_s32: STRING_32} Current then
295 Result := l_s32
296 else
297 Result := string
298 end
299 ensure
300 Result_not_void: Result /= Void
301 correct_type: Result.same_type (create {STRING_32}.make_empty)
302 first_item: count > 0 implies Result.item (1) = item (1)
303 recurse: count > 1 implies Result.substring (2, count).is_equal (
304 substring (2, count).string)
305 end
306
307 substring_index (other: READABLE_STRING_32; start_index: INTEGER): INTEGER
308 -- Index of first occurrence of other at or after start_index;
309 -- 0 if none
310 require
311 other_not_void: other /= Void
312 other_valid_string_8: other.is_valid_as_string_8
313 valid_start_index: start_index >= 1 and start_index <= count + 1
314 do
315 Result := string_searcher.substring_index (Current, other, start_index, count)
316 ensure
317 valid_result: Result = 0 or else
318 (start_index <= Result and Result <= count - other.count + 1)
319 zero_if_absent: (Result = 0) =
320 not substring (start_index, count).has_substring (other)
321 at_this_index: Result >= start_index implies
322 other.same_string (substring (Result, Result + other.count - 1))
323 none_before: Result > start_index implies
324 not substring (start_index, Result + other.count - 2).has_substring (other)
325 end
326
327 fuzzy_index (other: READABLE_STRING_32; start: INTEGER; fuzz: INTEGER): INTEGER
328 -- Position of first occurrence of `other' at or after `start'
329 -- with 0..`fuzz' mismatches between the string and `other'.
330 -- 0 if there are no fuzzy matches
331 require
332 other_exists: other /= Void
333 other_valid_string_8: other.is_valid_as_string_8
334 other_not_empty: not other.is_empty
335 start_large_enough: start >= 1
336 start_small_enough: start <= count
337 acceptable_fuzzy: fuzz <= other.count
338 do
339 Result := string_searcher.fuzzy_index (Current, other, start, count, fuzz)
340 end
341
342 feature -- Measurement
343
344 capacity: INTEGER
345 -- Allocated space
346 do
347 Result := area.count - 1
348 end
349
350 count: INTEGER
351 -- Actual number of characters making up the string
352
353 occurrences (c: CHARACTER_32): INTEGER
354 -- Number of times `c' appears in the string
355 local
356 i, nb: INTEGER
357 a: SPECIAL [CHARACTER_32]
358 do
359 from
360 nb := count
361 a := area
362 until
363 i = nb
364 loop
365 if a.item (i) = c then
366 Result := Result + 1
367 end
368 i := i + 1
369 end
370 ensure then
371 zero_if_empty: count = 0 implies Result = 0
372 recurse_if_not_found_at_first_position:
373 (count > 0 and then item (1) /= c) implies
374 Result = substring (2, count).occurrences (c)
375 recurse_if_found_at_first_position:
376 (count > 0 and then item (1) = c) implies
377 Result = 1 + substring (2, count).occurrences (c)
378 end
379
380 index_set: INTEGER_INTERVAL
381 -- Range of acceptable indexes
382 do
383 create Result.make (1, count)
384 ensure
385 index_set_not_void: Result /= Void
386 index_set_count: Result.count = count
387 end
388
389 feature -- Comparison
390
391 is_equal (other: like Current): BOOLEAN
392 -- Is string made of same character sequence as `other'
393 -- (possibly with a different capacity)?
394 local
395 l_count: INTEGER
396 do
397 if other = Current then
398 Result := True
399 else
400 l_count := count
401 if l_count = other.count then
402 Result := str_strict_cmp (area, other.area, l_count) = 0
403 end
404 end
405 end
406
407 is_case_insensitive_equal (other: like Current): BOOLEAN
408 -- Is string made of same character sequence as `other' regardless of casing
409 -- (possibly with a different capacity)?
410 require
411 is_valid_as_string_8: is_valid_as_string_8
412 other_not_void: other /= Void
413 other_is_valid_as_string_8: other.is_valid_as_string_8
414 local
415 l_area, l_other_area: like area
416 i, nb: INTEGER
417 do
418 if other = Current then
419 Result := True
420 else
421 nb := count
422 if nb = other.count then
423 from
424 l_area := area
425 l_other_area := other.area
426 Result := True
427 until
428 i = nb
429 loop
430 if l_area.item (i).as_lower /= l_other_area.item (i).as_lower then
431 Result := False
432 i := nb - 1 -- Jump out of loop
433 end
434 i := i + 1
435 end
436 end
437 end
438 ensure
439 symmetric: Result implies other.is_case_insensitive_equal (Current)
440 consistent: standard_is_equal (other) implies Result
441 valid_result: as_lower.is_equal (other.as_lower) implies Result
442 end
443
444 same_string (other: READABLE_STRING_32): BOOLEAN is
445 -- Do `Current' and `other' have same character sequence?
446 require
447 other_not_void: other /= Void
448 do
449 if other = Current then
450 Result := True
451 elseif other.count = count then
452 if same_type (other) then
453 Result := area.same_items (other.area, 0, 0, count)
454 else
455 Result := same_string_general (other)
456 end
457 end
458 ensure
459 definition: Result = string.is_equal (other.string)
460 end
461
462 infix "<" (other: like Current): BOOLEAN
463 -- Is string lexicographically lower than `other'?
464 local
465 other_count: INTEGER
466 current_count: INTEGER
467 do
468 if other /= Current then
469 other_count := other.count
470 current_count := count
471 if other_count = current_count then
472 Result := str_strict_cmp (other.area, area, other_count) > 0
473 else
474 if current_count < other_count then
475 Result := str_strict_cmp (other.area, area, current_count) >= 0
476 else
477 Result := str_strict_cmp (other.area, area, other_count) > 0
478 end
479 end
480 end
481 end
482
483 feature -- Status report
484
485 is_string_8: BOOLEAN = False
486 -- <Precursor>
487
488 is_string_32: BOOLEAN = True
489 -- <Precursor>
490
491 is_valid_as_string_8: BOOLEAN is
492 -- <Precursor>
493 local
494 i, nb: INTEGER
495 l_area: like area
496 do
497 from
498 nb := count
499 Result := True
500 l_area := area
501 until
502 i = nb or not Result
503 loop
504 Result := l_area.item (i).code <= {CHARACTER_8}.max_value
505 i := i + 1
506 end
507 end
508
509 has (c: CHARACTER_32): BOOLEAN
510 -- Does string include `c'?
511 local
512 i, nb: INTEGER
513 l_area: like area
514 do
515 nb := count
516 if nb > 0 then
517 from
518 l_area := area
519 until
520 i = nb or else (l_area.item (i) = c)
521 loop
522 i := i + 1
523 end
524 Result := (i < nb)
525 end
526 ensure then
527 false_if_empty: count = 0 implies not Result
528 true_if_first: count > 0 and then item (1) = c implies Result
529 recurse: (count > 0 and then item (1) /= c) implies
530 (Result = substring (2, count).has (c))
531 end
532
533 has_substring (other: READABLE_STRING_32): BOOLEAN
534 -- Does `Current' contain `other'?
535 require
536 other_not_void: other /= Void
537 do
538 if other = Current then
539 Result := True
540 elseif other.count <= count then
541 Result := substring_index (other, 1) > 0
542 end
543 ensure
544 false_if_too_small: count < other.count implies not Result
545 true_if_initial: (count >= other.count and then
546 other.same_string (substring (1, other.count))) implies Result
547 recurse: (count >= other.count and then
548 not other.same_string (substring (1, other.count))) implies
549 (Result = substring (2, count).has_substring (other))
550 end
551
552 starts_with (s: READABLE_STRING_32): BOOLEAN
553 -- Does string begin with `s'?
554 require
555 argument_not_void: s /= Void
556 local
557 i: INTEGER
558 l_area, l_s_area: like area
559 do
560 if Current = s then
561 Result := True
562 else
563 i := s.count
564 if i <= count then
565 from
566 l_area := area
567 l_s_area := s.area
568 Result := True
569 until
570 i = 0 or not Result
571 loop
572 i := i - 1
573 Result := l_area.item (i) = l_s_area.item (i)
574 end
575 end
576 end
577 ensure
578 definition: Result = s.same_string (substring (1, s.count))
579 end
580
581 ends_with (s: READABLE_STRING_32): BOOLEAN
582 -- Does string finish with `s'?
583 require
584 argument_not_void: s /= Void
585 local
586 i, j: INTEGER
587 l_area, l_s_area: like area
588 do
589 if Current = s then
590 Result := True
591 else
592 i := s.count
593 j := count
594 if i <= j then
595 from
596 l_area := area
597 l_s_area := s.area
598 Result := True
599 until
600 i = 0 or not Result
601 loop
602 i := i - 1
603 j := j - 1
604 Result := l_area.item (j) = l_s_area.item (i)
605 end
606 end
607 end
608 ensure
609 definition: Result = s.same_string (substring (count - s.count + 1, count))
610 end
611
612 valid_index (i: INTEGER): BOOLEAN
613 -- Is `i' within the bounds of the string?
614 do
615 Result := (i > 0) and (i <= count)
616 ensure then
617 definition: Result = (1 <= i and i <= count)
618 end
619
620 valid_code (v: NATURAL_32): BOOLEAN
621 -- Is `v' a valid code for a CHARACTER_32?
622 do
623 Result := True
624 end
625
626 is_number_sequence: BOOLEAN
627 -- Does `Current' represent a number sequence?
628 do
629 Result := is_valid_integer_or_natural ({NUMERIC_INFORMATION}.type_no_limitation)
630 ensure
631 syntax_and_range:
632 -- Result is true if and only if the following two
633 -- conditions are satisfied:
634 --
635 -- In the following BNF grammar, the value of
636 -- Current can be produced by "Integer_literal":
637 --
638 -- Integer_literal = [Space] [Sign] Integer [Space]
639 -- Space = " " | " " Space
640 -- Sign = "+" | "-"
641 -- Integer = Digit | Digit Integer
642 -- Digit = "0"|"1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9"
643 end
644
645 is_real_sequence: BOOLEAN
646 -- Does `Current' represent a real sequence?
647 local
648 l_convertor: like ctor_convertor
649 do
650 l_convertor := ctor_convertor
651 l_convertor.parse_string_with_type (Current, {NUMERIC_INFORMATION}.type_no_limitation)
652 Result := l_convertor.is_integral_double
653 ensure
654 syntax_and_range:
655 -- 'Result' is True if and only if the following condition is satisfied:
656 --
657 -- In the following BNF grammar, the value of
658 -- 'Current' can be produced by "Real_literal":
659 --
660 -- Real_literal = Mantissa [Exponent_part]
661 -- Exponent_part = "E" Exponent
662 -- | "e" Exponent
663 -- Exponent = Integer_literal
664 -- Mantissa = Decimal_literal
665 -- Decimal_literal = Integer_literal ["." [Integer]] | "." Integer
666 -- Integer_literal = [Sign] Integer
667 -- Sign = "+" | "-"
668 -- Integer = Digit | Digit Integer
669 -- Digit = "0"|"1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9"
670 end
671
672 is_real: BOOLEAN
673 -- Does `Current' represent a REAL?
674 local
675 l_convertor: like ctor_convertor
676 do
677 l_convertor := ctor_convertor
678 l_convertor.parse_string_with_type (Current, {NUMERIC_INFORMATION}.type_real)
679 Result := l_convertor.is_integral_real
680 ensure
681 syntax_and_range:
682 -- 'Result' is True if and only if the following two
683 -- conditions are satisfied:
684 --
685 -- 1. In the following BNF grammar, the value of
686 -- 'Current' can be produced by "Real_literal":
687 --
688 -- Real_literal = Mantissa [Exponent_part]
689 -- Exponent_part = "E" Exponent
690 -- | "e" Exponent
691 -- Exponent = Integer_literal
692 -- Mantissa = Decimal_literal
693 -- Decimal_literal = Integer_literal ["." [Integer]] | "." Integer
694 -- Integer_literal = [Sign] Integer
695 -- Sign = "+" | "-"
696 -- Integer = Digit | Digit Integer
697 -- Digit = "0"|"1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9"
698 --
699 -- 2. The numerical value represented by 'Current'
700 -- is within the range that can be represented
701 -- by an instance of type REAL.
702 end
703
704 is_double: BOOLEAN
705 -- Does `Current' represent a DOUBLE?
706 local
707 l_convertor: like ctor_convertor
708 do
709 if is_valid_as_string_8 then
710 l_convertor := ctor_convertor
711 l_convertor.parse_string_with_type (Current, {NUMERIC_INFORMATION}.type_double)
712 Result := l_convertor.is_integral_double
713 end
714 ensure
715 syntax_and_range:
716 -- 'Result' is True if and only if the following two
717 -- conditions are satisfied:
718 --
719 -- 1. In the following BNF grammar, the value of
720 -- 'Current' can be produced by "Real_literal":
721 --
722 -- Real_literal = Mantissa [Exponent_part]
723 -- Exponent_part = "E" Exponent
724 -- | "e" Exponent
725 -- Exponent = Integer_literal
726 -- Mantissa = Decimal_literal
727 -- Decimal_literal = Integer_literal ["." [Integer]] | "." Integer
728 -- Integer_literal = [Sign] Integer
729 -- Sign = "+" | "-"
730 -- Integer = Digit | Digit Integer
731 -- Digit = "0"|"1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9"
732 --
733 -- 2. The numerical value represented by 'Current'
734 -- is within the range that can be represented
735 -- by an instance of type DOUBLE.
736 end
737
738 is_boolean: BOOLEAN
739 -- Does `Current' represent a BOOLEAN?
740 local
741 nb: INTEGER
742 l_area: like area
743 do
744 nb := count
745 if nb = 4 then
746 -- Check if this is `true_constant'
747 l_area := area
748 Result := l_area.item (0).lower = 't' and then
749 l_area.item (1).lower = 'r' and then
750 l_area.item (2).lower = 'u' and then
751 l_area.item (3).lower = 'e'
752 elseif nb = 5 then
753 -- Check if this is `false_constant'
754 l_area := area
755 Result := l_area.item (0).lower = 'f' and then
756 l_area.item (1).lower = 'a' and then
757 l_area.item (2).lower = 'l' and then
758 l_area.item (3).lower = 's' and then
759 l_area.item (4).lower = 'e'
760 end
761 ensure
762 is_boolean: Result = (true_constant.same_string (as_lower.as_string_8) or
763 false_constant.same_string (as_lower.as_string_8))
764 end
765
766 is_integer_8: BOOLEAN
767 -- Does `Current' represent an INTEGER_8?
768 do
769 Result := is_valid_integer_or_natural ({NUMERIC_INFORMATION}.type_integer_8)
770 end
771
772 is_integer_16: BOOLEAN
773 -- Does `Current' represent an INTEGER_16?
774 do
775 Result := is_valid_integer_or_natural ({NUMERIC_INFORMATION}.type_integer_16)
776 end
777
778 is_integer, is_integer_32: BOOLEAN
779 -- Does `Current' represent an INTEGER_32?
780 do
781 Result := is_valid_integer_or_natural ({NUMERIC_INFORMATION}.type_integer_32)
782 end
783
784 is_integer_64: BOOLEAN
785 -- Does `Current' represent an INTEGER_64?
786 do
787 Result := is_valid_integer_or_natural ({NUMERIC_INFORMATION}.type_integer_64)
788 end
789
790 is_natural_8: BOOLEAN
791 -- Does `Current' represent a NATURAL_8?
792 do
793 Result := is_valid_integer_or_natural ({NUMERIC_INFORMATION}.type_natural_8)
794 end
795
796 is_natural_16: BOOLEAN
797 -- Does `Current' represent a NATURAL_16?
798
799 do
800 Result := is_valid_integer_or_natural ({NUMERIC_INFORMATION}.type_natural_16)
801 end
802
803 is_natural, is_natural_32: BOOLEAN
804 -- Does `Current' represent a NATURAL_32?
805 do
806 Result := is_valid_integer_or_natural ({NUMERIC_INFORMATION}.type_natural_32)
807 end
808
809 is_natural_64: BOOLEAN
810 -- Does `Current' represent a NATURAL_64?
811 do
812 Result := is_valid_integer_or_natural ({NUMERIC_INFORMATION}.type_natural_64)
813 end
814
815 feature {READABLE_STRING_32} -- Duplication
816
817 copy (other: like Current)
818 -- Reinitialize by copying the characters of `other'.
819 -- (This is also used by `twin'.)
820 local
821 old_area: like area
822 do
823 if other /= Current then
824 old_area := area
825 standard_copy (other)
826 -- Note: <= is needed as all Eiffel string should have an
827 -- extra character to insert null character at the end.
828 if old_area = Void or else old_area.count <= count then
829 area := area.twin
830 else
831 old_area.copy_data (area, 0, 0, count)
832 area := old_area
833 end
834 internal_hash_code := 0
835 end
836 ensure then
837 new_result_count: count = other.count
838 -- same_characters: For every `i' in 1..`count', `item' (`i') = `other'.`item' (`i')
839 end
840
841 feature {NONE} -- Element change
842
843 fill_character (c: CHARACTER_32)
844 -- Fill with `capacity' characters all equal to `c'.
845 local
846 l_cap: like capacity
847 do
848 l_cap := capacity
849 if l_cap /= 0 then
850 area.fill_with (c, 0, l_cap - 1)
851 count := l_cap
852 internal_hash_code := 0
853 end
854 ensure
855 filled: count = capacity
856 same_size: capacity = old capacity
857 -- all_char: For every `i' in 1..`capacity', `item' (`i') = `c'
858 end
859
860 feature -- Element change
861
862 infix "+" (s: READABLE_STRING_32): like Current
863 -- Append a copy of 's' at the end of a copy of Current,
864 -- Then return the Result.
865 require
866 argument_not_void: s /= Void
867 deferred
868 ensure
869 Result_exists: Result /= Void
870 new_count: Result.count = count + s.count
871 initial: elks_checking implies Result.substring (1, count).is_equal (Current)
872 final: elks_checking implies Result.substring (count + 1, count + s.count).same_string (s)
873 end
874
875 feature -- Conversion
876
877 as_lower: like Current
878 -- New object with all letters in lower case.
879 require
880 is_valid_as_string_8: is_valid_as_string_8
881 deferred
882 ensure
883 as_lower_attached: Result /= Void
884 length: Result.count = count
885 anchor: count > 0 implies Result.item (1) = item (1).as_lower
886 recurse: count > 1 implies Result.substring (2, count).
887 is_equal (substring (2, count).as_lower)
888 end
889
890 as_upper: like Current
891 -- New object with all letters in upper case
892 require
893 is_valid_as_string_8: is_valid_as_string_8
894 deferred
895 ensure
896 as_upper_attached: Result /= Void
897 length: Result.count = count
898 anchor: count > 0 implies Result.item (1) = item (1).as_upper
899 recurse: count > 1 implies Result.substring (2, count).
900 is_equal (substring (2, count).as_upper)
901 end
902
903 to_integer_8: INTEGER_8
904 -- 8-bit integer value
905 require
906 is_integer_8: is_integer_8
907 local
908 l_convertor: like ctoi_convertor
909 do
910 l_convertor := ctoi_convertor
911 l_convertor.parse_string_with_type (Current, {NUMERIC_INFORMATION}.type_no_limitation)
912 Result := l_convertor.parsed_integer_8
913 end
914
915 to_integer_16: INTEGER_16
916 -- 16-bit integer value
917 require
918 is_integer_16: is_integer_16
919 local
920 l_convertor: like ctoi_convertor
921 do
922 l_convertor := ctoi_convertor
923 l_convertor.parse_string_with_type (Current, {NUMERIC_INFORMATION}.type_no_limitation)
924 Result := l_convertor.parsed_integer_16
925 end
926
927 to_integer, to_integer_32: INTEGER_32
928 -- 32-bit integer value
929 require
930 is_integer: is_integer_32
931 local
932 l_convertor: like ctoi_convertor
933 do
934 l_convertor := ctoi_convertor
935 l_convertor.parse_string_with_type (Current, {NUMERIC_INFORMATION}.type_no_limitation)
936 Result := l_convertor.parsed_integer
937 end
938
939 to_integer_64: INTEGER_64
940 -- 64-bit integer value
941 require
942 is_integer_64: is_integer_64
943 local
944 l_convertor: like ctoi_convertor
945 do
946 l_convertor := ctoi_convertor
947 l_convertor.parse_string_with_type (Current, {NUMERIC_INFORMATION}.type_no_limitation)
948 Result := l_convertor.parsed_integer_64
949 end
950
951 to_natural_8: NATURAL_8
952 -- 8-bit natural value
953 require
954 is_natural_8: is_natural_8
955 local
956 l_convertor: like ctoi_convertor
957 do
958 l_convertor := ctoi_convertor
959 l_convertor.parse_string_with_type (Current, {NUMERIC_INFORMATION}.type_no_limitation)
960 Result := l_convertor.parsed_natural_8
961 end
962
963 to_natural_16: NATURAL_16
964 -- 16-bit natural value
965 require
966 is_natural_16: is_natural_16
967 local
968 l_convertor: like ctoi_convertor
969 do
970 l_convertor := ctoi_convertor
971 l_convertor.parse_string_with_type (Current, {NUMERIC_INFORMATION}.type_no_limitation)
972 Result := l_convertor.parsed_natural_16
973 end
974
975 to_natural, to_natural_32: NATURAL_32
976 -- 32-bit natural value
977 require
978 is_natural: is_natural_32
979 local
980 l_convertor: like ctoi_convertor
981 do
982 l_convertor := ctoi_convertor
983 l_convertor.parse_string_with_type (Current, {NUMERIC_INFORMATION}.type_no_limitation)
984 Result := l_convertor.parsed_natural_32
985 end
986
987 to_natural_64: NATURAL_64
988 -- 64-bit natural value
989 require
990 is_natural_64: is_natural_64
991 local
992 l_convertor: like ctoi_convertor
993 do
994 l_convertor := ctoi_convertor
995 l_convertor.parse_string_with_type (Current, {NUMERIC_INFORMATION}.type_no_limitation)
996 Result := l_convertor.parsed_natural_64
997 end
998
999 to_real: REAL
1000 -- Real value;
1001 -- for example, when applied to "123.0", will yield 123.0
1002 require
1003 represents_a_real: is_real
1004 do
1005 Result := to_double
1006 end
1007
1008 to_double: DOUBLE
1009 -- "Double" value;
1010 -- for example, when applied to "123.0", will yield 123.0 (double)
1011 require
1012 represents_a_double: is_double
1013 local
1014 l_convertor: like ctor_convertor
1015 do
1016 l_convertor := ctor_convertor
1017 l_convertor.parse_string_with_type (Current, {NUMERIC_INFORMATION}.type_no_limitation)
1018 Result := l_convertor.parsed_double
1019 end
1020
1021 to_boolean: BOOLEAN
1022 -- Boolean value;
1023 -- "True" yields `True', "False" yields `False'
1024 -- (case-insensitive)
1025 require
1026 is_boolean: is_boolean
1027 do
1028 check true_constant.count = 4 end
1029 if count = 4 then
1030 Result := True
1031 end
1032 ensure
1033 to_boolean: (Result = as_lower.same_string (true_constant)) or
1034 (not Result = as_lower.same_string (false_constant))
1035 end
1036
1037 split (a_separator: CHARACTER_32): LIST [like Current]
1038 -- Split on `a_separator'.
1039 local
1040 l_list: ARRAYED_LIST [like Current]
1041 part: like Current
1042 i, j, c: INTEGER
1043 do
1044 c := count
1045 -- Worse case allocation: every character is a separator
1046 create l_list.make (c + 1)
1047 if c > 0 then
1048 from
1049 i := 1
1050 until
1051 i > c
1052 loop
1053 j := index_of (a_separator, i)
1054 if j = 0 then
1055 -- No separator was found, we will
1056 -- simply create a list with a copy of
1057 -- Current in it.
1058 j := c + 1
1059 end
1060 part := substring (i, j - 1)
1061 l_list.extend (part)
1062 i := j + 1
1063 end
1064 if j = c then
1065 check
1066 last_character_is_a_separator: item (j) = a_separator
1067 end
1068 -- A separator was found at the end of the string
1069 l_list.extend (new_string (0))
1070 end
1071 else
1072 -- Extend empty string, since Current is empty.
1073 l_list.extend (new_string (0))
1074 end
1075 Result := l_list
1076 check
1077 l_list.count = occurrences (a_separator) + 1
1078 end
1079 ensure
1080 Result /= Void
1081 end
1082
1083 mirrored: like Current
1084 -- Mirror image of string;
1085 -- Result for "Hello world" is "dlrow olleH".
1086 deferred
1087 ensure
1088 same_count: Result.count = count
1089 -- reversed: For every `i' in 1..`count', `Result'.`item' (`i') = `item' (`count'+1-`i')
1090 end
1091
1092 feature -- Duplication
1093
1094 substring (start_index, end_index: INTEGER): like Current
1095 -- Copy of substring containing all characters at indices
1096 -- between `start_index' and `end_index'
1097 deferred
1098 end
1099
1100 feature -- Output
1101
1102 out: STRING
1103 -- Printable representation
1104 do
1105 create Result.make (count)
1106 Result.append (as_string_8)
1107 ensure then
1108 out_not_void: Result /= Void
1109 same_items: same_type ("") implies same_string (Result)
1110 end
1111
1112 feature {NONE} -- Implementation
1113
1114 new_string (n: INTEGER): like Current
1115 -- New instance of current with space for at least `n' characters.
1116 require
1117 n_non_negative: n >= 0
1118 deferred
1119 ensure
1120 new_string_not_void: Result /= Void
1121 new_string_empty: Result.is_empty
1122 new_string_area_big_enough: Result.capacity >= n
1123 end
1124
1125 feature {NONE} -- Implementation
1126
1127 is_valid_integer_or_natural (type: INTEGER) : BOOLEAN
1128 -- Is `Current' a valid number according to given `type'?
1129 local
1130 l_convertor: like ctoi_convertor
1131 do
1132 if is_valid_as_string_8 then
1133 l_convertor := ctoi_convertor
1134 l_convertor.reset (type)
1135 l_convertor.parse_string_with_type (Current, type)
1136 Result := l_convertor.is_integral_integer
1137 end
1138 end
1139
1140 str_strict_cmp (this, other: like area; nb: INTEGER): INTEGER
1141 -- Compare `this' and `other' strings
1142 -- for the first `nb' characters.
1143 -- 0 if equal, < 0 if `this' < `other',
1144 -- > 0 if `this' > `other'
1145 require
1146 this_not_void: this /= Void or else nb = 0
1147 other_not_void: other /= Void
1148 nb_non_negative: nb >= 0
1149 nb_valid: (this /= Void implies nb <= this.count) and nb <= other.count
1150 local
1151 i, l_current_code, l_other_code: INTEGER
1152 do
1153 from
1154 until
1155 i = nb
1156 loop
1157 l_current_code := this.item (i).code
1158 l_other_code := other.item (i).code
1159 if l_current_code /= l_other_code then
1160 Result := l_current_code - l_other_code
1161 i := nb - 1 -- Jump out of loop
1162 end
1163 i := i + 1
1164 end
1165 end
1166
1167 to_lower_area (a: like area; start_index, end_index: INTEGER)
1168 -- Replace all characters in `a' between `start_index' and `end_index'
1169 -- with their lower version when available.
1170 require
1171 a_not_void: a /= Void
1172 start_index_non_negative: start_index >= 0
1173 start_index_not_too_big: start_index <= end_index + 1
1174 end_index_valid: end_index < a.count
1175 local
1176 i: INTEGER
1177 c: CHARACTER_32
1178 do
1179 from
1180 i := start_index
1181 until
1182 i > end_index
1183 loop
1184 c := a.item (i)
1185 if c.is_character_8 then
1186 a.put (c.lower, i)
1187 end
1188 i := i + 1
1189 end
1190 end
1191
1192 to_upper_area (a: like area; start_index, end_index: INTEGER)
1193 -- Replace all characters in `a' between `start_index' and `end_index'
1194 -- with their upper version when available.
1195 require
1196 a_not_void: a /= Void
1197 start_index_non_negative: start_index >= 0
1198 start_index_not_too_big: start_index <= end_index + 1
1199 end_index_valid: end_index < a.count
1200 local
1201 i: INTEGER
1202 c: CHARACTER_32
1203 do
1204 from
1205 i := start_index
1206 until
1207 i > end_index
1208 loop
1209 c := a.item (i)
1210 if c.is_character_8 then
1211 a.put (c.upper, i)
1212 end
1213 i := i + 1
1214 end
1215 end
1216
1217 mirror_area (a: like area; start_index, end_index: INTEGER)
1218 -- Mirror all characters in `a' between `start_index' and `end_index'.
1219 require
1220 a_not_void: a /= Void
1221 start_index_non_negative: start_index >= 0
1222 start_index_not_too_big: start_index <= end_index + 1
1223 end_index_valid: end_index < a.count
1224 local
1225 c: CHARACTER_32
1226 i, j: INTEGER
1227 do
1228 from
1229 i := end_index
1230 until
1231 i < start_index
1232 loop
1233 c := a.item (i)
1234 a.put (a.item (j), i)
1235 a.put (c, j)
1236 i := i - 1
1237 j := j + 1
1238 end
1239 end
1240
1241 feature {READABLE_STRING_8, READABLE_STRING_32} -- Implementation
1242
1243 area: SPECIAL [CHARACTER_32]
1244 -- Storage for characters
1245
1246 invariant
1247 area_not_void: area /= Void
1248
1249 end

Properties

Name Value
svn:eol-style native
svn:keywords Author Date ID Revision

  ViewVC Help
Powered by ViewVC 1.1.23