cbor-packed 0.1.5 → 0.2.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.
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