cbor-packed 0.1.5 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: aac07ac277ddc9d142fcfd1d2b6b6b07279522354e3f72b4cbec52466e94b6c3
4
- data.tar.gz: 7963b3afd7a8e205b65b5e4fb4a69496aa358e29aac1c1cc126fa4b14db38b20
3
+ metadata.gz: 9306aa8a05d1747901cda5a72e3636199ce2dc403e09c8731c2fbd6c6be93623
4
+ data.tar.gz: 9ccd87f2b36818c1b71b7e946cdfe370c230f40ea9331fc407e925a0ff214824
5
5
  SHA512:
6
- metadata.gz: 2e25f214b1944aa20817ee2e4fc9640c7d2c8f698bb22fb9e207aa22d2ba7adb78a32fb8b2ef51e8b7d8c981e3d0b29b8aca97f932ca54cc70ad14268756f797
7
- data.tar.gz: 1200e4a27c0e2063ed4073406a0e55f4a12eb0efec213b5e26b069924a4a699a450e180c80302cba144883e5cafad31b6fab11a3b8e7e3ce6e2b2c87003ee2d2
6
+ metadata.gz: b35a19072f26120f7aa4e67c9f4b3af64f3aea70eeaa0203b3d7d0c228d8ab20ea006cebd09e62d26233ea10c8fbacad5b9024e75f180f9f9462c81fe1e5632a
7
+ data.tar.gz: 57a9c79818180b0433230c3666fdc5742d3b8fa22e9fd1deda8941a8a75eef05b0f933c249c1131afb5f615b23920cce16b5d81fc09d30b07d04ac0d233dd8f9
data/cbor-packed.gemspec CHANGED
@@ -1,13 +1,12 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "cbor-packed"
3
- s.version = "0.1.5"
3
+ s.version = "0.2.2"
4
4
  s.summary = "CBOR (Concise Binary Object Representation) packer"
5
5
  s.description = %q{cbor-packed implements packed encoding for CBOR, RFC 7049 Section 3.9}
6
6
  s.author = "Carsten Bormann"
7
7
  s.email = "cabo@tzi.org"
8
8
  s.license = "Apache-2.0"
9
9
  s.homepage = "http://cbor.io/"
10
- s.has_rdoc = false
11
10
  s.test_files = Dir['test/**/*.rb']
12
11
  s.files = Dir['lib/**/*.rb'] + %w(cbor-packed.gemspec) + Dir['bin/**/*.rb']
13
12
  s.executables = Dir['bin/**/*.rb'].map {|x| File.basename(x)}
data/lib/cbor-packed.rb CHANGED
@@ -1,66 +1,220 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
- require "cbor" unless defined? CBOR
4
- # require "pp"
3
+ require "cbor-pure" unless defined? CBOR
4
+ require "pp"
5
5
 
6
6
  $compression_hack = 0
7
7
 
8
+ # class String
9
+ # def xeh
10
+ # gsub(/\s/, "").chars.each_slice(2).map{ |x| Integer(x.join, 16).chr("BINARY") }.join
11
+ # end
12
+ # end
13
+
8
14
  module CBOR
9
- PACKED_TAG = 51
15
+ PACKED_TAG = 1113
16
+ MIXED_PACKED_TAG = 113
10
17
  REF_TAG = 6
18
+ STRAIGHT_11_SIZE = 32 # How many 1+1 straight tags do we have
19
+
20
+ HEX_UC_TAG = 23
21
+ HEX_LC_TAG = 108 # 'l'.ord, SQUATTING, fix this
22
+ RECORD_TAG = 114 # 'r'.ord
23
+ UNDEFINED = CBOR::Simple.new(23)
11
24
 
25
+ # Use with || 4
26
+ # simple 6(1+0) 6(1+1)
12
27
  REF_SIZE = [*Array.new(16, 1), *Array.new(48, 2), *Array.new(512-48, 3)]
13
28
 
14
29
  class Packer
