slow_blink 0.0.4 → 0.0.5

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 (36) hide show
  1. checksums.yaml +4 -4
  2. data/ext/slow_blink/ext_schema_parser/lexer.c +168 -177
  3. data/ext/slow_blink/ext_schema_parser/lexer.h +1 -1
  4. data/ext/slow_blink/ext_schema_parser/parser.c +303 -306
  5. data/ext/slow_blink/ext_schema_parser/parser.h +11 -12
  6. data/ext/slow_blink/{ext_compact_encoder → message/ext_compact_encoder}/ext_compact_encoder.c +3 -1
  7. data/ext/slow_blink/message/ext_compact_encoder/extconf.rb +4 -0
  8. data/lib/slow_blink/error.rb +1 -1
  9. data/lib/slow_blink/message/binary.rb +19 -26
  10. data/lib/slow_blink/message/boolean.rb +17 -17
  11. data/lib/slow_blink/message/date.rb +24 -0
  12. data/lib/slow_blink/message/decimal.rb +34 -0
  13. data/lib/slow_blink/message/enumeration.rb +24 -23
  14. data/lib/slow_blink/message/field.rb +45 -6
  15. data/lib/slow_blink/message/fixed.rb +35 -25
  16. data/lib/slow_blink/message/floating_point.rb +16 -17
  17. data/lib/slow_blink/message/group.rb +242 -136
  18. data/lib/slow_blink/message/integer.rb +77 -51
  19. data/lib/slow_blink/message/model.rb +121 -85
  20. data/lib/slow_blink/message/sequence.rb +43 -28
  21. data/lib/slow_blink/message/string.rb +17 -31
  22. data/lib/slow_blink/message/time.rb +55 -17
  23. data/lib/slow_blink/message/time_of_day.rb +40 -50
  24. data/lib/slow_blink/schema.rb +17 -6
  25. data/lib/slow_blink/version.rb +1 -1
  26. data/rakefile +12 -7
  27. data/test/tc_incr_annote.rb +16 -0
  28. data/test/tc_inputs.rb +2 -2
  29. data/test/tc_model_dynamic_group.rb +105 -0
  30. data/test/tc_model_extension.rb +143 -0
  31. data/test/tc_model_static_group.rb +27 -36
  32. data/test/tc_model_think_blink.rb +18 -35
  33. metadata +12 -9
  34. data/ext/slow_blink/ext_compact_encoder/extconf.rb +0 -4
  35. /data/ext/slow_blink/{ext_compact_encoder → message/ext_compact_encoder}/compact_encoder.c +0 -0
  36. /data/ext/slow_blink/{ext_compact_encoder → message/ext_compact_encoder}/compact_encoder.h +0 -0
@@ -67,18 +67,17 @@ extern int yydebug;
67
67
  TOK_TYPE = 277,
68
68
  TOK_SCHEMA = 278,
69
69
  TOK_BINARY = 279,
70
- TOK_NUMBER = 280,
71
- TOK_FIXED = 281,
72
- TOK_LEFT_ARROW = 282,
73
- TOK_RIGHT_ARROW = 283,
74
- TOK_HEX = 284,
75
- TOK_UINT = 285,
76
- TOK_INT = 286,
77
- TOK_NAME = 287,
78
- TOK_NC_NAME = 288,
79
- TOK_ESCAPED_NC_NAME = 289,
80
- TOK_C_NAME = 290,
81
- TOK_LITERAL = 291
70
+ TOK_FIXED = 280,
71
+ TOK_LEFT_ARROW = 281,
72
+ TOK_RIGHT_ARROW = 282,
73
+ TOK_HEX = 283,
74
+ TOK_UINT = 284,
75
+ TOK_INT = 285,
76
+ TOK_NAME = 286,
77
+ TOK_NC_NAME = 287,
78
+ TOK_ESCAPED_NC_NAME = 288,
79
+ TOK_C_NAME = 289,
80
+ TOK_LITERAL = 290
82
81
  };
83
82
  #endif
84
83
 
