boss-protocol 0.0.1

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/.gitignore ADDED
@@ -0,0 +1,21 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .DS_Store
19
+ .idea
20
+ .rbx
21
+ .rvmrc
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in boss-protocol.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2008-2012 sergeych
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,77 @@
1
+ # Boss Protocol
2
+
3
+ BOSS is acronym for Binary Object Streamable Storage.
4
+
5
+ The very space-effective, platfomr-independent streamable and traversable typed binary protocol.
6
+ Allow to effectively store small or
7
+ any
8
+ sized
9
+ integers, strings or binary data of any size, floats and doubles, arrays and hashes in a very effective way. It caches
10
+ repeating objects and stores/restores links to objects.
11
+
12
+ Streamable means that you can use a pipe (tcp/ip, wahtever), put the object at one side and load it on other, one-by-one,
13
+ and caching and links will be restored properly.
14
+
15
+ 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 json/boss/whatever. For example, typical
17
+ JSON reduces in size twice with Boss.
18
+
19
+ Boss protocol also allow to transparently compress its representations.
20
+
21
+ *Attention* ruby version is under final development, its streaming support may not work as expected, while the rest
22
+ seem to work just fine.
23
+
24
+ There are versions in C and Python that are in most part ready.
25
+
26
+ ## Installation
27
+
28
+ Add this line to your application's Gemfile:
29
+
30
+ gem 'boss-protocol'
31
+
32
+ And then execute:
33
+
34
+ $ bundle
35
+
36
+ Or install it yourself as:
37
+
38
+ $ gem install boss-protocol
39
+
40
+ ## Usage
41
+
42
+ 1.9.3-p327 :011 > require 'boss-protocol'
43
+ => false
44
+ 1.9.3-p327 :012 > data = { 'test' => [1, 2, -1.22, 'great!'] }
45
+ => {"test"=>[1, 2, -1.22, "great!"]}
46
+ 1.9.3-p327 :013 > x = Boss.dump data
47
+ => "\x0F#test&\b\x109\x85\xEBQ\xB8\x1E\x85\xF3\xBF3great!"
48
+ 1.9.3-p327 :014 > Marshal.dump data
49
+ => "\x04\b{\x06I\"\ttest\x06:\x06ET[\ti\x06i\af\n-1.22I\"\vgreat!\x06;\x00T"
50
+
51
+ Note that boss representation is smaller than ruby's Marshal one
52
+
53
+ 1.9.3-p327 :015 > Boss.load(x) == data
54
+ => true
55
+
56
+ To use the transparent compression:
57
+
58
+ 1.9.3-p327 :013 > data = "Boss is a very effective protocol!" * 4096; nil
59
+ => nil
60
+ 1.9.3-p327 :014 > data.length
61
+ => 139264
62
+ 1.9.3-p327 :015 > x = Boss.dump_compressed(data); nil
63
+ => nil
64
+ 1.9.3-p327 :016 > x.length
65
+ => 147
66
+ 1.9.3-p327 :017 > data == Boss.load(x)
67
+ => true
68
+
69
+ Streaming docs are in progress. Please wait.
70
+
71
+ ## Contributing
72
+
73
+ 1. Fork it
74
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
75
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
76
+ 4. Push to the branch (`git push origin my-new-feature`)
77
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'boss-protocol/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "boss-protocol"
8
+ gem.version = Boss::VERSION
9
+ gem.authors = ["sergeych"]
10
+ gem.email = ["real.sergeych@gmail.com"]
11
+ gem.description = %q{Binary streamable bit-effective protocol to effectively store object tree hierarchies}
12
+ gem.summary = %q{Traversable and streamable to some extend protocol supports lists, hashes, caching,
13
+ compression and more}
14
+ gem.homepage = ""
15
+
16
+ gem.files = `git ls-files`.split($/)
17
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
18
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
19
+ gem.require_paths = ["lib"]
20
+
21
+ gem.add_dependency 'bzip2-ruby'
22
+ gem.add_development_dependency "rspec"
23
+ end
@@ -0,0 +1,3 @@
1
+ module Boss
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,471 @@
1
+ require "boss-protocol/version"
2
+
3
+ # Encoding: utf-8
4
+ require 'stringio'
5
+ require 'zlib'
6
+ require 'bzip2'
7
+
8
+ # Copyright (c) 2008-2012 by sergeych (real.sergeych@gmail.com)
9
+ #
10
+ # MIT License
11
+ #
12
+ # Permission is hereby granted, free of charge, to any person obtaining
13
+ # a copy of this software and associated documentation files (the
14
+ # "Software"), to deal in the Software without restriction, including
15
+ # without limitation the rights to use, copy, modify, merge, publish,
16
+ # distribute, sublicense, and/or sell copies of the Software, and to
17
+ # permit persons to whom the Software is furnished to do so, subject to
18
+ # the following conditions:
19
+ #
20
+ # The above copyright notice and this permission notice shall be
21
+ # included in all copies or substantial portions of the Software.
22
+ #
23
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.#
30
+ #
31
+ # sergey.chernov@thrift.ru
32
+ #
33
+
34
+ ##
35
+ # Boss protocol version 1.2 basic implementation
36
+ #
37
+ # 1.2 version adds support for booelans and removes support for python __reduce__ - based objects
38
+ # as absolutely non portable. It also introduces
39
+ #
40
+ # 1.1 version changes the way to store bignums in header, now it is
41
+ # encoded <bytes_length> followed by the specified number of bytes
42
+ # LSB first
43
+ #
44
+ # No object serialization yet, no callables and bound methods - these appear to be
45
+ # non portable between platoforms.
46
+ #
47
+ module Boss
48
+ # Basic types
49
+ TYPE_INT = 0
50
+ TYPE_EXTRA = 1
51
+ TYPE_NINT = 2
52
+
53
+ TYPE_TEXT = 3
54
+ TYPE_BIN = 4
55
+ TYPE_CREF = 5
56
+ TYPE_LIST = 6
57
+ TYPE_DICT = 7
58
+
59
+ # Extra types:
60
+
61
+ DZERO = 0 #: float 0.0
62
+ FZERO = 1 #: double 0.0
63
+
64
+ DONE = 2 #: double 1.0
65
+ FONE = 3 #: float 1.0
66
+ DMINUSONE = 4 #: double -1.0
67
+ FMINUSONE = 5 #: float -1.0
68
+
69
+ TFLOAT = 6 #: 32-bit IEEE float
70
+ TDOUBLE = 7 #: 64-bit IEEE float
71
+
72
+ TOBJECT = 8 #: object record
73
+ TMETHOD = 9 #: instance method
74
+ TFUNCTION = 10 #: callable function
75
+ TGLOBREF = 11 #: global reference
76
+
77
+ TTRUE = 12
78
+ TFALSE = 13
79
+
80
+ TCOMPRESSED = 14
81
+
82
+ def checkArg(cond, msg=nil)
83
+ raise ArgumentError unless cond
84
+ end
85
+
86
+ class UnknownTypeException < Exception;
87
+ end
88
+
89
+ ##
90
+ # Formats ruby object hierarchies with BOSS
91
+ # notation
92
+ #
93
+ class Formatter
94
+
95
+ include Boss # for checkArg
96
+
97
+ ##
98
+ # Construct formatter for a given IO-like object
99
+ # or create StringIO one as output
100
+ #
101
+ def initialize(dst=nil)
102
+ @io = dst ? dst : StringIO.new('', 'wb')
103
+ @io.set_encoding 'binary'
104
+ @cache = { nil => 0 }
105
+ end
106
+
107
+ def put_compressed ob
108
+ data = Boss.dump(ob)
109
+ whdr TYPE_EXTRA, TCOMPRESSED
110
+ type = case data.length
111
+ when 0..160
112
+ 0
113
+ when 161..8192
114
+ data = Zlib::Deflate.new.deflate(data, Zlib::FINISH)
115
+ 1
116
+ else
117
+ data = Bzip2.compress data
118
+ 2
119
+ end
120
+ whdr type, data.length
121
+ wbin data
122
+ end
123
+
124
+ ##
125
+ # Put object tree routed as ob to the output.
126
+ # Alias: <<. It is possible to put more than one
127
+ # object to the same Formatter. Not that formatter
128
+ # has per-instance cache so put(x) put(x) put(x)
129
+ # will store one object and 2 more refs to it, so
130
+ # on load time only one object will be constructed and
131
+ # 2 more refs will be creted.
132
+ def put(ob)
133
+ case ob
134
+ when Fixnum, Bignum
135
+ if ob < 0
136
+ whdr TYPE_NINT, -ob
137
+ else
138
+ whdr TYPE_INT, ob
139
+ end
140
+ when String, Symbol
141
+ ob = ob.to_s unless ob.is_a?(String)
142
+ if notCached(ob)
143
+ if ob.encoding == Encoding::BINARY
144
+ whdr TYPE_BIN, ob.length
145
+ wbin ob
146
+ else
147
+ whdr TYPE_TEXT, ob.bytesize
148
+ wbin ob.dup.encode(Encoding::UTF_8)
149
+ end
150
+ end
151
+ when Array
152
+ if notCached(ob)
153
+ whdr TYPE_LIST, ob.length
154
+ ob.each { |x| put(x) }
155
+ end
156
+ when Hash
157
+ if notCached(ob)
158
+ whdr TYPE_DICT, ob.length
159
+ ob.each { |k, v| self << k << v }
160
+ end
161
+ when Float
162
+ case ob
163
+ when 0
164
+ whdr TYPE_EXTRA, DZERO
165
+ when -1.0
166
+ whdr TYPE_EXTRA, DMINUSONE
167
+ when +1.0
168
+ whdr TYPE_EXTRA, DONE
169
+ else
170
+ whdr TYPE_EXTRA, TDOUBLE
171
+ wdouble ob
172
+ end
173
+ when TrueClass, FalseClass
174
+ whdr TYPE_EXTRA, ob ? TTRUE : TFALSE
175
+ when nil
176
+ whdr TYPE_CREF, 0
177
+ else
178
+ error = "error: not supported object: #{ob}, #{ob.class}"
179
+ p error
180
+ raise NotSupportedException, error
181
+ end
182
+ self
183
+ end
184
+
185
+ alias << put
186
+
187
+ ##
188
+ # Get the result as string, may not work if
189
+ # some specific IO instance is passsed to constructor.
190
+ # works well with default contructor or StringIO
191
+ def string
192
+ # p "string!! #{@io.string}"
193
+ @io.string
194
+ end
195
+
196
+ private
197
+
198
+ ##
199
+ # Write cache ref if the object is cached, and return true
200
+ # otherwise store object in the cache. Caller should
201
+ # write object to @io if notCached return true, and skip
202
+ # writing otherwise
203
+ def notCached(obj)
204
+ n = @cache[obj]
205
+ if n
206
+ whdr TYPE_CREF, n
207
+ false
208
+ else
209
+ @cache[obj] = @cache.length
210
+ true
211
+ end
212
+ end
213
+
214
+ ##
215
+ # Write variable-length positive integer
216
+ def wrenc(value)
217
+ checkArg value >= 0
218
+ while value > 0x7f
219
+ wbyte value & 0x7f
220
+ value >>= 7
221
+ end
222
+ wbyte value | 0x80
223
+ end
224
+
225
+ ##
226
+ # write standard record header with code and value
227
+ #
228
+ def whdr(code, value)
229
+ checkArg code.between?(0, 7)
230
+ checkArg value >= 0
231
+ # p "WHDR #{code}, #{value}"
232
+ if value < 23
233
+ wbyte code | value<<3
234
+ else
235
+ # Get the size of the value (0..9)
236
+ if (n=sizeBytes(value)) < 9
237
+ wbyte code | (n+22) << 3
238
+ else
239
+ wbyte code | 0xF8
240
+ wrenc n
241
+ end
242
+ n.times { wbyte value & 0xff; value >>=8 }
243
+ end
244
+ end
245
+
246
+ ##
247
+ # Determine minimum amount of bytes needed to
248
+ # store value (should be positive integer)
249
+ def sizeBytes(value)
250
+ checkArg value >= 0
251
+ mval = 0x100
252
+ cnt = 1
253
+ while value >= mval
254
+ cnt += 1
255
+ mval <<= 8
256
+ end
257
+ cnt
258
+ end
259
+
260
+ ##
261
+ # write binary value
262
+ #
263
+ def wbin(bb)
264
+ @io.syswrite bb
265
+ end
266
+
267
+ ##
268
+ # write single byte
269
+ def wbyte(b)
270
+ @io.putc(b.chr)
271
+ end
272
+
273
+ def wdouble val
274
+ wbin [val].pack('E')
275
+ end
276
+
277
+
278
+ end
279
+
280
+ ##
281
+ # Parser incapsulates IO-like cource and provides deserializing of
282
+ # BOSS objects. Parser can store multiple root objects and share same
283
+ # object cache for all them
284
+ class Parser
285
+
286
+ include Enumerable
287
+
288
+ ##
289
+ # construct parser to read from the given string or IO-like
290
+ # object
291
+ def initialize(src=nil)
292
+ @io = src.class <= String ? StringIO.new(src) : src
293
+ @io.set_encoding Encoding::BINARY
294
+ @cache = [nil]
295
+ end
296
+
297
+ ##
298
+ # Load the object (object tree) from the stream. Note that if there
299
+ # is more than one object in the stream that are stored with the same
300
+ # Formatter instance, they will share same cache and references,
301
+ # see Boss.Formatter.put for details.
302
+ # Note that nil is a valid restored object. Check eof? or catch
303
+ # EOFError, or use Boss.Parser.each to read all objects from the stream
304
+ def get
305
+ code, value = rhdr
306
+ case code
307
+ when TYPE_INT
308
+ return value
309
+ when TYPE_NINT
310
+ return -value
311
+ when TYPE_EXTRA
312
+ case value
313
+ when TTRUE
314
+ true
315
+ when TFALSE
316
+ false
317
+ when DZERO, FZERO
318
+ 0
319
+ when DONE, FONE
320
+ 1.0
321
+ when DMINUSONE, FMINUSONE
322
+ -1.0
323
+ when TDOUBLE
324
+ rdouble
325
+ when TCOMPRESSED
326
+ type, size = rhdr
327
+ data = rbin size
328
+ case type
329
+ when 0
330
+ Boss.load data
331
+ when 1
332
+ Boss.load Zlib::Inflate.new(Zlib::MAX_WBITS).inflate(data)
333
+ when 2
334
+ Boss.load Bzip2.uncompress data
335
+ else
336
+ raise UnknownTypeException, "type #{type}"
337
+ end
338
+ else
339
+ raise UnknownTypeException
340
+ end
341
+ when TYPE_TEXT, TYPE_BIN
342
+ s = rbin value
343
+ s.force_encoding code == TYPE_BIN ? Encoding::BINARY : Encoding::UTF_8
344
+ @cache << s
345
+ return s
346
+ when TYPE_LIST
347
+ # p "items", value
348
+ @cache << (list = [])
349
+ value.times { list << get }
350
+ return list
351
+ when TYPE_DICT
352
+ @cache << (dict = { })
353
+ value.times { dict[get] = get }
354
+ return dict
355
+ when TYPE_CREF
356
+ return @cache[value]
357
+ else
358
+ raise UnknownTypeException
359
+ end
360
+ end
361
+
362
+ ##
363
+ # True is underlying IO-like object reached its end.
364
+ def eof?
365
+ @io.eof?
366
+ end
367
+
368
+ ##
369
+ # yields all objects in the stream
370
+ def each
371
+ @io.rewind
372
+ yield get until eof?
373
+ end
374
+
375
+ private
376
+
377
+ ##
378
+ # Read header and return code,value
379
+ def rhdr
380
+ b = rbyte
381
+ code, value = b & 7, b >> 3
382
+ case value
383
+ when 0..22
384
+ return code, value
385
+ when 23...31
386
+ return code, rlongint(value-22)
387
+ else
388
+ n = renc
389
+ return code, rlongint(n)
390
+ end
391
+ end
392
+
393
+ ##
394
+ # read n-bytes long positive integer
395
+ def rlongint(bytes)
396
+ res = i = 0
397
+ bytes.times do
398
+ res |= rbyte << i
399
+ i += 8
400
+ end
401
+ res
402
+ end
403
+
404
+ ##
405
+ # Read variable-length positive integer
406
+ def renc
407
+ value = i = 0
408
+ loop do
409
+ x = rbyte
410
+ value |= (x&0x7f) << i
411
+ return value if x & 0x80 != 0
412
+ i += 7
413
+ end
414
+ end
415
+
416
+ def rbyte
417
+ @io.readbyte
418
+ end
419
+
420
+ def rdouble
421
+ rbin(8).unpack('E')[0]
422
+ end
423
+
424
+ def rbin(length)
425
+ @io.sysread length
426
+ end
427
+ end
428
+
429
+ ##
430
+ # If block is given, yields all objects from the
431
+ # src (that can be either string or IO), passes it to the block and stores
432
+ # what block returns in the array, unless block returns nil. The array
433
+ # is then returned.
434
+ #
435
+ # Otherwise, reads and return first object from src
436
+ def Boss.load(src)
437
+ p = Parser.new(src)
438
+ if block_given?
439
+ res = []
440
+ res << yield(p.get) while !p.eof?
441
+ res
442
+ else
443
+ p.get
444
+ end
445
+ end
446
+
447
+ # Load all objects from the src and return them as an array
448
+ def Boss.load_all src
449
+ p = Parser.new(src)
450
+ res = []
451
+ res << p.get while !p.eof?
452
+ res
453
+ end
454
+
455
+ ##
456
+ # convert all arguments into successive BOSS encoeded
457
+ # object, so all them will share same global reference
458
+ # cache.
459
+ def Boss.dump(*roots)
460
+ f = f = Formatter.new
461
+ roots.each { |r| f << r }
462
+ f.string
463
+ end
464
+
465
+ def Boss.dump_compressed(*roots)
466
+ f = f = Formatter.new
467
+ roots.each { |r| f.put_compressed r }
468
+ f.string
469
+ end
470
+ end
471
+
data/spec/boss_spec.rb ADDED
@@ -0,0 +1,467 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+ require 'json'
5
+ require 'zlib'
6
+ require 'base64'
7
+ require 'boss-protocol'
8
+
9
+ describe 'Boss' do
10
+
11
+ it 'should perform compatible encode' do
12
+ Vectors.each do |a, b|
13
+ Boss.load(a).should == b
14
+ end
15
+ end
16
+
17
+ it 'should perform compatible decode' do
18
+ Vectors.each do |a,b|
19
+ Boss.load(a).should == b
20
+ end
21
+ end
22
+
23
+ it 'should properly encode positive and negative floats' do
24
+ round_check 0
25
+ round_check 1.0
26
+ round_check -1.0
27
+ round_check 2.0
28
+ round_check -2.0
29
+ round_check 1.11
30
+ round_check -1.11
31
+ end
32
+
33
+ it 'should encode booleans' do
34
+ round_check true
35
+ round_check false
36
+ end
37
+
38
+ it 'should properly encode nil' do
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 cache data' do
46
+ a = [1,2,3,4]
47
+ ca = { 1 => 55 }
48
+ b, c, d, e, f, g = Boss.load(Boss.dump([a,a,ca,ca, "oops", "oops"]))
49
+ a.should == b
50
+ b.should == c
51
+ b.should be_eql(c)
52
+
53
+ ca.should == d
54
+ ca.should == e
55
+ d.should be_equal(e)
56
+
57
+ f.should == "oops"
58
+ g.should == f
59
+ g.should be_equal(f)
60
+ end
61
+
62
+ it 'should properly encode very big integers' do
63
+ val = 1<<1024 * 7 + 117
64
+ round_check val
65
+ end
66
+
67
+ it 'should decode one by one using block' do
68
+ args = [1,2,3,4,5]
69
+ s = Boss.dump(*args)
70
+ res = []
71
+ res = Boss.load(s) { |x| x }
72
+ args.should == res
73
+ end
74
+
75
+ it 'should cache arrays and hashes too' do
76
+ d = { "Hello" => "world" }
77
+ a = [112,11]
78
+ r = Boss.load_all(Boss.dump( a,d,a,d ))
79
+ [a,d,a,d].should == r
80
+ r[1].should be_equal(r[3])
81
+ r[0].should be_equal(r[2])
82
+ end
83
+
84
+ it 'should properly encode multilevel structures' do
85
+ root = { "level" => 1}
86
+ p = root
87
+ 200.times { |n|
88
+ x = { "level" => n+2}
89
+ p['data'] = x
90
+ p['payload'] = 'great'
91
+ p = x
92
+ }
93
+ round_check root
94
+ end
95
+
96
+
97
+ it 'should effectively compress/decompress' do
98
+ # No compression
99
+ data = "Too short"
100
+ x0 = Boss.dump_compressed data
101
+ Boss.load(x0).should == data
102
+ x0.length.should <= (data.length + 3)
103
+
104
+ # short compression: zlib
105
+ data = "z" * 1024
106
+ x1 = Boss.dump_compressed data
107
+ Boss.load(x1).should == data
108
+ x1.length.should <= (data.length/10)
109
+
110
+ # hevay compression on big data
111
+ data = JSON.parse(Zlib::Inflate.new(Zlib::MAX_WBITS).inflate(Base64::decode64(CompressedTestJson)))
112
+ round_check data
113
+ x2 = Boss.dump_compressed(data)
114
+ Boss.load(x2).should == data
115
+ x2.length.should < 13700
116
+ end
117
+
118
+
119
+ def round_check(ob)
120
+ ob.should == Boss.load(Boss.dump(ob))
121
+ end
122
+
123
+
124
+ ##
125
+ # Set (force) string str encoding to binary
126
+ def self.bytes!(str)
127
+ str.force_encoding Encoding::BINARY
128
+ str
129
+ end
130
+
131
+ Vectors = [['8', 7], ["\xb8F", 70], [".\x00\x08\n8:", [0, 1, -1, 7, -7]], ["\xc8p\x11\x01", 70000],
132
+ ['+Hello', 'Hello'], [',Hello', bytes!('Hello'), 2, 4, 4, 1]]
133
+
134
+ CompressedTestJson = <<-End
135
+ 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
465
+ End
466
+
467
+ end
@@ -0,0 +1,17 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # Require this file using `require "spec_helper"` to ensure that it is only
4
+ # loaded once.
5
+ #
6
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
7
+ RSpec.configure do |config|
8
+ config.treat_symbols_as_metadata_keys_with_true_values = true
9
+ config.run_all_when_everything_filtered = true
10
+ config.filter_run :focus
11
+
12
+ # Run specs in random order to surface order dependencies. If you find an
13
+ # order dependency and want to debug it, you can fix the order by providing
14
+ # the seed, which is printed after each run.
15
+ # --seed 1234
16
+ config.order = 'random'
17
+ end
metadata ADDED
@@ -0,0 +1,92 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: boss-protocol
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - sergeych
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-12-20 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bzip2-ruby
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rspec
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ description: Binary streamable bit-effective protocol to effectively store object
47
+ tree hierarchies
48
+ email:
49
+ - real.sergeych@gmail.com
50
+ executables: []
51
+ extensions: []
52
+ extra_rdoc_files: []
53
+ files:
54
+ - .gitignore
55
+ - .rspec
56
+ - Gemfile
57
+ - LICENSE.txt
58
+ - README.md
59
+ - Rakefile
60
+ - boss-protocol.gemspec
61
+ - lib/boss-protocol.rb
62
+ - lib/boss-protocol/version.rb
63
+ - spec/boss_spec.rb
64
+ - spec/spec_helper.rb
65
+ homepage: ''
66
+ licenses: []
67
+ post_install_message:
68
+ rdoc_options: []
69
+ require_paths:
70
+ - lib
71
+ required_ruby_version: !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
+ none: false
79
+ requirements:
80
+ - - ! '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ requirements: []
84
+ rubyforge_project:
85
+ rubygems_version: 1.8.24
86
+ signing_key:
87
+ specification_version: 3
88
+ summary: Traversable and streamable to some extend protocol supports lists, hashes,
89
+ caching, compression and more
90
+ test_files:
91
+ - spec/boss_spec.rb
92
+ - spec/spec_helper.rb