slow_blink 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
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