Class: EventMachine::SystemCommand::Pipe

Inherits:
EM::Connection
  • Object
show all
Defined in:
lib/em-systemcommand/pipe.rb

Instance Method Summary collapse

Constructor Details

#initialize(master, name) ⇒ Pipe

Returns a new instance of Pipe.



6
7
8
9
10
11
12
13
14
15
# File 'lib/em-systemcommand/pipe.rb', line 6

def initialize master, name
  @master             = master
  @name               = name
  @master.pipes[name] = self
  begin
    @outputbuffer     = StringIO.new
  rescue Exception => e
    puts "Uninitialized constant StringIO. This may happen when you forgot to use bundler. Use `bundle exec`."
  end
end

Instance Method Details

#closeObject

Close the attached IO object.



185
186
187
188
189
190
191
192
# File 'lib/em-systemcommand/pipe.rb', line 185

def close
  begin
    @io.close unless @io.closed?
    detach
  rescue Exception => e
    # ignore errors, when the io object might be closed already
  end
end

#data {|data| ... } ⇒ Object

Adds a callback for receive_data events.

Yields:

  • The callback that´s to be added to the data callback array

Yield Parameters:

  • data (String)

    The data that´s received



179
180
181
# File 'lib/em-systemcommand/pipe.rb', line 179

def data &block
  receive_data_callbacks << block
end

#line {|line| ... } ⇒ Object

Adds a callback for receive_line events.

Yields:

  • The callback that should be added to callback array for line events

Yield Parameters:

  • line (String)

    The line that has been received



62
63
64
# File 'lib/em-systemcommand/pipe.rb', line 62

def line &block
  receive_line_callbacks << block
end

#match(regexp, opt = {}, &block) ⇒ Object

Convenience method to create a callback that matches a regular expression

Parameters:

  • regexp (Regexp)

    The regular expression that should be matched

  • opt (Hash) (defaults to: {})

    a customizable set of options

Options Hash (opt):

  • :in (Symbol)

    Match either in :line or :output

  • :match (Symbol)

    Match either :first or :last



32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/em-systemcommand/pipe.rb', line 32

def match regexp, opt = {}, &block
  opt = { in: :line, match: :first }.merge opt
  (opt[:in] == :output ? receive_update_callbacks : receive_line_callbacks) << lambda do |data|
    matches = data.scan regexp
    if matches.length > 0
      case opt[:match]
      when :first
        block.call *matches[0]
      when :last
        block.call *matches[matches.length-1]
      end
    end
  end
end

#outputString

The content of the output buffer as string.

Returns:

  • (String)

    The connections output



21
22
23
# File 'lib/em-systemcommand/pipe.rb', line 21

def output
  @outputbuffer.string
end

#parse_cr(data, ix) ⇒ Object

Parses carriage return when data is received.

Parameters:

  • data (String)

    The received data

  • ix (Integer)

    The index of the carriage return



110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/em-systemcommand/pipe.rb', line 110

def parse_cr data, ix
  ln = (@linebuffer << data[0...ix]).join
  @linebuffer.clear

  receive_line ln
  @outputbuffer.print ln

  # jump back to the last line feed
  @outputbuffer.pos = @lf_offset

  # parse rest of the data
  parse_crlf data[(ix+1)..-1]
end

#parse_crlf(data) ⇒ Object

Parse received data for line feeds or carriage returns.

Parameters:

  • data (String)

    The received data



154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
# File 'lib/em-systemcommand/pipe.rb', line 154

def parse_crlf data
  return if data == ''
  if ilf = data.index("\n")
    # if we find a LF and that LF is after a CR we first handle
    # the CR
    if icr = data.index("\r") and ilf != (icr+1) and icr < ilf
      parse_cr data, icr
    else
      parse_lf data, ilf
    end
  else
    if icr = data.index("\r")
      parse_cr data, icr
    else
      @linebuffer << data
      @outputbuffer.print data
    end
  end
end

#parse_lf(data, ix) ⇒ Object

Parses line feed when data is received.

Parameters:

  • data (String)

    The received data

  • ix (Integer)

    The index of the line feed



129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/em-systemcommand/pipe.rb', line 129

def parse_lf data, ix
  ln = (@linebuffer << data[0...ix]).join
  @linebuffer.clear
  ln.chomp!

  receive_line ln
  @outputbuffer.print ln

  # jump to the end of the buffer to keep the characters, that
  # may already have been written
  @outputbuffer.pos = @outputbuffer.length
  # print the line feed
  @outputbuffer.puts
  # set last line feed to the current cursor position, so we
  # know where we have to jump back, when a carriage return occurs
  @lf_offset = @outputbuffer.pos

  # parse rest of the data
  parse_crlf data[(ix+1)..-1]
end

#receive_data(data, recursive = false) ⇒ Object

Invoked when data was received.

Parameters:

  • data (String)

    The received data



90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/em-systemcommand/pipe.rb', line 90

def receive_data data, recursive = false
  # if recursive is true we already invoked the receive data callbacks!
  unless recursive
    receive_data_callbacks.each do |callback|
      callback.call data.dup
    end
  end
  @linebuffer ||= []
  @lf_offset  ||= 0

  parse_crlf data

  receive_update @outputbuffer.string unless recursive
end

#receive_line(line) ⇒ Object

Invoked when line was received

Parameters:

  • line (String)

    The line that´s received



51
52
53
54
55
# File 'lib/em-systemcommand/pipe.rb', line 51

def receive_line line
  receive_line_callbacks.each do |callback|
    callback.call line.dup
  end
end

#receive_update(buffer) ⇒ Object

Invoked when a line was written, but ‘\r` was received without a line-break in the end.

Parameters:

  • buffer (String)

    The complete buffer content of this connection



71
72
73
74
75
# File 'lib/em-systemcommand/pipe.rb', line 71

def receive_update buffer
  receive_update_callbacks.each do |callback|
    callback.call buffer.dup
  end
end

#unbindObject

Invoked when the connection is terminated. Calls ‘unbind(@name)` on master.



197
198
199
200
# File 'lib/em-systemcommand/pipe.rb', line 197

def unbind
  self.close
  @master.unbind(@name)
end

#update {|buffer| ... } ⇒ Object

Adds a callback for receive_update events.

Yields:

  • The callback that should be added to callback array for update events

Yield Parameters:

  • buffer (String)

    The complete buffer content of this connection



82
83
84
# File 'lib/em-systemcommand/pipe.rb', line 82

def update &block
  receive_update_callbacks << block
end