cbor-packed 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/cbor-packed.gemspec +17 -0
- data/lib/cbor-packed.rb +305 -0
- data/test/exa2.rb +37 -0
- data/test/exa2r.rb +59 -0
- data/test/test-packed.rb +101 -0
- metadata +50 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 7ec7bd11d45d35c418a0fe98aa43c369b3384b2b43cb94486fd6e3463eae3232
|
4
|
+
data.tar.gz: 88efc5decfeeedb1c049df0e5a9ba126c35bdf8a661218e29db3eb836c39f9c6
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1b6add7d575ff6ab3f239c9cf8f4f434ec8cc3c7d02e717c58b8c79a2007dd6d033ec10739c8bbac788e73d292f37501a002730303a8f58479a7131243fd04ac
|
7
|
+
data.tar.gz: efd9b83c4da71f11354398048e6421770583b2fef0e22b4e3ac1f964ba2d5f4d2d69b2cb1e6441058062313940d6fee492f6dd7579dd0e25202734229a33058b
|
data/cbor-packed.gemspec
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = "cbor-packed"
|
3
|
+
s.version = "0.1.3"
|
4
|
+
s.summary = "CBOR (Concise Binary Object Representation) packer"
|
5
|
+
s.description = %q{cbor-packed implements packed encoding for CBOR, RFC 7049 Section 3.9}
|
6
|
+
s.author = "Carsten Bormann"
|
7
|
+
s.email = "cabo@tzi.org"
|
8
|
+
s.license = "Apache-2.0"
|
9
|
+
s.homepage = "http://cbor.io/"
|
10
|
+
s.has_rdoc = false
|
11
|
+
s.test_files = Dir['test/**/*.rb']
|
12
|
+
s.files = Dir['lib/**/*.rb'] + %w(cbor-packed.gemspec) + Dir['bin/**/*.rb']
|
13
|
+
s.executables = Dir['bin/**/*.rb'].map {|x| File.basename(x)}
|
14
|
+
s.required_ruby_version = '>= 1.9.2'
|
15
|
+
|
16
|
+
s.require_paths = ["lib"]
|
17
|
+
end
|
data/lib/cbor-packed.rb
ADDED
@@ -0,0 +1,305 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require "cbor" unless defined? CBOR
|
4
|
+
# require "pp"
|
5
|
+
|
6
|
+
$compression_hack = 0
|
7
|
+
|
8
|
+
module CBOR
|
9
|
+
PACKED_TAG = 51
|
10
|
+
REF_TAG = 6
|
11
|
+
|
12
|
+
class Packer
|
13
|
+
def self.from_item(item)
|
14
|
+
count = Hash.new(0)
|
15
|
+
item.cbor_visit do |o|
|
16
|
+
(count[o] += 1) == 1
|
17
|
+
# if the count gets > 1, we can stop visiting, so we return false in the block
|
18
|
+
end
|
19
|
+
# pp count
|
20
|
+
# count is now a Hash with all data items as keys and the number of times they occur as values
|
21
|
+
|
22
|
+
# choose those matches that are occurring > 1, make first rough estimate of saving
|
23
|
+
good_count = count.select {|k, v| v > 1}.map {|k, v| [k, v, l = k.to_cbor.length,
|
24
|
+
(v-1)*(l-1)]}
|
25
|
+
# good_count is now an array of [k, v, length, savings] tuples
|
26
|
+
|
27
|
+
# select those that potentially have savings (> 0) and sort by best saving first
|
28
|
+
better_count = good_count.to_a.select {|a| a[3] > 0}.sort_by {|a| -a[3]}
|
29
|
+
# pp better_count
|
30
|
+
|
31
|
+
# now: take the best out???; re-visit that reducing by n; re-sort and filter???
|
32
|
+
# sort by descending number of references we'll get -- the higher reference counts go first
|
33
|
+
match_array = better_count.sort_by {|a| -a[1]}.map {|a| a[0]}
|
34
|
+
# pp match_array
|
35
|
+
|
36
|
+
# XXX the below needs to be done with arrays and (hard!) maps as well
|
37
|
+
# do this on the reverse to find common suffixes
|
38
|
+
# select all strings (ignoring reference counts) and sort them
|
39
|
+
strings = count.select {|k, v| String === k}.map(&:first).sort
|
40
|
+
if strings != []
|
41
|
+
string_common = strings[1..-1].zip(strings).map{ |y, x|
|
42
|
+
l = x.chars.zip(y.chars).take_while{|a, b| a == b}.length # should be bytes
|
43
|
+
[x, l]
|
44
|
+
} << [strings[-1], 0]
|
45
|
+
# string_common: list of strings/counts of number of /bytes/ matching with next
|
46
|
+
# pp string_common
|
47
|
+
end
|
48
|
+
translate = {}
|
49
|
+
prefixes = []
|
50
|
+
if string_common
|
51
|
+
prefix_stack = [[0, false]] # sentinel
|
52
|
+
pos = 0 # mirror prefix_stack[-1][0]
|
53
|
+
tag_no = REF_TAG
|
54
|
+
string_common.each do |s, l|
|
55
|
+
if l > pos + 2 + $compression_hack
|
56
|
+
if t = prefix_stack[-1][1] # if we still have a prefix left
|
57
|
+
prefixes << CBOR::Tagged.new(t, s[pos...l])
|
58
|
+
else
|
59
|
+
prefixes << s[0...l]
|
60
|
+
end
|
61
|
+
prefix_stack << [l, tag_no]
|
62
|
+
pos = l
|
63
|
+
tag_no += 1
|
64
|
+
tag_no = 225 if tag_no == REF_TAG+1
|
65
|
+
tag_no = 28704 if tag_no == 256
|
66
|
+
end
|
67
|
+
if t = prefix_stack[-1][1] # if we still have a viable prefix left
|
68
|
+
translate[s] = CBOR::Tagged.new(t, s[pos..-1])
|
69
|
+
end
|
70
|
+
# pop the prefix stack
|
71
|
+
while l < pos
|
72
|
+
prefix_stack.pop
|
73
|
+
pos = prefix_stack[-1][0]
|
74
|
+
end
|
75
|
+
# pp prefix_stack
|
76
|
+
# pp pos
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
# pp translate
|
81
|
+
# XXX test replacing match_array here
|
82
|
+
match_array = match_array.map do |v|
|
83
|
+
if r = translate[v]
|
84
|
+
# puts "*** replacing #{v.inspect} by #{r.inspect}"
|
85
|
+
r
|
86
|
+
else
|
87
|
+
v
|
88
|
+
end
|
89
|
+
end
|
90
|
+
# pp [:PREFIXES, prefixes]
|
91
|
+
# pp translate
|
92
|
+
new(match_array, prefixes, [], translate)
|
93
|
+
end
|
94
|
+
def initialize(match_array, prefix_array, suffix_array, translate)
|
95
|
+
@hit = translate
|
96
|
+
# XXX: make sure we don't overwrite the existing prefix compression values!
|
97
|
+
# (this should really be done downwards, ...) 16 x 1, 160 x 2, (512-48) x 3
|
98
|
+
match_array[0...16].each_with_index do |o, i|
|
99
|
+
@hit[o] = CBOR::Simple.new(i)
|
100
|
+
end
|
101
|
+
# if m = match_array[16...128]
|
102
|
+
# m.each_with_index do |o, i|
|
103
|
+
# @hit[o] = CBOR::Simple.new(i + 128)
|
104
|
+
# end
|
105
|
+
# end
|
106
|
+
if m = match_array[16..-1]
|
107
|
+
m.each_with_index do |o, i|
|
108
|
+
@hit[o] = CBOR::Tagged.new(REF_TAG, (i >> 1) ^ -(i & 1))
|
109
|
+
end
|
110
|
+
end
|
111
|
+
# add one round of transitive matching
|
112
|
+
@hit.each do |k, v|
|
113
|
+
if r = @hit[v]
|
114
|
+
@hit[k] = r
|
115
|
+
end
|
116
|
+
end
|
117
|
+
# p @hit
|
118
|
+
@match_array = match_array
|
119
|
+
# @prefix = {} -- do that later
|
120
|
+
@prefix_array = prefix_array
|
121
|
+
@suffix_array = suffix_array
|
122
|
+
end
|
123
|
+
def has(o)
|
124
|
+
@hit[o]
|
125
|
+
end
|
126
|
+
def pack(pa)
|
127
|
+
# Don't forget to pack the match_array!
|
128
|
+
CBOR::Tagged.new(PACKED_TAG, [@match_array, @prefix_array, @suffix_array, pa])
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
class Unpacker
|
133
|
+
def initialize(match_array, prefix_array, suffix_array)
|
134
|
+
@simple_array = match_array[0...16]
|
135
|
+
@tagged_array = match_array[16..-1]
|
136
|
+
# index with 2i for i >= 0 or ~2i for i < 0
|
137
|
+
# no map as we need to populate in progress
|
138
|
+
# pp prefix_array
|
139
|
+
@prefix_array = []
|
140
|
+
prefix_array.each {|x| @prefix_array << x.to_unpacked_cbor1(self)}
|
141
|
+
@suffix_array = []
|
142
|
+
suffix_array.each {|x| @prefix_array << x.to_unpacked_cbor1(self)}
|
143
|
+
# XXX order? -- must do lazily!
|
144
|
+
end
|
145
|
+
def unsimple(sv)
|
146
|
+
@simple_array[sv]
|
147
|
+
end
|
148
|
+
def untag(tv)
|
149
|
+
@tagged_array[(i << 1) ^ (i >> 63)]
|
150
|
+
end
|
151
|
+
def unprefix(n)
|
152
|
+
@prefix_array[n]
|
153
|
+
end
|
154
|
+
def unsuffix(n)
|
155
|
+
@suffix_array[n]
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
module Packed
|
160
|
+
|
161
|
+
module Object_Packed_CBOR
|
162
|
+
def cbor_visit
|
163
|
+
yield self
|
164
|
+
end
|
165
|
+
def to_unpacked_cbor1(unpacker)
|
166
|
+
self
|
167
|
+
end
|
168
|
+
def to_packed_cbor(packer = Packer.from_item(self))
|
169
|
+
packer.pack(to_packed_cbor1(packer))
|
170
|
+
end
|
171
|
+
def to_packed_cbor1(packer = Packer.from_item(self))
|
172
|
+
if c = packer.has(self)
|
173
|
+
c
|
174
|
+
else
|
175
|
+
# Need to do the prefix dance, too
|
176
|
+
self
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
Object.send(:include, Object_Packed_CBOR)
|
181
|
+
|
182
|
+
module Simple_Packed_CBOR
|
183
|
+
def to_unpacked_cbor1(unpacker)
|
184
|
+
if v = unpacker.unsimple(value)
|
185
|
+
v.to_unpacked_cbor1(unpacker)
|
186
|
+
else
|
187
|
+
self
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
CBOR::Simple.send(:include, Simple_Packed_CBOR)
|
192
|
+
|
193
|
+
module String_Packed_CBOR
|
194
|
+
def packed_merge(other, unpacker)
|
195
|
+
# add checks
|
196
|
+
to_unpacked_cbor1(unpacker) + other.to_unpacked_cbor1(unpacker)
|
197
|
+
end
|
198
|
+
end
|
199
|
+
String.send(:include, String_Packed_CBOR)
|
200
|
+
|
201
|
+
module Array_Packed_CBOR
|
202
|
+
def cbor_visit(&b)
|
203
|
+
if yield self
|
204
|
+
each do |o|
|
205
|
+
o.cbor_visit(&b)
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
def to_unpacked_cbor1(unpacker)
|
210
|
+
map {|x| x.to_unpacked_cbor1(unpacker)}
|
211
|
+
end
|
212
|
+
def to_packed_cbor1(packer = Packer.from_item(self))
|
213
|
+
if c = packer.has(self)
|
214
|
+
c.to_unpacked_cbor1(unpacker)
|
215
|
+
else
|
216
|
+
# TODO: Find useful prefixes
|
217
|
+
map {|x| x.to_packed_cbor1(packer)}
|
218
|
+
end
|
219
|
+
end
|
220
|
+
def packed_merge(other, unpacker)
|
221
|
+
# TODO: add checks
|
222
|
+
to_unpacked_cbor1(unpacker) + other.to_unpacked_cbor1(unpacker)
|
223
|
+
end
|
224
|
+
end
|
225
|
+
Array.send(:include, Array_Packed_CBOR)
|
226
|
+
|
227
|
+
module Hash_Packed_CBOR
|
228
|
+
def cbor_visit(&b)
|
229
|
+
if yield self
|
230
|
+
each do |k, v|
|
231
|
+
k.cbor_visit(&b)
|
232
|
+
v.cbor_visit(&b)
|
233
|
+
end
|
234
|
+
end
|
235
|
+
end
|
236
|
+
def to_unpacked_cbor1(unpacker)
|
237
|
+
Hash[map {|k, v| [k.to_unpacked_cbor1(unpacker), v.to_unpacked_cbor1(unpacker)]}]
|
238
|
+
end
|
239
|
+
def to_packed_cbor1(packer = Packer.from_item(self))
|
240
|
+
if c = packer.has(self)
|
241
|
+
c.to_unpacked_cbor1(unpacker)
|
242
|
+
else
|
243
|
+
# TODO: Find useful prefixes
|
244
|
+
Hash[map {|k, v| [k.to_packed_cbor1(packer), v.to_packed_cbor1(packer)]}]
|
245
|
+
end
|
246
|
+
end
|
247
|
+
def packed_merge(other, unpacker)
|
248
|
+
# TODO: add checks
|
249
|
+
to_unpacked_cbor1(unpacker).merge other.to_unpacked_cbor1(unpacker)
|
250
|
+
end
|
251
|
+
end
|
252
|
+
Hash.send(:include, Hash_Packed_CBOR)
|
253
|
+
|
254
|
+
module Tagged_Packed_CBOR
|
255
|
+
def cbor_visit(&b)
|
256
|
+
if yield self
|
257
|
+
value.cbor_visit(&b)
|
258
|
+
end
|
259
|
+
end
|
260
|
+
def to_unpacked_cbor
|
261
|
+
if tag == PACKED_TAG
|
262
|
+
# check that this really is an array
|
263
|
+
# warn value.to_yaml
|
264
|
+
ma, pa, sa, pv = value
|
265
|
+
unpacker = Unpacker.new(ma, pa, sa)
|
266
|
+
pv.to_unpacked_cbor1(unpacker)
|
267
|
+
else
|
268
|
+
fail "error message here"
|
269
|
+
end
|
270
|
+
end
|
271
|
+
def to_unpacked_cbor1(unpacker)
|
272
|
+
case tag
|
273
|
+
when REF_TAG
|
274
|
+
if Integer === value
|
275
|
+
unpacker(untag(value))
|
276
|
+
else
|
277
|
+
unpacker.unprefix(0).packed_merge value, unpacker
|
278
|
+
end
|
279
|
+
when 225...256
|
280
|
+
unpacker.unprefix(tag-(256-32)).packed_merge value, unpacker
|
281
|
+
when 28704...32768 # (- 28704 (- 32768 4096)) == 32
|
282
|
+
unpacker.unprefix(tag-(32768-4096)).packed_merge value, unpacker
|
283
|
+
when 1879052288...2147483648 # (- 1879052288 (- 2147483648 268435456)) == 4096
|
284
|
+
unpacker.unprefix(tag-(2147483648-268435456)).packed_merge value, unpacker
|
285
|
+
when 216...224
|
286
|
+
value.packed_merge unpacker.unsuffix(tag-216), unpacker
|
287
|
+
when 27647...28672
|
288
|
+
value.packed_merge unpacker.unsuffix(tag-(28672-1024)), unpacker
|
289
|
+
when 1811940352...1879048192
|
290
|
+
value.packed_merge unpacker.unsuffix(tag-(1879048192-67108864)), unpacker
|
291
|
+
else
|
292
|
+
CBOR::Tagged.new(tag, value.to_unpacked_cbor1(unpacker))
|
293
|
+
end
|
294
|
+
end
|
295
|
+
def to_packed_cbor1(packer = Packer.from_item(self))
|
296
|
+
if c = packer.has(self)
|
297
|
+
c
|
298
|
+
else
|
299
|
+
CBOR::Tagged.new(tag, value.to_packed_cbor1(packer))
|
300
|
+
end
|
301
|
+
end
|
302
|
+
end
|
303
|
+
CBOR::Tagged.send(:include, Tagged_Packed_CBOR)
|
304
|
+
end
|
305
|
+
end
|
data/test/exa2.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'cbor-pure'
|
2
|
+
require 'cbor-packed'
|
3
|
+
require 'cbor-diagnostic'
|
4
|
+
require 'json'
|
5
|
+
require 'yaml'
|
6
|
+
|
7
|
+
fn = "/Users/cabo/big/wot-thing-description/test-bed/data/plugfest/2017-05-osaka/MyLED_f.jsonld"
|
8
|
+
puts fn.split("/")[4..-1].join("/")
|
9
|
+
jf = File.read(fn)
|
10
|
+
puts "JSON file: #{jf.length}"
|
11
|
+
jo = JSON.parse(jf)
|
12
|
+
jsw = JSON::generate(jo, :allow_nan => true, :max_nesting => false)
|
13
|
+
# l3 jsw, "JSON no whitespace"
|
14
|
+
File.write("/tmp/jsw", jsw)
|
15
|
+
|
16
|
+
# p jo
|
17
|
+
cb = jo.to_cbor
|
18
|
+
# l3 cb, "CBOR"
|
19
|
+
$compression_hack = 1000
|
20
|
+
pa = jo.to_packed_cbor
|
21
|
+
cbp = pa.to_cbor
|
22
|
+
# l3 cbp, "CBOR packed"
|
23
|
+
puts "CBOR packed (sharing only): #{cbp.length}"
|
24
|
+
$compression_hack = 0
|
25
|
+
pa = jo.to_packed_cbor
|
26
|
+
cbp = pa.to_cbor
|
27
|
+
# l3 cbp, "CBOR packed"
|
28
|
+
puts "CBOR packed: #{cbp.length}"
|
29
|
+
File.write("/tmp/cbp", cbp)
|
30
|
+
File.write("/tmp/cbu", cb)
|
31
|
+
pad = CBOR.decode(cbp)
|
32
|
+
up = pad.to_unpacked_cbor
|
33
|
+
pp up == jo
|
34
|
+
if up != jo
|
35
|
+
puts up.to_yaml
|
36
|
+
puts pad.to_yaml # get rid of unwanted sharing...
|
37
|
+
end
|
data/test/exa2r.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'cbor-pure'
|
2
|
+
require 'cbor-packed'
|
3
|
+
require 'treetop'
|
4
|
+
require 'cbor-diag-parser'
|
5
|
+
require 'cbor-diagnostic'
|
6
|
+
require 'json'
|
7
|
+
require 'yaml'
|
8
|
+
|
9
|
+
input = DATA.read
|
10
|
+
|
11
|
+
|
12
|
+
parser = CBOR_DIAGParser.new
|
13
|
+
if result = parser.parse(input)
|
14
|
+
o = result.to_rb.to_unpacked_cbor
|
15
|
+
puts o.cbor_diagnostic
|
16
|
+
else
|
17
|
+
puts "*** can't parse #{i}"
|
18
|
+
puts "*** #{parser.failure_reason}"
|
19
|
+
end
|
20
|
+
|
21
|
+
# ruby -I ../lib exa2r.rb | jq > .out1
|
22
|
+
# jq < ~/big/wot-thing-description/test-bed/data/plugfest/2017-05-osaka/MyLED_f.jsonld > .out2
|
23
|
+
# ruby .check
|
24
|
+
# => true
|
25
|
+
|
26
|
+
|
27
|
+
__END__
|
28
|
+
|
29
|
+
51([/shared/["name", "@type", "links", "href", "mediaType",
|
30
|
+
/ 0 1 2 3 4 /
|
31
|
+
"application/json", "outputData", {"valueType": {"type":
|
32
|
+
/ 5 6 7 /
|
33
|
+
"number"}}, ["Property"], "writable", "valueType", "type"],
|
34
|
+
/ 8 9 10 11 /
|
35
|
+
/prefix/ ["http://192.168.1.10", 6("3:8445/wot/thing"),
|
36
|
+
/ 6 225 /
|
37
|
+
225("/MyLED/"), 226("rgbValue"), "rgbValue",
|
38
|
+
/ 226 227 228 /
|
39
|
+
{simple(6): simple(7), simple(9): true, simple(1): simple(8)}],
|
40
|
+
/ 229 /
|
41
|
+
/suffix/ [],
|
42
|
+
/rump/ {simple(0): "MyLED",
|
43
|
+
"interactions": [
|
44
|
+
229({simple(2): [{simple(3): 227("Red"), simple(4): simple(5)}],
|
45
|
+
simple(0): 228("Red")}),
|
46
|
+
229({simple(2): [{simple(3): 227("Green"), simple(4): simple(5)}],
|
47
|
+
simple(0): 228("Green")}),
|
48
|
+
229({simple(2): [{simple(3): 227("Blue"), simple(4): simple(5)}],
|
49
|
+
simple(0): 228("Blue")}),
|
50
|
+
229({simple(2): [{simple(3): 227("White"), simple(4): simple(5)}],
|
51
|
+
simple(0): "rgbValueWhite"}),
|
52
|
+
{simple(2): [{simple(3): 226("ledOnOff"), simple(4): simple(5)}],
|
53
|
+
simple(6): {simple(10): {simple(11): "boolean"}}, simple(0):
|
54
|
+
"ledOnOff", simple(9): true, simple(1): simple(8)},
|
55
|
+
{simple(2): [{simple(3): 226("colorTemperatureChanged"),
|
56
|
+
simple(4): simple(5)}], simple(6): simple(7), simple(0):
|
57
|
+
"colorTemperatureChanged", simple(1): ["Event"]}],
|
58
|
+
simple(1): "Lamp", "id": "0", "base": 225(""),
|
59
|
+
"@context": 6("2:8444/wot/w3c-wot-td-context.jsonld")}])
|
data/test/test-packed.rb
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'cbor-pure'
|
2
|
+
require 'cbor-packed'
|
3
|
+
require 'cbor-diagnostic'
|
4
|
+
require 'json'
|
5
|
+
require 'yaml'
|
6
|
+
require 'zlib'
|
7
|
+
require 'lz4-ruby'
|
8
|
+
|
9
|
+
def l3(bin, desc)
|
10
|
+
puts "#{desc}: #{bin.length}, deflate: #{Zlib.deflate(bin, Zlib::BEST_COMPRESSION).length}, lz4: #{LZ4::compress(bin).length}, lz4hc: #{LZ4::compressHC(bin).length}"
|
11
|
+
end
|
12
|
+
|
13
|
+
fn = "/Users/cabo/big/wot-thing-description/test-bed/data/plugfest/2017-05-osaka/MyLED_f.jsonld"
|
14
|
+
puts fn.split("/")[4..-1].join("/")
|
15
|
+
jf = File.read(fn)
|
16
|
+
puts "JSON file: #{jf.length}"
|
17
|
+
jo = JSON.parse(jf)
|
18
|
+
jsw = JSON::generate(jo, :allow_nan => true, :max_nesting => false)
|
19
|
+
l3 jsw, "JSON no whitespace"
|
20
|
+
File.write("/tmp/jsw", jsw)
|
21
|
+
|
22
|
+
# p jo
|
23
|
+
cb = jo.to_cbor
|
24
|
+
l3 cb, "CBOR"
|
25
|
+
$compression_hack = 1000
|
26
|
+
pa = jo.to_packed_cbor
|
27
|
+
cbp = pa.to_cbor
|
28
|
+
# l3 cbp, "CBOR packed"
|
29
|
+
puts "CBOR packed (sharing only): #{cbp.length}"
|
30
|
+
$compression_hack = 0
|
31
|
+
pa = jo.to_packed_cbor
|
32
|
+
cbp = pa.to_cbor
|
33
|
+
# l3 cbp, "CBOR packed"
|
34
|
+
puts "CBOR packed: #{cbp.length}"
|
35
|
+
File.write("/tmp/cbp", cbp)
|
36
|
+
File.write("/tmp/cbu", cb)
|
37
|
+
pad = CBOR.decode(cbp)
|
38
|
+
# puts pad.to_yaml
|
39
|
+
up = pad.to_unpacked_cbor
|
40
|
+
pp up == jo
|
41
|
+
if up != jo
|
42
|
+
puts up.to_yaml
|
43
|
+
puts pad.to_yaml # get rid of unwanted sharing...
|
44
|
+
end
|
45
|
+
|
46
|
+
# puts "#{pa.value.map {|x| x.to_cbor.length}}"
|
47
|
+
puts pa.value[1].to_json
|
48
|
+
|
49
|
+
exin = JSON.load(DATA)
|
50
|
+
exout = exin.to_packed_cbor
|
51
|
+
p CBOR.encode(exin).length, CBOR.encode(exout).length
|
52
|
+
puts exout.cbor_diagnostic
|
53
|
+
if exin != exout.to_unpacked_cbor
|
54
|
+
fail exout.inspect
|
55
|
+
end
|
56
|
+
|
57
|
+
exit
|
58
|
+
|
59
|
+
# $compression_hack = 1000
|
60
|
+
|
61
|
+
a1 = {"aaaa" => "aaaaaaaa", "aaaaaaaaaaaa" => "aaaa", "aaaaaaaa" => "aaaaaaaaaaaa"}
|
62
|
+
pa1 = a1.to_packed_cbor
|
63
|
+
puts pa1.to_yaml
|
64
|
+
a1u = pa1.to_unpacked_cbor
|
65
|
+
if a1u != a1
|
66
|
+
puts a1u.to_yaml
|
67
|
+
end
|
68
|
+
|
69
|
+
__END__
|
70
|
+
|
71
|
+
{ "store": {
|
72
|
+
"book": [
|
73
|
+
{ "category": "reference",
|
74
|
+
"author": "Nigel Rees",
|
75
|
+
"title": "Sayings of the Century",
|
76
|
+
"price": 8.95
|
77
|
+
},
|
78
|
+
{ "category": "fiction",
|
79
|
+
"author": "Evelyn Waugh",
|
80
|
+
"title": "Sword of Honour",
|
81
|
+
"price": 12.99
|
82
|
+
},
|
83
|
+
{ "category": "fiction",
|
84
|
+
"author": "Herman Melville",
|
85
|
+
"title": "Moby Dick",
|
86
|
+
"isbn": "0-553-21311-3",
|
87
|
+
"price": 8.95
|
88
|
+
},
|
89
|
+
{ "category": "fiction",
|
90
|
+
"author": "J. R. R. Tolkien",
|
91
|
+
"title": "The Lord of the Rings",
|
92
|
+
"isbn": "0-395-19395-8",
|
93
|
+
"price": 22.99
|
94
|
+
}
|
95
|
+
],
|
96
|
+
"bicycle": {
|
97
|
+
"color": "red",
|
98
|
+
"price": 19.95
|
99
|
+
}
|
100
|
+
}
|
101
|
+
}
|
metadata
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: cbor-packed
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.3
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Carsten Bormann
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2021-05-04 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: cbor-packed implements packed encoding for CBOR, RFC 7049 Section 3.9
|
14
|
+
email: cabo@tzi.org
|
15
|
+
executables: []
|
16
|
+
extensions: []
|
17
|
+
extra_rdoc_files: []
|
18
|
+
files:
|
19
|
+
- cbor-packed.gemspec
|
20
|
+
- lib/cbor-packed.rb
|
21
|
+
- test/exa2.rb
|
22
|
+
- test/exa2r.rb
|
23
|
+
- test/test-packed.rb
|
24
|
+
homepage: http://cbor.io/
|
25
|
+
licenses:
|
26
|
+
- Apache-2.0
|
27
|
+
metadata: {}
|
28
|
+
post_install_message:
|
29
|
+
rdoc_options: []
|
30
|
+
require_paths:
|
31
|
+
- lib
|
32
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
33
|
+
requirements:
|
34
|
+
- - ">="
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: 1.9.2
|
37
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
42
|
+
requirements: []
|
43
|
+
rubygems_version: 3.2.15
|
44
|
+
signing_key:
|
45
|
+
specification_version: 4
|
46
|
+
summary: CBOR (Concise Binary Object Representation) packer
|
47
|
+
test_files:
|
48
|
+
- test/exa2.rb
|
49
|
+
- test/exa2r.rb
|
50
|
+
- test/test-packed.rb
|