em-systemcommand 2.0.0 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,18 +1,23 @@
1
+ # -*- coding: utf-8 -*-
1
2
  module EventMachine
2
3
  class SystemCommand
3
4
  class Pipe < EM::Connection
4
5
 
5
- def initialize(master, name)
6
+ def initialize master, name
6
7
  @master = master
7
8
  @name = name
8
9
  @master.pipes[name] = self
9
10
  begin
10
- @outputbuffer = StringIO.new()
11
+ @outputbuffer = StringIO.new
11
12
  rescue Exception => e
12
13
  puts "Uninitialized constant StringIO. This may happen when you forgot to use bundler. Use `bundle exec`."
13
14
  end
14
15
  end
15
16
 
17
+ ##
18
+ # The content of the output buffer as string.
19
+ #
20
+ # @return [String] The connections output
16
21
  def output
17
22
  @outputbuffer.string
18
23
  end
@@ -20,6 +25,10 @@ module EventMachine
20
25
  ##
21
26
  # Convenience method to create a callback that matches a regular
22
27
  # expression
28
+ #
29
+ # @param [Regexp] regexp The regular expression that should be matched
30
+ # @option opt [Symbol] :in Match either in `:line` or `:output`
31
+ # @option opt [Symbol] :match Match either `:first` or `:last`
23
32
  def match regexp, opt = {}, &block
24
33
  opt = { in: :line, match: :first }.merge opt
25
34
  (opt[:in] == :output ? receive_update_callbacks : receive_line_callbacks) << lambda do |data|
@@ -35,68 +44,115 @@ module EventMachine
35
44
  end
36
45
  end
37
46
 
47
+ ##
38
48
  # Invoked when line was received
49
+ #
50
+ # @param [String] line The line that´s received
39
51
  def receive_line line
40
52
  receive_line_callbacks.each do |callback|
41
53
  callback.call line.dup
42
54
  end
43
55
  end
44
56
 
57
+ ##
45
58
  # Adds a callback for `receive_line` events.
59
+ #
60
+ # @yield The callback that should be added to callback array for line events
61
+ # @yieldparam [String] line The line that has been received
46
62
  def line &block
47
63
  receive_line_callbacks << block
48
64
  end
49
65
 
66
+ ##
50
67
  # Invoked when a line was written, but `\r` was received without
51
68
  # a line-break in the end.
69
+ #
70
+ # @param [String] buffer The complete buffer content of this connection
52
71
  def receive_update buffer
53
72
  receive_update_callbacks.each do |callback|
54
73
  callback.call buffer.dup
55
74
  end
56
75
  end
57
76
 
77
+ ##
58
78
  # Adds a callback for `receive_update` events.
79
+ #
80
+ # @yield The callback that should be added to callback array for update events
81
+ # @yieldparam [String] buffer The complete buffer content of this connection
59
82
  def update &block
60
83
  receive_update_callbacks << block
61
84
  end
62
85
 
86
+ ##
63
87
  # Invoked when data was received.
88
+ #
89
+ # @param [String] data The received data
64
90
  def receive_data data, recursive = false
91
+ # if recursive is true we already invoked the receive data callbacks!
65
92
  unless recursive
66
93
  receive_data_callbacks.each do |callback|
67
94
  callback.call data.dup
68
95
  end
69
96
  end
70
97
  @linebuffer ||= []
71
- @cr_offset = 0
98
+ @lf_offset ||= 0
72
99
 
73
100
  parse_crlf data
74
101
 
75
102
  receive_update @outputbuffer.string unless recursive
76
103
  end
77
104
 
105
+ ##
106
+ # Parses carriage return when data is received.
107
+ #
108
+ # @param [String] data The received data
109
+ # @param [Integer] ix The index of the carriage return
78
110
  def parse_cr data, ix
79
111
  ln = (@linebuffer << data[0...ix]).join
80
112
  @linebuffer.clear
113
+
81
114
  receive_line ln
82
115
  @outputbuffer.print ln
83
- @outputbuffer.pos = @cr_offset
84
- parse_crlf data[(ix+1)..-1] # receive rest data
116
+
117
+ # jump back to the last line feed
118
+ @outputbuffer.pos = @lf_offset
119
+
120
+ # parse rest of the data
121
+ parse_crlf data[(ix+1)..-1]
85
122
  end
86
123
 
124
+ ##
125
+ # Parses line feed when data is received.
126
+ #
127
+ # @param [String] data The received data
128
+ # @param [Integer] ix The index of the line feed
87
129
  def parse_lf data, ix