15
- def self.from_item(item)
30
+ def self.build_match_array(item)
31
+ # Hash with all data items as keys and the number of times they occur as values:
16
32
  count = Hash.new(0)
17
33
  item.cbor_visit do |o|
18
34
  (count[o] += 1) == 1
19
35
  # if the count gets > 1, we can stop visiting, so we return false in the block
20
36
  end
21
- # pp count
22
- # count is now a Hash with all data items as keys and the number of times they occur as values
23
37
 
24
38
  # choose those matches that are occurring > 1, make first rough estimate of saving
25
- good_count = count.select {|k, v| v > 1}.map {|k, v| [k, v, l = k.to_cbor.length,
26
- (v-1)*(l-1)]}
27
- # good_count is now an array of [k, v, length, savings] tuples
39
+ good_count = count
40
+ .select {|k, v| v > 1}
41
+ .map {|k, v|
42
+ l = k.to_cbor.length
43
+ # v-1: We can only save space for the second etc.
44
+ # l-1: We'll need at least 1 byte for the reference
45
+ gain = (v-1)*(l-1)
46
+ [k, v, l] if gain > 0
47
+ }.compact
48
+ .sort_by {|a| -a[1]}
49
+ # good_count is now an array of [value, count, length] tuples that have potential gain,
50
+ # sorted by descending number of references we'll get
28
51
 
29
- # select those that potentially have savings (> 0) and sort by best saving first
30
- better_count = good_count.to_a.select {|a| a[3] > 0}.sort_by {|a| -a[3]}
31
- # pp better_count
52
+ match_array = []
53
+ good_count.each {|a|
54
+ match_array << a[0] if (REF_SIZE[match_array.size] || 4) < a[2]
55
+ }
56
+ # pp match_array
57
+ [count, match_array]
58
+ end
32
59
 
33
- # now: take the best out???; re-visit that reducing by n; re-sort and filter???
60
+ def self.argref(n, casezero = 6)
61
+ case n
62
+ when 0
63
+ casezero
64
+ when 1..31
65
+ n + 224
66
+ when 32...0x1000
67
+ n + 0x7000
68
+ when 0x1000...0x10000000
69
+ n + 0x70000000
70
+ end
71
+ end
34
72
 
35
- # sort by descending number of references we'll get
36
- # -- the higher reference counts go first
37
- # then filter out the entries that actually improve
73
+ def self.sharedref(i)
74
+ if i < 16
75
+ CBOR::Simple.new(i)
76
+ else
77
+ i -= 16
78
+ CBOR::Tagged.new(REF_TAG, (i >> 1) ^ -(i & 1))
79
+ end
80
+ end
38
81
 
