digital-transport 0.1.0 → 0.2.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1669102f928a133acaf1bfb0e6b5840aa6df31e7
4
- data.tar.gz: bba0e0f506afcef5278d0883d7b93f3ac3b42a06
3
+ metadata.gz: ebc25beae1ce280e5b8a3c653a92a35cf3518485
4
+ data.tar.gz: 479c4e3741cfbedb5fa95c851aa34d90d070cb77
5
5
  SHA512:
6
- metadata.gz: fe3002c1b50cb0ff33deda8c28be6f09927d6e9cc9f0396fbe25ba1de3c944d4df63dcaa9ab022c637167838b4ca52aa0fea0e056999f68b108257351a22f8a4
7
- data.tar.gz: d57e9dbc17737602bfd7816a76ce65708483b307655a404d0afafa58da5940056bb5ff5834c134c1aca78a2065bc80d4f45959500b6070892fefb4cb718aaa0e
6
+ metadata.gz: 6014ebe51f458190fc65b3523810b21e13bf9a5bbe3cf2aec18851b86abf17872ff72b2c42b1052468de9926cf8801c46136d64613384d205e54f522bd4d785a
7
+ data.tar.gz: d962fea7aa632121b9f17e33274d5f349f2f6379bc2f3d41959fdfc8bbb6f6c4c45f01caf9f3ec8b74e4acfca905d5edb426215261fe5dcc56f54e60b94bda49
@@ -1,8 +1,8 @@
1
1
  language: ruby
2
2
  rvm:
3
3
  - 2.1.2
4
- - 1.9.3
5
4
  - 2.2.1
5
+ - head
6
6
  os:
7
7
  - linux
8
8
  - osx
@@ -34,12 +34,12 @@ module Digital
34
34
 
35
35
  private_constant :Tcp, :Serial
36
36
 
37
- def new_tcp_adapter(ip, port)
38
- Tcp.new(ip.dup.freeze, port)
37
+ def new_tcp_adapter(ip, port, opts = {})
38
+ Tcp.new(ip.dup.freeze, port, opts.dup.freeze)
39
39
  end
40
40
 
41
- def new_serial_adapter(_port, _opts = {})
42
- raise NotImplementedError
41
+ def new_serial_adapter(port, opts = {})
42
+ Serial.new(port, opts.dup.freeze)
43
43
  end
44
44
 
45
45
  def new_usb_adapter(_port, _opts = {})
@@ -20,7 +20,7 @@ module Digital
20
20
  not_implemented __method__
21
21
  end
22
22
 
23
- def connect(_opts = {})
23
+ def connect
24
24
  not_implemented __method__
25
25
  end
26
26
 
@@ -6,8 +6,116 @@ module Digital
6
6
  class Serial
7
7
  include Digital::Transport::Errors
8
8
  include Digital::Transport::Adapters::Interface
9
+ include CommPort
9
10
  include Functional
10
11
 
12
+ DEFAULTS = {
13
+ timeout: 10,
14
+ baud_rate: CommPort::BAUD_115200,
15
+ data_bits: CommPort::DATA_BITS_8,
16
+ parity: CommPort::PAR_NONE,
17
+ stop_bits: CommPort::STOP_BITS_1,
18
+ flow_control: CommPort::FLOW_OFF
19
+ }.freeze
20
+
21
+ def initialize(port, opt = {})
22
+ @port = port.freeze
23
+ @opts = DEFAULTS.merge(opt.dup).freeze
24
+ @io = nil
25
+ end
26
+
27
+ # @return [Either] monad representing a value of one of two possible types
28
+ # 1. Exception covariant
29
+ # 2. Adapter interface invariant
30
+ #
31
+ # @see Adapters#new_serial_adapter
32
+ #
33
+ def connect
34
+ io = Rs232.new(@port)
35
+ io.connecting_timeout = @opts[:timeout].to_i if p.respond_to?(:connecting_timeout)
36
+ io.open
37
+ io.baud_rate = @opts[:baud_rate].to_i
38
+ io.data_bits = @opts[:data_bits].to_i
39
+ io.parity = @opts[:parity].to_i
40
+ io.stop_bits = @opts[:stop_bits].to_i
41
+ io.flow_control = @opts[:flow_control].to_i
42
+ @io = io
43
+ Either.right(self)
44
+ rescue Exception => ex
45
+ Either.left(ex)
46
+ end
47
+
48
+ def write(bytes)
49
+ raise NotConnected unless open?
50
+ Either.right(@io.write(bytes))
51
+ rescue => ex
52
+ Either.left(ex)
53
+ end
54
+
55
+ def close
56
+ return !open? unless open?
57
+ @io && @io.close
58
+ @io = nil
59
+ !open?
60
+ end
61
+
62
+ def flush
63
+ @io && @io.flush
64
+ end
65
+
66
+ def open?
67
+ @io && !@io.closed?
68
+ end
69
+
70
+ def read(count, blocking = false)
71
+ raise NotConnected unless open?
72
+ array = []
73
+
74
+ bytes_count = (count == -1) ? @io.available? : count
75
+
76
+ if blocking
77
+ bytes = read_io_until(count, count)
78
+ array.push bytes if bytes
79
+ else
80
+ bytes_count.times do
81
+ byte = @io.read(1)
82
+ array.push byte if byte
83
+ end
84
+ end
85
+ Either.right(array.empty? ? nil : array.join)
86
+ rescue => ex
87
+ Either.left(ex)
88
+ end
89
+
90
+ private
91
+
92
+ # @api private
93
+ #
94
+ # simulate blocking function
95
+ #
96
+ # @param [Fixnum] count
97
+ # @param [Fixnum] up_to
98
+ #
99
+ # no direct ruby usage
100
+ #
101
+ def block_io_until(count, up_to)
102
+ up_to -= 1 while @io.available? < count && up_to > 0
103
+ up_to > 0
104
+ end
105
+
106
+ # @api private
107
+ #
108
+ # simulate blocking function
109
+ #
110
+ # @param [Fixnum] count
111
+ # @param [Fixnum] up_to
112
+ #
113
+ # no direct ruby usage
114
+ #
115
+ def read_io_until(count, up_to)
116
+ sleep 0.001 until block_io_until(count, up_to)
117
+ read(count)
118
+ end
11
119
  end
