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