boss-protocol 0.0.2 → 0.1.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.
- data/README.md +22 -11
- data/lib/boss-protocol/version.rb +1 -1
- data/lib/boss-protocol.rb +6 -0
- data/spec/boss_spec.rb +31 -24
- metadata +1 -1
data/README.md
CHANGED
@@ -23,10 +23,21 @@ json/boss/whatever. For example, typical JSON reduces in size twice with Boss.
|
|
23
23
|
|
24
24
|
Boss protocol also allow to transparently compress its representations.
|
25
25
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
26
|
+
Supported types:
|
27
|
+
|
28
|
+
* Signed integers of any length
|
29
|
+
* Signed floats and doubles (4 or 8 bytes)
|
30
|
+
* Boolean values (true/false)
|
31
|
+
* UTF-8 encoded texts, any length
|
32
|
+
* Binary data, any length
|
33
|
+
* Time objects (rounded to 1s resolution)
|
34
|
+
* Arrays with any number of elements
|
35
|
+
* Hashes with any keys and values and unlimited length
|
36
|
+
* Reference to the object that already was serialized
|
37
|
+
|
38
|
+
There is a pending extension to serialize user types that will be available
|
39
|
+
soon or even faster - leave me a request in issues. There are also versions
|
40
|
+
in C and Python that are in most part ready but are parts
|
30
41
|
in other systems and need to be extracted first.
|
31
42
|
|
32
43
|
## Installation
|
@@ -74,9 +85,8 @@ To use the transparent compression:
|
|
74
85
|
|
75
86
|
## Streaming sample
|
76
87
|
|
77
|
-
|
78
|
-
|
79
|
-
This sample shows boss object passing between 2 forked processes:
|
88
|
+
This sample shows boss object hierarchies passing between 2 forked processes
|
89
|
+
using a pipe:
|
80
90
|
|
81
91
|
if fork
|
82
92
|
wr.close
|
@@ -96,15 +106,16 @@ This sample shows boss object passing between 2 forked processes:
|
|
96
106
|
out << ["Foo", "bar"]
|
97
107
|
out.put_compressed "Zz"*62
|
98
108
|
out << ["Hello", "world", "!"]
|
99
|
-
out << { "
|
109
|
+
out << { "That's all" => "folks!" }
|
100
110
|
wr.close
|
101
111
|
end
|
102
112
|
|
103
|
-
|
113
|
+
Both ways in the sample are identical; second one (with get) may be sometimes
|
104
114
|
more convenient, say, to terminate object polling on some condition before eof.
|
105
115
|
|
106
|
-
|
107
|
-
read/write binary data. Usual files,
|
116
|
+
All you need is IO-like object that provide io.read(length) on the read side
|
117
|
+
and io.write(data) on another, capable to read/write binary data. Usual files,
|
118
|
+
pipes, tcp sockets, stringIO - everything is ok.
|
108
119
|
|
109
120
|
The protocol could be very effectively used to form higher level protocols over the
|
110
121
|
network as it caches data on the fly and can provide links (if used with
|
data/lib/boss-protocol.rb
CHANGED
@@ -82,6 +82,7 @@ module Boss
|
|
82
82
|
TFALSE = 13
|
83
83
|
|
84
84
|
TCOMPRESSED = 14
|
85
|
+
TTIME = 15
|
85
86
|
|
86
87
|
def checkArg(cond, msg=nil)
|
87
88
|
raise ArgumentError unless cond
|
@@ -182,6 +183,9 @@ module Boss
|
|
182
183
|
whdr TYPE_EXTRA, ob ? TTRUE : TFALSE
|
183
184
|
when nil
|
184
185
|
whdr TYPE_CREF, 0
|
186
|
+
when Time
|
187
|
+
whdr TYPE_EXTRA, TTIME
|
188
|
+
wrenc ob.to_i
|
185
189
|
else
|
186
190
|
error = "error: not supported object: #{ob}, #{ob.class}"
|
187
191
|
p error
|
@@ -340,6 +344,8 @@ module Boss
|
|
340
344
|
else
|
341
345
|
raise UnknownTypeException, "type #{type}"
|
342
346
|
end
|
347
|
+
when TTIME
|
348
|
+
Time.at renc
|
343
349
|
else
|
344
350
|
raise UnknownTypeException
|
345
351
|
end
|
data/spec/boss_spec.rb
CHANGED
@@ -15,7 +15,7 @@ describe 'Boss' do
|
|
15
15
|
end
|
16
16
|
|
17
17
|
it 'should perform compatible decode' do
|
18
|
-
Vectors.each do |a,b|
|
18
|
+
Vectors.each do |a, b|
|
19
19
|
Boss.load(a).should == b
|
20
20
|
end
|
21
21
|
end
|
@@ -36,16 +36,23 @@ describe 'Boss' do
|
|
36
36
|
end
|
37
37
|
|
38
38
|
it 'should properly encode nil' do
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
39
|
+
round_check(1)
|
40
|
+
round_check(nil)
|
41
|
+
round_check([1])
|
42
|
+
round_check([nil, nil, nil, 3, 4, 5, nil])
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should encode Time' do
|
46
|
+
# Time is rounded to seconds on serialization, so we need
|
47
|
+
# take care of the comparison
|
48
|
+
t = Time.now
|
49
|
+
Boss.load(Boss.dump t).should be_within(1).of(t)
|
43
50
|
end
|
44
51
|
|
45
52
|
it 'should cache data' do
|
46
|
-
a
|
47
|
-
ca
|
48
|
-
b, c, d, e, f, g = Boss.load(Boss.dump([a,a,ca,ca, "oops", "oops"]))
|
53
|
+
a = [1, 2, 3, 4]
|
54
|
+
ca = { 1 => 55 }
|
55
|
+
b, c, d, e, f, g = Boss.load(Boss.dump([a, a, ca, ca, "oops", "oops"]))
|
49
56
|
a.should == b
|
50
57
|
b.should == c
|
51
58
|
b.should be_eql(c)
|
@@ -65,30 +72,30 @@ describe 'Boss' do
|
|
65
72
|
end
|
66
73
|
|
67
74
|
it 'should decode one by one using block' do
|
68
|
-
args = [1,2,3,4,5]
|
69
|
-
s
|
70
|
-
res
|
71
|
-
res
|
75
|
+
args = [1, 2, 3, 4, 5]
|
76
|
+
s = Boss.dump(*args)
|
77
|
+
res = []
|
78
|
+
res = Boss.load(s) { |x| x }
|
72
79
|
args.should == res
|
73
80
|
end
|
74
81
|
|
75
82
|
it 'should cache arrays and hashes too' do
|
76
83
|
d = { "Hello" => "world" }
|
77
|
-
a = [112,11]
|
78
|
-
r = Boss.load_all(Boss.dump(
|
79
|
-
[a,d,a,d].should == r
|
84
|
+
a = [112, 11]
|
85
|
+
r = Boss.load_all(Boss.dump(a, d, a, d))
|
86
|
+
[a, d, a, d].should == r
|
80
87
|
r[1].should be_equal(r[3])
|
81
88
|
r[0].should be_equal(r[2])
|
82
89
|
end
|
83
90
|
|
84
91
|
it 'should properly encode multilevel structures' do
|
85
|
-
root = { "level" => 1}
|
86
|
-
p
|
92
|
+
root = { "level" => 1 }
|
93
|
+
p = root
|
87
94
|
200.times { |n|
|
88
|
-
x
|
89
|
-
p['data']
|
95
|
+
x = { "level" => n+2 }
|
96
|
+
p['data'] = x
|
90
97
|
p['payload'] = 'great'
|
91
|
-
p
|
98
|
+
p = x
|
92
99
|
}
|
93
100
|
round_check root
|
94
101
|
end
|
@@ -97,13 +104,13 @@ describe 'Boss' do
|
|
97
104
|
it 'should effectively compress/decompress' do
|
98
105
|
# No compression
|
99
106
|
data = "Too short"
|
100
|
-
x0
|
107
|
+
x0 = Boss.dump_compressed data
|
101
108
|
Boss.load(x0).should == data
|
102
109
|
x0.length.should <= (data.length + 3)
|
103
110
|
|
104
111
|
# short compression: zlib
|
105
112
|
data = "z" * 1024
|
106
|
-
x1
|
113
|
+
x1 = Boss.dump_compressed data
|
107
114
|
Boss.load(x1).should == data
|
108
115
|
x1.length.should <= (data.length/10)
|
109
116
|
|
@@ -131,7 +138,7 @@ describe 'Boss' do
|
|
131
138
|
Vectors = [['8', 7], ["\xb8F", 70], [".\x00\x08\n8:", [0, 1, -1, 7, -7]], ["\xc8p\x11\x01", 70000],
|
132
139
|
['+Hello', 'Hello'], [',Hello', bytes!('Hello'), 2, 4, 4, 1]]
|
133
140
|
|
134
|
-
CompressedTestJson =
|
141
|
+
CompressedTestJson = <<-End
|
135
142
|
eJztfVlz20iy7vv5FQi9dHcExca++OWGLLvdXmTrWOrxmbm+MVEkimRZIMDG
|
136
143
|
Ipk+0f/9ZmZVAQVQpETKmhhPaKKn3ZaIIlCV+SGXLzP/978s+N/RktfsyHpm
|
137
144
|
/e9RVbO6qY6eHRVXR3+N5G9LXq2KvOLyE6LmS/jA/4X/So+e+bEzOsrZksMl
|
@@ -462,6 +469,6 @@ mizfqNHM4GxlFv0UHm8hpGOGRQjy2UGa17xW1dcpFlyBMPF0PL5HbDcJfHsz
|
|
462
469
|
GOPFwUaiO8beVd7QYfG/2yg0t2XZnuHHyrU8/A4qXN/xDugS4Wqi7R3L/rgI
|
463
470
|
ZPRlks8o0Gc+RzbVHfjjBc+8ffGnPSaQaU6ZDxOCIu82CDqxTouy6UhoFPN1
|
464
471
|
NhpXhYHtuZti57hJEhySiPp/f/3XX//1/wEcUSZF
|
465
|
-
End
|
472
|
+
End
|
466
473
|
|
467
474
|
end
|