note
	description: "Read and write access to an internal array of pixels."
	author: "Louis Marchand"
	date: "Tue, 26 Jan 2016 19:34:13 +0000"
	revision: "2.1"

class 
	GAME_PIXEL_READER_WRITER

create 
	make_from_pointer,
	make

feature {NONE} -- Initialization

	default_create
			-- Process instances of classes with no creation clause.
			-- (Default: do nothing.)
			-- (from ANY)
		do
		end

	make_from_pointer (a_item: POINTER; a_format: GAME_PIXEL_FORMAT_READABLE; a_width, a_height, a_pitch: INTEGER_32)
			-- Initialization for Current using a_item as item, a_format as pixel_format,
			-- a_width as width, a_height as height and a_pitch as pitch
			-- (from GAME_PIXEL_BUFFER)
		require -- from GAME_PIXEL_BUFFER
			exists: not a_item.is_default_pointer
		local
			l_mask_information: TUPLE [position: INTEGER_32; bit_count: INTEGER_32]
			l_masks: TUPLE [red: NATURAL_32; green: NATURAL_32; blue: NATURAL_32; alpha: NATURAL_32]
		do
			create internal_item.share_from_pointer (a_item, a_height * a_pitch)
			width := a_width
			height := a_height
			pitch := a_pitch
			pixel_format := a_format
			bytes_per_pixel := pixel_format.bytes_per_pixel
			is_valid := True
		ensure -- from GAME_PIXEL_BUFFER
			item_not_null: not item.is_default_pointer
			item_set: item ~ a_item
			item_valid: is_valid
		end
	
