cddl 0.8.8 → 0.8.13

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: 6c877883cb125426e061f527ba4375c0f021d70dfef060336fe0bb0f5e2ca3d4
4
- data.tar.gz: 7a3dc4065f3616bf57c229b410782b35140018ecada4418c0ef45056c62aef0b
3
+ metadata.gz: bbd414d9d4fbc897f8f31c03437fa57155547c0f02978de2da4f75844cf0e1ef
4
+ data.tar.gz: 9aa239d57c5e70f8352da90cc8023273a2793577df84ee6e003a1ac0fdc200dc
5
5
  SHA512:
6
- metadata.gz: b3987fbe82e80dddba2f650b1a12941ed6092708297302cf1a78dfe45b20b79d08e85901cb8739b5fc79eab8cde70ca8efb88698f4340da72c722a7a461565c6
7
- data.tar.gz: 68c35688bac9b30411ee419e171860c463df28c3452bce1741399274e51295b609e0acc8df54e9876037f9d96ba02e369fd9465c2fe7c38bb9682d5ec19018cd
6
+ metadata.gz: 00dac4c95e0b94e0bc3ae775b1bf1ab33a41507bb06774ccaa0838daf6c9fffc0c2d4b3d049199c3ae35858888be853058248c710ea056edd718a0938fd7d8e3
7
+ data.tar.gz: 18ea8731c6ab8ec9ae547331be276b9ca1c58c490c6986969824a0a56c7870478ca01418f8ae83a5504d393c14e9fcc5764bfc0cb65c7f2f267cd1757dfbdbac
@@ -1,6 +1,6 @@
1
1
  spec = Gem::Specification.new do |s|
2
2
  s.name = 'cddl'
3
- s.version = '0.8.8'
3
+ s.version = '0.8.13'
4
4
  s.summary = "CDDL generator and validator."
5
5
  s.description = %{A parser, generator, and validator for CDDL}
6
6
  s.add_dependency('cbor-diag')
@@ -19,3 +19,4 @@ spec = Gem::Specification.new do |s|
19
19
  s.homepage = "http://github.com/cabo/cddl"
20
20
  s.license = 'MIT'
21
21
  end
22
+
@@ -16,6 +16,7 @@ type1 = type2 [S (rangeop / annotator) S type2]
16
16
  / "#" "6" ["." uint] "(" S type S ")" ; note no space!
17
17
  / "#" DIGIT ["." uint] ; major/ai
18
18
  / "#" ; any
19
+ / "~" S typename [genericarg]
19
20
  / "{" S group S "}"
20
21
  / "[" S group S "]"
21
22
  / "&" S "(" S group S ")"
@@ -329,8 +329,12 @@ module CDDL
329
329
  unless kr
330
330
  case vr[0]
331
331
  when :grpent
332
- fail "grpent in map #{vr.inspect}" unless vr.size == 2
333
- g = Array.new(st) { generate1(vr[1], true) }.flatten(1)
332
+ # fail "grpent in map #{vr.inspect}" unless vr.size == 2
333
+ g = Array.new(st) {
334
+ vr[1..-1].map{ |vrx|
335
+ generate1(vrx, true)
336
+ }.flatten(1)
337
+ }.flatten(1)
334
338
  # warn "GGG #{g.inspect}"
335
339
  return g
336
340
  when :grpchoice
@@ -435,6 +439,8 @@ module CDDL
435
439
  $default_warned = true
436
440
  end
437
441
  generate1(target, inmap)
442
+ when :feature
443
+ generate1(target, inmap)
438
444
  when :eq
439
445
  content = generate1(control)
440
446
  if validate1(content, where)
@@ -523,7 +529,7 @@ module CDDL
523
529
  end
524
530
  end
525
531
 
