slow_blink 0.0.1 → 0.0.2

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.
@@ -0,0 +1,46 @@
1
+ # Copyright (c) 2016 Cameron Harper
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ # this software and associated documentation files (the "Software"), to deal in
5
+ # the Software without restriction, including without limitation the rights to
6
+ # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7
+ # the Software, and to permit persons to whom the Software is furnished to do so,
8
+ # subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in all
11
+ # copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15
+ # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
+ # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18
+ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19
+
20
+ module SlowBlink
21
+ module Annotatable
22
+
23
+ # @return [Array<Annotation>]
24
+ attr_reader :annotes
25
+
26
+ # @private
27
+ #
28
+ # @param annotes [Array<Annotation,Integer>]
29
+ def annote(annotes)
30
+ annotes.each do |a|
31
+ if a.is_a? Annotation
32
+ if @annotes[a.id]
33
+ puts "#{a.location}: warning: overriding previous annotation for id '#{a.id}'"
34
+ end
35
+ @annotes[a.id] = a
36
+ else
37
+ if @nameWithID.id
38
+ puts "#{a.location}: warning: overriding previous id"
39
+ end
40
+ @nameWithID.id = a
41
+ end
42
+ end
43
+ end
44
+
45
+ end
46
+ end
@@ -0,0 +1,38 @@
1
+ # Copyright (c) 2016 Cameron Harper
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ # this software and associated documentation files (the "Software"), to deal in
5
+ # the Software without restriction, including without limitation the rights to
6
+ # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7
+ # the Software, and to permit persons to whom the Software is furnished to do so,
8
+ # subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in all
11
+ # copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15
+ # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
+ # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18
+ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19
+
20
+ module SlowBlink
21
+ class Annotation
22
+
23
+ attr_reader :location
24
+ attr_reader :id
25
+ attr_reader :literal
26
+
27
+ # @param id [String] any string
28
+ # @param literal [String] any string
29
+ # @param location [String]
30
+ def initialize(id,literal,location)
31
+ @id = id
32
+ @literal = literal
33
+ @location = location
34
+ end
35
+
36
+ end
37
+ end
38
+
@@ -0,0 +1,97 @@
1
+ # Copyright (c) 2016 Cameron Harper
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ # this software and associated documentation files (the "Software"), to deal in
5
+ # the Software without restriction, including without limitation the rights to
6
+ # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7
+ # the Software, and to permit persons to whom the Software is furnished to do so,
8
+ # subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in all
11
+ # copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15
+ # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
+ # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18
+ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19
+
20
+ # SlowBlink
21
+ module SlowBlink
22
+
23
+ module CompactEncoder
24
+
25
+ # @return [String]
26
+ def self.putNull
27
+ "\x40"
28
+ end
29
+
30
+ # @return [String]
31
+ def self.putPresent
32
+ "\x01"
33
+ end
34
+
35
+ def self.putBool(value)
36
+ (value) ? "\x01" : "\x00"
37
+ end
38
+
39
+ # @param value [Float]
40
+ # @return [String]
41
+ def self.putF64(value)
42
+ putVLC([value].pack("G").unpack("Q<").first)
43
+ end
44
+
45
+ def self.putString(value)
46
+ putVLC(value.size) + value
47
+ end
48
+
49
+ def self.putBinary(value)
50
+ putVLC(value.size) + value.to_s
51
+ end
52
+
53
+ def self.putFixed(value)
54
+ value.to_s
55
+ end
56
+
57
+
58
+
59
+
60
+
61
+ # @private
62
+ #
63
+ # @param value [Integer] unsigned integer
64
+ # @return [Integer] bytes to encode as VLC
65
+ def self.getSizeUnsigned(value)
66
+ end
67
+
68
+ # @private
69
+ #
70
+ # @param value [Integer] signed integer
71
+ # @return [Integer] bytes to encode as VLC
72
+ def self.getSizeSigned(value)
73
+ end
74
+
75
+ # @private
76
+ #
77
+ # @param value [Integer] signed or unsigned integer
78
+ # @param opts [Hash] option
79
+ # @option opts [Symbol] :signed value is a signed integer
80
+ def self.putVLC(value, **opts)
81
+ bytes = opts[:signed] ? getSizeSigned(value) : getSizeUnsigned(value)
82
+ case bytes
83
+ when 1
84
+ [value].pack("C")
85
+ when 2
86
+ [0x80 | value].pack("S<")
87
+ else
88
+ out = [0xc0 | bytes]
89
+ while out.size < (bytes - 1) do
90
+ out << (value >> 8)
91
+ end
92
+ out.pack("S<C#{bytes-2}")
93
+ end
94
+ end
95
+ end
96
+
97
+ end
@@ -0,0 +1,50 @@
1
+ # Copyright (c) 2016 Cameron Harper
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ # this software and associated documentation files (the "Software"), to deal in
5
+ # the Software without restriction, including without limitation the rights to
6
+ # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7
+ # the Software, and to permit persons to whom the Software is furnished to do so,
8
+ # subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in all
11
+ # copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15
+ # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
+ # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18
+ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19
+
20
+ module SlowBlink
21
+
22
+ # SCHEMA
23
+ class SchemaRef
24
+ end
25
+
26
+ # qName
27
+ class DefinitionRef < SchemaRef
28
+ # @param qName [String] name of the definition to annotate
29
+ def initialize(qName)
30
+ @qName = qName
31
+ end
32
+ end
33
+
34
+ # qName.TYPE
35
+ class DefinitionTypeRef < DefinitionRef
36
+ end
37
+
38
+ # qName.name
39
+ class FieldRef < SchemaRef
40
+ def initialize(qName, name)
41
+ @qName = qName
42
+ @name = name
43
+ end
44
+ end
45
+
46
+ # qName.name.TYPE
47
+ class FieldTypeRef < FieldRef
48
+ end
49
+
50
+ end
@@ -0,0 +1,57 @@
1
+ # Copyright (c) 2016 Cameron Harper
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ # this software and associated documentation files (the "Software"), to deal in
5
+ # the Software without restriction, including without limitation the rights to
6
+ # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7
+ # the Software, and to permit persons to whom the Software is furnished to do so,
8
+ # subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in all
11
+ # copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15
+ # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
+ # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18
+ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19
+
20
+ module SlowBlink
21
+ class Definition
22
+
23
+ include Annotatable
24
+ extend CompactEncoder
25
+
26
+ # @return [String]
27
+ attr_reader :location
28
+
29
+ # @return [String]
30
+ attr_reader :nameWithID
31
+
32
+ # @return [Enumeration]
33
+ # @return [Type]
34
+ attr_reader :enumOrType
35
+
36
+ # @private
37
+ #
38
+ # @param nameWithID [NameWithID]
39
+ # @param enumOrType [Enumeration, Type]
40
+ # @param location [String]
41
+ def initialize(nameWithID, enumOrType, location)
42
+ @annotes = {}
43
+ @schema = nil
44
+ @enumOrType = enumOrType
45
+ @location = location
46
+ @nameWithID = nameWithID
47
+ end
48
+
49
+ # @private
50
+ #
51
+ # @!macro common_link
52
+ def link(schema, stack=[])
53
+ @schema = @enumOrType.link(schema, stack << self)
54
+ end
55
+
56
+ end
57
+ end
@@ -0,0 +1,105 @@
1
+ # Copyright (c) 2016 Cameron Harper
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ # this software and associated documentation files (the "Software"), to deal in
5
+ # the Software without restriction, including without limitation the rights to
6
+ # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7
+ # the Software, and to permit persons to whom the Software is furnished to do so,
8
+ # subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in all
11
+ # copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15
+ # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
+ # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18
+ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19
+
20
+ module SlowBlink
21
+
22
+ class Enumeration
23
+
24
+ include Annotatable
25
+ extend CompactEncoder
26
+
27
+ # @private
28
+ #
29
+ # @param syms [Array<Sym>] symbol list
30
+ def initialize(syms)
31
+ @annotes = {}
32
+ @rawSyms = syms
33
+ @syms = {}
34
+ @schema = nil
35
+ end
36
+
37
+ def ===(other)
38
+ self.class == other.class
39
+ end
40
+
41
+ # @private
42
+ #
43
+ # @macro common_link
44
+ def link(schema, stack=[])
45
+ if @schema != schema
46
+ @schema = nil
47
+ value = 0
48
+ errors = 0
49
+ @syms = {}
50
+ @rawSyms.each do |s|
51
+ if @syms[s.name]
52
+ puts "#{s.location}: error: duplicate name"
53
+ errors += 1
54
+ else
55
+ if s.val
56
+ if @syms.values.include? s.val
57
+ puts "#{s.location}: error: duplicate value"
58
+ errors += 1
59
+ else
60
+ value = s.val + 1
61
+ end
62
+ else
63
+ @syms[s.name] = value
64
+ value += 1
65
+ end
66
+ end
67
+ end
68
+ if errors == 0
69
+ @schema = schema
70
+ end
71
+ end
72
+ @schema
73
+ end
74
+
75
+ # @param nameOrVal [String,Integer]
76
+ # @return [Sym]
77
+ # @return [nil]
78
+ def sym(nameOrVal)
79
+ if key.kind_of? String
80
+ @syms[key.to_s]
81
+ else
82
+ @syms.detect{|s|s.val == s.to_i}
83
+ end
84
+ end
85
+
86
+ # @private
87
+ def validate(input)
88
+ if sym(input)
89
+ true
90
+ else
91
+ raise
92
+ end
93
+ end
94
+
95
+ # @private
96
+ def encode_compact(value, **opts)
97
+ if opts[:opt]
98
+ putPresent + putVLC(value)
99
+ else
100
+ putVLC(value)
101
+ end
102
+ end
103
+
104
+ end
105
+ end
@@ -0,0 +1,4 @@
1
+ module SlowBlink
2
+ class Error < Exception
3
+ end
4
+ end
@@ -0,0 +1,82 @@
1
+ # Copyright (c) 2016 Cameron Harper
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ # this software and associated documentation files (the "Software"), to deal in
5
+ # the Software without restriction, including without limitation the rights to
6
+ # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7
+ # the Software, and to permit persons to whom the Software is furnished to do so,
8
+ # subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in all
11
+ # copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15
+ # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
+ # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18
+ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19
+
20
+ module SlowBlink
21
+
22
+ class Field
23
+
24
+ include Annotatable
25
+ extend CompactEncoder
26
+
27
+ # @return [String]
28
+ attr_reader :location
29
+
30
+ # @return [Type]
31
+ attr_reader :type
32
+
33
+ # @return [NameWithID]
34
+ attr_reader :nameWithID
35
+
36
+ # @return [true] field is optional
37
+ # @return [false] field is mandatory
38
+ def opt?
39
+ @opt
40
+ end
41
+
42
+ # @private
43
+ #
44
+ # @param nameWithID [NameWithID]
45
+ # @param type [Type]
46
+ # @param opt [true,false] field is optional?
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
55
+ end
56
+
57
+ # @private
58
+ #
59
+ # @!macro common_link
60
+ def link(schema,stack=[])
61
+ if @schema != schema
62
+ @schema = nil
63
+ if @type.link(schema, stack << self)
64
+ @schema = schema
65
+ end
66
+ end
67
+ @schema
68
+ end
69
+
70
+ # @private
71
+ def encode_compact(value, **opts)
72
+ if value[name]
73
+ @type.encode_compact(value[:name], opt: @opt)
74
+ elsif @opt
75
+ putNull
76
+ else
77
+ raise
78
+ end
79
+ end
80
+
81
+ end
82
+ end
@@ -0,0 +1,129 @@
1
+ # Copyright (c) 2016 Cameron Harper
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ # this software and associated documentation files (the "Software"), to deal in
5
+ # the Software without restriction, including without limitation the rights to
6
+ # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7
+ # the Software, and to permit persons to whom the Software is furnished to do so,
8
+ # subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in all
11
+ # copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15
+ # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
+ # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18
+ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19
+
20
+ module SlowBlink
21
+
22
+ class Group
23
+
24
+ include Annotatable
25
+ extend CompactEncoder
26
+
27
+ # @return [String]
28
+ attr_reader :location
29
+
30
+ # @return [NameWithID]
31
+ attr_reader :nameWithID
32
+
33
+ # @private
34
+ #
35
+ # @param nameWithID [NameWithID]
36
+ # @param superGroup [REF, nil]
37
+ # @param fields [Array<Field>]
38
+ # @param location [String]
39
+ def initialize(nameWithID, superGroup, fields, location)
40
+ @annotes = {}
41
+ @schema = nil
42
+ @superGroup = superGroup
43
+ @rawFields = fields
44
+ @location = location
45
+ @fields = []
46
+ @nameWithID = nameWithID
47
+ end
48
+
49
+ # @private
50
+ #
51
+ # @macro common_link
52
+ def link(schema,stack=[])
53
+ if @schema != schema
54
+ errors = 0
55
+ @schema = nil
56
+ @fields = {}
57
+ if !@superGroup or (@superGroup and @superGroup.link(schema, stack << self))
58
+ if !@superGroup or @superGroup.value.is_a?(Group)
59
+ if @superGroup
60
+ @fields.merge(@superGroup.value.fields)
61
+ end
62
+ @rawFields.each do |f|
63
+ if @fields[f.nameWithID.name]
64
+ puts "#{f.location}: error: field with duplicate name '#{f.nameWithID.name}'"
65
+ errors += 1
66
+ else
67
+ if f.link(schema, stack.dup << self)
68
+ @fields[f.nameWithID.name] = f
69
+ else
70
+ errors += 1
71
+ end
72
+ end
73
+ end
74
+ if errors == 0
75
+ @schema = schema
76
+ end
77
+ else
78
+ puts "#{@superGroup.location}: error: superGroup must be a group"
79
+ end
80
+ end
81
+ end
82
+ @schema
83
+ end
84
+
85
+ # @param name [String] name of field
86
+ # @return [Field] field exists
87
+ # @return [nil] field does not exist
88
+ def field(name)
89
+ @fields[name]
90
+ end
91
+
92
+ def fields
93
+ @fields
94
+ end
95
+
96
+ # @private
97
+ def validate(value)
98
+ if value.kind_of? Hash
99
+ if value["$type"] == @nameWithID.name
100
+ @fields.each do |name,f|
101
+ f.validate(value[name])
102
+ end
103
+ true
104
+ else
105
+ raise
106
+ end
107
+ end
108
+ end
109
+
110
+ # @private
111
+ #
112
+ # @param value [Hash] Blink JSON format
113
+ # @param opts [Hash] options
114
+ # @option opts [Symbol] :dynamic encode as dynamic group
115
+ # @return [String] compact format
116
+ def encode_compact(value, **opts)
117
+ out = ""
118
+ @fields.each do |name, f|
119
+ out << f.encode_compact(value)
120
+ end
121
+ if opts[:dynamic]
122
+ putVLC(@nameWithID.id) + putVLC(out.size) + out
123
+ else
124
+ out
125
+ end
126
+ end
127
+
128
+ end
129
+ end