Automatic generation produced by ISE Eiffel
indexing description: "[ Sequences of characters, accessible through integer indices in a contiguous range. ]" status: "See notice at end of class" date: "$Date: 2001/11/16 20:34:15 $" revision: "$Revision: 1.1.1.1 $" class STRING inherit INDEXABLE [CHARACTER, INTEGER] redefine copy, is_equal, out, prune_all, changeable_comparison_criterion end RESIZABLE [CHARACTER] redefine copy, is_equal, out, changeable_comparison_criterion end HASHABLE redefine copy, is_equal, out end COMPARABLE redefine copy, is_equal, out end TO_SPECIAL [CHARACTER] redefine copy, is_equal, out end STRING_HANDLER redefine copy, is_equal, out end create make, make_from_string, make_from_c feature {NONE} -- Initialization make (n: INTEGER) is -- Allocate space for at least n characters. require non_negative_size: n >= 0 do count := 0 if n = 0 then area := empty_area else make_area (n + 1) end ensure empty_string: count = 0 area_allocated: capacity >= n end feature -- Initialization remake (n: INTEGER) is obsolete "Use `make' instead" -- Allocate space for at least n characters. require non_negative_size: n >= 0 do count := 0 make (n) ensure empty_string: count = 0 area_allocated: capacity >= n end make_from_string (s: STRING) is -- Initialize from the characters of s. -- (Useful in proper descendants of class STRING, -- to initialize a string-like object from a manifest string.) require string_exists: s /= void do area := s.area count := s.count ensure shared_implementation: shared_with (s) end make_from_c (c_string: POINTER) is -- Initialize from contents of c_string, -- a string created by some external C function require c_string_exists: c_string /= default_pointer local length: INTEGER do length := str_len (c_string) make_area (length + 1); ($area).memory_copy (c_string, length) count := length end from_c (c_string: POINTER) is -- Reset contents of string from contents of c_string, -- a string created by some external C function. require c_string_exists: c_string /= default_pointer local length: INTEGER do length := str_len (c_string) if capacity < length then make_area (length + 1) end; ($area).memory_copy (c_string, length) count := length ensure no_zero_byte: not has ('%U') end from_c_substring (c_string: POINTER; start_pos, end_pos: INTEGER) is -- Reset contents of string from substring of c_string, -- a string created by some external C function. require c_string_exists: c_string /= default_pointer start_position_big_enough: start_pos >= 1 end_position_big_enough: start_pos <= end_pos + 1 local length: INTEGER do length := end_pos - start_pos + 1 if capacity < length then make_area (length + 1) end; ($area).memory_copy (c_string + (start_pos - 1), (end_pos - start_pos + 1)) count := length ensure valid_count: count = end_pos - start_pos + 1 end adapt (s: STRING): like Current is -- Object of a type conforming to the type of s, -- initialized with attributes from s do create Result.make (0) Result.share (s) end feature -- Access item (i: INTEGER): CHARACTER is -- Character at position i -- Was declared in STRING as synonym of @. do Result := area.item (i - 1) end infix "@" (i: INTEGER): CHARACTER is -- Character at position i -- Was declared in STRING as synonym of item. do Result := area.item (i - 1) end item_code (i: INTEGER): INTEGER is -- Numeric code of character at position i require index_small_enough: i <= count index_large_enough: i > 0 do Result := area.item (i - 1).code end hash_code: INTEGER is -- Hash code value do Result := hashcode ($area, count) end False_constant: STRING is "false" -- Constant string "false" True_constant: STRING is "true" -- Constant string "true" shared_with (other: like Current): BOOLEAN is -- Does string share the text of other? do Result := (other /= void) and then (area = other.area) end has (c: CHARACTER): BOOLEAN is -- Does string include c? local counter: INTEGER do if not is_empty then from counter := 1 until counter > count or else (item (counter) = c) loop counter := counter + 1 end Result := (counter <= count) end end index_of (c: CHARACTER; start: INTEGER): INTEGER is -- Position of first occurrence of c at or after start; -- 0 if none. require start_large_enough: start >= 1 start_small_enough: start <= count + 1 local a: like area i, nb: INTEGER do nb := count if start <= nb then from i := start - 1 nb := nb - 1 a := area until i > nb or else a.item (i) = c loop i := i + 1 end if i <= nb then Result := i + 1 end end ensure correct_place: Result > 0 implies item (Result) = c end last_index_of (c: CHARACTER; start_index_from_end: INTEGER): INTEGER is -- Position of last occurence of c. -- 0 if none require start_index_small_enough: start_index_from_end <= count start_index_large_enough: start_index_from_end >= 1 local a: like area i: INTEGER do from i := start_index_from_end - 1 a := area until i < 0 or else a.item (i) = c loop i := i - 1 end if i >= 0 then Result := i + 1 end ensure correct_place: Result > 0 implies item (Result) = c end substring_index (other: STRING; start: INTEGER): INTEGER is -- Position of first occurrence of other at or after start; -- 0 if none. require other_nonvoid: other /= void other_notempty: not other.is_empty start_large_enough: start >= 1 start_small_enough: start <= count local a: ANY do a := other.area Result := str_str ($area, $a, count, other.count, start, 0) ensure correct_place: Result > 0 implies substring (Result, Result + other.count - 1).is_equal (other) end fuzzy_index (other: STRING; start: INTEGER; fuzz: INTEGER): INTEGER is -- Position of first occurrence of other at or after start -- with 0..fuzz mismatches between the string and other. -- 0 if there are no fuzzy matches require other_exists: other /= void other_not_empty: not other.is_empty start_large_enough: start >= 1 start_small_enough: start <= count acceptable_fuzzy: fuzz <= other.count local a: ANY do a := other.area Result := str_str ($area, $a, count, other.count, start, fuzz) end feature -- Measurement capacity: INTEGER is -- Allocated space do Result := area.count - 1 end count: INTEGER -- Actual number of characters making up the string occurrences (c: CHARACTER): INTEGER is -- Number of times c appears in the string local counter, nb: INTEGER a: SPECIAL [CHARACTER] do from counter := 0 nb := count - 1 a := area until counter > nb loop if a.item (counter) = c then Result := Result + 1 end counter := counter + 1 end end index_set: INTEGER_INTERVAL is -- Range of acceptable indexes do create Result.make (1, count) ensure then Result.count = count end feature -- Comparison is_equal (other: like Current): BOOLEAN is -- Is string made of same character sequence as other -- (possibly with a different capacity)? local o_area: like area do if other = Current then Result := True elseif count = other.count then o_area := other.area; Result := str_strict_cmp ($area, $o_area, count) = 0 end end infix "<" (other: like Current): BOOLEAN is -- Is string lexicographically lower than other? local other_area: like area other_count: INTEGER current_count: INTEGER do other_area := other.area other_count := other.count current_count := count if other_count = current_count then Result := str_strict_cmp ($other_area, $area, other_count) > 0 else if current_count < other_count then Result := str_strict_cmp ($other_area, $area, current_count) >= 0 else Result := str_strict_cmp ($other_area, $area, other_count) > 0 end end end feature -- Status report Extendible: BOOLEAN is True -- May new items be added? (Answer: yes.) prunable: BOOLEAN is -- May items be removed? (Answer: yes.) do Result := True end valid_index (i: INTEGER): BOOLEAN is -- Is i within the bounds of the string? do Result := (i > 0) and (i <= count) end Changeable_comparison_criterion: BOOLEAN is False is_integer: BOOLEAN is -- Does Current represent an INTEGER? do Result := str_isi ($area, count) end is_real: BOOLEAN is -- Does Current represent a REAL? do Result := str_isr ($area, count) end is_double: BOOLEAN is -- Does Current represent a DOUBLE? do Result := str_isd ($area, count) end is_boolean: BOOLEAN is -- Does Current represent a BOOLEAN? local s: STRING do s := clone (Current) s.right_adjust s.left_adjust s.to_lower Result := s.is_equal (true_constant) or else s.is_equal (false_constant) end feature -- Element change set (t: like Current; n1, n2: INTEGER) is -- Set current string to substring of t from indices n1 -- to n2, or to empty string if no such substring. require argument_not_void: t /= void local s: STRING do s := t.substring (n1, n2) area := s.area count := s.count ensure is_substring: is_equal (t.substring (n1, n2)) end copy (other: like Current) is -- Reinitialize by copying the characters of other. -- (This is also used by clone.) local old_area: like area do if other /= Current then old_area := area standard_copy (other) if old_area = void or else old_area.count < area.count then area := standard_clone (area) else ($old_area).memory_copy ($area, count) area := old_area end end ensure then new_result_count: count = other.count end subcopy (other: like Current; start_pos, end_pos, index_pos: INTEGER) is -- Copy characters of other within bounds start_pos and -- end_pos to current string starting at index index_pos. require other_not_void: other /= void valid_start_pos: other.valid_index (start_pos) valid_end_pos: other.valid_index (end_pos) valid_bounds: (start_pos <= end_pos) or (start_pos = end_pos + 1) valid_index_pos: valid_index (index_pos) enough_space: (count - index_pos) >= (end_pos - start_pos) local other_area: like area start0, end0, index0: INTEGER do other_area := other.area start0 := start_pos - 1 end0 := end_pos - 1 index0 := index_pos - 1 spsubcopy ($other_area, $area, start0, end0, index0) end replace_substring (s: like Current; start_pos, end_pos: INTEGER) is -- Copy the characters of s to positions -- start_pos .. end_pos. require string_exists: s /= void index_small_enough: end_pos <= count order_respected: start_pos <= end_pos index_large_enough: start_pos > 0 local new_size, substring_size: INTEGER s_area: like area do substring_size := end_pos - start_pos + 1 new_size := s.count + count - substring_size if new_size > capacity then resize (new_size + additional_space) end s_area := s.area str_replace ($area, $s_area, count, s.count, start_pos, end_pos) count := new_size ensure new_count: count = old count + s.count - end_pos + start_pos - 1 end replace_substring_all (original, new: like Current) is -- Replace every occurence of original with new. require original_exists: original /= void new_exists: new /= void original_not_empty: not original.is_empty local change_pos: INTEGER do if not is_empty then from change_pos := substring_index (original, 1) until change_pos = 0 loop replace_substring (new, change_pos, change_pos + original.count - 1) if change_pos + new.count <= count then change_pos := substring_index (original, change_pos + new.count) else change_pos := 0 end end end end replace_blank is -- Replace all current characters with blanks. do replace_character (' ') ensure same_size: (count = old count) and (capacity = old capacity) end fill_blank is -- Fill with capacity blank characters. do fill_character (' ') ensure filled: full same_size: (count = capacity) and (capacity = old capacity) end replace_character (c: CHARACTER) is -- Replace all current characters with characters all equal to c. do ($area).memory_set (c.code, count) ensure same_size: (count = old count) and (capacity = old capacity) end fill_character (c: CHARACTER) is -- Fill with capacity characters all equal to c. do ($area).memory_set (c.code, capacity) count := capacity ensure filled: full same_size: (count = capacity) and (capacity = old capacity) end head (n: INTEGER) is -- Remove all characters except for the first n; -- do nothing if n >= count. require non_negative_argument: n >= 0 do if n < count then count := n end ensure new_count: count = n.min (old count) end tail (n: INTEGER) is -- Remove all characters except for the last n; -- do nothing if n >= count. require non_negative_argument: n >= 0 local i, j: INTEGER do if n < count then from j := (count - n) i := 0 until i = n loop area.put (area.item (j), i) i := i + 1 j := j + 1 end count := n end ensure new_count: count = n.min (old count) end left_adjust is -- Remove leading whitespace. do count := str_left ($area, count) ensure new_count: (count /= 0) implies ((item (1) /= ' ') and (item (1) /= '%T') and (item (1) /= '%R') and (item (1) /= '%N')) end right_adjust is -- Remove trailing whitespace. do count := str_right ($area, count) ensure new_count: (count /= 0) implies ((item (count) /= ' ') and (item (count) /= '%T') and (item (count) /= '%R') and (item (count) /= '%N')) end share (other: like Current) is -- Make current string share the text of other. -- Subsequent changes to the characters of current string -- will also affect other, and conversely. require argument_not_void: other /= void do area := other.area count := other.count ensure shared_count: other.count = count end put (c: CHARACTER; i: INTEGER) is -- Replace character at position i by c. do area.put (c, i - 1) end precede (c: CHARACTER) is -- Add c at front. do if count = capacity then resize (count + additional_space) end str_cprepend ($area, c, count) count := count + 1 ensure new_count: count = old count + 1 end prepend (s: STRING) is -- Prepend a copy of s at front. require argument_not_void: s /= void local new_size: INTEGER s_area: like area do new_size := count + s.count if new_size > capacity then resize (new_size + additional_space) end s_area := s.area str_insert ($area, $s_area, count, s.count, 1) count := new_size ensure new_count: count = old count + s.count end prepend_boolean (b: BOOLEAN) is -- Prepend the string representation of b at front. do prepend (b.out) end prepend_character (c: CHARACTER) is -- Prepend the string representation of c at front. do prepend (c.out) end prepend_double (d: DOUBLE) is -- Prepend the string representation of d at front. do prepend (d.out) end prepend_integer (i: INTEGER) is -- Prepend the string representation of i at front. do prepend (i.out) end prepend_real (r: REAL) is -- Prepend the string representation of r at front. do prepend (r.out) end prepend_string (s: STRING) is -- Prepend a copy of s, if not void, at front. do if s /= void then prepend (s) end end append (s: STRING) is -- Append a copy of s at end. require argument_not_void: s /= void local new_size: INTEGER s_area: like area do new_size := s.count + count if new_size > capacity then resize (new_size + additional_space) end s_area := s.area; ($area + count).memory_copy ($s_area, s.count) count := new_size ensure new_count: count = old count + old s.count end infi