slow_blink 0.0.3 → 0.0.4

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.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/ext/slow_blink/ext_schema_parser/parser.c +245 -245
  3. data/lib/slow_blink/annotatable.rb +1 -2
  4. data/lib/slow_blink/annotation.rb +8 -1
  5. data/lib/slow_blink/compact_encoder.rb +1 -0
  6. data/lib/slow_blink/definition.rb +34 -10
  7. data/lib/slow_blink/enumeration.rb +15 -12
  8. data/lib/slow_blink/field.rb +9 -8
  9. data/lib/slow_blink/group.rb +61 -24
  10. data/lib/slow_blink/incremental_annotation.rb +7 -4
  11. data/lib/slow_blink/integer.rb +1 -1
  12. data/{test/tc_model.rb → lib/slow_blink/log.rb} +23 -40
  13. data/lib/slow_blink/message/binary.rb +39 -45
  14. data/lib/slow_blink/message/boolean.rb +25 -33
  15. data/lib/slow_blink/message/date.rb +2 -7
  16. data/lib/slow_blink/message/decimal.rb +1 -1
  17. data/lib/slow_blink/message/enumeration.rb +29 -33
  18. data/lib/slow_blink/message/field.rb +29 -37
  19. data/lib/slow_blink/message/fixed.rb +37 -45
  20. data/lib/slow_blink/message/floating_point.rb +24 -32
  21. data/lib/slow_blink/message/group.rb +172 -187
  22. data/lib/slow_blink/message/integer.rb +83 -132
  23. data/lib/slow_blink/message/model.rb +64 -63
  24. data/lib/slow_blink/message/sequence.rb +40 -48
  25. data/lib/slow_blink/message/string.rb +44 -51
  26. data/lib/slow_blink/message/time.rb +25 -40
  27. data/lib/slow_blink/message/time_of_day.rb +73 -86
  28. data/lib/slow_blink/name_with_id.rb +2 -6
  29. data/lib/slow_blink/namespace.rb +36 -36
  30. data/lib/slow_blink/ref.rb +29 -13
  31. data/lib/slow_blink/schema.rb +26 -10
  32. data/lib/slow_blink/schema_buffer.rb +14 -0
  33. data/lib/slow_blink/sequence.rb +16 -20
  34. data/lib/slow_blink/string.rb +0 -2
  35. data/lib/slow_blink/sym.rb +7 -5
  36. data/lib/slow_blink/type.rb +8 -5
  37. data/lib/slow_blink/version.rb +1 -1
  38. data/test/tc_field.rb +41 -0
  39. data/test/tc_group.rb +11 -0
  40. data/test/tc_model_static_group.rb +114 -0
  41. data/test/{tc_model_encode.rb → tc_model_think_blink.rb} +58 -13
  42. data/test/tc_types.rb +39 -0
  43. metadata +7 -6
@@ -19,76 +19,69 @@
19
19
 
20
20
  module SlowBlink::Message
21
21
 
22
- module STRING
22
+ class STRING
23
23
 
24
- module CLASS
25
-
26
- def name
27
- @name
28
- end
24
+ def self.name
25
+ @name
26
+ end
29
27
 
30
- def opt?
31
- @opt
32
- end
28
+ def self.opt?
29
+ @opt
30
+ end
33
31
 
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)
32
+ def self.from_compact!(input)
33
+ value = input.getString!
34
+ if value
35
+ if !@type.size or value.size <= @type.size
36
+ self.new(value)
44
37
  else
45
- raise Error.new "W5: Value cannot be null"
38
+ raise Error.new "W7: String value exceeds maximum size"
46
39
  end
40
+ elsif @opt
41
+ self.new(nil)
42
+ else
43
+ raise Error.new "W5: Value cannot be null"
47
44
  end
48
-
49
- def size
50
- @type.size
51
- end
52
-
53
45
  end
54
46
 
55
- module INSTANCE
47
+ def self.size
48
+ @type.size
49
+ end
56
50
 
57
- def get
58
- @value
59
- end
51
+ def get
52
+ @value
53
+ end
60
54
 
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
55
+ def set(value)
56
+ if value
57
+ if value.kind_of? String
58
+ if !self.class.size or value.size <= self.class.size
59
+ @value = value
69
60
  else
70
- raise Error.new "expecting a string type"
61
+ raise Error.new "string cannot be larger than #{self.class.size} bytes"
71
62
  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