@@ -97,8 +97,10 @@ void Init_ext_compact_encoder(void)
97
97
  {
98
98
  VALUE cSlowBlink;
99
99
 
100
+ rb_require("slow_blink/message/model.rb");
101
+
100
102
  cSlowBlink = rb_define_module("SlowBlink");
101
- cError = rb_const_get(cSlowBlink, rb_intern("Error"));
103
+ cError = rb_const_get(rb_define_module_under(cSlowBlink, "Message"), rb_intern("Error"));
102
104
 
103
105
  rb_define_method(rb_cString, "putNull", putNull, 0);
104
106
  rb_define_method(rb_cString, "putPresent", putPresent, 0);
@@ -0,0 +1,4 @@
1
+ require 'mkmf'
2
+ $CFLAGS += " -std=c99"
3
+ create_makefile('slow_blink/message/ext_compact_encoder')
4
+
@@ -18,6 +18,6 @@
18
18
  # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19
19
 
20
20
  module SlowBlink
21
- class Error < Exception
21
+ class Error < StandardError
22
22
  end
23
23
  end
@@ -21,11 +21,7 @@ module SlowBlink::Message
21
21
 
22
22
  class BINARY
23
23
 
24
- def self.opt?
25
- @opt
26
- end
27
-
28
- def self.from_compact!(input)
24
+ def self.from_compact!(input, stack)
29
25
  value = input.getBinary!
30
26
  if value
31
27
  if !@size or value.size <= @size
@@ -33,39 +29,38 @@ module SlowBlink::Message
33
29
  else
34
30
  raise Error.new "W8: Binary value exceeds maximum size"
35
31
  end
36
- elsif @opt
37
- self.new(nil)
38
32
  else
39
- raise Error.new "W5: Value cannot be null"
40
- end
33
+ value
34
+ end
41
35
  end
42
36
 
37
+ # @return [Integer,nil] maximum size of string in bytes
43
38
  def self.size
44
39
  @type.size
45
40
  end
46
41
 
42
+ # @return [String]
43
+ def get
44
+ @value
45
+ end
46
+
47
+ # Set a binary value
48
+ # @param value [String]
49
+ # @raise [TypeError]
50
+ # @raise [RangeError] value is larger than {::size}
47
51
  def set(value)
48
- if value
49
- if value.kind_of? String
50
- if !self.class.size or value.size <= self.class.size
51
- @value = value
52
- else
53
- raise Error.new "string cannot be larger than #{self.class.size} bytes"
54
- end
52
+ if value.kind_of? String
53
+ if !self.class.size or value.size <= self.class.size
54
+ @value = value.to_s
55
55
  else
56
- raise Error.new "expecting a string type"
56
+ raise RangeError.new "String instance cannot be larger than #{self.class.size} bytes"
57
57
  end
58
- elsif self.class.opt?
59
- @value = nil
60
58
  else
61
- raise Error.new "string cannot be null"
59
+ raise TypeError.new "expecting a String instance"
62
60
  end
63
61
  end
64
62
 
65
- def get
66
- @value
67
- end
68
-
63
+ # @note calls {#set}(value)
69
64
  def initialize(value)
70
65
  set(value)
71
66
  end
@@ -74,8 +69,6 @@ module SlowBlink::Message
74
69
  out.putBinary(@value)
75
70
  end
76
71
 
77
-
78
-
79
72
  end
80
73
 
81
74
  end
@@ -21,36 +21,36 @@ module SlowBlink::Message
21
21
 
22
22
  class BOOLEAN
23
23
 
24
- def self.from_compact!(input)
25
- self.new(input.getBool!)
26
- end
27
-
28
- def set(value)
24
+ def self.from_compact!(input, stack)
25
+ value = input.getBool!
29
26
  if value
30
- if value.kind_of? TrueClass or value.kind_of? FalseClass
31
- @value = value
32
- else
33
- raise "expecting true/false"
34
- end
35
- elsif self.class.opt?
36
- @value = nil
27
+ self.new(value)
37
28
  else
38
- raise Error.new "value unacceptable"
29
+ value
39
30
  end
40
31
  end
41
32
 
33
+ # @return [TrueClass,FalseClass]
42
34
  def get
43
35
  @value
44
36
  end
45
37
 
46
- def initialize(value)
47
- if value
48
- set(value)
38
+ # Set a boolean value
39
+ # @param value [TrueClass,FalseClass]
40
+ # @raise [TypeError] value must be literally TrueClass or FalseClass
41
+ def set(value)
42
+ if value.kind_of? TrueClass or value.kind_of? FalseClass
43
+ @value = value
49
44
  else
50
- @value = nil
45
+ raise TypeError.new "expecting true/false"
51
46
  end
52
47
  end
53
48
 
49
+ # @note calls {#set}(value)
50
+ def initialize(value)
51
+ set(value)
52
+ end
53
+
54
54
  def to_compact(out)
55
55
  out.putBool(@value)
56
56
  end
@@ -21,6 +21,30 @@ module SlowBlink::Message
21
21
 
22
22
  class DATE
23
23
 
24
+ def self.from_compact!(input, stack)
25
+ value = input.getI32!
26
+ if value
27
+ self.new(value)
28
+ else
29
+ value
30
+ end
31
+ end
32
+
33
+ def get
34
+ @value
35
+ end
36
+
37
+ def set(value)
38
+ raise Error.new "type not supported"
39
+ end
40
+
41
+ def initialize(value)
42
+ set(value)
43
+ end
44
+
45
+ def to_compact(out)
46
+ out.putI32(@value.strftime('%Q'))
47
+ end
24
48
 
25
49
  end
26
50
 
@@ -17,9 +17,43 @@
17
17
  # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18
18
  # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19
19
 
20
+ require 'bigdecimal'
21
+
20
22
  module SlowBlink::Message
21
23
 
22
24
  class DECIMAL
25
+
26
+ def self.from_compact!(input, stack)
27
+ e = input.getI8!
28
+ if e
29
+ m = input.getI64!
30
+ if m
31
+ self.new("#{m}E#{e}")
32
+ else
33
+ raise "a null mantissa is not defined"
34
+ end
35
+ else
36
+ nil
37
+ end
38
+ end
39
+
40
+ def initialize(value)
41
+ set(value)
42
+ end
43
+
44
+ def get
45
+ @value
46
+ end
47
+
48
+ def set(value)
49
+ @value = BigDecimal.new(value.to_s)
50
+ end
51
+
52
+ def to_compact(out)
53
+ out.putI8(@value.exponent)
54
+ out.putI64(0)
55
+ end
56
+
23
57
  end
24
58
 
25
59
  end
@@ -21,43 +21,44 @@ module SlowBlink::Message
21
21
 
22
22
  class ENUMERATION
23
23
 
24
-
25
-
26
- def self.from_compact!(input)
27
- self.new(input.getU32!)
24
+ # @return [Hash] symbol => value table
25
+ def self.symbols
26
+ @symbols
28
27
  end
29
28
 
30
-
31
-
32
- # @param v [String]
33
- def set(value)
29
+ def self.from_compact!(input, stack)
30
+ value = input.getU32!
34
31
  if value
35
- if self.symbols[value]
36
- @value = self.class.symbols[value]
37
- else
38
- raise Error.new "symbol '#{value}' not defined in enumeration"
39
- end
40
- elsif self.class.opt?
41
- @value = nil
32
+ self.new(value)
42
33
  else
43
- raise Error.new "field may not be null"
44
- end
34
+ value
35
+ end
45
36
  end
46
37
 
38
+ # @return [String]
47
39
  def get
48
40
  @value
49
41
  end
50
42
 
51
- def initialize(value)
52
- if value
53
- set(value)
43
+ # Set a symbol
44
+ # @param value [String] symbol in enumeration
45
+ # @raise [RangeError] value is not valid symbol
46
+ def set(value)
47
+ if @symbols[value]
48
+ @value = value.to_s
54
49
  else
55
- @value = nil
56
- end
50
+ raise RangeError.new "symbol '#{value}' not defined in enumeration"
51
+ end
52
+ end
53
+
54
+ # @note calls {#set}(value)
55
+ def initialize(value)
56
+ @symbols = self.class.symbols
57
+ set(value)
57
58
  end
58
59
 
59
60
  def to_compact(out)
60
- out.putU32(@value ? self.class.symbols[@value] : nil)
61
+ out.putU32(@symbols[@value])
61
62
  end
62
63
 
63
64
  end
@@ -36,28 +36,67 @@ module SlowBlink::Message
36
36
  @id
37
37
  end
38
38
 
39
+ # @return [Object] type contained by field
39
40
  def self.type
40
41
  @type
41
42
  end
42
43
 
43
- def self.from_compact!(input)
44
- @type.from_compact!(input)
44
+ # @param input [String] Blink compact form
45
+ # @param stack [Array]
46
+ # @return [Field] instance of anonymous subclass of Field
47
+ def self.from_compact!(input, stack)
48
+ self.new(@type.from_compact!(input, stack))
45
49
  end
46
50
 
51
+ # @note calls {#set}(value)
47
52
  def initialize(value)
48
- @value = self.class.type.new(value)
53
+ @opt = self.class.opt?
54
+ @type = self.class.type
55
+ if value.is_a? self.class.type
56
+ @value = value
57
+ elsif value
58
+ @value = self.class.type.new(value)
59
+ else
60
+ @value = nil
61
+ end
49
62
  end
50
63
 
64
+
51
65
  def set(value)
52
- @value.set(value)
66
+ if value
67
+ if value.is_a? self.class.type
68
+ @value = value
69
+ elsif @value
70
+ @value.set(value)
71
+ else
72
+ @value = self.class.type.new(value)
73
+ end
74
+ elsif @opt
75
+ @value = nil
76
+ else
77
+ raise TypeError.new "field can not be set to null"
78
+ end
53
79
  end
54
80
 
81
+ # @return field value or nil
55
82
  def get
56
- @value.get
83
+ if @value
84
+ @value.get
85
+ else
86
+ nil
87
+ end
57
88
  end
58
89
 
90
+ # @param out [String] output appended to this string
91
+ # @return [String]
59
92
  def to_compact(out)
60
- @value.to_compact(out)
93
+ if @value
94
+ @value.to_compact(out)
95
+ elsif @opt
96
+ out.putNull
97
+ else
98
+ raise Error.new "field '#{self.name}' must not be null"
99
+ end
61
100
  end
62
101
 
63
102
  end
@@ -20,51 +20,61 @@
20
20
  module SlowBlink::Message
21
21
 
22
22
  class FIXED
23
+
24
+ # @note optionality affects how instances of this type are encoded
25
+ #
26
+ # @return [true,false] is optional
27
+ def self.opt?
28
+ @opt
29
+ end
23
30
 
24
- def self.from_compact!(input)
25
- if opt?
26
- self.new(input.getFixedOptional!)
31
+ def self.from_compact!(input, stack)
32
+ if @opt
33
+ value = input.getFixedOptional!
34
+ else
35
+ value = input.getFixed!
36
+ end
37
+ if value
38
+ self.new(value)
27
39
  else
28
- self.new(input.getFixed!)
40
+ value
29
41
  end
30
42
  end
31
43
 
44
+ # @return [Integer,nil] size of fixed type in bytes
32
45
  def self.size
33
46
  @type.size
34
47
  end
35
48
 
49
+ # @return [String]
50
+ def get
51
+ @value
52
+ end
53
+
54
+ # Set a fixed size type
55
+ # @param value [String]
56
+ # @raise [RangeError]
57
+ # @raise [TypeError]
36
58
  def set(value)
37
- if value
38
- if value.kind_of? String
39
- if value.size == self.class.size
40
- @value = value
41
- else
42
- raise Error.new "must be #{@size} bytes"
43
- end
59
+ if value.kind_of? String
60
+ if value.size == self.class.size
61
+ @value = value.to_s
44
62
  else
45
- raise "expecting string"
63
+ raise RangeError.new "String instance must have size of #{@size} bytes"
46
64
  end
47
- elsif self.class.opt?
48
- @value = nil
49
65
  else
50
- raise Error.new "value unacceptable"
66
+ raise TypeError.new "expecting a String instance"
51
67
  end
52
68
  end
53
69
 
54
- def get
55
- @value
56
- end
57
-
70
+ # @note calls {#set}(value)
58
71
  def initialize(value)
59
- if value
60
- set(value)
61
- else
62
- @value = nil
63
- end
72
+ @opt = self.class.opt?
73
+ set(value)
64
74
  end
65
75
 
66
76
  def to_compact(out)
67
- if self.opt?
77
+ if @opt
68
78
  out.putFixedOptional(@value)
69
79
  else
70
80
  out.putFixed(@value)
@@ -21,36 +21,35 @@ module SlowBlink::Message
21
21
 
22
22
  class FLOATING_POINT
23
23
 
24
- def self.from_compact!(input)
25
- self.new(input.getF64!)
26
- end
27
-
28
- def set(value)
24
+ def self.from_compact!(input, stack)
25
+ value = input.getF64!
29
26
  if value
30
- if value.kind_of? Numeric
31
- @value = value
32
- else
33
- raise "expecting float"
34
- end
35
- elsif self.class.opt?
36
- @value = nil
27
+ self.new(value)
37
28
  else
38
- raise Error.new "value unacceptable"
29
+ value
39
30
  end
40
31
  end
41
32
 
33
+ # @return [Numeric]
42
34
  def get
43
35
  @value
44
36
  end
45
37
 
46
- def initialize(value)
47
- if value
48
- set(value)
38
+ # @param value [Numeric]
39
+ # @raise [TypeError]
40
+ def set(value)
41
+ if value.kind_of? Numeric
42
+ @value = value.to_f
49
43
  else
50
- @value = nil
44
+ raise TypeError.new "expecting an instance of Numeric"
51
45
  end
52
46
  end
53
47
 
48
+ # @note calls {#set}(value)
49
+ def initialize(value)
50
+ set(value)
51
+ end
52
+
54
53
  def to_compact(out)
55
54
  out.putF64(@value)
56
55
  end