nstrct 0.1.3 → 0.1.5
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 +4 -4
- data/.travis.yml +6 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +6 -4
- data/README.md +2 -2
- data/Rakefile +7 -0
- data/cross_platform_test +11 -11
- data/lib/nstrct/argument.rb +65 -65
- data/lib/nstrct/frame.rb +5 -5
- data/lib/nstrct/instruction.rb +9 -13
- data/lib/nstrct/version.rb +1 -1
- data/spec/protocol_spec.rb +18 -14
- metadata +10 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7a26c54c7028ec20750d4ee5e4d88509c7f74616
|
4
|
+
data.tar.gz: 2a89f910a4b0e226174536167c1efa1c05d0309a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6f3e1716890fb3a47fe4506fb6db39fb18f256e0a7fe3ef2f855ff2a1b9eeacba5366b03ea5384234da7c752c9dd7682a11083cad09443f7e0bbec25b31c0b44
|
7
|
+
data.tar.gz: e7044f1ef72deb00c9502e555f560cd5aae395122b13060baf41145a3149c538a35cb2ffe4b02fbf765a2c8593e464254fe41fcbc472720a8ce17a4652df5aea
|
data/.travis.yml
ADDED
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
nstrct (0.1.
|
4
|
+
nstrct (0.1.5)
|
5
5
|
digest-crc
|
6
6
|
|
7
7
|
GEM
|
@@ -9,18 +9,20 @@ GEM
|
|
9
9
|
specs:
|
10
10
|
diff-lcs (1.2.5)
|
11
11
|
digest-crc (0.4.0)
|
12
|
+
rake (10.1.1)
|
12
13
|
rspec (2.14.1)
|
13
14
|
rspec-core (~> 2.14.0)
|
14
15
|
rspec-expectations (~> 2.14.0)
|
15
16
|
rspec-mocks (~> 2.14.0)
|
16
|
-
rspec-core (2.14.
|
17
|
-
rspec-expectations (2.14.
|
17
|
+
rspec-core (2.14.8)
|
18
|
+
rspec-expectations (2.14.5)
|
18
19
|
diff-lcs (>= 1.1.3, < 2.0)
|
19
|
-
rspec-mocks (2.14.
|
20
|
+
rspec-mocks (2.14.6)
|
20
21
|
|
21
22
|
PLATFORMS
|
22
23
|
ruby
|
23
24
|
|
24
25
|
DEPENDENCIES
|
25
26
|
nstrct!
|
27
|
+
rake
|
26
28
|
rspec
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# nstrct-ruby
|
1
|
+
# nstrct-ruby [](https://travis-ci.org/nstrct/nstrct-ruby) [](https://codeclimate.com/github/nstrct/nstrct-ruby)
|
2
2
|
|
3
3
|
**a multi-purpose binary protocol for instruction interchange**
|
4
4
|
|
@@ -13,7 +13,7 @@ The protcol **nstrct** is designed to be an alternative in those situations wher
|
|
13
13
|
* [Obj-C (nstrct-objc)](http://github.com/nstrct/nstrct-objc)
|
14
14
|
* [Java (nstrct-c)](http://github.com/nstrct/nstrct-java)
|
15
15
|
|
16
|
-
_This software has been open sourced by [ElectricFeel Mobility Systems
|
16
|
+
_This software has been open sourced by [ElectricFeel Mobility Systems GmbH](http://electricfeel.com) and is further maintained by [Joël Gähwiler](http://github.com/256dpi)._
|
17
17
|
|
18
18
|
## Instruction Composing
|
19
19
|
|
data/Rakefile
ADDED
data/cross_platform_test
CHANGED
@@ -8,22 +8,22 @@ require 'nstrct'
|
|
8
8
|
mode = nil
|
9
9
|
|
10
10
|
MIN = {
|
11
|
-
int8: (2**7)
|
12
|
-
int16: (2**15)
|
13
|
-
int32: (2**31)
|
14
|
-
int64: (2**63)
|
11
|
+
int8: (2 ** 7) * -1,
|
12
|
+
int16: (2 ** 15) * -1,
|
13
|
+
int32: (2 ** 31) * -1,
|
14
|
+
int64: (2 ** 63) * -1
|
15
15
|
}
|
16
16
|
|
17
17
|
MAX = {
|
18
|
-
uint8: (2**8)-1,
|
19
|
-
uint16: (2**16)-1,
|
20
|
-
uint32: (2**32)-1,
|
21
|
-
uint64: (2**64)-1,
|
22
|
-
float32: 3.4028234663852886*(10**38),
|
23
|
-
float64: 1.7976931348623157*(10**308)
|
18
|
+
uint8: (2 ** 8) - 1,
|
19
|
+
uint16: (2 ** 16) - 1,
|
20
|
+
uint32: (2 ** 32) - 1,
|
21
|
+
uint64: (2 ** 64) - 1,
|
22
|
+
float32: 3.4028234663852886 * (10 ** 38),
|
23
|
+
float64: 1.7976931348623157 * (10 ** 308)
|
24
24
|
}
|
25
25
|
|
26
|
-
def assert
|
26
|
+
def assert(test, exp)
|
27
27
|
unless exp
|
28
28
|
puts test
|
29
29
|
exit!
|
data/lib/nstrct/argument.rb
CHANGED
@@ -20,47 +20,47 @@ module Nstrct
|
|
20
20
|
}
|
21
21
|
|
22
22
|
# Get the datatype of a argument code
|
23
|
-
def self.datatype_by_for_argument_code
|
24
|
-
DATATYPES.detect{ |k,v| v == code }[0]
|
23
|
+
def self.datatype_by_for_argument_code(code)
|
24
|
+
DATATYPES.detect { |k, v| v == code }[0]
|
25
25
|
end
|
26
26
|
|
27
27
|
# Parse a single value of a buffer
|
28
|
-
def self.parse_value
|
28
|
+
def self.parse_value(datatype, data)
|
29
29
|
case datatype
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
30
|
+
when :boolean
|
31
|
+
return data.slice!(0).unpack('C')[0] == 1
|
32
|
+
when :int8
|
33
|
+
return data.slice!(0).unpack('c')[0]
|
34
|
+
when :int16
|
35
|
+
return data.slice!(0..1).unpack('s>')[0]
|
36
|
+
when :int32
|
37
|
+
return data.slice!(0..3).unpack('l>')[0]
|
38
|
+
when :int64
|
39
|
+
return data.slice!(0..7).unpack('q>')[0]
|
40
|
+
when :uint8
|
41
|
+
return data.slice!(0).unpack('C')[0]
|
42
|
+
when :uint16
|
43
|
+
return data.slice!(0..1).unpack('S>')[0]
|
44
|
+
when :uint32
|
45
|
+
return data.slice!(0..3).unpack('L>')[0]
|
46
|
+
when :uint64
|
47
|
+
return data.slice!(0..7).unpack('Q>')[0]
|
48
|
+
when :float32
|
49
|
+
return data.slice!(0..3).unpack('g')[0]
|
50
|
+
when :float64
|
51
|
+
return data.slice!(0..7).unpack('G')[0]
|
52
|
+
when :string
|
53
|
+
length = data.slice!(0).unpack('C')[0]
|
54
|
+
return length > 0 ? data.slice!(0..length - 1) : ''
|
55
|
+
when :array
|
56
|
+
raise 'cannot parse array value directly'
|
57
|
+
else
|
58
|
+
raise "datatype '#{datatype}' not recognized"
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
62
62
|
# Parse a single argument from a buffer
|
63
|
-
def self.parse
|
63
|
+
def self.parse(data)
|
64
64
|
datatype = self.datatype_by_for_argument_code(data.slice!(0).unpack('C')[0])
|
65
65
|
if datatype == :array
|
66
66
|
array_datatype = self.datatype_by_for_argument_code(data.slice!(0).unpack('C')[0])
|
@@ -78,42 +78,42 @@ module Nstrct
|
|
78
78
|
attr_reader :datatype, :value, :array
|
79
79
|
|
80
80
|
# Instantiate a new Argument providing its datatype, value and arrayness
|
81
|
-
def initialize
|
82
|
-
@datatype, @value, @array = datatype, value, array
|
81
|
+
def initialize(datatype, value, array)
|
82
|
+
@datatype, @value, @array = datatype.to_sym, value, array
|
83
83
|
end
|
84
84
|
|
85
85
|
# Pack a single value in a buffer
|
86
|
-
def pack_value
|
86
|
+
def pack_value(datatype, value, data)
|
87
87
|
case datatype
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
88
|
+
when :boolean
|
89
|
+
data += [to_boolean(value) ? 1 : 0].pack('C')
|
90
|
+
when :int8
|
91
|
+
data += [value.to_i].pack('c')
|
92
|
+
when :int16
|
93
|
+
data += [value.to_i].pack('s>')
|
94
|
+
when :int32
|
95
|
+
data += [value.to_i].pack('l>')
|
96
|
+
when :int64
|
97
|
+
data += [value.to_i].pack('q>')
|
98
|
+
when :uint8
|
99
|
+
data += [value.to_i].pack('C')
|
100
|
+
when :uint16
|
101
|
+
data += [value.to_i].pack('S>')
|
102
|
+
when :uint32
|
103
|
+
data += [value.to_i].pack('L>')
|
104
|
+
when :uint64
|
105
|
+
data += [value.to_i].pack('Q>')
|
106
|
+
when :float32
|
107
|
+
data += [value.to_f].pack('g')
|
108
|
+
when :float64
|
109
|
+
data += [value.to_f].pack('G')
|
110
|
+
when :string
|
111
|
+
data += [value.to_s.size].pack('C')
|
112
|
+
data += value.to_s
|
113
|
+
when :array
|
114
|
+
raise 'cannot pack array value directly'
|
115
|
+
else
|
116
|
+
raise "datatype '#{datatype}' not recognized"
|
117
117
|
end
|
118
118
|
data
|
119
119
|
end
|
data/lib/nstrct/frame.rb
CHANGED
@@ -13,17 +13,17 @@ module Nstrct
|
|
13
13
|
FRAME_START = 0x55
|
14
14
|
FRAME_END = 0xAA
|
15
15
|
|
16
|
-
def self.crc32
|
16
|
+
def self.crc32(buffer)
|
17
17
|
Digest::CRC32.checksum buffer
|
18
18
|
end
|
19
19
|
|
20
|
-
def self.available?
|
20
|
+
def self.available?(buffer)
|
21
21
|
if buffer.size >= 1
|
22
22
|
raise StartOfFrameInvalid unless buffer.slice(0).unpack('C')[0] == FRAME_START
|
23
23
|
if buffer.size >= 3
|
24
24
|
payload_length = buffer.slice(1..2).unpack('S>')[0]
|
25
|
-
if buffer.size >= (payload_length+FRAME_OVERHEAD)
|
26
|
-
raise EndOfFrameInvalid unless buffer.slice(payload_length+FRAME_OVERHEAD-1).unpack('C')[0] == FRAME_END
|
25
|
+
if buffer.size >= (payload_length + FRAME_OVERHEAD)
|
26
|
+
raise EndOfFrameInvalid unless buffer.slice(payload_length + FRAME_OVERHEAD - 1).unpack('C')[0] == FRAME_END
|
27
27
|
return true
|
28
28
|
end
|
29
29
|
end
|
@@ -35,7 +35,7 @@ module Nstrct
|
|
35
35
|
raise NoFrameAvailable unless self.available?(buffer)
|
36
36
|
buffer.slice!(0) # remove start of frame
|
37
37
|
length = buffer.slice!(0..1).unpack('S>')[0]
|
38
|
-
payload = buffer.slice!(0..length-1)
|
38
|
+
payload = buffer.slice!(0..length - 1)
|
39
39
|
checksum = buffer.slice!(0..3).unpack('L>')[0]
|
40
40
|
buffer.slice!(0) # remove end of frame
|
41
41
|
raise ChecksumInvalid unless checksum == crc32(payload)
|
data/lib/nstrct/instruction.rb
CHANGED
@@ -5,7 +5,7 @@ module Nstrct
|
|
5
5
|
attr_accessor :code, :arguments
|
6
6
|
|
7
7
|
# Parse one message from the data stream.
|
8
|
-
def self.parse
|
8
|
+
def self.parse(data)
|
9
9
|
code = data.slice!(0..1).unpack('s>')[0]
|
10
10
|
num_arguments = data.slice!(0).unpack('C')[0]
|
11
11
|
data.slice!(0..1) # num_array_elements
|
@@ -20,31 +20,30 @@ module Nstrct
|
|
20
20
|
#
|
21
21
|
# Message.build_instruction 54, [ :boolean, true], [[:int8], [7, 8, 9]] ]
|
22
22
|
#
|
23
|
-
def self.build
|
24
|
-
arguments =
|
25
|
-
args.each do |arg|
|
23
|
+
def self.build(code, *args)
|
24
|
+
arguments = args.map do |arg|
|
26
25
|
if arg[0].is_a?(Array)
|
27
|
-
|
26
|
+
Nstrct::Argument.new(arg[0][0], arg[1], true)
|
28
27
|
else
|
29
|
-
|
28
|
+
Nstrct::Argument.new(arg[0], arg[1], false)
|
30
29
|
end
|
31
30
|
end
|
32
31
|
self.new(code, arguments)
|
33
32
|
end
|
34
33
|
|
35
34
|
# Instantiate a new instruction by its code and alist of arguments
|
36
|
-
def initialize
|
35
|
+
def initialize(code, arguments = [])
|
37
36
|
@code, @arguments = code, arguments
|
38
37
|
end
|
39
38
|
|
40
39
|
# Get all the arguments values
|
41
40
|
def argument_values
|
42
|
-
@arguments.map{ |arg| arg.value }
|
41
|
+
@arguments.map { |arg| arg.value }
|
43
42
|
end
|
44
43
|
|
45
44
|
# get all elements in arrays
|
46
45
|
def array_elements
|
47
|
-
@arguments.inject(0){ |sum, a| sum + (a.array ? a.value.is_a?(Array) ? a.value.size : 0 : 0) }
|
46
|
+
@arguments.inject(0) { |sum, a| sum + (a.array ? a.value.is_a?(Array) ? a.value.size : 0 : 0) }
|
48
47
|
end
|
49
48
|
|
50
49
|
# Pack a single instruction in a buffer
|
@@ -52,10 +51,7 @@ module Nstrct
|
|
52
51
|
message = [@code].pack('s>')
|
53
52
|
message += [@arguments.size].pack('C')
|
54
53
|
message += [array_elements].pack('s>')
|
55
|
-
@arguments.
|
56
|
-
message += arg.pack
|
57
|
-
end
|
58
|
-
message
|
54
|
+
@arguments.inject(message) { |msg, arg| msg + arg.pack }
|
59
55
|
end
|
60
56
|
|
61
57
|
# Return a comparable inspection
|
data/lib/nstrct/version.rb
CHANGED
data/spec/protocol_spec.rb
CHANGED
@@ -3,13 +3,17 @@ require 'spec_helper'
|
|
3
3
|
describe Nstrct::Argument do
|
4
4
|
|
5
5
|
it 'should coerce string booleans' do
|
6
|
-
Nstrct::Argument.new(:boolean, 'true', false).pack.
|
7
|
-
Nstrct::Argument.new(:boolean, 'false', false).pack.
|
8
|
-
Nstrct::Argument.new(:boolean, true, false).pack.
|
9
|
-
Nstrct::Argument.new(:boolean, false, false).pack.
|
10
|
-
Nstrct::Argument.new(:boolean, 1, false).pack.
|
11
|
-
Nstrct::Argument.new(:boolean, 0, false).pack.
|
12
|
-
Nstrct::Argument.new(:boolean, 2, false).pack.
|
6
|
+
expect(Nstrct::Argument.new(:boolean, 'true', false).pack).to eq("\x01\x01")
|
7
|
+
expect(Nstrct::Argument.new(:boolean, 'false', false).pack).to eq("\x01\x00")
|
8
|
+
expect(Nstrct::Argument.new(:boolean, true, false).pack).to eq("\x01\x01")
|
9
|
+
expect(Nstrct::Argument.new(:boolean, false, false).pack).to eq("\x01\x00")
|
10
|
+
expect(Nstrct::Argument.new(:boolean, 1, false).pack).to eq("\x01\x01")
|
11
|
+
expect(Nstrct::Argument.new(:boolean, 0, false).pack).to eq("\x01\x00")
|
12
|
+
expect(Nstrct::Argument.new(:boolean, 2, false).pack).to eq("\x01\x01")
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'should allow string datatypes' do
|
16
|
+
expect(Nstrct::Argument.new('boolean', 2, false).pack).to eq("\x01\x01")
|
13
17
|
end
|
14
18
|
|
15
19
|
it 'should treat wrong arrays' do
|
@@ -23,13 +27,13 @@ describe Nstrct::Instruction do
|
|
23
27
|
it 'should pack and unpack an empty instruction' do
|
24
28
|
instruction1 = Nstrct::Instruction.new(382, [])
|
25
29
|
instruction2 = Nstrct::Instruction.parse(instruction1.pack)
|
26
|
-
instruction1.inspect.
|
30
|
+
expect(instruction1.inspect).to eq(instruction2.inspect)
|
27
31
|
end
|
28
32
|
|
29
33
|
it 'should pack and unpack an instructionw with arguments' do
|
30
34
|
instruction1 = Nstrct::Instruction.build(232, [:float32, 1.0 ], [[:boolean], []], [:boolean, true], [:int8, 2], [:float32, 1.0], [[:uint16], [54, 23, 1973]])
|
31
35
|
instruction2 = Nstrct::Instruction.parse(instruction1.pack)
|
32
|
-
instruction1.inspect.
|
36
|
+
expect(instruction1.inspect).to eq(instruction2.inspect)
|
33
37
|
end
|
34
38
|
|
35
39
|
end
|
@@ -39,7 +43,7 @@ describe Nstrct::Frame do
|
|
39
43
|
it 'should pack and unpack a frame' do
|
40
44
|
frame1 = Nstrct::Frame.new(Nstrct::Instruction.new(132, []))
|
41
45
|
frame2 = Nstrct::Frame.parse(frame1.pack)
|
42
|
-
frame1.inspect.
|
46
|
+
expect(frame1.inspect).to eq(frame2.inspect)
|
43
47
|
end
|
44
48
|
|
45
49
|
describe 'errors' do
|
@@ -47,24 +51,24 @@ describe Nstrct::Frame do
|
|
47
51
|
let(:frame) { Nstrct::Frame.new(Nstrct::Instruction.new(132, [])) }
|
48
52
|
|
49
53
|
it 'should raise start of frame invalid' do
|
50
|
-
expect{ Nstrct::Frame.parse('hello') }.to raise_error Nstrct::Frame::StartOfFrameInvalid
|
54
|
+
expect { Nstrct::Frame.parse('hello') }.to raise_error Nstrct::Frame::StartOfFrameInvalid
|
51
55
|
end
|
52
56
|
|
53
57
|
it 'should raise end of frame invalid' do
|
54
58
|
data = frame.pack
|
55
59
|
data[-1] = 'B'
|
56
|
-
expect{ Nstrct::Frame.parse(data) }.to raise_error Nstrct::Frame::EndOfFrameInvalid
|
60
|
+
expect { Nstrct::Frame.parse(data) }.to raise_error Nstrct::Frame::EndOfFrameInvalid
|
57
61
|
end
|
58
62
|
|
59
63
|
it 'should raise no frame available' do
|
60
64
|
data = frame.pack.slice(-1..-4)
|
61
|
-
expect{ Nstrct::Frame.parse(data) }.to raise_error Nstrct::Frame::NoFrameAvailable
|
65
|
+
expect { Nstrct::Frame.parse(data) }.to raise_error Nstrct::Frame::NoFrameAvailable
|
62
66
|
end
|
63
67
|
|
64
68
|
it 'should raise checksum invalid' do
|
65
69
|
data = frame.pack
|
66
70
|
data[-2] = 'C'
|
67
|
-
expect{ Nstrct::Frame.parse(data) }.to raise_error Nstrct::Frame::ChecksumInvalid
|
71
|
+
expect { Nstrct::Frame.parse(data) }.to raise_error Nstrct::Frame::ChecksumInvalid
|
68
72
|
end
|
69
73
|
|
70
74
|
end
|
metadata
CHANGED
@@ -1,27 +1,27 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nstrct
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joël Gähwiler
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-03-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: digest-crc
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
description: Interchange formats like json or xml are great to keep data visible,
|
@@ -35,11 +35,13 @@ executables: []
|
|
35
35
|
extensions: []
|
36
36
|
extra_rdoc_files: []
|
37
37
|
files:
|
38
|
-
- .gitignore
|
38
|
+
- ".gitignore"
|
39
|
+
- ".travis.yml"
|
39
40
|
- Gemfile
|
40
41
|
- Gemfile.lock
|
41
42
|
- LICENSE.txt
|
42
43
|
- README.md
|
44
|
+
- Rakefile
|
43
45
|
- cross_platform_test
|
44
46
|
- lib/nstrct.rb
|
45
47
|
- lib/nstrct/argument.rb
|
@@ -59,17 +61,17 @@ require_paths:
|
|
59
61
|
- lib
|
60
62
|
required_ruby_version: !ruby/object:Gem::Requirement
|
61
63
|
requirements:
|
62
|
-
- -
|
64
|
+
- - ">="
|
63
65
|
- !ruby/object:Gem::Version
|
64
66
|
version: '0'
|
65
67
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
66
68
|
requirements:
|
67
|
-
- -
|
69
|
+
- - ">="
|
68
70
|
- !ruby/object:Gem::Version
|
69
71
|
version: '0'
|
70
72
|
requirements: []
|
71
73
|
rubyforge_project:
|
72
|
-
rubygems_version: 2.0
|
74
|
+
rubygems_version: 2.2.0
|
73
75
|
signing_key:
|
74
76
|
specification_version: 4
|
75
77
|
summary: a multi-purpose binary protocol for instruction interchange
|