slow_blink 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/ext/slow_blink/ext_compact_encoder/compact_encoder.c +258 -0
  3. data/ext/slow_blink/ext_compact_encoder/compact_encoder.h +92 -0
  4. data/ext/slow_blink/ext_compact_encoder/ext_compact_encoder.c +555 -0
  5. data/ext/slow_blink/ext_compact_encoder/extconf.rb +4 -0
  6. data/ext/slow_blink/ext_schema_parser/lexer.c +59 -59
  7. data/ext/slow_blink/ext_schema_parser/lexer.h +2 -2
  8. data/ext/slow_blink/ext_schema_parser/parser.c +380 -367
  9. data/ext/slow_blink/ext_schema_parser/parser.h +1 -1
  10. data/lib/slow_blink/annotatable.rb +1 -1
  11. data/lib/slow_blink/annotation.rb +5 -5
  12. data/lib/slow_blink/binary.rb +26 -0
  13. data/lib/slow_blink/boolean.rb +26 -0
  14. data/lib/slow_blink/compact_encoder.rb +45 -71
  15. data/lib/slow_blink/date.rb +25 -0
  16. data/lib/slow_blink/decimal.rb +26 -0
  17. data/lib/slow_blink/definition.rb +19 -10
  18. data/lib/slow_blink/enumeration.rb +14 -36
  19. data/lib/slow_blink/error.rb +19 -0
  20. data/lib/slow_blink/field.rb +3 -16
  21. data/lib/slow_blink/fixed.rb +26 -0
  22. data/lib/slow_blink/floating_point.rb +27 -0
  23. data/lib/slow_blink/group.rb +30 -43
  24. data/lib/slow_blink/incremental_annotation.rb +75 -21
  25. data/lib/slow_blink/integer.rb +65 -0
  26. data/lib/slow_blink/message/binary.rb +87 -0
  27. data/lib/slow_blink/message/boolean.rb +68 -0
  28. data/lib/slow_blink/message/date.rb +33 -0
  29. data/lib/slow_blink/message/decimal.rb +25 -0
  30. data/lib/slow_blink/message/enumeration.rb +69 -0
  31. data/lib/slow_blink/message/field.rb +73 -0
  32. data/lib/slow_blink/message/fixed.rb +84 -0
  33. data/lib/slow_blink/message/floating_point.rb +68 -0
  34. data/lib/slow_blink/message/group.rb +260 -0
  35. data/lib/slow_blink/message/integer.rb +217 -0
  36. data/lib/slow_blink/message/model.rb +202 -0
  37. data/lib/slow_blink/message/sequence.rb +85 -0
  38. data/lib/slow_blink/message/string.rb +95 -0
  39. data/lib/slow_blink/message/time.rb +78 -0
  40. data/lib/slow_blink/message/time_of_day.rb +132 -0
  41. data/lib/slow_blink/name_with_id.rb +2 -1
  42. data/lib/slow_blink/namespace.rb +140 -0
  43. data/lib/slow_blink/object.rb +29 -0
  44. data/lib/slow_blink/ref.rb +93 -0
  45. data/lib/slow_blink/schema.rb +94 -68
  46. data/lib/slow_blink/{component_reference.rb → schema_buffer.rb} +11 -22
  47. data/lib/slow_blink/sequence.rb +58 -0
  48. data/lib/slow_blink/string.rb +40 -0
  49. data/lib/slow_blink/sym.rb +4 -0
  50. data/lib/slow_blink/time.rb +30 -0
  51. data/lib/slow_blink/time_of_day.rb +30 -0
  52. data/lib/slow_blink/type.rb +7 -402
  53. data/lib/slow_blink/version.rb +1 -1
  54. data/lib/slow_blink.rb +1 -0
  55. data/rakefile +14 -3
  56. data/test/{integration/capture_stderr.rb → capture_stderr.rb} +0 -0
  57. data/test/tc_compact_encoder.rb +341 -0
  58. data/test/tc_field.rb +53 -0
  59. data/test/tc_group.rb +122 -0
  60. data/test/tc_incr_annote.rb +27 -0
  61. data/test/{integration/tc_inputs.rb → tc_inputs.rb} +7 -11
  62. data/test/tc_model.rb +65 -0
  63. data/test/tc_model_encode.rb +63 -0
  64. data/test/tc_namespace.rb +8 -0
  65. data/test/tc_types.rb +198 -0
  66. metadata +58 -11
  67. data/ext/slow_blink/ext_schema_parser/parser.l +0 -139
  68. data/ext/slow_blink/ext_schema_parser/parser.y +0 -932
  69. data/lib/slow_blink/message.rb +0 -43
