indexing description: "[ binary ring buffer ]" date: "$Date$" revision: "$Revision$" class EM_BINARY_RING_BUFFER inherit KI_BUFFER [CHARACTER] redefine put, item end create make feature {NONE} -- Initialization make (n: INTEGER) is -- Create a new binary ring buffer being able -- to contain `n' characters. require n_not_negative: n >= 0 do create buffer.make_new_unshared (n) create read_position_pointer.make_new_unshared (4) create write_position_pointer.make_new_unshared (4) ensure count_set: count = n end feature -- Access item (i: INTEGER): CHARACTER is -- Item at position `i' do Result := buffer.item (i - 1).to_character end feature -- Measurement count: INTEGER is -- Number of items in buffer do Result := buffer.count end free: INTEGER is -- Number of free items in buffer do Result := (read_position + count - write_position - 1) \\ count end feature -- Element change put (v: CHARACTER; i: INTEGER) is -- Replace item at position `i' by `v'. do buffer.put (v.code, i - 1) end write_from_character_buffer (a_buffer: KI_CHARACTER_BUFFER) is -- Fill buffer from other buffer require a_buffer_not_void: a_buffer /= Void enough_space: a_buffer.count <= free local ar: like buffer special: SPECIAL [CHARACTER] do special := a_buffer.as_special create ar.make_shared (special.base_address + 1, special.count) if write_position + a_buffer.count < count then buffer.copy_from_to (ar, write_position) else buffer.copy_from_to_count (ar, write_position, count - write_position) buffer.copy_from_position_count (ar, count - write_position, ar.count - count + write_position) end write_position_pointer.put_integer ((write_position + ar.count) \\ count, 0) end write_from_stream (a_stream: KI_INPUT_STREAM [CHARACTER]; nb: INTEGER): INTEGER is -- Fill buffer, with at most `nb' items read from `a_stream'. -- Return the number of items actually read. require a_stream_not_void: a_stream /= Void a_stream_open_read: a_stream.is_open_read not_end_of_input: not a_stream.end_of_input nb_large_enough: nb > 0 enough_space: nb <= free do if write_position + nb <= count then Result := a_stream.read_to_buffer (current, write_position + 1, nb) else Result := a_stream.read_to_buffer (current, write_position + 1, count - write_position) if not a_stream.end_of_input then Result := Result + a_stream.read_to_buffer (current, 1, nb + write_position - count) end end write_position_pointer.put_integer ((write_position + Result) \\ count, 0) end read_to (a_array: EM_INT8_ARRAY; nb: INTEGER): INTEGER is -- read from buffer to array at most nb items -- returns the number of read items require a_array_not_void: a_array /= Void nb_large_enough: nb > 0 nb_not_to_large: nb <= a_array.count do Result := (write_position - read_position + count) \\ count if Result > nb then Result := nb end if read_position + Result < count then a_array.copy_from_position_count (buffer, read_position, Result) else a_array.copy_from_position_count (buffer, read_position, count - read_position) a_array.copy_from_to_count (buffer, count - read_position, Result - count + read_position) end read_position_pointer.put_integer ((read_position + Result) \\ count, 0) end clear is -- fast clear buffer do write_position.set_item (read_position) end feature -- Resizing resize (n: INTEGER) is -- Resize buffer so that it contains `n' items. -- Do not lose any previously entered items. local new_buffer: like buffer do -- todo: shoud not make a gap in the ring create new_buffer.make_new_unshared (n) new_buffer.copy_from_count (buffer, buffer.count) buffer := new_buffer end feature {NONE, EM_AUDIO_MOVIE_STREAM} -- implementation read_position: INTEGER is -- get value from read_position_pointer do Result := read_position_pointer.read_integer (0) end read_position_pointer: EWG_MANAGED_POINTER write_position: INTEGER is -- get value from write_position_pointer do Result := write_position_pointer.read_integer (0) end write_position_pointer: EWG_MANAGED_POINTER buffer: EM_INT8_ARRAY invariant buffer_exist: buffer /= Void end