RFC7159 7159
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +61 -0
- data/.rspec +4 -0
- data/.yardopts +2 -0
- data/Gemfile +46 -0
- data/LICENSE.txt +40 -0
- data/README.txt +899 -0
- data/RFC7159 +899 -0
- data/RFC7159.gemspec +85 -0
- data/Rakefile +82 -0
- data/lib/RFC7159.rb +80 -0
- data/lib/RFC7159/array.rb +134 -0
- data/lib/RFC7159/dumper.rb +231 -0
- data/lib/RFC7159/false.rb +79 -0
- data/lib/RFC7159/null.rb +79 -0
- data/lib/RFC7159/number.rb +149 -0
- data/lib/RFC7159/object.rb +140 -0
- data/lib/RFC7159/parser.ry +267 -0
- data/lib/RFC7159/string.rb +221 -0
- data/lib/RFC7159/true.rb +79 -0
- data/lib/RFC7159/value.rb +96 -0
- data/lib/RFC7159/version.rb +48 -0
- data/spec/RFC7159_spec.rb +275 -0
- data/spec/acceptance/README.txt +66 -0
- data/spec/acceptance/invalid/0001-ws/0001-verical-tab.txt +1 -0
- data/spec/acceptance/invalid/0001-ws/0002-null.txt +0 -0
- data/spec/acceptance/invalid/0001-ws/0003-space-in-number-1.txt +1 -0
- data/spec/acceptance/invalid/0001-ws/0004-space-in-number-2.txt +1 -0
- data/spec/acceptance/invalid/0001-ws/0005-space-in-number-3.txt +1 -0
- data/spec/acceptance/invalid/0001-ws/0006-space-in-number-4.txt +1 -0
- data/spec/acceptance/invalid/0001-ws/0007-space-in-number-5.txt +1 -0
- data/spec/acceptance/invalid/0001-ws/0008-space-in-number-6.txt +1 -0
- data/spec/acceptance/invalid/0001-ws/0009-space-in-literal.txt +1 -0
- data/spec/acceptance/invalid/0001-ws/0010-Unicode-LINE_SEPARATOR.txt +1 -0
- data/spec/acceptance/invalid/0002-comments/0001-C-style.txt +1 -0
- data/spec/acceptance/invalid/0002-comments/0002-C-plusplus-style.txt +2 -0
- data/spec/acceptance/invalid/0002-comments/0003-sh-style.txt +2 -0
- data/spec/acceptance/invalid/0002-comments/0004-python-docstring.txt +3 -0
- data/spec/acceptance/invalid/0002-comments/0005-SQL-style.txt +2 -0
- data/spec/acceptance/invalid/0002-comments/0006-BASIC-style.txt +2 -0
- data/spec/acceptance/invalid/0003-literals/0001-FALSE.txt +1 -0
- data/spec/acceptance/invalid/0003-literals/0002-NULL.txt +1 -0
- data/spec/acceptance/invalid/0003-literals/0003-TRUE.txt +1 -0
- data/spec/acceptance/invalid/0003-literals/0004-NUL.txt +1 -0
- data/spec/acceptance/invalid/0003-literals/0005-nil.txt +1 -0
- data/spec/acceptance/invalid/0003-literals/0006-undef.txt +1 -0
- data/spec/acceptance/invalid/0003-literals/0007-modifier.txt +1 -0
- data/spec/acceptance/invalid/0003-literals/0008-undefined.txt +1 -0
- data/spec/acceptance/invalid/0004-numbers/0001-omit-zero.txt +1 -0
- data/spec/acceptance/invalid/0004-numbers/0002-minus-dot.txt +1 -0
- data/spec/acceptance/invalid/0004-numbers/0003-missing-frac.txt +1 -0
- data/spec/acceptance/invalid/0004-numbers/0004-missing-exp.txt +1 -0
- data/spec/acceptance/invalid/0004-numbers/0005-octal.txt +1 -0
- data/spec/acceptance/invalid/0004-numbers/0006-hexadecimal.txt +1 -0
- data/spec/acceptance/invalid/0004-numbers/0007-comma.txt +1 -0
- data/spec/acceptance/invalid/0004-numbers/0008-perl-underscore.txt +1 -0
- data/spec/acceptance/invalid/0004-numbers/0009-NaN.txt +1 -0
- data/spec/acceptance/invalid/0004-numbers/0010-Inf.txt +1 -0
- data/spec/acceptance/invalid/0004-numbers/0011-Infinity.txt +1 -0
- data/spec/acceptance/invalid/0005-strings/0000-NUL.txt +0 -0
- data/spec/acceptance/invalid/0005-strings/0001-not-terminated.txt +1 -0
- data/spec/acceptance/invalid/0005-strings/0002-single-quote.txt +1 -0
- data/spec/acceptance/invalid/0005-strings/0003-back-quote.txt +1 -0
- data/spec/acceptance/invalid/0005-strings/0004-carriage-return.txt +1 -0
- data/spec/acceptance/invalid/0005-strings/0005-line-feed.txt +2 -0
- data/spec/acceptance/invalid/0005-strings/0006-unknown-escape-a.txt +1 -0
- data/spec/acceptance/invalid/0005-strings/0007-unknown-escape-perl-style.txt +1 -0
- data/spec/acceptance/invalid/0005-strings/0008-unknown-escape-C-style.txt +1 -0
- data/spec/acceptance/invalid/0005-strings/0009-unknown-escape-ruby-style.txt +1 -0
- data/spec/acceptance/invalid/0005-strings/0010-escape-too-short.txt +1 -0
- data/spec/acceptance/invalid/0005-strings/0011-C-string-concat.txt +1 -0
- data/spec/acceptance/invalid/0005-strings/0012-perl-string-concat.txt +1 -0
- data/spec/acceptance/invalid/0005-strings/0013-Java-string-concat.txt +1 -0
- data/spec/acceptance/invalid/0006-encodings/0001-CESU-8.txt +1 -0
- data/spec/acceptance/invalid/0006-encodings/0002-Windows-31J.txt +1 -0
- data/spec/acceptance/invalid/0006-encodings/0003-EBCDIC.txt +1 -0
- data/spec/acceptance/invalid/0006-encodings/0004-overlong-utf8.txt +1 -0
- data/spec/acceptance/invalid/0007-arrays/0001-lacks-open.txt +1 -0
- data/spec/acceptance/invalid/0007-arrays/0002-lacks-close.txt +1 -0
- data/spec/acceptance/invalid/0007-arrays/0003-interleaving-parens.txt +1 -0
- data/spec/acceptance/invalid/0007-arrays/0004-dangling-comma.txt +1 -0
- data/spec/acceptance/invalid/0007-arrays/0005-missing-comma.txt +1 -0
- data/spec/acceptance/invalid/0007-arrays/0006-colon-instead-of-comma.txt +1 -0
- data/spec/acceptance/invalid/0008-hashes/0001-key-missing.txt +1 -0
- data/spec/acceptance/invalid/0008-hashes/0002-value-missing.txt +1 -0
- data/spec/acceptance/invalid/0008-hashes/0003-true-key.txt +1 -0
- data/spec/acceptance/invalid/0008-hashes/0004-false-key.txt +1 -0
- data/spec/acceptance/invalid/0008-hashes/0005-null-key.txt +1 -0
- data/spec/acceptance/invalid/0008-hashes/0006-numeric-key.txt +1 -0
- data/spec/acceptance/invalid/0008-hashes/0007-array-key.txt +1 -0
- data/spec/acceptance/invalid/0008-hashes/0008-hash-key.txt +1 -0
- data/spec/acceptance/invalid/0008-hashes/0009-key-not-escaped.txt +4 -0
- data/spec/acceptance/invalid/0009-javascriptisms/0001-JSONP.txt +1 -0
- data/spec/acceptance/invalid/0009-javascriptisms/0002-new-Array.txt +3 -0
- data/spec/acceptance/invalid/0009-javascriptisms/0003-new-Date.txt +1 -0
- data/spec/acceptance/invalid/0009-javascriptisms/0004-new-Error.txt +1 -0
- data/spec/acceptance/invalid/0009-javascriptisms/0005-Math.txt +1 -0
- data/spec/acceptance/invalid/0009-javascriptisms/0006-regular-expression.txt +1 -0
- data/spec/acceptance/invalid/0009-javascriptisms/0007-function.txt +7 -0
- data/spec/acceptance/invalid/0009-javascriptisms/0008-this.txt +1 -0
- data/spec/acceptance/invalid/0009-javascriptisms/0009-plusplus.txt +3 -0
- data/spec/acceptance/invalid/0009-javascriptisms/0010-ternary-operator.txt +1 -0
- data/spec/acceptance/valid/0001-ws/0001-space.json +1 -0
- data/spec/acceptance/valid/0001-ws/0002-tab.json +1 -0
- data/spec/acceptance/valid/0001-ws/0003-lf.json +1 -0
- data/spec/acceptance/valid/0001-ws/0004-cr.json +1 -0
- data/spec/acceptance/valid/0001-ws/0005-before.json +1 -0
- data/spec/acceptance/valid/0001-ws/0006-after.json +1 -0
- data/spec/acceptance/valid/0001-ws/0007-around-comma.json +3 -0
- data/spec/acceptance/valid/0001-ws/0008-around-colon.json +3 -0
- data/spec/acceptance/valid/0002-bare-values/0001-false.json +1 -0
- data/spec/acceptance/valid/0002-bare-values/0002-null.json +1 -0
- data/spec/acceptance/valid/0002-bare-values/0003-true.json +1 -0
- data/spec/acceptance/valid/0002-bare-values/0004-number.json +1 -0
- data/spec/acceptance/valid/0002-bare-values/0005-string.json +1 -0
- data/spec/acceptance/valid/0003-literals/0001-false.json +1 -0
- data/spec/acceptance/valid/0003-literals/0002-null.json +1 -0
- data/spec/acceptance/valid/0003-literals/0003-true.json +1 -0
- data/spec/acceptance/valid/0004-numbers/0000-zero.json +1 -0
- data/spec/acceptance/valid/0004-numbers/0001-one.json +1 -0
- data/spec/acceptance/valid/0004-numbers/0002-two.json +1 -0
- data/spec/acceptance/valid/0004-numbers/0003-three.json +1 -0
- data/spec/acceptance/valid/0004-numbers/0004-four.json +1 -0
- data/spec/acceptance/valid/0004-numbers/0005-five.json +1 -0
- data/spec/acceptance/valid/0004-numbers/0006-six.json +1 -0
- data/spec/acceptance/valid/0004-numbers/0007-seven.json +1 -0
- data/spec/acceptance/valid/0004-numbers/0008-eight.json +1 -0
- data/spec/acceptance/valid/0004-numbers/0009-nine.json +1 -0
- data/spec/acceptance/valid/0004-numbers/0010-ten.json +1 -0
- data/spec/acceptance/valid/0004-numbers/0011-minus.json +1 -0
- data/spec/acceptance/valid/0004-numbers/0012-fraction.json +1 -0
- data/spec/acceptance/valid/0004-numbers/0013-exponent.json +1 -0
- data/spec/acceptance/valid/0004-numbers/0014-exponent-minus.json +1 -0
- data/spec/acceptance/valid/0004-numbers/0015-exponent-plus.json +1 -0
- data/spec/acceptance/valid/0004-numbers/0016-complex.json +1 -0
- data/spec/acceptance/valid/0004-numbers/0017-DBL_MAX.json +1 -0
- data/spec/acceptance/valid/0004-numbers/0018-DBL_MIN.json +1 -0
- data/spec/acceptance/valid/0004-numbers/0019-subnormal-number.json +1 -0
- data/spec/acceptance/valid/0004-numbers/0020-1E400.json +1 -0
- data/spec/acceptance/valid/0004-numbers/0021-pi.json +1 -0
- data/spec/acceptance/valid/0004-numbers/0022-UINT32_MAX.json +1 -0
- data/spec/acceptance/valid/0004-numbers/0023-UINT64_MAX.json +1 -0
- data/spec/acceptance/valid/0004-numbers/0024-INT64_MIN.json +1 -0
- data/spec/acceptance/valid/0004-numbers/0025-high-resolution-zero.json +1 -0
- data/spec/acceptance/valid/0005-strings/0001-empty.json +1 -0
- data/spec/acceptance/valid/0005-strings/0002-basic-latin.json +1 -0
- data/spec/acceptance/valid/0005-strings/0003-escapes.json +1 -0
- data/spec/acceptance/valid/0005-strings/0004-raw-unicode.json +1 -0
- data/spec/acceptance/valid/0005-strings/0005-escaped-unicode.json +1 -0
- data/spec/acceptance/valid/0005-strings/0006-escaped-NUL.json +1 -0
- data/spec/acceptance/valid/0005-strings/0007-escaped-invalid-unicode-still-valid-as-json.json +1 -0
- data/spec/acceptance/valid/0005-strings/0008-ruby-json-gem-cant-handle-this.json +1 -0
- data/spec/acceptance/valid/0005-strings/0009-unescaped-invalid-javascript-still-valid-as-json.json +1 -0
- data/spec/acceptance/valid/0006-m17n/0001-genesis.json +6 -0
- data/spec/acceptance/valid/0006-m17n/0002-heart-sutra.json +5 -0
- data/spec/acceptance/valid/0006-m17n/0003-escaped-valid-surrogate-pair.json +1 -0
- data/spec/acceptance/valid/0006-m17n/0004-unescaped-valid-supplementary-multilingual-plane.json +1 -0
- data/spec/acceptance/valid/0007-arrays/0000-empty.json +1 -0
- data/spec/acceptance/valid/0007-arrays/0001-one-element.json +1 -0
- data/spec/acceptance/valid/0007-arrays/0002-multiple-elements.json +33 -0
- data/spec/acceptance/valid/0007-arrays/0003-various-types.json +1 -0
- data/spec/acceptance/valid/0007-arrays/0004-nested.json +17 -0
- data/spec/acceptance/valid/0008-hashes/0000-empty.json +1 -0
- data/spec/acceptance/valid/0008-hashes/0001-onekey.json +1 -0
- data/spec/acceptance/valid/0008-hashes/0002-many-keys.json +5 -0
- data/spec/acceptance/valid/0008-hashes/0003-empty-key.json +3 -0
- data/spec/acceptance/valid/0008-hashes/0004-true-value.json +3 -0
- data/spec/acceptance/valid/0008-hashes/0005-false-value.json +3 -0
- data/spec/acceptance/valid/0008-hashes/0006-null-value.json +3 -0
- data/spec/acceptance/valid/0008-hashes/0007-string-value.json +3 -0
- data/spec/acceptance/valid/0008-hashes/0008-numeric-value.json +3 -0
- data/spec/acceptance/valid/0008-hashes/0009-array-value.json +8 -0
- data/spec/acceptance/valid/0008-hashes/0010-hash-value.json +20 -0
- data/spec/acceptance/valid/0008-hashes/0011-duplicate-key-in-different-representations.json +4 -0
- data/spec/acceptance/valid/0008-hashes/0011-duplicate-key.json +4 -0
- data/spec/spec_helper.rb +54 -0
- metadata +520 -0
data/RFC7159.gemspec
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
#! /your/favourite/path/to/gem
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
|
4
|
+
# Copyright (c) 2014 Urabe, Shyouhei. All rights reserved.
|
5
|
+
#
|
6
|
+
# Redistribution and use in source and binary forms, with or without
|
7
|
+
# modification, are permitted provided that the following conditions are met:
|
8
|
+
#
|
9
|
+
# - Redistributions of source code must retain the above copyright
|
10
|
+
# notice, this list of conditions and the following disclaimer.
|
11
|
+
#
|
12
|
+
# - Redistributions in binary form must reproduce the above copyright
|
13
|
+
# notice, this list of conditions and the following disclaimer in
|
14
|
+
# the documentation and/or other materials provided with the
|
15
|
+
# distribution.
|
16
|
+
#
|
17
|
+
# - Neither the name of Internet Society, IETF or IETF Trust, nor the
|
18
|
+
# names of specific contributors, may be used to endorse or promote
|
19
|
+
# products derived from this software without specific prior written
|
20
|
+
# permission.
|
21
|
+
#
|
22
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS”
|
23
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
24
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
25
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
26
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
27
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
28
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
29
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
30
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
31
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
32
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
33
|
+
|
34
|
+
# coding: utf-8
|
35
|
+
|
36
|
+
require_relative 'lib/RFC7159/version'
|
37
|
+
|
38
|
+
Gem::Specification.new do |spec|
|
39
|
+
spec.name = 'RFC7159'
|
40
|
+
spec.version = RFC7159::VERSION
|
41
|
+
spec.authors = %w'Urabe, Shyouhei'
|
42
|
+
spec.email = %w'shyouhei@ruby-lang.org'
|
43
|
+
spec.summary = 'RFC7159 parser / generator'
|
44
|
+
spec.description = <<-'end'.gsub /\n\s*/, ''
|
45
|
+
A JSON parser/generator that conforms (I believe) to RFC7159 "The
|
46
|
+
JavaScript Object Notation (JSON) Data Interchange Format". That RFC is
|
47
|
+
very different to its predecessor RFC4627, when it comes to parsing.
|
48
|
+
This gem honors the updated syntax as possible. The generator guarantees
|
49
|
+
that a parsed valid properly rounds-trip to identical valid JSON
|
50
|
+
representation.
|
51
|
+
end
|
52
|
+
spec.homepage = 'http://github.com/shyouhei/RFC7159'
|
53
|
+
spec.license = "Simplified BSD License" # consult LICENSE.txt
|
54
|
+
|
55
|
+
spec.files = `git ls-files -z`.split("\x0") + %w'lib/RFC7159/parser.rb'
|
56
|
+
spec.executables = %w''
|
57
|
+
spec.test_files = spec.files.grep(%r{^spec/})
|
58
|
+
spec.require_paths = %w'lib'
|
59
|
+
|
60
|
+
spec.required_ruby_version = '~> 2.1' # String#scrub used
|
61
|
+
spec.add_development_dependency 'bundler', '~> 1.5'
|
62
|
+
spec.add_development_dependency 'rake', '~> 10.1'
|
63
|
+
spec.add_development_dependency 'rdoc', '~> 4.0'
|
64
|
+
spec.add_development_dependency 'yard', '~> 0.8'
|
65
|
+
spec.add_development_dependency 'rspec', '~> 2.14'
|
66
|
+
spec.add_development_dependency 'simplecov', '>= 0'
|
67
|
+
spec.add_development_dependency 'racc', '~> 1.4.11'
|
68
|
+
# racc runtime is inside ruby's stdlib so no runtime dependency.
|
69
|
+
|
70
|
+
# below are only for comparisons
|
71
|
+
spec.add_development_dependency 'json' # 1.8.1 tested
|
72
|
+
spec.add_development_dependency 'yajl-ruby' # 1.2.0 tested
|
73
|
+
spec.add_development_dependency 'oj' # 2.6.1 tested
|
74
|
+
end
|
75
|
+
|
76
|
+
#
|
77
|
+
# Local Variables:
|
78
|
+
# mode: ruby
|
79
|
+
# coding: utf-8-unix
|
80
|
+
# indent-tabs-mode: t
|
81
|
+
# tab-width: 3
|
82
|
+
# ruby-indent-level: 3
|
83
|
+
# fill-column: 79
|
84
|
+
# default-justification: full
|
85
|
+
# End:
|
data/Rakefile
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
#! /your/favourite/path/to/rake
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
|
4
|
+
# Copyright (c) 2014 Urabe, Shyouhei. All rights reserved.
|
5
|
+
#
|
6
|
+
# Redistribution and use in source and binary forms, with or without
|
7
|
+
# modification, are permitted provided that the following conditions are met:
|
8
|
+
#
|
9
|
+
# - Redistributions of source code must retain the above copyright
|
10
|
+
# notice, this list of conditions and the following disclaimer.
|
11
|
+
#
|
12
|
+
# - Redistributions in binary form must reproduce the above copyright
|
13
|
+
# notice, this list of conditions and the following disclaimer in
|
14
|
+
# the documentation and/or other materials provided with the
|
15
|
+
# distribution.
|
16
|
+
#
|
17
|
+
# - Neither the name of Internet Society, IETF or IETF Trust, nor the
|
18
|
+
# names of specific contributors, may be used to endorse or promote
|
19
|
+
# products derived from this software without specific prior written
|
20
|
+
# permission.
|
21
|
+
#
|
22
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS”
|
23
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
24
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
25
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
26
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
27
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
28
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
29
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
30
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
31
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
32
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
33
|
+
|
34
|
+
require 'rubygems'
|
35
|
+
require 'bundler'
|
36
|
+
require 'rake'
|
37
|
+
require "bundler/gem_tasks"
|
38
|
+
begin
|
39
|
+
Bundler.setup(:default, :development)
|
40
|
+
rescue Bundler::BundlerError => e
|
41
|
+
$stderr.puts e.message
|
42
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
43
|
+
exit e.status_code
|
44
|
+
end
|
45
|
+
|
46
|
+
require 'rspec/core'
|
47
|
+
require 'rspec/core/rake_task'
|
48
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
49
|
+
spec.pattern = FileList['spec/**/*_spec.rb']
|
50
|
+
end
|
51
|
+
|
52
|
+
require 'yard'
|
53
|
+
YARD::Rake::YardocTask.new
|
54
|
+
|
55
|
+
task yard: 'lib/RFC7159/parser.rb'
|
56
|
+
task rdoc: 'lib/RFC7159/parser.rb'
|
57
|
+
task build: 'lib/RFC7159/parser.rb'
|
58
|
+
file 'lib/RFC7159/parser.rb' => %w'lib/RFC7159/parser.ry' do |t|
|
59
|
+
sh "bundle exec racc --debug --output-file=#{t.name} #{t.prerequisites.first}"
|
60
|
+
end
|
61
|
+
|
62
|
+
desc "a la rails console"
|
63
|
+
task :console do
|
64
|
+
require_relative 'lib/RFC7159'
|
65
|
+
require 'irb'
|
66
|
+
require 'irb/completion'
|
67
|
+
ARGV.clear
|
68
|
+
IRB.start
|
69
|
+
end
|
70
|
+
|
71
|
+
task default: :spec
|
72
|
+
|
73
|
+
#
|
74
|
+
# Local Variables:
|
75
|
+
# mode: ruby
|
76
|
+
# coding: utf-8-unix
|
77
|
+
# indent-tabs-mode: t
|
78
|
+
# tab-width: 3
|
79
|
+
# ruby-indent-level: 3
|
80
|
+
# fill-column: 79
|
81
|
+
# default-justification: full
|
82
|
+
# End:
|
data/lib/RFC7159.rb
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
#! /your/favourite/path/to/ruby
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
|
4
|
+
# Copyright (c) 2014 Urabe, Shyouhei. All rights reserved.
|
5
|
+
#
|
6
|
+
# Redistribution and use in source and binary forms, with or without
|
7
|
+
# modification, are permitted provided that the following conditions are met:
|
8
|
+
#
|
9
|
+
# - Redistributions of source code must retain the above copyright
|
10
|
+
# notice, this list of conditions and the following disclaimer.
|
11
|
+
#
|
12
|
+
# - Redistributions in binary form must reproduce the above copyright
|
13
|
+
# notice, this list of conditions and the following disclaimer in
|
14
|
+
# the documentation and/or other materials provided with the
|
15
|
+
# distribution.
|
16
|
+
#
|
17
|
+
# - Neither the name of Internet Society, IETF or IETF Trust, nor the
|
18
|
+
# names of specific contributors, may be used to endorse or promote
|
19
|
+
# products derived from this software without specific prior written
|
20
|
+
# permission.
|
21
|
+
#
|
22
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS”
|
23
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
24
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
25
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
26
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
27
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
28
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
29
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
30
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
31
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
32
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
33
|
+
|
34
|
+
require_relative 'RFC7159/parser'
|
35
|
+
require_relative 'RFC7159/value'
|
36
|
+
require_relative 'RFC7159/dumper'
|
37
|
+
|
38
|
+
# This is a RFC7159-conforming JSON parser/generator.
|
39
|
+
module RFC7159
|
40
|
+
# This is our Marshal.load -compat API
|
41
|
+
# @param [::String, IO] str The input
|
42
|
+
# @param [true, false] plain Output to be plain-old ruby object, or not.
|
43
|
+
# @return [::Object] Evaluated plain-old ruby object
|
44
|
+
# @return [RFC7159::Value] Evaluated JSON value object
|
45
|
+
# @raise [Racc::ParseError] The input is invalid
|
46
|
+
# @raise [Encoding::CompatibilityError] The input is invalid
|
47
|
+
def self.load str, plain: false
|
48
|
+
ast = RFC7159::Parser.new.parse str
|
49
|
+
obj = RFC7159::Value.from_ast ast
|
50
|
+
if plain
|
51
|
+
return obj.plain_old_ruby_object
|
52
|
+
else
|
53
|
+
return obj
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# This is our Marshal.dump -compat API
|
58
|
+
# @param [::Object] obj The input (should be JSONable)
|
59
|
+
# @param [IO] port IO port to dump obj into
|
60
|
+
# @return [::String] Dumped valid JSON text representation
|
61
|
+
# @return [port] Indicates the output went to the port.
|
62
|
+
# @raise [TypeEeepe] obj not JSONable
|
63
|
+
# @raise [Errno::ELOOP] Cyclic relation(s) detected
|
64
|
+
def self.dump obj, port: ''.encode(Encoding::UTF_8)
|
65
|
+
bag = RFC7159::Dumper.new port
|
66
|
+
bag.start_dump obj
|
67
|
+
return port
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
#
|
72
|
+
# Local Variables:
|
73
|
+
# mode: ruby
|
74
|
+
# coding: utf-8-unix
|
75
|
+
# indent-tabs-mode: t
|
76
|
+
# tab-width: 3
|
77
|
+
# ruby-indent-level: 3
|
78
|
+
# fill-column: 79
|
79
|
+
# default-justification: full
|
80
|
+
# End:
|
@@ -0,0 +1,134 @@
|
|
1
|
+
#! /your/favourite/path/to/ruby
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
|
4
|
+
# Copyright (c) 2014 Urabe, Shyouhei. All rights reserved.
|
5
|
+
#
|
6
|
+
# Redistribution and use in source and binary forms, with or without
|
7
|
+
# modification, are permitted provided that the following conditions are met:
|
8
|
+
#
|
9
|
+
# - Redistributions of source code must retain the above copyright
|
10
|
+
# notice, this list of conditions and the following disclaimer.
|
11
|
+
#
|
12
|
+
# - Redistributions in binary form must reproduce the above copyright
|
13
|
+
# notice, this list of conditions and the following disclaimer in
|
14
|
+
# the documentation and/or other materials provided with the
|
15
|
+
# distribution.
|
16
|
+
#
|
17
|
+
# - Neither the name of Internet Society, IETF or IETF Trust, nor the
|
18
|
+
# names of specific contributors, may be used to endorse or promote
|
19
|
+
# products derived from this software without specific prior written
|
20
|
+
# permission.
|
21
|
+
#
|
22
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS”
|
23
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
24
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
25
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
26
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
27
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
28
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
29
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
30
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
31
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
32
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
33
|
+
|
34
|
+
# The Arrays, as described in RFC7159 section 5.
|
35
|
+
class RFC7159::Array < RFC7159::Value
|
36
|
+
|
37
|
+
# Parse the AST from parser, and convert into corrsponding values.
|
38
|
+
# @param [::Array] ast the AST, generated by the parser
|
39
|
+
# @return [Array] evaluated instance
|
40
|
+
# @raise [ArgumentError] malformed input
|
41
|
+
def self.from_ast ast
|
42
|
+
type, *ary = *ast
|
43
|
+
raise ArgumentError, "not an object: #{ast.inspect}" if type != :array
|
44
|
+
ary.map! do |a|
|
45
|
+
RFC7159::Value.from_ast a
|
46
|
+
end
|
47
|
+
new ary
|
48
|
+
end
|
49
|
+
|
50
|
+
# fetch the index
|
51
|
+
# @param [Integer] idx index to obtain
|
52
|
+
# @return [Value] corresponding value
|
53
|
+
# @return [nil] not found / out of bounds
|
54
|
+
def [] idx
|
55
|
+
@array[idx]
|
56
|
+
end
|
57
|
+
|
58
|
+
# iterate over the contents
|
59
|
+
# @yield [RFC7159::Value] element
|
60
|
+
def each &b
|
61
|
+
@array.each(&b)
|
62
|
+
end
|
63
|
+
|
64
|
+
# @return [Integer] the count of elements
|
65
|
+
def size
|
66
|
+
@array.size
|
67
|
+
end
|
68
|
+
|
69
|
+
alias length size
|
70
|
+
|
71
|
+
# equality
|
72
|
+
# @param [Array] other comparison target
|
73
|
+
# @return [true] they are equal
|
74
|
+
# @return [false] otherwise.
|
75
|
+
def == other
|
76
|
+
return false unless length == other.length
|
77
|
+
@array.each_index do |i|
|
78
|
+
j = @array[i]
|
79
|
+
k = @other[i]
|
80
|
+
return false unless j == k
|
81
|
+
end
|
82
|
+
return true
|
83
|
+
end
|
84
|
+
|
85
|
+
# @return [::Array] converted array
|
86
|
+
def plain_old_ruby_object
|
87
|
+
@array.map do |i|
|
88
|
+
i.plain_old_ruby_object
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
alias to_a plain_old_ruby_object
|
93
|
+
alias to_ary plain_old_ruby_object
|
94
|
+
|
95
|
+
# JSON gem compat
|
96
|
+
# @return [::String] JSONified representation
|
97
|
+
def to_json
|
98
|
+
RFC7159::Dumper.new.dump self
|
99
|
+
end
|
100
|
+
|
101
|
+
# @return [::String] the array in string
|
102
|
+
def inspect
|
103
|
+
sprintf "#<%p:%#016x %p>", self.class, self.object_id << 1, @array
|
104
|
+
end
|
105
|
+
|
106
|
+
# For pretty print
|
107
|
+
# @param [PP] pp the pp
|
108
|
+
def pretty_print pp
|
109
|
+
hdr = sprintf '#<%p:%#016x', self.class, self.object_id << 1
|
110
|
+
pp.group 1, hdr, '>' do
|
111
|
+
pp.breakable
|
112
|
+
@array.pretty_print pp
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
private
|
117
|
+
private_class_method:new
|
118
|
+
# @private
|
119
|
+
def initialize ary
|
120
|
+
@array = ary
|
121
|
+
@array.freeze
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
#
|
126
|
+
# Local Variables:
|
127
|
+
# mode: ruby
|
128
|
+
# coding: utf-8-unix
|
129
|
+
# indent-tabs-mode: t
|
130
|
+
# tab-width: 3
|
131
|
+
# ruby-indent-level: 3
|
132
|
+
# fill-column: 79
|
133
|
+
# default-justification: full
|
134
|
+
# End:
|
@@ -0,0 +1,231 @@
|
|
1
|
+
#! /your/favourite/path/to/ruby
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
|
4
|
+
# Copyright (c) 2014 Urabe, Shyouhei. All rights reserved.
|
5
|
+
#
|
6
|
+
# Redistribution and use in source and binary forms, with or without
|
7
|
+
# modification, are permitted provided that the following conditions are met:
|
8
|
+
#
|
9
|
+
# - Redistributions of source code must retain the above copyright
|
10
|
+
# notice, this list of conditions and the following disclaimer.
|
11
|
+
#
|
12
|
+
# - Redistributions in binary form must reproduce the above copyright
|
13
|
+
# notice, this list of conditions and the following disclaimer in
|
14
|
+
# the documentation and/or other materials provided with the
|
15
|
+
# distribution.
|
16
|
+
#
|
17
|
+
# - Neither the name of Internet Society, IETF or IETF Trust, nor the
|
18
|
+
# names of specific contributors, may be used to endorse or promote
|
19
|
+
# products derived from this software without specific prior written
|
20
|
+
# permission.
|
21
|
+
#
|
22
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS”
|
23
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
24
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
25
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
26
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
27
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
28
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
29
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
30
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
31
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
32
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
33
|
+
|
34
|
+
require_relative 'value'
|
35
|
+
require 'prettyprint'
|
36
|
+
|
37
|
+
# Dumps ruby object into JSON string
|
38
|
+
class RFC7159::Dumper
|
39
|
+
|
40
|
+
# @param [#<<] port output destination
|
41
|
+
def initialize port
|
42
|
+
@port = port
|
43
|
+
@bag = Hash.new
|
44
|
+
@pp = PrettyPrint.new @port
|
45
|
+
@bag.compare_by_identity
|
46
|
+
end
|
47
|
+
|
48
|
+
# @param [::Object] target target to dump
|
49
|
+
# @return [self] self.
|
50
|
+
def start_dump target
|
51
|
+
dump target
|
52
|
+
return self
|
53
|
+
ensure
|
54
|
+
@bag.clear
|
55
|
+
@pp.flush
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def dump obj
|
61
|
+
obj2 = try_convert obj
|
62
|
+
case obj2
|
63
|
+
when ::Array, RFC7159::Array then
|
64
|
+
ensure_unique obj2
|
65
|
+
@pp.group 1, '[', ']' do
|
66
|
+
obj2.each.with_index do |i, j|
|
67
|
+
@pp.text ',' if j > 0
|
68
|
+
@pp.breakable ''
|
69
|
+
dump i
|
70
|
+
end
|
71
|
+
end
|
72
|
+
when ::Hash, RFC7159::Object then
|
73
|
+
ensure_unique obj2
|
74
|
+
@pp.group 1, '{', '}' do
|
75
|
+
obj2.each_pair.with_index do |(i, j), k|
|
76
|
+
@pp.text ',' if k > 0
|
77
|
+
@pp.breakable ''
|
78
|
+
case i
|
79
|
+
when ::String, RFC7159::String
|
80
|
+
dump i
|
81
|
+
else
|
82
|
+
dump i.to_str # should raise for non-string-ish
|
83
|
+
end
|
84
|
+
@pp.text ':'
|
85
|
+
dump j
|
86
|
+
end
|
87
|
+
end
|
88
|
+
when RFC7159::Value then
|
89
|
+
obj3 = obj2.to_json
|
90
|
+
@pp.text obj3
|
91
|
+
when ::String then
|
92
|
+
obj3 = try_escape_string obj2
|
93
|
+
@pp.text '"'
|
94
|
+
@pp.text obj3
|
95
|
+
@pp.text '"'
|
96
|
+
when ::Numeric then
|
97
|
+
obj3 = try_stringize_numeric obj2
|
98
|
+
@pp.text obj3
|
99
|
+
when ::TrueClass then
|
100
|
+
@pp.text 'true'
|
101
|
+
when ::FalseClass then
|
102
|
+
@pp.text 'false'
|
103
|
+
when ::NilClass then
|
104
|
+
@pp.text 'null'
|
105
|
+
else
|
106
|
+
begin
|
107
|
+
# Try fallback
|
108
|
+
@pp.text obj2.to_json
|
109
|
+
rescue NoMethodError
|
110
|
+
raise TypeError, "not JSONable: #{obj}"
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
# Check repetition. JSON is a true tree -- no cyclic lists, nor even direct
|
116
|
+
# acyclic graphs are allowed. We check that here.
|
117
|
+
#
|
118
|
+
# - strings, numbers, booleans are all OK to appear multiple times.
|
119
|
+
# - empty arrays and empty hashes are special-cased OK.
|
120
|
+
# - other cases are subject to appear exactly once.
|
121
|
+
def ensure_unique obj
|
122
|
+
if @bag.include? obj and not obj2.empty?
|
123
|
+
raise Errno::ELOOP, "target appears twice: #{target.inspect}"
|
124
|
+
else
|
125
|
+
@bag.store obj, obj
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def try_convert obj
|
130
|
+
case obj
|
131
|
+
when RFC7159::Value, Hash, Array, String, Integer, Float, BigDecimal, TrueClass, FalseClass, NilClass
|
132
|
+
return obj
|
133
|
+
else
|
134
|
+
begin
|
135
|
+
return obj.to_hash
|
136
|
+
rescue NoMethodError
|
137
|
+
begin
|
138
|
+
return obj.to_ary
|
139
|
+
rescue NoMethodError
|
140
|
+
begin
|
141
|
+
return obj.to_str
|
142
|
+
rescue NoMethodError
|
143
|
+
begin
|
144
|
+
return obj.to_int
|
145
|
+
rescue NoMethodError
|
146
|
+
begin
|
147
|
+
return obj.to_f
|
148
|
+
rescue NoMethodError
|
149
|
+
raise TypeError, "not JSONable: #{obj.class}"
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def try_escape_string str
|
159
|
+
buf = nil
|
160
|
+
|
161
|
+
begin
|
162
|
+
# fast path
|
163
|
+
if str.valid_encoding?
|
164
|
+
str2 = str.encode Encoding::UTF_8
|
165
|
+
buf = str.unpack('U*')
|
166
|
+
end
|
167
|
+
rescue Encoding::UndefinedConversionError
|
168
|
+
# str might be invalid, but that's OK as per RFC7159 section 8.2.
|
169
|
+
end
|
170
|
+
|
171
|
+
unless buf
|
172
|
+
case str.encoding
|
173
|
+
when Encoding::UTF_32BE then buf = str.unpack 'N*'
|
174
|
+
when Encoding::UTF_32LE then buf = str.unpack 'V*'
|
175
|
+
when Encoding::UTF_16BE then buf = str.unpack 'n*'
|
176
|
+
when Encoding::UTF_16LE then buf = str.unpack 'v*'
|
177
|
+
when Encoding::UTF_8,
|
178
|
+
Encoding::UTF8_MAC,
|
179
|
+
Encoding::US_ASCII then buf = str.unpack 'U*'
|
180
|
+
else buf = str.unpack 'C*' # fallback
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
# We don't escape \/, because that seems to be de facto standard.
|
185
|
+
return buf.inject '' do |r, i|
|
186
|
+
c = nil
|
187
|
+
case i
|
188
|
+
when 0x22 then c = '\\"' # " quotation mark U+0022
|
189
|
+
when 0x5C then c = '\\\\' # \ reverse solidus U+005C
|
190
|
+
# when 0x2F then c = '\\/' # / solidus U+002F
|
191
|
+
when 0x08 then c = '\\b' # b backspace U+0008
|
192
|
+
when 0x0C then c = '\\f' # f form feed U+000C
|
193
|
+
when 0x0A then c = '\\n' # n line feed U+000A
|
194
|
+
when 0x0D then c = '\\r' # r carriage return U+000D
|
195
|
+
when 0x09 then c = '\\t' # t tab U+0009
|
196
|
+
when 0x00..0x1F, 0xD800..0xDFFF then
|
197
|
+
c = sprintf '\\u%04X', i
|
198
|
+
else
|
199
|
+
c = [i].pack 'U'
|
200
|
+
end
|
201
|
+
r << c
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
def try_stringize_numeric num
|
206
|
+
case num
|
207
|
+
when Float, BigDecimal
|
208
|
+
if num.finite?
|
209
|
+
# FIXME: does this lose precision?
|
210
|
+
num.to_s
|
211
|
+
else
|
212
|
+
raise TypeError, "not JSONable: #{num.inspect}"
|
213
|
+
end
|
214
|
+
when Integer
|
215
|
+
return num.to_s
|
216
|
+
else
|
217
|
+
raise TypeError, "not JSONable: #{num.inspect}"
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
#
|
223
|
+
# Local Variables:
|
224
|
+
# mode: ruby
|
225
|
+
# coding: utf-8-unix
|
226
|
+
# indent-tabs-mode: t
|
227
|
+
# tab-width: 3
|
228
|
+
# ruby-indent-level: 3
|
229
|
+
# fill-column: 79
|
230
|
+
# default-justification: full
|
231
|
+
# End:
|