RFC7159 7159

Sign up to get free protection for your applications and to get access to all the features.
Files changed (177) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +61 -0
  3. data/.rspec +4 -0
  4. data/.yardopts +2 -0
  5. data/Gemfile +46 -0
  6. data/LICENSE.txt +40 -0
  7. data/README.txt +899 -0
  8. data/RFC7159 +899 -0
  9. data/RFC7159.gemspec +85 -0
  10. data/Rakefile +82 -0
  11. data/lib/RFC7159.rb +80 -0
  12. data/lib/RFC7159/array.rb +134 -0
  13. data/lib/RFC7159/dumper.rb +231 -0
  14. data/lib/RFC7159/false.rb +79 -0
  15. data/lib/RFC7159/null.rb +79 -0
  16. data/lib/RFC7159/number.rb +149 -0
  17. data/lib/RFC7159/object.rb +140 -0
  18. data/lib/RFC7159/parser.ry +267 -0
  19. data/lib/RFC7159/string.rb +221 -0
  20. data/lib/RFC7159/true.rb +79 -0
  21. data/lib/RFC7159/value.rb +96 -0
  22. data/lib/RFC7159/version.rb +48 -0
  23. data/spec/RFC7159_spec.rb +275 -0
  24. data/spec/acceptance/README.txt +66 -0
  25. data/spec/acceptance/invalid/0001-ws/0001-verical-tab.txt +1 -0
  26. data/spec/acceptance/invalid/0001-ws/0002-null.txt +0 -0
  27. data/spec/acceptance/invalid/0001-ws/0003-space-in-number-1.txt +1 -0
  28. data/spec/acceptance/invalid/0001-ws/0004-space-in-number-2.txt +1 -0
  29. data/spec/acceptance/invalid/0001-ws/0005-space-in-number-3.txt +1 -0
  30. data/spec/acceptance/invalid/0001-ws/0006-space-in-number-4.txt +1 -0
  31. data/spec/acceptance/invalid/0001-ws/0007-space-in-number-5.txt +1 -0
  32. data/spec/acceptance/invalid/0001-ws/0008-space-in-number-6.txt +1 -0
  33. data/spec/acceptance/invalid/0001-ws/0009-space-in-literal.txt +1 -0
  34. data/spec/acceptance/invalid/0001-ws/0010-Unicode-LINE_SEPARATOR.txt +1 -0
  35. data/spec/acceptance/invalid/0002-comments/0001-C-style.txt +1 -0
  36. data/spec/acceptance/invalid/0002-comments/0002-C-plusplus-style.txt +2 -0
  37. data/spec/acceptance/invalid/0002-comments/0003-sh-style.txt +2 -0
  38. data/spec/acceptance/invalid/0002-comments/0004-python-docstring.txt +3 -0
  39. data/spec/acceptance/invalid/0002-comments/0005-SQL-style.txt +2 -0
  40. data/spec/acceptance/invalid/0002-comments/0006-BASIC-style.txt +2 -0
  41. data/spec/acceptance/invalid/0003-literals/0001-FALSE.txt +1 -0
  42. data/spec/acceptance/invalid/0003-literals/0002-NULL.txt +1 -0
  43. data/spec/acceptance/invalid/0003-literals/0003-TRUE.txt +1 -0
  44. data/spec/acceptance/invalid/0003-literals/0004-NUL.txt +1 -0
  45. data/spec/acceptance/invalid/0003-literals/0005-nil.txt +1 -0
  46. data/spec/acceptance/invalid/0003-literals/0006-undef.txt +1 -0
  47. data/spec/acceptance/invalid/0003-literals/0007-modifier.txt +1 -0
  48. data/spec/acceptance/invalid/0003-literals/0008-undefined.txt +1 -0
  49. data/spec/acceptance/invalid/0004-numbers/0001-omit-zero.txt +1 -0
  50. data/spec/acceptance/invalid/0004-numbers/0002-minus-dot.txt +1 -0
  51. data/spec/acceptance/invalid/0004-numbers/0003-missing-frac.txt +1 -0
  52. data/spec/acceptance/invalid/0004-numbers/0004-missing-exp.txt +1 -0
  53. data/spec/acceptance/invalid/0004-numbers/0005-octal.txt +1 -0
  54. data/spec/acceptance/invalid/0004-numbers/0006-hexadecimal.txt +1 -0
  55. data/spec/acceptance/invalid/0004-numbers/0007-comma.txt +1 -0
  56. data/spec/acceptance/invalid/0004-numbers/0008-perl-underscore.txt +1 -0
  57. data/spec/acceptance/invalid/0004-numbers/0009-NaN.txt +1 -0
  58. data/spec/acceptance/invalid/0004-numbers/0010-Inf.txt +1 -0
  59. data/spec/acceptance/invalid/0004-numbers/0011-Infinity.txt +1 -0
  60. data/spec/acceptance/invalid/0005-strings/0000-NUL.txt +0 -0
  61. data/spec/acceptance/invalid/0005-strings/0001-not-terminated.txt +1 -0
  62. data/spec/acceptance/invalid/0005-strings/0002-single-quote.txt +1 -0
  63. data/spec/acceptance/invalid/0005-strings/0003-back-quote.txt +1 -0
  64. data/spec/acceptance/invalid/0005-strings/0004-carriage-return.txt +1 -0
  65. data/spec/acceptance/invalid/0005-strings/0005-line-feed.txt +2 -0
  66. data/spec/acceptance/invalid/0005-strings/0006-unknown-escape-a.txt +1 -0
  67. data/spec/acceptance/invalid/0005-strings/0007-unknown-escape-perl-style.txt +1 -0
  68. data/spec/acceptance/invalid/0005-strings/0008-unknown-escape-C-style.txt +1 -0
  69. data/spec/acceptance/invalid/0005-strings/0009-unknown-escape-ruby-style.txt +1 -0
  70. data/spec/acceptance/invalid/0005-strings/0010-escape-too-short.txt +1 -0
  71. data/spec/acceptance/invalid/0005-strings/0011-C-string-concat.txt +1 -0
  72. data/spec/acceptance/invalid/0005-strings/0012-perl-string-concat.txt +1 -0
  73. data/spec/acceptance/invalid/0005-strings/0013-Java-string-concat.txt +1 -0
  74. data/spec/acceptance/invalid/0006-encodings/0001-CESU-8.txt +1 -0
  75. data/spec/acceptance/invalid/0006-encodings/0002-Windows-31J.txt +1 -0
  76. data/spec/acceptance/invalid/0006-encodings/0003-EBCDIC.txt +1 -0
  77. data/spec/acceptance/invalid/0006-encodings/0004-overlong-utf8.txt +1 -0
  78. data/spec/acceptance/invalid/0007-arrays/0001-lacks-open.txt +1 -0
  79. data/spec/acceptance/invalid/0007-arrays/0002-lacks-close.txt +1 -0
  80. data/spec/acceptance/invalid/0007-arrays/0003-interleaving-parens.txt +1 -0
  81. data/spec/acceptance/invalid/0007-arrays/0004-dangling-comma.txt +1 -0
  82. data/spec/acceptance/invalid/0007-arrays/0005-missing-comma.txt +1 -0
  83. data/spec/acceptance/invalid/0007-arrays/0006-colon-instead-of-comma.txt +1 -0
  84. data/spec/acceptance/invalid/0008-hashes/0001-key-missing.txt +1 -0
  85. data/spec/acceptance/invalid/0008-hashes/0002-value-missing.txt +1 -0
  86. data/spec/acceptance/invalid/0008-hashes/0003-true-key.txt +1 -0
  87. data/spec/acceptance/invalid/0008-hashes/0004-false-key.txt +1 -0
  88. data/spec/acceptance/invalid/0008-hashes/0005-null-key.txt +1 -0
  89. data/spec/acceptance/invalid/0008-hashes/0006-numeric-key.txt +1 -0
  90. data/spec/acceptance/invalid/0008-hashes/0007-array-key.txt +1 -0
  91. data/spec/acceptance/invalid/0008-hashes/0008-hash-key.txt +1 -0
  92. data/spec/acceptance/invalid/0008-hashes/0009-key-not-escaped.txt +4 -0
  93. data/spec/acceptance/invalid/0009-javascriptisms/0001-JSONP.txt +1 -0
  94. data/spec/acceptance/invalid/0009-javascriptisms/0002-new-Array.txt +3 -0
  95. data/spec/acceptance/invalid/0009-javascriptisms/0003-new-Date.txt +1 -0
  96. data/spec/acceptance/invalid/0009-javascriptisms/0004-new-Error.txt +1 -0
  97. data/spec/acceptance/invalid/0009-javascriptisms/0005-Math.txt +1 -0
  98. data/spec/acceptance/invalid/0009-javascriptisms/0006-regular-expression.txt +1 -0
  99. data/spec/acceptance/invalid/0009-javascriptisms/0007-function.txt +7 -0
  100. data/spec/acceptance/invalid/0009-javascriptisms/0008-this.txt +1 -0
  101. data/spec/acceptance/invalid/0009-javascriptisms/0009-plusplus.txt +3 -0
  102. data/spec/acceptance/invalid/0009-javascriptisms/0010-ternary-operator.txt +1 -0
  103. data/spec/acceptance/valid/0001-ws/0001-space.json +1 -0
  104. data/spec/acceptance/valid/0001-ws/0002-tab.json +1 -0
  105. data/spec/acceptance/valid/0001-ws/0003-lf.json +1 -0
  106. data/spec/acceptance/valid/0001-ws/0004-cr.json +1 -0
  107. data/spec/acceptance/valid/0001-ws/0005-before.json +1 -0
  108. data/spec/acceptance/valid/0001-ws/0006-after.json +1 -0
  109. data/spec/acceptance/valid/0001-ws/0007-around-comma.json +3 -0
  110. data/spec/acceptance/valid/0001-ws/0008-around-colon.json +3 -0
  111. data/spec/acceptance/valid/0002-bare-values/0001-false.json +1 -0
  112. data/spec/acceptance/valid/0002-bare-values/0002-null.json +1 -0
  113. data/spec/acceptance/valid/0002-bare-values/0003-true.json +1 -0
  114. data/spec/acceptance/valid/0002-bare-values/0004-number.json +1 -0
  115. data/spec/acceptance/valid/0002-bare-values/0005-string.json +1 -0
  116. data/spec/acceptance/valid/0003-literals/0001-false.json +1 -0
  117. data/spec/acceptance/valid/0003-literals/0002-null.json +1 -0
  118. data/spec/acceptance/valid/0003-literals/0003-true.json +1 -0
  119. data/spec/acceptance/valid/0004-numbers/0000-zero.json +1 -0
  120. data/spec/acceptance/valid/0004-numbers/0001-one.json +1 -0
  121. data/spec/acceptance/valid/0004-numbers/0002-two.json +1 -0
  122. data/spec/acceptance/valid/0004-numbers/0003-three.json +1 -0
  123. data/spec/acceptance/valid/0004-numbers/0004-four.json +1 -0
  124. data/spec/acceptance/valid/0004-numbers/0005-five.json +1 -0
  125. data/spec/acceptance/valid/0004-numbers/0006-six.json +1 -0
  126. data/spec/acceptance/valid/0004-numbers/0007-seven.json +1 -0
  127. data/spec/acceptance/valid/0004-numbers/0008-eight.json +1 -0
  128. data/spec/acceptance/valid/0004-numbers/0009-nine.json +1 -0
  129. data/spec/acceptance/valid/0004-numbers/0010-ten.json +1 -0
  130. data/spec/acceptance/valid/0004-numbers/0011-minus.json +1 -0
  131. data/spec/acceptance/valid/0004-numbers/0012-fraction.json +1 -0
  132. data/spec/acceptance/valid/0004-numbers/0013-exponent.json +1 -0
  133. data/spec/acceptance/valid/0004-numbers/0014-exponent-minus.json +1 -0
  134. data/spec/acceptance/valid/0004-numbers/0015-exponent-plus.json +1 -0
  135. data/spec/acceptance/valid/0004-numbers/0016-complex.json +1 -0
  136. data/spec/acceptance/valid/0004-numbers/0017-DBL_MAX.json +1 -0
  137. data/spec/acceptance/valid/0004-numbers/0018-DBL_MIN.json +1 -0
  138. data/spec/acceptance/valid/0004-numbers/0019-subnormal-number.json +1 -0
  139. data/spec/acceptance/valid/0004-numbers/0020-1E400.json +1 -0
  140. data/spec/acceptance/valid/0004-numbers/0021-pi.json +1 -0
  141. data/spec/acceptance/valid/0004-numbers/0022-UINT32_MAX.json +1 -0
  142. data/spec/acceptance/valid/0004-numbers/0023-UINT64_MAX.json +1 -0
  143. data/spec/acceptance/valid/0004-numbers/0024-INT64_MIN.json +1 -0
  144. data/spec/acceptance/valid/0004-numbers/0025-high-resolution-zero.json +1 -0
  145. data/spec/acceptance/valid/0005-strings/0001-empty.json +1 -0
  146. data/spec/acceptance/valid/0005-strings/0002-basic-latin.json +1 -0
  147. data/spec/acceptance/valid/0005-strings/0003-escapes.json +1 -0
  148. data/spec/acceptance/valid/0005-strings/0004-raw-unicode.json +1 -0
  149. data/spec/acceptance/valid/0005-strings/0005-escaped-unicode.json +1 -0
  150. data/spec/acceptance/valid/0005-strings/0006-escaped-NUL.json +1 -0
  151. data/spec/acceptance/valid/0005-strings/0007-escaped-invalid-unicode-still-valid-as-json.json +1 -0
  152. data/spec/acceptance/valid/0005-strings/0008-ruby-json-gem-cant-handle-this.json +1 -0
  153. data/spec/acceptance/valid/0005-strings/0009-unescaped-invalid-javascript-still-valid-as-json.json +1 -0
  154. data/spec/acceptance/valid/0006-m17n/0001-genesis.json +6 -0
  155. data/spec/acceptance/valid/0006-m17n/0002-heart-sutra.json +5 -0
  156. data/spec/acceptance/valid/0006-m17n/0003-escaped-valid-surrogate-pair.json +1 -0
  157. data/spec/acceptance/valid/0006-m17n/0004-unescaped-valid-supplementary-multilingual-plane.json +1 -0
  158. data/spec/acceptance/valid/0007-arrays/0000-empty.json +1 -0
  159. data/spec/acceptance/valid/0007-arrays/0001-one-element.json +1 -0
  160. data/spec/acceptance/valid/0007-arrays/0002-multiple-elements.json +33 -0
  161. data/spec/acceptance/valid/0007-arrays/0003-various-types.json +1 -0
  162. data/spec/acceptance/valid/0007-arrays/0004-nested.json +17 -0
  163. data/spec/acceptance/valid/0008-hashes/0000-empty.json +1 -0
  164. data/spec/acceptance/valid/0008-hashes/0001-onekey.json +1 -0
  165. data/spec/acceptance/valid/0008-hashes/0002-many-keys.json +5 -0
  166. data/spec/acceptance/valid/0008-hashes/0003-empty-key.json +3 -0
  167. data/spec/acceptance/valid/0008-hashes/0004-true-value.json +3 -0
  168. data/spec/acceptance/valid/0008-hashes/0005-false-value.json +3 -0
  169. data/spec/acceptance/valid/0008-hashes/0006-null-value.json +3 -0
  170. data/spec/acceptance/valid/0008-hashes/0007-string-value.json +3 -0
  171. data/spec/acceptance/valid/0008-hashes/0008-numeric-value.json +3 -0
  172. data/spec/acceptance/valid/0008-hashes/0009-array-value.json +8 -0
  173. data/spec/acceptance/valid/0008-hashes/0010-hash-value.json +20 -0
  174. data/spec/acceptance/valid/0008-hashes/0011-duplicate-key-in-different-representations.json +4 -0
  175. data/spec/acceptance/valid/0008-hashes/0011-duplicate-key.json +4 -0
  176. data/spec/spec_helper.rb +54 -0
  177. metadata +520 -0
@@ -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:
@@ -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:
@@ -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: