packet_io 0.4.0.rc2

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,21 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
data/History.txt ADDED
@@ -0,0 +1,6 @@
1
+ == 0.4.0 / 2011-05-31
2
+ * much simpler reimplementation without threads
3
+
4
+ == 0.3.0 / 2008-10-12
5
+ * initial release
6
+
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Levin Alexander
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,42 @@
1
+ serial_interface
2
+ by Levin Alexander
3
+ http://levinalex.net/
4
+
5
+ == DESCRIPTION:
6
+
7
+ serial_interface intends to be a small library that makes it easy
8
+ to define packet based protocols over a serial link (RS232) in a
9
+ declarative fashion.
10
+
11
+ == SYNOPSIS:
12
+
13
+ nothing written yet
14
+
15
+ == INSTALL:
16
+
17
+ * not yet written
18
+
19
+ == LICENSE:
20
+
21
+ (The MIT License)
22
+
23
+ Copyright (c) 2006-2008 Levin Alexander
24
+
25
+ Permission is hereby granted, free of charge, to any person obtaining
26
+ a copy of this software and associated documentation files (the
27
+ 'Software'), to deal in the Software without restriction, including
28
+ without limitation the rights to use, copy, modify, merge, publish,
29
+ distribute, sublicense, and/or sell copies of the Software, and to
30
+ permit persons to whom the Software is furnished to do so, subject to
31
+ the following conditions:
32
+
33
+ The above copyright notice and this permission notice shall be
34
+ included in all copies or substantial portions of the Software.
35
+
36
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
37
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
38
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
39
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
40
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
41
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
42
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,19 @@
1
+ $LOAD_PATH.unshift './lib'
2
+
3
+ require 'bundler'
4
+ Bundler::GemHelper.install_tasks
5
+
6
+ require 'packet_io'
7
+
8
+ require 'rake/testtask'
9
+ Rake::TestTask.new(:test) do |test|
10
+ test.libs << 'lib' << 'test'
11
+ test.pattern = 'test/**/test_*.rb'
12
+ test.verbose = true
13
+ end
14
+
15
+ require 'yard'
16
+ YARD::Rake::YardocTask.new
17
+
18
+ task :doc => :yard
19
+ task :default => [:test]
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.3.0
@@ -0,0 +1,113 @@
1
+ module PacketIO
2
+
3
+ # a chainable IO-Listener that provides two methods:
4
+ #
5
+ # {#on_data} ::
6
+ # a callback that is called whenever a message is received
7
+ # {#write} ::
8
+ # can be called so send messages to the underlying IO
9
+ #
10
+ # when overriding this class, you need to implement two methods:
11
+ #
12
+ # {#receive} ::
13
+ # is called from an underlying IO whenever a message is received
14
+ # the message can be handled. Call {#forward} to propagate
15
+ #
16
+ # {#write} ::
17
+ # transform/encode a message before sending it. Call +super+ to propagate
18
+ #
19
+ # See {LineBasedProtocol} for a toy implementation which strips
20
+ # newlines and only forwards complete lines.
21
+ #
22
+ class Base
23
+
24
+ # @param [Base, #on_data] read data source
25
+ # @param [Base, IO, #write] write object where messages are written to
26
+ #
27
+ def initialize(read, write = read)
28
+ @reader, @writer = read, write
29
+ @on_data = nil
30
+ @reader.on_data { |*data| receive(*data) } if @reader.respond_to?(:on_data)
31
+ end
32
+
33
+ # register a block, to be run whenever the protocol implementation
34
+ # receives data (by calling {#forward})
35
+ #
36
+ # this is used to chain protocol layers together
37
+ #
38
+ # @return [self]
39
+ # @yield [*args] called whenever the protocol implementaion calls {#forward}
40
+ # @yieldreturn [nil]
41
+ #
42
+ def on_data(&block)
43
+ @on_data = block
44
+ self
45
+ end
46
+
47
+ # @see #write
48
+ #
49
+ def <<(*args)
50
+ write(*args)
51
+ end
52
+
53
+ # write data to underlying interface. override if data needs to be preprocessed
54
+ #
55
+ def write(*args)
56
+ @writer.<<(*args) if @writer
57
+ end
58
+
59
+
60
+ protected
61
+
62
+ # override this method to handle data received from an underlying interface, for
63
+ # example splitting it into messages or only passing on complete lines
64
+ # (see {LineBasedProtocol#receive} for an example)
65
+ #
66
+ # call {#forward} to pass it on to higher levels
67
+ #
68
+ # @return [nil]
69
+ #
70
+ def receive(data)
71
+ forward(data)
72
+ end
73
+
74
+ def forward(*data)
75
+ @on_data.call(*data) if @on_data
76
+ end
77
+ end
78
+
79
+
80
+ class LineBasedProtocol < Base
81
+
82
+ # strip newlines from received data and pass on complete lines
83
+ #
84
+ # @param [String] data
85
+ #
86
+ def receive(data)
87
+ @memo ||= ""
88
+ scanner = StringScanner.new(@memo + data)
89
+ while s = scanner.scan(/.*?\n/)
90
+ forward(s.strip)
91
+ end
92
+ @memo = scanner.rest
93
+ nil
94
+ end
95
+
96
+ # add a newline to data and pass it on
97
+ # @param [String] data
98
+ #
99
+ def write(data)
100
+ super(data + "\n")
101
+ end
102
+ end
103
+
104
+ class IOListener < Base
105
+ def run!
106
+ while not @reader.eof?
107
+ str = @reader.readpartial(4096)
108
+ forward(str)
109
+ end
110
+ end
111
+ end
112
+ end
113
+
@@ -0,0 +1,49 @@
1
+ module PacketIO::Test
2
+ class MockServer
3
+ def initialize(read, write)
4
+ @read, @write = read, write
5
+ @queue = Queue.new
6
+ @thread = Thread.new do
7
+ parse_commands
8
+ end
9
+ end
10
+
11
+ def write(string)
12
+ @queue.push [:write, string]
13
+ self
14
+ end
15
+
16
+ def read_all
17
+ @read.readpartial(4096)
18
+ end
19
+
20
+ def wait(seconds = 0.02)
21
+ @queue.push [:wait, seconds]
22
+ self
23
+ end
24
+
25
+ def eof
26
+ @queue.push [:close]
27
+ end
28
+
29
+
30
+ private
31
+
32
+ def parse_commands
33
+ loop do
34
+ action, data = @queue.pop
35
+
36
+ case action
37
+ when :close
38
+ @write.close
39
+ break
40
+ when :write
41
+ @write.write(data)
42
+ @write.flush
43
+ when :wait
44
+ sleep data
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
data/lib/packet_io.rb ADDED
@@ -0,0 +1,8 @@
1
+
2
+ module PacketIO
3
+ VERSION = '0.4.0.rc2'
4
+ end
5
+
6
+ require 'strscan'
7
+ require 'packet_io/io_listener'
8
+
data/packet_io.gemspec ADDED
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require 'packet_io'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = %q{packet_io}
7
+ s.version = PacketIO::VERSION
8
+
9
+ s.authors = ["Levin Alexander"]
10
+ s.description = %q{}
11
+ s.email = %q{mail@levinalex.net}
12
+
13
+ s.files = `git ls-files`.split("\n")
14
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
15
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
16
+
17
+ s.homepage = %q{http://github.com/levinalex/packet_io}
18
+ s.rdoc_options = ["--charset=UTF-8"]
19
+ s.require_paths = ["lib"]
20
+ s.summary = %q{define packet based protocols in a declarative fashion}
21
+
22
+ s.add_development_dependency("shoulda", ["~> 2.11.3"])
23
+ s.add_development_dependency("mocha", ["~> 0.9.12"])
24
+ s.add_development_dependency("yard", ["~> 0.7.1"])
25
+ s.add_development_dependency("cucumber", ["~> 0.10.3"])
26
+ end
27
+
data/test/helper.rb ADDED
@@ -0,0 +1,13 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+ require 'mocha'
5
+
6
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
7
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
8
+ require 'packet_io'
9
+ require 'packet_io/test/mock_server'
10
+
11
+ class Test::Unit::TestCase
12
+ end
13
+
@@ -0,0 +1,34 @@
1
+ require 'helper'
2
+
3
+ class TestIOListener < Test::Unit::TestCase
4
+ context "a server" do
5
+ setup do
6
+ r1, w1 = IO.pipe # Server -> Client
7
+ r2, w2 = IO.pipe # Client -> Server
8
+
9
+ @server = PacketIO::IOListener.new(r1, w2)
10
+ @protocol = PacketIO::LineBasedProtocol.new(@server)
11
+ @device = PacketIO::Test::MockServer.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
metadata ADDED
@@ -0,0 +1,139 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: packet_io
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: true
5
+ segments:
6
+ - 0
7
+ - 4
8
+ - 0
9
+ - rc2
10
+ version: 0.4.0.rc2
11
+ platform: ruby
12
+ authors:
13
+ - Levin Alexander
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-05-31 00:00:00 +02:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: shoulda
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ segments:
30
+ - 2
31
+ - 11
32
+ - 3
33
+ version: 2.11.3
34
+ type: :development
35
+ version_requirements: *id001
36
+ - !ruby/object:Gem::Dependency
37
+ name: mocha
38
+ prerelease: false
39
+ requirement: &id002 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ~>
43
+ - !ruby/object:Gem::Version
44
+ segments:
45
+ - 0
46
+ - 9
47
+ - 12
48
+ version: 0.9.12
49
+ type: :development
50
+ version_requirements: *id002
51
+ - !ruby/object:Gem::Dependency
52
+ name: yard
53
+ prerelease: false
54
+ requirement: &id003 !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ~>
58
+ - !ruby/object:Gem::Version
59
+ segments:
60
+ - 0
61
+ - 7
62
+ - 1
63
+ version: 0.7.1
64
+ type: :development
65
+ version_requirements: *id003
66
+ - !ruby/object:Gem::Dependency
67
+ name: cucumber
68
+ prerelease: false
69
+ requirement: &id004 !ruby/object:Gem::Requirement
70
+ none: false
71
+ requirements:
72
+ - - ~>
73
+ - !ruby/object:Gem::Version
74
+ segments:
75
+ - 0
76
+ - 10
77
+ - 3
78
+ version: 0.10.3
79
+ type: :development
80
+ version_requirements: *id004
81
+ description: ""
82
+ email: mail@levinalex.net
83
+ executables: []
84
+
85
+ extensions: []
86
+
87
+ extra_rdoc_files: []
88
+
89
+ files:
90
+ - .document
91
+ - .gitignore
92
+ - History.txt
93
+ - LICENSE
94
+ - README.rdoc
95
+ - Rakefile
96
+ - VERSION
97
+ - lib/packet_io.rb
98
+ - lib/packet_io/io_listener.rb
99
+ - lib/packet_io/test/mock_server.rb
100
+ - packet_io.gemspec
101
+ - test/helper.rb
102
+ - test/test_io_listener.rb
103
+ has_rdoc: true
104
+ homepage: http://github.com/levinalex/packet_io
105
+ licenses: []
106
+
107
+ post_install_message:
108
+ rdoc_options:
109
+ - --charset=UTF-8
110
+ require_paths:
111
+ - lib
112
+ required_ruby_version: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ segments:
118
+ - 0
119
+ version: "0"
120
+ required_rubygems_version: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ">"
124
+ - !ruby/object:Gem::Version
125
+ segments:
126
+ - 1
127
+ - 3
128
+ - 1
129
+ version: 1.3.1
130
+ requirements: []
131
+
132
+ rubyforge_project:
133
+ rubygems_version: 1.3.7
134
+ signing_key:
135
+ specification_version: 3
136
+ summary: define packet based protocols in a declarative fashion
137
+ test_files:
138
+ - test/helper.rb
139
+ - test/test_io_listener.rb