note
	description: "[
		Sequences of immutable 32-bit characters, accessible through integer indices
		in a contiguous range.
	]"
	library: "Free implementation of ELKS library"
	status: "See notice at end of class."
	legal: "See notice at end of class."
	date: "$Date: 2020-05-12 20:58:01 +0000 (Tue, 12 May 2020) $"
	revision: "$Revision: 104181 $"

frozen class 
	IMMUTABLE_STRING_32

inherit
	READABLE_STRING_32
		undefine
			Is_immutable
		redefine
			copy,
			area_lower
		end

	IMMUTABLE_STRING_GENERAL
		rename
			ends_with as ends_with_general,
			is_case_insensitive_equal as is_case_insensitive_equal_general,
			plus as plus_general,
			same_caseless_characters as same_caseless_characters_general,
			same_characters as same_characters_general,
			same_string as same_string_general,
			starts_with as starts_with_general
		undefine
			is_equal,
			out,
			copy,
			has,
			index_of,
			last_index_of,
			occurrences
		end

	MISMATCH_CORRECTOR
		undefine
			copy,
			is_equal,
			out
		redefine
			correct_mismatch
		end

create 
	make,
	make_empty,
	make_filled,
	make_from_string,
	make_from_string_general,
	make_from_string_8,
	make_from_string_32,
	make_from_c,
	make_from_c_byte_array,
	make_from_cil,
	make_from_separate


create {IMMUTABLE_STRING_32}
	make_from_area_and_bounds

convert
	to_cil: {SYSTEM_STRING},
	make_from_cil ({SYSTEM_STRING}),
	make_from_string_8 ({READABLE_STRING_8,
		IMMUTABLE_STRING_8,
		STRING_8}),
	make_from_string_32 ({READABLE_STRING_32,
		STRING_32}),
	make_from_string_general ({READABLE_STRING_GENERAL,
		STRING_GENERAL,
		IMMUTABLE_STRING_GENERAL}),
	as_string_32: {STRING_32}

feature {NONE} -- Initialization

	make_from_string_general (s: READABLE_STRING_GENERAL)
			-- Initialize from the characters of s.
		do
			if attached {READABLE_STRING_8} s as s8 then
				make_from_string_8 (s8)
			elseif attached {READABLE_STRING_32} s as s32 then
				make_from_string_32 (s32)
			else
				make_from_string_32 (s.to_string_32)
			end
		end

	make_from_string_8 (s: READABLE_STRING_8)
			-- Initialize from the characters of s.
		require
			s_attached: s /= Void
		local
			a: like area
			s_area: SPECIAL [CHARACTER_8]
			i, j, nb: INTEGER_32
		do
			create a.make_empty (s.count + 1)
			from
				i := 0
				j := s.area_lower
				s_area := s.area
				nb := s.count - 1
			until
				i > nb
			loop
				a.extend (s_area [j].to_character_32)
				i := i + 1
				j := j + 1
			end;
			a.extend ('%U'.to_character_32)
			make_from_area_and_bounds (a, 0, s.count)
		end

	make_from_string_32 (s: READABLE_STRING_32)
			-- Initialize from the characters of s.
		require
			s_attached: s /= Void
		local
			a: like area
		do
			area := s.area
			if same_type (s) then
				area_lower := s.area_lower
			else
				create a.make_empty (s.count + 1);
				a.copy_data (s.area, s.area_lower, 0, s.count + 1)
				area := a
				area_lower := 0
			end
			count := s.count
		end

	make_from_area_and_bounds (a: like area; low, n: like count)
			-- Initialize current with area a with lower bounds low and count n.
		require
			a_not_void: a /= Void
			a_valid_count: (a.count - low) >= count + 1
			low_non_negative: low >= 0
			n_non_negative: n >= 0
		do
			area := a
			area_lower := low
			count := n
		ensure
			area_set: area = a
			area_lower_set: area_lower = low
			count_set: count = n
		end

	make_from_cil (a_system_string: SYSTEM_STRING)
			-- Initialize Current with a_system_string.
		local
			l_count: INTEGER_32
		do
			if a_system_string /= Void then
				l_count := a_system_string.length + Dotnet_convertor.escape_count (a_system_string)
			end
			make (l_count)
			if l_count > 0 then
				Dotnet_convertor.read_system_string_into_area_32 (a_system_string, area)
				count := l_count
			end
		end
	
feature -- Duplication

	copy (other: like Current)
			-- Reinitialize by copying the characters of other.
			-- (This is also used by twin.)
		do
			if other /= Current then
				standard_copy (other)
			end
		ensure then
			new_result_count: count = other.count
		end
	
feature -- Access

	item alias "[]" (i: INTEGER_32): CHARACTER_32
			-- Character at position i
			-- Was declared in IMMUTABLE_STRING_32 as synonym of at.
		do
			Result := area.item (i + area_lower - 1)
		end

	at alias "@" (i: INTEGER_32): CHARACTER_32
			-- Character at position i
			-- Was declared in IMMUTABLE_STRING_32 as synonym of item.
		do
			Result := area.item (i + area_lower - 1)
		end

	code (i: INTEGER_32): NATURAL_32
			-- Numeric code of character at position i
		do
			Result := area.item (i + area_lower - 1).natural_32_code
		end

	item_code (i: INTEGER_32): INTEGER_32
		obsolete "Due to potential truncation it is recommended to use `code (i)' instead. [2017-05-31]"
			-- Numeric code of character at position i
		do
			Result := area.item (i + area_lower - 1).natural_32_code.as_integer_32
		end
	
