slow_blink 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/ext/slow_blink/ext_schema_parser/lexer.c +2793 -839
  3. data/ext/slow_blink/ext_schema_parser/lexer.h +14 -137
  4. data/ext/slow_blink/ext_schema_parser/parser.c +616 -670
  5. data/ext/slow_blink/ext_schema_parser/parser.h +6 -4
  6. data/ext/slow_blink/message/ext_compact_encoder/blink_compact.c +642 -0
  7. data/ext/slow_blink/message/ext_compact_encoder/blink_compact.h +411 -0
  8. data/ext/slow_blink/message/ext_compact_encoder/blink_debug.h +46 -0
  9. data/ext/slow_blink/message/ext_compact_encoder/blink_stream.c +314 -0
  10. data/ext/slow_blink/message/ext_compact_encoder/blink_stream.h +185 -0
  11. data/ext/slow_blink/message/ext_compact_encoder/ext_compact_encoder.c +382 -269
  12. data/lib/slow_blink/definition.rb +18 -53
  13. data/lib/slow_blink/dynamic_group.rb +8 -0
  14. data/lib/slow_blink/enum.rb +101 -0
  15. data/lib/slow_blink/field.rb +63 -33
  16. data/lib/slow_blink/generate_c/model.rb +89 -0
  17. data/lib/slow_blink/group.rb +119 -100
  18. data/lib/slow_blink/message/binary.rb +3 -4
  19. data/lib/slow_blink/message/boolean.rb +3 -4
  20. data/lib/slow_blink/message/date.rb +3 -4
  21. data/lib/slow_blink/message/decimal.rb +3 -5
  22. data/lib/slow_blink/message/{enumeration.rb → enum.rb} +17 -17
  23. data/lib/slow_blink/message/field.rb +77 -27
  24. data/lib/slow_blink/message/fixed.rb +5 -21
  25. data/lib/slow_blink/message/floating_point.rb +3 -4
  26. data/lib/slow_blink/message/group.rb +90 -161
  27. data/lib/slow_blink/message/integer.rb +24 -32
  28. data/lib/slow_blink/message/model.rb +50 -110
  29. data/lib/slow_blink/message/string.rb +3 -4
  30. data/lib/slow_blink/message/time.rb +5 -5
  31. data/lib/slow_blink/message/time_of_day.rb +5 -12
  32. data/lib/slow_blink/ref.rb +22 -71
  33. data/lib/slow_blink/schema.rb +64 -85
  34. data/lib/slow_blink/schema_buffer.rb +1 -4
  35. data/lib/slow_blink/static_group.rb +37 -0
  36. data/lib/slow_blink/string.rb +4 -5
  37. data/lib/slow_blink/sym.rb +8 -28
  38. data/lib/slow_blink/type.rb +10 -19
  39. data/lib/slow_blink/version.rb +1 -1
  40. data/lib/slow_blink.rb +1 -0
  41. data/test/tc_compact_encoder.rb +114 -147
  42. data/test/tc_inputs.rb +2 -4
  43. data/test/tc_model_string.rb +29 -0
  44. data/test/tc_schema_new.rb +212 -0
  45. metadata +17 -26
  46. data/ext/slow_blink/ext_schema_parser/common.h +0 -27
  47. data/ext/slow_blink/message/ext_compact_encoder/compact_encoder.c +0 -258
  48. data/ext/slow_blink/message/ext_compact_encoder/compact_encoder.h +0 -92
  49. data/lib/slow_blink/annotatable.rb +0 -48
  50. data/lib/slow_blink/annotation.rb +0 -47
  51. data/lib/slow_blink/enumeration.rb +0 -90
  52. data/lib/slow_blink/incremental_annotation.rb +0 -151
  53. data/lib/slow_blink/log.rb +0 -51
  54. data/lib/slow_blink/message/sequence.rb +0 -98
  55. data/lib/slow_blink/name_with_id.rb +0 -49
  56. data/lib/slow_blink/namespace.rb +0 -143
  57. data/lib/slow_blink/sequence.rb +0 -57
  58. data/test/tc_field.rb +0 -94
  59. data/test/tc_group.rb +0 -114
  60. data/test/tc_incr_annote.rb +0 -22
  61. data/test/tc_namespace.rb +0 -8
  62. data/test/tc_types.rb +0 -218