feature -- Access

	generating_type: TYPE [detachable GAME_PIXEL_READER_WRITER]
			-- Type of current object
			-- (type of which it is a direct instance)
			-- (from ANY)
		external
			"built_in"
		ensure -- from ANY
			generating_type_not_void: Result /= Void
		end

	generator: STRING_8
			-- Name of current object's generating class
			-- (base class of the type of which it is a direct instance)
			-- (from ANY)
		external
			"built_in"
		ensure -- from ANY
			generator_not_void: Result /= Void
			generator_not_empty: not Result.is_empty
		end

	has_error: BOOLEAN
			-- Is the library has generate an error
			-- (from GAME_ERROR_MANAGER)

	height: INTEGER_32
			-- Dimensions of the pixel array
			-- (from GAME_PIXEL_BUFFER)

	index (a_line, a_column: INTEGER_32): NATURAL_8 assign set_index
			-- Get the index of the indexed pixel at line a_line and column a_column
		require -- from GAME_PIXEL_READER
			is_item_valid: is_valid
			is_line_valid: a_line >= 1 and then a_line <= height
			is_column_valid: a_line >= 1 and then a_column <= width
			indexed: pixel_format.is_indexed
			bits_per_pixel_valid: pixel_format.bits_per_pixel = 8
		do
			Result := Precursor (a_line, a_column)
		end

	item: POINTER
			-- Memory pointer to the pixels array
			-- (from GAME_PIXEL_BUFFER)
		require -- from GAME_PIXEL_BUFFER
			pointer_valid: is_valid
		do
			Result := internal_item.item
		end

	last_error: READABLE_STRING_GENERAL
			-- The last error generate by the library
			-- (from GAME_SDL_ANY)
		local
			l_string: C_STRING
		do
			if is_manual_error then
				Result := Precursor {GAME_ERROR_MANAGER}
			else
				create l_string.make_by_pointer ({GAME_SDL_EXTERNAL}.sdl_geterror)
				Result := l_string.string
			end
		end

	pitch: INTEGER_32
			-- Length of a row of pixels in bytes
			-- (from GAME_PIXEL_BUFFER)

	pixel (a_line, a_column: INTEGER_32): GAME_COLOR_READABLE assign set_pixel
			-- Get the color of the pixel at line a_line and column a_column
		require -- from GAME_PIXEL_READER
			is_item_valid: is_valid
			is_line_valid: a_line >= 1 and then a_line <= height
			is_column_valid: a_line >= 1 and then a_column <= width
			not_indexed: not pixel_format.is_indexed
		do
			Result := Precursor (a_line, a_column)
		end

	pixel_format: GAME_PIXEL_FORMAT_READABLE
			-- (from GAME_PIXEL_BUFFER)

	set_index (a_index: NATURAL_8; a_line, a_column: INTEGER_32)
			-- Set the index of the indexed pixel at line a_line and column a_column to a_index
			-- (from GAME_PIXEL_WRITER)
		require -- from GAME_PIXEL_WRITER
			is_item_valid: is_valid
			is_line_valid: a_line >= 1 and then a_line <= height
			is_column_valid: a_line >= 1 and then a_column <= width
			indexed: pixel_format.is_indexed
			bits_per_pixel_valid: pixel_format.bits_per_pixel = 8
		do
			internal_item.put_natural_8 (a_index, (a_line - 1) * pitch + (a_column - 1))
		end

	set_pixel (a_color: GAME_COLOR_READABLE; a_line, a_column: INTEGER_32)
			-- Set the color of the pixel at line a_line and column a_column to a_color
			-- (from GAME_PIXEL_WRITER)
		require -- from GAME_PIXEL_WRITER
			is_item_valid: is_valid
			is_line_valid: a_line >= 1 and then a_line <= height
			is_column_valid: a_line >= 1 and then a_column <= width
			not_indexed: not pixel_format.is_indexed
		local
			l_color_index: NATURAL_32
			l_red, l_green, l_blue, l_alpha: NATURAL_8
			l_position: INTEGER_32
		do
			l_position := (a_line - 1) * pitch + (a_column - 1) * bytes_per_pixel
			l_color_index := {GAME_SDL_EXTERNAL}.sdl_maprgba (pixel_format.item, a_color.red, a_color.green, a_color.blue, a_color.alpha)
			if bytes_per_pixel = 1 then
				internal_item.put_natural_8 (l_color_index.to_natural_8, l_position)
			elseif bytes_per_pixel = 2 then
				internal_item.put_natural_16 (l_color_index.to_natural_16, l_position)
			elseif bytes_per_pixel = 3 then
				if Is_little_endian then
					internal_item.put_natural_8 (l_color_index.bit_and (255).to_natural_8, l_position);
					internal_item.put_natural_8 (l_color_index.bit_shift_right (8).bit_and (255).to_natural_8, l_position + 1);
					internal_item.put_natural_8 (l_color_index.bit_shift_right (16).bit_and (255).to_natural_8, l_position + 2)
				else
					internal_item.put_natural_8 (l_color_index.bit_shift_right (16).bit_and (255).to_natural_8, l_position);
					internal_item.put_natural_8 (l_color_index.bit_shift_right (8).bit_and (255).to_natural_8, l_position + 1);
					internal_item.put_natural_8 (l_color_index.bit_and (255).to_natural_8, l_position + 2)
				end
			elseif bytes_per_pixel = 4 then
				internal_item.put_natural_32 (l_color_index, l_position)
			end
		end

	width: INTEGER_32
			-- Dimensions of the pixel array
			-- (from GAME_PIXEL_BUFFER)
	