feature -- Basic operations

	plus alias "+" (s: READABLE_STRING_32): like Current
			-- Concatenation with s.
		local
			a: like area
			n: like count
		do
			n := s.count
			create a.make_empty (count + n + 1);
			a.copy_data (area, area_lower, 0, count);
			a.copy_data (s.area, s.area_lower, count, n + 1)
			create Result.make_from_area_and_bounds (a, 0, count + n)
		end

	plus_general (s: READABLE_STRING_GENERAL): like Current
			-- Concatenation of the current string with s.
		local
			a, a_32: like area
			l_s8_area: SPECIAL [CHARACTER_8]
			i, j, nb: INTEGER_32
		do
			if attached {READABLE_STRING_32} s as l_s32 then
				Result := plus (l_s32)
			else
				create a.make_empty (count + s.count + 1);
				a.copy_data (area, area_lower, 0, count)
				if attached {READABLE_STRING_8} s as l_s8 then
					create a_32.make_empty (l_s8.count + 1)
					from
						i := 0
						j := l_s8.area_lower
						l_s8_area := l_s8.area
						nb := l_s8.count - 1
					until
						i > nb
					loop
						a_32.extend (l_s8_area [j].to_character_32)
						i := i + 1
						j := j + 1
					end;
					a_32.extend ('%U'.to_character_32);
					a.copy_data (a_32, 0, count, nb + 2)
				end
				create Result.make_from_area_and_bounds (a, 0, count + s.count)
			end
		end

	mirrored: like Current
			-- Mirror image of string;
			-- Result for "Hello world" is "dlrow olleH".
		local
			a: like area
		do
			create a.make_empty (count + 1);
			a.copy_data (area, area_lower, 0, count + 1)
			mirror_area (a, 0, count - 1)
			create Result.make_from_area_and_bounds (a, 0, count)
		end

	as_lower: like Current
			-- New object with all letters in lower case.
		local
			a: like area
		do
			create a.make_empty (count + 1);
			a.copy_data (area, area_lower, 0, count + 1)
			to_lower_area (a, 0, count - 1)
			create Result.make_from_area_and_bounds (a, 0, count)
		end

	as_upper: like Current
			-- New object with all letters in upper case
		local
			a: like area
		do
			create a.make_empty (count + 1);
			a.copy_data (area, area_lower, 0, count + 1)
			to_upper_area (a, 0, count - 1)
			create Result.make_from_area_and_bounds (a, 0, count)
		end

	substring (start_index, end_index: INTEGER_32): like Current
			-- Copy of substring containing all characters at indices
			-- between start_index and end_index
		local
			a: like area
			nb: INTEGER_32
		do
			if (1 <= start_index) and (start_index <= end_index) and (end_index <= count) then
				nb := end_index - start_index + 1
				create a.make_empty (nb + 1);
				a.copy_data (area, area_lower + start_index - 1, 0, nb);
				a.extend ('%U'.to_character_32)
				create Result.make_from_area_and_bounds (a, 0, nb)
			else
				Result := Empty_string
			end
		end

	shared_substring (start_index, end_index: INTEGER_32): like Current
		do
			if (1 <= start_index) and (start_index <= end_index) and (end_index <= count) then
				create Result.make_from_area_and_bounds (area, area_lower + start_index - 1, end_index - start_index + 1)
			else
				Result := Empty_string
			end
		end

	linear_representation: LINEAR [CHARACTER_32]
			-- Representation as a linear structure
		local
			temp: ARRAYED_LIST [CHARACTER_32]
			i: INTEGER_32
		do
			create temp.make (capacity)
			from
				i := 1
			until
				i > count
			loop
				temp.extend (item (i))
				i := i + 1
			end
			Result := temp
		end

	is_empty: BOOLEAN
			-- Is structure empty?
		do
			Result := count = 0
		end
	
feature {NONE} -- Implementation

	new_string (n: INTEGER_32): IMMUTABLE_STRING_32
			-- New instance of current with space for at least n characters.
		do
			create Result.make (n)
		end

	Empty_string: IMMUTABLE_STRING_32
			-- Shared empty immutable string
		once
			create Result.make (0)
		ensure
			empty_string_not_void: Result /= Void
			empty_string_empty: Result.is_empty
		end
	
feature {READABLE_STRING_8, READABLE_STRING_32}{READABLE_STRING_8, READABLE_STRING_32, STRING_8_SEARCHER, STRING_32_SEARCHER, HEXADECIMAL_STRING_TO_INTEGER_CONVERTER, STRING_TO_INTEGER_CONVERTOR, STRING_TO_REAL_CONVERTOR, STRING_32_ITERATION_CURSOR} -- Implementation

	area_lower: INTEGER_32
			-- Index where current string starts in area
	
feature -- Transformation

	correct_mismatch
			-- Attempt to correct object mismatch during retrieve using Mismatch_information.
		do
			if area = Void and then attached {like area} Mismatch_information.item ("area") as l_area then
				area := l_area
			end
		end
	
note
	copyright: "Copyright (c) 1984-2020, Eiffel Software and others"
	license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
	source: "[
		Eiffel Software
		5949 Hollister Ave., Goleta, CA 93117 USA
		Telephone 805-685-1006, Fax 805-685-6869
		Website http://www.eiffel.com
		Customer support http://support.eiffel.com
	]"

end -- class IMMUTABLE_STRING_32

Generated by ISE EiffelStudio