@@ -21,13 +21,10 @@
21
21
 
22
22
  module SlowBlink::Message
23
23
 
24
- # @abstract
25
- #
26
- # A Group may form a complete message or be nested as a {DynamicGroup}
27
- class Group
24
+ class StaticGroup
28
25
 
29
26
  # @private
30
- # @return [Hash<Field>] group fields
27
+ # @return [Array<Field>] group fields
31
28
  def self.fields
32
29
  @fields
33
30
  end
@@ -45,56 +42,30 @@ module SlowBlink::Message
45
42
  end
46
43
 
47
44
  # @private
48
- # @param input [String] Blink compact form
45
+ # @param input [StringIO, String] Blink compact form
49
46
  # @param stack [Array] used to measure depth of recursion
50
47
  # @return [Group, nil]
51
48
  # @raise [Error] recursion depth limit
52
- def self.from_compact!(input, stack)
49
+ def self.from_compact(input, stack)
53
50
 
54
51
  fields = {}
55
- extensions = []
56
52
 
57
53
  if stack.size < @maxRecursion
58
54
  stack << self
59
55
  else
60
56
  raise RecursionLimit
61
57
  end
62
-
63
- @fields.each do |fn, fd|
64
- fields[fn] = fd.from_compact!(input, stack)
65
- end
66
58
 
67
- if input.size > 0
68
- expected = input.getU32!
69
- if expected
70
- while extensions.size != expected do
71
- extensions << @extensionObject.from_compact!(input, stack)
72
- end
73
- else
74
- raise ExtensionPadding
75
- end
76
- end
77
-
78
- if input.size != 0
79
- raise ExtensionPadding
80
- end
81
-
82
- group = self.new(fields)
83
-
84
- extensions.each do |e|
85
- group.extension << group
59
+ @fields.each do |f|
60
+ fields[f.name] = f.from_compact(input, stack)
86
61
  end
87
62
 
88
63
  stack.pop
89
-
90
- group
64
+
65
+ self.new(fields)
91
66
 
92
67
  end
93
68
 
94
- # @api user
95
- # @return [Array<Group>] extension objects
96
- attr_reader :extension
97
-
98
69
  # @api user
99
70
  # Finds Field by name and calls {Field#set}(value)
100
71
  #
@@ -102,8 +73,8 @@ module SlowBlink::Message
102
73
  # @param value [Object]
103
74
  # @raise [IndexError, TypeError]
104
75
  def []=(name, value)
105
- if @value[name]
106
- @value[name].set(value)
76
+ if field = @value[name]
77
+ field.set(value)
107
78
  else
108
79
  raise IndexError.new "field #{name} is not defined in this group"
109
80
  end
@@ -117,8 +88,8 @@ module SlowBlink::Message
117
88
  # @return [Object]
118
89
  # @raise [IndexError, TypeError]
119
90
  def [](name)
120
- if @value[name]
121
- @value[name].get
91
+ if field = @value[name]
92
+ field.get
122
93
  else
123
94
  raise IndexError.new "field #{name} is not defined in this group"
124
95
  end
@@ -139,6 +110,7 @@ module SlowBlink::Message
139
110
  # @return [self]
140
111
  # @raise [IndexError, TypeError]
141
112
  def set(value)
113
+
142
114
  if value.kind_of? Hash
143
115
  value.each do |fn, fv|
144
116
  if @value[fn]
@@ -154,7 +126,7 @@ module SlowBlink::Message
154
126
  end
155
127
  end
156
128
  # replace @value with value from another instance of self.class
157
- elsif value.is_a? self.class
129
+ elsif value.kind_of? self.class
158
130
  @value = value.fields.to_h
159
131
  else
160
132
  raise TypeError.new "expecting a Hash or a StaticGroup instance"