63
  else
83
- @value = nil
64
+ raise Error.new "expecting a string type"
84
65
  end
66
+ elsif self.class.opt?
67
+ @value = nil
68
+ else
69
+ raise Error.new "string cannot be null"
85
70
  end
71
+ end
86
72
 
87
- def to_compact(out)
88
- out.putString(@value)
73
+ def initialize(value)
74
+ @value = nil
75
+ if value
76
+ set(value)
89
77
  end
78
+ end
90
79
 
80
+ def to_compact(out)
81
+ out.putString(@value)
91
82
  end
83
+
84
+
92
85
 
93
86
  end
94
87
 
@@ -19,60 +19,45 @@
19
19
 
20
20
  module SlowBlink::Message
21
21
 
22
- module MILLI_TIME
23
22
 
24
- module CLASS
25
-
26
- def from_compact!(input)
27
- self.new(input.getI64!)
28
- end
23
+ class MILLI_TIME
29
24
 
25
+ def self.from_compact!(input)
26
+ self.new(input.getI64!)
30
27
  end
31
28
 
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
29
+ def set(value)
30
+ if value
31
+ raise
32
+ elsif self.class.opt?
33
+ @value = nil
34
+ else
35
+ raise
46
36
  end
37
+ end
47
38
 
48
- def initialize(value)
49
- if value
50
- set(value)
51
- else
52
- @value = nil
53
- end
54
- end
39
+ def get
40
+ @value
41
+ end
55
42
 
56
- def to_compact(out)
57
- out.putI64(@value)
43
+ def initialize(value)
44
+ if value
45
+ set(value)
46
+ else
47
+ @value = nil
58
48
  end
49
+ end
59
50
 
51
+ def to_compact(out)
52
+ out.putI64(@value)
60
53
  end
54
+
61
55
 
62
56
  end
63
57
 
64
- module NANO_TIME
58
+ class NANO_TIME < MILLI_TIME
59
+
65
60
 
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
61
  end
77
62
 
78
63
  end
@@ -19,113 +19,100 @@
19
19
 
20
20
  module SlowBlink::Message
21
21
 
22
- module TIME_OF_DAY_MILLI
22
+ class TIME_OF_DAY_MILLI
23
23
 
24
- module CLASS
25
-
26
- def from_compact!(input)
27
- self.new(input.get32!)
28
- end
29
-
24
+ def self.from_compact!(input)
25
+ self.new(input.get32!)
30
26
  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
27
+
28
+ def set(value)
29
+ if value
30
+ if value.kind_of? Integer
31
+ if value < 86400000
32
+ @value = value
44
33
  else
45
- raise "what is this?"
46
- end
47
- elsif self.class.opt?
48
- @value = nil
34
+ raise Error.new "input out of range"
35
+ end
36
+ elsif value.kind_of? Time
37
+ @value = value.to_i
49
38
  else
50
- raise
51
- end
39
+ raise "what is this?"
40
+ end
41
+ elsif self.class.opt?
42
+ @value = nil
43
+ else
44
+ raise
52
45
  end
46
+ end
53
47
 
54
- def get
55
- @value
56
- end
48
+ def get
49
+ @value
50
+ end
57
51
 
58
- def initialize(value)
59
- if value
60
- set(value)
61
- else
62
- @value = nil
63
- end
52
+ def initialize(value)
53
+ if value
54
+ set(value)
55
+ else
56
+ @value = nil
64
57
  end
58
+ end
65
59
 
66
- # @private
67
- def to_compact(out)
68
- out.putU32(@value)
69
-
60
+ # @private
61
+ def to_compact(out)
62
+ out.putU32(@value)
70
63
 
71
-
72
- end
73
64
 
74
- end
65
+
66
+ end
67
+
68
+
75
69
 
76
70
  end
77
71
 
78
- module TIME_OF_DAY_NANO
79
-
80
- module CLASS
81
-
82
- def from_compact!(input)
83
- self.new(input.getU64!)
84
- end
85
-
72
+ class TIME_OF_DAY_NANO
73
+
74
+ def self.from_compact!(input)
75
+ self.new(input.getU64!)
86
76
  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
77
+
78
+ def set(value)
79
+ if value
80
+ if value.kind_of? Integer
81
+ if value < 86400000000000
82
+ @value = value
101
83
  else
