slow_blink 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/slow_blink/ext_schema_parser/parser.c +245 -245
- data/lib/slow_blink/annotatable.rb +1 -2
- data/lib/slow_blink/annotation.rb +8 -1
- data/lib/slow_blink/compact_encoder.rb +1 -0
- data/lib/slow_blink/definition.rb +34 -10
- data/lib/slow_blink/enumeration.rb +15 -12
- data/lib/slow_blink/field.rb +9 -8
- data/lib/slow_blink/group.rb +61 -24
- data/lib/slow_blink/incremental_annotation.rb +7 -4
- data/lib/slow_blink/integer.rb +1 -1
- data/{test/tc_model.rb → lib/slow_blink/log.rb} +23 -40
- data/lib/slow_blink/message/binary.rb +39 -45
- data/lib/slow_blink/message/boolean.rb +25 -33
- data/lib/slow_blink/message/date.rb +2 -7
- data/lib/slow_blink/message/decimal.rb +1 -1
- data/lib/slow_blink/message/enumeration.rb +29 -33
- data/lib/slow_blink/message/field.rb +29 -37
- data/lib/slow_blink/message/fixed.rb +37 -45
- data/lib/slow_blink/message/floating_point.rb +24 -32
- data/lib/slow_blink/message/group.rb +172 -187
- data/lib/slow_blink/message/integer.rb +83 -132
- data/lib/slow_blink/message/model.rb +64 -63
- data/lib/slow_blink/message/sequence.rb +40 -48
- data/lib/slow_blink/message/string.rb +44 -51
- data/lib/slow_blink/message/time.rb +25 -40
- data/lib/slow_blink/message/time_of_day.rb +73 -86
- data/lib/slow_blink/name_with_id.rb +2 -6
- data/lib/slow_blink/namespace.rb +36 -36
- data/lib/slow_blink/ref.rb +29 -13
- data/lib/slow_blink/schema.rb +26 -10
- data/lib/slow_blink/schema_buffer.rb +14 -0
- data/lib/slow_blink/sequence.rb +16 -20
- data/lib/slow_blink/string.rb +0 -2
- data/lib/slow_blink/sym.rb +7 -5
- data/lib/slow_blink/type.rb +8 -5
- data/lib/slow_blink/version.rb +1 -1
- data/test/tc_field.rb +41 -0
- data/test/tc_group.rb +11 -0
- data/test/tc_model_static_group.rb +114 -0
- data/test/{tc_model_encode.rb → tc_model_think_blink.rb} +58 -13
- data/test/tc_types.rb +39 -0
- metadata +7 -6
@@ -19,199 +19,150 @@
|
|
19
19
|
|
20
20
|
module SlowBlink::Message
|
21
21
|
|
22
|
-
|
22
|
+
class INTEGER
|
23
23
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
@name
|
28
|
-
end
|
29
|
-
|
30
|
-
def opt?
|
31
|
-
@opt
|
32
|
-
end
|
33
|
-
|
34
|
-
def in_range?(value)
|
35
|
-
@type.class::RANGE.cover? value
|
36
|
-
end
|
24
|
+
def self.name
|
25
|
+
@name
|
26
|
+
end
|
37
27
|
|
28
|
+
def self.opt?
|
29
|
+
@opt
|
38
30
|
end
|
39
31
|
|
40
|
-
|
32
|
+
def self.in_range?(value)
|
33
|
+
@type.class::RANGE.cover? value
|
34
|
+
end
|
41
35
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
else
|
48
|
-
raise Error.new "value out of range"
|
49
|
-
end
|
36
|
+
def set(value)
|
37
|
+
if value
|
38
|
+
if value.kind_of? Integer
|
39
|
+
if self.class.in_range?(value)
|
40
|
+
@value = value.to_i
|
50
41
|
else
|
51
|
-
raise Error.new "value
|
42
|
+
raise Error.new "value out of range"
|
52
43
|
end
|
53
|
-
elsif self.class.opt?
|
54
|
-
@value = nil
|
55
44
|
else
|
56
|
-
raise Error.new "value
|
45
|
+
raise Error.new "value must be an integer"
|
57
46
|
end
|
47
|
+
elsif self.class.opt?
|
48
|
+
@value = nil
|
49
|
+
else
|
50
|
+
raise Error.new "value unacceptable"
|
58
51
|
end
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
52
|
+
end
|
53
|
+
|
54
|
+
def get
|
55
|
+
@value
|
56
|
+
end
|
63
57
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
end
|
58
|
+
# @param value [Integer, nil]
|
59
|
+
def initialize(value)
|
60
|
+
if value
|
61
|
+
set(value)
|
62
|
+
else
|
63
|
+
@value = nil
|
71
64
|
end
|
72
65
|
end
|
66
|
+
|
73
67
|
|
74
68
|
end
|
75
69
|
|
76
|
-
|
70
|
+
class U8 < INTEGER
|
77
71
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
self.new(input.getU8!)
|
82
|
-
end
|
72
|
+
|
73
|
+
def self.from_compact!(input)
|
74
|
+
self.new(input.getU8!)
|
83
75
|
end
|
84
76
|
|
85
|
-
|
86
|
-
|
87
|
-
def to_compact(out)
|
88
|
-
out.putU8(@value)
|
89
|
-
end
|
77
|
+
def to_compact(out)
|
78
|
+
out.putU8(@value)
|
90
79
|
end
|
91
80
|
|
81
|
+
|
92
82
|
end
|
93
83
|
|
94
|
-
|
84
|
+
class U16 < INTEGER
|
95
85
|
|
96
|
-
|
97
|
-
|
98
|
-
def from_compact!(input)
|
99
|
-
self.new(input.getU16!)
|
100
|
-
end
|
86
|
+
def self.from_compact!(input)
|
87
|
+
self.new(input.getU16!)
|
101
88
|
end
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
def to_compact(out)
|
106
|
-
out.putU16(@value)
|
107
|
-
end
|
89
|
+
|
90
|
+
def to_compact(out)
|
91
|
+
out.putU16(@value)
|
108
92
|
end
|
93
|
+
|
109
94
|
end
|
110
95
|
|
111
|
-
|
96
|
+
class U32 < INTEGER
|
112
97
|
|
113
|
-
|
114
|
-
|
115
|
-
def from_compact!(input)
|
116
|
-
self.new(input.getU32!)
|
117
|
-
end
|
98
|
+
def self.from_compact!(input)
|
99
|
+
self.new(input.getU32!)
|
118
100
|
end
|
119
101
|
|
120
|
-
|
121
|
-
|
122
|
-
def to_compact(out)
|
123
|
-
out.putU32(@value)
|
124
|
-
end
|
102
|
+
def to_compact(out)
|
103
|
+
out.putU32(@value)
|
125
104
|
end
|
126
105
|
|
127
106
|
end
|
128
107
|
|
129
|
-
|
108
|
+
class U64 < INTEGER
|
130
109
|
|
131
|
-
|
132
|
-
|
133
|
-
def from_compact!(input)
|
134
|
-
self.new(input.getU64!)
|
135
|
-
end
|
110
|
+
def self.from_compact!(input)
|
111
|
+
self.new(input.getU64!)
|
136
112
|
end
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
def to_compact(out)
|
141
|
-
out.putU64(@value)
|
142
|
-
end
|
113
|
+
|
114
|
+
def to_compact(out)
|
115
|
+
out.putU64(@value)
|
143
116
|
end
|
144
117
|
|
145
118
|
end
|
146
119
|
|
147
|
-
|
120
|
+
class I8 < INTEGER
|
148
121
|
|
149
|
-
|
150
|
-
|
151
|
-
def from_compact!(input)
|
152
|
-
self.new(input.getI8!)
|
153
|
-
end
|
122
|
+
def self.from_compact!(input)
|
123
|
+
self.new(input.getI8!)
|
154
124
|
end
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
def to_compact(out)
|
159
|
-
out.putI8(@value)
|
160
|
-
end
|
125
|
+
|
126
|
+
def to_compact(out)
|
127
|
+
out.putI8(@value)
|
161
128
|
end
|
162
129
|
|
163
130
|
end
|
164
131
|
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
self.new(input.getI16!)
|
170
|
-
end
|
132
|
+
class I16 < INTEGER
|
133
|
+
|
134
|
+
def self.from_compact!(input)
|
135
|
+
self.new(input.getI16!)
|
171
136
|
end
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
def to_compact(out)
|
176
|
-
out.putI16(@value)
|
177
|
-
end
|
137
|
+
|
138
|
+
def to_compact(out)
|
139
|
+
out.putI16(@value)
|
178
140
|
end
|
179
141
|
|
180
142
|
end
|
181
143
|
|
182
|
-
|
144
|
+
class I32 < INTEGER
|
183
145
|
|
184
|
-
|
185
|
-
|
186
|
-
def from_compact!(input)
|
187
|
-
self.new(input.getI32!)
|
188
|
-
end
|
146
|
+
def self.from_compact!(input)
|
147
|
+
self.new(input.getI32!)
|
189
148
|
end
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
def to_compact(out)
|
194
|
-
out.putI32(@value)
|
195
|
-
end
|
149
|
+
|
150
|
+
def to_compact(out)
|
151
|
+
out.putI32(@value)
|
196
152
|
end
|
197
153
|
|
198
154
|
end
|
199
155
|
|
200
|
-
|
156
|
+
class I64 < INTEGER
|
201
157
|
|
202
|
-
|
203
|
-
|
204
|
-
def from_compact!(input)
|
205
|
-
self.new(input.getI64!)
|
206
|
-
end
|
158
|
+
def self.from_compact!(input)
|
159
|
+
self.new(input.getI64!)
|
207
160
|
end
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
def to_compact(out)
|
212
|
-
out.putI64(@value)
|
213
|
-
end
|
161
|
+
|
162
|
+
def to_compact(out)
|
163
|
+
out.putI64(@value)
|
214
164
|
end
|
165
|
+
|
215
166
|
end
|
216
167
|
|
217
168
|
end
|
@@ -26,110 +26,115 @@ module SlowBlink
|
|
26
26
|
|
27
27
|
class Model
|
28
28
|
|
29
|
-
# @
|
30
|
-
#
|
31
|
-
|
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
|
29
|
+
# @api user
|
30
|
+
#
|
31
|
+
# Create a Model from a {Schema}
|
42
32
|
#
|
43
|
-
# @param schema [Schema]
|
44
|
-
|
45
|
-
def initialize(schema, **opts)
|
33
|
+
# @param schema [SlowBlink::Schema]
|
34
|
+
def initialize(schema)
|
46
35
|
@schema = schema
|
47
|
-
@
|
36
|
+
@taggedGroups = {}
|
48
37
|
schema.tagged.each do |id, g|
|
49
|
-
@
|
38
|
+
@taggedGroups[id] = _model_group(false, g)
|
50
39
|
end
|
51
|
-
|
52
|
-
@top = Class.new do
|
40
|
+
taggedGroups = @taggedGroups
|
41
|
+
@top = Class.new(DynamicGroup) do
|
53
42
|
@opt = false
|
54
|
-
@groups =
|
55
|
-
@permitted =
|
56
|
-
extend DynamicGroup::CLASS
|
57
|
-
include DynamicGroup::INSTANCE
|
43
|
+
@groups = taggedGroups
|
44
|
+
@permitted = taggedGroups.keys
|
58
45
|
end
|
59
46
|
end
|
60
47
|
|
48
|
+
# @api user
|
49
|
+
#
|
50
|
+
# Initialise a message model instance with a compact form string
|
51
|
+
#
|
52
|
+
# @note return value will be an *anonymous* *subclass* *instance* of {DynamicGroup}
|
53
|
+
#
|
54
|
+
# @param [String] Blink Protocol compact form
|
55
|
+
# @return [DynamicGroup] group instance
|
56
|
+
#
|
61
57
|
def decode_compact(input)
|
62
58
|
@top.from_compact!(input.dup)
|
63
59
|
end
|
64
60
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
61
|
+
# @api user
|
62
|
+
#
|
63
|
+
# Create an instance of a group subclass
|
64
|
+
#
|
65
|
+
# @note return value will be an *anonymous* *subclass* *instance* of {DynamicGroup} or {StaticGroup}
|
66
|
+
#
|
67
|
+
# @overload group(name, data)
|
68
|
+
#
|
69
|
+
# @param name [String] name of group
|
70
|
+
# @param data [Hash] bulk initialisation data
|
71
|
+
# @return [StaticGroup,DynamicGroup] group instance
|
72
|
+
#
|
73
|
+
# @overload group(name)
|
74
|
+
#
|
75
|
+
# @param name [String] name of group
|
76
|
+
# @yield [Group] group instance to initalise
|
77
|
+
# @return [StaticGroup,DynamicGroup] group instance
|
78
|
+
#
|
79
|
+
def group(name, data=nil, &block)
|
70
80
|
group = @top.groups.values.detect{|g|g.name == name}
|
71
81
|
if group
|
72
|
-
top = @top.new(group.new(
|
73
|
-
|
82
|
+
top = @top.new(group.new(data))
|
83
|
+
if block
|
84
|
+
self.instance_exec(top, &block)
|
85
|
+
# validate optional constraint here
|
86
|
+
end
|
74
87
|
top
|
75
88
|
else
|
76
89
|
raise
|
77
90
|
end
|
78
91
|
end
|
79
92
|
|
80
|
-
|
81
|
-
if block.nil?
|
82
|
-
raise
|
83
|
-
end
|
84
|
-
result = self.instance_exec(&block)
|
85
|
-
end
|
86
|
-
|
87
|
-
# @private
|
93
|
+
# @api private
|
88
94
|
#
|
89
95
|
# Create a model for a Group
|
90
96
|
#
|
91
97
|
# @param opt [true,false] this group is allowed to be optional
|
92
98
|
# @param group [SlowBlink::Group] group definition
|
93
|
-
# @return [Class] anonymous
|
99
|
+
# @return [Class] anonymous subclass of {StaticGroup}
|
94
100
|
def _model_group(opt, group)
|
95
101
|
this = self
|
96
|
-
|
102
|
+
Class.new(StaticGroup) do
|
103
|
+
@implements = group.class
|
97
104
|
@name = group.nameWithID.name
|
98
105
|
@id = group.nameWithID.id
|
99
106
|
@opt = opt
|
100
107
|
@fields = group.fields.inject([]) do |fields, f|
|
101
108
|
fields << this._model_field(f)
|
102
109
|
end
|
103
|
-
|
104
|
-
include StaticGroup::INSTANCE
|
110
|
+
|
105
111
|
end
|
106
112
|
end
|
107
113
|
|
108
114
|
|
109
|
-
# @private
|
115
|
+
# @api private
|
110
116
|
#
|
111
117
|
# Create a model for a Field
|
112
118
|
#
|
113
119
|
# @param field [SlowBlink::Field] field definition
|
114
|
-
# @return [Class] anonymous
|
120
|
+
# @return [Class] anonymous subclass of {Field}
|
115
121
|
def _model_field(field)
|
116
122
|
this = self
|
117
|
-
|
123
|
+
Class.new(Field) do
|
124
|
+
@implements = field.class
|
118
125
|
@opt = field.opt?
|
119
126
|
@name = field.nameWithID.name
|
120
127
|
@id = field.nameWithID.id
|
121
128
|
@type = this._model_type(field)
|
122
|
-
include Field::INSTANCE
|
123
|
-
extend Field::CLASS
|
124
129
|
end
|
125
130
|
end
|
126
131
|
|
127
|
-
# @private
|
132
|
+
# @api private
|
128
133
|
#
|
129
134
|
# Create a model for a type
|
130
135
|
#
|
131
136
|
# @param field [SlowBlink::Field] field definition (containing type)
|
132
|
-
# @return [Class] anonymous
|
137
|
+
# @return [Class] anonymous subclass
|
133
138
|
def _model_type(field)
|
134
139
|
type = field.type
|
135
140
|
name = field.nameWithID.name
|
@@ -137,13 +142,11 @@ module SlowBlink
|
|
137
142
|
when SlowBlink::OBJECT
|
138
143
|
groups = @groups
|
139
144
|
permitted = @schema.tagged.keys
|
140
|
-
klass = Class.new do
|
141
|
-
@
|
142
|
-
|
145
|
+
klass = Class.new(DynamicGroup) do
|
146
|
+
@implements = type.class
|
147
|
+
@opt = field.opt?
|
143
148
|
@groups = groups
|
144
|
-
@permitted = permitted
|
145
|
-
extend DynamicGroup::CLASS
|
146
|
-
include DynamicGroup::INSTANCE
|
149
|
+
@permitted = permitted
|
147
150
|
end
|
148
151
|
when SlowBlink::REF
|
149
152
|
if type.ref.kind_of? Group
|
@@ -155,13 +158,12 @@ module SlowBlink
|
|
155
158
|
permitted << id
|
156
159
|
end
|
157
160
|
end
|
158
|
-
|
161
|
+
Class.new(DynamicGroup) do
|
162
|
+
@implements = type.class
|
159
163
|
@name = name
|
160
164
|
@opt = field.opt?
|
161
165
|
@groups = groups
|
162
166
|
@permitted = permitted
|
163
|
-
extend DynamicGroup::CLASS
|
164
|
-
include DynamicGroup::INSTANCE
|
165
167
|
end
|
166
168
|
else
|
167
169
|
_model_group(field.opt?, type.ref)
|
@@ -170,12 +172,11 @@ module SlowBlink
|
|
170
172
|
_model_type(opt, type.ref)
|
171
173
|
end
|
172
174
|
else
|
173
|
-
|
175
|
+
Class.new(SlowBlink::Message.const_get(type.class.name.split('::').last)) do
|
176
|
+
klass =
|
174
177
|
@opt = field.opt?
|
175
178
|
@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
|
+
@type = type
|
179
180
|
end
|
180
181
|
end
|
181
182
|
end
|
@@ -19,65 +19,57 @@
|
|
19
19
|
|
20
20
|
module SlowBlink::Message
|
21
21
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
size
|
29
|
-
|
30
|
-
while out.size < size do
|
31
|
-
value << @type.from_compact!(input)
|
32
|
-
end
|
33
|
-
self.new(value)
|
34
|
-
else
|
35
|
-
self.new
|
22
|
+
class SEQUENCE
|
23
|
+
|
24
|
+
def self.from_compact!(input)
|
25
|
+
value = []
|
26
|
+
size = input.getU32!
|
27
|
+
if size
|
28
|
+
while out.size < size do
|
29
|
+
value << @type.from_compact!(input)
|
36
30
|
end
|
31
|
+
self.new(value)
|
32
|
+
else
|
33
|
+
self.new
|
37
34
|
end
|
38
|
-
|
39
35
|
end
|
40
36
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
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
|
37
|
+
# @param v [Array,nil]
|
38
|
+
def set(value)
|
39
|
+
if value
|
40
|
+
if value.kind_of? Array
|
41
|
+
@value = v
|
53
42
|
else
|
54
|
-
raise Error.new "
|
43
|
+
raise Error.new "bad type"
|
55
44
|
end
|
45
|
+
elsif self.class.opt?
|
46
|
+
@value = nil
|
47
|
+
else
|
48
|
+
raise Error.new "value unacceptable"
|
56
49
|
end
|
50
|
+
end
|
57
51
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
# @param value [Array]
|
63
|
-
def initialize(value)
|
64
|
-
if value
|
65
|
-
set(value)
|
66
|
-
else
|
67
|
-
@value = nil
|
68
|
-
end
|
69
|
-
end
|
52
|
+
def get
|
53
|
+
@value
|
54
|
+
end
|
70
55
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
out.putU32(nil)
|
78
|
-
end
|
56
|
+
# @param value [Array]
|
57
|
+
def initialize(value)
|
58
|
+
if value
|
59
|
+
set(value)
|
60
|
+
else
|
61
|
+
@value = nil
|
79
62
|
end
|
63
|
+
end
|
80
64
|
|
65
|
+
def to_compact(out)
|
66
|
+
if @value
|
67
|
+
@value.inject(out.putU32(@value.size)) do |out, v|
|
68
|
+
out << v.to_compact
|
69
|
+
end
|
70
|
+
else
|
71
|
+
out.putU32(nil)
|
72
|
+
end
|
81
73
|
end
|
82
74
|
|
83
75
|
end
|