├── .gitignore
├── .rspec
├── .yard_redcarpet_ext
├── .yardopts
├── BUILD.md
├── CHANGELOG.md
├── CONTRIBUTING.md
├── DEV.md
├── Gemfile
├── Jarfile
├── LICENSE
├── README.md
├── Rakefile
├── TODO.org
├── benchmarks
├── decoding_time.rb
└── encoding_time.rb
├── bin
├── benchmark
├── read-transit
├── read-write
├── roundtrip
└── rspec-across-supported-versions
├── build
├── jruby_version
├── release
└── revision
├── dev
└── irb_tools.rb
├── ext
└── com
│ └── cognitect
│ └── transit
│ └── ruby
│ ├── TransitService.java
│ ├── TransitTypeConverter.java
│ ├── marshaler
│ ├── Base.java
│ ├── Json.java
│ ├── MessagePack.java
│ └── VerboseJson.java
│ └── unmarshaler
│ ├── Base.java
│ ├── Json.java
│ ├── MessagePack.java
│ ├── RubyArrayReader.java
│ ├── RubyMapReader.java
│ └── RubyReaders.java
├── lib
├── transit.rb
└── transit
│ ├── date_time_util.rb
│ ├── decoder.rb
│ ├── marshaler
│ ├── base.rb
│ ├── cruby
│ │ ├── json.rb
│ │ └── messagepack.rb
│ └── jruby
│ │ ├── json.rb
│ │ └── messagepack.rb
│ ├── read_handlers.rb
│ ├── reader.rb
│ ├── rolling_cache.rb
│ ├── transit_types.rb
│ ├── unmarshaler
│ └── cruby
│ │ ├── json.rb
│ │ └── messagepack.rb
│ ├── write_handlers.rb
│ └── writer.rb
├── spec
├── spec_helper.rb
└── transit
│ ├── date_time_util_spec.rb
│ ├── decoder_spec.rb
│ ├── exemplar_spec.rb
│ ├── marshaler_spec.rb
│ ├── reader_spec.rb
│ ├── rolling_cache_spec.rb
│ ├── round_trip_spec.rb
│ ├── transit_types_spec.rb
│ └── writer_spec.rb
└── transit-ruby.gemspec
/.gitignore:
--------------------------------------------------------------------------------
1 | *.gem
2 | *.rbc
3 | *.log
4 | .bundle
5 | .config
6 | coverage
7 | InstalledFiles
8 | lib/bundler/man
9 | pkg
10 | rdoc
11 | spec/reports
12 | test/tmp
13 | test/version_tmp
14 | tmp
15 |
16 | # YARD artifacts
17 | .yardoc
18 | _yardoc
19 | doc/
20 | .rbenv-version
21 | .rvm
22 | Gemfile.lock
23 | .ruby-version
24 | .ruby-gemset
25 | spec_helper-local.rb
26 | Gemfile-custom
27 |
28 | # lock_jar
29 | Jarfile.lock
30 |
31 | # IDE
32 | .classpath
33 | .project
34 | transit.jar
35 | /target/
36 |
--------------------------------------------------------------------------------
/.rspec:
--------------------------------------------------------------------------------
1 | --color
2 |
--------------------------------------------------------------------------------
/.yard_redcarpet_ext:
--------------------------------------------------------------------------------
1 | :tables
--------------------------------------------------------------------------------
/.yardopts:
--------------------------------------------------------------------------------
1 | --markup markdown
2 | -
3 | CHANGELOG.md
4 | LICENSE
5 |
--------------------------------------------------------------------------------
/BUILD.md:
--------------------------------------------------------------------------------
1 | ## Build (internal)
2 |
3 | ### Version
4 |
5 | The build version is automatically incremented. To determine the
6 | current build version:
7 |
8 | build/version
9 |
10 | ### Package
11 |
12 | gem install bundler
13 | bundle install
14 | bundle exec rake build
15 |
16 | ### Install locally
17 |
18 | bundle exec rake install
19 |
20 | ### Docs
21 |
22 | To build api documentation:
23 |
24 | gem install yard
25 | yard
26 |
27 | ### Release
28 |
29 | #### Pre-requisites:
30 |
31 | * permission to push gems to https://rubygems.org/gems/transit-ruby
32 | * public and private key files for MRI
33 |
34 | To sign the gem for MRI (currently disabled for JRuby), you'll need
35 | to generate public and private keys. Follow the directions from `gem
36 | cert -h` to generate the following files:
37 |
38 | ~/.gem/transit-ruby/gem-private_key.pem
39 | ~/.gem/transit-ruby/gem-public_cert.pem
40 |
41 | Once those are in place, you can run:
42 |
43 | ./build/release
44 |
45 | You'll be prompted to confirm MRI and JRuby releases and for cert
46 | passwords for the MRI version.
47 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ### 0.8.591 / 2015-05-03
2 |
3 | * Bump lock_jar dependency to ~> 0.12.0 #17
4 |
5 | ### 0.8.588 / 2015-04-10
6 |
7 | * Update to transit-java-0.8.287 for json int boundary fix in JRuby
8 |
9 | ### 0.8.586 / 2015-03-13
10 |
11 | * Add handler caching for MRI
12 | * Bump to transit-java-0.8.285 for handler caching in JRuby
13 |
14 | ### 0.8.572 / 2015-01-15
15 |
16 | * Marshal int map keys as ints in msgpack
17 |
18 | ### 0.8.569 / 2014-12-03
19 |
20 | * ByteArray#to_s forces default encoding for platform
21 | * fixes rare bug in which trying to print binary data nested within
22 | decoded binary data raises an encoding incompatibility error.
23 |
24 | ### 0.8.567 / 2014-09-21
25 |
26 | * restore newline suppression when writing in json mode
27 | * helpful error message when nested object has no handler
28 |
29 | ### 0.8.560 (java platform only) / 2014-09-12
30 |
31 | * Bump dependency on transit-java to 0.8.269
32 | * fixes bug which turned an empty set into an array
33 |
34 | ### 0.8.552 (java platform only) / 2014-09-12
35 |
36 | * Support JRuby!
37 |
38 | ### 0.8.539 / 2014-09-05
39 |
40 | * Support special numbers (NaN, INF, -INF)
41 |
42 | ### 0.8.467 / 2014-07-22
43 |
44 | * Initial release
45 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | ## Contributing
2 |
3 | This library is open source, developed internally by Cognitect. We welcome discussions of potential problems and enhancement suggestions on the [transit-format mailing list](https://groups.google.com/forum/#!forum/transit-format). Issues can be filed using GitHub [issues](https://github.com/cognitect/transit-ruby/issues) for this project. Because transit is incorporated into products and client projects, we prefer to do development internally and are not accepting pull requests or patches.
4 |
--------------------------------------------------------------------------------
/DEV.md:
--------------------------------------------------------------------------------
1 | ### Development setup
2 |
3 | gem install bundler
4 | bundle install
5 |
6 | Transit Ruby uses transit as a submodule to get at the transit
7 | exemplar files. The tests will not run without the exemplar files.
8 | You need to run a couple of git commands to set up the transit
9 | git submodule:
10 |
11 | git submodule init
12 | git submodule update
13 |
14 | ### Run rspec examples
15 |
16 | rspec
17 |
18 | ## Benchmarks
19 |
20 | ./bin/benchmark # reads transit data in json and json-verbose formats
21 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | # -*- ruby -*-
2 |
3 | source 'https://rubygems.org'
4 |
5 | gemspec
6 |
7 | # Gemfile-custom is .gitignored, but eval'd here so you can add
8 | # whatever dev tools you like to use to your local environment.
9 | eval File.read('Gemfile-custom') if File.exist?('Gemfile-custom')
10 |
--------------------------------------------------------------------------------
/Jarfile:
--------------------------------------------------------------------------------
1 | # -*- ruby -*-
2 |
3 | jruby_version=File.read("build/jruby_version").chomp
4 |
5 | # dependency to transit-java
6 | # this setup uses maven central for the repository
7 |
8 | jar "com.cognitect:transit-java:0.8.287"
9 |
10 | group 'development' do
11 | jar "org.jruby:jruby-complete:#{jruby_version}"
12 | end
13 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 |
2 | Apache License
3 | Version 2.0, January 2004
4 | http://www.apache.org/licenses/
5 |
6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7 |
8 | 1. Definitions.
9 |
10 | "License" shall mean the terms and conditions for use, reproduction,
11 | and distribution as defined by Sections 1 through 9 of this document.
12 |
13 | "Licensor" shall mean the copyright owner or entity authorized by
14 | the copyright owner that is granting the License.
15 |
16 | "Legal Entity" shall mean the union of the acting entity and all
17 | other entities that control, are controlled by, or are under common
18 | control with that entity. For the purposes of this definition,
19 | "control" means (i) the power, direct or indirect, to cause the
20 | direction or management of such entity, whether by contract or
21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
22 | outstanding shares, or (iii) beneficial ownership of such entity.
23 |
24 | "You" (or "Your") shall mean an individual or Legal Entity
25 | exercising permissions granted by this License.
26 |
27 | "Source" form shall mean the preferred form for making modifications,
28 | including but not limited to software source code, documentation
29 | source, and configuration files.
30 |
31 | "Object" form shall mean any form resulting from mechanical
32 | transformation or translation of a Source form, including but
33 | not limited to compiled object code, generated documentation,
34 | and conversions to other media types.
35 |
36 | "Work" shall mean the work of authorship, whether in Source or
37 | Object form, made available under the License, as indicated by a
38 | copyright notice that is included in or attached to the work
39 | (an example is provided in the Appendix below).
40 |
41 | "Derivative Works" shall mean any work, whether in Source or Object
42 | form, that is based on (or derived from) the Work and for which the
43 | editorial revisions, annotations, elaborations, or other modifications
44 | represent, as a whole, an original work of authorship. For the purposes
45 | of this License, Derivative Works shall not include works that remain
46 | separable from, or merely link (or bind by name) to the interfaces of,
47 | the Work and Derivative Works thereof.
48 |
49 | "Contribution" shall mean any work of authorship, including
50 | the original version of the Work and any modifications or additions
51 | to that Work or Derivative Works thereof, that is intentionally
52 | submitted to Licensor for inclusion in the Work by the copyright owner
53 | or by an individual or Legal Entity authorized to submit on behalf of
54 | the copyright owner. For the purposes of this definition, "submitted"
55 | means any form of electronic, verbal, or written communication sent
56 | to the Licensor or its representatives, including but not limited to
57 | communication on electronic mailing lists, source code control systems,
58 | and issue tracking systems that are managed by, or on behalf of, the
59 | Licensor for the purpose of discussing and improving the Work, but
60 | excluding communication that is conspicuously marked or otherwise
61 | designated in writing by the copyright owner as "Not a Contribution."
62 |
63 | "Contributor" shall mean Licensor and any individual or Legal Entity
64 | on behalf of whom a Contribution has been received by Licensor and
65 | subsequently incorporated within the Work.
66 |
67 | 2. Grant of Copyright License. Subject to the terms and conditions of
68 | this License, each Contributor hereby grants to You a perpetual,
69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 | copyright license to reproduce, prepare Derivative Works of,
71 | publicly display, publicly perform, sublicense, and distribute the
72 | Work and such Derivative Works in Source or Object form.
73 |
74 | 3. Grant of Patent License. Subject to the terms and conditions of
75 | this License, each Contributor hereby grants to You a perpetual,
76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77 | (except as stated in this section) patent license to make, have made,
78 | use, offer to sell, sell, import, and otherwise transfer the Work,
79 | where such license applies only to those patent claims licensable
80 | by such Contributor that are necessarily infringed by their
81 | Contribution(s) alone or by combination of their Contribution(s)
82 | with the Work to which such Contribution(s) was submitted. If You
83 | institute patent litigation against any entity (including a
84 | cross-claim or counterclaim in a lawsuit) alleging that the Work
85 | or a Contribution incorporated within the Work constitutes direct
86 | or contributory patent infringement, then any patent licenses
87 | granted to You under this License for that Work shall terminate
88 | as of the date such litigation is filed.
89 |
90 | 4. Redistribution. You may reproduce and distribute copies of the
91 | Work or Derivative Works thereof in any medium, with or without
92 | modifications, and in Source or Object form, provided that You
93 | meet the following conditions:
94 |
95 | (a) You must give any other recipients of the Work or
96 | Derivative Works a copy of this License; and
97 |
98 | (b) You must cause any modified files to carry prominent notices
99 | stating that You changed the files; and
100 |
101 | (c) You must retain, in the Source form of any Derivative Works
102 | that You distribute, all copyright, patent, trademark, and
103 | attribution notices from the Source form of the Work,
104 | excluding those notices that do not pertain to any part of
105 | the Derivative Works; and
106 |
107 | (d) If the Work includes a "NOTICE" text file as part of its
108 | distribution, then any Derivative Works that You distribute must
109 | include a readable copy of the attribution notices contained
110 | within such NOTICE file, excluding those notices that do not
111 | pertain to any part of the Derivative Works, in at least one
112 | of the following places: within a NOTICE text file distributed
113 | as part of the Derivative Works; within the Source form or
114 | documentation, if provided along with the Derivative Works; or,
115 | within a display generated by the Derivative Works, if and
116 | wherever such third-party notices normally appear. The contents
117 | of the NOTICE file are for informational purposes only and
118 | do not modify the License. You may add Your own attribution
119 | notices within Derivative Works that You distribute, alongside
120 | or as an addendum to the NOTICE text from the Work, provided
121 | that such additional attribution notices cannot be construed
122 | as modifying the License.
123 |
124 | You may add Your own copyright statement to Your modifications and
125 | may provide additional or different license terms and conditions
126 | for use, reproduction, or distribution of Your modifications, or
127 | for any such Derivative Works as a whole, provided Your use,
128 | reproduction, and distribution of the Work otherwise complies with
129 | the conditions stated in this License.
130 |
131 | 5. Submission of Contributions. Unless You explicitly state otherwise,
132 | any Contribution intentionally submitted for inclusion in the Work
133 | by You to the Licensor shall be under the terms and conditions of
134 | this License, without any additional terms or conditions.
135 | Notwithstanding the above, nothing herein shall supersede or modify
136 | the terms of any separate license agreement you may have executed
137 | with Licensor regarding such Contributions.
138 |
139 | 6. Trademarks. This License does not grant permission to use the trade
140 | names, trademarks, service marks, or product names of the Licensor,
141 | except as required for reasonable and customary use in describing the
142 | origin of the Work and reproducing the content of the NOTICE file.
143 |
144 | 7. Disclaimer of Warranty. Unless required by applicable law or
145 | agreed to in writing, Licensor provides the Work (and each
146 | Contributor provides its Contributions) on an "AS IS" BASIS,
147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148 | implied, including, without limitation, any warranties or conditions
149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150 | PARTICULAR PURPOSE. You are solely responsible for determining the
151 | appropriateness of using or redistributing the Work and assume any
152 | risks associated with Your exercise of permissions under this License.
153 |
154 | 8. Limitation of Liability. In no event and under no legal theory,
155 | whether in tort (including negligence), contract, or otherwise,
156 | unless required by applicable law (such as deliberate and grossly
157 | negligent acts) or agreed to in writing, shall any Contributor be
158 | liable to You for damages, including any direct, indirect, special,
159 | incidental, or consequential damages of any character arising as a
160 | result of this License or out of the use or inability to use the
161 | Work (including but not limited to damages for loss of goodwill,
162 | work stoppage, computer failure or malfunction, or any and all
163 | other commercial damages or losses), even if such Contributor
164 | has been advised of the possibility of such damages.
165 |
166 | 9. Accepting Warranty or Additional Liability. While redistributing
167 | the Work or Derivative Works thereof, You may choose to offer,
168 | and charge a fee for, acceptance of support, warranty, indemnity,
169 | or other liability obligations and/or rights consistent with this
170 | License. However, in accepting such obligations, You may act only
171 | on Your own behalf and on Your sole responsibility, not on behalf
172 | of any other Contributor, and only if You agree to indemnify,
173 | defend, and hold each Contributor harmless for any liability
174 | incurred by, or claims asserted against, such Contributor by reason
175 | of your accepting any such warranty or additional liability.
176 |
177 | END OF TERMS AND CONDITIONS
178 |
179 | APPENDIX: How to apply the Apache License to your work.
180 |
181 | To apply the Apache License to your work, attach the following
182 | boilerplate notice, with the fields enclosed by brackets "[]"
183 | replaced with your own identifying information. (Don't include
184 | the brackets!) The text should be enclosed in the appropriate
185 | comment syntax for the file format. We also recommend that a
186 | file or class name and description of purpose be included on the
187 | same "printed page" as the copyright notice for easier
188 | identification within third-party archives.
189 |
190 | Copyright [yyyy] [name of copyright owner]
191 |
192 | Licensed under the Apache License, Version 2.0 (the "License");
193 | you may not use this file except in compliance with the License.
194 | You may obtain a copy of the License at
195 |
196 | http://www.apache.org/licenses/LICENSE-2.0
197 |
198 | Unless required by applicable law or agreed to in writing, software
199 | distributed under the License is distributed on an "AS IS" BASIS,
200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201 | See the License for the specific language governing permissions and
202 | limitations under the License.
203 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # This library is no longer maintained. If you are interested in using or maintaining, please fork it and update according to the license.
2 |
3 |
4 | transit-ruby
5 | ===================
6 |
7 | Transit is a data format and a set of libraries for conveying
8 | values between applications written in different languages. This
9 | library provides support for marshalling Transit data to/from Ruby.
10 |
11 | [Rationale](http://blog.cognitect.com/blog/2014/7/22/transit)
12 | [API docs](http://rubydoc.info/gems/transit-ruby)
13 | [Specification](https://github.com/cognitect/transit-format)
14 |
15 | This implementation's major.minor version number corresponds to the
16 | version of the Transit specification it supports.
17 |
18 | _NOTE: Transit is intended primarily as a wire protocol for transferring data between applications. If storing Transit data durably, readers and writers are expected to use the same version of Transit and you are responsible for migrating/transforming/re-storing that data when and if the transit format changes._
19 |
20 | ## Contributing
21 |
22 | This library is open source, developed internally by Cognitect. We welcome discussions of potential problems and enhancement suggestions on the [transit-format mailing list](https://groups.google.com/forum/#!forum/transit-format). Issues can be filed using GitHub [issues](https://github.com/cognitect/transit-ruby/issues) for this project. Because transit is incorporated into products and client projects, we prefer to do development internally and are not accepting pull requests or patches.
23 |
24 | ## Releases and Dependency Information
25 |
26 | See https://rubygems.org/gems/transit-ruby
27 |
28 | ## Install
29 |
30 | ```sh
31 | gem install transit-ruby
32 | ```
33 |
34 | ## Basic Usage
35 |
36 | ```ruby
37 | # io can be any Ruby IO
38 |
39 | writer = Transit::Writer.new(:json, io) # or :json_verbose, :msgpack
40 | writer.write(value)
41 |
42 | reader = Transit::Reader.new(:json, io) # or :msgpack
43 | reader.read
44 |
45 | # or
46 |
47 | reader.read {|val| do_something_with(val)}
48 | ```
49 |
50 | For example:
51 |
52 | ```
53 | irb(2.1.1): io = StringIO.new('', 'w+')
54 | ==========> #
55 | irb(2.1.1): writer = Transit::Writer.new(:json, io)
56 | ==========> # nil
59 | irb(2.1.1): writer.write(123456789012345678901234567890)
60 | ==========> nil
61 | irb(2.1.1): io.string
62 | ==========> "[\"~#'\",\"abc\"]\n[\"~#'\",\"~n123456789012345678901234567890\"]\n"
63 | irb(2.1.1): reader = Transit::Reader.new(:json, StringIO.new(io.string))
64 | ==========> # {Point => PointWriteHandler.new})
106 | writer.write(Point.new(37,42))
107 |
108 | p io.string.chomp
109 | #=> "[\"~#point\",[37,42]]"
110 |
111 | reader = Transit::Reader.new(:json, StringIO.new(io.string),
112 | :handlers => {"point" => PointReadHandler.new})
113 | p reader.read
114 | #=> #
115 | ```
116 |
117 | See
118 | [Transit::WriteHandlers](http://rubydoc.info/gems/transit-ruby/Transit/WriteHandlers)
119 | for more info.
120 |
121 | ## Default Type Mapping
122 |
123 | |Transit type|Write accepts|Read returns|Example(write)|Example(read)|
124 | |------------|-------------|------------|--------------|-------------|
125 | |null|nil|nil|nil|nil|
126 | |string|String|String|"abc"|"abc"|
127 | |boolean|true, false|true, false|false|false|
128 | |integer|Integer|Integer|123|123|
129 | |decimal|Float|Float|123.456|123.456|
130 | |keyword|Symbol|Symbol|:abc|:abc|
131 | |symbol|Transit::Symbol|Transit::Symbol|Transit::Symbol.new("foo")|`#`|
132 | |big decimal|BigDecimal|BigDecimal|BigDecimal("2**64")|`#`|
133 | |big integer|Integer|Integer|2**128|340282366920938463463374607431768211456|
134 | |time|DateTime, Date, Time|DateTime|DateTime.now|`#`|
135 | |uri|Addressable::URI, URI|Addressable::URI|Addressable::URI.parse("http://example.com")|`#`|
136 | |uuid|Transit::UUID|Transit::UUID|Transit::UUID.new|`#`|
137 | |char|Transit::TaggedValue|String|Transit::TaggedValue.new("c", "a")|"a"|
138 | |array|Array|Array|[1, 2, 3]|[1, 2, 3]|
139 | |list|Transit::TaggedValue|Array|Transit::TaggedValue.new("list", [1, 2, 3])|[1, 2, 3]|
140 | |set|Set|Set|Set.new([1, 2, 3])|`#`|
141 | |map|Hash|Hash|`{a: 1, b: 2, c: 3}`|`{:a=>1, :b=>2, :c=>3}`|
142 | |bytes|Transit::ByteArray|Transit::ByteArray|Transit::ByteArray.new("base64")|base64|
143 | |link|Transit::Link|Transit::Link|Transit::Link.new(Addressable::URI.parse("http://example.org/search"), "search")|`##, "rel"=>"search", "name"=>nil, "render"=>nil, "prompt"=>nil}>`|
144 |
145 | ### Additional types (not required by the [transit-format](https://github.com/cognitect/transit-format) spec)
146 |
147 | |Semantic type|Write accepts|Read returns|Example(write)|Example(read)|
148 | |------------|-------------|------------|--------------|-------------|
149 | |ratio|Rational|Rational|Rational(1, 3)|Rational(1, 3)|
150 |
151 | ## Tested Ruby Versions
152 |
153 | * MRI 2.1.10, 2.2.7, 2.3.4, 2.4.0, 2.4.1, 2.6.0..3
154 | * JRuby 1.7.13..16
155 |
156 | ## Copyright and License
157 |
158 | Copyright © 2014 Cognitect
159 |
160 | Licensed under the Apache License, Version 2.0 (the "License");
161 | you may not use this file except in compliance with the License.
162 | You may obtain a copy of the License at
163 |
164 | http://www.apache.org/licenses/LICENSE-2.0
165 |
166 | Unless required by applicable law or agreed to in writing, software
167 | distributed under the License is distributed on an "AS IS" BASIS,
168 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
169 | implied.
170 | See the License for the specific language governing permissions and
171 | limitations under the License.
172 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | # -*- ruby -*-
2 | #!/usr/bin/env rake
3 |
4 | require 'bundler'
5 | Bundler.setup
6 |
7 | require 'rspec/core/rake_task'
8 | RSpec::Core::RakeTask.new(:spec)
9 | Rake::Task[:spec].prerequisites << :compile
10 | task :default => :spec
11 |
12 | task :irb do
13 | sh 'irb -I lib -r transit -I dev -r irb_tools'
14 | end
15 |
16 | def project_name
17 | "transit-ruby"
18 | end
19 |
20 | def gemspec_filename
21 | @gemspec_filename ||= "#{project_name}.gemspec"
22 | end
23 |
24 | def spec_version
25 | @spec_version ||= /"(\d+\.\d+).dev"/.match(File.read(gemspec_filename))[1]
26 | end
27 |
28 | def jruby?
29 | defined?(RUBY_ENGINE) && RUBY_ENGINE == "jruby"
30 | end
31 |
32 | def jruby_version
33 | @jruby_version ||= `cat build/jruby_version`.chomp
34 | end
35 |
36 | def revision
37 | @revision ||= `build/revision`.chomp.to_i
38 | end
39 |
40 | def build_version
41 | @build_version ||= "#{spec_version}.#{revision}"
42 | end
43 |
44 | def published?
45 | gem_search = `gem q -rn "^transit-ruby$"`
46 | if jruby?
47 | gem_search =~ /\(#{revision}.*java.*\)/
48 | else
49 | gem_search =~ /\(#{revision}.*ruby.*\)/
50 | end
51 | end
52 |
53 | def tagged?
54 | `git tag` =~ /#{revision}/
55 | end
56 |
57 | def gem_filename
58 | if jruby?
59 | @gem_filename ||= "#{project_name}-#{build_version}-java.gem"
60 | else
61 | @gem_filename ||= "#{project_name}-#{build_version}.gem"
62 | end
63 | end
64 |
65 | def gem_path
66 | @gem_path ||= "pkg/#{gem_filename}"
67 | end
68 |
69 | desc "Use JRuby"
70 | task :use_jruby do
71 | sh "rbenv local jruby-#{jruby_version}"
72 | end
73 |
74 | desc "Build #{gem_filename}.gem into the pkg directory"
75 | task :build => [:compile] do
76 | begin
77 | gemspec_content = File.read(gemspec_filename)
78 | File.open(gemspec_filename, 'w+') do |f|
79 | f.write gemspec_content.sub("#{spec_version}.dev", build_version)
80 | end
81 | sh "gem build #{gemspec_filename}"
82 | sh "mkdir -p pkg"
83 | sh "mv #{gem_filename} #{gem_path}"
84 | ensure
85 | File.open(gemspec_filename, 'w+') do |f|
86 | f.write gemspec_content
87 | end
88 | end
89 | end
90 |
91 | desc "Build and install #{gem_filename}"
92 | task :install => [:build] do
93 | sh "gem install #{gem_path}"
94 | end
95 |
96 | task :ensure_committed do
97 | raise "Cannot release with uncommitted changes." unless `git status` =~ /clean/
98 | end
99 |
100 | desc "Prepare to sign the gem"
101 | task :prepare_to_sign do
102 | if jruby?
103 | puts "Gem signing is disabled for transit-ruby for JRuby"
104 | else
105 | private_key_path = File.expand_path(File.join(ENV['HOME'], '.gem', 'transit-ruby', 'gem-private_key.pem'))
106 | public_key_path = File.expand_path(File.join(ENV['HOME'], '.gem', 'transit-ruby', 'gem-public_cert.pem'))
107 | if File.exist?(public_key_path) and File.exist?(private_key_path)
108 | ENV['SIGN_GEM'] = 'true'
109 | else
110 | raise "Missing one or both key files: #{public_key_path}, #{private_key_path}"
111 | end
112 | end
113 | end
114 |
115 | task :publish => [:build] do
116 | unless tagged?
117 | sh "git tag v#{build_version}"
118 | end
119 | if published?
120 | puts "Already published #{gem_filename}"
121 | exit
122 | end
123 | puts "Ready to publish #{gem_filename} to rubygems. Enter 'Y' to publish, anything else to stop:"
124 | input = STDIN.gets.chomp
125 | if input.downcase == 'y'
126 | sh "gem push #{gem_path}"
127 | else
128 | puts "Canceling publish (you entered #{input.inspect} instead of 'Y')"
129 | sh "git tag -d v#{build_version}"
130 | end
131 | end
132 |
133 | desc "Create tag v#{build_version} and build and push #{gem_filename} to Rubygems"
134 | task :release => [:ensure_committed, :prepare_to_sign, :publish]
135 |
136 | desc "Uninstall #{project_name}"
137 | task :uninstall do
138 | sh "gem uninstall #{project_name}"
139 | end
140 |
141 | desc "Clean up generated files"
142 | task :clobber do
143 | sh "rm -rf ./tmp ./pkg ./.yardoc doc lib/transit.jar"
144 | end
145 |
146 | # rake compiler
147 | if jruby?
148 | require 'rake/javaextensiontask'
149 | Rake::JavaExtensionTask.new('transit') do |ext|
150 | require 'lock_jar'
151 | LockJar.lock
152 | locked_jars = LockJar.load(['default', 'development'])
153 |
154 | ext.name = 'transit'
155 | ext.ext_dir = 'ext'
156 | ext.lib_dir = 'lib'
157 | ext.source_version = '1.6'
158 | ext.target_version = '1.6'
159 | ext.classpath = locked_jars.map {|x| File.expand_path x}.join ':'
160 | end
161 | else
162 | task :compile do
163 | # no-op for C Ruby
164 | end
165 | end
166 |
--------------------------------------------------------------------------------
/TODO.org:
--------------------------------------------------------------------------------
1 | * ship it!
2 | * continue spike of streaming parse
3 | There is a conflict between OJ's parsing model and our caching
4 | model: hash values get processed before keys, so we're caching keys
5 | after any caching is performed within a nested structure.
6 |
--------------------------------------------------------------------------------
/benchmarks/decoding_time.rb:
--------------------------------------------------------------------------------
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 | $LOAD_PATH << File.expand_path("../../lib", __FILE__)
16 | require 'transit'
17 | require 'benchmark'
18 |
19 | decoder = Transit::Decoder.new
20 | custom_decoder = Transit::Decoder.new
21 | custom_decoder.register("t") {|t| Transit::Util.date_time_from_millis(t.to_i)}
22 |
23 | n = 10000
24 |
25 | t = Time.now
26 | m = Transit::Util.date_time_to_millis(t)
27 | m_to_s = m.to_s
28 | s = t.utc.iso8601(3)
29 |
30 | results = [Time.parse(s).utc,
31 | Transit::Util.date_time_from_millis(m),
32 | Transit::Util.date_time_from_millis(m_to_s.to_i),
33 | decoder.decode("~t#{s}"),
34 | decoder.decode({"~#t" => m}),
35 | custom_decoder.decode("~t#{m}")]
36 |
37 | as_millis = results.map {|r| Transit::Util.date_time_to_millis(r)}
38 |
39 | if Set.new(as_millis).length > 1
40 | warn "Not all methods returned the same values:"
41 | warn as_millis.to_s
42 | end
43 |
44 | Benchmark.benchmark do |bm|
45 | puts "Time.parse(#{s.inspect}).utc"
46 | 3.times do
47 | bm.report do
48 | n.times do
49 | Time.parse(s).utc
50 | end
51 | end
52 | end
53 |
54 | puts
55 | puts "Transit::Util.date_time_from_millis(#{m.inspect})"
56 | 3.times do
57 | bm.report do
58 | n.times do
59 | Transit::Util.date_time_from_millis(m)
60 | end
61 | end
62 | end
63 |
64 | puts
65 | puts "Transit::Util.date_time_from_millis(#{m_to_s.inspect}.to_i)"
66 | 3.times do
67 | bm.report do
68 | n.times do
69 | Transit::Util.date_time_from_millis(m_to_s.to_i)
70 | end
71 | end
72 | end
73 |
74 | puts
75 | puts "decoder.decode(\"~t#{s}\")"
76 | 3.times do
77 | bm.report do
78 | n.times do
79 | decoder.decode("~t#{s}")
80 | end
81 | end
82 | end
83 |
84 | puts
85 | puts "decoder.decode({\"~#t\" => #{m}})"
86 | 3.times do
87 | bm.report do
88 | n.times do
89 | decoder.decode({"~#t" => m})
90 | end
91 | end
92 | end
93 |
94 | puts
95 | puts "custom_decoder.decode(\"~t#{m}\")"
96 | 3.times do
97 | bm.report do
98 | n.times do
99 | custom_decoder.decode("~t#{m}")
100 | end
101 | end
102 | end
103 | end
104 |
105 | __END__
106 |
107 | $ ruby benchmarks/decoding_time.rb
108 | Not all methods returned the same values:
109 | [1397450386660, 1397450386661, 1397450386661, 1397450386660, 1397450386661, 1397450386661]
110 |
111 | # This ^^ shows that Time.new.iso8601(3) is truncating millis instead of rounding them.
112 |
113 | Time.parse("2014-04-14T04:39:46.660Z").utc
114 | 0.270000 0.000000 0.270000 ( 0.265990)
115 | 0.260000 0.000000 0.260000 ( 0.261357)
116 | 0.260000 0.000000 0.260000 ( 0.263597)
117 |
118 | Transit::Util.date_time_from_millis(1397450386661)
119 | 0.040000 0.000000 0.040000 ( 0.041289)
120 | 0.040000 0.000000 0.040000 ( 0.043084)
121 | 0.050000 0.000000 0.050000 ( 0.043169)
122 |
123 | Transit::Util.date_time_from_millis("1397450386661".to_i)
124 | 0.040000 0.000000 0.040000 ( 0.048342)
125 | 0.050000 0.000000 0.050000 ( 0.047006)
126 | 0.050000 0.010000 0.060000 ( 0.046771)
127 |
128 | decoder.decode("~t2014-04-14T04:39:46.660Z")
129 | 0.310000 0.000000 0.310000 ( 0.311126)
130 | 0.310000 0.000000 0.310000 ( 0.312943)
131 | 0.320000 0.000000 0.320000 ( 0.317080)
132 |
133 | decoder.decode({"~#t" => 1397450386661})
134 | 0.080000 0.000000 0.080000 ( 0.081899)
135 | 0.070000 0.000000 0.070000 ( 0.077323)
136 | 0.080000 0.000000 0.080000 ( 0.079400)
137 |
138 | custom_decoder.decode("~t1397450386661")
139 | 0.080000 0.000000 0.080000 ( 0.074236)
140 | 0.080000 0.000000 0.080000 ( 0.080308)
141 | 0.070000 0.000000 0.070000 ( 0.075567)
142 |
--------------------------------------------------------------------------------
/benchmarks/encoding_time.rb:
--------------------------------------------------------------------------------
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 | $LOAD_PATH << File.expand_path("../../lib", __FILE__)
16 | require 'transit'
17 | require 'benchmark'
18 |
19 | n = 10000
20 |
21 | $date_time = DateTime.now
22 | $time = Time.now
23 | $date = Date.today
24 |
25 | def header(s)
26 | puts s.sub(/^\$/,'')
27 | puts eval(s)
28 | end
29 |
30 | Benchmark.benchmark do |bm|
31 | header '$date_time.new_offset(0).strftime(Transit::TIME_FORMAT)'
32 | 3.times do
33 | bm.report do
34 | n.times do
35 | $date_time.new_offset(0).strftime("%FT%H:%M:%S.%LZ")
36 | end
37 | end
38 | end
39 |
40 | puts
41 |
42 | header '$date_time.to_time.utc.strftime(Transit::TIME_FORMAT)'
43 | 3.times do
44 | bm.report do
45 | n.times do;
46 | $date_time.to_time.utc.strftime(Transit::TIME_FORMAT)
47 | end
48 | end
49 | end
50 |
51 | puts
52 |
53 | header "$date_time.to_time.utc.iso8601(3)"
54 | 3.times do
55 | bm.report do
56 | n.times do
57 | $date_time.to_time.utc.iso8601(3)
58 | end
59 | end
60 | end
61 |
62 | puts
63 |
64 | header '$time.getutc.strftime(Transit::TIME_FORMAT)'
65 | 3.times do
66 | bm.report do
67 | n.times do
68 | $time.getutc.strftime(Transit::TIME_FORMAT)
69 | end
70 | end
71 | end
72 |
73 | puts
74 |
75 | header '$time.to_datetime.new_offset(0).strftime(Transit::TIME_FORMAT)'
76 | 3.times do
77 | bm.report do
78 | n.times do
79 | $time.to_datetime.new_offset(0).strftime(Transit::TIME_FORMAT)
80 | end
81 | end
82 | end
83 |
84 | puts
85 |
86 | header '$date.to_datetime.strftime(Transit::TIME_FORMAT)'
87 | 3.times do
88 | bm.report do
89 | n.times do
90 | $date.to_datetime.strftime(Transit::TIME_FORMAT)
91 | end
92 | end
93 | end
94 |
95 | puts
96 |
97 | header '$date.to_time.strftime(Transit::TIME_FORMAT)'
98 | 3.times do
99 | bm.report do
100 | n.times do
101 | $date.to_time.strftime(Transit::TIME_FORMAT)
102 | end
103 | end
104 | end
105 |
106 | puts
107 |
108 | header 'Time.gm($date.year, $date.month, $date.day).iso8601(3)'
109 | 3.times do
110 | bm.report do
111 | n.times do
112 | Time.gm($date.year, $date.month, $date.day).iso8601(3)
113 | end
114 | end
115 | end
116 |
117 | puts
118 |
119 | header 'Time.gm($date.year, $date.month, $date.day).strftime(Transit::TIME_FORMAT)'
120 | 3.times do
121 | bm.report do
122 | n.times do
123 | Time.gm($date.year, $date.month, $date.day).strftime(Transit::TIME_FORMAT)
124 | end
125 | end
126 | end
127 | end
128 |
129 | __END__
130 |
131 | $ ruby benchmarks/encoding_time.rb
132 | date_time.new_offset(0).strftime(Transit::TIME_FORMAT)
133 | 2014-04-18T19:35:20.150Z
134 | 0.020000 0.000000 0.020000 ( 0.022102)
135 | 0.020000 0.000000 0.020000 ( 0.020739)
136 | 0.030000 0.010000 0.040000 ( 0.025088)
137 |
138 | date_time.to_time.utc.strftime(Transit::TIME_FORMAT)
139 | 2014-04-18T19:35:20.150Z
140 | 0.080000 0.000000 0.080000 ( 0.081011)
141 | 0.070000 0.000000 0.070000 ( 0.079435)
142 | 0.080000 0.000000 0.080000 ( 0.079693)
143 |
144 | date_time.to_time.utc.iso8601(3)
145 | 2014-04-18T19:35:20.150Z
146 | 0.100000 0.000000 0.100000 ( 0.095387)
147 | 0.100000 0.000000 0.100000 ( 0.099325)
148 | 0.090000 0.000000 0.090000 ( 0.097779)
149 |
150 | time.getutc.strftime(Transit::TIME_FORMAT)
151 | 2014-04-18T19:35:20.150Z
152 | 0.030000 0.000000 0.030000 ( 0.022180)
153 | 0.020000 0.000000 0.020000 ( 0.023639)
154 | 0.030000 0.000000 0.030000 ( 0.027751)
155 |
156 | time.to_datetime.new_offset(0).strftime(Transit::TIME_FORMAT)
157 | 2014-04-18T19:35:20.150Z
158 | 0.040000 0.000000 0.040000 ( 0.043754)
159 | 0.040000 0.000000 0.040000 ( 0.039013)
160 | 0.040000 0.000000 0.040000 ( 0.044270)
161 |
162 | date.to_datetime.strftime(Transit::TIME_FORMAT)
163 | 2014-04-18T00:00:00.000Z
164 | 0.020000 0.000000 0.020000 ( 0.020463)
165 | 0.020000 0.000000 0.020000 ( 0.020716)
166 | 0.030000 0.000000 0.030000 ( 0.022477)
167 |
168 | date.to_time.strftime(Transit::TIME_FORMAT)
169 | 2014-04-18T00:00:00.000Z
170 | 0.090000 0.000000 0.090000 ( 0.098463)
171 | 0.090000 0.000000 0.090000 ( 0.082547)
172 | 0.080000 0.000000 0.080000 ( 0.088301)
173 |
174 | Time.gm($date.year, $date.month, $date.day).iso8601(3)
175 | 2014-04-18T00:00:00.000Z
176 | 0.050000 0.000000 0.050000 ( 0.050571)
177 | 0.070000 0.000000 0.070000 ( 0.063049)
178 | 0.050000 0.000000 0.050000 ( 0.049378)
179 |
180 | Time.gm($date.year, $date.month, $date.day).strftime(Transit::TIME_FORMAT)
181 | 2014-04-18T00:00:00.000Z
182 | 0.030000 0.000000 0.030000 ( 0.037934)
183 | 0.040000 0.000000 0.040000 ( 0.038376)
184 | 0.040000 0.000000 0.040000 ( 0.037938)
185 |
--------------------------------------------------------------------------------
/bin/benchmark:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 |
3 | ## Copyright (c) Cognitect, Inc.
4 | ## All rights reserved.
5 |
6 | $LOAD_PATH << File.expand_path("../../lib", __FILE__)
7 | require 'benchmark'
8 | require 'stringio'
9 | require 'json'
10 | require 'transit'
11 | require 'oj'
12 |
13 | def read_transit(data)
14 | io = StringIO.new(data, 'r+')
15 | Transit::Reader.new(:json, io).read
16 | end
17 |
18 | def write_transit(data)
19 | io = StringIO.new('', 'w+')
20 | Transit::Writer.new(:json, io).write(data)
21 | end
22 |
23 | def read_json(data)
24 | io = StringIO.new(data, 'r+')
25 | Oj::load(data)
26 | end
27 |
28 | data = nil
29 |
30 | n = 100
31 |
32 | include Benchmark
33 | puts "**************************"
34 | puts "transit-json"
35 | open("../transit-format/examples/0.8/example.json", 'r') {|f| data = f.read}
36 | Benchmark.benchmark(CAPTION, 20, FORMAT, "avg read transit:", "avg read oj:", "avg write transit:") do |bm|
37 | t = bm.report("read transit (#{n} x):") { n.times { read_transit(data) } }
38 | y = bm.report("read oj (#{n} x):") { n.times { read_json(data) } }
39 | w = bm.report("write transit (#{n} x):") { n.times { write_transit(data) } }
40 | [t/n, y/n, w/n]
41 | end
42 |
43 | puts "**************************"
44 | puts "transit-json-verbose"
45 | open("../transit-format/examples/0.8/example.verbose.json", 'r') {|f| data = f.read}
46 | Benchmark.benchmark(CAPTION, 20, FORMAT, "avg read transit:", "avg read oj:", "avg write transit:") do |bm|
47 | t = bm.report("read transit (#{n} x):") { n.times { read_transit(data) } }
48 | y = bm.report("read oj (#{n} x):") { n.times { read_json(data) } }
49 | w = bm.report("write transit (#{n} x):") { n.times { write_transit(data) } }
50 | [t/n, y/n, w/n]
51 | end
52 | puts "**************************"
53 |
--------------------------------------------------------------------------------
/bin/read-transit:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # Copyright (c) Cognitect, Inc.
3 | # All rights reserved.
4 |
5 | $LOAD_PATH << 'lib'
6 | require 'transit'
7 |
8 | transport = ARGV[0] || "json"
9 |
10 | r = Transit::Reader.new(transport.gsub("-","_").to_sym, STDIN)
11 | r.read {|o| p o}
12 |
--------------------------------------------------------------------------------
/bin/read-write:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # Copyright (c) Cognitect, Inc.
3 | # All rights reserved.
4 |
5 | $LOAD_PATH << 'lib'
6 | require 'transit'
7 |
8 | transport = (ARGV[0] || "json").gsub("-","_").to_sym
9 |
10 | r = Transit::Reader.new(transport, STDIN)
11 | w = Transit::Writer.new(transport, STDOUT)
12 |
13 | r.read {|o| w.write o}
14 |
--------------------------------------------------------------------------------
/bin/roundtrip:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Copyright (c) Cognitect, Inc.
3 | # All rights reserved.
4 |
5 | cd `dirname $0`/..
6 |
7 | exec bin/read-write "$@"
8 |
--------------------------------------------------------------------------------
/bin/rspec-across-supported-versions:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 | # Copyright (c) Cognitect, Inc.
3 | # All rights reserved.
4 |
5 | for r in 1.9.3-p547 2.0.0-p353 2.1.0 2.1.1 2.1.2 jruby-1.7.13 jruby-1.7.14 jruby-1.7.15 jruby-1.7.16
6 | do
7 | eval "rbenv local $r"
8 | echo `ruby -v`
9 | rake compile
10 | rspec
11 | done
12 |
13 | rm .ruby-version
14 |
--------------------------------------------------------------------------------
/build/jruby_version:
--------------------------------------------------------------------------------
1 | 1.7.16
2 |
--------------------------------------------------------------------------------
/build/release:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Returns the revision number used for deployment.
4 |
5 | rbenv local --unset
6 | rake release
7 | rake use_jruby
8 | rake release
9 |
--------------------------------------------------------------------------------
/build/revision:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Returns the revision number used for deployment.
4 |
5 | set -e
6 |
7 | REVISION=`git --no-replace-objects describe --tags --match v0.0`
8 |
9 | # Extract the version number from the string. Do this in two steps so
10 | # it is a little easier to understand.
11 | REVISION=${REVISION:5} # drop the first 5 characters
12 | REVISION=${REVISION:0:${#REVISION}-9} # drop the last 9 characters
13 |
14 | echo $REVISION
15 |
--------------------------------------------------------------------------------
/dev/irb_tools.rb:
--------------------------------------------------------------------------------
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 | require 'stringio'
16 |
17 | def time
18 | start = Time.now
19 | yield
20 | puts "Elapsed: #{Time.now - start}"
21 | end
22 |
23 | class Object
24 | def to_transit(format=:json)
25 | sio = StringIO.new
26 | Transit::Writer.new(format, sio).write(self)
27 | sio.string
28 | end
29 | end
30 |
31 | class String
32 | def from_transit(format=:json)
33 | sio = StringIO.new(self)
34 | Transit::Reader.new(format, sio).read
35 | end
36 | end
37 |
--------------------------------------------------------------------------------
/ext/com/cognitect/transit/ruby/TransitService.java:
--------------------------------------------------------------------------------
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
12 | // implied.
13 | // See the License for the specific language governing permissions and
14 | // limitations under the License.
15 |
16 | package com.cognitect.transit.ruby;
17 |
18 | import java.io.IOException;
19 |
20 | import org.jruby.Ruby;
21 | import org.jruby.RubyClass;
22 | import org.jruby.RubyModule;
23 | import org.jruby.runtime.ObjectAllocator;
24 | import org.jruby.runtime.builtin.IRubyObject;
25 | import org.jruby.runtime.load.BasicLibraryService;
26 |
27 | public class TransitService implements BasicLibraryService {
28 |
29 | @Override
30 | public boolean basicLoad(Ruby runtime) throws IOException {
31 | RubyModule transit = runtime.defineModule("Transit");
32 | RubyModule unmarshaler = transit.defineModuleUnder("Unmarshaler");
33 | RubyClass json_unmarshaler = unmarshaler.defineClassUnder("Json", runtime.getObject(), new ObjectAllocator() {
34 | private com.cognitect.transit.ruby.unmarshaler.Json json = null;
35 | public IRubyObject allocate(Ruby runtime, RubyClass rubyClass) {
36 | if (json == null) {
37 | json = new com.cognitect.transit.ruby.unmarshaler.Json(runtime, rubyClass);
38 | }
39 | try {
40 | com.cognitect.transit.ruby.unmarshaler.Json clone =
41 | (com.cognitect.transit.ruby.unmarshaler.Json)json.clone();
42 | clone.setMetaClass(rubyClass);
43 | return clone;
44 | } catch (CloneNotSupportedException e) {
45 | return new com.cognitect.transit.ruby.unmarshaler.Json(runtime, rubyClass);
46 | }
47 | }
48 | });
49 | json_unmarshaler.defineAnnotatedMethods(com.cognitect.transit.ruby.unmarshaler.Json.class);
50 |
51 | RubyClass messagepack_unmarshaler = unmarshaler.defineClassUnder("MessagePack", runtime.getObject(), new ObjectAllocator() {
52 | private com.cognitect.transit.ruby.unmarshaler.MessagePack msgpack = null;
53 | public IRubyObject allocate(Ruby runtime, RubyClass rubyClass) {
54 | if (msgpack == null) {
55 | msgpack = new com.cognitect.transit.ruby.unmarshaler.MessagePack(runtime, rubyClass);
56 | }
57 | try {
58 | com.cognitect.transit.ruby.unmarshaler.MessagePack clone =
59 | (com.cognitect.transit.ruby.unmarshaler.MessagePack)msgpack.clone();
60 | clone.setMetaClass(rubyClass);
61 | return clone;
62 | } catch (CloneNotSupportedException e) {
63 | return new com.cognitect.transit.ruby.unmarshaler.MessagePack(runtime, rubyClass);
64 | }
65 | }
66 | });
67 | messagepack_unmarshaler.defineAnnotatedMethods(com.cognitect.transit.ruby.unmarshaler.MessagePack.class);
68 |
69 | RubyModule marshaler = transit.defineModuleUnder("Marshaler");
70 | RubyClass json_marshaler = marshaler.defineClassUnder("Json", runtime.getObject(), new ObjectAllocator() {
71 | private com.cognitect.transit.ruby.marshaler.Json json = null;
72 | public IRubyObject allocate(Ruby runtime, RubyClass rubyClass) {
73 | if (json == null) {
74 | json = new com.cognitect.transit.ruby.marshaler.Json(runtime, rubyClass);
75 | }
76 | try {
77 | com.cognitect.transit.ruby.marshaler.Json clone =
78 | (com.cognitect.transit.ruby.marshaler.Json)json.clone();
79 | clone.setMetaClass(rubyClass);
80 | return clone;
81 | } catch (CloneNotSupportedException e) {
82 | return new com.cognitect.transit.ruby.marshaler.Json(runtime, rubyClass);
83 | }
84 | }
85 | });
86 | json_marshaler.defineAnnotatedMethods(com.cognitect.transit.ruby.marshaler.Json.class);
87 |
88 | RubyClass verbosejson_marshaler = marshaler.defineClassUnder("VerboseJson", runtime.getObject(), new ObjectAllocator() {
89 | private com.cognitect.transit.ruby.marshaler.VerboseJson verboseJson = null;
90 | public IRubyObject allocate(Ruby runtime, RubyClass rubyClass) {
91 | if (verboseJson == null) {
92 | verboseJson = new com.cognitect.transit.ruby.marshaler.VerboseJson(runtime, rubyClass);
93 | }
94 | try {
95 | com.cognitect.transit.ruby.marshaler.VerboseJson clone =
96 | (com.cognitect.transit.ruby.marshaler.VerboseJson)verboseJson.clone();
97 | clone.setMetaClass(rubyClass);
98 | return clone;
99 | } catch (CloneNotSupportedException e) {
100 | return new com.cognitect.transit.ruby.marshaler.VerboseJson(runtime, rubyClass);
101 | }
102 | }
103 | });
104 | verbosejson_marshaler.defineAnnotatedMethods(com.cognitect.transit.ruby.marshaler.VerboseJson.class);
105 |
106 | RubyClass messagepack_marshaler = marshaler.defineClassUnder("MessagePack", runtime.getObject(), new ObjectAllocator() {
107 | private com.cognitect.transit.ruby.marshaler.MessagePack msgpack = null;
108 | public IRubyObject allocate(Ruby runtime, RubyClass rubyClass) {
109 | if (msgpack == null) {
110 | msgpack = new com.cognitect.transit.ruby.marshaler.MessagePack(runtime, rubyClass);
111 | }
112 | try {
113 | com.cognitect.transit.ruby.marshaler.MessagePack clone =
114 | (com.cognitect.transit.ruby.marshaler.MessagePack)msgpack.clone();
115 | clone.setMetaClass(rubyClass);
116 | return clone;
117 | } catch (CloneNotSupportedException e) {
118 | return new com.cognitect.transit.ruby.marshaler.MessagePack(runtime, rubyClass);
119 | }
120 | }
121 | });
122 | messagepack_marshaler.defineAnnotatedMethods(com.cognitect.transit.ruby.marshaler.MessagePack.class);
123 |
124 | return true;
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/ext/com/cognitect/transit/ruby/TransitTypeConverter.java:
--------------------------------------------------------------------------------
1 | package com.cognitect.transit.ruby;
2 |
3 | import java.util.Arrays;
4 | import java.util.List;
5 |
6 | import org.jruby.Ruby;
7 | import org.jruby.runtime.builtin.IRubyObject;
8 |
9 | public class TransitTypeConverter {
10 | private static final List specialString = Arrays.asList("NaN", "Infinity", "-Infinity");
11 |
12 | public static boolean needsCostomConverter(Object o) {
13 | if ((o instanceof String) && specialString.contains((String)o)) {
14 | return true;
15 | } else {
16 | return false;
17 | }
18 | }
19 |
20 | public static IRubyObject convertStringToFloat(Ruby runtime, Object o) {
21 | String str = (String)o;
22 | if ("NaN".equals(str)) {
23 | return runtime.newFloat(Double.NaN);
24 | } else if ("Infinity".equals(str)) {
25 | return runtime.newFloat(Double.POSITIVE_INFINITY);
26 | } else if ("-Infinity".equals(str)) {
27 | return runtime.newFloat(Double.NEGATIVE_INFINITY);
28 | } else {
29 | return runtime.getNil();
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/ext/com/cognitect/transit/ruby/marshaler/Base.java:
--------------------------------------------------------------------------------
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
12 | // implied.
13 | // See the License for the specific language governing permissions and
14 | // limitations under the License.
15 |
16 | package com.cognitect.transit.ruby.marshaler;
17 |
18 | import java.io.OutputStream;
19 | import java.util.HashMap;
20 | import java.util.Map;
21 | import java.util.Set;
22 |
23 | import org.jruby.Ruby;
24 | import org.jruby.RubyArray;
25 | import org.jruby.RubyClass;
26 | import org.jruby.RubyHash;
27 | import org.jruby.RubyModule;
28 | import org.jruby.RubyObject;
29 | import org.jruby.RubyString;
30 | import org.jruby.javasupport.JavaUtil;
31 | import org.jruby.runtime.Block;
32 | import org.jruby.runtime.ThreadContext;
33 | import org.jruby.runtime.builtin.IRubyObject;
34 |
35 | import com.cognitect.transit.WriteHandler;
36 | import com.cognitect.transit.Writer;
37 |
38 | public class Base extends RubyObject {
39 | private static final long serialVersionUID = -3179062656279837886L;
40 | protected Writer