boss-protocol 0.0.1 → 0.0.2
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 +56 -15
- data/boss-protocol.gemspec +1 -1
- data/lib/boss-protocol.rb +28 -16
- data/lib/boss-protocol/version.rb +1 -1
- data/samples/testp.rb +25 -0
- metadata +4 -3
data/README.md
CHANGED
@@ -2,26 +2,32 @@
|
|
2
2
|
|
3
3
|
BOSS is acronym for Binary Object Streamable Storage.
|
4
4
|
|
5
|
-
The very space-effective,
|
6
|
-
Allow to effectively store small or
|
7
|
-
any
|
8
|
-
|
9
|
-
|
10
|
-
repeating objects and stores/restores links to objects.
|
5
|
+
The very space-effective, platform-independent^ streamable and traversable
|
6
|
+
typed binary protocol. Allow to effectively store small or any sized integers,
|
7
|
+
strings or binary data of any size, floats and doubles, arrays and hashes in a
|
8
|
+
very effective way. It caches repeating objects and stores/restores links to
|
9
|
+
objects.
|
11
10
|
|
12
|
-
|
13
|
-
|
11
|
+
The protocol allow to effectively store texts and binary data of absolutely any
|
12
|
+
size, signed integers of absolutely any size, arrays and hashes with no limit
|
13
|
+
on items and overall gross size. It is desirable to use build-in compression when
|
14
|
+
appropriate.
|
15
|
+
|
16
|
+
Streamable means that you can use a pipe (tcp/ip, wahtever), put the object at
|
17
|
+
one side and load it on other, one-by-one, and caching and links will be
|
18
|
+
restored properly.
|
14
19
|
|
15
20
|
Initially, this protocol was intended to be used in secure communications. Its
|
16
|
-
main goal was to very effective data sending and is a great replacement for
|
17
|
-
JSON reduces in size twice with Boss.
|
21
|
+
main goal was to very effective data sending and is a great replacement for
|
22
|
+
json/boss/whatever. For example, typical JSON reduces in size twice with Boss.
|
18
23
|
|
19
24
|
Boss protocol also allow to transparently compress its representations.
|
20
25
|
|
21
|
-
*Attention* ruby version is under final development, its streaming support may
|
22
|
-
seem to work just fine.
|
26
|
+
*Attention* ruby version is under final development, its streaming support may
|
27
|
+
not work as expected, while the rest seem to work just fine.
|
23
28
|
|
24
|
-
There are versions in C and Python that are in most part ready
|
29
|
+
There are versions in C and Python that are in most part ready but are parts
|
30
|
+
in other systems and need to be extracted first.
|
25
31
|
|
26
32
|
## Installation
|
27
33
|
|
@@ -37,7 +43,7 @@ Or install it yourself as:
|
|
37
43
|
|
38
44
|
$ gem install boss-protocol
|
39
45
|
|
40
|
-
## Usage
|
46
|
+
## Simple Usage
|
41
47
|
|
42
48
|
1.9.3-p327 :011 > require 'boss-protocol'
|
43
49
|
=> false
|
@@ -66,7 +72,42 @@ To use the transparent compression:
|
|
66
72
|
1.9.3-p327 :017 > data == Boss.load(x)
|
67
73
|
=> true
|
68
74
|
|
69
|
-
Streaming
|
75
|
+
## Streaming sample
|
76
|
+
|
77
|
+
Cehck the code in samples folder.
|
78
|
+
|
79
|
+
This sample shows boss object passing between 2 forked processes:
|
80
|
+
|
81
|
+
if fork
|
82
|
+
wr.close
|
83
|
+
if true
|
84
|
+
# You can do it with block:
|
85
|
+
Boss::Parser.new(rd).each { |obj| puts "Got an object: #{obj}" }
|
86
|
+
else
|
87
|
+
# You can do it without block too:
|
88
|
+
input = Boss::Parser.new rd
|
89
|
+
puts "Got an object: #{input.get}" while !input.eof?
|
90
|
+
end
|
91
|
+
rd.close
|
92
|
+
Process.wait
|
93
|
+
else
|
94
|
+
rd.close
|
95
|
+
out = Boss::Formatter.new wr
|
96
|
+
out << ["Foo", "bar"]
|
97
|
+
out.put_compressed "Zz"*62
|
98
|
+
out << ["Hello", "world", "!"]
|
99
|
+
out << { "Thats all" => "folks!" }
|
100
|
+
wr.close
|
101
|
+
end
|
102
|
+
|
103
|
+
Boss ways in the sample are identical; second one (with get) may be sometimes
|
104
|
+
more convenient, say, to terminate object polling on some condition before eof.
|
105
|
+
|
106
|
+
So, all you need is IO-like object that provide io.read(length) and io.write(data) to
|
107
|
+
read/write binary data. Usual files, pipes, tcp sockets, stringIO - everything is ok.
|
108
|
+
|
109
|
+
The protocol could be very effectively used to form higher level protocols over the
|
110
|
+
network as it caches data on the fly and can provide links (if used with
|
70
111
|
|
71
112
|
## Contributing
|
72
113
|
|
data/boss-protocol.gemspec
CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |gem|
|
|
9
9
|
gem.authors = ["sergeych"]
|
10
10
|
gem.email = ["real.sergeych@gmail.com"]
|
11
11
|
gem.description = %q{Binary streamable bit-effective protocol to effectively store object tree hierarchies}
|
12
|
-
gem.summary = %q{Traversable and streamable to
|
12
|
+
gem.summary = %q{Traversable and streamable to protocol supports lists, hashes, caching,
|
13
13
|
compression and more}
|
14
14
|
gem.homepage = ""
|
15
15
|
|
data/lib/boss-protocol.rb
CHANGED
@@ -44,8 +44,12 @@ require 'bzip2'
|
|
44
44
|
# No object serialization yet, no callables and bound methods - these appear to be
|
45
45
|
# non portable between platoforms.
|
46
46
|
#
|
47
|
+
# Please note that most of this code was developed in 2008 so it is kind of old ;)
|
48
|
+
# though working.
|
49
|
+
|
47
50
|
module Boss
|
48
|
-
|
51
|
+
|
52
|
+
# Basic types
|
49
53
|
TYPE_INT = 0
|
50
54
|
TYPE_EXTRA = 1
|
51
55
|
TYPE_NINT = 2
|
@@ -104,6 +108,10 @@ module Boss
|
|
104
108
|
@cache = { nil => 0 }
|
105
109
|
end
|
106
110
|
|
111
|
+
##
|
112
|
+
# same as put but automatically select and use proper compression. Parser.get
|
113
|
+
# will automatically decompress.
|
114
|
+
#
|
107
115
|
def put_compressed ob
|
108
116
|
data = Boss.dump(ob)
|
109
117
|
whdr TYPE_EXTRA, TCOMPRESSED
|
@@ -186,10 +194,9 @@ module Boss
|
|
186
194
|
|
187
195
|
##
|
188
196
|
# Get the result as string, may not work if
|
189
|
-
# some specific IO instance is
|
190
|
-
# works well with default
|
197
|
+
# some specific IO instance is passed to constructor.
|
198
|
+
# works well with default constructor or StringIO
|
191
199
|
def string
|
192
|
-
# p "string!! #{@io.string}"
|
193
200
|
@io.string
|
194
201
|
end
|
195
202
|
|
@@ -261,7 +268,7 @@ module Boss
|
|
261
268
|
# write binary value
|
262
269
|
#
|
263
270
|
def wbin(bb)
|
264
|
-
@io.
|
271
|
+
@io.write bb
|
265
272
|
end
|
266
273
|
|
267
274
|
##
|
@@ -273,12 +280,10 @@ module Boss
|
|
273
280
|
def wdouble val
|
274
281
|
wbin [val].pack('E')
|
275
282
|
end
|
276
|
-
|
277
|
-
|
278
283
|
end
|
279
284
|
|
280
285
|
##
|
281
|
-
# Parser
|
286
|
+
# Parser implements IO-like behavior and provides deserializing of
|
282
287
|
# BOSS objects. Parser can store multiple root objects and share same
|
283
288
|
# object cache for all them
|
284
289
|
class Parser
|
@@ -305,9 +310,9 @@ module Boss
|
|
305
310
|
code, value = rhdr
|
306
311
|
case code
|
307
312
|
when TYPE_INT
|
308
|
-
|
313
|
+
value
|
309
314
|
when TYPE_NINT
|
310
|
-
|
315
|
+
-value
|
311
316
|
when TYPE_EXTRA
|
312
317
|
case value
|
313
318
|
when TTRUE
|
@@ -342,18 +347,18 @@ module Boss
|
|
342
347
|
s = rbin value
|
343
348
|
s.force_encoding code == TYPE_BIN ? Encoding::BINARY : Encoding::UTF_8
|
344
349
|
@cache << s
|
345
|
-
|
350
|
+
s
|
346
351
|
when TYPE_LIST
|
347
352
|
# p "items", value
|
348
353
|
@cache << (list = [])
|
349
354
|
value.times { list << get }
|
350
|
-
|
355
|
+
list
|
351
356
|
when TYPE_DICT
|
352
357
|
@cache << (dict = { })
|
353
358
|
value.times { dict[get] = get }
|
354
|
-
|
359
|
+
dict
|
355
360
|
when TYPE_CREF
|
356
|
-
|
361
|
+
@cache[value]
|
357
362
|
else
|
358
363
|
raise UnknownTypeException
|
359
364
|
end
|
@@ -368,7 +373,6 @@ module Boss
|
|
368
373
|
##
|
369
374
|
# yields all objects in the stream
|
370
375
|
def each
|
371
|
-
@io.rewind
|
372
376
|
yield get until eof?
|
373
377
|
end
|
374
378
|
|
@@ -421,8 +425,12 @@ module Boss
|
|
421
425
|
rbin(8).unpack('E')[0]
|
422
426
|
end
|
423
427
|
|
428
|
+
def rfloat
|
429
|
+
rbin(4).unpack('e')[0]
|
430
|
+
end
|
431
|
+
|
424
432
|
def rbin(length)
|
425
|
-
@io.
|
433
|
+
@io.read length
|
426
434
|
end
|
427
435
|
end
|
428
436
|
|
@@ -462,6 +470,10 @@ module Boss
|
|
462
470
|
f.string
|
463
471
|
end
|
464
472
|
|
473
|
+
##
|
474
|
+
# Just like Boss.dump but automatically use proper compression
|
475
|
+
# depending on the data size. Boss.load or Boss.load_all will
|
476
|
+
# automatically decompress the data
|
465
477
|
def Boss.dump_compressed(*roots)
|
466
478
|
f = f = Formatter.new
|
467
479
|
roots.each { |r| f.put_compressed r }
|
data/samples/testp.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require '../lib/boss-protocol'
|
2
|
+
|
3
|
+
rd, wr = IO.pipe
|
4
|
+
|
5
|
+
if fork
|
6
|
+
wr.close
|
7
|
+
if false
|
8
|
+
# You can do it with block:
|
9
|
+
Boss::Parser.new(rd).each { |obj| puts "Got an object: #{obj}" }
|
10
|
+
else
|
11
|
+
# You can do it without block too:
|
12
|
+
input = Boss::Parser.new rd
|
13
|
+
puts "Got an object: #{input.get}" while !input.eof?
|
14
|
+
end
|
15
|
+
rd.close
|
16
|
+
Process.wait
|
17
|
+
else
|
18
|
+
rd.close
|
19
|
+
out = Boss::Formatter.new wr
|
20
|
+
out << ["Foo", "bar"]
|
21
|
+
out.put_compressed "Zz"*62
|
22
|
+
out << ["Hello", "world", "!"]
|
23
|
+
out << { "Thats all" => "folks!" }
|
24
|
+
wr.close
|
25
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: boss-protocol
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -60,6 +60,7 @@ files:
|
|
60
60
|
- boss-protocol.gemspec
|
61
61
|
- lib/boss-protocol.rb
|
62
62
|
- lib/boss-protocol/version.rb
|
63
|
+
- samples/testp.rb
|
63
64
|
- spec/boss_spec.rb
|
64
65
|
- spec/spec_helper.rb
|
65
66
|
homepage: ''
|
@@ -85,8 +86,8 @@ rubyforge_project:
|
|
85
86
|
rubygems_version: 1.8.24
|
86
87
|
signing_key:
|
87
88
|
specification_version: 3
|
88
|
-
summary: Traversable and streamable to
|
89
|
-
|
89
|
+
summary: Traversable and streamable to protocol supports lists, hashes, caching, compression
|
90
|
+
and more
|
90
91
|
test_files:
|
91
92
|
- spec/boss_spec.rb
|
92
93
|
- spec/spec_helper.rb
|