lib/ionian/extension/io.rb in ionian-0.6.12 vs lib/ionian/extension/io.rb in ionian-0.7.0
- old
+ new
@@ -37,11 +37,11 @@
#
def has_data? timeout: 0
::IO.select([self], nil, nil, timeout) ? true : false
end
- # Returns the regular expression used for {#read_match}.
+ # @return [Regexp] Regular expression used for {#read_match}.
def expression
@ionian_expression
end
# Set the expression to match against the read buffer.
@@ -82,12 +82,12 @@
#
#
# @yieldparam match [MatchData] If there are multiple matches, the block
# is called multiple times.
#
- # @return [Array<MatchData>, nil] Returns an array of matches.
- # Returns nil if no data was received within the timeout period.
+ # @return [Array<MatchData>, nil] matches.
+ # Nil if no data was received within the timeout period.
#
#
# @option kwargs [Numeric] :timeout (nil) Timeout in seconds IO::select
# will block. Blocks indefinitely by default. Set to 0 for nonblocking.
#
@@ -112,20 +112,27 @@
exp = kwargs.fetch :expression, @ionian_expression
exp = Regexp.new "(.*?)#{exp}" if exp.is_a? String
unless skip_select
- return nil unless ::IO.select [self], nil, nil, timeout
+ return nil unless self.has_data? timeout: timeout
end
- # Read data from the IO buffer until it's empty.
- @ionian_buf << read_all
-
@matches = []
+ # TODO: Implement an option for number of bytes or timeout to throw away
+ # data if no match is found.
+ Timeout.timeout(timeout) do
+ loop do
+ # Read data from the IO buffer until it's empty.
+ @ionian_buf << read_all
+ break if @ionian_buf =~ exp
+ end
+ end
+
while @ionian_buf =~ exp
- @matches << $~ # Match data.
+ @matches << $~ # Match data.
@ionian_buf = $' # Leave post match data in the buffer.
end
# Convert named captures to methods.
if build_methods
@@ -153,10 +160,11 @@
# Start a thread that checks for data and notifies match and error handlers.
# Passes kwargs to {#read_match}.
# This method SHOULD NOT be used if {#read_match} is used.
def run_match **kwargs
@run_match_thread ||= Thread.new do
+ Thread.current.thread_variable_set :match_thread_running, true
begin
while not closed? do
matches = read_match **kwargs
matches.each { |match| notify_match_handlers match } if matches
end
@@ -166,10 +174,18 @@
@run_match_thread = nil
end
end
end
+ def run_match_is_running?
+ return true if \
+ @run_match_thread and
+ @run_match_thread.thread_variable_get(:match_thread_running)
+
+ false
+ end
+
# Erase the data in the IO and Ionian buffers.
# This is typically handled automatically.
def purge
# Erase IO buffer.
read_all
@@ -193,10 +209,11 @@
alias_method :on_match, :register_match_handler
# @deprecated Use {#register_match_handler} instead.
def register_observer &block
+ STDOUT.puts "WARN: Call to deprecated method #{__method__}"
register_match_handler &block
end
# Unregister a block from being called when matched data is received.
def unregister_match_handler &block
@@ -204,9 +221,10 @@
block
end
# @deprecated Use {#unregister_match_handler} instead.
def unregister_observer &block
+ STDOUT.puts "WARN: Call to deprecated method #{__method__}"
unregister_match_handler &block
end
# Register a block to be called when {#run_match} raises an error.
# Method callbacks can be registered with &object.method(:method).
\ No newline at end of file