lis 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,114 +0,0 @@
1
- require 'strscan'
2
-
3
- module LIS::Transfer
4
-
5
- # a chainable IO-Listener that provides two methods:
6
- #
7
- # {#on_data} ::
8
- # a callback that is called whenever a message is received
9
- # {#write} ::
10
- # can be called so send messages to the underlying IO
11
- #
12
- # when overriding this class, you need to implement two methods:
13
- #
14
- # {#receive} ::
15
- # is called from an underlying IO whenever a message is received
16
- # the message can be handled. Call {#forward} to propagate
17
- #
18
- # {#write} ::
19
- # transform/encode a message before sending it. Call +super+ to propagate
20
- #
21
- # See {LineBasedProtocol} for a toy implementation which strips
22
- # newlines and only forwards complete lines.
23
- #
24
- class Base
25
-
26
- # @param [Base, #on_data] read data source
27
- # @param [Base, IO, #write] write object where messages are written to
28
- #
29
- def initialize(read, write = read)
30
- @reader, @writer = read, write
31
- @on_data = nil
32
- @reader.on_data { |*data| receive(*data) } if @reader.respond_to?(:on_data)
33
- end
34
-
35
- # register a block, to be run whenever the protocol implementation
36
- # receives data (by calling {#forward})
37
- #
38
- # this is used to chain protocol layers together
39
- #
40
- # @return [self]
41
- # @yield [*args] called whenever the protocol implementaion calls {#forward}
42
- # @yieldreturn [nil]
43
- #
44
- def on_data(&block)
45
- @on_data = block
46
- self
47
- end
48
-
49
- # @see #write
50
- def <<(*args)
51
- write(*args)
52
- end
53
-
54
- # write data to underlying interface. override if data needs to be preprocessed
55
- #
56
- def write(*args)
57
- @writer.<<(*args) if @writer
58
- end
59
-
60
-
61
- protected
62
-
63
- # override this method to handle data received from an underlying interface, for
64
- # example splitting it into messages or only passing on complete lines
65
- # (see {LineBasedProtocol#receive} for an example)
66
- #
67
- # call {#forward} to pass it on to higher levels
68
- #
69
- # @return [nil]
70
- #
71
- def receive(data)
72
- forward(data)
73
- end
74
-
75
- def forward(*data)
76
- @on_data.call(*data) if @on_data
77
- end
78
- end
79
-
80
-
81
- class LineBasedProtocol < Base
82
-
83
- # strip newlines from received data and pass on complete lines
84
- #
85
- # @param [String] data
86
- #
87
- def receive(data)
88
- @memo ||= ""
89
- scanner = StringScanner.new(@memo + data)
90
- while s = scanner.scan(/.*?\n/)
91
- forward(s.strip)
92
- end
93
- @memo = scanner.rest
94
- nil
95
- end
96
-
97
- # add a newline to data and pass it on
98
- # @param [String] data
99
- #
100
- def write(data)
101
- super(data + "\n")
102
- end
103
- end
104
-
105
- class IOListener < Base
106
- def run!
107
- while not @reader.eof?
108
- str = @reader.readpartial(4096)
109
- forward(str)
110
- end
111
- end
112
- end
113
- end
114
-
@@ -1,34 +0,0 @@
1
- require 'helper'
2
-
3
- class TestIOListener < Test::Unit::TestCase
4
- context "a server" do
5
- setup do
6
- r1, w1 = IO.pipe # Immulite -> LIS
7
- r2, w2 = IO.pipe # LIS -> Immulite
8
-
9
- @server = LIS::Transfer::IOListener.new(r1, w2)
10
- @protocol = LIS::Transfer::LineBasedProtocol.new(@server)
11
- @device = Mock::Server.new(r2, w1)
12
- end
13
-
14
- should "exist" do
15
- assert_not_nil @server
16
- end
17
-
18
- should "yield packets written to it" do
19
- @packets = []
20
- @protocol.on_data { |packet| @packets << packet }
21
-
22
- @device.write("fo").wait.write("o\n").wait.write("bar\n").eof
23
- @server.run!
24
-
25
- assert_equal ["foo", "bar"], @packets
26
- end
27
-
28
- should "send data" do
29
- @protocol << "hello world"
30
- data = @device.read_all
31
- assert_equal "hello world\n", data
32
- end
33
- end
34
- end