@@ -0,0 +1,202 @@
1
+ # Copyright (c) 2016 Cameron Harper
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ # this software and associated documentation files (the "Software"), to deal in
5
+ # the Software without restriction, including without limitation the rights to
6
+ # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7
+ # the Software, and to permit persons to whom the Software is furnished to do so,
8
+ # subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in all
11
+ # copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15
+ # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
+ # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18
+ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19
+
20
+ module SlowBlink
21
+
22
+ module Message
23
+
24
+ class Error < Exception
25
+ end
26
+
27
+ class Model
28
+
29
+ # @param nameOrID [String,Integer] name or id of top-level group
30
+ # @return [Class] anonymous class extending {DynamicGroup::CLASS} and including {DynamicGroup::INSTANCE}
31
+ def [](nameOrID)
32
+ if nameOrID.kind_of? Integer
33
+ @top.new(@top.groups.values.detect{|g|g.name == nameOrID})
34
+ else
35
+ @top.new(@top.groups[nameOrID])
36
+ end
37
+ end
38
+
39
+ attr_reader :top
40
+
41
+ # Initialise a message model from a schema
42
+ #
43
+ # @param schema [Schema]
44
+ # @param opts [Hash]
45
+ def initialize(schema, **opts)
46
+ @schema = schema
47
+ @groups = {}
48
+ schema.tagged.each do |id, g|
49
+ @groups[id] = _model_group(false, g)
50
+ end
51
+ groups = @groups
52
+ @top = Class.new do
53
+ @opt = false
54
+ @groups = groups
55
+ @permitted = groups.keys
56
+ extend DynamicGroup::CLASS
57
+ include DynamicGroup::INSTANCE
58
+ end
59
+ end
60
+
61
+ def decode_compact(input)
62
+ @top.from_compact!(input.dup)
63
+ end
64
+
65
+ def encode_compact(input)
66
+ @top.from_compact!(input)
67
+ end
68
+
69
+ def group(name, &block)
70
+ group = @top.groups.values.detect{|g|g.name == name}
71
+ if group
72
+ top = @top.new(group.new(nil))
73
+ top.instance_exec(top, &block)
74
+ top
75
+ else
76
+ raise
77
+ end
78
+ end
79
+
80
+ def new(&block)
81
+ if block.nil?
82
+ raise
83
+ end
84
+ result = self.instance_exec(&block)
85
+ end
86
+
87
+ # @private
88
+ #
89
+ # Create a model for a Group
90
+ #
91
+ # @param opt [true,false] this group is allowed to be optional
92
+ # @param group [SlowBlink::Group] group definition
93
+ # @return [Class] anonymous class extending {StaticGroup::CLASS} and including {StaticGroup::INSTANCE}
94
+ def _model_group(opt, group)
95
+ this = self
96
+ klass = Class.new do
97
+ @name = group.nameWithID.name
98
+ @id = group.nameWithID.id
99
+ @opt = opt
100
+ @fields = group.fields.inject([]) do |fields, f|
101
+ fields << this._model_field(f)
102
+ end
103
+ extend StaticGroup::CLASS
104
+ include StaticGroup::INSTANCE
105
+ end
106
+ end
107
+
108
+
109
+ # @private
110
+ #
111
+ # Create a model for a Field
112
+ #
113
+ # @param field [SlowBlink::Field] field definition
114
+ # @return [Class] anonymous class extending {Field::CLASS} and including {Field::INSTANCE}
115
+ def _model_field(field)
116
+ this = self
117
+ klass = Class.new do
118
+ @opt = field.opt?
119
+ @name = field.nameWithID.name
120
+ @id = field.nameWithID.id
121
+ @type = this._model_type(field)
122
+ include Field::INSTANCE
123
+ extend Field::CLASS
124
+ end
125
+ end
126
+
127
+ # @private
128
+ #
129
+ # Create a model for a type
130
+ #
131
+ # @param field [SlowBlink::Field] field definition (containing type)
132
+ # @return [Class] anonymous class extending {Field::CLASS} and including {Field::INSTANCE}
133
+ def _model_type(field)
134
+ type = field.type
135
+ name = field.nameWithID.name
136
+ case type.class
137
+ when SlowBlink::OBJECT
138
+ groups = @groups
139
+ permitted = @schema.tagged.keys
140
+ klass = Class.new do
141
+ @opt = field.opt?
142
+
143
+ @groups = groups
144
+ @permitted = permitted
145
+ extend DynamicGroup::CLASS
146
+ include DynamicGroup::INSTANCE
147
+ end
148
+ when SlowBlink::REF
149
+ if type.ref.kind_of? Group
150
+ if type.dynamic?
151
+ groups = @groups
152
+ permitted = @schema.tagged.keys
153
+ @schema.tagged.each do |id, g|
154
+ if g.group_kind_of?(type)
155
+ permitted << id
156
+ end
157
+ end
158
+ klass = Class.new do
159
+ @name = name
160
+ @opt = field.opt?
161
+ @groups = groups
162
+ @permitted = permitted
163
+ extend DynamicGroup::CLASS
164
+ include DynamicGroup::INSTANCE
165
+ end
166
+ else
167
+ _model_group(field.opt?, type.ref)
168
+ end
169
+ else
170
+ _model_type(opt, type.ref)
171
+ end
172
+ else
173
+ return Class.new do
174
+ @opt = field.opt?
175
+ @name = name
176
+ @type = type
177
+ extend SlowBlink::Message.const_get(type.class.name.split('::').last + "::CLASS")
178
+ include SlowBlink::Message.const_get(type.class.name.split('::').last + "::INSTANCE")
179
+ end
180
+ end
181
+ end
182
+
183
+ end
184
+
185
+ end
186
+
187
+ end
188
+
189
+ require "slow_blink/message/field"
190
+ require "slow_blink/message/integer"
191
+ require "slow_blink/message/string"
192
+ require "slow_blink/message/binary"
193
+ require "slow_blink/message/fixed"
194
+ require "slow_blink/message/boolean"
195
+ require "slow_blink/message/enumeration"
196
+ require "slow_blink/message/floating_point"
197
+ require "slow_blink/message/sequence"
198
+ require "slow_blink/message/group"
199
+ require "slow_blink/message/time"
200
+ require "slow_blink/message/time_of_day"
201
+ require "slow_blink/message/date"
202
+
@@ -0,0 +1,85 @@
1
+ # Copyright (c) 2016 Cameron Harper
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ # this software and associated documentation files (the "Software"), to deal in
5
+ # the Software without restriction, including without limitation the rights to
6
+ # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7
+ # the Software, and to permit persons to whom the Software is furnished to do so,
8
+ # subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in all
11
+ # copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15
+ # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
+ # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18
+ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19
+
20
+ module SlowBlink::Message
21
+
22
+ module SEQUENCE
23
+
24
+ module CLASS
25
+
26
+ def from_compact!(input)
27
+ value = []
28
+ size = input.getU32!
29
+ if size
30
+ while out.size < size do
31
+ value << @type.from_compact!(input)
32
+ end
33
+ self.new(value)
34
+ else
35
+ self.new
36
+ end
37
+ end
38
+
39
+ end
40
+
41
+ module INSTANCE
42
+
43
+ # @param v [Array,nil]
44
+ def set(value)
45
+ if value
46
+ if value.kind_of? Array
47
+ @value = v
48
+ else
49
+ raise Error.new "bad type"
50
+ end
51
+ elsif self.class.opt?
52
+ @value = nil
53
+ else
54
+ raise Error.new "value unacceptable"
55
+ end
56
+ end
57
+
58
+ def get
59
+ @value
60
+ end
61
+
62
+ # @param value [Array]
63
+ def initialize(value)
64
+ if value
65
+ set(value)
66
+ else
67
+ @value = nil
68
+ end
69
+ end
70
+
71
+ def to_compact(out)
72
+ if @value
73
+ @value.inject(out.putU32(@value.size)) do |out, v|
74
+ out << v.to_compact
75
+ end
76
+ else
77
+ out.putU32(nil)
78
+ end
79
+ end
80
+
81
+ end
82
+
83
+ end
84
+
85
+ end
@@ -0,0 +1,95 @@
1
+ # Copyright (c) 2016 Cameron Harper
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ # this software and associated documentation files (the "Software"), to deal in
5
+ # the Software without restriction, including without limitation the rights to
6
+ # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7
+ # the Software, and to permit persons to whom the Software is furnished to do so,
8
+ # subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in all
11
+ # copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15
+ # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
+ # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18
+ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19
+
20
+ module SlowBlink::Message
21
+
22
+ module STRING
23
+
24
+ module CLASS
25
+
26
+ def name
27
+ @name
28
+ end
29
+
30
+ def opt?
31
+ @opt
32
+ end
33
+
34
+ def from_compact!(input)
35
+ value = input.getString!
36
+ if value
37
+ if !@type.size or value.size <= @type.size
38
+ self.new(value)
39
+ else
40
+ raise Error.new "W7: String value exceeds maximum size"
41
+ end
42
+ elsif @opt
43
+ self.new(nil)
44
+ else
45
+ raise Error.new "W5: Value cannot be null"
46
+ end
47
+ end
48
+
49
+ def size
50
+ @type.size
51
+ end
52
+
53
+ end
54
+
55
+ module INSTANCE
56
+
57
+ def get
58
+ @value
59
+ end
60
+
61
+ def set(value)
62
+ if value
63
+ if value.kind_of? String
64
+ if !self.class.size or value.size <= self.class.size
65
+ @value = value
66
+ else
67
+ raise Error.new "string cannot be larger than #{self.class.size} bytes"
68
+ end
69
+ else
70
+ raise Error.new "expecting a string type"
71
+ end
72
+ elsif self.class.opt?
73
+ @value = nil
74
+ else
75
+ raise Error.new "string cannot be null"
76
+ end
77
+ end
78
+
79
+ def initialize(value)
80
+ if value
81
+ set(value)
82
+ else
83
+ @value = nil
84
+ end
85
+ end
86
+
87
+ def to_compact(out)
88
+ out.putString(@value)
89
+ end
90
+
91
+ end
92
+
93
+ end
94
+
95
+ end
@@ -0,0 +1,78 @@
1
+ # Copyright (c) 2016 Cameron Harper
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ # this software and associated documentation files (the "Software"), to deal in
5
+ # the Software without restriction, including without limitation the rights to
6
+ # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7
+ # the Software, and to permit persons to whom the Software is furnished to do so,
8
+ # subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in all
11
+ # copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15
+ # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
+ # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18
+ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19
+
20
+ module SlowBlink::Message
21
+
22
+ module MILLI_TIME
23
+
24
+ module CLASS
25
+
26
+ def from_compact!(input)
27
+ self.new(input.getI64!)
28
+ end
29
+
30
+ end
31
+
32
+ module INSTANCE
33
+
34
+ def set(value)
35
+ if value
36
+ raise
37
+ elsif self.class.opt?
38
+ @value = nil
39
+ else
40
+ raise
41
+ end
42
+ end
43
+
44
+ def get
45
+ @value
46
+ end
47
+
48
+ def initialize(value)
49
+ if value
50
+ set(value)
51
+ else
52
+ @value = nil
53
+ end
54
+ end
55
+
56
+ def to_compact(out)
57
+ out.putI64(@value)
58
+ end
59
+
60
+ end
61
+
62
+ end
63
+
64
+ module NANO_TIME
65
+
66
+ module CLASS
67
+
68
+ include SlowBlink::Message::MILLI_TIME::CLASS
69
+ end
70
+
71
+ module INSTANCE
72
+
73
+ include SlowBlink::Message::MILLI_TIME::INSTANCE
74
+ end
75
+
76
+ end
77
+
78
+ end
@@ -0,0 +1,132 @@
1
+ # Copyright (c) 2016 Cameron Harper
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ # this software and associated documentation files (the "Software"), to deal in
5
+ # the Software without restriction, including without limitation the rights to
6
+ # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7
+ # the Software, and to permit persons to whom the Software is furnished to do so,
8
+ # subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in all
11
+ # copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15
+ # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
+ # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18
+ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19
+
20
+ module SlowBlink::Message
21
+
22
+ module TIME_OF_DAY_MILLI
23
+
24
+ module CLASS
25
+
26
+ def from_compact!(input)
27
+ self.new(input.get32!)
28
+ end
29
+
30
+ end
31
+
32
+ module INSTANCE
33
+
34
+ def set(value)
35
+ if value
36
+ if value.kind_of? Integer
37
+ if value < 86400000
38
+ @value = value
39
+ else
40
+ raise Error.new "input out of range"
41
+ end
42
+ elsif value.kind_of? Time
43
+ @value = value.to_i
44
+ else
45
+ raise "what is this?"
46
+ end
47
+ elsif self.class.opt?
48
+ @value = nil
49
+ else
50
+ raise
51
+ end
52
+ end
53
+
54
+ def get
55
+ @value
56
+ end
57
+
58
+ def initialize(value)
59
+ if value
60
+ set(value)
61
+ else
62
+ @value = nil
63
+ end
64
+ end
65
+
66
+ # @private
67
+ def to_compact(out)
68
+ out.putU32(@value)
69
+
70
+
71
+
72
+ end
73
+
74
+ end
75
+
76
+ end
77
+
78
+ module TIME_OF_DAY_NANO
79
+
80
+ module CLASS
81
+
82
+ def from_compact!(input)
83
+ self.new(input.getU64!)
84
+ end
85
+
86
+ end
87
+
88
+ module INSTANCE
89
+
90
+
91
+ def set(value)
92
+ if value
93
+ if value.kind_of? Integer
94
+ if value < 86400000000000
95
+ @value = value
96
+ else
97
+ raise Error.new "input out of range"
98
+ end
99
+ elsif value.kind_of? Time
100
+ @value = value.to_i
101
+ else
102
+ raise "what is this?"
103
+ end
104
+ elsif self.class.opt?
105
+ @value = nil
106
+ else
107
+ raise
108
+ end
109
+ end
110
+
111
+ def get
112
+ @value
113
+ end
114
+
115
+ def initialize(value)
116
+ if value
117
+ set(value)
118
+ else
119
+ @value = nil
120
+ end
121
+ end
122
+
123
+ # @private
124
+ def to_compact(out)
125
+ out.putU64(@value)
126
+ end
127
+
128
+ end
129
+
130
+ end
131
+
132
+ end
@@ -34,8 +34,9 @@ module SlowBlink
34
34
  # @param name [String]
35
35
  # @param id [nil,Integer]
36
36
  def initialize(name, id)
37
+ @annotes = {}
37
38
  @name = name
38
- @id = id
39
+ @id = id
39
40
  end
40
41
 
41
42
  # @private