526
- VALUE_TYPE = {text: String, int: Integer, float: Float}
532
+ VALUE_TYPE = {text: String, bytes: String, int: Integer, float: Float}
527
533
  SIMPLE_VALUE = {
528
534
  [:prim, 7, 20] => [true, false, :bool],
529
535
  [:prim, 7, 21] => [true, true, :bool],
@@ -541,17 +547,33 @@ module CDDL
541
547
  end
542
548
  end
543
549
 
550
+ def extract_array(t)
551
+ return [false] unless t[0] == :array
552
+ [true, *t[1..-1].map { |el|
553
+ return [false] unless el[0..3] == [:member, 1, 1, nil]
554
+ ok, v, vt = extract_value(el[4])
555
+ return [false] unless ok
556
+ [v, vt]
557
+ }]
558
+ end
559
+
544
560
  def validate_diag
545
561
  [@last_data, @last_rule, @last_message]
546
562
  end
547
563
 
548
564
  def validate(d, warn=true)
549
565
  @recursion = 0
566
+ $features = Hash.new {|h, k| h[k] = {}}
550
567
  result = validate1a(d, rules)
551
- unless result
552
- if warn
568
+ if warn
569
+ if result
570
+ if $features != {}
571
+ warn "** Features potentially used: #{$features.map {|k, v| "#{k}: #{v.keys}"}.join(", ")}"
572
+ end
573
+ else
553
574
  warn "CDDL validation failure (#{result.inspect} for #{d.inspect}):"
554
575
  PP::pp(validate_diag, STDERR)
576
+ puts(validate_diag.cbor_diagnostic)
555
577
  end
556
578
  end
557
579
  result
@@ -741,9 +763,12 @@ module CDDL
741
763
  idx, ann = validate_forward(d, 0, where)
742
764
  ann if validate_result(idx == d.size) { "#{validate_diag.inspect} -- cannot complete (#{idx}, #{d.size}) array #{d} for #{where}" }
743
765
  end
744
- when :text, :int, :float, :bytes
766
+ when :int, :float
745
767
  _, v = extract_value(where)
746
768
  [] if d == v
769
+ when :text, :bytes
770
+ _, v = extract_value(where)
771
+ [] if d == v && ((d.encoding == Encoding::BINARY) == (v.encoding == Encoding::BINARY))
747
772
  when :range
748
773
  [] if where[2] === d && where[1].include?(d)
749
774
  when :anno
@@ -789,6 +814,22 @@ module CDDL
789
814
  $default_warned = true
790
815
  end
791
816
  ann
817
+ when :feature
818
+ ok, v, vt = extract_value(control)
819
+ if ok
820
+ nm = v
821
+ det = d
822
+ else
823
+ ok, *v = extract_array(control)
824
+ if ok && v.size == 2
825
+ nm = v[0][0]
826
+ det = v[1][0]
827
+ else
828
+ warn "*** feature controller not implemented: #{control.inspect}"
829
+ end
830
+ end
831
+ $features[nm][det] = true
832
+ ann
792
833
  when :lt, :le, :gt, :ge, :eq, :ne
793
834
  op = OPERATORS[where[1]]
794
835
  ok, v, _vt = extract_value(control)
@@ -837,6 +878,14 @@ module CDDL
837
878
  when 3
838
879
  String === d && d.encoding != Encoding::BINARY # cheat
839
880
  when 6
881
+ if Integer === d
882
+ t = 2 # assuming only 2/3 match an Integer
883
+ if d < 0
884
+ d = ~d
885
+ t = 3
886
+ end
887
+ d = CBOR::Tagged.new(t, d == 0 ? "".b : d.digits(256).reverse!.pack("C*"))
888
+ end
840
889
  CBOR::Tagged === d && d.tag == where[2] && validate1a(d.data, where[3])
841
890
  when 7
842
891
  t, v = extract_value(where)
@@ -959,7 +1008,7 @@ module CDDL
959
1008
  when ""
960
1009
  parts[1].b
961
1010
  when "h"
962
- parts[1].gsub(/\s/, "").chars.each_slice(2).map{ |x| Integer(x.join, 16).chr("BINARY") }.join
1011
+ parts[1].gsub(/\s/, "").chars.each_slice(2).map{ |x| Integer(x.join, 16).chr("BINARY") }.join.b
963
1012
  when "b64"
964
1013
  Base64.urlsafe_decode64(parts[1])
965
1014
  else
@@ -1142,7 +1191,7 @@ module CDDL
1142
1191
  end
1143
1192
  when :recurse_grpent # XXX we don't have the entry yet
1144
1193
  when :member
1145
- fail "map entry without member key given: #{member}" unless member[3] || member[4][0] == :grpent || member[4][0] == :grpchoice
1194
+ fail "map entry #{member.inspect} without member key given: #{member}" unless member[3] || member[4][0] == :grpent || member[4][0] == :grpchoice
1146
1195
  else
1147
1196
  fail ["type1 member", member].inspect unless member[0] == :member
1148
1197
  end
@@ -1152,7 +1201,7 @@ module CDDL
1152
1201
  BRACE = {"{" => :map, "[" => :array}
1153
1202
  RANGE_EXCLUDE_END = {".." => false, "..." => true}
1154
1203
  SUPPORTED_ANNOTATIONS = [:bits, :size, :regexp, :cbor, :cborseq, :within, :and,
1155
- :default, :lt, :le, :gt, :ge, :eq, :ne]
1204
+ :default, :lt, :le, :gt, :ge, :eq, :ne, :feature]
1156
1205
 
