xnlogic-transit-ruby 0.8.572-java

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,39 @@
1
+ # Copyright 2014 Cognitect. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS-IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ module Transit
16
+ # @api private
17
+ module DateTimeUtil
18
+ def to_millis(v)
19
+ case v
20
+ when DateTime
21
+ t = v.new_offset(0).to_time
22
+ when Date
23
+ t = Time.gm(v.year, v.month, v.day)
24
+ when Time
25
+ t = v
26
+ else
27
+ raise "Don't know how to get millis from #{t.inspect}"
28
+ end
29
+ (t.to_i * 1000) + (t.usec / 1000.0).round
30
+ end
31
+
32
+ def from_millis(millis)
33
+ t = Time.at(millis / 1000).utc
34
+ DateTime.new(t.year, t.month, t.day, t.hour, t.min, t.sec + (millis % 1000 * 0.001))
35
+ end
36
+
37
+ module_function :to_millis, :from_millis
38
+ end
39
+ end
@@ -0,0 +1,123 @@
1
+ # Copyright 2014 Cognitect. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS-IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ module Transit
16
+ # Converts a transit value to an instance of a type
17
+ # @api private
18
+ class Decoder
19
+ MUTEX = Mutex.new
20
+ HANDLER_CACHE = {}
21
+
22
+ ESC_ESC = "#{ESC}#{ESC}"
23
+ ESC_SUB = "#{ESC}#{SUB}"
24
+ ESC_RES = "#{ESC}#{RES}"
25
+
26
+ IDENTITY = ->(v){v}
27
+
28
+ GROUND_TAGS = %w[_ s ? i d b ' array map]
29
+
30
+ def initialize(options={})
31
+ custom_handlers = options[:handlers] || {}
32
+ custom_handlers.each {|k,v| validate_handler(k,v)}
33
+ MUTEX.synchronize do
34
+ if HANDLER_CACHE.has_key?(custom_handlers)
35
+ @handlers = HANDLER_CACHE[custom_handlers]
36
+ else
37
+ @handlers = ReadHandlers::DEFAULT_READ_HANDLERS.merge(custom_handlers)
38
+ end
39
+
40
+ end
41
+ @default_handler = options[:default_handler] || ReadHandlers::DEFAULT_READ_HANDLER
42
+ end
43
+
44
+ # @api private
45
+ class Tag < String; end
46
+
47
+ # Decodes a transit value to a corresponding object
48
+ #
49
+ # @param node a transit value to be decoded
50
+ # @param cache
51
+ # @param as_map_key
52
+ # @return decoded object
53
+ def decode(node, cache=RollingCache.new, as_map_key=false)
54
+ case node
55
+ when String
56
+ if cache.has_key?(node)
57
+ cache.read(node)
58
+ else
59
+ parsed = if !node.start_with?(ESC)
60
+ node
61
+ elsif node.start_with?(TAG)
62
+ Tag.new(node[2..-1])
63
+ elsif handler = @handlers[node[1]]
64
+ handler.from_rep(node[2..-1])
65
+ elsif node.start_with?(ESC_ESC, ESC_SUB, ESC_RES)
66
+ node[1..-1]
67
+ else
68
+ @default_handler.from_rep(node[1], node[2..-1])
69
+ end
70
+ if cache.cacheable?(node, as_map_key)
71
+ cache.write(parsed)
72
+ end
73
+ parsed
74
+ end
75
+ when Array
76
+ return node if node.empty?
77
+ e0 = decode(node.shift, cache, false)
78
+ if e0 == MAP_AS_ARRAY
79
+ decode(Hash[*node], cache)
80
+ elsif Tag === e0
81
+ v = decode(node.shift, cache)
82
+ if handler = @handlers[e0]
83
+ handler.from_rep(v)
84
+ else
85
+ @default_handler.from_rep(e0,v)
86
+ end
87
+ else
88
+ [e0] + node.map {|e| decode(e, cache, as_map_key)}
89
+ end
90
+ when Hash
91
+ if node.size == 1
92
+ k = decode(node.keys.first, cache, true)
93
+ v = decode(node.values.first, cache, false)
94
+ if Tag === k
95
+ if handler = @handlers[k]
96
+ handler.from_rep(v)
97
+ else
98
+ @default_handler.from_rep(k,v)
99
+ end
100
+ else
101
+ {k => v}
102
+ end
103
+ else
104
+ node.keys.each do |k|
105
+ node.store(decode(k, cache, true), decode(node.delete(k), cache))
106
+ end
107
+ node
108
+ end
109
+ else
110
+ node
111
+ end
112
+ end
113
+
114
+ def validate_handler(key, handler)
115
+ raise ArgumentError.new(CAN_NOT_OVERRIDE_GROUND_TYPES_MESSAGE) if GROUND_TAGS.include?(key)
116
+ end
117
+
118
+ CAN_NOT_OVERRIDE_GROUND_TYPES_MESSAGE = <<-MSG
119
+ You can not supply custom read handlers for ground types.
120
+ MSG
121
+
122
+ end
123
+ end
@@ -0,0 +1,193 @@
1
+ # Copyright 2014 Cognitect. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS-IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ module Transit
16
+ # Transit::Writer marshals Ruby objects as transit values to an output stream.
17
+ # @see https://github.com/cognitect/transit-format
18
+ module Marshaler
19
+
20
+ HANDLER_CACHE = {}
21
+ VERBOSE_HANDLER_CACHE = {}
22
+ MUTEX = Mutex.new
23
+
24
+ # @api private
25
+ # Included in VerboseJson subclasses. Defined here to make it
26
+ # available in CRuby and JRuby environments.
27
+ module VerboseHandlers
28
+ def build_handlers(custom_handlers)
29
+ if VERBOSE_HANDLER_CACHE.has_key?(custom_handlers)
30
+ VERBOSE_HANDLER_CACHE[custom_handlers]
31
+ else
32
+ handlers = super(custom_handlers).reduce({}) do |h, (k,v)|
33
+ if v.respond_to?(:verbose_handler) && vh = v.verbose_handler
34
+ h.store(k, vh)
35
+ else
36
+ h.store(k, v)
37
+ end
38
+ h
39
+ end
40
+ VERBOSE_HANDLER_CACHE[custom_handlers] = handlers
41
+ handlers
42
+ end
43
+ end
44
+ end
45
+
46
+ # @api private
47
+ module Base
48
+ def parse_options(opts)
49
+ MUTEX.synchronize do
50
+ @handlers = build_handlers(opts[:handlers])
51
+ end
52
+ @handlers.values.each { |h| h.handlers=(@handlers) if h.respond_to?(:handlers=) }
53
+ end
54
+
55
+ def build_handlers(custom_handlers)
56
+ if HANDLER_CACHE.has_key?(custom_handlers)
57
+ HANDLER_CACHE[custom_handlers]
58
+ else
59
+ handlers = WriteHandlers::DEFAULT_WRITE_HANDLERS.dup
60
+ handlers.merge!(custom_handlers) if custom_handlers
61
+ HANDLER_CACHE[custom_handlers] = handlers
62
+ handlers
63
+ end
64
+ end
65
+
66
+ def find_handler(obj)
67
+ obj.class.ancestors.each do |a|
68
+ if handler = @handlers[a]
69
+ return handler
70
+ end
71
+ end
72
+ nil
73
+ end
74
+
75
+ def escape(s)
76
+ if s.start_with?(SUB,ESC,RES) && s != "#{SUB} "
77
+ "#{ESC}#{s}"
78
+ else
79
+ s
80
+ end
81
+ end
82
+
83
+ def emit_nil(as_map_key, cache)
84
+ as_map_key ? emit_string(ESC, "_", nil, true, cache) : emit_value(nil)
85
+ end
86
+
87
+ def emit_string(prefix, tag, value, as_map_key, cache)
88
+ encoded = "#{prefix}#{tag}#{value}"
89
+ if cache.cacheable?(encoded, as_map_key)
90
+ emit_value(cache.write(encoded), as_map_key)
91
+ else
92
+ emit_value(encoded, as_map_key)
93
+ end
94
+ end
95
+
96
+ def emit_boolean(handler, b, as_map_key, cache)
97
+ as_map_key ? emit_string(ESC, "?", handler.string_rep(b), true, cache) : emit_value(b)
98
+ end
99
+
100
+ def emit_double(d, as_map_key, cache)
101
+ as_map_key ? emit_string(ESC, "d", d, true, cache) : emit_value(d)
102
+ end
103
+
104
+ def emit_array(a, cache)
105
+ emit_array_start(a.size)
106
+ a.each {|e| marshal(e, false, cache)}
107
+ emit_array_end
108
+ end
109
+
110
+ def emit_map(m, cache)
111
+ emit_map_start(m.size)
112
+ m.each do |k,v|
113
+ marshal(k, true, cache)
114
+ marshal(v, false, cache)
115
+ end
116
+ emit_map_end
117
+ end
118
+
119
+ def emit_tagged_value(tag, rep, cache)
120
+ emit_array_start(2)
121
+ emit_string(ESC, "#", tag, false, cache)
122
+ marshal(rep, false, cache)
123
+ emit_array_end
124
+ end
125
+
126
+ def emit_encoded(handler, tag, obj, as_map_key, cache)
127
+ if tag.length == 1
128
+ rep = handler.rep(obj)
129
+ if String === rep
130
+ emit_string(ESC, tag, rep, as_map_key, cache)
131
+ elsif as_map_key || @prefer_strings
132
+ if str_rep = handler.string_rep(obj)
133
+ emit_string(ESC, tag, str_rep, as_map_key, cache)
134
+ else
135
+ raise "Cannot be encoded as String: " + {:tag => tag, :rep => rep, :obj => obj}.to_s
136
+ end
137
+ else
138
+ emit_tagged_value(tag, handler.rep(obj), cache)
139
+ end
140
+ elsif as_map_key
141
+ raise "Cannot be used as a map key: " + {:tag => tag, :rep => rep, :obj => obj}.to_s
142
+ else
143
+ emit_tagged_value(tag, handler.rep(obj), cache)
144
+ end
145
+ end
146
+
147
+ def marshal(obj, as_map_key, cache)
148
+ if handler = find_handler(obj)
149
+ tag = handler.tag(obj)
150
+ case tag
151
+ when "_"
152
+ emit_nil(as_map_key, cache)
153
+ when "?"
154
+ emit_boolean(handler, obj, as_map_key, cache)
155
+ when "s"
156
+ emit_string(nil, nil, escape(handler.rep(obj)), as_map_key, cache)
157
+ when "i"
158
+ emit_int(tag, handler.rep(obj), as_map_key, cache)
159
+ when "d"
160
+ emit_double(handler.rep(obj), as_map_key, cache)
161
+ when "'"
162
+ emit_tagged_value(tag, handler.rep(obj), cache)
163
+ when "array"
164
+ emit_array(handler.rep(obj), cache)
165
+ when "map"
166
+ emit_map(handler.rep(obj), cache)
167
+ else
168
+ emit_encoded(handler, tag, obj, as_map_key, cache)
169
+ end
170
+ else
171
+ raise "Can not find a Write Handler for #{obj.inspect}."
172
+ end
173
+ end
174
+
175
+ def marshal_top(obj, cache=RollingCache.new)
176
+ if handler = find_handler(obj)
177
+ if tag = handler.tag(obj)
178
+ if tag.length == 1
179
+ marshal(TaggedValue.new(QUOTE, obj), false, cache)
180
+ else
181
+ marshal(obj, false, cache)
182
+ end
183
+ flush
184
+ else
185
+ raise "Handler must provide a non-nil tag: #{handler.inspect}"
186
+ end
187
+ else
188
+ raise "Can not find a Write Handler for #{obj.inspect}."
189
+ end
190
+ end
191
+ end
192
+ end
193
+ end
@@ -0,0 +1,38 @@
1
+ # Copyright 2014 Cognitect. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS-IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ module Transit
16
+ module Marshaler
17
+
18
+ # @api private
19
+ module JsonBase
20
+ def initialize(io, opts)
21
+ parse_options(opts)
22
+ end
23
+ end
24
+
25
+ # @api private
26
+ class Json
27
+ include Transit::Marshaler::Base
28
+ include Transit::Marshaler::JsonBase
29
+ end
30
+
31
+ # @api private
32
+ class VerboseJson
33
+ include Transit::Marshaler::Base
34
+ include Transit::Marshaler::JsonBase
35
+ include Transit::Marshaler::VerboseHandlers
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,25 @@
1
+ # Copyright 2014 Cognitect. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS-IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ module Transit
16
+ module Marshaler
17
+ class MessagePack
18
+ include Transit::Marshaler::Base
19
+
20
+ def initialize(io, opts)
21
+ parse_options(opts)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,113 @@
1
+ # Copyright 2014 Cognitect. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS-IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ module Transit
16
+ # @see Transit::WriteHandlers
17
+ module ReadHandlers
18
+ class Default
19
+ def from_rep(tag,val) TaggedValue.new(tag, val) end
20
+ end
21
+ class NilHandler
22
+ def from_rep(_) nil end
23
+ end
24
+ class KeywordHandler
25
+ def from_rep(v) v.to_sym end
26
+ end
27
+ class BooleanHandler
28
+ def from_rep(v) v == "t" end
29
+ end
30
+ class ByteArrayHandler
31
+ def from_rep(v) ByteArray.from_base64(v) end
32
+ end
33
+ class FloatHandler
34
+ def from_rep(v) Float(v) end
35
+ end
36
+ class IntegerHandler
37
+ def from_rep(v) v.to_i end
38
+ end
39
+ class BigIntegerHandler
40
+ def from_rep(v) v.to_i end
41
+ end
42
+ class BigDecimalHandler
43
+ def from_rep(v) BigDecimal.new(v) end
44
+ end
45
+ class SpecialNumbersHandler
46
+ def from_rep(v)
47
+ case v
48
+ when "NaN" then Float::NAN
49
+ when "INF" then Float::INFINITY
50
+ when "-INF" then -Float::INFINITY
51
+ else raise ArgumentError.new("Don't know how to handle #{v.inspect} for the \"z\" tag")
52
+ end
53
+ end
54
+ end
55
+ class IdentityHandler
56
+ def from_rep(v) v end
57
+ end
58
+ class SymbolHandler
59
+ def from_rep(v) Transit::Symbol.new(v) end
60
+ end
61
+ class TimeStringHandler
62
+ def from_rep(v) DateTime.iso8601(v) end
63
+ end
64
+ class TimeIntHandler
65
+ def from_rep(v) DateTimeUtil.from_millis(v.to_i) end
66
+ end
67
+ class UuidHandler
68
+ def from_rep(v) UUID.new(v) end
69
+ end
70
+ class UriHandler
71
+ def from_rep(v) Addressable::URI.parse(v) end
72
+ end
73
+ class SetHandler
74
+ def from_rep(v) Set.new(v) end
75
+ end
76
+ class LinkHandler
77
+ def from_rep(v) Link.new(v) end
78
+ end
79
+ class CmapHandler
80
+ def from_rep(v) Hash[*v] end
81
+ end
82
+ class RatioHandler
83
+ def from_rep(v) Rational(v[0], v[1]) end
84
+ end
85
+
86
+ DEFAULT_READ_HANDLERS = {
87
+ "_" => NilHandler.new,
88
+ ":" => KeywordHandler.new,
89
+ "?" => BooleanHandler.new,
90
+ "b" => ByteArrayHandler.new,
91
+ "d" => FloatHandler.new,
92
+ "i" => IntegerHandler.new,
93
+ "n" => BigIntegerHandler.new,
94
+ "f" => BigDecimalHandler.new,
95
+ "c" => IdentityHandler.new,
96
+ "$" => SymbolHandler.new,
97
+ "t" => TimeStringHandler.new,
98
+ "m" => TimeIntHandler.new,
99
+ "u" => UuidHandler.new,
100
+ "r" => UriHandler.new,
101
+ "'" => IdentityHandler.new,
102
+ "z" => SpecialNumbersHandler.new,
103
+ "set" => SetHandler.new,
104
+ "link" => LinkHandler.new,
105
+ "list" => IdentityHandler.new,
106
+ "cmap" => CmapHandler.new,
107
+ "ratio" => RatioHandler.new
108
+ }.freeze
109
+
110
+ DEFAULT_READ_HANDLER = Default.new
111
+
112
+ end
113
+ end