88
130
  ln = (@linebuffer << data[0...ix]).join
89
131
  @linebuffer.clear
90
132
  ln.chomp!
133
+
91
134
  receive_line ln
92
135
  @outputbuffer.print ln
136
+
137
+ # jump to the end of the buffer to keep the characters, that
138
+ # may already have been written
93
139
  @outputbuffer.pos = @outputbuffer.length
140
+ # print the line feed
94
141
  @outputbuffer.puts
95
- @cr_offset = @outputbuffer.pos
96
- parse_crlf data[(ix+1)..-1] # receive rest data
142
+ # set last line feed to the current cursor position, so we
143
+ # know where we have to jump back, when a carriage return occurs
144
+ @lf_offset = @outputbuffer.pos
145
+
146
+ # parse rest of the data
147
+ parse_crlf data[(ix+1)..-1]
97
148
  end
98
149
 
150
+ ##
151
+ # Parse received data for line feeds or carriage returns.
152
+ #
153
+ # @param [String] data The received data
99
154
  def parse_crlf data
155
+ return if data == ''
100
156
  if ilf = data.index("\n")
101
157
  # if we find a LF and that LF is after a CR we first handle
102
158
  # the CR
@@ -115,11 +171,16 @@ module EventMachine
115
171
  end
116
172
  end
117
173
 
174
+ ##
118
175
  # Adds a callback for `receive_data` events.
176
+ #
177
+ # @yield The callback that´s to be added to the data callback array
178
+ # @yieldparam [String] data The data that´s received
119
179
  def data &block
120
180
  receive_data_callbacks << block
121
181
  end
122
182
 
183
+ ##
123
184
  # Close the attached IO object.
124
185
  def close
125
186
  begin
@@ -1,5 +1,5 @@
1
1
  module Em
2
2
  module Systemcommand
3
- VERSION = "2.0.0"
3
+ VERSION = "2.0.1"
4
4
  end
5
5
  end
@@ -2,6 +2,27 @@ require 'spec_helper'
2
2
 
3
3
  describe 'Pipe' do
4
4
 
5
+ context 'parsing' do
6
+
7
+ it 'should handle carriage returns' do
8
+ cmd = EM::SystemCommand.new 'exit 0;'
9
+ pipe = EM::SystemCommand::Pipe.new(nil, cmd, :stdout)
10
+ pipe.receive_data "test\n"
11
+ pipe.receive_data " 32768 0% 0.00kB/s 0:00:00\r"
12
+ pipe.receive_data " 131235840 12% 125.12MB/s 0:00:06\r"
13
+ pipe.receive_data " 261619712 25% 124.80MB/s 0:00:05\r"
14
+ pipe.receive_data " 391544832 38% 124.54MB/s 0:00:04\r"
15
+ pipe.receive_data " 522616832 51% 124.69MB/s 0:00:03\r"
16
+ pipe.receive_data " 652738560 63% 124.43MB/s 0:00:02\r"
17
+ pipe.receive_data " 783056896 76% 124.41MB/s 0:00:01\r"
18
+ pipe.receive_data " 906657792 88% 122.90MB/s 0:00:00\r"
19
+ pipe.receive_data " 1024000000 100% 123.67MB/s 0:00:07 (xfer#1, to-check=0/1)\n"
20
+ pipe.receive_data "\n"
21
+ pipe.receive_data "sent 1024125065 bytes received 31 bytes 120485305.41 bytes/sec\ntotal size is 1024000000 speedup is 1.00\n"
22
+ pipe.output.should == "test\n 1024000000 100% 123.67MB/s 0:00:07 (xfer#1, to-check=0/1)\n\nsent 1024125065 bytes received 31 bytes 120485305.41 bytes/sec\ntotal size is 1024000000 speedup is 1.00\n"
23
+ end
24
+ end
25
+
5
26
  context '#receive_data' do
6
27
  it 'should correctly do a carriage return in the output buffer' do
7
28
  EM.run do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: em-systemcommand
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.0.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -163,7 +163,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
163
163
  version: '0'
164
164
  segments:
165
165
  - 0
166
- hash: 1829514624315752226
166
+ hash: -2179568276682517415
167
167
  required_rubygems_version: !ruby/object:Gem::Requirement
168
168
  none: false
169
169
  requirements:
@@ -172,7 +172,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
172
172
  version: '0'
173
173
  segments:
174
174
  - 0
175
- hash: 1829514624315752226
175
+ hash: -2179568276682517415
176
176
  requirements: []
177
177
  rubyforge_project:
178
178
  rubygems_version: 1.8.24