1157
1206
  def type1(n, canbegroup = false)
1158
1207
  # puts "NVALUE #{n.value.inspect}"
@@ -1214,6 +1263,26 @@ module CDDL
1214
1263
  v
1215
1264
  }
1216
1265
  ]
1266
+ when /\A~/
1267
+ if tn = n.typename
1268
+ s = type_recall(tn.to_s, false, n.genericarg).flatten(1)
1269
+ else
1270
+ fail "No typename in unwrap #{n}"
1271
+ end
1272
+ if s[0] != :type1
1273
+ fail [:UNWRAPs0, s].inspect
1274
+ end
1275
+ case s[1]
1276
+ when :map, :array
1277
+ [:grpent, s[2..-1]]
1278
+ when :prim
1279
+ if s[2] != 6
1280
+ fail [:UNWRAPs2, s].inspect
1281
+ end
1282
+ s[4] # check :type1?
1283
+ else
1284
+ fail [:UNWRAPs1, s].inspect
1285
+ end
1217
1286
  else
1218
1287
  "unimplemented #{n}"
1219
1288
  end
@@ -0,0 +1,14 @@
1
+ coap-problem-details = {
2
+ type => uint,
3
+ ? title => text,
4
+ ? response-code => bstr .size 1,
5
+ ? detail => text,
6
+ ? instance => uri,
7
+ * $$coap-problem-details-extension,
8
+ }
9
+
10
+ type = 0
11
+ title = 1
12
+ response-code = 2
13
+ detail = 3
14
+ instance = 4
@@ -0,0 +1 @@
1
+ abignum = unsigned
@@ -0,0 +1,136 @@
1
+ start = bundle
2
+
3
+ dtn-time = uint
4
+
5
+ creation-timestamp = [dtn-time, sequence: uint]
6
+
7
+ eid-generic = [uri-code, SSP: any]
8
+
9
+ uri-code = uint
10
+
11
+ eid = eid-choice .within eid-generic
12
+
13
+ eid-choice /= [dtn-code, SSP: (text / 0)]
14
+
15
+ dtn-code = 1 ; TBD
16
+
17
+ eid-choice /= [ipn-code, SSP: [nodenum: uint, servicenum: uint]]
18
+
19
+ ipn-code = 2 ; TBD
20
+
21
+ bundle-control-flags = uint .bits bundleflagbits
22
+
23
+ bundleflagbits = &(
24
+
25
+ reserved: 15
26
+
27
+ reserved: 14
28
+
29
+ reserved: 13
30
+
31
+ bundle-deletion-status-reports-are-requested: 12
32
+
33
+ bundle-delivery-status-reports-are-requested: 11
34
+
35
+ bundle-forwarding-status-reports-are-requested: 10
36
+
37
+ reserved: 9
38
+
39
+ bundle-reception-status-reports-are-requested: 8
40
+
41
+ bundle-contains-a-Manifest-block: 7
42
+
43
+ status-time-is-requested-in-all-status-reports: 6
44
+
45
+ user-application-acknowledgement-is-requested: 5
46
+
47
+ reserved: 4
48
+
49
+ reserved: 3
50
+
51
+ bundle-must-not-be-fragmented: 2
52
+
53
+ payload-is-an-administrative-record: 1
54
+
55
+ bundle-is-a-fragment: 0
56
+
57
+ )
58
+
59
+ crc = bytes
60
+
61
+ block-control-flags = uint .bits blockflagbits
62
+
63
+ blockflagbits = &(
64
+
65
+ reserved: 7
66
+
67
+ reserved: 6
68
+
69
+ reserved: 5
70
+
71
+ reserved: 4
72
+
73
+ bundle-must-be-deleted-if-block-cannot-be-processed: 3
74
+
75
+ status-report-must-be-transmitted-if-block-cannot-be-processed: 2
76
+
77
+ block-must-be-removed-from-bundle-if-it-cannot-be-processed: 1
78
+
79
+ block-must-be-replicated-in-every-fragment: 0
80
+
81
+ )
82
+
83
+ bundle = [primary-block, *extension-block, payload-block]
84
+
85
+ primary-block = [
86
+
87
+ version: 7,
88
+
89
+ bundle-control-flags,
90
+
91
+ crc-type: uint,
92
+
93
+ destination: eid,
94
+
95
+ source-node: eid,
96
+
97
+ report-to: eid,
98
+
99
+ creation-timestamp,
100
+
101
+ lifetime: uint,
102
+
103
+ ? fragment-offset: uint,
104
+
105
+ ? total-application-data-length: uint,
106
+
107
+ ? crc,
108
+
109
+ ]
110
+
111
+ canonical-block = [
112
+
113
+ block-type-code: uint,
114
+
115
+ canonical-block-common,
116
+
117
+ ? crc
118
+
119
+ ]
120
+
121
+ canonical-block-common = (
122
+
123
+ block-number: uint,
124
+
125
+ block-control-flags,
126
+
127
+ crc-type: uint,
128
+
129
+ block-type-specific-data: bytes
130
+
131
+ )
132
+
133
+
134
+ payload-block = ([block-type-code: 1, canonical-block-common, ?crc]) .within canonical-block
135
+
136
+ extension-block = ([block-type-code: (uint .ne 1), canonical-block-common, ?crc]) .within canonical-block
@@ -0,0 +1,181 @@
1
+ start = bundle / #6.55799(bundle)
2
+
3
+ ; Times before 2000 are invalid
4
+ dtn-time = uint
5
+
6
+ ; CRC enumerated type
7
+ crc-type = 0 / 1 / 2
8
+ ; Either 16-bit or 32-bit
9
+ crc-value = (bstr .size 2) / (bstr .size 4)
10
+
11
+ creation-timestamp = [dtn-time, sequence: uint]
12
+
13
+ eid = $eid-choice .within eid-structure
14
+ eid-structure = [
15
+ uri-code: uint,
16
+ SSP: any
17
+ ]
18
+ $eid-choice /= [
19
+ uri-code: 1,
20
+ SSP: (tstr / 0)
21
+ ]
22
+ $eid-choice /= [
23
+ uri-code: 2,
24
+ SSP: [
25
+ nodenum: uint,
26
+ servicenum: uint
27
+ ]
28
+ ]
29
+
30
+ bundle-control-flags = uint .bits bundleflagbits
31
+ bundleflagbits = &(
32
+ reserved: 15
33
+ reserved: 14
34
+ reserved: 13
35
+ bundle-deletion-status-reports-are-requested: 12
36
+ bundle-delivery-status-reports-are-requested: 11
37
+ bundle-forwarding-status-reports-are-requested: 10
38
+ reserved: 9
39
+ bundle-reception-status-reports-are-requested: 8
40
+ bundle-contains-a-Manifest-block: 7
41
+ status-time-is-requested-in-all-status-reports: 6
42
+ user-application-acknowledgement-is-requested: 5
43
+ reserved: 4
44
+ reserved: 3
45
+ bundle-must-not-be-fragmented: 2
46
+ payload-is-an-administrative-record: 1
47
+ bundle-is-a-fragment: 0
48
+ )
49
+
50
+ block-control-flags = uint .bits blockflagbits
51
+ blockflagbits = &(
52
+ reserved: 7
53
+ reserved: 6
54
+ reserved: 5
55
+ reserved: 4
56
+ bundle-must-be-deleted-if-block-cannot-be-processed: 3
57
+ status-report-must-be-transmitted-if-block-cannot-be-processed: 2
58
+ block-must-be-removed-from-bundle-if-it-cannot-be-processed: 1
59
+ block-must-be-replicated-in-every-fragment: 0
60
+ )
61
+
62
+ bundle = [primary-block, *extension-block, payload-block]
63
+
64
+ primary-block = [
65
+ version: 7,
66
+ bundle-control-flags,
67
+ crc-type,
68
+ destination: eid,
69
+ source-node: eid,
70
+ report-to: eid,
71
+ creation-timestamp,
72
+ lifetime: uint,
73
+ ? (
74
+ fragment-offset: uint,
75
+ ; total-application-data-length: uint,
76
+ )
77
+ ? crc-value,
78
+ ]
79
+
80
+ ; Abstract shared structure of all non-primary blocks
81
+ canonical-block-structure = [
82
+ block-type-code: uint,
83
+ block-number: uint,
84
+ block-control-flags,
85
+ crc-type,
86
+ ; Each block type defines the content within the bytestring
87
+ block-type-specific-data,
88
+ ? crc-value
89
+ ]
90
+ block-type-specific-data = bstr / #6.24(bstr)
91
+ ; Extension block type, which does not specialize any more than the code/number
92
+ extension-block = $extension-block-structure .within canonical-block-structure
93
+ $extension-block-structure = [
94
+ block-type-code: (uint .gt 1),
95
+ extension-block-number,
96
+ block-control-flags,
97
+ crc-type,
98
+ ($extension-block-data .within block-type-specific-data)
99
+ ? crc-value
100
+ ]
101
+ extension-block-number = (uint .ne 0)
102
+ ; Payload block type
103
+ payload-block = payload-block-structure .within canonical-block-structure
104
+ payload-block-structure = [
105
+ block-type-code: 1,
106
+ block-number: 0,
107
+ block-control-flags,
108
+ crc-type,
109
+ ($payload-block-data .within block-type-specific-data)
110
+ ? crc-value
111
+ ]
112
+
113
+ ; Arbitrary payload data
114
+ $payload-block-data /= bstr
115
+
116
+
117
+ ; Administrative record as a payload data specialization
118
+ $payload-block-data /= block-type-specific-data .cbor admin-record
119
+ admin-record = $admin-record .within admin-record-structure
120
+ admin-record-structure = [
121
+ record-type-code: uint,
122
+ record-content: any
123
+ ]
124
+ ; Only one defined record type
125
+ $admin-record /= [1, status-record-content]
126
+ status-record-content = [
127
+ bundle-status-information,
128
+ status-report-reason-code: uint,
129
+ source-node-eid: eid,
130
+ subject-creation-timestamp: creation-timestamp,
131
+ ? (
132
+ subject-payload-offset: uint,
133
+ subject-payload-length: uint
134
+ )
135
+ ]
136
+ bundle-status-information = [
137
+ reporting-node-received-bundle: status-info-content,
138
+ reporting-node-forwarded-bundle: status-info-content,
139
+ reporting-node-delivered-bundle: status-info-content,
140
+ reporting-node-deleted-bundle: status-info-content
141
+ ]
142
+ status-info-content = [
143
+ status-indicator: bool,
144
+ ? timestamp: dtn-time
145
+ ]
146
+
147
+ ; Previous Node extension block
148
+ $extension-block-structure /= [
149
+ block-type-code: 7,
150
+ extension-block-number,
151
+ block-control-flags,
152
+ crc-type,
153
+ (block-type-specific-data .cbor ext-data-previous-node)
154
+ ? crc-value
155
+ ]
156
+ ext-data-previous-node = eid
157
+
158
+ ; Bundle Age extension block
159
+ $extension-block-structure /= [
160
+ block-type-code: 8,
161
+ extension-block-number,
162
+ block-control-flags,
163
+ crc-type,
164
+ (block-type-specific-data .cbor ext-data-bundle-age)
165
+ ? crc-value
166
+ ]
167
+ ext-data-bundle-age = uint
168
+
169
+ ; Hop Count extension block
170
+ $extension-block-structure /= [
171
+ block-type-code: 9,
172
+ extension-block-number,
173
+ block-control-flags,
174
+ crc-type,
175
+ (block-type-specific-data .cbor ext-data-hop-count)
176
+ ? crc-value
177
+ ]
178
+ ext-data-hop-count = [
179
+ hop-limit: uint,
180
+ hop-count: uint
181
+ ]