transit-ruby 0.8.552-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,115 @@
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
+ ESC_ESC = "#{ESC}#{ESC}"
20
+ ESC_SUB = "#{ESC}#{SUB}"
21
+ ESC_RES = "#{ESC}#{RES}"
22
+
23
+ IDENTITY = ->(v){v}
24
+
25
+ GROUND_TAGS = %w[_ s ? i d b ' array map]
26
+
27
+ def initialize(options={})
28
+ custom_handlers = options[:handlers] || {}
29
+ custom_handlers.each {|k,v| validate_handler(k,v)}
30
+ @handlers = ReadHandlers::DEFAULT_READ_HANDLERS.merge(custom_handlers)
31
+ @default_handler = options[:default_handler] || ReadHandlers::DEFAULT_READ_HANDLER
32
+ end
33
+
34
+ # @api private
35
+ class Tag < String; end
36
+
37
+ # Decodes a transit value to a corresponding object
38
+ #
39
+ # @param node a transit value to be decoded
40
+ # @param cache
41
+ # @param as_map_key
42
+ # @return decoded object
43
+ def decode(node, cache=RollingCache.new, as_map_key=false)
44
+ case node
45
+ when String
46
+ if cache.has_key?(node)
47
+ cache.read(node)
48
+ else
49
+ parsed = begin
50
+ if !node.start_with?(ESC)
51
+ node
52
+ elsif node.start_with?(TAG)
53
+ Tag.new(node[2..-1])
54
+ elsif handler = @handlers[node[1]]
55
+ handler.from_rep(node[2..-1])
56
+ elsif node.start_with?(ESC_ESC, ESC_SUB, ESC_RES)
57
+ node[1..-1]
58
+ else
59
+ @default_handler.from_rep(node[1], node[2..-1])
60
+ end
61
+ end
62
+ if cache.cacheable?(node, as_map_key)
63
+ cache.write(parsed)
64
+ end
65
+ parsed
66
+ end
67
+ when Array
68
+ return node if node.empty?
69
+ e0 = decode(node.shift, cache, false)
70
+ if e0 == MAP_AS_ARRAY
71
+ decode(Hash[*node], cache)
72
+ elsif Tag === e0
73
+ v = decode(node.shift, cache)
74
+ if handler = @handlers[e0]
75
+ handler.from_rep(v)
76
+ else
77
+ @default_handler.from_rep(e0,v)
78
+ end
79
+ else
80
+ [e0] + node.map {|e| decode(e, cache, as_map_key)}
81
+ end
82
+ when Hash
83
+ if node.size == 1
84
+ k = decode(node.keys.first, cache, true)
85
+ v = decode(node.values.first, cache, false)
86
+ if Tag === k
87
+ if handler = @handlers[k]
88
+ handler.from_rep(v)
89
+ else
90
+ @default_handler.from_rep(k,v)
91
+ end
92
+ else
93
+ {k => v}
94
+ end
95
+ else
96
+ node.keys.each do |k|
97
+ node.store(decode(k, cache, true), decode(node.delete(k), cache))
98
+ end
99
+ node
100
+ end
101
+ else
102
+ node
103
+ end
104
+ end
105
+
106
+ def validate_handler(key, handler)
107
+ raise ArgumentError.new(CAN_NOT_OVERRIDE_GROUND_TYPES_MESSAGE) if GROUND_TAGS.include?(key)
108
+ end
109
+
110
+ CAN_NOT_OVERRIDE_GROUND_TYPES_MESSAGE = <<-MSG
111
+ You can not supply custom read handlers for ground types.
112
+ MSG
113
+
114
+ end
115
+ end
@@ -0,0 +1,179 @@
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
+ # @api private
21
+ module Base
22
+ def parse_options(opts)
23
+ @cache_enabled = !opts[:verbose]
24
+ @prefer_strings = opts[:prefer_strings]
25
+ @max_int = opts[:max_int]
26
+ @min_int = opts[:min_int]
27
+
28
+ handlers = WriteHandlers::DEFAULT_WRITE_HANDLERS.dup
29
+ handlers = handlers.merge!(opts[:handlers]) if opts[:handlers]
30
+ @handlers = (opts[:verbose] ? verbose_handlers(handlers) : handlers)
31
+ @handlers.values.each do |h|
32
+ if h.respond_to?(:handlers=)
33
+ h.handlers=(@handlers)
34
+ end
35
+ end
36
+ end
37
+
38
+ def find_handler(obj)
39
+ obj.class.ancestors.each do |a|
40
+ if handler = @handlers[a]
41
+ return handler
42
+ end
43
+ end
44
+ nil
45
+ end
46
+
47
+ def verbose_handlers(handlers)
48
+ handlers.each do |k, v|
49
+ if v.respond_to?(:verbose_handler) && vh = v.verbose_handler
50
+ handlers.store(k, vh)
51
+ end
52
+ end
53
+ handlers
54
+ end
55
+
56
+ def escape(s)
57
+ if s.start_with?(SUB,ESC,RES) && s != "#{SUB} "
58
+ "#{ESC}#{s}"
59
+ else
60
+ s
61
+ end
62
+ end
63
+
64
+ def emit_nil(as_map_key, cache)
65
+ as_map_key ? emit_string(ESC, "_", nil, true, cache) : emit_value(nil)
66
+ end
67
+
68
+ def emit_string(prefix, tag, value, as_map_key, cache)
69
+ encoded = "#{prefix}#{tag}#{value}"
70
+ if @cache_enabled && cache.cacheable?(encoded, as_map_key)
71
+ emit_value(cache.write(encoded), as_map_key)
72
+ else
73
+ emit_value(encoded, as_map_key)
74
+ end
75
+ end
76
+
77
+ def emit_boolean(handler, b, as_map_key, cache)
78
+ as_map_key ? emit_string(ESC, "?", handler.string_rep(b), true, cache) : emit_value(b)
79
+ end
80
+
81
+ def emit_int(tag, i, as_map_key, cache)
82
+ if as_map_key || i > @max_int || i < @min_int
83
+ emit_string(ESC, tag, i, as_map_key, cache)
84
+ else
85
+ emit_value(i, as_map_key)
86
+ end
87
+ end
88
+
89
+ def emit_double(d, as_map_key, cache)
90
+ as_map_key ? emit_string(ESC, "d", d, true, cache) : emit_value(d)
91
+ end
92
+
93
+ def emit_array(a, cache)
94
+ emit_array_start(a.size)
95
+ a.each {|e| marshal(e, false, cache)}
96
+ emit_array_end
97
+ end
98
+
99
+ def emit_map(m, cache)
100
+ emit_map_start(m.size)
101
+ m.each do |k,v|
102
+ marshal(k, true, cache)
103
+ marshal(v, false, cache)
104
+ end
105
+ emit_map_end
106
+ end
107
+
108
+ def emit_tagged_value(tag, rep, cache)
109
+ emit_array_start(2)
110
+ emit_string(ESC, "#", tag, false, cache)
111
+ marshal(rep, false, cache)
112
+ emit_array_end
113
+ end
114
+
115
+ def emit_encoded(handler, tag, obj, as_map_key, cache)
116
+ if tag.length == 1
117
+ rep = handler.rep(obj)
118
+ if String === rep
119
+ emit_string(ESC, tag, rep, as_map_key, cache)
120
+ elsif as_map_key || @prefer_strings
121
+ if str_rep = handler.string_rep(obj)
122
+ emit_string(ESC, tag, str_rep, as_map_key, cache)
123
+ else
124
+ raise "Cannot be encoded as String: " + {:tag => tag, :rep => rep, :obj => obj}.to_s
125
+ end
126
+ else
127
+ emit_tagged_value(tag, handler.rep(obj), cache)
128
+ end
129
+ elsif as_map_key
130
+ raise "Cannot be used as a map key: " + {:tag => tag, :rep => rep, :obj => obj}.to_s
131
+ else
132
+ emit_tagged_value(tag, handler.rep(obj), cache)
133
+ end
134
+ end
135
+
136
+ def marshal(obj, as_map_key, cache)
137
+ handler = find_handler(obj)
138
+ tag = handler.tag(obj)
139
+ case tag
140
+ when "_"
141
+ emit_nil(as_map_key, cache)
142
+ when "?"
143
+ emit_boolean(handler, obj, as_map_key, cache)
144
+ when "s"
145
+ emit_string(nil, nil, escape(handler.rep(obj)), as_map_key, cache)
146
+ when "i"
147
+ emit_int(tag, handler.rep(obj), as_map_key, cache)
148
+ when "d"
149
+ emit_double(handler.rep(obj), as_map_key, cache)
150
+ when "'"
151
+ emit_tagged_value(tag, handler.rep(obj), cache)
152
+ when "array"
153
+ emit_array(handler.rep(obj), cache)
154
+ when "map"
155
+ emit_map(handler.rep(obj), cache)
156
+ else
157
+ emit_encoded(handler, tag, obj, as_map_key, cache)
158
+ end
159
+ end
160
+
161
+ def marshal_top(obj, cache=RollingCache.new)
162
+ if handler = find_handler(obj)
163
+ if tag = handler.tag(obj)
164
+ if tag.length == 1
165
+ marshal(TaggedValue.new(QUOTE, obj), false, cache)
166
+ else
167
+ marshal(obj, false, cache)
168
+ end
169
+ flush
170
+ else
171
+ raise "Handler must provide a non-nil tag: #{handler.inspect}"
172
+ end
173
+ else
174
+ raise "Can not find a Write Handler for #{obj.inspect}."
175
+ end
176
+ end
177
+ end
178
+ end
179
+ end
@@ -0,0 +1,46 @@
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
+ module JsonBase
19
+ def default_opts
20
+ {:prefer_strings => true,
21
+ :max_int => JSON_MAX_INT,
22
+ :min_int => JSON_MIN_INT}
23
+ end
24
+ end
25
+
26
+ # @api private
27
+ class Json
28
+ include Transit::Marshaler::Base
29
+ include Transit::Marshaler::JsonBase
30
+
31
+ def initialize(io, opts)
32
+ parse_options(default_opts.merge(opts))
33
+ end
34
+ end
35
+
36
+ # @api private
37
+ class VerboseJson
38
+ include Transit::Marshaler::Base
39
+ include Transit::Marshaler::JsonBase
40
+
41
+ def initialize(io, opts)
42
+ parse_options(default_opts.merge(opts))
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,31 @@
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 default_opts
21
+ {:prefer_strings => false,
22
+ :max_int => MAX_INT,
23
+ :min_int => MIN_INT}
24
+ end
25
+
26
+ def initialize(io, opts)
27
+ parse_options(default_opts.merge(opts))
28
+ end
29
+ end
30
+ end
31
+ 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