39
- match_array = []
82
+ def self.build_bytes_from_hex(strings, count, match_array, item, translate, prefixes)
83
+ optimizable, others = strings.partition do |str|
84
+ if /(?:(?<lc>(?:[0-9a-f][0-9a-f]){4,})|(?<uc>(?:[0-9A-F][0-9A-F]){4,}))$/ =~ str
85
+ left = $`
86
+ # warn [:lc, left, lc, uc].inspect
87
+ bytes = [
88
+ if lc
89
+ tag = HEX_LC_TAG
90
+ fail if uc
91
+ lc
92
+ else
93
+ fail unless uc
94
+ tag = HEX_UC_TAG
95
+ uc
96
+ end].pack('H*').b
97
+ if outer = translate[str]
98
+ fail outer.inspect unless CBOR::Tagged === outer && left == outer.value # XXX
99
+ else
100
+ referto = bytes
101
+ if (count[bytes] += 1) == 2 # patch up match_array...
102
+ # translate[bytes] = sharedref(match_array.size) # happens later, too
103
+ match_array << bytes
104
+ referto = sharedref(match_array.size-1)
105
+ end
106
+ prefixes << left unless prefixes[-1] == left
107
+ translate[str] = CBOR::Tagged.new(argref(prefixes.size-1),
108
+ CBOR::Tagged.new(tag, referto)) unless count[bytes] > 2
109
+ # don't overwrite any entry made at == 2
110
+ end
111
+ true
112
+ end
113
+ end
114
+ others
115
+ end
40
116
 
41
- better_count.sort_by {|a| -a[1]}.each {|a|
42
- match_array << a[0] if (REF_SIZE[match_array.size] || 4) < a[2]
117
+ def self.build_maps(count, match_array, translate, prefixes)
118
+ klcount = Hash.new(0)
119
+ mapvalues = Hash.new {|h, kl| # kl = key list
120
+ h.member?(kl) or h[kl] = Hash.new {|hv, kv|
121
+ hv.member?(kv) or hv[kv] = Hash.new(0)
122
+ }
43
123
  }
44
- # pp match_array
45
124
 
46
- # XXX the below needs to be done with arrays and (hard!) maps as well
125
+ count.select {|o, _n| Hash === o}.each do |o, _n|
126
+ kl = o.keys.sort
127
+ klcount[kl] += 1
128
+ v = o.values_at(*kl)
129
+ z = kl.zip(v)
130
+ z.each do |k1, v1|
131
+ mapvalues[kl][k1][v1] += 1
132
+ end
133
+ end
134
+ repkl = klcount.select {|kl, n| n > 1}.sort_by {|kl, n| -n} # sort not needed
135
+ # fudge here -- ignore single children even in parent selection
136
+
137
+ # parent selection
138
+
139
+ klparents = {}
140
+ repkl.map do |kl, n|
141
+ klparent = {}
142
+ mapvalues[kl].each do |k1, v1|
143
+ repv = v1.to_a.select{|k2, v2| v2 > (n+3)/2} # low-hanging ->
144
+ if repv != [] # -> should be zero or one of them
145
+ # pp [k1, repv]
146
+ # The k1 values are those that go into the head arrays
147
+ # first .first: low-hanging, second .first: repeated member value
148
+ klparent[k1] = repv.first.first
149
+ end
150
+ end
151
+ # pp klparent
152
+ if klparent != {}
153
+ ix = prefixes.size
154
+ prefixes << klparent
155
+ constant_keys = Set[*klparent.keys]
156
+ variable_keys = Set[*kl] - constant_keys
157
+ klparents[kl] = [
158
+ klparent, argref(ix), constant_keys, variable_keys.to_a
159
+ ]
160
+ end
161
+ end
162
+
163
+ klmatch = {}
164
+
165
+ count.select {|o, _n| Hash === o}.each do |o, _n|
166
+ kl = o.keys.sort
167
+ klp, ref, constant_keys, variable_kl = klparents[kl]
168
+ if klp # split off parent, return to common code then
169
+ oouter = o
170
+ o = o.reject {|k| constant_keys.include? k}
171
+ kl = variable_kl
172
+ end
173
+ if kl.size > 1 && (klp || klcount[kl] > 1) # TODO: tune
174
+ unless ix = klmatch[kl]
175
+ ix = prefixes.size
176
+ prefixes << CBOR::Tagged.new(RECORD_TAG, kl)
177
+ klmatch[kl] = ix
178
+ end
179
+ packed = translate[o] = CBOR::Tagged.new(argref(ix), o.values_at(*kl)) # needs packing
180
+ end
181
+ if packed && klp
182
+ translate[oouter] = CBOR::Tagged.new(ref, packed) # merge Hashes
183
+ end
184
+ end
185
+
186
+ end
187
+
188
+ CBOR_PACKED_HEX = ENV["CBOR_PACKED_HEX"]
189
+ CBOR_PACKED_MAPS = ENV["CBOR_PACKED_MAPS"]
190
+
191
+ def self.from_item(item)
192
+ count, match_array = build_match_array(item)
193
+
194
+ # TODO: the below needs to be done with arrays and (hard!) maps as well
47
195
  # do this on the reverse to find common suffixes
196
+
197
+ translate = {} # map (sub)items to their arg-packed versions
198
+ prefixes = [] # provisional prefix table used in the above
199
+
48
200
  # select all strings (ignoring reference counts) and sort them
49
201
  strings = count.select {|k, v| String === k}.map(&:first).sort
50
202
  if strings != []
51
- string_common = strings[1..-1].zip(strings).map{ |y, x|
52
- l = x.chars.zip(y.chars).take_while{|a, b| a == b}.length # should be bytes
53
- [x, l]
54
- } << [strings[-1], 0]
203
+ strings = build_bytes_from_hex(strings, count, match_array, item, translate, prefixes) if CBOR_PACKED_HEX
204
+ if strings != []
205
+ string_common = strings[1..-1].zip(strings).map{ |y, x|
206
+ l = x.chars.zip(y.chars).take_while{|a, b| a == b}.length # should be bytes
207
+ [x, l]
208
+ } << [strings[-1], 0]
209
+ end
55
210
  # string_common: list of strings/counts of number of /bytes/ matching with next
56
211
  # pp string_common
57
212
  end
58
- translate = {}
59
- prefixes = []
60
213
  if string_common
214
+
61
215
  prefix_stack = [[0, false]] # sentinel
62
216
  pos = 0 # mirror prefix_stack[-1][0]
63
- tag_no = REF_TAG
217
+ tag_no = argref(prefixes.size) # REF_TAG
64
218
  string_common.each do |s, l|
65
219
  if l > pos + 2 + $compression_hack
66
220
  if t = prefix_stack[-1][1] # if we still have a prefix left
@@ -71,8 +225,9 @@ module CBOR
71
225
  prefix_stack << [l, tag_no]
72
226
  pos = l
73
227
  tag_no += 1
74
- tag_no = 225 if tag_no == REF_TAG+1
228
+ tag_no = 225 if tag_no == REF_TAG+1 # skip 224, as we always can use 6 here
75
229
  tag_no = 28704 if tag_no == 256
230
+ tag_no = 1879052288 if tag_no == 32768
76
231
  end
77
232
  if t = prefix_stack[-1][1] # if we still have a viable prefix left
78
233
  translate[s] = CBOR::Tagged.new(t, s[pos..-1])
@@ -87,8 +242,45 @@ module CBOR
87
242
  end
88
243
 
89
244
  end
90
- # pp translate
91
- # XXX test replacing match_array here
245
+ # pp [:TRANSLATE, translate]
246
+ # pp [:PREFIXES, prefixes]
247
+ # Note that we didn't compute a suffix table to mix in
248
+
249
+ build_maps(count, match_array, translate, prefixes) if CBOR_PACKED_MAPS
250
+
251
+ match_array_size = match_array.size
252
+ mixed = match_array_size + prefixes.size <= STRAIGHT_11_SIZE
253
+ if mixed && match_array_size != 0
254
+ # We need to shift by match_array_size
255
+ translate = Hash[translate.map {|k, v|
256
+ PP.pp v, STDERR
257
+ newtag = v.tag
258
+ if newtag == REF_TAG
259
+ newtag = 224
260
+ end
261
+ # this works only if <= STRAIGHT_11_SIZE (above)
262
+ newtag += match_array_size
263
+ [k, CBOR::Tagged.new(newtag, v.value)]
264
+ }]
265
+ prefixes = prefixes.map {|p|
266
+ if CBOR::Tagged === p
267
+ case p.tag
268
+ when REF_TAG
269
+ CBOR::Tagged.new(224 + match_array_size, p.value)
270
+ when 224..255
271
+ CBOR::Tagged.new(p.tag + match_array_size, p.value)
272
+ else # this works only if <= STRAIGHT_11_SIZE (above)
273
+ p
274
+ end
275
+ else
276
+ p
277
+ end
278
+ }
279
+ # pp translate
280
+ # pp prefixes
281
+ end
282
+
283
+ # Check match_array for direct entries of an arg-packed string
92
284
  match_array = match_array.map do |v|
93
285
  if r = translate[v]
94
286
  # puts "*** replacing #{v.inspect} by #{r.inspect}"
@@ -97,18 +289,18 @@ module CBOR
97
289
  v
98
290
  end
99
291
  end
100
- # pp [:PREFIXES, prefixes]
101
- # pp translate
102
- new(match_array, prefixes, [], translate)
292
+
293
+ new(match_array, prefixes, translate, mixed)
103
294
  end
104
- def initialize(match_array, prefix_array, suffix_array, translate)
295
+ def initialize(match_array, argument_array, translate, mixed)
296
+ @mixed = mixed
105
297
  @hit = translate
106
298
  # XXX: make sure we don't overwrite the existing prefix compression values!
107
299
  # (this should really be done downwards, ...) 16 x 1, 160 x 2, (512-48) x 3
108
300
  match_array[0...16].each_with_index do |o, i|
109
301
  @hit[o] = CBOR::Simple.new(i)
110
302
  end
111
- # if m = match_array[16...128]
303
+ # if m = match_array[16...128] # no allocation for simple(16...128)
112
304
  # m.each_with_index do |o, i|
113
305
  # @hit[o] = CBOR::Simple.new(i + 128)
114
306
  # end
@@ -124,49 +316,48 @@ module CBOR
124
316
  @hit[k] = r
125
317
  end
126
318
  end
127
- # p @hit
319
+ # warn [:HIT, @hit['688921AF59455E4D35D2FFE5FD21CA0598D42374'.xeh]].inspect
128
320
  @match_array = match_array
129
321
  # @prefix = {} -- do that later
130
- @prefix_array = prefix_array
131
- @suffix_array = suffix_array
322
+ @argument_array = argument_array
132
323
  end
133
324
  def has(o)
325
+ # warn [:HIT1].inspect if o == '688921AF59455E4D35D2FFE5FD21CA0598D42374'.xeh
134
326
  @hit[o]
135
327
  end
136
328
  def pack(pa)
137
- # Don't forget to pack the match_array!
138
- CBOR::Tagged.new(PACKED_TAG, [@match_array, @prefix_array, @suffix_array, pa])
329
+ pa = pa.to_packed_cbor1(self) # should also sort by frequency...
330
+ if @mixed
331
+ mixed_array = @match_array + @argument_array
332
+ CBOR::Tagged.new(MIXED_PACKED_TAG, [mixed_array, pa])
333
+ else
334
+ CBOR::Tagged.new(PACKED_TAG, [@match_array, @argument_array, pa])
335
+ end
139
336
  end
140
337
  end
141
338
 
142
339
  class Unpacker
143
- def initialize(match_array, prefix_array, suffix_array)
340
+ def initialize(match_array, argument_array)
144
341
  @simple_array = match_array[0...16]
145
342
  @tagged_array = match_array[16..-1]
146
343
  # index with 2i for i >= 0 or ~2i for i < 0
147
344
  # no map as we need to populate in progress
148
- # pp prefix_array
149
- @prefix_array = []
150
- prefix_array.each {|x| @prefix_array << x.to_unpacked_cbor1(self)}
151
- @suffix_array = []
152
- suffix_array.each {|x| @prefix_array << x.to_unpacked_cbor1(self)}
153
- # XXX order? -- must do lazily!
345
+ # pp argument_array
346
+ @argument_array = []
347
+ @raw_argument_array = argument_array
154
348
  end
155
349
  def unsimple(sv)
156
- @simple_array[sv]
350
+ @simple_array[sv].to_unpacked_cbor1(self)
157
351
  end
158
352
  def untag(i)
159
353
  # @tagged_array[(i << 1) ^ (i >> 63)]
160
354
  ix = (i << 1) ^ (i >> 63)
161
355
  ret = @tagged_array[ix]
162
356
  # warn "** UNTAG i=#{i} ix=#{ix} ret=#{ret}"
163
- ret
357
+ ret.to_unpacked_cbor1(self)
164
358
  end
165
359
  def unprefix(n)
166
- @prefix_array[n]
167
- end
168
- def unsuffix(n)
169
- @suffix_array[n]
360
+ @argument_array[n] ||= @raw_argument_array[n].to_unpacked_cbor1(self)
170
361
  end
171
362
  end
172
363
 
@@ -209,6 +400,16 @@ module CBOR
209
400
  # add checks
210
401
  lhs = to_unpacked_cbor1(unpacker)
211
402
  rhs = other.to_unpacked_cbor1(unpacker)
403
+ if CBOR::Tagged === rhs
404
+ case rhs.tag
405
+ when HEX_LC_TAG
406
+ rhs = rhs.value.unpack("H*").first
407
+ when HEX_UC_TAG
408
+ rhs = rhs.value.unpack("H*").first.upcase
409
+ else
410
+ fail ArgumentError, "*** String#packed_merge: unknown tag #{rhs.tag} on rhs"
411
+ end
412
+ end
212
413
  begin
213
414
  lhs + rhs
214
415
  rescue => detail
@@ -268,8 +469,13 @@ module CBOR
268
469
  end
269
470
  end
270
471
  def packed_merge(other, unpacker)
271
- # TODO: add checks
272
- to_unpacked_cbor1(unpacker).merge other.to_unpacked_cbor1(unpacker)
472
+ rhs = other
473
+ until Hash === rhs
474
+ rhso = rhs
475
+ rhs = rhs.to_unpacked_cbor1(unpacker)
476
+ fail ArgumentError, "*** In #{self.inspect}, cannot further unpack #{rhs.inspect}" unless rhso != rhs
477
+ end
478
+ to_unpacked_cbor1(unpacker).merge rhs
273
479
  end
274
480
  end
275
481
  Hash.send(:include, Hash_Packed_CBOR)
@@ -284,11 +490,17 @@ module CBOR
284
490
  if tag == PACKED_TAG
285
491
  # check that this really is an array
286
492
  # warn value.to_yaml
287
- ma, pa, sa, pv = value
288
- unpacker = Unpacker.new(ma, pa, sa)
493
+ ma, aa, pv = value
494
+ unpacker = Unpacker.new(ma, aa)
495
+ pv.to_unpacked_cbor1(unpacker)
496
+ elsif tag == MIXED_PACKED_TAG
497
+ # check that this really is an array
498
+ # warn value.to_yaml
499
+ args, pv = value
500
+ unpacker = Unpacker.new(args, args)
289
501
  pv.to_unpacked_cbor1(unpacker)
290
502
  else
291
- fail "error message here"
503
+ fail "*** Don't know how to unpack tag #{tag}"
292
504
  end
293
505
  end
294
506
  def to_unpacked_cbor1(unpacker)
@@ -319,9 +531,30 @@ module CBOR
319
531
  CBOR::Tagged.new(tag, value.to_unpacked_cbor1(unpacker))
320
532
  end
321
533
  end
534
+ def packed_merge(other, unpacker)
535
+ # tag must be a function tag -- TODO add standin tag decoder for lhs (value)
536
+ case tag
537
+ when RECORD_TAG
538
+ rhs = other.to_unpacked_cbor1(unpacker)
539
+ raise ArgumentError, "*** need arrays for record tag (#{
540
+ value.inspect}, #{rhs.inspect})" unless Array === value && Array === rhs
541
+ n = value.size - rhs.size
542
+ if n > 0
543
+ rhs += [UNDEFINED] * n
544
+ elsif n < 0
545
+ raise ArgumentError, "*** too many values (#{rhs.inspect
546
+ }) for record tag keys (#{value.inspect
547
+ })" unless Array === value && Array === rhs
548
+ end
549
+ Hash[value.zip(rhs).select{|k, v| v != UNDEFINED}]
550
+ else
551
+ raise ArgumentError, "*** function tag #{tag} not implemented"
552
+ end
553
+ end
554
+
322
555
  def to_packed_cbor1(packer = Packer.from_item(self))
323
556
  if c = packer.has(self)
324
- c
557
+ c.to_packed_cbor1(packer)
325
558
  else
326
559
  CBOR::Tagged.new(tag, value.to_packed_cbor1(packer))
327
560
  end
data/test/exa2r1.rb ADDED
@@ -0,0 +1,58 @@
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
+ 1113([/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
+ /rump/ {simple(0): "MyLED",
42
+ "interactions": [
43
+ 229({simple(2): [{simple(3): 227("Red"), simple(4): simple(5)}],
44
+ simple(0): 228("Red")}),
45
+ 229({simple(2): [{simple(3): 227("Green"), simple(4): simple(5)}],
46
+ simple(0): 228("Green")}),
47
+ 229({simple(2): [{simple(3): 227("Blue"), simple(4): simple(5)}],
48
+ simple(0): 228("Blue")}),
49
+ 229({simple(2): [{simple(3): 227("White"), simple(4): simple(5)}],
50
+ simple(0): "rgbValueWhite"}),
51
+ {simple(2): [{simple(3): 226("ledOnOff"), simple(4): simple(5)}],
52
+ simple(6): {simple(10): {simple(11): "boolean"}}, simple(0):
53
+ "ledOnOff", simple(9): true, simple(1): simple(8)},
54
+ {simple(2): [{simple(3): 226("colorTemperatureChanged"),
55
+ simple(4): simple(5)}], simple(6): simple(7), simple(0):
56
+ "colorTemperatureChanged", simple(1): ["Event"]}],
57
+ simple(1): "Lamp", "id": "0", "base": 225(""),
58
+ "@context": 6("2:8444/wot/w3c-wot-td-context.jsonld")}])
data/test/test-packed.rb CHANGED
@@ -35,16 +35,18 @@ puts "CBOR packed: #{cbp.length}"
35
35
  File.write("/tmp/cbp", cbp)
36
36
  File.write("/tmp/cbu", cb)
37
37
  pad = CBOR.decode(cbp)
38
- # puts pad.to_yaml
38
+ puts "--- packed decoded ---"
39
+ puts pad.to_yaml
39
40
  up = pad.to_unpacked_cbor
40
- pp up == jo
41
+ pp [:EQUAL, up == jo]
41
42
  if up != jo
43
+ puts "--- not equal ---"
42
44
  puts up.to_yaml
43
45
  puts pad.to_yaml # get rid of unwanted sharing...
44
46
  end
45
47
 
46
48
  # puts "#{pa.value.map {|x| x.to_cbor.length}}"
47
- puts pa.value[1].to_json
49
+ puts "pa.value[1].to_json: ", pa.value[1].to_json
48
50
 
49
51
  exin = JSON.load(DATA)
50
52
  exout = exin.to_packed_cbor
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cbor-packed
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Carsten Bormann
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-03-30 00:00:00.000000000 Z
11
+ date: 2025-01-03 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: cbor-packed implements packed encoding for CBOR, RFC 7049 Section 3.9
14
14
  email: cabo@tzi.org
@@ -20,6 +20,7 @@ files:
20
20
  - lib/cbor-packed.rb
21
21
  - test/exa2.rb
22
22
  - test/exa2r.rb
23
+ - test/exa2r1.rb
23
24
  - test/test-packed.rb
24
25
  homepage: http://cbor.io/
25
26
  licenses:
@@ -40,11 +41,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
40
41
  - !ruby/object:Gem::Version
41
42
  version: '0'
42
43
  requirements: []
43
- rubygems_version: 3.3.7
44
+ rubygems_version: 3.5.14
44
45
  signing_key:
45
46
  specification_version: 4
46
47
  summary: CBOR (Concise Binary Object Representation) packer
47
48
  test_files:
48
49
  - test/exa2.rb
49
50
  - test/exa2r.rb
51
+ - test/exa2r1.rb
50
52
  - test/test-packed.rb