transit-ruby 0.8.552-java

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