@@ -168,42 +140,27 @@ module SlowBlink::Message
168
140
  # @note calls {#set}(fields)
169
141
  # @param fields [Hash]
170
142
  def initialize(fields={})
171
- @extension = []
172
- @fields = self.class.fields
173
143
  @value = {}
174
- self.class.fields.each do |fn, fd|
175
- @value[fn] = fd.new(nil)
144
+ self.class.fields.each do |f|
145
+ @value[f.name] = f.new(nil)
176
146
  end
177
147
  set(fields)
178
148
  end
179
149
 
180
150
  # @return [String] Blink Protocol compact form
181
- def encode_compact
151
+ def encode_compact
182
152
  if self.class.id
183
- to_compact("")
153
+ to_compact("")
184
154
  else
185
155
  raise UntaggedGroup.new "cannot encode a group without an ID"
186
156
  end
187
157
  end
188
158
 
189
159
  # @private
190
- def to_compact(out)
191
- group = "".putU64(self.class.id)
160
+ def to_compact(out)
192
161
  @value.each do |fn, fv|
193
- fv.to_compact(group)
194
- end
195
- if @extension.size > 0
196
- group.putU32(@extension.size)
197
- @extension.each do |e|
198
- #if e.is_a? @extensionObject
199
- e.to_compact(group)
200
- #else
201
- # raise EncodingError.new "cannot convert unknown extension object to compact form"
202
- #end
203
- end
204
- end
205
- out.putU32(group.size)
206
- out << group
162
+ fv.to_compact(out)
163
+ end
207
164
  end
208
165
 
209
166
  protected
@@ -215,105 +172,57 @@ module SlowBlink::Message
215
172
  end
216
173
 
217
174
  end
175
+
176
+ class Group < StaticGroup
218
177
 
219
- # @abstract
220
- #
221
- # A StaticGroup is a kind of {Group} that can only exist as the contents of a {Field}
222
- class StaticGroup < Group
178
+ attr_reader :extension
223
179
 
224
- # @private
225
- #
226
- # @note optionality affects how instances of this type are encoded
227
- #
228
- # @return [true,false] is optional
229
- def self.opt?
230
- @opt
180
+ def self.ancestorID
181
+ @ancestorID
231
182
  end
232
183
 
233
- # @private
234
- # @param input [String] Blink compact form
235
- # @param stack [Array] used to measure depth of recursion
236
- # @return [Group, nil]
237
- # @raise [Error] recursion depth limit
238
- def self.from_compact!(input, stack)
239
-
240
- if stack.size < @maxRecursion
241
- stack << self
242
- else
243
- raise RecursionLimit
244
- end
245
-
246
- if @opt
247
- present = input.getPresent
248
- else
249
- present = true
250
- end
251
- if present
252
- fields = {}
253
- @fields.each do |fn, fd|
254
- fields[fn] = fd.from_compact!(input, stack)
255
- end
256
- result = self.new(fields)
257
- else
258
- nil
259
- end
260
-
261
- stack.pop
262
- result
263
-
184
+ def initialize(fields={}, *extension)
185
+ super(fields)
186
+ @extension = extension
264
187
  end
265
188
 
266
- # @note StaticGroup does not have extensions
267
- # @raise [NoMethodError]
268
- def extension
269
- raise NoMethodError.new "StaticGroup does not implement #{__method__}"
270
- end
271
-
272
189
  # @private
273
190
  def to_compact(out)
274
- if self.class.opt?
275
- out.putPresent
276
- end
277
- @value.each do |fn, fv|
278
- fv.to_compact(out)
191
+
192
+ groupOut = String.new.putU64(self.class.id)
193
+ super(groupOut)
194
+ if @extension.size > 0
195
+ groupOut.putU32(@extension.size)
196
+ @extension.each do |e|
197
+ e.to_compact(groupOut)
198
+ end
279
199
  end
280
- out
281
- end
282
200
 