102
- raise "what is this?"
103
- end
104
- elsif self.class.opt?
105
- @value = nil
84
+ raise Error.new "input out of range"
85
+ end
86
+ elsif value.kind_of? Time
87
+ @value = value.to_i
106
88
  else
107
- raise
108
- end
89
+ raise "what is this?"
90
+ end
91
+ elsif self.class.opt?
92
+ @value = nil
93
+ else
94
+ raise
109
95
  end
96
+ end
110
97
 
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
98
+ def get
99
+ @value
100
+ end
101
+
102
+ def initialize(value)
103
+ if value
104
+ set(value)
105
+ else
106
+ @value = nil
121
107
  end
122
-
123
- # @private
124
- def to_compact(out)
125
- out.putU64(@value)
126
- end
127
-
128
108
  end
109
+
110
+ # @private
111
+ def to_compact(out)
112
+ out.putU64(@value)
113
+ end
114
+
115
+
129
116
 
130
117
  end
131
118
 
@@ -25,12 +25,9 @@ module SlowBlink
25
25
  # @return [String]
26
26
  attr_reader :name
27
27
 
28
- # @return [Integer]
29
- # @return [nil]
28
+ # @return [Integer,nil]
30
29
  attr_reader :id
31
30
 
32
- # @private
33
- #
34
31
  # @param name [String]
35
32
  # @param id [nil,Integer]
36
33
  def initialize(name, id)
@@ -39,8 +36,7 @@ module SlowBlink
39
36
  @id = id
40
37
  end
41
38
 
42
- # @private
43
- #
39
+ # @api private
44
40
  # @param value [Integer]
45
41
  def id=(value)
46
42
  @id = id
@@ -37,13 +37,13 @@ module SlowBlink
37
37
 
38
38
  # @!method self.parse(input, **opts)
39
39
  #
40
+ # @api private
41
+ #
40
42
  # @param input [String] Blink Schema
41
43
  # @param opts [Hash] options
42
44
  # @option opts [String] :fileName filename to append to error message strings
43
45
  # @return [Namespace]
44
46
 
45
- # @private
46
- #
47
47
  # @param filename [nil,String]
48
48
  # @param name [nil,String]
49
49
  # @param defs [Array<Definition,Group>]
@@ -57,7 +57,7 @@ module SlowBlink
57
57
  @name = name
58
58
  @schema = nil
59
59
 
60
- errors = 0
60
+ error = false
61
61
 
62
62
  # populate table of definitions
63
63
  # gather list of groups and incrAnnotations
@@ -67,8 +67,8 @@ module SlowBlink
67
67
  @incrAnnotations << d
68
68
  else
69
69
  if @definitions[d.nameWithID.name]
70
- puts "#{d.location}: error: duplicate definition name '#{d.nameWithID.name}' (first defined at #{definitions[d.nameWithID.name].location})"
71
- errors += 1
70
+ Log.error "#{d.location}: error: definitions must have unique names ('#{d.nameWithID.name}' first appears at #{definitions[d.nameWithID.name].location})"
71
+ error = true
72
72
  else
73
73
  @definitions[d.nameWithID.name] = d
74
74
  if d.is_a? Group
@@ -79,47 +79,45 @@ module SlowBlink
79
79
  end
80
80
  end
81
81
 
82
- if errors > 0
82
+ if error
83
83
  raise
84
84
  end
85
85
 
86
86
  end
87
87
 
88
+ # @api private
89
+ #
88
90
  # @param namespace [Namespace]
89
91
  def merge!(namespace)
90
- if namespace.name == @name
91
- @incrAnnotations.concat(namespace.incrAnnotations)
92
- namespace.definitions.each do |d|
93
- if @definitions[d.nameWithID.name]
94
- puts "#{d.location}: error: duplicate definition name '#{d.nameWithID.name}' (first defined at #{definitions[d.nameWithID.name].location})"
95
- errors += 1
96
- else
97
- @definitions[d.nameWithID.name] = d
98
- if d.is_a? Group
99
- @groups << d
100
- end
101
- end
102
- end
103
- else
104
- raise "error: cannot merge different namespaces"
105
- end
92
+ @incrAnnotations.concat(namespace.incrAnnotations)
93
+ namespace.definitions.each do |d|
94
+ if @definitions[d.nameWithID.name]
95
+ Log.error "#{d.location}: error: definitions must have unique names ('#{d.nameWithID.name}' first appears at #{definitions[d.nameWithID.name].location})"
96
+ raise
97
+ else
98
+ @definitions[d.nameWithID.name] = d
99
+ if d.is_a? Group
100
+ @groups << d
101
+ end
102
+ end
103
+ end
106
104
  end
