slow_blink 0.0.6 → 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
@@ -24,68 +24,33 @@ module SlowBlink
|
|
24
24
|
|
25
25
|
class Definition
|
26
26
|
|
27
|
-
|
28
|
-
|
29
|
-
def self.===(other)
|
30
|
-
self == other
|
31
|
-
end
|
27
|
+
# @return [Type] defined type
|
28
|
+
attr_reader :type
|
32
29
|
|
33
30
|
# @macro location
|
34
31
|
attr_reader :location
|
35
32
|
|
36
|
-
# @return [
|
37
|
-
attr_reader :
|
33
|
+
# @return [String]
|
34
|
+
attr_reader :name
|
38
35
|
|
39
|
-
# @return [
|
40
|
-
attr_reader :
|
36
|
+
# @return [Integer,nil]
|
37
|
+
attr_reader :id
|
41
38
|
|
42
|
-
|
43
|
-
|
44
|
-
@ns = namespace
|
45
|
-
end
|
46
|
-
|
47
|
-
# @param nameWithID [NameWithID]
|
48
|
-
# @param type [ENUMERATION, Type]
|
49
|
-
# @param location [String]
|
50
|
-
def initialize(nameWithID, type, location)
|
51
|
-
@annotes = {}
|
52
|
-
@type = type
|
53
|
-
@location = location
|
54
|
-
@nameWithID = nameWithID
|
55
|
-
@ns = nil
|
39
|
+
def self.===(other)
|
40
|
+
self == other
|
56
41
|
end
|
57
42
|
|
58
|
-
# @
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
# a definition can resolve to a definition only if there is a dynamic
|
67
|
-
# link somewhere in the chain
|
68
|
-
sf = stack.each
|
69
|
-
begin
|
70
|
-
loop do
|
71
|
-
if sf.next == self
|
72
|
-
loop do
|
73
|
-
begin
|
74
|
-
f = sf.next
|
75
|
-
if f.respond_to? "dynamic?".to_sym and f.dynamic?
|
76
|
-
return schema
|
77
|
-
end
|
78
|
-
rescue StopIteration
|
79
|
-
raise ParseError.new "#{self.location}: error: invalid cycle detected"
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
|
-
rescue StopIteration
|
43
|
+
# @private
|
44
|
+
def initialize(attr)
|
45
|
+
@location = attr[:loc].freeze
|
46
|
+
@ns = attr[:ns].freeze
|
47
|
+
@name = attr[:name][:name].dup
|
48
|
+
if @ns
|
49
|
+
@name.prepend "#{@ns}::"
|
85
50
|
end
|
86
|
-
|
87
|
-
@
|
88
|
-
|
51
|
+
@name.freeze
|
52
|
+
@id = attr[:name][:id]
|
53
|
+
@type = SlowBlink.const_get(attr[:type][:class]).new(attr[:type].merge({:table => attr[:table], :ns => attr[:ns], :name => @name}))
|
89
54
|
end
|
90
55
|
|
91
56
|
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
# @license
|
2
|
+
#
|
3
|
+
# Copyright (c) 2016 Cameron Harper
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy of
|
6
|
+
# this software and associated documentation files (the "Software"), to deal in
|
7
|
+
# the Software without restriction, including without limitation the rights to
|
8
|
+
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
9
|
+
# the Software, and to permit persons to whom the Software is furnished to do so,
|
10
|
+
# subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in all
|
13
|
+
# copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
17
|
+
# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
18
|
+
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
19
|
+
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
20
|
+
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
+
|
22
|
+
module SlowBlink
|
23
|
+
|
24
|
+
class ENUM < Type
|
25
|
+
|
26
|
+
def self.===(other)
|
27
|
+
self == other
|
28
|
+
end
|
29
|
+
|
30
|
+
# @return [Array<Sym>]
|
31
|
+
def symbols
|
32
|
+
@symbols.values
|
33
|
+
end
|
34
|
+
|
35
|
+
# @return [String]
|
36
|
+
attr_reader :name
|
37
|
+
|
38
|
+
# @private
|
39
|
+
def initialize(attr)
|
40
|
+
|
41
|
+
@location = attr[:loc]
|
42
|
+
@symbols = {}
|
43
|
+
@name = attr[:name].dup.freeze
|
44
|
+
|
45
|
+
attr[:syms].each do |s|
|
46
|
+
|
47
|
+
if @symbols[s[:name]]
|
48
|
+
raise ParseError.new "#{s[:loc]}: duplicate symbol name"
|
49
|
+
else
|
50
|
+
if s[:value]
|
51
|
+
if s[:value] < 2147483647 and s[:value] > -2147483648
|
52
|
+
if @symbols.values.last
|
53
|
+
if @symbols.values.map{|sym|sym.value}.include? s[:value]
|
54
|
+
raise ParseError.new "#{s[:loc]}: ambiguous enum value"
|
55
|
+
else
|
56
|
+
@symbols[s[:name]] = Sym.new(s)
|
57
|
+
end
|
58
|
+
else
|
59
|
+
@symbols[s[:name]] = Sym.new(s)
|
60
|
+
end
|
61
|
+
else
|
62
|
+
raise ParseError.new "#{s[:loc]}: value out of range for an enum"
|
63
|
+
end
|
64
|
+
else
|
65
|
+
if @symbols.values.last
|
66
|
+
if (@symbols.values.last.value + 1) < 2147483647
|
67
|
+
if @symbols.values.map{|sym|sym.value}.include? s[:value]
|
68
|
+
raise ParseError.new "#{s[:loc]}: ambiguous enum value"
|
69
|
+
else
|
70
|
+
@symbols[s[:name]] = Sym.new(s.merge({:implicit => true, :value => @symbols.values.last.value + 1}))
|
71
|
+
end
|
72
|
+
else
|
73
|
+
raise ParseError.new "#{s[:loc]}: implicit value out of range for an enum"
|
74
|
+
end
|
75
|
+
else
|
76
|
+
@symbols[s[:name]] = Sym.new(s.merge({:implicit => true, :value => 0}))
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
|
85
|
+
# @param nameOrVal [String,Integer]
|
86
|
+
# @raise [RangeError] nameOrVal does not resolve to a symbol
|
87
|
+
# @return [Sym]
|
88
|
+
def symbol(nameOrVal)
|
89
|
+
if nameOrVal.kind_of? String
|
90
|
+
if (result = @symbols[nameOrVal]).nil?
|
91
|
+
raise RangeError
|
92
|
+
end
|
93
|
+
else
|
94
|
+
if (result = @symbols.values.detect{|s|s.value == nameOrVal.to_i}).nil?
|
95
|
+
raise RangeError
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
end
|
data/lib/slow_blink/field.rb
CHANGED
@@ -23,50 +23,80 @@
|
|
23
23
|
module SlowBlink
|
24
24
|
|
25
25
|
class Field
|
26
|
-
|
27
|
-
|
26
|
+
|
27
|
+
# @param [Integer]
|
28
|
+
attr_reader :id
|
29
|
+
|
30
|
+
# @param [String]
|
31
|
+
attr_reader :name
|
28
32
|
|
29
33
|
# @macro location
|
30
34
|
attr_reader :location
|
31
35
|
|
32
36
|
# @return [Type]
|
33
|
-
|
37
|
+
def type
|
38
|
+
result = nil
|
39
|
+
if @type.is_a? REF
|
40
|
+
|
41
|
+
ptr = @type.resolve
|
42
|
+
stack = []
|
43
|
+
sequence = @type.sequence?
|
44
|
+
dynamic = @type.dynamic?
|
34
45
|
|
35
|
-
|
36
|
-
attr_reader :nameWithID
|
46
|
+
while ptr and ptr.is_a? Definition and ptr.type.is_a? REF do
|
37
47
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
48
|
+
if stack.include? ptr
|
49
|
+
raise ParseError.new "#{ptr.location}: circular reference detected"
|
50
|
+
else
|
51
|
+
if ptr.type.dynamic?
|
52
|
+
# assumption: double dynamic is still dynamic
|
53
|
+
dynamic = true
|
54
|
+
end
|
55
|
+
if ptr.type.sequence?
|
56
|
+
if sequence
|
57
|
+
raise ParseError.new "#{ptr.location}: sequence of sequences detected while resolving from '#{@type.location}'"
|
58
|
+
end
|
59
|
+
sequence = true
|
60
|
+
end
|
61
|
+
stack << ptr
|
62
|
+
ptr = ptr.type.resolve
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
if ptr.nil?
|
67
|
+
if stack.size == 0
|
68
|
+
stack << @type
|
69
|
+
end
|
70
|
+
raise ParseError.new "#{stack.last.location}: reference does not resolve"
|
71
|
+
elsif ptr.is_a? Group
|
72
|
+
if dynamic
|
73
|
+
result = DynamicGroup.new(:group => ptr, :sequence => sequence, :table => @table)
|
74
|
+
else
|
75
|
+
result = StaticGroup.new(:group => ptr, :sequence => sequence, :table => @table)
|
76
|
+
end
|
77
|
+
else
|
78
|
+
result = ptr.type
|
79
|
+
end
|
80
|
+
else
|
81
|
+
result = @type
|
82
|
+
end
|
83
|
+
|
84
|
+
result
|
42
85
|
end
|
43
86
|
|
44
|
-
# @
|
45
|
-
|
46
|
-
|
47
|
-
# @param location [String]
|
48
|
-
def initialize(nameWithID, type, opt, location)
|
49
|
-
@annotes = {}
|
50
|
-
@schema = nil
|
51
|
-
@type = type
|
52
|
-
@opt = opt
|
53
|
-
@location = location
|
54
|
-
@nameWithID = nameWithID
|
87
|
+
# @return [true,false]
|
88
|
+
def optional?
|
89
|
+
@optional
|
55
90
|
end
|
56
91
|
|
57
|
-
# @
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
def link(schema,ns, stack=[])
|
66
|
-
if @schema.nil?
|
67
|
-
@schema = @type.link(schema, ns, stack << self)
|
68
|
-
end
|
69
|
-
@schema
|
92
|
+
# @private
|
93
|
+
def initialize(attr)
|
94
|
+
@name = attr[:name][:name].freeze
|
95
|
+
@id = attr[:name][:id]
|
96
|
+
@optional = attr[:opt]
|
97
|
+
@location = attr[:location].freeze
|
98
|
+
@type = SlowBlink.const_get(attr[:type][:class]).new(attr[:type].merge({:table => attr[:table], :ns => attr[:ns]}))
|
99
|
+
@table = attr[:table]
|
70
100
|
end
|
71
101
|
|
72
102
|
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'erb'
|
2
|
+
|
3
|
+
module SlowBlink
|
4
|
+
|
5
|
+
module GenerateC
|
6
|
+
|
7
|
+
include SlowBlink
|
8
|
+
|
9
|
+
class Model
|
10
|
+
|
11
|
+
def initialize(schema)
|
12
|
+
@schema = schema
|
13
|
+
@prefix = ""
|
14
|
+
@options = {}
|
15
|
+
end
|
16
|
+
|
17
|
+
def render
|
18
|
+
header = put("groups.h.erb")
|
19
|
+
source = put("groups.c.erb")
|
20
|
+
|
21
|
+
File.write("groups.h", header)
|
22
|
+
File.write("groups.c", source)
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def put(filename)
|
28
|
+
f = File.read(File.expand_path(File.join(File.dirname(__FILE__), filename)))
|
29
|
+
erb = ERB.new(f, nil, "<>-")
|
30
|
+
erb.filename = filename
|
31
|
+
erb.result(binding)
|
32
|
+
end
|
33
|
+
|
34
|
+
def gname(g)
|
35
|
+
"#{@prefix}#{g.name.gsub("::","_")}"
|
36
|
+
end
|
37
|
+
|
38
|
+
def fname(f)
|
39
|
+
"_#{f.name}"
|
40
|
+
end
|
41
|
+
|
42
|
+
def value_type(type)
|
43
|
+
|
44
|
+
out = ""
|
45
|
+
|
46
|
+
case type.class
|
47
|
+
when BINARY, STRING, FIXED
|
48
|
+
out << "struct blink_string"
|
49
|
+
when U8
|
50
|
+
out << "uint8_t"
|
51
|
+
when U16
|
52
|
+
out << "uint16_t"
|
53
|
+
when U32
|
54
|
+
out << "uint32_t"
|
55
|
+
when U64
|
56
|
+
out << "uint64_t"
|
57
|
+
when I8
|
58
|
+
out << "int8_t"
|
59
|
+
when I16
|
60
|
+
out << "int16_t"
|
61
|
+
when I32
|
62
|
+
out << "int32_t"
|
63
|
+
when I64
|
64
|
+
out << "int64_t"
|
65
|
+
when ENUM
|
66
|
+
out << "const char *"
|
67
|
+
when FLOATING_POINT
|
68
|
+
out << "double"
|
69
|
+
when DECIMAL
|
70
|
+
out << "struct blink_decimal"
|
71
|
+
when BOOLEAN
|
72
|
+
out << "bool"
|
73
|
+
when StaticGroup
|
74
|
+
out << "struct #{cname(type.name)} *"
|
75
|
+
when OBJECT, DynamicGroup
|
76
|
+
out << "struct base_group *"
|
77
|
+
else
|
78
|
+
raise
|
79
|
+
end
|
80
|
+
|
81
|
+
out
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
|
89
|
+
end
|
data/lib/slow_blink/group.rb
CHANGED
@@ -24,133 +24,152 @@ module SlowBlink
|
|
24
24
|
|
25
25
|
class Group
|
26
26
|
|
27
|
-
include Annotatable
|
28
|
-
|
29
27
|
def self.===(other)
|
30
28
|
self == other
|
31
29
|
end
|
32
30
|
|
33
|
-
# @
|
34
|
-
attr_reader :
|
31
|
+
# @return [Integer,nil]
|
32
|
+
attr_reader :id
|
35
33
|
|
36
|
-
# @return [
|
37
|
-
attr_reader :
|
34
|
+
# @return [String] qualified name
|
35
|
+
attr_reader :name
|
38
36
|
|
37
|
+
# @macro location
|
38
|
+
attr_reader :location
|
39
|
+
|
39
40
|
# @return [Array<Field>]
|
40
41
|
def fields
|
41
|
-
@fields.values
|
42
|
-
end
|
43
42
|
|
44
|
-
|
45
|
-
|
46
|
-
|
43
|
+
# collect all ancestors
|
44
|
+
ancestors = []
|
45
|
+
ptr = superGroup
|
46
|
+
while ptr do
|
47
|
+
ancestors.unshift ptr
|
48
|
+
ptr = ptr.superGroup
|
49
|
+
end
|
50
|
+
|
51
|
+
result = {}
|
52
|
+
|
53
|
+
ancestors.each do |g|
|
54
|
+
g.rawFields.each do |f|
|
55
|
+
result[f.name] = f
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
@fields.each do |fn, fv|
|
60
|
+
if result[fn]
|
61
|
+
raise ParseError.new "#{fv.location}: field name shadowed by supergroup"
|
62
|
+
else
|
63
|
+
result[fn] = fv
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
result.values
|
47
68
|
end
|
48
69
|
|
49
|
-
# @
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
@location = location
|
59
|
-
@fields = []
|
60
|
-
@nameWithID = nameWithID
|
61
|
-
@ns = nil
|
70
|
+
# @return [Array<Group>] super groups in order of most super
|
71
|
+
def ancestors
|
72
|
+
result = []
|
73
|
+
ptr = superGroup
|
74
|
+
while ptr do
|
75
|
+
result << ptr
|
76
|
+
ptr = ptr.superGroup
|
77
|
+
end
|
78
|
+
result
|
62
79
|
end
|
63
80
|
|
64
|
-
# @
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
rescue StopIteration
|
88
|
-
raise ParseError.new "#{self.location}: error: invalid cycle detected"
|
89
|
-
end
|
81
|
+
# @return [Group,nil]
|
82
|
+
def superGroup
|
83
|
+
|
84
|
+
result = nil
|
85
|
+
|
86
|
+
if @super
|
87
|
+
|
88
|
+
ptr = @super.resolve
|
89
|
+
stack = []
|
90
|
+
sequence = false
|
91
|
+
dynamic = false
|
92
|
+
|
93
|
+
while ptr and ptr.is_a? Definition and ptr.type.is_a? REF do
|
94
|
+
|
95
|
+
if stack.include? ptr
|
96
|
+
raise ParseError.new "#{@super.location}: supergoup circular reference"
|
97
|
+
else
|
98
|
+
if ptr.type.dynamic?
|
99
|
+
dynamic = true
|
100
|
+
end
|
101
|
+
if ptr.type.sequence?
|
102
|
+
if sequence
|
103
|
+
raise ParseError.new "#{@super.location}: sequence of sequence detected at '#{ptr.type.location}'"
|
90
104
|
end
|
105
|
+
sequence = true
|
91
106
|
end
|
107
|
+
stack << ptr
|
108
|
+
ptr = ptr.type.resolve
|
92
109
|
end
|
93
|
-
rescue StopIteration
|
94
110
|
end
|
95
111
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
if
|
100
|
-
|
101
|
-
if @superGroup.dynamic_reference?
|
102
|
-
Log.error "#{@superGroup.location}: error: reference to supergroup must not be dynamic"
|
103
|
-
error = true
|
104
|
-
else
|
105
|
-
@superGroup.ref.fields.each do |f|
|
106
|
-
@fields[f.nameWithID.name] = f
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|
110
|
-
if !error
|
111
|
-
@rawFields.each do |f|
|
112
|
-
if @fields[f.nameWithID.name]
|
113
|
-
Log.error "#{f.location}: error: field names must be unique within a group ('#{f.nameWithID.name}' first appears at #{@fields[f.nameWithID.name].location})"
|
114
|
-
error = true
|
115
|
-
else
|
116
|
-
if f.link(schema, @ns, stack.dup << self)
|
117
|
-
@fields[f.nameWithID.name] = f
|
118
|
-
else
|
119
|
-
error = true
|
120
|
-
end
|
121
|
-
end
|
122
|
-
end
|
123
|
-
end
|
124
|
-
else
|
125
|
-
Log.error "#{@superGroup.location}: error: reference to supergroup must resolve to group definition"
|
126
|
-
error = true
|
112
|
+
if ptr.nil?
|
113
|
+
raise ParseError.new "#{@super.location}: supergroup reference '#{@super.ref}' does not resolve"
|
114
|
+
elsif ptr.is_a? Definition
|
115
|
+
if dynamic
|
116
|
+
raise ParseError.new "#{@super.location}: supergroup reference cannot resolve dynamic reference to a #{ptr.type.class} makes no sense"
|
127
117
|
end
|
118
|
+
raise ParseError.new "#{@super.location}: supergroup reference must resolve to a group"
|
128
119
|
else
|
129
|
-
|
120
|
+
if dynamic
|
121
|
+
raise ParseError.new "#{@super.location}: supergroup reference cannot be dynamic"
|
122
|
+
end
|
123
|
+
if sequence
|
124
|
+
raise ParseError.new "#{@super.location}: supergroup reference cannot be a sequence"
|
125
|
+
end
|
126
|
+
if ptr == self
|
127
|
+
raise ParseError.new "#{@super.location}: supergroup cannot be own group"
|
128
|
+
end
|
129
|
+
result = ptr
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
result
|
134
|
+
end
|
135
|
+
|
136
|
+
# @private
|
137
|
+
def initialize(attr)
|
138
|
+
|
139
|
+
@ns = attr[:ns].freeze
|
140
|
+
@name = attr[:name][:name].dup
|
141
|
+
if @ns
|
142
|
+
@name.prepend "#{@ns}::"
|
143
|
+
end
|
144
|
+
@name.freeze
|
145
|
+
@id = attr[:name][:id]
|
146
|
+
@location = attr[:name][:loc].freeze
|
147
|
+
@fields = {}
|
148
|
+
|
149
|
+
if attr[:super]
|
150
|
+
@super = REF.new(attr[:super].merge(:table=>attr[:table], :ns=>attr[:ns]))
|
151
|
+
if @super.ref == @name or @super.ref.split("::").last == @name
|
152
|
+
raise ParseError.new "#{@location}: supergroup cannot be own group"
|
130
153
|
end
|
154
|
+
else
|
155
|
+
@super = nil
|
156
|
+
end
|
131
157
|
|
132
|
-
|
133
|
-
|
158
|
+
attr[:fields].each do |f|
|
159
|
+
if @fields[f[:name][:name]]
|
160
|
+
raise ParseError.new "#{f[:location]}: duplicate field name"
|
161
|
+
else
|
162
|
+
@fields[f[:name][:name]] = Field.new(f.merge({:table => attr[:table], :ns => attr[:ns]}))
|
134
163
|
end
|
135
|
-
|
136
164
|
end
|
137
|
-
|
138
|
-
@schema
|
139
|
-
end
|
140
165
|
|
141
|
-
# @param name [String] name of field
|
142
|
-
# @return [Field] field exists
|
143
|
-
# @return [nil] field does not exist
|
144
|
-
def field(name)
|
145
|
-
@fields[name]
|
146
166
|
end
|
147
167
|
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
end
|
168
|
+
protected
|
169
|
+
|
170
|
+
def rawFields
|
171
|
+
@fields.values
|
172
|
+
end
|
154
173
|
|
155
174
|
end
|
156
175
|
end
|
@@ -25,16 +25,15 @@ module SlowBlink::Message
|
|
25
25
|
class BINARY
|
26
26
|
|
27
27
|
# @private
|
28
|
-
def self.from_compact
|
29
|
-
value = input.getBinary
|
30
|
-
if value
|
28
|
+
def self.from_compact(input, stack)
|
29
|
+
if value = input.getBinary
|
31
30
|
if !@size or value.size <= @size
|
32
31
|
self.new(value)
|
33
32
|
else
|
34
33
|
raise WeakError8.new "W8: Binary value exceeds maximum size"
|
35
34
|
end
|
36
35
|
else
|
37
|
-
|
36
|
+
nil
|
38
37
|
end
|
39
38
|
end
|
40
39
|
|