283
- # @note StaticGroup cannot be encoded as a top level message
284
- # @raise [NoMethodError]
285
- def encode_compact
286
- raise NoMethodError.new "StaticGroup does not inmplement #{__method__}"
201
+ out.putU32(groupOut.size)
202
+ out << groupOut
203
+
287
204
  end
288
-
205
+
289
206
  end
290
207
 
291
- # @abstract
292
- #
293
- # A DynamicGroup has a {Group} which has a {Group.id} that appears in {DynamicGroup.permitted} list
294
208
  class DynamicGroup
295
209
 
296
- # @return [Hash] Hash of all groups referenced by name
297
- def self.groups
298
- @groups
299
- end
300
-
301
- # @return [Hash] Hash of all tagged groups referenced by ID
302
210
  def self.taggedGroups
303
211
  @taggedGroups
304
212
  end
305
213
 
306
- # @return [Array<Integer>] Array of group IDs that can be encapsulated by this DynamicGroup
307
- def self.permitted
308
- @permitted
214
+ def self.permittedID
215
+ @permittedID
309
216
  end
310
217
 
311
218
  # @private
312
- # @param input [String] Blink compact form
219
+ # @param input [StringIO] Blink compact form
313
220
  # @param stack [Array] used to measure depth of recursion
314
221
  # @return [Group, nil]
315
222
  # @raise [Error] recursion depth limit
316
- def self.from_compact!(input, stack)
223
+ def self.from_compact(input, stack)
224
+
225
+ group = nil
317
226
 
318
227
  if stack.size < @maxRecursion
319
228
  stack << self
@@ -321,36 +230,58 @@ module SlowBlink::Message
321
230
  raise RecursionLimit
322
231
  end
323
232
 
324
- buf = input.getBinary!
233
+ if input.kind_of? String
234
+ input = StringIO.new(input)
235
+ end
236
+
237
+ buf = input.getBinary
238
+
325
239
  if buf.size > 0
326
- id = buf.getU64!
327
- group = @taggedGroups[id]
328
- if group
329
- if @permitted.include? group.id
330
- result = self.new(group.from_compact!(buf, stack))
240
+
241
+ buf = StringIO.new(buf)
242
+ id = buf.getU64
243
+
244
+ if klass = @taggedGroups[id]
245
+
246
+ if @permittedID.include? id
247
+
248
+ group = klass.from_compact(buf, stack)
249
+
250
+ if !buf.eof?
251
+ size = buf.getU32
252
+ while group.extension.size < size do
253
+ group.extension << @anyTaggedGroup.from_compact(buf, stack)
254
+ end
255
+ end
256
+
257
+ if !buf.eof?
258
+ raise ExtensionPadding
259
+ end
260
+
331
261
  else
332
262
  raise WeakError15.new "W15: Group is known but unexpected"
333
263
  end
334
264
  else
335
- raise WeakError2.new "W2: Group id #{group.id} is unknown"
265
+ raise WeakError2.new "W2: Group id #{id} is unknown"
336
266
  end
337
- else
267
+
268
+ elsif stack.size == 1
269
+ raise WeakError5.new "W??: top level cannot be null"
270
+ else
338
271
  raise WeakError5.new "W5: Value cannot be null"
339
272
  end
340
273
 
341
274
  stack.pop
342
- result
275
+ group
343
276
 
344
277
  end
345
278
 
346
- def set(value)
347
- # is group one of the groups we understand?
348
- if self.class.taggedGroups.values.detect{|g| value.is_a? g}
349
- # is this group permitted?
350
- if self.class.permitted.include? value.class.id
279
+ def set(value)
280
+ if value.kind_of? Group
281
+ if self.class.permittedID.include? value.class.id
351
282
  @value = value
352
283
  else
353
- raise TypeError.new "group is known but compatible with schema"
284
+ raise TypeError.new "incompatible group"
354
285
  end
355
286
  # native values
356
287
  elsif value.kind_of? Hash
@@ -365,20 +296,18 @@ module SlowBlink::Message
365
296
  @value.get
366
297
  end
367
298
 