107
105
 
108
- # @param schema [Schema] common schema
109
- # @param stack [Array] used to detect cycles
110
- def link(schema, stack=[])
111
- if @schema.nil?
112
- errors = 0
113
- @definitions.each do |name, d|
114
- if !d.link(schema, stack.dup << self)
115
- errors += 1
116
- end
117
- end
118
- if errors == 0
119
- @schema = schema
120
- end
106
+ # @api private
107
+ #
108
+ # Resolve references, enforce constraints, and detect cycles
109
+ #
110
+ # @param schema [Schema] schema this definition belongs to
111
+ # @param stack [nil, Array] objects that depend on this object
112
+ # @return [true,false] linked?
113
+ def link(schema, stack=[])
114
+ errors = 0
115
+ @definitions.each do |name, d|
116
+ if !d.link(schema, stack.dup << self)
117
+ errors += 1
118
+ end
121
119
  end
122
- @schema
120
+ errors == 0
123
121
  end
124
122
 
125
123
  # @param name [String] unqualified name
@@ -128,6 +126,8 @@ module SlowBlink
128
126
  @definitions[name]
129
127
  end
130
128
 
129
+ # @param name [String]
130
+ # @return [Group,nil]
131
131
  def group(name)
132
132
  @groups.detect{|g|g.nameWithID.name == name}
133
133
  end
@@ -30,11 +30,16 @@ module SlowBlink
30
30
  @dynamic
31
31
  end
32
32
 
33
+ # Either this reference is dynamic or an intermediate reference is dynamic
34
+ #
35
+ # @return [true,false]
36
+ def dynamic_reference?
37
+ @dynamic or @dynamic_reference
38
+ end
39
+
33
40
  # @return [String]
34
41
  attr_reader :qname
35
42
 
36
- # @private
37
- #
38
43
  # @param qname [String]
39
44
  # @param dynamic [true,false]
40
45
  # @param location [String]
@@ -49,12 +54,18 @@ module SlowBlink
49
54
  end
50
55
  @dynamic = dynamic
51
56
  @ref = nil
57
+ @dynamic_reference = false
52
58
  super(location)
53
59
  end
54
60
 
55
- # @private
56
- #
57
- # @macro common_link
61
+ # @api private
62
+ #
63
+ # Resolve references, enforce constraints, and detect cycles
64
+ #
65
+ # @param schema [Schema] schema this definition belongs to
66
+ # @param ns [Namespace] namespace this definition belongs to
67
+ # @param stack [nil, Array] objects that depend on this object
68
+ # @return [true,false] linked?
58
69
  def link(schema, ns, stack=[])
59
70
  if @schema.nil?
60
71
  if @namespace
@@ -63,25 +74,30 @@ module SlowBlink
63
74
  ref = ns.resolve(@name) or schema.resolve(@namespace, @name)
64
75
  end
65
76
  if ref and ref.link(schema, stack << self)
66
- # follow reference to get type
77
+ # follow reference
67
78
  loop do
68
- if ref.kind_of? Definition and ref.type.kind_of? REF
69
- ref = ref.type.ref
70
- else
71
- if !ref.kind_of? Group
79
+ if ref.kind_of? Definition
80
+ if ref.type.kind_of? REF
81
+ if ref.type.dynamic?
82
+ @dynamic_reference = true
83
+ end
84
+ ref = ref.type.ref
85
+ next
86
+ else
72
87
  ref = ref.type
73
88
  end
74
- break
75
89
  end
90
+ break
76
91
  end
92
+
77
93
  if @dynamic and !ref.kind_of? Group
78
- puts "#{@location}: error: '#{@qname}' must resolve to a group with an ID"
94
+ Log.error "#{@location}: error: a dynamic reference must resolve to a group that has an identifier"
79
95
  else
80
96
  @ref = ref
81
97
  @schema = schema
82
98
  end
83
99
  else
84
- puts "#{@location}: error: '#{@qname}' is not defined in schema"
100
+ Log.error "#{@location}: error: unresolved reference ('#{@qname}' is not defined as a group, type, or enum)"
85
101
  end
86
102
  end
87
103
  @schema