12
120
  end
13
121
  end
@@ -10,47 +10,32 @@ module Digital
10
10
  include Digital::Transport::Errors
11
11
  include Digital::Transport::Adapters::Interface
12
12
 
13
- DEFAULTS = { timeout: 10 }.freeze
13
+ DEFAULTS = { timeout: 10, tcp_no_delay: 1 }.freeze
14
14
 
15
- def initialize(ip, port)
16
- @ip = ip
15
+ def initialize(ip, port, opts = {})
16
+ @ip = ip.freeze
17
+ @opts = DEFAULTS.merge(opts.dup).freeze
17
18
  @port = port
18
19
  @io = nil
19
- yield self if block_given?
20
20
  end
21
21
 
22
- # @return [Either] either monad representing a value of one of two possible types
22
+ # @return [Either] monad representing a value of one of two possible types
23
23
  # 1. Exception covariant
24
24
  # 2. Adapter interface invariant
25
25
  #
26
- # @example
26
+ # @see Adapters#new_tcp_adapter
27
27
  #
28
- # include Digital::Transport::Adapters
29
- #
30
- # on_success = -> x {
31
- # puts "connection open? -> #{x.open?}"
32
- # x.write("Hello, World!") =>
33
- # x.read 2 #=>
34
- # }
35
- # on_failure = -> x { puts "Wasn't able to connect due to: #{x.message}" }
36
- #
37
- # maybe = new_tcp_adapter('10.0.0.250', 12000).connect
38
- # maybe.either(on_failure, on_success)
39
- #
40
- def connect(opt = { timeout: 10, tcp_no_delay: 1 })
28
+ def connect
41
29
  return open? if open?
42
- map = opt.dup.freeze
43
30
  Socket.new(AF_INET, SOCK_STREAM, 0).tap do |socket|
44
- socket.setsockopt(IPPROTO_TCP, TCP_NODELAY, map[:tcp_nodelay].to_i)
31
+ socket.setsockopt(IPPROTO_TCP, TCP_NODELAY, (@opts[:tcp_nodelay] || DEFAULTS[:tcp_no_delay]).to_i)
45
32
  return connect_nonblock(
46
33
  socket,
47
34
  Socket.pack_sockaddr_in(@port, @ip),
48
- map[:timeout].to_i.nonzero? || DEFAULTS[:timeout])
35
+ @opts[:timeout].to_i.nonzero? || DEFAULTS[:timeout])
49
36
  end
50
37
  end
51
38
 
52
- # @raise [Errno::ECONNRESET] if connection reset by peer
53
- #
54
39
  # @return [Boolean] representing operation state
55
40
  def close
56
41
  return !open? unless open?
@@ -60,14 +45,11 @@ module Digital
60
45
  !open?
61
46
  end
62
47
 
63
- # @raise [Errno::ECONNRESET] if connection reset by peer
64
- # @return [Ethernet] it self
65
48
  def flush
66
49
  @io && @io.flush
67
50
  end
68
51
 
69
52
  # @param [String] string
70
- # @return [Fixnum] representing amount of bytes written
71
53
  def write(string)
72
54
  raise NotConnected unless open?
73
55
  written = 0
@@ -90,10 +72,9 @@ module Digital
90
72
 
91
73
  # @param [Fixnum] count how many bytes to read
92
74
  # @param [Boolean] should_block which will simulate blocking function
93
- # @return [String, nil] the String which was received or nil otherwise
94
75
  def read(count, should_block = false)
95
76
  raise NotConnected unless open?
96
- Either.right @io.read_nonblock(count).tap
77
+ Either.right @io.read_nonblock(count)
97
78
  rescue IO::WaitReadable
98
79
  if should_block
99
80
  IO.select [@io]
@@ -111,6 +92,7 @@ module Digital
111
92
 
112
93
  private
113
94
 
95
+ # @api private
114
96
  def connect_nonblock(io_like, endpoint, timeout)
115
97
  io_like.connect_nonblock(endpoint)
116
98
  rescue Errno::EINPROGRESS # connection in progress, wait a bit.
@@ -1,5 +1,5 @@
1
1
  module Digital
2
2
  module Transport
3
- VERSION = "0.1.0"
3
+ VERSION = "0.2.0".freeze
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: digital-transport
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Roman Lishtaba