368
- # Calls {Group#extension}
369
- # @return [Array]
370
- def extension
371
- @value.extension
372
- end
373
-
374
299
  # @note calls {#set}(value)
375
300
  def initialize(value)
376
- set(value)
301
+ set(value)
377
302
  end
378
303
 
379
304
  # @private
380
305
  def to_compact(out)
381
- @value.to_compact(out)
306
+ @value.to_compact(out)
307
+ end
308
+
309
+ def extension
310
+ @value.extension
382
311
  end
383
312
 
384
313
  end
@@ -62,12 +62,11 @@ module SlowBlink::Message
62
62
  class U8 < INTEGER
63
63
 
64
64
  # @private
65
- def self.from_compact!(input, stack)
66
- value = input.getU8!
67
- if value
65
+ def self.from_compact(input, stack)
66
+ if value = input.getU8
68
67
  self.new(value)
69
68
  else
70
- value
69
+ nil
71
70
  end
72
71
  end
73
72
 
@@ -82,12 +81,11 @@ module SlowBlink::Message
82
81
  class U16 < INTEGER
83
82
 
84
83
  # @private
85
- def self.from_compact!(input, stack)
86
- value = input.getU16!
87
- if value
84
+ def self.from_compact(input, stack)
85
+ if value = input.getU16
88
86
  self.new(value)
89
87
  else
90
- value
88
+ nil
91
89
  end
92
90
  end
93
91
 
@@ -102,12 +100,11 @@ module SlowBlink::Message
102
100
  class U32 < INTEGER
103
101
 
104
102
  # @private
105
- def self.from_compact!(input, stack)
106
- value = input.getU32!
107
- if value
103
+ def self.from_compact(input, stack)
104
+ if value = input.getU32
108
105
  self.new(value)
109
106
  else
110
- value
107
+ nil
111
108
  end
112
109
  end
113
110
 
@@ -122,12 +119,11 @@ module SlowBlink::Message
122
119
  class U64 < INTEGER
123
120
 
124
121
  # @private
125
- def self.from_compact!(input, stack)
126
- value = input.getU64!
127
- if value
122
+ def self.from_compact(input, stack)
123
+ if value = input.getU64
128
124
  self.new(value)
129
125
  else
130
- value
126
+ nil
131
127
  end
132
128
  end
133
129
 
@@ -142,12 +138,11 @@ module SlowBlink::Message
142
138
  class I8 < INTEGER
143
139
 
144
140
  # @private
145
- def self.from_compact!(input, stack)
146
- value = input.getI8!
147
- if value
141
+ def self.from_compact(input, stack)
142
+ if value = input.getI8
148
143
  self.new(value)
149
144
  else
150
- value
145
+ nil
151
146
  end
152
147
  end
153
148
 
@@ -162,12 +157,11 @@ module SlowBlink::Message
162
157
  class I16 < INTEGER
163
158
 
164
159
  # @private
165
- def self.from_compact!(input, stack)
166
- value = input.getI16!
167
- if value
160
+ def self.from_compact(input, stack)
161
+ if value = input.getI16
168
162
  self.new(value)
169
163
  else
170
- value
164
+ nil
171
165
  end
172
166
  end
173
167
 
@@ -182,12 +176,11 @@ module SlowBlink::Message
182
176
  class I32 < INTEGER
183
177
 
184
178
  # @private
185
- def self.from_compact!(input, stack)
186
- value = input.getI32!
187
- if value
179
+ def self.from_compact(input, stack)
180
+ if value = input.getI32
188
181
  self.new(value)
189
182
  else
190
- value
183
+ nil
191
184
  end
192
185
  end
193
186
 
@@ -202,12 +195,11 @@ module SlowBlink::Message
202
195
  class I64 < INTEGER
203
196
 
204
197
  # @private
205
- def self.from_compact!(input, stack)
206
- value = input.getI64!
207
- if value
198
+ def self.from_compact(input, stack)
199
+ if value = input.getI64
208
200
  self.new(value)
209
201
  else
210
- value
202
+ nil
211
203
  end
212
204
  end
213
205