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.
- checksums.yaml +4 -4
- data/ext/slow_blink/ext_schema_parser/lexer.c +2793 -839
- data/ext/slow_blink/ext_schema_parser/lexer.h +14 -137
- data/ext/slow_blink/ext_schema_parser/parser.c +616 -670
- data/ext/slow_blink/ext_schema_parser/parser.h +6 -4
- data/ext/slow_blink/message/ext_compact_encoder/blink_compact.c +642 -0
- data/ext/slow_blink/message/ext_compact_encoder/blink_compact.h +411 -0
- data/ext/slow_blink/message/ext_compact_encoder/blink_debug.h +46 -0
- data/ext/slow_blink/message/ext_compact_encoder/blink_stream.c +314 -0
- data/ext/slow_blink/message/ext_compact_encoder/blink_stream.h +185 -0
- data/ext/slow_blink/message/ext_compact_encoder/ext_compact_encoder.c +382 -269
- data/lib/slow_blink/definition.rb +18 -53
- data/lib/slow_blink/dynamic_group.rb +8 -0
- data/lib/slow_blink/enum.rb +101 -0
- data/lib/slow_blink/field.rb +63 -33
- data/lib/slow_blink/generate_c/model.rb +89 -0
- data/lib/slow_blink/group.rb +119 -100
- data/lib/slow_blink/message/binary.rb +3 -4
- data/lib/slow_blink/message/boolean.rb +3 -4
- data/lib/slow_blink/message/date.rb +3 -4
- data/lib/slow_blink/message/decimal.rb +3 -5
- data/lib/slow_blink/message/{enumeration.rb → enum.rb} +17 -17
- data/lib/slow_blink/message/field.rb +77 -27
- data/lib/slow_blink/message/fixed.rb +5 -21
- data/lib/slow_blink/message/floating_point.rb +3 -4
- data/lib/slow_blink/message/group.rb +90 -161
- data/lib/slow_blink/message/integer.rb +24 -32
- data/lib/slow_blink/message/model.rb +50 -110
- data/lib/slow_blink/message/string.rb +3 -4
- data/lib/slow_blink/message/time.rb +5 -5
- data/lib/slow_blink/message/time_of_day.rb +5 -12
- data/lib/slow_blink/ref.rb +22 -71
- data/lib/slow_blink/schema.rb +64 -85
- data/lib/slow_blink/schema_buffer.rb +1 -4
- data/lib/slow_blink/static_group.rb +37 -0
- data/lib/slow_blink/string.rb +4 -5
- data/lib/slow_blink/sym.rb +8 -28
- data/lib/slow_blink/type.rb +10 -19
- data/lib/slow_blink/version.rb +1 -1
- data/lib/slow_blink.rb +1 -0
- data/test/tc_compact_encoder.rb +114 -147
- data/test/tc_inputs.rb +2 -4
- data/test/tc_model_string.rb +29 -0
- data/test/tc_schema_new.rb +212 -0
- metadata +17 -26
- data/ext/slow_blink/ext_schema_parser/common.h +0 -27
- data/ext/slow_blink/message/ext_compact_encoder/compact_encoder.c +0 -258
- data/ext/slow_blink/message/ext_compact_encoder/compact_encoder.h +0 -92
- data/lib/slow_blink/annotatable.rb +0 -48
- data/lib/slow_blink/annotation.rb +0 -47
- data/lib/slow_blink/enumeration.rb +0 -90
- data/lib/slow_blink/incremental_annotation.rb +0 -151
- data/lib/slow_blink/log.rb +0 -51
- data/lib/slow_blink/message/sequence.rb +0 -98
- data/lib/slow_blink/name_with_id.rb +0 -49
- data/lib/slow_blink/namespace.rb +0 -143
- data/lib/slow_blink/sequence.rb +0 -57
- data/test/tc_field.rb +0 -94
- data/test/tc_group.rb +0 -114
- data/test/tc_incr_annote.rb +0 -22
- data/test/tc_namespace.rb +0 -8
- data/test/tc_types.rb +0 -218
@@ -19,6 +19,7 @@
|
|
19
19
|
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
20
20
|
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
21
|
|
22
|
+
|
22
23
|
module SlowBlink
|
23
24
|
|
24
25
|
# This module is concerned with generating models from Schema that are optimised for encoding/decoding and enforcing constraints
|
@@ -112,63 +113,45 @@ module SlowBlink
|
|
112
113
|
@maxRecursion = opts[:maxRecursion]||DEFAULT_MAX_RECURSION
|
113
114
|
maxRecursion = @maxRecursion
|
114
115
|
|
115
|
-
#
|
116
|
-
|
116
|
+
# any of the groups
|
117
|
+
|
117
118
|
taggedGroups = @taggedGroups
|
118
|
-
|
119
|
-
@
|
119
|
+
|
120
|
+
@anyTaggedGroup = Class.new(DynamicGroup) do
|
120
121
|
@maxRecursion = maxRecursion
|
121
|
-
@
|
122
|
-
@opt = false
|
123
|
-
@groups = groups
|
122
|
+
@anyTaggedGroup = self
|
124
123
|
@taggedGroups = taggedGroups
|
125
|
-
@
|
124
|
+
@permittedID = schema.groups.map{|g|g.id}.select{|g|g}
|
126
125
|
end
|
127
|
-
|
126
|
+
|
127
|
+
anyTaggedGroup = @anyTaggedGroup
|
128
128
|
|
129
|
-
|
130
|
-
|
131
|
-
g.fields.
|
132
|
-
|
133
|
-
end
|
134
|
-
@groups[name] = Class.new(Group) do
|
135
|
-
@extensionObject = extensionObject
|
129
|
+
# create an anon class for each group defined in schema
|
130
|
+
schema.groups.each do |g|
|
131
|
+
fields = g.fields.map{|f| _model_field(f)}
|
132
|
+
@groups[g.name] = Class.new(Group) do
|
136
133
|
@maxRecursion = maxRecursion
|
137
|
-
@
|
138
|
-
@
|
139
|
-
@
|
134
|
+
@anyTaggedGroup = anyTaggedGroup
|
135
|
+
@name = g.name
|
136
|
+
@id = g.id
|
137
|
+
@fields = fields
|
140
138
|
end
|
141
|
-
if g.
|
142
|
-
@taggedGroups[g.
|
139
|
+
if g.id
|
140
|
+
@taggedGroups[g.id] = @groups[g.name]
|
143
141
|
end
|
144
142
|
end
|
145
143
|
|
146
|
-
|
147
144
|
end
|
148
145
|
|
149
146
|
# @api user
|
150
147
|
#
|
151
148
|
# Initialise a {Group} from a compact form string
|
152
|
-
# @param input [
|
149
|
+
# @param input [StringIO] Blink Protocol compact form
|
153
150
|
# @return [Group] anonymous subclass instance of Group
|
154
151
|
# @raise [WeakError,StrongError]
|
155
152
|
# @raise [RecursionLimit]
|
156
|
-
# @raise []
|
157
153
|
def decode_compact(input)
|
158
|
-
|
159
|
-
inputSize = input.size
|
160
|
-
buf = input.getBinary!
|
161
|
-
if buf.size > 0
|
162
|
-
id = buf.getU64!
|
163
|
-
groupClass = @taggedGroups[id]
|
164
|
-
if groupClass
|
165
|
-
group = groupClass.from_compact!(buf, stack)
|
166
|
-
else
|
167
|
-
raise WeakError2.new "W2: Group id #{group.id} is unknown"
|
168
|
-
end
|
169
|
-
else
|
170
|
-
raise WeakError1.new "W1: Top level group cannot be null"
|
171
|
-
end
|
154
|
+
@anyTaggedGroup.from_compact(input, []).get
|
172
155
|
end
|
173
156
|
|
174
157
|
# @api user
|
@@ -179,11 +162,10 @@ module SlowBlink
|
|
179
162
|
# @return [Group] anonymous subclass of Group
|
180
163
|
# @raise [RangeError] unknown group
|
181
164
|
def group(name)
|
182
|
-
group = @groups[name]
|
183
|
-
if group
|
184
|
-
group
|
185
|
-
else
|
165
|
+
if (group = @groups[name]).nil?
|
186
166
|
raise RangeError.new "group '#{name}' is unknown"
|
167
|
+
else
|
168
|
+
group
|
187
169
|
end
|
188
170
|
end
|
189
171
|
|
@@ -194,89 +176,47 @@ module SlowBlink
|
|
194
176
|
# @param field [SlowBlink::Field] field definition
|
195
177
|
# @return [Class] anonymous subclass of {Field}
|
196
178
|
def _model_field(field)
|
197
|
-
|
179
|
+
|
180
|
+
type = _model_type(field.type)
|
198
181
|
Class.new(Field) do
|
199
|
-
@
|
200
|
-
@name = field.
|
201
|
-
@id = field.
|
182
|
+
@optional = field.optional?
|
183
|
+
@name = field.name
|
184
|
+
@id = field.id
|
202
185
|
@type = type
|
203
|
-
|
186
|
+
@sequence = field.type.sequence?
|
187
|
+
end
|
204
188
|
end
|
205
189
|
|
206
190
|
# Create a model for a type
|
207
191
|
#
|
208
192
|
# @param type [SlowBlink::Type] type definition
|
209
193
|
# @param opt [true,false] parent definition may allow this type to be optional
|
210
|
-
def _model_type(type
|
211
|
-
|
194
|
+
def _model_type(type)
|
195
|
+
anyTaggedGroup = @anyTaggedGroup
|
212
196
|
maxRecursion = @maxRecursion
|
197
|
+
|
213
198
|
case type.class
|
214
199
|
when SlowBlink::OBJECT
|
215
|
-
|
200
|
+
@anyTaggedGroup
|
201
|
+
when SlowBlink::DynamicGroup
|
216
202
|
taggedGroups = @taggedGroups
|
217
|
-
permitted = @taggedGroups.keys
|
218
203
|
Class.new(DynamicGroup) do
|
219
|
-
@
|
204
|
+
@anyTaggedGroup = anyTaggedGroup
|
220
205
|
@maxRecursion = maxRecursion
|
221
|
-
@opt = opt
|
222
|
-
@groups = groups
|
223
206
|
@taggedGroups = taggedGroups
|
224
|
-
@
|
225
|
-
end
|
226
|
-
when SlowBlink::REF
|
227
|
-
if type.ref.kind_of? SlowBlink::Group
|
228
|
-
if type.dynamic?
|
229
|
-
taggedGroups = @taggedGroups
|
230
|
-
groups = @groups
|
231
|
-
permitted = @taggedGroups.keys
|
232
|
-
@schema.tagged.each do |id, g|
|
233
|
-
if g.group_kind_of?(type)
|
234
|
-
permitted << id
|
235
|
-
end
|
236
|
-
end
|
237
|
-
Class.new(DynamicGroup) do
|
238
|
-
@extensionObject = extensionObject
|
239
|
-
@maxRecursion = maxRecursion
|
240
|
-
@opt = opt
|
241
|
-
@taggedGroups = taggedGroups
|
242
|
-
@groups = groups
|
243
|
-
@permitted = permitted
|
244
|
-
end
|
245
|
-
else
|
246
|
-
fields = {}
|
247
|
-
type.ref.fields.each do |f|
|
248
|
-
fields[f.nameWithID.name] = _model_field(f)
|
249
|
-
end
|
250
|
-
Class.new(StaticGroup) do
|
251
|
-
@extensionObject = extensionObject
|
252
|
-
@maxRecursion = maxRecursion
|
253
|
-
@name = type.ref.nameWithID.name
|
254
|
-
@id = nil
|
255
|
-
@opt = opt
|
256
|
-
@fields = fields
|
257
|
-
end
|
258
|
-
end
|
259
|
-
else
|
260
|
-
_model_type(type.ref, false)
|
261
|
-
end
|
262
|
-
when SlowBlink::SEQUENCE
|
263
|
-
t = _model_type(type.type, false)
|
264
|
-
Class.new(SEQUENCE) do
|
265
|
-
@maxRecursion = maxRecursion
|
266
|
-
@type = t
|
267
|
-
end
|
268
|
-
when SlowBlink::ENUMERATION
|
269
|
-
symbols = {}
|
270
|
-
type.symbols.each do |n,v|
|
271
|
-
symbols[n] = v.val
|
207
|
+
@permittedID = type.groups.map{|g|g.id}
|
272
208
|
end
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
209
|
+
when SlowBlink::StaticGroup
|
210
|
+
fields = type.fields.map{|f| _model_field(f)}
|
211
|
+
Class.new(StaticGroup) do
|
212
|
+
@maxRecursion = maxRecursion
|
213
|
+
@name = type.name
|
214
|
+
@id = type.id
|
215
|
+
@fields = fields
|
216
|
+
end
|
217
|
+
else
|
277
218
|
Class.new(SlowBlink::Message.const_get(type.class.name.split('::').last)) do
|
278
|
-
@
|
279
|
-
@type = type
|
219
|
+
@type = type
|
280
220
|
end
|
281
221
|
end
|
282
222
|
end
|
@@ -287,6 +227,7 @@ module SlowBlink
|
|
287
227
|
|
288
228
|
end
|
289
229
|
|
230
|
+
require "stringio"
|
290
231
|
require "slow_blink/message/ext_compact_encoder"
|
291
232
|
require "slow_blink/message/field"
|
292
233
|
require "slow_blink/message/integer"
|
@@ -294,9 +235,8 @@ require "slow_blink/message/string"
|
|
294
235
|
require "slow_blink/message/binary"
|
295
236
|
require "slow_blink/message/fixed"
|
296
237
|
require "slow_blink/message/boolean"
|
297
|
-
require "slow_blink/message/
|
238
|
+
require "slow_blink/message/enum"
|
298
239
|
require "slow_blink/message/floating_point"
|
299
|
-
require "slow_blink/message/sequence"
|
300
240
|
require "slow_blink/message/group"
|
301
241
|
require "slow_blink/message/time"
|
302
242
|
require "slow_blink/message/time_of_day"
|
@@ -25,16 +25,15 @@ module SlowBlink::Message
|
|
25
25
|
class STRING
|
26
26
|
|
27
27
|
# @private
|
28
|
-
def self.from_compact
|
29
|
-
value = input.getString
|
30
|
-
if value
|
28
|
+
def self.from_compact(input, stack)
|
29
|
+
if value = input.getString
|
31
30
|
if !@type.size or value.size <= @type.size
|
32
31
|
self.new(value)
|
33
32
|
else
|
34
33
|
raise WeakError7.new "W7: String value exceeds maximum size"
|
35
34
|
end
|
36
35
|
else
|
37
|
-
|
36
|
+
nil
|
38
37
|
end
|
39
38
|
end
|
40
39
|
|
@@ -18,6 +18,7 @@
|
|
18
18
|
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
19
19
|
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
20
20
|
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
+
|
21
22
|
require 'time'
|
22
23
|
|
23
24
|
module SlowBlink::Message
|
@@ -26,12 +27,11 @@ module SlowBlink::Message
|
|
26
27
|
class MILLI_TIME
|
27
28
|
|
28
29
|
# @private
|
29
|
-
def self.from_compact
|
30
|
-
value = input.getI64
|
31
|
-
if value
|
30
|
+
def self.from_compact(input, stack)
|
31
|
+
if value = input.getI64
|
32
32
|
self.new(value)
|
33
33
|
else
|
34
|
-
|
34
|
+
nil
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
@@ -51,7 +51,7 @@ module SlowBlink::Message
|
|
51
51
|
# @raise [ArgumentError]
|
52
52
|
def set(value)
|
53
53
|
if value.kind_of? Time or value.kind_of? DateTime or value.kind_of? Date
|
54
|
-
@value =
|
54
|
+
@value = value.to_datetime
|
55
55
|
elsif value.kind_of? String
|
56
56
|
@value = DateTime.parse(value)
|
57
57
|
elsif value.kind_of? Integer
|
@@ -25,9 +25,8 @@ module SlowBlink::Message
|
|
25
25
|
class TIME_OF_DAY_MILLI
|
26
26
|
|
27
27
|
# @private
|
28
|
-
def self.from_compact
|
29
|
-
value = input.getU32
|
30
|
-
if value
|
28
|
+
def self.from_compact(input, stack)
|
29
|
+
if value = input.getU32
|
31
30
|
self.new(value)
|
32
31
|
else
|
33
32
|
value
|
@@ -54,12 +53,7 @@ module SlowBlink::Message
|
|
54
53
|
|
55
54
|
# @note calls {#set}(value)
|
56
55
|
def initialize(value)
|
57
|
-
|
58
|
-
if value
|
59
|
-
set(value)
|
60
|
-
else
|
61
|
-
@value = nil
|
62
|
-
end
|
56
|
+
set(value)
|
63
57
|
end
|
64
58
|
|
65
59
|
# @private
|
@@ -73,9 +67,8 @@ module SlowBlink::Message
|
|
73
67
|
class TIME_OF_DAY_NANO
|
74
68
|
|
75
69
|
# @private
|
76
|
-
def self.from_compact
|
77
|
-
value = input.getU64
|
78
|
-
if value
|
70
|
+
def self.from_compact(input, stack)
|
71
|
+
if value = input.getU64
|
79
72
|
self.new(value)
|
80
73
|
else
|
81
74
|
value
|
data/lib/slow_blink/ref.rb
CHANGED
@@ -22,88 +22,39 @@
|
|
22
22
|
|
23
23
|
module SlowBlink
|
24
24
|
|
25
|
+
# A REF is a type that points to a Group or a Definition
|
26
|
+
# by a reference string.
|
27
|
+
#
|
28
|
+
#
|
25
29
|
class REF < Type
|
26
30
|
|
27
|
-
# @return
|
31
|
+
# @return [String]
|
28
32
|
attr_reader :ref
|
29
33
|
|
30
|
-
# @return [true]
|
31
|
-
# @return [false] static reference
|
34
|
+
# @return [true,false]
|
32
35
|
def dynamic?
|
33
36
|
@dynamic
|
34
37
|
end
|
35
38
|
|
36
|
-
#
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
# @return [String]
|
44
|
-
attr_reader :qname
|
45
|
-
|
46
|
-
# @param qname [String]
|
47
|
-
# @param dynamic [true,false]
|
48
|
-
# @param location [String]
|
49
|
-
def initialize(qname, dynamic, location)
|
50
|
-
@qname = qname
|
51
|
-
if qname.split(":").size == 1
|
52
|
-
@namespace = nil
|
53
|
-
@name = qname
|
54
|
-
else
|
55
|
-
@namespace = qname.split(":").first
|
56
|
-
@name = qname.split(":").last
|
57
|
-
end
|
58
|
-
@dynamic = dynamic
|
59
|
-
@ref = nil
|
60
|
-
@dynamic_reference = false
|
61
|
-
super(location)
|
62
|
-
end
|
63
|
-
|
64
|
-
# @api private
|
65
|
-
#
|
66
|
-
# Resolve references, enforce constraints, and detect cycles
|
67
|
-
#
|
68
|
-
# @param schema [Schema] schema this definition belongs to
|
69
|
-
# @param ns [Namespace] namespace this definition belongs to
|
70
|
-
# @param stack [nil, Array] objects that depend on this object
|
71
|
-
# @return [true,false] linked?
|
72
|
-
def link(schema, ns, stack=[])
|
73
|
-
if @schema.nil?
|
74
|
-
if @namespace
|
75
|
-
ref = schema.resolve(@namespace, @name)
|
76
|
-
else
|
77
|
-
ref = ns.resolve(@name) or schema.resolve(@namespace, @name)
|
78
|
-
end
|
79
|
-
if ref and ref.link(schema, stack << self)
|
80
|
-
# follow reference
|
81
|
-
loop do
|
82
|
-
if ref.kind_of? Definition
|
83
|
-
if ref.type.kind_of? REF
|
84
|
-
if ref.type.dynamic?
|
85
|
-
@dynamic_reference = true
|
86
|
-
end
|
87
|
-
ref = ref.type.ref
|
88
|
-
next
|
89
|
-
else
|
90
|
-
ref = ref.type
|
91
|
-
end
|
92
|
-
end
|
93
|
-
break
|
94
|
-
end
|
95
|
-
|
96
|
-
if @dynamic and !ref.kind_of? Group
|
97
|
-
Log.error "#{@location}: error: a dynamic reference must resolve to a group that has an identifier"
|
98
|
-
else
|
99
|
-
@ref = ref
|
100
|
-
@schema = schema
|
39
|
+
# @return [Group, Definition]
|
40
|
+
def resolve
|
41
|
+
result = nil
|
42
|
+
if @table
|
43
|
+
if (result = @table[@ref]).nil?
|
44
|
+
if @ns and @ref.split("::").size == 1
|
45
|
+
result = @table[@ns + "::" + @ref]
|
101
46
|
end
|
102
|
-
else
|
103
|
-
Log.error "#{@location}: error: unresolved reference ('#{@qname}' is not defined as a group, type, or enum)"
|
104
47
|
end
|
105
48
|
end
|
106
|
-
|
49
|
+
result
|
50
|
+
end
|
51
|
+
|
52
|
+
# @private
|
53
|
+
def initialize(attr)
|
54
|
+
super(attr)
|
55
|
+
@ref = attr[:ref].freeze
|
56
|
+
@dynamic = attr[:dynamic]
|
57
|
+
@table = attr[:table]
|
107
58
|
end
|
108
59
|
|
109
60
|
end
|
data/lib/slow_blink/schema.rb
CHANGED
@@ -20,7 +20,6 @@
|
|
20
20
|
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
21
|
|
22
22
|
|
23
|
-
# SlowBlink namespace
|
24
23
|
module SlowBlink
|
25
24
|
|
26
25
|
# @!macro location
|
@@ -50,124 +49,104 @@ module SlowBlink
|
|
50
49
|
|
51
50
|
# @api user
|
52
51
|
#
|
53
|
-
# @return [
|
54
|
-
|
52
|
+
# @return [Array<Group>] groups
|
53
|
+
def groups
|
54
|
+
@defs.values.select do |d|
|
55
|
+
d.is_a? Group
|
56
|
+
end
|
57
|
+
end
|
55
58
|
|
56
|
-
|
57
|
-
|
58
|
-
# @return [Array<
|
59
|
-
|
59
|
+
# @api user
|
60
|
+
#
|
61
|
+
# @return [Array<Definition,Group>] definitions
|
62
|
+
def definitions
|
63
|
+
@defs.values
|
64
|
+
end
|
60
65
|
|
61
66
|
# @api user
|
62
67
|
#
|
63
|
-
# Create a Schema from one or more
|
64
|
-
# in the order they appear.
|
68
|
+
# Create a Schema from one or more Blink Protocol schemas
|
65
69
|
#
|
66
|
-
# @param buffer [Array<SchemaBuffer>]
|
70
|
+
# @param buffer [Array<SchemaBuffer,String>]
|
67
71
|
def initialize(*buffer)
|
68
72
|
|
73
|
+
namespace = []
|
74
|
+
|
69
75
|
if buffer.size > 0
|
70
|
-
namespace = []
|
71
76
|
buffer.each do |b|
|
72
|
-
|
77
|
+
if buffer.kind_of? String
|
78
|
+
namespace << SlowBlink.parse_file_buffer(buffer)
|
79
|
+
else
|
80
|
+
namespace << SlowBlink.parse_file_buffer(b.buffer, filename: b.filename)
|
81
|
+
end
|
73
82
|
end
|
74
83
|
else
|
75
84
|
raise ArgumentError.new "at least one buffer required"
|
76
85
|
end
|
77
86
|
|
78
|
-
@
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
begin
|
87
|
-
@ns[ns.name].merge!(ns)
|
88
|
-
rescue
|
89
|
-
raise ParseError
|
87
|
+
@defs = {}
|
88
|
+
|
89
|
+
# create groups and definitions
|
90
|
+
namespace.each do |ns|
|
91
|
+
ns[:defs].select{|d|d[:class] != :IncrementalAnnotation}.each do |d|
|
92
|
+
key = d[:name][:name].dup
|
93
|
+
if ns[:name]
|
94
|
+
key.prepend "#{ns[:name]}::"
|
90
95
|
end
|
91
|
-
|
92
|
-
|
93
|
-
|
96
|
+
if @defs[key]
|
97
|
+
raise ParseError.new "#{d[:loc]}: duplicate definition: '#{key}' first defined at '#{@defs[key].location}'"
|
98
|
+
else
|
99
|
+
@defs[key] = SlowBlink.const_get(d[:class]).new(d.merge({:ns=>ns[:name], :table=>@defs}))
|
100
|
+
end
|
101
|
+
end
|
94
102
|
end
|
95
103
|
|
96
|
-
#
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
Log.error "error: groups that have identifiers must have unique identifiers ('#{@g.nameWithID.id}' was first assigned to '#{@tagged[g.nameWithID.id].nameWithID.name}' at #{@tagged[g.nameWithID.id].location}"
|
109
|
-
error = true
|
110
|
-
else
|
111
|
-
@tagged[g.nameWithID.id] = g
|
104
|
+
# test that reference definitions resolve and detect circular references
|
105
|
+
@defs.values.each do |d|
|
106
|
+
if d.is_a? Definition and d.type.is_a? REF
|
107
|
+
ptr = d.type.resolve
|
108
|
+
if ptr
|
109
|
+
stack = [d]
|
110
|
+
while ptr and ptr.is_a? Definition and ptr.type.is_a? REF do
|
111
|
+
if stack.include? ptr
|
112
|
+
raise ParseError.new "#{d.type.location}: '#{d.name}' resolves to a circular reference"
|
113
|
+
else
|
114
|
+
ptr = ptr.type.resolve
|
115
|
+
end
|
112
116
|
end
|
117
|
+
else
|
118
|
+
raise ParseError.new "#{d.type.location}: '#{d.name}' does not resolve"
|
113
119
|
end
|
114
120
|
end
|
115
121
|
end
|
116
122
|
|
117
|
-
# resolve
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
@groups = {}
|
126
|
-
@ns.each do |name, ns|
|
127
|
-
ns.groups.each do |g|
|
128
|
-
if name
|
129
|
-
@groups[g.nameWithID.name.prepend "#{name}:"] = g
|
123
|
+
# test that groups resolve and meet constraints
|
124
|
+
tagged = {}
|
125
|
+
@defs.values.each do |d|
|
126
|
+
if d.is_a? Group
|
127
|
+
d.superGroup
|
128
|
+
d.fields
|
129
|
+
if d.id and tagged[d.id]
|
130
|
+
raise ParseError.new "#{d.type.location}: duplicate tag"
|
130
131
|
else
|
131
|
-
|
132
|
-
end
|
132
|
+
tagged[d.id] = d
|
133
|
+
end
|
133
134
|
end
|
134
135
|
end
|
135
136
|
|
136
|
-
if error
|
137
|
-
raise ParseError
|
138
|
-
end
|
139
|
-
|
140
137
|
end
|
141
138
|
|
142
|
-
# Resolve a name to a definition in any namespace
|
143
|
-
#
|
144
|
-
# @param namespace [String,nil]
|
145
|
-
# @param name [String]
|
146
|
-
# @return [Definition,Group]
|
147
|
-
def resolve(namespace, name)
|
148
|
-
if @ns[namespace]
|
149
|
-
@ns[namespace].resolve(name)
|
150
|
-
else
|
151
|
-
nil
|
152
|
-
end
|
153
|
-
end
|
154
|
-
|
155
139
|
end
|
156
140
|
|
157
141
|
end
|
158
142
|
|
159
143
|
require 'slow_blink/parse_error'
|
160
|
-
require 'slow_blink/log'
|
161
144
|
require 'slow_blink/schema_buffer'
|
162
|
-
require 'slow_blink/annotatable'
|
163
|
-
require 'slow_blink/namespace'
|
164
145
|
require 'slow_blink/version'
|
165
|
-
require 'slow_blink/annotation'
|
166
|
-
require 'slow_blink/incremental_annotation'
|
167
|
-
require 'slow_blink/group'
|
168
146
|
require 'slow_blink/field'
|
169
|
-
require 'slow_blink/definition'
|
170
147
|
require 'slow_blink/type'
|
148
|
+
require 'slow_blink/static_group'
|
149
|
+
require 'slow_blink/dynamic_group'
|
171
150
|
require 'slow_blink/integer'
|
172
151
|
require 'slow_blink/decimal'
|
173
152
|
require 'slow_blink/floating_point'
|
@@ -177,13 +156,13 @@ require 'slow_blink/fixed'
|
|
177
156
|
require 'slow_blink/date'
|
178
157
|
require 'slow_blink/time_of_day'
|
179
158
|
require 'slow_blink/time'
|
180
|
-
require 'slow_blink/sequence'
|
181
159
|
require 'slow_blink/ref'
|
160
|
+
require 'slow_blink/group'
|
182
161
|
require 'slow_blink/object'
|
183
162
|
require 'slow_blink/boolean'
|
184
|
-
require 'slow_blink/
|
163
|
+
require 'slow_blink/enum'
|
185
164
|
require 'slow_blink/sym'
|
186
|
-
require 'slow_blink/
|
165
|
+
require 'slow_blink/definition'
|
187
166
|
require 'slow_blink/ext_schema_parser'
|
188
167
|
|
189
168
|
|
@@ -22,10 +22,7 @@
|
|
22
22
|
|
23
23
|
module SlowBlink
|
24
24
|
|
25
|
-
# Use
|
26
|
-
# rather than loading from files.
|
27
|
-
#
|
28
|
-
# It combines the schema string with an optional filename string.
|
25
|
+
# Use SchemaBuffer when you want to deal named in-memory schemas
|
29
26
|
#
|
30
27
|
# e.g:
|
31
28
|
#
|