feature -- Comparison

	frozen deep_equal (a: detachable ANY; b: like arg #1): BOOLEAN
			-- Are a and b either both void
			-- or attached to isomorphic object structures?
			-- (from ANY)
		do
			if a = Void then
				Result := b = Void
			else
				Result := b /= Void and then a.is_deep_equal (b)
			end
		ensure -- from ANY
			instance_free: class
			shallow_implies_deep: standard_equal (a, b) implies Result
			both_or_none_void: (a = Void) implies (Result = (b = Void))
			same_type: (Result and (a /= Void)) implies (b /= Void and then a.same_type (b))
			symmetric: Result implies deep_equal (b, a)
		end

	frozen equal (a: detachable ANY; b: like arg #1): BOOLEAN
			-- Are a and b either both void or attached
			-- to objects considered equal?
			-- (from ANY)
		do
			if a = Void then
				Result := b = Void
			else
				Result := b /= Void and then a.is_equal (b)
			end
		ensure -- from ANY
			instance_free: class
			definition: Result = (a = Void and b = Void) or else ((a /= Void and b /= Void) and then a.is_equal (b))
		end

	frozen is_deep_equal alias "≡≡≡" (other: GAME_PIXEL_READER_WRITER): BOOLEAN
			-- Are Current and other attached to isomorphic object structures?
			-- (from ANY)
		require -- from ANY
			other_not_void: other /= Void
		external
			"built_in"
		ensure -- from ANY
			shallow_implies_deep: standard_is_equal (other) implies Result
			same_type: Result implies same_type (other)
			symmetric: Result implies other.is_deep_equal (Current)
		end

	is_equal (other: GAME_PIXEL_READER_WRITER): BOOLEAN
			-- Is other attached to an object considered
			-- equal to current object?
			-- (from ANY)
		require -- from ANY
			other_not_void: other /= Void
		external
			"built_in"
		ensure -- from ANY
			symmetric: Result implies other ~ Current
			consistent: standard_is_equal (other) implies Result
		end

	frozen standard_equal (a: detachable ANY; b: like arg #1): BOOLEAN
			-- Are a and b either both void or attached to
			-- field-by-field identical objects of the same type?
			-- Always uses default object comparison criterion.
			-- (from ANY)
		do
			if a = Void then
				Result := b = Void
			else
				Result := b /= Void and then a.standard_is_equal (b)
			end
		ensure -- from ANY
			instance_free: class
			definition: Result = (a = Void and b = Void) or else ((a /= Void and b /= Void) and then a.standard_is_equal (b))
		end

	frozen standard_is_equal alias "" (other: GAME_PIXEL_READER_WRITER): BOOLEAN
			-- Is other attached to an object of the same type
			-- as current object, and field-by-field identical to it?
			-- (from ANY)
		require -- from ANY
			other_not_void: other /= Void
		external
			"built_in"
		ensure -- from ANY
			same_type: Result implies same_type (other)
			symmetric: Result implies other.standard_is_equal (Current)
		end
	
feature -- Status report

	conforms_to (other: ANY): BOOLEAN
			-- Does type of current object conform to type
			-- of other (as per Eiffel: The Language, chapter 13)?
			-- (from ANY)
		require -- from ANY
			other_not_void: other /= Void
		external
			"built_in"
		end

	is_valid: BOOLEAN
			-- item can be accessed
			-- (from GAME_PIXEL_BUFFER)

	same_type (other: ANY): BOOLEAN
			-- Is type of current object identical to type of other?
			-- (from ANY)
		require -- from ANY
			other_not_void: other /= Void
		external
			"built_in"
		ensure -- from ANY
			definition: Result = (conforms_to (other) and other.conforms_to (Current))
		end
	
feature -- Duplication

	frozen clone (other: detachable ANY): like other
		obsolete "Use `twin' instead. [2017-05-31]"
			-- Void if other is void; otherwise new object
			-- equal to other
			--
			-- For non-void other, clone calls copy;
			-- to change copying/cloning semantics, redefine copy.
			-- (from ANY)
		do
			if other /= Void then
				Result := other.twin
			end
		ensure -- from ANY
			instance_free: class
			equal: Result ~ other
		end

	copy (other: GAME_PIXEL_READER_WRITER)
			-- Update current object using fields of object attached
			-- to other, so as to yield equal objects.
			-- (from ANY)
		require -- from ANY
			other_not_void: other /= Void
			type_identity: same_type (other)
		external
			"built_in"
		ensure -- from ANY
			is_equal: Current ~ other
		end

	frozen deep_clone (other: detachable ANY): like other
		obsolete "Use `deep_twin' instead. [2017-05-31]"
			-- Void if other is void: otherwise, new object structure
			-- recursively duplicated from the one attached to other
			-- (from ANY)
		do
			if other /= Void then
				Result := other.deep_twin
			end
		ensure -- from ANY
			instance_free: class
			deep_equal: deep_equal (other, Result)
		end

	frozen deep_copy (other: GAME_PIXEL_READER_WRITER)
			-- Effect equivalent to that of:
			--		copy (other . deep_twin)
			-- (from ANY)
		require -- from ANY
			other_not_void: other /= Void
		do
			copy (other.deep_twin)
		ensure -- from ANY
			deep_equal: deep_equal (Current, other)
		end

	frozen deep_twin: GAME_PIXEL_READER_WRITER
			-- New object structure recursively duplicated from Current.
			-- (from ANY)
		external
			"built_in"
		ensure -- from ANY
			deep_twin_not_void: Result /= Void
			deep_equal: deep_equal (Current, Result)
		end

	frozen standard_clone (other: detachable ANY): like other
		obsolete "Use `standard_twin' instead. [2017-05-31]"
			-- Void if other is void; otherwise new object
			-- field-by-field identical to other.
			-- Always uses default copying semantics.
			-- (from ANY)
		do
			if other /= Void then
				Result := other.standard_twin
			end
		ensure -- from ANY
			instance_free: class
			equal: standard_equal (Result, other)
		end

	frozen standard_copy (other: GAME_PIXEL_READER_WRITER)
			-- Copy every field of other onto corresponding field
			-- of current object.
			-- (from ANY)
		require -- from ANY
			other_not_void: other /= Void
			type_identity: same_type (other)
		external
			"built_in"
		ensure -- from ANY
			is_standard_equal: standard_is_equal (other)
		end

	frozen standard_twin: GAME_PIXEL_READER_WRITER
			-- New object field-by-field identical to other.
			-- Always uses default copying semantics.
			-- (from ANY)
		external
			"built_in"
		ensure -- from ANY
			standard_twin_not_void: Result /= Void
			equal: standard_equal (Result, Current)
		end

	frozen twin: GAME_PIXEL_READER_WRITER
			-- New object equal to Current
			-- twin calls copy; to change copying/twinning semantics, redefine copy.
			-- (from ANY)
		external
			"built_in"
		ensure -- from ANY
			twin_not_void: Result /= Void
			is_equal: Result ~ Current
		end
	
feature -- Basic operations

	frozen as_attached: attached GAME_PIXEL_READER_WRITER
		obsolete "Remove calls to this feature. [2017-05-31]"
			-- Attached version of Current.
			-- (Can be used during transitional period to convert
			-- non-void-safe classes to void-safe ones.)
			-- (from ANY)
		do
			Result := Current
		end

	frozen default: detachable GAME_PIXEL_READER_WRITER
			-- Default value of object's type
			-- (from ANY)
		do
		end

	frozen default_pointer: POINTER
			-- Default value of type POINTER
			-- (Avoid the need to write p.default for
			-- some p of type POINTER.)
			-- (from ANY)
		do
		ensure -- from ANY
			instance_free: class
		end

	default_rescue
			-- Process exception for routines with no Rescue clause.
			-- (Default: do nothing.)
			-- (from ANY)
		do
		end

	frozen do_nothing
			-- Execute a null action.
			-- (from ANY)
		do
		ensure -- from ANY
			instance_free: class
		end
	
feature {NONE} -- Implementation

	bytes_per_pixel: INTEGER_32
			-- (from GAME_PIXEL_BUFFER)

	clear_error
			-- Remove error pending in Current
			-- (from GAME_SDL_ANY)
		require -- from  GAME_ERROR_MANAGER
			True
		do
			{GAME_SDL_EXTERNAL}.sdl_clearerror
			Precursor {GAME_ERROR_MANAGER}
			is_manual_error := False
		ensure -- from GAME_ERROR_MANAGER
			no_error: not has_error
		ensure then -- from GAME_SDL_ANY
			no_error: not is_manual_error
		end

	disable_print_on_error
			-- Desactive the print_on_error functionnality.
			-- (from GAME_ERROR_MANAGER)
		do
			Print_on_error_internal.put (False)
		end

	enable_print_on_error
			-- Active the print_on_error functionnality.
			-- (from GAME_ERROR_MANAGER)
		do
			Print_on_error_internal.put (True)
		end

	internal_item: MANAGED_POINTER
			-- Memory pointer to the pixels array
			-- (from GAME_PIXEL_BUFFER)

	is_manual_error: BOOLEAN
			-- Is the current pending error is a manual error (using manual_error as message)
			-- (from GAME_SDL_ANY)

	make (a_format: GAME_PIXEL_FORMAT_READABLE; a_width, a_height: INTEGER_32)
			-- Initialization for Current allocating item using a_format as pixel_format,
			-- a_width as width and a_height as height
		do
			bytes_per_pixel := a_format.bytes_per_pixel
			pixel_format := a_format
			width := a_width
			height := a_height
			pitch := a_width * bytes_per_pixel
			create internal_item.make (a_width * a_height * bytes_per_pixel)
			is_valid := not internal_item.item.is_default_pointer
			if not is_valid then
				put_manual_error ("No more memory", "Cannot allocate a pixel buffer")
			end
		ensure
			is_created: not has_error implies not item.is_default_pointer
		end

	manage_error_boolean (a_boolean: BOOLEAN; a_message: READABLE_STRING_GENERAL)
			-- Create an error if a_boolean is false.
			-- If there is an error, append a_message to the error message
			-- on the SDL2 library
			-- (from GAME_SDL_ANY)
		do
			if not a_boolean then
				if Print_on_error_internal.item then
					Io.Error.put_string (a_message.to_string_8 + "%N");
					Io.Error.put_string (last_error.to_string_8 + "%N")
				end
				has_error := True
			end
		ensure -- from GAME_SDL_ANY
				not a_boolean implies has_error
		end

	manage_error_code (a_error_code: INTEGER_32; a_message: READABLE_STRING_GENERAL)
			-- If needed create an error depending of the error code a_code.
			-- If there is an error, append a_message to the error message
			-- on the SDL2 library
			-- (from GAME_SDL_ANY)
		do
			if a_error_code < 0 then
				if Print_on_error_internal.item then
					Io.Error.put_string (a_message.to_string_8 + "%N");
					Io.Error.put_string (last_error.to_string_8 + "%N")
				end
				has_error := True
			end
		end

	manage_error_pointer (a_pointer: POINTER; a_message: READABLE_STRING_GENERAL)
			-- Create an error if a_pointer is not valid.
			-- If there is an error, append a_message to the error message
			-- on the SDL2 library
			-- (from GAME_SDL_ANY)
		do
			if a_pointer.is_default_pointer then
				if Print_on_error_internal.item then
					Io.Error.put_string (a_message.to_string_8 + "%N");
					Io.Error.put_string (last_error.to_string_8 + "%N")
				end
				has_error := True
			end
		ensure -- from GAME_SDL_ANY
				a_pointer.is_default_pointer implies has_error
		end

	manual_error: detachable READABLE_STRING_GENERAL
			-- The specific message for the last error
			-- (from GAME_ERROR_MANAGER)

	print_on_error: BOOLEAN
			-- When an error occured, the library will print
			-- informations about the error on the error console
			-- output (default is True).
			-- (from GAME_ERROR_MANAGER)
		do
			Result := Print_on_error_internal.item
		end

	Print_on_error_internal: CELL [BOOLEAN]
			-- True when an error occured,
			-- The library will print it right away.
			-- (from GAME_ERROR_MANAGER)
		once ("PROCESS")
			create Result.put (True)
		end

	put_manual_error (a_general_message, a_specific_error: READABLE_STRING_GENERAL)
			-- Create an error using a_general_error for the debug information
			-- and a_specific_error for the lasting information
			-- (from GAME_SDL_ANY)
		do
			is_manual_error := True
			Precursor {GAME_ERROR_MANAGER} (a_general_message, a_specific_error)
		ensure -- from GAME_ERROR_MANAGER
				has_error
		end

	set_print_on_error (a_value: BOOLEAN)
			-- Assign to print_on_error the value of a_value
			-- (from GAME_ERROR_MANAGER)
		do
			if a_value then
				enable_print_on_error
			else
				disable_print_on_error
			end
		ensure -- from GAME_ERROR_MANAGER
			is_assign: print_on_error ~ a_value
		end
	
feature {GAME_SURFACE} -- Implementation

	close
			-- Put item as not valid.
			-- (from GAME_PIXEL_BUFFER)
		do
			is_valid := False
		end
	
feature -- Access bits size

	boolean_bits: INTEGER_32
			-- Number of bits in a value of type BOOLEAN
			-- (from PLATFORM)
		do
			Result := boolean_bytes * 8
		ensure -- from PLATFORM
			instance_free: class
		end

	Character_32_bits: INTEGER_32 = 32
			-- Number of bits in a value of type CHARACTER_32
			-- (from PLATFORM)

	Character_8_bits: INTEGER_32 = 8
			-- Number of bits in a value of type CHARACTER_8
			-- (from PLATFORM)

	Integer_16_bits: INTEGER_32 = 16
			-- Number of bits in a value of type INTEGER_16
			-- (from PLATFORM)

	Integer_32_bits: INTEGER_32 = 32
			-- Number of bits in a value of type INTEGER_32
			-- (from PLATFORM)

	Integer_64_bits: INTEGER_32 = 64
			-- Number of bits in a value of type INTEGER_64
			-- (from PLATFORM)

	Integer_8_bits: INTEGER_32 = 8
			-- Number of bits in a value of type INTEGER_8
			-- (from PLATFORM)

	Natural_16_bits: INTEGER_32 = 16
			-- Number of bits in a value of type NATURAL_16
			-- (from PLATFORM)

	Natural_32_bits: INTEGER_32 = 32
			-- Number of bits in a value of type NATURAL_32
			-- (from PLATFORM)

	Natural_64_bits: INTEGER_32 = 64
			-- Number of bits in a value of type NATURAL_64
			-- (from PLATFORM)

	Natural_8_bits: INTEGER_32 = 8
			-- Number of bits in a value of type NATURAL_8
			-- (from PLATFORM)

	pointer_bits: INTEGER_32
			-- Number of bits in a value of type POINTER
			-- (from PLATFORM)
		do
			Result := pointer_bytes * 8
		ensure -- from PLATFORM
			instance_free: class
		end

	Real_32_bits: INTEGER_32 = 32
			-- Number of bits in a value of type REAL_32
			-- (from PLATFORM)

	Real_64_bits: INTEGER_32 = 64
			-- Number of bits in a value of type REAL_64
			-- (from PLATFORM)
	
feature -- Access bytes size

	boolean_bytes: INTEGER_32
			-- Number of bytes in a value of type BOOLEAN
			-- (from PLATFORM)
		external
			"built_in static"
		ensure -- from PLATFORM
			instance_free: class
		end

	Character_32_bytes: INTEGER_32 = 4
			-- Number of bytes in a value of type CHARACTER_32
			-- (from PLATFORM)

	Character_8_bytes: INTEGER_32 = 1
			-- Number of bytes in a value of type CHARACTER_8
			-- (from PLATFORM)

	Integer_16_bytes: INTEGER_32 = 2
			-- Number of bytes in a value of type INTEGER_16
			-- (from PLATFORM)

	Integer_32_bytes: INTEGER_32 = 4
			-- Number of bytes in a value of type INTEGER_32
			-- (from PLATFORM)

	Integer_64_bytes: INTEGER_32 = 8
			-- Number of bytes in a value of type INTEGER_64
			-- (from PLATFORM)

	Integer_8_bytes: INTEGER_32 = 1
			-- Number of bytes in a value of type INTEGER_8
			-- (from PLATFORM)

	Natural_16_bytes: INTEGER_32 = 2
			-- Number of bytes in a value of type NATURAL_16
			-- (from PLATFORM)

	Natural_32_bytes: INTEGER_32 = 4
			-- Number of bytes in a value of type NATURAL_32
			-- (from PLATFORM)

	Natural_64_bytes: INTEGER_32 = 8
			-- Number of bytes in a value of type NATURAL_64
			-- (from PLATFORM)

	Natural_8_bytes: INTEGER_32 = 1
			-- Number of bytes in a value of type NATURAL_8
			-- (from PLATFORM)

	pointer_bytes: INTEGER_32
			-- Number of bytes in a value of type POINTER
			-- (from PLATFORM)
		external
			"built_in static"
		ensure -- from PLATFORM
			instance_free: class
		end

	Real_32_bytes: INTEGER_32 = 4
			-- Number of bytes in a value of type REAL_32
			-- (from PLATFORM)

	Real_64_bytes: INTEGER_32 = 8
			-- Number of bytes in a value of type REAL_64
			-- (from PLATFORM)
	
feature -- Obsoletes

	character_bits: INTEGER_32
		obsolete "Use `character_8_bits' instead. [2017-05-31]"
			-- Number of bits in a value of type CHARACTER_8
			-- (from PLATFORM)
		do
			Result := 8
		ensure -- from PLATFORM
			instance_free: class
		end

	character_bytes: INTEGER_32
		obsolete "Use `character_8_bytes' instead. [2017-05-31]"
			-- Number of bytes in a value of type CHARACTER_8
			-- (from PLATFORM)
		external
			"built_in static"
		ensure -- from PLATFORM
			instance_free: class
		end

	double_bits: INTEGER_32
		obsolete "Use `real_64_bits' instead. [2017-05-31]"
			-- Number of bits in a value of type REAL_64
			-- (from PLATFORM)
		do
			Result := 64
		ensure -- from PLATFORM
			instance_free: class
		end

	double_bytes: INTEGER_32
		obsolete "Use `real_64_bytes' instead. [2017-05-31]"
			-- Number of bytes in a value of type REAL_64
			-- (from PLATFORM)
		external
			"built_in static"
		ensure -- from PLATFORM
			instance_free: class
		end

	integer_bits: INTEGER_32
		obsolete "Use `integer_32_bits' instead. [2017-05-31]"
			-- Number of bits in a value of type INTEGER_32
			-- (from PLATFORM)
		do
			Result := 32
		ensure -- from PLATFORM
			instance_free: class
		end

	integer_bytes: INTEGER_32
		obsolete "Use `integer_32_bytes' instead. [2017-05-31]"
			-- Number of bytes in a value of type INTEGER_32
			-- (from PLATFORM)
		external
			"built_in static"
		ensure -- from PLATFORM
			instance_free: class
		end

	maximum_character_code: INTEGER_32
		obsolete "Use `{CHARACTER_8}.max_value' instead. [2017-05-31]"
			-- Largest supported code for CHARACTER_8 values
			-- (from PLATFORM)
		do
			Result := {CHARACTER_8}.max_value
		ensure -- from PLATFORM
			instance_free: class
			meaningful: Result >= 127
		end

	maximum_integer: INTEGER_32
		obsolete "Use `{INTEGER}.max_value' instead. [2017-05-31]"
			-- Largest supported value of type INTEGER_32
			-- (from PLATFORM)
		do
			Result := {INTEGER_32}.max_value
		ensure -- from PLATFORM
			instance_free: class
			meaningful: Result >= 0
		end

	minimum_character_code: INTEGER_32
		obsolete "Use `{CHARACTER_8}.min_value' instead. [2017-05-31]"
			-- Smallest supported code for CHARACTER_8 values
			-- (from PLATFORM)
		do
			Result := {CHARACTER_8}.min_value
		ensure -- from PLATFORM
			instance_free: class
			meaningful: Result <= 0
		end

	minimum_integer: INTEGER_32
		obsolete "Use `{INTEGER}.min_value' instead. [2017-05-31]"
			-- Smallest supported value of type INTEGER_32
			-- (from PLATFORM)
		do
			Result := {INTEGER_32}.min_value
		ensure -- from PLATFORM
			instance_free: class
			meaningful: Result <= 0
		end

	real_bits: INTEGER_32
		obsolete "Use `real_32_bits' instead. [2017-05-31]"
			-- Number of bits in a value of type REAL_32
			-- (from PLATFORM)
		do
			Result := 32
		ensure -- from PLATFORM
			instance_free: class
		end

	real_bytes: INTEGER_32
		obsolete "Use `real_32_bytes' instead. [2017-05-31]"
			-- Number of bytes in a value of type REAL_32
			-- (from PLATFORM)
		external
			"built_in static"
		ensure -- from PLATFORM
			instance_free: class
		end

	wide_character_bytes: INTEGER_32
		obsolete "Use `character_32_bytes' instead. [2017-05-31]"
			-- Number of bytes in a value of type CHARACTER_32
			-- (from PLATFORM)
		external
			"built_in static"
		ensure -- from PLATFORM
			instance_free: class
		end
	
feature -- Output

	Io: STD_FILES
			-- Handle to standard file setup
			-- (from ANY)
		once
			create Result;
			Result.set_output_default
		ensure -- from ANY
			instance_free: class
			io_not_void: Result /= Void
		end

	out: STRING_8
			-- New string containing terse printable representation
			-- of current object
			-- (from ANY)
		do
			Result := tagged_out
		ensure -- from ANY
			out_not_void: Result /= Void
		end

	print (o: detachable ANY)
			-- Write terse external representation of o
			-- on standard output.
			-- (from ANY)
		local
			s: READABLE_STRING_8
		do
			if attached o then
				s := o.out
				if attached {READABLE_STRING_32} s as s32 then
					Io.put_string_32 (s32)
				elseif attached {READABLE_STRING_8} s as s8 then
					Io.put_string (s8)
				else
					Io.put_string_32 (s.as_string_32)
				end
			end
		ensure -- from ANY
			instance_free: class
		end

	frozen tagged_out: STRING_8
			-- New string containing terse printable representation
			-- of current object
			-- (from ANY)
		external
			"built_in"
		ensure -- from ANY
			tagged_out_not_void: Result /= Void
		end
	
feature -- Platform

	is_64_bits: BOOLEAN
			-- Is the current process runing in 64-bit mode
			-- (from PLATFORM)
		external
			"built_in static"
		ensure -- from PLATFORM
			instance_free: class
		end

	is_dotnet: BOOLEAN
			-- Are we targetting .NET?
			-- (from PLATFORM)
		external
			"built_in static"
		ensure -- from PLATFORM
			instance_free: class
		end

	Is_little_endian: BOOLEAN
			-- Is current platform a little endian one?
			-- (from PLATFORM)
		local
			l_nat16: NATURAL_16
			l_nat8: NATURAL_8
			l_first: NATURAL_8
		once
			l_nat16 := 17185
			l_nat8 := 33;
			($l_first).memory_copy ($l_nat16.to_pointer, 1)
			Result := l_first = l_nat8
		ensure -- from PLATFORM
			instance_free: class
		end

	is_mac: BOOLEAN
			-- Are we running on Mac OS?
			-- (from PLATFORM)
		external
			"built_in static"
		ensure -- from PLATFORM
			instance_free: class
		end

	is_scoop_capable: BOOLEAN
			-- Is current platform capable of SCOOP?
			-- (from PLATFORM)
		external
			"built_in static"
		ensure -- from PLATFORM
			instance_free: class
		end

	is_thread_capable: BOOLEAN
			-- Is current platform capable of multi-threading?
			-- (from PLATFORM)
		external
			"built_in static"
		ensure -- from PLATFORM
			instance_free: class
		end

	is_unix: BOOLEAN
			-- Are we running on a Unix like platform?
			-- (from PLATFORM)
		external
			"built_in static"
		ensure -- from PLATFORM
			instance_free: class
		end

	is_vms: BOOLEAN
			-- Are we running on VMS?
			-- (from PLATFORM)
		external
			"built_in static"
		ensure -- from PLATFORM
			instance_free: class
		end

	is_vxworks: BOOLEAN
			-- Are we running on VxWorks?
			-- (from PLATFORM)
		external
			"built_in static"
		ensure -- from PLATFORM
			instance_free: class
		end

	is_windows: BOOLEAN
			-- Are we running on Windows platform?
			-- (from PLATFORM)
		external
			"built_in static"
		ensure -- from PLATFORM
			instance_free: class
		end

	Operating_environment: OPERATING_ENVIRONMENT
			-- Objects available from the operating system
			-- (from ANY)
		once
			create Result
		ensure -- from ANY
			instance_free: class
			operating_environment_not_void: Result /= Void
		end
	
feature {NONE} -- Retrieval

	frozen internal_correct_mismatch
			-- Called from runtime to perform a proper dynamic dispatch on correct_mismatch
			-- from MISMATCH_CORRECTOR.
			-- (from ANY)
		local
			l_msg: STRING_32
			l_exc: EXCEPTIONS
		do
			if attached {MISMATCH_CORRECTOR} Current as l_corrector then
				l_corrector.correct_mismatch
			else
				create l_msg.make_from_string ("Mismatch: ".as_string_32)
				create l_exc;
				l_msg.append (generating_type.name_32);
				l_exc.raise_retrieval_exception (l_msg)
			end
		end
	
invariant
	null_means_invalid: internal_item.item.is_default_pointer implies not is_valid

		-- from GAME_PIXEL_BUFFER
	exists: not has_error implies not item.is_default_pointer

		-- from ANY
	reflexive_equality: standard_is_equal (Current)
	reflexive_conformance: conforms_to (Current)

end -- class GAME_PIXEL_READER_WRITER

Generated by ISE EiffelStudio