From 1abcac36823dc97bc1a0383077f23acf19b6370e Mon Sep 17 00:00:00 2001 From: zverok Date: Thu, 8 Mar 2018 17:32:36 +0200 Subject: [PATCH] Enchance generic JSON and #generate docs --- lib/json.rb | 50 +- lib/json/common.rb | 29 +- tmp/rdoc/BigDecimal.html | 239 + tmp/rdoc/CHANGES_md.html | 927 ++++ tmp/rdoc/Class.html | 160 + tmp/rdoc/Complex.html | 240 + tmp/rdoc/Date.html | 243 + tmp/rdoc/DateTime.html | 258 + tmp/rdoc/Exception.html | 242 + tmp/rdoc/Fuzzer.html | 354 ++ tmp/rdoc/Gemfile.html | 218 + tmp/rdoc/JSON.html | 989 ++++ tmp/rdoc/JSON/CircularDatastructure.html | 103 + tmp/rdoc/JSON/Ext.html | 99 + tmp/rdoc/JSON/Ext/Generator.html | 104 + .../JSON/Ext/Generator/GeneratorMethods.html | 96 + .../Ext/Generator/GeneratorMethods/Array.html | 153 + .../Generator/GeneratorMethods/Bignum.html | 151 + .../GeneratorMethods/FalseClass.html | 151 + .../Generator/GeneratorMethods/Fixnum.html | 151 + .../Ext/Generator/GeneratorMethods/Float.html | 151 + .../Ext/Generator/GeneratorMethods/Hash.html | 154 + .../Generator/GeneratorMethods/Integer.html | 151 + .../Generator/GeneratorMethods/NilClass.html | 151 + .../Generator/GeneratorMethods/Object.html | 159 + .../Generator/GeneratorMethods/String.html | 289 ++ .../GeneratorMethods/String/Extend.html | 155 + .../Generator/GeneratorMethods/TrueClass.html | 151 + tmp/rdoc/JSON/Ext/Generator/State.html | 1518 ++++++ tmp/rdoc/JSON/Ext/Parser.html | 540 ++ tmp/rdoc/JSON/GeneratorError.html | 105 + tmp/rdoc/JSON/GenericObject.html | 547 ++ tmp/rdoc/JSON/JSONError.html | 158 + tmp/rdoc/JSON/MissingUnicodeSupport.html | 106 + tmp/rdoc/JSON/NestingError.html | 106 + tmp/rdoc/JSON/ParserError.html | 105 + tmp/rdoc/JSON/Pure.html | 99 + tmp/rdoc/JSON/Pure/Generator.html | 96 + .../JSON/Pure/Generator/GeneratorMethods.html | 96 + .../Generator/GeneratorMethods/Array.html | 153 + .../GeneratorMethods/FalseClass.html | 146 + .../Generator/GeneratorMethods/Float.html | 164 + .../Pure/Generator/GeneratorMethods/Hash.html | 154 + .../Generator/GeneratorMethods/Integer.html | 146 + .../Generator/GeneratorMethods/NilClass.html | 146 + .../Generator/GeneratorMethods/Object.html | 149 + .../Generator/GeneratorMethods/String.html | 294 ++ .../GeneratorMethods/String/Extend.html | 152 + .../Generator/GeneratorMethods/TrueClass.html | 146 + tmp/rdoc/JSON/Pure/Generator/State.html | 760 +++ tmp/rdoc/JSON/Pure/Parser.html | 918 ++++ tmp/rdoc/JSONAdditionTest.html | 648 +++ tmp/rdoc/JSONAdditionTest/A.html | 291 ++ tmp/rdoc/JSONAdditionTest/A2.html | 157 + tmp/rdoc/JSONAdditionTest/B.html | 199 + tmp/rdoc/JSONAdditionTest/C.html | 199 + tmp/rdoc/JSONCommonInterfaceTest.html | 805 +++ tmp/rdoc/JSONEncodingTest.html | 385 ++ tmp/rdoc/JSONExtParserTest.html | 159 + tmp/rdoc/JSONFixturesTest.html | 240 + tmp/rdoc/JSONGeneratorTest.html | 1239 +++++ tmp/rdoc/JSONGenericObjectTest.html | 383 ++ tmp/rdoc/JSONParserTest.html | 1457 ++++++ tmp/rdoc/JSONParserTest/Encoding.html | 96 + tmp/rdoc/JSONParserTest/SubArray.html | 195 + tmp/rdoc/JSONParserTest/SubArray2.html | 201 + tmp/rdoc/JSONParserTest/SubArrayWrapper.html | 289 ++ tmp/rdoc/JSONParserTest/SubHash.html | 195 + tmp/rdoc/JSONParserTest/SubHash2.html | 200 + tmp/rdoc/JSONParserTest/SubOpenStruct.html | 225 + tmp/rdoc/JSONServlet.html | 170 + tmp/rdoc/JSONStringMatchingTest.html | 178 + tmp/rdoc/JSONStringMatchingTest/TestTime.html | 232 + tmp/rdoc/Kernel.html | 96 + tmp/rdoc/MyState.html | 225 + tmp/rdoc/Object.html | 183 + tmp/rdoc/OpenStruct.html | 241 + tmp/rdoc/README-json-jruby_md.html | 241 + tmp/rdoc/README_md.html | 627 +++ tmp/rdoc/Rakefile.html | 641 +++ tmp/rdoc/Range.html | 241 + tmp/rdoc/Rational.html | 240 + tmp/rdoc/Regexp.html | 240 + tmp/rdoc/Set.html | 239 + tmp/rdoc/Struct.html | 242 + tmp/rdoc/Symbol.html | 239 + tmp/rdoc/Time.html | 250 + tmp/rdoc/VERSION.html | 200 + tmp/rdoc/created.rid | 34 + tmp/rdoc/css/fonts.css | 167 + tmp/rdoc/css/rdoc.css | 590 +++ tmp/rdoc/data/example_json.html | 202 + tmp/rdoc/data/index_html.html | 243 + tmp/rdoc/data/prototype_js.html | 4566 +++++++++++++++++ tmp/rdoc/ext/json/ext/generator/depend.html | 86 + tmp/rdoc/ext/json/ext/parser/depend.html | 86 + tmp/rdoc/ext/json/ext/parser/parser_rl.html | 1022 ++++ tmp/rdoc/fonts/Lato-Light.ttf | Bin 0 -> 94668 bytes tmp/rdoc/fonts/Lato-LightItalic.ttf | Bin 0 -> 94196 bytes tmp/rdoc/fonts/Lato-Regular.ttf | Bin 0 -> 96184 bytes tmp/rdoc/fonts/Lato-RegularItalic.ttf | Bin 0 -> 95316 bytes tmp/rdoc/fonts/SourceCodePro-Bold.ttf | Bin 0 -> 71200 bytes tmp/rdoc/fonts/SourceCodePro-Regular.ttf | Bin 0 -> 71692 bytes tmp/rdoc/images/add.png | Bin 0 -> 733 bytes tmp/rdoc/images/arrow_up.png | Bin 0 -> 372 bytes tmp/rdoc/images/brick.png | Bin 0 -> 452 bytes tmp/rdoc/images/brick_link.png | Bin 0 -> 764 bytes tmp/rdoc/images/bug.png | Bin 0 -> 774 bytes tmp/rdoc/images/bullet_black.png | Bin 0 -> 211 bytes tmp/rdoc/images/bullet_toggle_minus.png | Bin 0 -> 207 bytes tmp/rdoc/images/bullet_toggle_plus.png | Bin 0 -> 209 bytes tmp/rdoc/images/date.png | Bin 0 -> 626 bytes tmp/rdoc/images/delete.png | Bin 0 -> 715 bytes tmp/rdoc/images/find.png | Bin 0 -> 659 bytes tmp/rdoc/images/loadingAnimation.gif | Bin 0 -> 5886 bytes tmp/rdoc/images/macFFBgHack.png | Bin 0 -> 207 bytes tmp/rdoc/images/package.png | Bin 0 -> 853 bytes tmp/rdoc/images/page_green.png | Bin 0 -> 621 bytes tmp/rdoc/images/page_white_text.png | Bin 0 -> 342 bytes tmp/rdoc/images/page_white_width.png | Bin 0 -> 309 bytes tmp/rdoc/images/plugin.png | Bin 0 -> 591 bytes tmp/rdoc/images/ruby.png | Bin 0 -> 592 bytes tmp/rdoc/images/tag_blue.png | Bin 0 -> 1880 bytes tmp/rdoc/images/tag_green.png | Bin 0 -> 613 bytes tmp/rdoc/images/transparent.png | Bin 0 -> 97 bytes tmp/rdoc/images/wrench.png | Bin 0 -> 610 bytes tmp/rdoc/images/wrench_orange.png | Bin 0 -> 584 bytes tmp/rdoc/images/zoom.png | Bin 0 -> 692 bytes tmp/rdoc/index.html | 176 + .../src/json/ext/ByteListTranscoder_java.html | 363 ++ .../src/json/ext/GeneratorMethods_java.html | 425 ++ .../src/json/ext/GeneratorService_java.html | 241 + .../src/json/ext/GeneratorState_java.html | 686 +++ .../java/src/json/ext/Generator_java.html | 633 +++ .../java/src/json/ext/OptionsReader_java.html | 309 ++ .../java/src/json/ext/ParserService_java.html | 233 + tmp/rdoc/java/src/json/ext/Parser_java.html | 2681 ++++++++++ tmp/rdoc/java/src/json/ext/Parser_rl.html | 1084 ++++ .../java/src/json/ext/RuntimeInfo_java.html | 310 ++ .../java/src/json/ext/StringDecoder_java.html | 367 ++ .../java/src/json/ext/StringEncoder_java.html | 310 ++ tmp/rdoc/java/src/json/ext/Utils_java.html | 285 + tmp/rdoc/js/darkfish.js | 161 + tmp/rdoc/js/jquery.js | 4 + tmp/rdoc/js/navigation.js | 142 + tmp/rdoc/js/navigation.js.gz | Bin 0 -> 1021 bytes tmp/rdoc/js/search.js | 109 + tmp/rdoc/js/search_index.js | 1 + tmp/rdoc/js/search_index.js.gz | Bin 0 -> 5897 bytes tmp/rdoc/js/searcher.js | 229 + tmp/rdoc/js/searcher.js.gz | Bin 0 -> 1694 bytes tmp/rdoc/json-java_gemspec.html | 245 + tmp/rdoc/json_pure_gemspec.html | 239 + tmp/rdoc/references/rfc7159_txt.html | 928 ++++ tmp/rdoc/table_of_contents.html | 832 +++ tmp/rdoc/tests/fixtures/fail10_json.html | 200 + tmp/rdoc/tests/fixtures/fail11_json.html | 200 + tmp/rdoc/tests/fixtures/fail12_json.html | 200 + tmp/rdoc/tests/fixtures/fail13_json.html | 200 + tmp/rdoc/tests/fixtures/fail14_json.html | 200 + tmp/rdoc/tests/fixtures/fail18_json.html | 200 + tmp/rdoc/tests/fixtures/fail19_json.html | 200 + tmp/rdoc/tests/fixtures/fail20_json.html | 202 + tmp/rdoc/tests/fixtures/fail21_json.html | 200 + tmp/rdoc/tests/fixtures/fail22_json.html | 200 + tmp/rdoc/tests/fixtures/fail23_json.html | 200 + tmp/rdoc/tests/fixtures/fail24_json.html | 200 + tmp/rdoc/tests/fixtures/fail25_json.html | 200 + tmp/rdoc/tests/fixtures/fail27_json.html | 200 + tmp/rdoc/tests/fixtures/fail28_json.html | 200 + tmp/rdoc/tests/fixtures/fail2_json.html | 200 + tmp/rdoc/tests/fixtures/fail3_json.html | 200 + tmp/rdoc/tests/fixtures/fail4_json.html | 200 + tmp/rdoc/tests/fixtures/fail5_json.html | 200 + tmp/rdoc/tests/fixtures/fail6_json.html | 200 + tmp/rdoc/tests/fixtures/fail7_json.html | 200 + tmp/rdoc/tests/fixtures/fail8_json.html | 200 + tmp/rdoc/tests/fixtures/fail9_json.html | 200 + .../tests/fixtures/obsolete_fail1_json.html | 201 + tmp/rdoc/tests/fixtures/pass15_json.html | 200 + tmp/rdoc/tests/fixtures/pass16_json.html | 200 + tmp/rdoc/tests/fixtures/pass17_json.html | 200 + tmp/rdoc/tests/fixtures/pass1_json.html | 257 + tmp/rdoc/tests/fixtures/pass26_json.html | 200 + tmp/rdoc/tests/fixtures/pass2_json.html | 200 + tmp/rdoc/tests/fixtures/pass3_json.html | 207 + tmp/rdoc/tools/diff_sh.html | 218 + 187 files changed, 49866 insertions(+), 18 deletions(-) create mode 100644 tmp/rdoc/BigDecimal.html create mode 100644 tmp/rdoc/CHANGES_md.html create mode 100644 tmp/rdoc/Class.html create mode 100644 tmp/rdoc/Complex.html create mode 100644 tmp/rdoc/Date.html create mode 100644 tmp/rdoc/DateTime.html create mode 100644 tmp/rdoc/Exception.html create mode 100644 tmp/rdoc/Fuzzer.html create mode 100644 tmp/rdoc/Gemfile.html create mode 100644 tmp/rdoc/JSON.html create mode 100644 tmp/rdoc/JSON/CircularDatastructure.html create mode 100644 tmp/rdoc/JSON/Ext.html create mode 100644 tmp/rdoc/JSON/Ext/Generator.html create mode 100644 tmp/rdoc/JSON/Ext/Generator/GeneratorMethods.html create mode 100644 tmp/rdoc/JSON/Ext/Generator/GeneratorMethods/Array.html create mode 100644 tmp/rdoc/JSON/Ext/Generator/GeneratorMethods/Bignum.html create mode 100644 tmp/rdoc/JSON/Ext/Generator/GeneratorMethods/FalseClass.html create mode 100644 tmp/rdoc/JSON/Ext/Generator/GeneratorMethods/Fixnum.html create mode 100644 tmp/rdoc/JSON/Ext/Generator/GeneratorMethods/Float.html create mode 100644 tmp/rdoc/JSON/Ext/Generator/GeneratorMethods/Hash.html create mode 100644 tmp/rdoc/JSON/Ext/Generator/GeneratorMethods/Integer.html create mode 100644 tmp/rdoc/JSON/Ext/Generator/GeneratorMethods/NilClass.html create mode 100644 tmp/rdoc/JSON/Ext/Generator/GeneratorMethods/Object.html create mode 100644 tmp/rdoc/JSON/Ext/Generator/GeneratorMethods/String.html create mode 100644 tmp/rdoc/JSON/Ext/Generator/GeneratorMethods/String/Extend.html create mode 100644 tmp/rdoc/JSON/Ext/Generator/GeneratorMethods/TrueClass.html create mode 100644 tmp/rdoc/JSON/Ext/Generator/State.html create mode 100644 tmp/rdoc/JSON/Ext/Parser.html create mode 100644 tmp/rdoc/JSON/GeneratorError.html create mode 100644 tmp/rdoc/JSON/GenericObject.html create mode 100644 tmp/rdoc/JSON/JSONError.html create mode 100644 tmp/rdoc/JSON/MissingUnicodeSupport.html create mode 100644 tmp/rdoc/JSON/NestingError.html create mode 100644 tmp/rdoc/JSON/ParserError.html create mode 100644 tmp/rdoc/JSON/Pure.html create mode 100644 tmp/rdoc/JSON/Pure/Generator.html create mode 100644 tmp/rdoc/JSON/Pure/Generator/GeneratorMethods.html create mode 100644 tmp/rdoc/JSON/Pure/Generator/GeneratorMethods/Array.html create mode 100644 tmp/rdoc/JSON/Pure/Generator/GeneratorMethods/FalseClass.html create mode 100644 tmp/rdoc/JSON/Pure/Generator/GeneratorMethods/Float.html create mode 100644 tmp/rdoc/JSON/Pure/Generator/GeneratorMethods/Hash.html create mode 100644 tmp/rdoc/JSON/Pure/Generator/GeneratorMethods/Integer.html create mode 100644 tmp/rdoc/JSON/Pure/Generator/GeneratorMethods/NilClass.html create mode 100644 tmp/rdoc/JSON/Pure/Generator/GeneratorMethods/Object.html create mode 100644 tmp/rdoc/JSON/Pure/Generator/GeneratorMethods/String.html create mode 100644 tmp/rdoc/JSON/Pure/Generator/GeneratorMethods/String/Extend.html create mode 100644 tmp/rdoc/JSON/Pure/Generator/GeneratorMethods/TrueClass.html create mode 100644 tmp/rdoc/JSON/Pure/Generator/State.html create mode 100644 tmp/rdoc/JSON/Pure/Parser.html create mode 100644 tmp/rdoc/JSONAdditionTest.html create mode 100644 tmp/rdoc/JSONAdditionTest/A.html create mode 100644 tmp/rdoc/JSONAdditionTest/A2.html create mode 100644 tmp/rdoc/JSONAdditionTest/B.html create mode 100644 tmp/rdoc/JSONAdditionTest/C.html create mode 100644 tmp/rdoc/JSONCommonInterfaceTest.html create mode 100644 tmp/rdoc/JSONEncodingTest.html create mode 100644 tmp/rdoc/JSONExtParserTest.html create mode 100644 tmp/rdoc/JSONFixturesTest.html create mode 100644 tmp/rdoc/JSONGeneratorTest.html create mode 100644 tmp/rdoc/JSONGenericObjectTest.html create mode 100644 tmp/rdoc/JSONParserTest.html create mode 100644 tmp/rdoc/JSONParserTest/Encoding.html create mode 100644 tmp/rdoc/JSONParserTest/SubArray.html create mode 100644 tmp/rdoc/JSONParserTest/SubArray2.html create mode 100644 tmp/rdoc/JSONParserTest/SubArrayWrapper.html create mode 100644 tmp/rdoc/JSONParserTest/SubHash.html create mode 100644 tmp/rdoc/JSONParserTest/SubHash2.html create mode 100644 tmp/rdoc/JSONParserTest/SubOpenStruct.html create mode 100644 tmp/rdoc/JSONServlet.html create mode 100644 tmp/rdoc/JSONStringMatchingTest.html create mode 100644 tmp/rdoc/JSONStringMatchingTest/TestTime.html create mode 100644 tmp/rdoc/Kernel.html create mode 100644 tmp/rdoc/MyState.html create mode 100644 tmp/rdoc/Object.html create mode 100644 tmp/rdoc/OpenStruct.html create mode 100644 tmp/rdoc/README-json-jruby_md.html create mode 100644 tmp/rdoc/README_md.html create mode 100644 tmp/rdoc/Rakefile.html create mode 100644 tmp/rdoc/Range.html create mode 100644 tmp/rdoc/Rational.html create mode 100644 tmp/rdoc/Regexp.html create mode 100644 tmp/rdoc/Set.html create mode 100644 tmp/rdoc/Struct.html create mode 100644 tmp/rdoc/Symbol.html create mode 100644 tmp/rdoc/Time.html create mode 100644 tmp/rdoc/VERSION.html create mode 100644 tmp/rdoc/created.rid create mode 100644 tmp/rdoc/css/fonts.css create mode 100644 tmp/rdoc/css/rdoc.css create mode 100644 tmp/rdoc/data/example_json.html create mode 100644 tmp/rdoc/data/index_html.html create mode 100644 tmp/rdoc/data/prototype_js.html create mode 100644 tmp/rdoc/ext/json/ext/generator/depend.html create mode 100644 tmp/rdoc/ext/json/ext/parser/depend.html create mode 100644 tmp/rdoc/ext/json/ext/parser/parser_rl.html create mode 100644 tmp/rdoc/fonts/Lato-Light.ttf create mode 100644 tmp/rdoc/fonts/Lato-LightItalic.ttf create mode 100644 tmp/rdoc/fonts/Lato-Regular.ttf create mode 100644 tmp/rdoc/fonts/Lato-RegularItalic.ttf create mode 100644 tmp/rdoc/fonts/SourceCodePro-Bold.ttf create mode 100644 tmp/rdoc/fonts/SourceCodePro-Regular.ttf create mode 100644 tmp/rdoc/images/add.png create mode 100644 tmp/rdoc/images/arrow_up.png create mode 100644 tmp/rdoc/images/brick.png create mode 100644 tmp/rdoc/images/brick_link.png create mode 100644 tmp/rdoc/images/bug.png create mode 100644 tmp/rdoc/images/bullet_black.png create mode 100644 tmp/rdoc/images/bullet_toggle_minus.png create mode 100644 tmp/rdoc/images/bullet_toggle_plus.png create mode 100644 tmp/rdoc/images/date.png create mode 100644 tmp/rdoc/images/delete.png create mode 100644 tmp/rdoc/images/find.png create mode 100644 tmp/rdoc/images/loadingAnimation.gif create mode 100644 tmp/rdoc/images/macFFBgHack.png create mode 100644 tmp/rdoc/images/package.png create mode 100644 tmp/rdoc/images/page_green.png create mode 100644 tmp/rdoc/images/page_white_text.png create mode 100644 tmp/rdoc/images/page_white_width.png create mode 100644 tmp/rdoc/images/plugin.png create mode 100644 tmp/rdoc/images/ruby.png create mode 100644 tmp/rdoc/images/tag_blue.png create mode 100644 tmp/rdoc/images/tag_green.png create mode 100644 tmp/rdoc/images/transparent.png create mode 100644 tmp/rdoc/images/wrench.png create mode 100644 tmp/rdoc/images/wrench_orange.png create mode 100644 tmp/rdoc/images/zoom.png create mode 100644 tmp/rdoc/index.html create mode 100644 tmp/rdoc/java/src/json/ext/ByteListTranscoder_java.html create mode 100644 tmp/rdoc/java/src/json/ext/GeneratorMethods_java.html create mode 100644 tmp/rdoc/java/src/json/ext/GeneratorService_java.html create mode 100644 tmp/rdoc/java/src/json/ext/GeneratorState_java.html create mode 100644 tmp/rdoc/java/src/json/ext/Generator_java.html create mode 100644 tmp/rdoc/java/src/json/ext/OptionsReader_java.html create mode 100644 tmp/rdoc/java/src/json/ext/ParserService_java.html create mode 100644 tmp/rdoc/java/src/json/ext/Parser_java.html create mode 100644 tmp/rdoc/java/src/json/ext/Parser_rl.html create mode 100644 tmp/rdoc/java/src/json/ext/RuntimeInfo_java.html create mode 100644 tmp/rdoc/java/src/json/ext/StringDecoder_java.html create mode 100644 tmp/rdoc/java/src/json/ext/StringEncoder_java.html create mode 100644 tmp/rdoc/java/src/json/ext/Utils_java.html create mode 100644 tmp/rdoc/js/darkfish.js create mode 100644 tmp/rdoc/js/jquery.js create mode 100644 tmp/rdoc/js/navigation.js create mode 100644 tmp/rdoc/js/navigation.js.gz create mode 100644 tmp/rdoc/js/search.js create mode 100644 tmp/rdoc/js/search_index.js create mode 100644 tmp/rdoc/js/search_index.js.gz create mode 100644 tmp/rdoc/js/searcher.js create mode 100644 tmp/rdoc/js/searcher.js.gz create mode 100644 tmp/rdoc/json-java_gemspec.html create mode 100644 tmp/rdoc/json_pure_gemspec.html create mode 100644 tmp/rdoc/references/rfc7159_txt.html create mode 100644 tmp/rdoc/table_of_contents.html create mode 100644 tmp/rdoc/tests/fixtures/fail10_json.html create mode 100644 tmp/rdoc/tests/fixtures/fail11_json.html create mode 100644 tmp/rdoc/tests/fixtures/fail12_json.html create mode 100644 tmp/rdoc/tests/fixtures/fail13_json.html create mode 100644 tmp/rdoc/tests/fixtures/fail14_json.html create mode 100644 tmp/rdoc/tests/fixtures/fail18_json.html create mode 100644 tmp/rdoc/tests/fixtures/fail19_json.html create mode 100644 tmp/rdoc/tests/fixtures/fail20_json.html create mode 100644 tmp/rdoc/tests/fixtures/fail21_json.html create mode 100644 tmp/rdoc/tests/fixtures/fail22_json.html create mode 100644 tmp/rdoc/tests/fixtures/fail23_json.html create mode 100644 tmp/rdoc/tests/fixtures/fail24_json.html create mode 100644 tmp/rdoc/tests/fixtures/fail25_json.html create mode 100644 tmp/rdoc/tests/fixtures/fail27_json.html create mode 100644 tmp/rdoc/tests/fixtures/fail28_json.html create mode 100644 tmp/rdoc/tests/fixtures/fail2_json.html create mode 100644 tmp/rdoc/tests/fixtures/fail3_json.html create mode 100644 tmp/rdoc/tests/fixtures/fail4_json.html create mode 100644 tmp/rdoc/tests/fixtures/fail5_json.html create mode 100644 tmp/rdoc/tests/fixtures/fail6_json.html create mode 100644 tmp/rdoc/tests/fixtures/fail7_json.html create mode 100644 tmp/rdoc/tests/fixtures/fail8_json.html create mode 100644 tmp/rdoc/tests/fixtures/fail9_json.html create mode 100644 tmp/rdoc/tests/fixtures/obsolete_fail1_json.html create mode 100644 tmp/rdoc/tests/fixtures/pass15_json.html create mode 100644 tmp/rdoc/tests/fixtures/pass16_json.html create mode 100644 tmp/rdoc/tests/fixtures/pass17_json.html create mode 100644 tmp/rdoc/tests/fixtures/pass1_json.html create mode 100644 tmp/rdoc/tests/fixtures/pass26_json.html create mode 100644 tmp/rdoc/tests/fixtures/pass2_json.html create mode 100644 tmp/rdoc/tests/fixtures/pass3_json.html create mode 100644 tmp/rdoc/tools/diff_sh.html diff --git a/lib/json.rb b/lib/json.rb index 947ac630a..ec9b571be 100644 --- a/lib/json.rb +++ b/lib/json.rb @@ -9,8 +9,11 @@ # JSON is completely language agnostic, making it the ideal interchange format. # # Built on two universally available structures: -# 1. A collection of name/value pairs. Often referred to as an _object_, hash table, record, struct, keyed list, or associative array. -# 2. An ordered list of values. More commonly called an _array_, vector, sequence or list. +# +# 1. A collection of name/value pairs. Often referred to as an _object_, hash table, +# record, struct, keyed list, or associative array. +# 2. An ordered list of values. More commonly called an _array_, vector, sequence or +# list. # # To read more about JSON visit: http://json.org # @@ -22,7 +25,7 @@ # require 'json' # # my_hash = JSON.parse('{"hello": "goodbye"}') -# puts my_hash["hello"] => "goodbye" +# puts my_hash["hello"] # => "goodbye" # # Notice the extra quotes '' around the hash notation. Ruby expects # the argument to be a string and can't convert objects like a hash or array. @@ -37,13 +40,50 @@ # require 'json' # # my_hash = {:hello => "goodbye"} -# puts JSON.generate(my_hash) => "{\"hello\":\"goodbye\"}" +# puts JSON.generate(my_hash) # => "{\"hello\":\"goodbye\"}" # # Or an alternative way: # # require 'json' -# puts {:hello => "goodbye"}.to_json => "{\"hello\":\"goodbye\"}" +# puts {:hello => "goodbye"}.to_json # => "{\"hello\":\"goodbye\"}" +# +# JSON.generate only allows objects or arrays to be converted +# to JSON syntax. to_json, however, accepts many Ruby classes +# even though it acts only as a method for serialization: +# +# require 'json' # +# 1.to_json => "1" +# +# The {#generate}[rdoc-ref:JSON#generate] method accepts a variety of options +# to set the formatting of string output and defining what input is accepteable. +# There are also shortcut methods pretty_generate (with a set of options to +# generate human-readable multiline JSON) and fast_generate (with a set of +# options to generate JSON faster at the price of disabling some checks). +# +# == Extended rendering and loading of Ruby objects +# +# JSON library provides optional _additions_ allowing to serialize and +# deserialize Ruby classes without loosing their type. +# +# # without additions +# require "json" +# json = JSON.generate({range: 1..3, regex: /test/}) +# # => '{"range":"1..3","regex":"(?-mix:test)"}' +# JSON.parse(json) +# # => {"range"=>"1..3", "regex"=>"(?-mix:test)"} +# +# # with additions +# require "json/add/range" +# require "json/add/regexp" +# json = JSON.generate({range: 1..3, regex: /test/}) +# # => '{"range":{"json_class":"Range","a":[1,3,false]},"regex":{"json_class":"Regexp","o":0,"s":"test"}}' +# JSON.parse(json) +# # => {"range"=>{"json_class"=>"Range", "a"=>[1, 3, false]}, "regex"=>{"json_class"=>"Regexp", "o"=>0, "s"=>"test"}} +# JSON.load(json) +# # => {"range"=>1..3, "regex"=>/test/} +# +# See JSON.load for details. module JSON require 'json/version' diff --git a/lib/json/common.rb b/lib/json/common.rb index 3be9fd8dc..5ba8f1d29 100644 --- a/lib/json/common.rb +++ b/lib/json/common.rb @@ -180,27 +180,30 @@ def parse!(source, opts = {}) end # Generate a JSON document from the Ruby data structure _obj_ and return - # it. _state_ is * a JSON::State object, - # * or a Hash like object (responding to to_hash), - # * an object convertible into a hash by a to_h method, - # that is used as or to configure a State object. + # it. _opts_ is + # * a Hash like object (responding to +to_hash+), + # * or an object convertible into a hash by a +to_h+ method, + # * or a JSON::State object. # - # It defaults to a state object, that creates the shortest possible JSON text - # in one line, checks for circular data structures and doesn't allow NaN, + # If hash-alike or hash-convertible object is provided, it is internally + # converted into a State object. + # + # The default options are set to create the shortest possible JSON text + # in one line, check for circular data structures and do not allow NaN, # Infinity, and -Infinity. # - # A _state_ hash can have the following keys: - # * *indent*: a string used to indent levels (default: ''), - # * *space*: a string that is put after, a : or , delimiter (default: ''), - # * *space_before*: a string that is put before a : pair delimiter (default: ''), - # * *object_nl*: a string that is put at the end of a JSON object (default: ''), - # * *array_nl*: a string that is put at the end of a JSON array (default: ''), + # An _opts_ hash can have the following keys: + # * *indent*: a string used to indent levels (default: ''), + # * *space*: a string that is put after a : pair delimiter (default: ''), + # * *space_before*: a string that is put before a : pair delimiter (default: ''), + # * *object_nl*: a string that is put at the end of a JSON object (default: ''), + # * *array_nl*: a string that is put at the end of a JSON array (default: ''), # * *allow_nan*: true if NaN, Infinity, and -Infinity should be # generated, otherwise an exception is thrown if these values are # encountered. This options defaults to false. # * *max_nesting*: The maximum depth of nesting allowed in the data # structures from which JSON is to be generated. Disable depth checking - # with :max_nesting => false, it defaults to 100. + # with max_nesting: false, it defaults to 100. # # See also the fast_generate for the fastest creation method with the least # amount of sanity checks, and the pretty_generate method for some diff --git a/tmp/rdoc/BigDecimal.html b/tmp/rdoc/BigDecimal.html new file mode 100644 index 000000000..3e9806a00 --- /dev/null +++ b/tmp/rdoc/BigDecimal.html @@ -0,0 +1,239 @@ + + + + + + +class BigDecimal - RDoc Documentation + + + + + + + + + + + + + + +
+

+ class BigDecimal +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Class Methods

+
+ + +
+ +
+ json_create(object) + + click to toggle source + +
+ + +
+ +

Import a JSON Marshalled object.

+ +

method used for JSON marshalling support.

+ + + + +
+
# File lib/json/add/bigdecimal.rb, line 11
+def self.json_create(object)
+  BigDecimal._load object['b']
+end
+
+ +
+ + + + +
+ + +
+ +
+
+

Public Instance Methods

+
+ + +
+ +
+ as_json(*) + + click to toggle source + +
+ + +
+ +

Marshal the object to JSON.

+ +

method used for JSON marshalling support.

+ + + + +
+
# File lib/json/add/bigdecimal.rb, line 18
+def as_json(*)
+  {
+    JSON.create_id => self.class.name,
+    'b'            => _dump,
+  }
+end
+
+ +
+ + + + +
+ + +
+ +
+ to_json(*) + + click to toggle source + +
+ + +
+ +

return the JSON value

+ + + + +
+
# File lib/json/add/bigdecimal.rb, line 26
+def to_json(*)
+  as_json.to_json
+end
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/CHANGES_md.html b/tmp/rdoc/CHANGES_md.html new file mode 100644 index 000000000..6539962f1 --- /dev/null +++ b/tmp/rdoc/CHANGES_md.html @@ -0,0 +1,927 @@ + + + + + + +CHANGES - RDoc Documentation + + + + + + + + + + + + + + +
+ +

Changes

+ +

2017-04-18 (2.1.0)

+ + +

2017-01-12 (2.0.3)

+ + +

2016-07-26 (2.0.2)

+ + +

2016-07-01 (2.0.1)

+ + +

2015-09-11 (2.0.0)

+ + +

2015-06-01 (1.8.3)

+ + +

2015-01-08 (1.8.2)

+ + +

2013-05-13 (1.8.1)

+ + +

2013-05-13 (1.8.0)

+ + +

2013-02-04 (1.7.7)

+ + +

2012-11-29 (1.7.6)

+ + +

2012-08-17 (1.7.5)

+ + +

2012-07-26 (1.7.4)

+ + +

2012-05-12 (1.7.3)

+ + +

2012-05-11 (1.7.2)

+ + +

2012-04-28 (1.7.1)

+ + +

2012-04-28 (1.7.0)

+ + +

2012-04-27 (1.6.7)

+ + +

2012-02-11 (1.6.6)

+ + +

2012-01-15 (1.6.5)

+ + +

2011-12-24 (1.6.4)

+ + +

2011-12-01 (1.6.3)

+ + +

2011-11-21 (1.6.2)

+ + +

2011-09-18 (1.6.1)

+ + +

2011-09-12 (1.6.0)

+ + +

2011-08-31 (1.5.4)

+ + +

2011-06-20 (1.5.3)

+ + +

2011-05-11 (1.5.2)

+ + +

2011-01-24 (1.5.1)

+ + +

2011-01-22 (1.5.0)

+ + +

2010-08-09 (1.4.6)

+ + +

2010-08-07 (1.4.5)

+ + +

2010-04-26 (1.4.2)

+ + +

2010-04-25 (1.4.1)

+ + +

2010-04-23 (1.4.0)

+ + +

2010-04-07 (1.2.4)

+ + +

2010-03-11 (1.2.3)

+ + +

2010-02-27 (1.2.2)

+ + +

2009-11-25 (1.2.1)

+ + +

2009-10-01 (1.2.0)

+ + +

2009-08-23 (1.1.9)

+ + +

2009-08-23 (1.1.8)

+ + +

2009-06-29 (1.1.7)

+ + +

2009-05-10 (1.1.6)

+ + +

2009-05-10 (1.1.5)

+ + +

2009-04-01 (1.1.4)

+ + +

2008-07-10 (1.1.3)

+ + +

2007-11-27 (1.1.2)

+ + +

2007-07-06 (1.1.1)

+ + +

2007-05-21 (1.1.0)

+ + +

2007-05-09 (1.0.4)

+ + +

2007-03-24 (1.0.3)

+ + +

2007-03-24 (1.0.2)

+ + +

2007-03-24 (1.0.1)

+ + +

2007-03-24 (1.0.0)

+ + +

2007-02-09 (0.4.3)

+ + +

2006-08-25 (0.4.2)

+ + +

2006-02-06 (0.4.1)

+ + +

2005-09-23 (0.4.0)

+ +
+ + + + + diff --git a/tmp/rdoc/Class.html b/tmp/rdoc/Class.html new file mode 100644 index 000000000..d4e676b4f --- /dev/null +++ b/tmp/rdoc/Class.html @@ -0,0 +1,160 @@ + + + + + + +class Class - RDoc Documentation + + + + + + + + + + + + + + +
+

+ class Class +

+ +
+ +

Extends any Class to include +json_creatable? method.

+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Instance Methods

+
+ + +
+ +
+ json_creatable?() + + click to toggle source + +
+ + +
+ +

Returns true if this class can be used to create an instance from a +serialised JSON string. The class has to implement +a class method json_create that expects a hash as first parameter. +The hash should include the required data.

+ + + + +
+
# File lib/json/common.rb, line 453
+def json_creatable?
+  respond_to?(:json_create)
+end
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/Complex.html b/tmp/rdoc/Complex.html new file mode 100644 index 000000000..d2f38cf17 --- /dev/null +++ b/tmp/rdoc/Complex.html @@ -0,0 +1,240 @@ + + + + + + +class Complex - RDoc Documentation + + + + + + + + + + + + + + +
+

+ class Complex +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Class Methods

+
+ + +
+ +
+ json_create(object) + + click to toggle source + +
+ + +
+ +

Deserializes JSON string by converting Real value +r, imaginary value i, to a Complex object.

+ + + + +
+
# File lib/json/add/complex.rb, line 11
+def self.json_create(object)
+  Complex(object['r'], object['i'])
+end
+
+ +
+ + + + +
+ + +
+ +
+
+

Public Instance Methods

+
+ + +
+ +
+ as_json(*) + + click to toggle source + +
+ + +
+ +

Returns a hash, that will be turned into a JSON +object and represent this object.

+ + + + +
+
# File lib/json/add/complex.rb, line 17
+def as_json(*)
+  {
+    JSON.create_id => self.class.name,
+    'r'            => real,
+    'i'            => imag,
+  }
+end
+
+ +
+ + + + +
+ + +
+ +
+ to_json(*) + + click to toggle source + +
+ + +
+ +

Stores class name (Complex) along with real value r and +imaginary value i as JSON string

+ + + + +
+
# File lib/json/add/complex.rb, line 26
+def to_json(*)
+  as_json.to_json
+end
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/Date.html b/tmp/rdoc/Date.html new file mode 100644 index 000000000..02274e2d0 --- /dev/null +++ b/tmp/rdoc/Date.html @@ -0,0 +1,243 @@ + + + + + + +class Date - RDoc Documentation + + + + + + + + + + + + + + +
+

+ class Date +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Class Methods

+
+ + +
+ +
+ json_create(object) + + click to toggle source + +
+ + +
+ +

Deserializes JSON string by converting Julian year +y, month m, day d and Day of +Calendar Reform sg to Date.

+ + + + +
+
# File lib/json/add/date.rb, line 11
+def self.json_create(object)
+  civil(*object.values_at('y', 'm', 'd', 'sg'))
+end
+
+ +
+ + + + +
+ + +
+ +
+
+

Public Instance Methods

+
+ + +
+ +
+ as_json(*) + + click to toggle source + +
+ + +
+ +

Returns a hash, that will be turned into a JSON +object and represent this object.

+ + + + +
+
# File lib/json/add/date.rb, line 19
+def as_json(*)
+  {
+    JSON.create_id => self.class.name,
+    'y' => year,
+    'm' => month,
+    'd' => day,
+    'sg' => start,
+  }
+end
+
+ +
+ + + + +
+ + +
+ +
+ to_json(*args) + + click to toggle source + +
+ + +
+ +

Stores class name (Date) with Julian year y, month +m, day d and Day of Calendar Reform +sg as JSON string

+ + + + +
+
# File lib/json/add/date.rb, line 31
+def to_json(*args)
+  as_json.to_json(*args)
+end
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/DateTime.html b/tmp/rdoc/DateTime.html new file mode 100644 index 000000000..6ca76651f --- /dev/null +++ b/tmp/rdoc/DateTime.html @@ -0,0 +1,258 @@ + + + + + + +class DateTime - RDoc Documentation + + + + + + + + + + + + + + +
+

+ class DateTime +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Class Methods

+
+ + +
+ +
+ json_create(object) + + click to toggle source + +
+ + +
+ +

Deserializes JSON string by converting year +y, month m, day d, hour +H, minute M, second S, offset +of and Day of Calendar Reform sg to DateTime.

+ + + + +
+
# File lib/json/add/date_time.rb, line 12
+def self.json_create(object)
+  args = object.values_at('y', 'm', 'd', 'H', 'M', 'S')
+  of_a, of_b = object['of'].split('/')
+  if of_b and of_b != '0'
+    args << Rational(of_a.to_i, of_b.to_i)
+  else
+    args << of_a
+  end
+  args << object['sg']
+  civil(*args)
+end
+
+ +
+ + + + +
+ + +
+ +
+
+

Public Instance Methods

+
+ + +
+ +
+ as_json(*) + + click to toggle source + +
+ + +
+ +

Returns a hash, that will be turned into a JSON +object and represent this object.

+ + + + +
+
# File lib/json/add/date_time.rb, line 28
+def as_json(*)
+  {
+    JSON.create_id => self.class.name,
+    'y' => year,
+    'm' => month,
+    'd' => day,
+    'H' => hour,
+    'M' => min,
+    'S' => sec,
+    'of' => offset.to_s,
+    'sg' => start,
+  }
+end
+
+ +
+ + + + +
+ + +
+ +
+ to_json(*args) + + click to toggle source + +
+ + +
+ +

Stores class name (DateTime) with Julian year y, month +m, day d, hour H, minute +M, second S, offset of and Day of +Calendar Reform sg as JSON string

+ + + + +
+
# File lib/json/add/date_time.rb, line 45
+def to_json(*args)
+  as_json.to_json(*args)
+end
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/Exception.html b/tmp/rdoc/Exception.html new file mode 100644 index 000000000..44d549751 --- /dev/null +++ b/tmp/rdoc/Exception.html @@ -0,0 +1,242 @@ + + + + + + +class Exception - RDoc Documentation + + + + + + + + + + + + + + +
+

+ class Exception +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Class Methods

+
+ + +
+ +
+ json_create(object) + + click to toggle source + +
+ + +
+ +

Deserializes JSON string by constructing new Exception object with message m and +backtrace b serialized with to_json

+ + + + +
+
# File lib/json/add/exception.rb, line 10
+def self.json_create(object)
+  result = new(object['m'])
+  result.set_backtrace object['b']
+  result
+end
+
+ +
+ + + + +
+ + +
+ +
+
+

Public Instance Methods

+
+ + +
+ +
+ as_json(*) + + click to toggle source + +
+ + +
+ +

Returns a hash, that will be turned into a JSON +object and represent this object.

+ + + + +
+
# File lib/json/add/exception.rb, line 18
+def as_json(*)
+  {
+    JSON.create_id => self.class.name,
+    'm'            => message,
+    'b'            => backtrace,
+  }
+end
+
+ +
+ + + + +
+ + +
+ +
+ to_json(*args) + + click to toggle source + +
+ + +
+ +

Stores class name (Exception) with message m and backtrace +array b as JSON string

+ + + + +
+
# File lib/json/add/exception.rb, line 28
+def to_json(*args)
+  as_json.to_json(*args)
+end
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/Fuzzer.html b/tmp/rdoc/Fuzzer.html new file mode 100644 index 000000000..a559c98d3 --- /dev/null +++ b/tmp/rdoc/Fuzzer.html @@ -0,0 +1,354 @@ + + + + + + +class Fuzzer - RDoc Documentation + + + + + + + + + + + + + + +
+

+ class Fuzzer +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Class Methods

+
+ + +
+ +
+ new(n, freqs = {}) + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tools/fuzz.rb, line 4
+def initialize(n, freqs = {})
+  sum = freqs.inject(0.0) { |s, x| s + x.last }
+  freqs.each_key { |x| freqs[x] /= sum }
+  s = 0.0
+  freqs.each_key do |x|
+    freqs[x] = s .. (s + t = freqs[x])
+    s += t
+  end
+  @freqs = freqs
+  @n = n
+  @alpha = (0..0xff).to_a
+end
+
+ +
+ + + + +
+ + +
+ +
+
+

Public Instance Methods

+
+ + +
+ +
+ fuzz(current = nil) + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tools/fuzz.rb, line 45
+def fuzz(current = nil)
+  if @n > 0
+    case current
+    when nil
+      @n -= 1
+      current = fuzz [ Hash, Array ][rand(2)].new
+    when Array
+      while @n > 0
+        @n -= 1
+        current << case p = make_pick
+        when Array, Hash
+          fuzz(p)
+        else
+          p
+        end
+      end
+    when Hash
+      while @n > 0
+        @n -= 1
+        current[random_string] = case p = make_pick
+        when Array, Hash
+          fuzz(p)
+        else
+          p
+        end
+      end
+    end
+  end
+  current
+end
+
+ +
+ + + + +
+ + +
+ +
+ make_pick() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tools/fuzz.rb, line 29
+def make_pick
+  k = pick
+  case
+  when k == Hash, k == Array
+    k.new
+  when k == true, k == false, k == nil
+    k
+  when k == String
+    random_string
+  when k == Fixnum
+    rand(2 ** 30) - 2 ** 29
+  when k == Bignum
+    rand(2 ** 70) - 2 ** 69
+  end
+end
+
+ +
+ + + + +
+ + +
+ +
+ pick() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tools/fuzz.rb, line 23
+def pick
+  r = rand
+  found = @freqs.find { |k, f| f.include? rand }
+  found && found.first
+end
+
+ +
+ + + + +
+ + +
+ +
+ random_string() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tools/fuzz.rb, line 17
+def random_string
+  s = ''
+  30.times { s << @alpha[rand(@alpha.size)] }
+  s
+end
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/Gemfile.html b/tmp/rdoc/Gemfile.html new file mode 100644 index 000000000..db473842a --- /dev/null +++ b/tmp/rdoc/Gemfile.html @@ -0,0 +1,218 @@ + + + + + + +Gemfile - RDoc Documentation + + + + + + + + + + + + + + +
+ +

# vim: set ft=ruby:

+ +

source 'rubygems.org'

+ +

case ENV when 'ext', nil

+ +
if ENV['RUBY_ENGINE'] == 'jruby'
+  gemspec :name => 'json-java'
+else
+  gemspec :name => 'json'
+end
+
+ +

when 'pure'

+ +
gemspec :name => 'json_pure'
+
+ +

end

+
+ + + + + diff --git a/tmp/rdoc/JSON.html b/tmp/rdoc/JSON.html new file mode 100644 index 000000000..6cb23b5a0 --- /dev/null +++ b/tmp/rdoc/JSON.html @@ -0,0 +1,989 @@ + + + + + + +module JSON - RDoc Documentation + + + + + + + + + + + + + + +
+

+ module JSON +

+ +
+ +

JavaScript Object Notation (JSON)

+ +

JSON is a lightweight data-interchange format. It +is easy for us humans to read and write. Plus, equally simple for machines +to generate or parse. JSON is completely language +agnostic, making it the ideal interchange format.

+ +

Built on two universally available structures:

+ +
1. A collection of name/value pairs. Often referred to as an _object_, hash table, record, struct, keyed list, or associative array.
+2. An ordered list of values. More commonly called an _array_, vector, sequence or list.
+ +

To read more about JSON visit: json.org

+ +

Parsing JSON

+ +

To parse a JSON string received by another +application or generated within your existing application:

+ +
require 'json'
+
+my_hash = JSON.parse('{"hello": "goodbye"}')
+puts my_hash["hello"] => "goodbye"
+
+ +

Notice the extra quotes '' around the hash notation. +Ruby expects the argument to be a string and can't convert objects like +a hash or array.

+ +

Ruby converts your string into a hash

+ +

Generating JSON

+ +

Creating a JSON string for communication or +serialization is just as simple.

+ +
require 'json'
+
+my_hash = {:hello => "goodbye"}
+puts JSON.generate(my_hash) => "{\"hello\":\"goodbye\"}"
+
+ +

Or an alternative way:

+ +
require 'json'
+puts {:hello => "goodbye"}.to_json => "{\"hello\":\"goodbye\"}"
+ +

JSON.generate only allows objects or arrays to be converted to +JSON syntax. to_json, however, accepts +many Ruby classes even though it acts only as a method for serialization:

+ +
require 'json'
+
+1.to_json => "1"
+ +

frozen_string_literal: false

+ +
+ + + + +
+ + + + + +
+
+

Constants

+
+
+ +
Infinity + +
+ + +
JSON_LOADED + +
+ + +
MinusInfinity + +
+ + +
NaN + +
+ + +
UnparserError + +

This exception is raised if a generator or unparser error occurs.

+ + +
VERSION + +

JSON version

+ + +
+
+ + + +
+
+

Attributes

+
+ + +
+
+ create_id[RW] +
+ +
+ +

This is create identifier, which is used to decide if the +json_create hook of a class should be called. It defaults to +'json_class'.

+ +
+
+ +
+
+ dump_default_options[RW] +
+ +
+ +

The global default options for the #dump method:

+ +
:max_nesting: false
+:allow_nan: true
+:allow_blank: true
+ +
+
+ +
+
+ generator[R] +
+ +
+ +

Returns the JSON generator module that is used by +JSON. This is either JSON::Ext::Generator or JSON::Pure::Generator.

+ +
+
+ +
+
+ load_default_options[RW] +
+ +
+ +

The global default options for the #load method:

+ +
:max_nesting: false
+:allow_nan: true
+:allow_blank: true
+ +
+
+ +
+
+ parser[R] +
+ +
+ +

Returns the JSON parser class that is used by JSON. This is either JSON::Ext::Parser or JSON::Pure::Parser.

+ +
+
+ +
+
+ state[RW] +
+ +
+ +

Returns the JSON generator state class that is used +by JSON. This is either JSON::Ext::Generator::State or JSON::Pure::Generator::State.

+ +
+
+ +
+ + + +
+
+

Public Class Methods

+
+ + +
+ +
+ [](object, opts = {}) + + click to toggle source + +
+ + +
+ +

If object is string-like, parse the string and return the parsed +result as a Ruby data structure. Otherwise generate a JSON text from the Ruby data structure object and +return it.

+ +

The opts argument is passed through to generate/parse +respectively. See generate and parse for their documentation.

+ + + + +
+
# File lib/json/common.rb, line 13
+def [](object, opts = {})
+  if object.respond_to? :to_str
+    JSON.parse(object.to_str, opts)
+  else
+    JSON.generate(object, opts)
+  end
+end
+
+ +
+ + + + +
+ + +
+ +
+ iconv(to, from, string) + + click to toggle source + +
+ + +
+ +

Encodes string using Ruby's String.encode

+ + + + +
+
# File lib/json/common.rb, line 406
+def self.iconv(to, from, string)
+  string.encode(to, from)
+end
+
+ +
+ + + + +
+ + +
+ +
+ restore(source, proc = nil, options = {}) + +
+ + +
+ + + + + + +
+ + + + +
+ Alias for: load +
+ +
+ + +
+ +
+ valid_utf8?(string) + + click to toggle source + +
+ + +
+ + + + + + +
+
# File lib/json/pure/generator.rb, line 74
+def valid_utf8?(string)
+  encoding = string.encoding
+  (encoding == Encoding::UTF_8 || encoding == Encoding::ASCII) &&
+    string.valid_encoding?
+end
+
+ +
+ + + + +
+ + +
+ +
+
+

Public Instance Methods

+
+ + +
+ +
+ dump(obj, anIO = nil, limit = nil) + + click to toggle source + +
+ + +
+ +

Dumps obj as a JSON string, i.e. calls +generate on the object and returns the result.

+ +

If anIO (an IO-like object or an object that responds to the write method) +was given, the resulting JSON is written to it.

+ +

If the number of nested arrays or objects exceeds limit, an +ArgumentError exception is raised. This argument is similar (but not +exactly the same!) to the limit argument in Marshal.dump.

+ +

The default options for the generator can be changed via the ::dump_default_options +method.

+ +

This method is part of the implementation of the load/dump interface of +Marshal and YAML.

+ + + + +
+
# File lib/json/common.rb, line 384
+def dump(obj, anIO = nil, limit = nil)
+  if anIO and limit.nil?
+    anIO = anIO.to_io if anIO.respond_to?(:to_io)
+    unless anIO.respond_to?(:write)
+      limit = anIO
+      anIO = nil
+    end
+  end
+  opts = JSON.dump_default_options
+  opts = opts.merge(:max_nesting => limit) if limit
+  result = generate(obj, opts)
+  if anIO
+    anIO.write result
+    anIO
+  else
+    result
+  end
+rescue JSON::NestingError
+  raise ArgumentError, "exceed depth limit"
+end
+
+ +
+ + + + +
+ + +
+ +
+ fast_generate(obj, opts = nil) + + click to toggle source + +
+ + +
+ +

Generate a JSON document from the Ruby data +structure obj and return it. This method disables the checks for +circles in Ruby objects.

+ +

WARNING: Be careful not to pass any Ruby data structures +with circles as obj argument because this will cause JSON to go into an infinite loop.

+ + + + +
+
# File lib/json/common.rb, line 239
+def fast_generate(obj, opts = nil)
+  if State === opts
+    state, opts = opts, nil
+  else
+    state = FAST_STATE_PROTOTYPE.dup
+  end
+  if opts
+    if opts.respond_to? :to_hash
+      opts = opts.to_hash
+    elsif opts.respond_to? :to_h
+      opts = opts.to_h
+    else
+      raise TypeError, "can't convert #{opts.class} into Hash"
+    end
+    state.configure(opts)
+  end
+  state.generate(obj)
+end
+
+ +
+ + + + +
+ + +
+ +
+ generate(obj, opts = nil) + + click to toggle source + +
+ + +
+ +

Generate a JSON document from the Ruby data +structure obj and return it. state is * a JSON::State +object,

+
  • +

    or a Hash like object (responding to to_hash),

    +
  • +

    an object convertible into a hash by a to_h method,

    +
+ +

that is used as or to configure a State object.

+ +

It defaults to a state object, that creates the shortest possible JSON text in one line, checks for circular data +structures and doesn't allow NaN, Infinity, and -Infinity.

+ +

A state hash can have the following keys:

+
  • +

    indent: a string used to indent levels (default: +''),

    +
  • +

    space: a string that is put after, a : or , delimiter +(default: ''),

    +
  • +

    space_before: a string that is put before a : pair +delimiter (default: ''),

    +
  • +

    object_nl: a string that is put at the end of a JSON object (default: ''),

    +
  • +

    array_nl: a string that is put at the end of a JSON array (default: ''),

    +
  • +

    allow_nan: true if NaN, Infinity, and -Infinity should be generated, +otherwise an exception is thrown if these values are encountered. This +options defaults to false.

    +
  • +

    max_nesting: The maximum depth of nesting allowed in the +data structures from which JSON is to be generated. +Disable depth checking with :max_nesting => false, it defaults to 100.

    +
+ +

See also the #fast_generate +for the fastest creation method with the least amount of sanity checks, and +the #pretty_generate +method for some defaults for pretty output.

+ + + + +
+
# File lib/json/common.rb, line 208
+def generate(obj, opts = nil)
+  if State === opts
+    state, opts = opts, nil
+  else
+    state = SAFE_STATE_PROTOTYPE.dup
+  end
+  if opts
+    if opts.respond_to? :to_hash
+      opts = opts.to_hash
+    elsif opts.respond_to? :to_h
+      opts = opts.to_h
+    else
+      raise TypeError, "can't convert #{opts.class} into Hash"
+    end
+    state = state.configure(opts)
+  end
+  state.generate(obj)
+end
+
+ +
+ + + + +
+ + +
+ +
+ load(source, proc = nil, options = {}) + + click to toggle source + +
+ + +
+ +

Load a ruby data structure from a JSON +source and return it. A source can either be a string-like object, +an IO-like object, or an object responding to the read method. If +proc was given, it will be called with any nested Ruby object as +an argument recursively in depth first order. To modify the default options +pass in the optional options argument as well.

+ +

BEWARE: This method is meant to serialise data from trusted user input, +like from your own database server or clients under your control, it could +be dangerous to allow untrusted users to pass JSON +sources into it. The default options for the parser can be changed via the +::load_default_options +method.

+ +

This method is part of the implementation of the load/dump interface of +Marshal and YAML.

+ + + + +
+
# File lib/json/common.rb, line 323
+def load(source, proc = nil, options = {})
+  opts = load_default_options.merge options
+  if source.respond_to? :to_str
+    source = source.to_str
+  elsif source.respond_to? :to_io
+    source = source.to_io.read
+  elsif source.respond_to?(:read)
+    source = source.read
+  end
+  if opts[:allow_blank] && (source.nil? || source.empty?)
+    source = 'null'
+  end
+  result = parse(source, opts)
+  recurse_proc(result, &proc) if proc
+  result
+end
+
+ +
+ + +
+ Also aliased as: restore +
+ + + +
+ + +
+ +
+ parse(source, opts = {}) + + click to toggle source + +
+ + +
+ +

Parse the JSON document source into a Ruby +data structure and return it.

+ +

opts can have the following keys:

+
  • +

    max_nesting: The maximum depth of nesting allowed in the +parsed data structures. Disable depth checking with :max_nesting => +false. It defaults to 100.

    +
  • +

    allow_nan: If set to true, allow NaN, Infinity and +-Infinity in defiance of RFC 7159 to be parsed by the Parser. This option +defaults to false.

    +
  • +

    symbolize_names: If set to true, returns symbols for the +names (keys) in a JSON object. Otherwise strings +are returned. Strings are the default.

    +
  • +

    create_additions: If set to false, the Parser doesn't +create additions even if a matching class and ::create_id was found. This +option defaults to false.

    +
  • +

    object_class: Defaults to Hash

    +
  • +

    array_class: Defaults to Array

    +
+ + + + +
+
# File lib/json/common.rb, line 155
+def parse(source, opts = {})
+  Parser.new(source, opts).parse
+end
+
+ +
+ + + + +
+ + +
+ +
+ parse!(source, opts = {}) + + click to toggle source + +
+ + +
+ +

Parse the JSON document source into a Ruby +data structure and return it. The bang version of the parse method defaults +to the more dangerous values for the opts hash, so be sure only to +parse trusted source documents.

+ +

opts can have the following keys:

+
  • +

    max_nesting: The maximum depth of nesting allowed in the +parsed data structures. Enable depth checking with :max_nesting => +anInteger. The parse! methods defaults to not doing max depth checking: +This can be dangerous if someone wants to fill up your stack.

    +
  • +

    allow_nan: If set to true, allow NaN, Infinity, +and -Infinity in defiance of RFC 7159 to be parsed by the Parser. This +option defaults to true.

    +
  • +

    create_additions: If set to false, the Parser doesn't +create additions even if a matching class and ::create_id was found. This +option defaults to false.

    +
+ + + + +
+
# File lib/json/common.rb, line 174
+def parse!(source, opts = {})
+  opts = {
+    :max_nesting  => false,
+    :allow_nan    => true
+  }.merge(opts)
+  Parser.new(source, opts).parse
+end
+
+ +
+ + + + +
+ + +
+ +
+ pretty_generate(obj, opts = nil) + + click to toggle source + +
+ + +
+ +

Generate a JSON document from the Ruby data +structure obj and return it. The returned document is a prettier +form of the document returned by unparse.

+ +

The opts argument can be used to configure the generator. See the +generate method for a more detailed explanation.

+ + + + +
+
# File lib/json/common.rb, line 270
+def pretty_generate(obj, opts = nil)
+  if State === opts
+    state, opts = opts, nil
+  else
+    state = PRETTY_STATE_PROTOTYPE.dup
+  end
+  if opts
+    if opts.respond_to? :to_hash
+      opts = opts.to_hash
+    elsif opts.respond_to? :to_h
+      opts = opts.to_h
+    else
+      raise TypeError, "can't convert #{opts.class} into Hash"
+    end
+    state.configure(opts)
+  end
+  state.generate(obj)
+end
+
+ +
+ + + + +
+ + +
+ +
+ recurse_proc(result, &proc) + + click to toggle source + +
+ + +
+ +

Recursively calls passed Proc if the parsed data structure is an +Array or Hash

+ + + + +
+
# File lib/json/common.rb, line 341
+def recurse_proc(result, &proc)
+  case result
+  when Array
+    result.each { |x| recurse_proc x, &proc }
+    proc.call result
+  when Hash
+    result.each { |x, y| recurse_proc x, &proc; recurse_proc y, &proc }
+    proc.call result
+  else
+    proc.call result
+  end
+end
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/JSON/CircularDatastructure.html b/tmp/rdoc/JSON/CircularDatastructure.html new file mode 100644 index 000000000..cbdbdff01 --- /dev/null +++ b/tmp/rdoc/JSON/CircularDatastructure.html @@ -0,0 +1,103 @@ + + + + + + +class JSON::CircularDatastructure - RDoc Documentation + + + + + + + + + + + + + + +
+

+ class JSON::CircularDatastructure +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+ + + + diff --git a/tmp/rdoc/JSON/Ext.html b/tmp/rdoc/JSON/Ext.html new file mode 100644 index 000000000..241174fc5 --- /dev/null +++ b/tmp/rdoc/JSON/Ext.html @@ -0,0 +1,99 @@ + + + + + + +module JSON::Ext - RDoc Documentation + + + + + + + + + + + + + + +
+

+ module JSON::Ext +

+ +
+ +

This module holds all the modules/classes that implement JSON's +functionality as C extensions.

+ +
+ + + + +
+ + + + + + + + + +
+
+ + + + diff --git a/tmp/rdoc/JSON/Ext/Generator.html b/tmp/rdoc/JSON/Ext/Generator.html new file mode 100644 index 000000000..795fa9ede --- /dev/null +++ b/tmp/rdoc/JSON/Ext/Generator.html @@ -0,0 +1,104 @@ + + + + + + +module JSON::Ext::Generator - RDoc Documentation + + + + + + + + + + + + + + +
+

+ module JSON::Ext::Generator +

+ +
+ +

This is the JSON generator implemented as a C +extension. It can be configured to be used by setting

+ +
JSON.generator = JSON::Ext::Generator
+
+ +

with the method generator= in JSON.

+ +
+ + + + +
+ + + + + + + + + +
+
+ + + + diff --git a/tmp/rdoc/JSON/Ext/Generator/GeneratorMethods.html b/tmp/rdoc/JSON/Ext/Generator/GeneratorMethods.html new file mode 100644 index 000000000..ad9b1a9db --- /dev/null +++ b/tmp/rdoc/JSON/Ext/Generator/GeneratorMethods.html @@ -0,0 +1,96 @@ + + + + + + +module JSON::Ext::Generator::GeneratorMethods - RDoc Documentation + + + + + + + + + + + + + + +
+

+ module JSON::Ext::Generator::GeneratorMethods +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+ + + + diff --git a/tmp/rdoc/JSON/Ext/Generator/GeneratorMethods/Array.html b/tmp/rdoc/JSON/Ext/Generator/GeneratorMethods/Array.html new file mode 100644 index 000000000..0c7e858f0 --- /dev/null +++ b/tmp/rdoc/JSON/Ext/Generator/GeneratorMethods/Array.html @@ -0,0 +1,153 @@ + + + + + + +module JSON::Ext::Generator::GeneratorMethods::Array - RDoc Documentation + + + + + + + + + + + + + + +
+

+ module JSON::Ext::Generator::GeneratorMethods::Array +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Instance Methods

+
+ + +
+ + +
+ + to_json(state = nil) + + + click to toggle source + +
+ + + +
+ +

Returns a JSON string containing a JSON array, that is generated from this Array instance. state is a JSON::State +object, that can also be used to configure the produced JSON string output further.

+ + + + +
+
static VALUE mArray_to_json(int argc, VALUE *argv, VALUE self) {
+    GENERATE_JSON(array);
+}
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/JSON/Ext/Generator/GeneratorMethods/Bignum.html b/tmp/rdoc/JSON/Ext/Generator/GeneratorMethods/Bignum.html new file mode 100644 index 000000000..82ae8f5ac --- /dev/null +++ b/tmp/rdoc/JSON/Ext/Generator/GeneratorMethods/Bignum.html @@ -0,0 +1,151 @@ + + + + + + +module JSON::Ext::Generator::GeneratorMethods::Bignum - RDoc Documentation + + + + + + + + + + + + + + +
+

+ module JSON::Ext::Generator::GeneratorMethods::Bignum +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Instance Methods

+
+ + +
+ + +
+ + to_json(*) + + + click to toggle source + +
+ + + +
+ +

Returns a JSON string representation +for this Integer number.

+ + + + +
+
static VALUE mBignum_to_json(int argc, VALUE *argv, VALUE self)
+{
+    GENERATE_JSON(bignum);
+}
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/JSON/Ext/Generator/GeneratorMethods/FalseClass.html b/tmp/rdoc/JSON/Ext/Generator/GeneratorMethods/FalseClass.html new file mode 100644 index 000000000..b32aeba21 --- /dev/null +++ b/tmp/rdoc/JSON/Ext/Generator/GeneratorMethods/FalseClass.html @@ -0,0 +1,151 @@ + + + + + + +module JSON::Ext::Generator::GeneratorMethods::FalseClass - RDoc Documentation + + + + + + + + + + + + + + +
+

+ module JSON::Ext::Generator::GeneratorMethods::FalseClass +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Instance Methods

+
+ + +
+ + +
+ + to_json(*) + + + click to toggle source + +
+ + + +
+ +

Returns a JSON string for false: +'false'.

+ + + + +
+
static VALUE mFalseClass_to_json(int argc, VALUE *argv, VALUE self)
+{
+    GENERATE_JSON(false);
+}
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/JSON/Ext/Generator/GeneratorMethods/Fixnum.html b/tmp/rdoc/JSON/Ext/Generator/GeneratorMethods/Fixnum.html new file mode 100644 index 000000000..8cdb9cd12 --- /dev/null +++ b/tmp/rdoc/JSON/Ext/Generator/GeneratorMethods/Fixnum.html @@ -0,0 +1,151 @@ + + + + + + +module JSON::Ext::Generator::GeneratorMethods::Fixnum - RDoc Documentation + + + + + + + + + + + + + + +
+

+ module JSON::Ext::Generator::GeneratorMethods::Fixnum +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Instance Methods

+
+ + +
+ + +
+ + to_json(*) + + + click to toggle source + +
+ + + +
+ +

Returns a JSON string representation +for this Integer number.

+ + + + +
+
static VALUE mFixnum_to_json(int argc, VALUE *argv, VALUE self)
+{
+    GENERATE_JSON(fixnum);
+}
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/JSON/Ext/Generator/GeneratorMethods/Float.html b/tmp/rdoc/JSON/Ext/Generator/GeneratorMethods/Float.html new file mode 100644 index 000000000..6aaa7bb51 --- /dev/null +++ b/tmp/rdoc/JSON/Ext/Generator/GeneratorMethods/Float.html @@ -0,0 +1,151 @@ + + + + + + +module JSON::Ext::Generator::GeneratorMethods::Float - RDoc Documentation + + + + + + + + + + + + + + +
+

+ module JSON::Ext::Generator::GeneratorMethods::Float +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Instance Methods

+
+ + +
+ + +
+ + to_json(*) + + + click to toggle source + +
+ + + +
+ +

Returns a JSON string representation +for this Float number.

+ + + + +
+
static VALUE mFloat_to_json(int argc, VALUE *argv, VALUE self)
+{
+    GENERATE_JSON(float);
+}
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/JSON/Ext/Generator/GeneratorMethods/Hash.html b/tmp/rdoc/JSON/Ext/Generator/GeneratorMethods/Hash.html new file mode 100644 index 000000000..1c35d414d --- /dev/null +++ b/tmp/rdoc/JSON/Ext/Generator/GeneratorMethods/Hash.html @@ -0,0 +1,154 @@ + + + + + + +module JSON::Ext::Generator::GeneratorMethods::Hash - RDoc Documentation + + + + + + + + + + + + + + +
+

+ module JSON::Ext::Generator::GeneratorMethods::Hash +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Instance Methods

+
+ + +
+ + +
+ + to_json(state = nil) + + + click to toggle source + +
+ + + +
+ +

Returns a JSON string containing a JSON object, that is generated from this +Hash instance. state is a JSON::State +object, that can also be used to configure the produced JSON string output further.

+ + + + +
+
static VALUE mHash_to_json(int argc, VALUE *argv, VALUE self)
+{
+    GENERATE_JSON(object);
+}
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/JSON/Ext/Generator/GeneratorMethods/Integer.html b/tmp/rdoc/JSON/Ext/Generator/GeneratorMethods/Integer.html new file mode 100644 index 000000000..c627cc66f --- /dev/null +++ b/tmp/rdoc/JSON/Ext/Generator/GeneratorMethods/Integer.html @@ -0,0 +1,151 @@ + + + + + + +module JSON::Ext::Generator::GeneratorMethods::Integer - RDoc Documentation + + + + + + + + + + + + + + +
+

+ module JSON::Ext::Generator::GeneratorMethods::Integer +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Instance Methods

+
+ + +
+ + +
+ + to_json(*) + + + click to toggle source + +
+ + + +
+ +

Returns a JSON string representation +for this Integer number.

+ + + + +
+
static VALUE mInteger_to_json(int argc, VALUE *argv, VALUE self)
+{
+    GENERATE_JSON(integer);
+}
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/JSON/Ext/Generator/GeneratorMethods/NilClass.html b/tmp/rdoc/JSON/Ext/Generator/GeneratorMethods/NilClass.html new file mode 100644 index 000000000..5067bd274 --- /dev/null +++ b/tmp/rdoc/JSON/Ext/Generator/GeneratorMethods/NilClass.html @@ -0,0 +1,151 @@ + + + + + + +module JSON::Ext::Generator::GeneratorMethods::NilClass - RDoc Documentation + + + + + + + + + + + + + + +
+

+ module JSON::Ext::Generator::GeneratorMethods::NilClass +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Instance Methods

+
+ + +
+ + +
+ + to_json(*) + + + click to toggle source + +
+ + + +
+ +

Returns a JSON string for nil: +'null'.

+ + + + +
+
static VALUE mNilClass_to_json(int argc, VALUE *argv, VALUE self)
+{
+    GENERATE_JSON(null);
+}
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/JSON/Ext/Generator/GeneratorMethods/Object.html b/tmp/rdoc/JSON/Ext/Generator/GeneratorMethods/Object.html new file mode 100644 index 000000000..2bd8f870b --- /dev/null +++ b/tmp/rdoc/JSON/Ext/Generator/GeneratorMethods/Object.html @@ -0,0 +1,159 @@ + + + + + + +module JSON::Ext::Generator::GeneratorMethods::Object - RDoc Documentation + + + + + + + + + + + + + + +
+

+ module JSON::Ext::Generator::GeneratorMethods::Object +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Instance Methods

+
+ + +
+ + +
+ + to_json(*) + + + click to toggle source + +
+ + + +
+ +

Converts this object to a string (calling to_s), converts it to a JSON string, and returns the result. This +is a fallback, if no special method to_json was defined for some +object.

+ + + + +
+
static VALUE mObject_to_json(int argc, VALUE *argv, VALUE self)
+{
+    VALUE state;
+    VALUE string = rb_funcall(self, i_to_s, 0);
+    rb_scan_args(argc, argv, "01", &state);
+    Check_Type(string, T_STRING);
+    state = cState_from_state_s(cState, state);
+    return cState_partial_generate(state, string);
+}
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/JSON/Ext/Generator/GeneratorMethods/String.html b/tmp/rdoc/JSON/Ext/Generator/GeneratorMethods/String.html new file mode 100644 index 000000000..d907e0520 --- /dev/null +++ b/tmp/rdoc/JSON/Ext/Generator/GeneratorMethods/String.html @@ -0,0 +1,289 @@ + + + + + + +module JSON::Ext::Generator::GeneratorMethods::String - RDoc Documentation + + + + + + + + + + + + + + +
+

+ module JSON::Ext::Generator::GeneratorMethods::String +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Class Methods

+
+ + +
+ + +
+ + included(modul) + + + click to toggle source + +
+ + + +
+ +

Extends modul with the String::Extend module.

+ + + + +
+
static VALUE mString_included_s(VALUE self, VALUE modul) {
+    VALUE result = rb_funcall(modul, i_extend, 1, mString_Extend);
+    return result;
+}
+
+ +
+ + + + +
+ + +
+ +
+
+

Public Instance Methods

+
+ + +
+ + +
+ + to_json(*) + + + click to toggle source + +
+ + + +
+ +

This string should be encoded with UTF-8 A call to this method returns a JSON string encoded with UTF16 big endian +characters as u????.

+ + + + +
+
static VALUE mString_to_json(int argc, VALUE *argv, VALUE self)
+{
+    GENERATE_JSON(string);
+}
+
+ +
+ + + + +
+ + +
+ + +
+ + to_json_raw(*args) + + + click to toggle source + +
+ + + +
+ +

This method creates a JSON text from +the result of a call to #to_json_raw_object of +this String.

+ + + + +
+
static VALUE mString_to_json_raw(int argc, VALUE *argv, VALUE self)
+{
+    VALUE obj = mString_to_json_raw_object(self);
+    Check_Type(obj, T_HASH);
+    return mHash_to_json(argc, argv, obj);
+}
+
+ +
+ + + + +
+ + +
+ + +
+ + to_json_raw_object() + + + click to toggle source + +
+ + + +
+ +

This method creates a raw object hash, that can be nested into other data +structures and will be generated as a raw string. This method should be +used, if you want to convert raw strings to JSON instead of UTF-8 strings, e. g. +binary data.

+ + + + +
+
static VALUE mString_to_json_raw_object(VALUE self)
+{
+    VALUE ary;
+    VALUE result = rb_hash_new();
+    rb_hash_aset(result, rb_funcall(mJSON, i_create_id, 0), rb_class_name(rb_obj_class(self)));
+    ary = rb_funcall(self, i_unpack, 1, rb_str_new2("C*"));
+    rb_hash_aset(result, rb_str_new2("raw"), ary);
+    return result;
+}
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/JSON/Ext/Generator/GeneratorMethods/String/Extend.html b/tmp/rdoc/JSON/Ext/Generator/GeneratorMethods/String/Extend.html new file mode 100644 index 000000000..3de7e09ec --- /dev/null +++ b/tmp/rdoc/JSON/Ext/Generator/GeneratorMethods/String/Extend.html @@ -0,0 +1,155 @@ + + + + + + +module JSON::Ext::Generator::GeneratorMethods::String::Extend - RDoc Documentation + + + + + + + + + + + + + + +
+

+ module JSON::Ext::Generator::GeneratorMethods::String::Extend +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Instance Methods

+
+ + +
+ + +
+ + json_create(o) + + + click to toggle source + +
+ + + +
+ +

Raw Strings are JSON Objects (the +raw bytes are stored in an array for the key “raw”). The Ruby String can be created by this module method.

+ + + + +
+
static VALUE mString_Extend_json_create(VALUE self, VALUE o)
+{
+    VALUE ary;
+    Check_Type(o, T_HASH);
+    ary = rb_hash_aref(o, rb_str_new2("raw"));
+    return rb_funcall(ary, i_pack, 1, rb_str_new2("C*"));
+}
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/JSON/Ext/Generator/GeneratorMethods/TrueClass.html b/tmp/rdoc/JSON/Ext/Generator/GeneratorMethods/TrueClass.html new file mode 100644 index 000000000..58ac18c60 --- /dev/null +++ b/tmp/rdoc/JSON/Ext/Generator/GeneratorMethods/TrueClass.html @@ -0,0 +1,151 @@ + + + + + + +module JSON::Ext::Generator::GeneratorMethods::TrueClass - RDoc Documentation + + + + + + + + + + + + + + +
+

+ module JSON::Ext::Generator::GeneratorMethods::TrueClass +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Instance Methods

+
+ + +
+ + +
+ + to_json(*) + + + click to toggle source + +
+ + + +
+ +

Returns a JSON string for true: +'true'.

+ + + + +
+
static VALUE mTrueClass_to_json(int argc, VALUE *argv, VALUE self)
+{
+    GENERATE_JSON(true);
+}
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/JSON/Ext/Generator/State.html b/tmp/rdoc/JSON/Ext/Generator/State.html new file mode 100644 index 000000000..014798d55 --- /dev/null +++ b/tmp/rdoc/JSON/Ext/Generator/State.html @@ -0,0 +1,1518 @@ + + + + + + +class JSON::Ext::Generator::State - RDoc Documentation + + + + + + + + + + + + + + +
+

+ class JSON::Ext::Generator::State +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Class Methods

+
+ + +
+ + +
+ + from_state(opts) + + + click to toggle source + +
+ + + +
+ +

Creates a State object from opts, which +ought to be Hash to create a new State instance +configured by opts, something else to create an unconfigured +instance. If opts is a State object, it +is just returned.

+ + + + +
+
static VALUE cState_from_state_s(VALUE self, VALUE opts)
+{
+    if (rb_obj_is_kind_of(opts, self)) {
+        return opts;
+    } else if (rb_obj_is_kind_of(opts, rb_cHash)) {
+        return rb_funcall(self, i_new, 1, opts);
+    } else {
+        if (NIL_P(CJSON_SAFE_STATE_PROTOTYPE)) {
+            CJSON_SAFE_STATE_PROTOTYPE = rb_const_get(mJSON, i_SAFE_STATE_PROTOTYPE);
+        }
+        return rb_funcall(CJSON_SAFE_STATE_PROTOTYPE, i_dup, 0);
+    }
+}
+
+ +
+ + + + +
+ + +
+ + +
+ + new(opts = {}) + + + click to toggle source + +
+ + + +
+ +

Instantiates a new State object, configured by +opts.

+ +

opts can have the following keys:

+
  • +

    indent: a string used to indent levels (default: +''),

    +
  • +

    space: a string that is put after, a : or , delimiter +(default: ''),

    +
  • +

    space_before: a string that is put before a : pair +delimiter (default: ''),

    +
  • +

    object_nl: a string that is put at the end of a JSON object (default: ''),

    +
  • +

    array_nl: a string that is put at the end of a JSON array (default: ''),

    +
  • +

    allow_nan: true if NaN, Infinity, and -Infinity should be +generated, otherwise an exception is thrown, if these values are +encountered. This options defaults to false.

    +
  • +

    buffer_initial_length: sets the initial length of the +generator's internal buffer.

    +
+ + + + +
+
static VALUE cState_initialize(int argc, VALUE *argv, VALUE self)
+{
+    VALUE opts;
+    GET_STATE(self);
+    state->max_nesting = 100;
+    state->buffer_initial_length = FBUFFER_INITIAL_LENGTH_DEFAULT;
+    rb_scan_args(argc, argv, "01", &opts);
+    if (!NIL_P(opts)) cState_configure(self, opts);
+    return self;
+}
+
+ +
+ + + + +
+ + +
+ +
+
+

Public Instance Methods

+
+ + +
+ + +
+ + [](name) + + + click to toggle source + +
+ + + +
+ +

Returns the value returned by method name.

+ + + + +
+
static VALUE cState_aref(VALUE self, VALUE name)
+{
+    name = rb_funcall(name, i_to_s, 0);
+    if (RTEST(rb_funcall(self, i_respond_to_p, 1, name))) {
+        return rb_funcall(self, i_send, 1, name);
+    } else {
+        return rb_ivar_get(self, rb_intern_str(rb_str_concat(rb_str_new2("@"), name)));
+    }
+}
+
+ +
+ + + + +
+ + +
+ + +
+ + []=(name, value) + + + click to toggle source + +
+ + + +
+ +

Sets the attribute name to value.

+ + + + +
+
static VALUE cState_aset(VALUE self, VALUE name, VALUE value)
+{
+    VALUE name_writer;
+
+    name = rb_funcall(name, i_to_s, 0);
+    name_writer = rb_str_cat2(rb_str_dup(name), "=");
+    if (RTEST(rb_funcall(self, i_respond_to_p, 1, name_writer))) {
+        return rb_funcall(self, i_send, 2, name_writer, value);
+    } else {
+        rb_ivar_set(self, rb_intern_str(rb_str_concat(rb_str_new2("@"), name)), value);
+    }
+    return Qnil;
+}
+
+ +
+ + + + +
+ + +
+ + +
+ + allow_nan? + + + click to toggle source + +
+ + + +
+ +

Returns true, if NaN, Infinity, and -Infinity should be generated, +otherwise returns false.

+ + + + +
+
static VALUE cState_allow_nan_p(VALUE self)
+{
+    GET_STATE(self);
+    return state->allow_nan ? Qtrue : Qfalse;
+}
+
+ +
+ + + + +
+ + +
+ + +
+ + array_nl() + + + click to toggle source + +
+ + + +
+ +

This string is put at the end of a line that holds a JSON array.

+ + + + +
+
static VALUE cState_array_nl(VALUE self)
+{
+    GET_STATE(self);
+    return state->array_nl ? rb_str_new(state->array_nl, state->array_nl_len) : rb_str_new2("");
+}
+
+ +
+ + + + +
+ + +
+ + +
+ + array_nl=(array_nl) + + + click to toggle source + +
+ + + +
+ +

This string is put at the end of a line that holds a JSON array.

+ + + + +
+
static VALUE cState_array_nl_set(VALUE self, VALUE array_nl)
+{
+    unsigned long len;
+    GET_STATE(self);
+    Check_Type(array_nl, T_STRING);
+    len = RSTRING_LEN(array_nl);
+    if (len == 0) {
+        if (state->array_nl) {
+            ruby_xfree(state->array_nl);
+            state->array_nl = NULL;
+        }
+    } else {
+        if (state->array_nl) ruby_xfree(state->array_nl);
+        state->array_nl = fstrndup(RSTRING_PTR(array_nl), len);
+        state->array_nl_len = len;
+    }
+    return Qnil;
+}
+
+ +
+ + + + +
+ + +
+ + +
+ + ascii_only? + + + click to toggle source + +
+ + + +
+ +

Returns true, if NaN, Infinity, and -Infinity should be generated, +otherwise returns false.

+ + + + +
+
static VALUE cState_ascii_only_p(VALUE self)
+{
+    GET_STATE(self);
+    return state->ascii_only ? Qtrue : Qfalse;
+}
+
+ +
+ + + + +
+ + +
+ + +
+ + buffer_initial_length + + + click to toggle source + +
+ + + +
+ +

This integer returns the current initial length of the buffer.

+ + + + +
+
static VALUE cState_buffer_initial_length(VALUE self)
+{
+    GET_STATE(self);
+    return LONG2FIX(state->buffer_initial_length);
+}
+
+ +
+ + + + +
+ + +
+ + +
+ + buffer_initial_length=(length) + + + click to toggle source + +
+ + + +
+ +

This sets the initial length of the buffer to length, if +length > 0, otherwise its value isn't changed.

+ + + + +
+
static VALUE cState_buffer_initial_length_set(VALUE self, VALUE buffer_initial_length)
+{
+    long initial_length;
+    GET_STATE(self);
+    Check_Type(buffer_initial_length, T_FIXNUM);
+    initial_length = FIX2LONG(buffer_initial_length);
+    if (initial_length > 0) {
+        state->buffer_initial_length = initial_length;
+    }
+    return Qnil;
+}
+
+ +
+ + + + +
+ + +
+ + +
+ + check_circular? + + + click to toggle source + +
+ + + +
+ +

Returns true, if circular data structures should be checked, otherwise +returns false.

+ + + + +
+
static VALUE cState_check_circular_p(VALUE self)
+{
+    GET_STATE(self);
+    return state->max_nesting ? Qtrue : Qfalse;
+}
+
+ +
+ + + + +
+ + +
+ + +
+ + configure(opts) + + + click to toggle source + +
+ + + +
+ +

Configure this State instance with the Hash +opts, and return itself.

+ + + + +
+
static VALUE cState_configure(VALUE self, VALUE opts)
+{
+    VALUE tmp;
+    GET_STATE(self);
+    tmp = rb_check_convert_type(opts, T_HASH, "Hash", "to_hash");
+    if (NIL_P(tmp)) tmp = rb_convert_type(opts, T_HASH, "Hash", "to_h");
+    opts = tmp;
+    tmp = rb_hash_aref(opts, ID2SYM(i_indent));
+    if (RTEST(tmp)) {
+        unsigned long len;
+        Check_Type(tmp, T_STRING);
+        len = RSTRING_LEN(tmp);
+        state->indent = fstrndup(RSTRING_PTR(tmp), len + 1);
+        state->indent_len = len;
+    }
+    tmp = rb_hash_aref(opts, ID2SYM(i_space));
+    if (RTEST(tmp)) {
+        unsigned long len;
+        Check_Type(tmp, T_STRING);
+        len = RSTRING_LEN(tmp);
+        state->space = fstrndup(RSTRING_PTR(tmp), len + 1);
+        state->space_len = len;
+    }
+    tmp = rb_hash_aref(opts, ID2SYM(i_space_before));
+    if (RTEST(tmp)) {
+        unsigned long len;
+        Check_Type(tmp, T_STRING);
+        len = RSTRING_LEN(tmp);
+        state->space_before = fstrndup(RSTRING_PTR(tmp), len + 1);
+        state->space_before_len = len;
+    }
+    tmp = rb_hash_aref(opts, ID2SYM(i_array_nl));
+    if (RTEST(tmp)) {
+        unsigned long len;
+        Check_Type(tmp, T_STRING);
+        len = RSTRING_LEN(tmp);
+        state->array_nl = fstrndup(RSTRING_PTR(tmp), len + 1);
+        state->array_nl_len = len;
+    }
+    tmp = rb_hash_aref(opts, ID2SYM(i_object_nl));
+    if (RTEST(tmp)) {
+        unsigned long len;
+        Check_Type(tmp, T_STRING);
+        len = RSTRING_LEN(tmp);
+        state->object_nl = fstrndup(RSTRING_PTR(tmp), len + 1);
+        state->object_nl_len = len;
+    }
+    tmp = ID2SYM(i_max_nesting);
+    state->max_nesting = 100;
+    if (option_given_p(opts, tmp)) {
+        VALUE max_nesting = rb_hash_aref(opts, tmp);
+        if (RTEST(max_nesting)) {
+            Check_Type(max_nesting, T_FIXNUM);
+            state->max_nesting = FIX2LONG(max_nesting);
+        } else {
+            state->max_nesting = 0;
+        }
+    }
+    tmp = ID2SYM(i_depth);
+    state->depth = 0;
+    if (option_given_p(opts, tmp)) {
+        VALUE depth = rb_hash_aref(opts, tmp);
+        if (RTEST(depth)) {
+            Check_Type(depth, T_FIXNUM);
+            state->depth = FIX2LONG(depth);
+        } else {
+            state->depth = 0;
+        }
+    }
+    tmp = ID2SYM(i_buffer_initial_length);
+    if (option_given_p(opts, tmp)) {
+        VALUE buffer_initial_length = rb_hash_aref(opts, tmp);
+        if (RTEST(buffer_initial_length)) {
+            long initial_length;
+            Check_Type(buffer_initial_length, T_FIXNUM);
+            initial_length = FIX2LONG(buffer_initial_length);
+            if (initial_length > 0) state->buffer_initial_length = initial_length;
+        }
+    }
+    tmp = rb_hash_aref(opts, ID2SYM(i_allow_nan));
+    state->allow_nan = RTEST(tmp);
+    tmp = rb_hash_aref(opts, ID2SYM(i_ascii_only));
+    state->ascii_only = RTEST(tmp);
+    return self;
+}
+
+ +
+ + +
+ Also aliased as: merge +
+ + + +
+ + +
+ + +
+ + depth + + + click to toggle source + +
+ + + +
+ +

This integer returns the current depth of data structure nesting.

+ + + + +
+
static VALUE cState_depth(VALUE self)
+{
+    GET_STATE(self);
+    return LONG2FIX(state->depth);
+}
+
+ +
+ + + + +
+ + +
+ + +
+ + depth=(depth) + + + click to toggle source + +
+ + + +
+ +

This sets the maximum level of data structure nesting in the generated JSON to the integer depth, #max_nesting = 0 if no maximum +should be checked.

+ + + + +
+
static VALUE cState_depth_set(VALUE self, VALUE depth)
+{
+    GET_STATE(self);
+    Check_Type(depth, T_FIXNUM);
+    state->depth = FIX2LONG(depth);
+    return Qnil;
+}
+
+ +
+ + + + +
+ + +
+ + +
+ + generate(obj) + + + click to toggle source + +
+ + + +
+ +

Generates a valid JSON document from +object obj and returns the result. If no valid JSON document can be created this method +raises a GeneratorError exception.

+ + + + +
+
static VALUE cState_generate(VALUE self, VALUE obj)
+{
+    VALUE result = cState_partial_generate(self, obj);
+    GET_STATE(self);
+    (void)state;
+    return result;
+}
+
+ +
+ + + + +
+ + +
+ + +
+ + indent() + + + click to toggle source + +
+ + + +
+ +

Returns the string that is used to indent levels in the JSON text.

+ + + + +
+
static VALUE cState_indent(VALUE self)
+{
+    GET_STATE(self);
+    return state->indent ? rb_str_new(state->indent, state->indent_len) : rb_str_new2("");
+}
+
+ +
+ + + + +
+ + +
+ + +
+ + indent=(indent) + + + click to toggle source + +
+ + + +
+ +

Sets the string that is used to indent levels in the JSON text.

+ + + + +
+
static VALUE cState_indent_set(VALUE self, VALUE indent)
+{
+    unsigned long len;
+    GET_STATE(self);
+    Check_Type(indent, T_STRING);
+    len = RSTRING_LEN(indent);
+    if (len == 0) {
+        if (state->indent) {
+            ruby_xfree(state->indent);
+            state->indent = NULL;
+            state->indent_len = 0;
+        }
+    } else {
+        if (state->indent) ruby_xfree(state->indent);
+        state->indent = fstrndup(RSTRING_PTR(indent), len);
+        state->indent_len = len;
+    }
+    return Qnil;
+}
+
+ +
+ + + + +
+ + +
+ + +
+ + initialize_copy(orig) + + + click to toggle source + +
+ + + +
+ +

Initializes this object from orig if it can be duplicated/cloned and +returns it.

+ + + + +
+
static VALUE cState_init_copy(VALUE obj, VALUE orig)
+{
+    JSON_Generator_State *objState, *origState;
+
+    if (obj == orig) return obj;
+    GET_STATE_TO(obj, objState);
+    GET_STATE_TO(orig, origState);
+    if (!objState) rb_raise(rb_eArgError, "unallocated JSON::State");
+
+    MEMCPY(objState, origState, JSON_Generator_State, 1);
+    objState->indent = fstrndup(origState->indent, origState->indent_len);
+    objState->space = fstrndup(origState->space, origState->space_len);
+    objState->space_before = fstrndup(origState->space_before, origState->space_before_len);
+    objState->object_nl = fstrndup(origState->object_nl, origState->object_nl_len);
+    objState->array_nl = fstrndup(origState->array_nl, origState->array_nl_len);
+    if (origState->array_delim) objState->array_delim = fbuffer_dup(origState->array_delim);
+    if (origState->object_delim) objState->object_delim = fbuffer_dup(origState->object_delim);
+    if (origState->object_delim2) objState->object_delim2 = fbuffer_dup(origState->object_delim2);
+    return obj;
+}
+
+ +
+ + + + +
+ + +
+ + +
+ + max_nesting + + + click to toggle source + +
+ + + +
+ +

This integer returns the maximum level of data structure nesting in the +generated JSON, #max_nesting = 0 if no maximum +is checked.

+ + + + +
+
static VALUE cState_max_nesting(VALUE self)
+{
+    GET_STATE(self);
+    return LONG2FIX(state->max_nesting);
+}
+
+ +
+ + + + +
+ + +
+ + +
+ + max_nesting=(depth) + + + click to toggle source + +
+ + + +
+ +

This sets the maximum level of data structure nesting in the generated JSON to the integer depth, #max_nesting = 0 if no maximum +should be checked.

+ + + + +
+
static VALUE cState_max_nesting_set(VALUE self, VALUE depth)
+{
+    GET_STATE(self);
+    Check_Type(depth, T_FIXNUM);
+    return state->max_nesting = FIX2LONG(depth);
+}
+
+ +
+ + + + +
+ + +
+ +
+ merge(p1) + +
+ + +
+ + + + + + +
+ + + + +
+ Alias for: configure +
+ +
+ + +
+ + +
+ + object_nl() + + + click to toggle source + +
+ + + +
+ +

This string is put at the end of a line that holds a JSON object (or Hash).

+ + + + +
+
static VALUE cState_object_nl(VALUE self)
+{
+    GET_STATE(self);
+    return state->object_nl ? rb_str_new(state->object_nl, state->object_nl_len) : rb_str_new2("");
+}
+
+ +
+ + + + +
+ + +
+ + +
+ + object_nl=(object_nl) + + + click to toggle source + +
+ + + +
+ +

This string is put at the end of a line that holds a JSON object (or Hash).

+ + + + +
+
static VALUE cState_object_nl_set(VALUE self, VALUE object_nl)
+{
+    unsigned long len;
+    GET_STATE(self);
+    Check_Type(object_nl, T_STRING);
+    len = RSTRING_LEN(object_nl);
+    if (len == 0) {
+        if (state->object_nl) {
+            ruby_xfree(state->object_nl);
+            state->object_nl = NULL;
+        }
+    } else {
+        if (state->object_nl) ruby_xfree(state->object_nl);
+        state->object_nl = fstrndup(RSTRING_PTR(object_nl), len);
+        state->object_nl_len = len;
+    }
+    return Qnil;
+}
+
+ +
+ + + + +
+ + +
+ + +
+ + space() + + + click to toggle source + +
+ + + +
+ +

Returns the string that is used to insert a space between the tokens in a +JSON string.

+ + + + +
+
static VALUE cState_space(VALUE self)
+{
+    GET_STATE(self);
+    return state->space ? rb_str_new(state->space, state->space_len) : rb_str_new2("");
+}
+
+ +
+ + + + +
+ + +
+ + +
+ + space=(space) + + + click to toggle source + +
+ + + +
+ +

Sets space to the string that is used to insert a space between +the tokens in a JSON string.

+ + + + +
+
static VALUE cState_space_set(VALUE self, VALUE space)
+{
+    unsigned long len;
+    GET_STATE(self);
+    Check_Type(space, T_STRING);
+    len = RSTRING_LEN(space);
+    if (len == 0) {
+        if (state->space) {
+            ruby_xfree(state->space);
+            state->space = NULL;
+            state->space_len = 0;
+        }
+    } else {
+        if (state->space) ruby_xfree(state->space);
+        state->space = fstrndup(RSTRING_PTR(space), len);
+        state->space_len = len;
+    }
+    return Qnil;
+}
+
+ +
+ + + + +
+ + +
+ + +
+ + space_before() + + + click to toggle source + +
+ + + +
+ +

Returns the string that is used to insert a space before the ':' in +JSON objects.

+ + + + +
+
static VALUE cState_space_before(VALUE self)
+{
+    GET_STATE(self);
+    return state->space_before ? rb_str_new(state->space_before, state->space_before_len) : rb_str_new2("");
+}
+
+ +
+ + + + +
+ + +
+ + +
+ + space_before=(space_before) + + + click to toggle source + +
+ + + +
+ +

Sets the string that is used to insert a space before the ':' in JSON objects.

+ + + + +
+
static VALUE cState_space_before_set(VALUE self, VALUE space_before)
+{
+    unsigned long len;
+    GET_STATE(self);
+    Check_Type(space_before, T_STRING);
+    len = RSTRING_LEN(space_before);
+    if (len == 0) {
+        if (state->space_before) {
+            ruby_xfree(state->space_before);
+            state->space_before = NULL;
+            state->space_before_len = 0;
+        }
+    } else {
+        if (state->space_before) ruby_xfree(state->space_before);
+        state->space_before = fstrndup(RSTRING_PTR(space_before), len);
+        state->space_before_len = len;
+    }
+    return Qnil;
+}
+
+ +
+ + + + +
+ + +
+ + +
+ + to_h + + + click to toggle source + +
+ + + +
+ +

Returns the configuration instance variables as a hash, that can be passed +to the configure method.

+ + + + +
+
static VALUE cState_to_h(VALUE self)
+{
+    VALUE result = rb_hash_new();
+    GET_STATE(self);
+    set_state_ivars(result, self);
+    rb_hash_aset(result, ID2SYM(i_indent), rb_str_new(state->indent, state->indent_len));
+    rb_hash_aset(result, ID2SYM(i_space), rb_str_new(state->space, state->space_len));
+    rb_hash_aset(result, ID2SYM(i_space_before), rb_str_new(state->space_before, state->space_before_len));
+    rb_hash_aset(result, ID2SYM(i_object_nl), rb_str_new(state->object_nl, state->object_nl_len));
+    rb_hash_aset(result, ID2SYM(i_array_nl), rb_str_new(state->array_nl, state->array_nl_len));
+    rb_hash_aset(result, ID2SYM(i_allow_nan), state->allow_nan ? Qtrue : Qfalse);
+    rb_hash_aset(result, ID2SYM(i_ascii_only), state->ascii_only ? Qtrue : Qfalse);
+    rb_hash_aset(result, ID2SYM(i_max_nesting), LONG2FIX(state->max_nesting));
+    rb_hash_aset(result, ID2SYM(i_depth), LONG2FIX(state->depth));
+    rb_hash_aset(result, ID2SYM(i_buffer_initial_length), LONG2FIX(state->buffer_initial_length));
+    return result;
+}
+
+ +
+ + +
+ Also aliased as: to_hash +
+ + + +
+ + +
+ +
+ to_hash() + +
+ + +
+ + + + + + +
+ + + + +
+ Alias for: to_h +
+ +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/JSON/Ext/Parser.html b/tmp/rdoc/JSON/Ext/Parser.html new file mode 100644 index 000000000..111f0edb8 --- /dev/null +++ b/tmp/rdoc/JSON/Ext/Parser.html @@ -0,0 +1,540 @@ + + + + + + +class JSON::Ext::Parser - RDoc Documentation + + + + + + + + + + + + + + +
+

+ class JSON::Ext::Parser +

+ +
+ +

This is the JSON parser implemented as a C +extension. It can be configured to be used by setting

+ +
JSON.parser = JSON::Ext::Parser
+
+ +

with the method parser= in JSON.

+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Class Methods

+
+ + +
+ + +
+ + new(source, opts → {}) + + + click to toggle source + +
+ + + +
+ +

Creates a new JSON::Ext::Parser instance for the +string source.

+ +

Creates a new JSON::Ext::Parser instance for the +string source.

+ +

It will be configured by the opts hash. opts can have the +following keys:

+ +

opts can have the following keys:

+
  • +

    max_nesting: The maximum depth of nesting allowed in the +parsed data structures. Disable depth checking with :max_nesting => +false|nil|0, it defaults to 100.

    +
  • +

    allow_nan: If set to true, allow NaN, Infinity and +-Infinity in defiance of RFC 4627 to be parsed by the Parser. This option defaults to false.

    +
  • +

    symbolize_names: If set to true, returns symbols for the +names (keys) in a JSON object. Otherwise +strings are returned, which is also the default. It's not possible to +use this option in conjunction with the create_additions +option.

    +
  • +

    create_additions: If set to false, the Parser doesn't create additions even if a +matching class and create_id was found. This option defaults to false.

    +
  • +

    object_class: Defaults to Hash

    +
  • +

    array_class: Defaults to Array

    +
+ + + + +
+
static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
+{
+    VALUE source, opts;
+    GET_PARSER_INIT;
+
+    if (json->Vsource) {
+        rb_raise(rb_eTypeError, "already initialized instance");
+    }
+#ifdef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH
+    rb_scan_args(argc, argv, "1:", &source, &opts);
+#else
+    rb_scan_args(argc, argv, "11", &source, &opts);
+#endif
+    if (!NIL_P(opts)) {
+#ifndef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH
+        opts = rb_convert_type(opts, T_HASH, "Hash", "to_hash");
+        if (NIL_P(opts)) {
+            rb_raise(rb_eArgError, "opts needs to be like a hash");
+        } else {
+#endif
+            VALUE tmp = ID2SYM(i_max_nesting);
+            if (option_given_p(opts, tmp)) {
+                VALUE max_nesting = rb_hash_aref(opts, tmp);
+                if (RTEST(max_nesting)) {
+                    Check_Type(max_nesting, T_FIXNUM);
+                    json->max_nesting = FIX2INT(max_nesting);
+                } else {
+                    json->max_nesting = 0;
+                }
+            } else {
+                json->max_nesting = 100;
+            }
+            tmp = ID2SYM(i_allow_nan);
+            if (option_given_p(opts, tmp)) {
+                json->allow_nan = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
+            } else {
+                json->allow_nan = 0;
+            }
+            tmp = ID2SYM(i_symbolize_names);
+            if (option_given_p(opts, tmp)) {
+                json->symbolize_names = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
+            } else {
+                json->symbolize_names = 0;
+            }
+            tmp = ID2SYM(i_create_additions);
+            if (option_given_p(opts, tmp)) {
+                json->create_additions = RTEST(rb_hash_aref(opts, tmp));
+            } else {
+                json->create_additions = 0;
+            }
+            if (json->symbolize_names && json->create_additions) {
+              rb_raise(rb_eArgError,
+                "options :symbolize_names and :create_additions cannot be "
+                " used in conjunction");
+            }
+            tmp = ID2SYM(i_create_id);
+            if (option_given_p(opts, tmp)) {
+                json->create_id = rb_hash_aref(opts, tmp);
+            } else {
+                json->create_id = rb_funcall(mJSON, i_create_id, 0);
+            }
+            tmp = ID2SYM(i_object_class);
+            if (option_given_p(opts, tmp)) {
+                json->object_class = rb_hash_aref(opts, tmp);
+            } else {
+                json->object_class = Qnil;
+            }
+            tmp = ID2SYM(i_array_class);
+            if (option_given_p(opts, tmp)) {
+                json->array_class = rb_hash_aref(opts, tmp);
+            } else {
+                json->array_class = Qnil;
+            }
+            tmp = ID2SYM(i_decimal_class);
+            if (option_given_p(opts, tmp)) {
+                json->decimal_class = rb_hash_aref(opts, tmp);
+            } else {
+                json->decimal_class = Qnil;
+            }
+            tmp = ID2SYM(i_match_string);
+            if (option_given_p(opts, tmp)) {
+                VALUE match_string = rb_hash_aref(opts, tmp);
+                json->match_string = RTEST(match_string) ? match_string : Qnil;
+            } else {
+                json->match_string = Qnil;
+            }
+#ifndef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH
+        }
+#endif
+    } else {
+        json->max_nesting = 100;
+        json->allow_nan = 0;
+        json->create_additions = 1;
+        json->create_id = rb_funcall(mJSON, i_create_id, 0);
+        json->object_class = Qnil;
+        json->array_class = Qnil;
+        json->decimal_class = Qnil;
+    }
+    source = convert_encoding(StringValue(source));
+    StringValue(source);
+    json->len = RSTRING_LEN(source);
+    json->source = RSTRING_PTR(source);;
+    json->Vsource = source;
+    return self;
+}
+
+ +
+ + + + +
+ + +
+ +
+
+

Public Instance Methods

+
+ + +
+ + +
+ + parse() + + + click to toggle source + +
+ + + +
+ +

Parses the current JSON text source +and returns the complete data structure as a result.

+ + + + +
+
static VALUE cParser_parse(VALUE self)
+{
+  char *p, *pe;
+  int cs = EVIL;
+  VALUE result = Qnil;
+  GET_PARSER;
+
+
+#line 1859 "parser.c"
+        {
+        cs = JSON_start;
+        }
+
+#line 758 "parser.rl"
+  p = json->source;
+  pe = p + json->len;
+
+#line 1868 "parser.c"
+        {
+        if ( p == pe )
+                goto _test_eof;
+        switch ( cs )
+        {
+st1:
+        if ( ++p == pe )
+                goto _test_eof1;
+case 1:
+        switch( (*p) ) {
+                case 13: goto st1;
+                case 32: goto st1;
+                case 34: goto tr2;
+                case 45: goto tr2;
+                case 47: goto st6;
+                case 73: goto tr2;
+                case 78: goto tr2;
+                case 91: goto tr2;
+                case 102: goto tr2;
+                case 110: goto tr2;
+                case 116: goto tr2;
+                case 123: goto tr2;
+        }
+        if ( (*p) > 10 ) {
+                if ( 48 <= (*p) && (*p) <= 57 )
+                        goto tr2;
+        } else if ( (*p) >= 9 )
+                goto st1;
+        goto st0;
+st0:
+cs = 0;
+        goto _out;
+tr2:
+#line 734 "parser.rl"
+        {
+        char *np = JSON_parse_value(json, p, pe, &result, 0);
+        if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;}
+    }
+        goto st10;
+st10:
+        if ( ++p == pe )
+                goto _test_eof10;
+case 10:
+#line 1912 "parser.c"
+        switch( (*p) ) {
+                case 13: goto st10;
+                case 32: goto st10;
+                case 47: goto st2;
+        }
+        if ( 9 <= (*p) && (*p) <= 10 )
+                goto st10;
+        goto st0;
+st2:
+        if ( ++p == pe )
+                goto _test_eof2;
+case 2:
+        switch( (*p) ) {
+                case 42: goto st3;
+                case 47: goto st5;
+        }
+        goto st0;
+st3:
+        if ( ++p == pe )
+                goto _test_eof3;
+case 3:
+        if ( (*p) == 42 )
+                goto st4;
+        goto st3;
+st4:
+        if ( ++p == pe )
+                goto _test_eof4;
+case 4:
+        switch( (*p) ) {
+                case 42: goto st4;
+                case 47: goto st10;
+        }
+        goto st3;
+st5:
+        if ( ++p == pe )
+                goto _test_eof5;
+case 5:
+        if ( (*p) == 10 )
+                goto st10;
+        goto st5;
+st6:
+        if ( ++p == pe )
+                goto _test_eof6;
+case 6:
+        switch( (*p) ) {
+                case 42: goto st7;
+                case 47: goto st9;
+        }
+        goto st0;
+st7:
+        if ( ++p == pe )
+                goto _test_eof7;
+case 7:
+        if ( (*p) == 42 )
+                goto st8;
+        goto st7;
+st8:
+        if ( ++p == pe )
+                goto _test_eof8;
+case 8:
+        switch( (*p) ) {
+                case 42: goto st8;
+                case 47: goto st1;
+        }
+        goto st7;
+st9:
+        if ( ++p == pe )
+                goto _test_eof9;
+case 9:
+        if ( (*p) == 10 )
+                goto st1;
+        goto st9;
+        }
+        _test_eof1: cs = 1; goto _test_eof;
+        _test_eof10: cs = 10; goto _test_eof;
+        _test_eof2: cs = 2; goto _test_eof;
+        _test_eof3: cs = 3; goto _test_eof;
+        _test_eof4: cs = 4; goto _test_eof;
+        _test_eof5: cs = 5; goto _test_eof;
+        _test_eof6: cs = 6; goto _test_eof;
+        _test_eof7: cs = 7; goto _test_eof;
+        _test_eof8: cs = 8; goto _test_eof;
+        _test_eof9: cs = 9; goto _test_eof;
+
+        _test_eof: {}
+        _out: {}
+        }
+
+#line 761 "parser.rl"
+
+  if (cs >= JSON_first_final && p == pe) {
+    return result;
+  } else {
+    rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
+    return Qnil;
+  }
+}
+
+ +
+ + + + +
+ + +
+ + +
+ + source() + + + click to toggle source + +
+ + + +
+ +

Returns a copy of the current source string, that was used to +construct this Parser.

+ + + + +
+
static VALUE cParser_source(VALUE self)
+{
+    GET_PARSER;
+    return rb_str_dup(json->Vsource);
+}
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/JSON/GeneratorError.html b/tmp/rdoc/JSON/GeneratorError.html new file mode 100644 index 000000000..65094e7c9 --- /dev/null +++ b/tmp/rdoc/JSON/GeneratorError.html @@ -0,0 +1,105 @@ + + + + + + +class JSON::UnparserError - RDoc Documentation + + + + + + + + + + + + + + +
+

+ class JSON::UnparserError +

+ +
+ +

This exception is raised if a generator or unparser error occurs.

+ +
+ + + + +
+ + + + + + + + + +
+
+ + + + diff --git a/tmp/rdoc/JSON/GenericObject.html b/tmp/rdoc/JSON/GenericObject.html new file mode 100644 index 000000000..1ff99cb10 --- /dev/null +++ b/tmp/rdoc/JSON/GenericObject.html @@ -0,0 +1,547 @@ + + + + + + +class JSON::GenericObject - RDoc Documentation + + + + + + + + + + + + + + +
+

+ class JSON::GenericObject +

+ +
+ +
+ + + + +
+ + + + + + + +
+
+

Attributes

+
+ + +
+
+ json_creatable[W] +
+ +
+ + + +
+
+ +
+ + + +
+
+

Public Class Methods

+
+ + +
+ +
+ dump(obj, *args) + + click to toggle source + +
+ + +
+ + + + + + +
+
# File lib/json/generic_object.rb, line 41
+def dump(obj, *args)
+  ::JSON.dump(obj, *args)
+end
+
+ +
+ + + + +
+ + +
+ +
+ from_hash(object) + + click to toggle source + +
+ + +
+ + + + + + +
+
# File lib/json/generic_object.rb, line 21
+def from_hash(object)
+  case
+  when object.respond_to?(:to_hash)
+    result = new
+    object.to_hash.each do |key, value|
+      result[key] = from_hash(value)
+    end
+    result
+  when object.respond_to?(:to_ary)
+    object.to_ary.map { |a| from_hash(a) }
+  else
+    object
+  end
+end
+
+ +
+ + + + +
+ + +
+ +
+ json_creatable?() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File lib/json/generic_object.rb, line 9
+def json_creatable?
+  @json_creatable
+end
+
+ +
+ + + + +
+ + +
+ +
+ json_create(data) + + click to toggle source + +
+ + +
+ + + + + + +
+
# File lib/json/generic_object.rb, line 15
+def json_create(data)
+  data = data.dup
+  data.delete JSON.create_id
+  self[data]
+end
+
+ +
+ + + + +
+ + +
+ +
+ load(source, proc = nil, opts = {}) + + click to toggle source + +
+ + +
+ + + + + + +
+
# File lib/json/generic_object.rb, line 36
+def load(source, proc = nil, opts = {})
+  result = ::JSON.load(source, proc, opts.merge(:object_class => self))
+  result.nil? ? new : result
+end
+
+ +
+ + + + +
+ + +
+ +
+
+

Public Instance Methods

+
+ + +
+ +
+ [](name) + + click to toggle source + +
+ + +
+ + + + + + +
+
# File lib/json/generic_object.rb, line 51
+def [](name)
+  __send__(name)
+end
+
+ +
+ + + + +
+ + +
+ +
+ []=(name, value) + + click to toggle source + +
+ + +
+ + + + + + +
+
# File lib/json/generic_object.rb, line 55
+def []=(name, value)
+  __send__("#{name}=", value)
+end
+
+ +
+ + + + +
+ + +
+ +
+ as_json(*) + + click to toggle source + +
+ + +
+ + + + + + +
+
# File lib/json/generic_object.rb, line 63
+def as_json(*)
+  { JSON.create_id => self.class.name }.merge to_hash
+end
+
+ +
+ + + + +
+ + +
+ +
+ to_hash() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File lib/json/generic_object.rb, line 47
+def to_hash
+  table
+end
+
+ +
+ + + + +
+ + +
+ +
+ to_json(*a) + + click to toggle source + +
+ + +
+ + + + + + +
+
# File lib/json/generic_object.rb, line 67
+def to_json(*a)
+  as_json.to_json(*a)
+end
+
+ +
+ + + + +
+ + +
+ +
+ |(other) + + click to toggle source + +
+ + +
+ + + + + + +
+
# File lib/json/generic_object.rb, line 59
+def |(other)
+  self.class[other.to_hash.merge(to_hash)]
+end
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/JSON/JSONError.html b/tmp/rdoc/JSON/JSONError.html new file mode 100644 index 000000000..eec91c193 --- /dev/null +++ b/tmp/rdoc/JSON/JSONError.html @@ -0,0 +1,158 @@ + + + + + + +class JSON::JSONError - RDoc Documentation + + + + + + + + + + + + + + +
+

+ class JSON::JSONError +

+ +
+ +

The base exception for JSON errors.

+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Class Methods

+
+ + +
+ +
+ wrap(exception) + + click to toggle source + +
+ + +
+ + + + + + +
+
# File lib/json/common.rb, line 108
+def self.wrap(exception)
+  obj = new("Wrapped(#{exception.class}): #{exception.message.inspect}")
+  obj.set_backtrace exception.backtrace
+  obj
+end
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/JSON/MissingUnicodeSupport.html b/tmp/rdoc/JSON/MissingUnicodeSupport.html new file mode 100644 index 000000000..6a91b2253 --- /dev/null +++ b/tmp/rdoc/JSON/MissingUnicodeSupport.html @@ -0,0 +1,106 @@ + + + + + + +class JSON::MissingUnicodeSupport - RDoc Documentation + + + + + + + + + + + + + + +
+

+ class JSON::MissingUnicodeSupport +

+ +
+ +

This exception is raised if the required unicode support is missing on the +system. Usually this means that the iconv library is not installed.

+ +
+ + + + +
+ + + + + + + + + +
+
+ + + + diff --git a/tmp/rdoc/JSON/NestingError.html b/tmp/rdoc/JSON/NestingError.html new file mode 100644 index 000000000..972a5c745 --- /dev/null +++ b/tmp/rdoc/JSON/NestingError.html @@ -0,0 +1,106 @@ + + + + + + +class JSON::NestingError - RDoc Documentation + + + + + + + + + + + + + + +
+

+ class JSON::NestingError +

+ +
+ +

This exception is raised if the nesting of parsed data structures is too +deep.

+ +
+ + + + +
+ + + + + + + + + +
+
+ + + + diff --git a/tmp/rdoc/JSON/ParserError.html b/tmp/rdoc/JSON/ParserError.html new file mode 100644 index 000000000..2b38411df --- /dev/null +++ b/tmp/rdoc/JSON/ParserError.html @@ -0,0 +1,105 @@ + + + + + + +class JSON::ParserError - RDoc Documentation + + + + + + + + + + + + + + +
+

+ class JSON::ParserError +

+ +
+ +

This exception is raised if a parser error occurs.

+ +
+ + + + +
+ + + + + + + + + +
+
+ + + + diff --git a/tmp/rdoc/JSON/Pure.html b/tmp/rdoc/JSON/Pure.html new file mode 100644 index 000000000..796e57f5e --- /dev/null +++ b/tmp/rdoc/JSON/Pure.html @@ -0,0 +1,99 @@ + + + + + + +module JSON::Pure - RDoc Documentation + + + + + + + + + + + + + + +
+

+ module JSON::Pure +

+ +
+ +

This module holds all the modules/classes that implement JSON's +functionality in pure ruby.

+ +
+ + + + +
+ + + + + + + + + +
+
+ + + + diff --git a/tmp/rdoc/JSON/Pure/Generator.html b/tmp/rdoc/JSON/Pure/Generator.html new file mode 100644 index 000000000..74d815df4 --- /dev/null +++ b/tmp/rdoc/JSON/Pure/Generator.html @@ -0,0 +1,96 @@ + + + + + + +module JSON::Pure::Generator - RDoc Documentation + + + + + + + + + + + + + + +
+

+ module JSON::Pure::Generator +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+ + + + diff --git a/tmp/rdoc/JSON/Pure/Generator/GeneratorMethods.html b/tmp/rdoc/JSON/Pure/Generator/GeneratorMethods.html new file mode 100644 index 000000000..ff47abc72 --- /dev/null +++ b/tmp/rdoc/JSON/Pure/Generator/GeneratorMethods.html @@ -0,0 +1,96 @@ + + + + + + +module JSON::Pure::Generator::GeneratorMethods - RDoc Documentation + + + + + + + + + + + + + + +
+

+ module JSON::Pure::Generator::GeneratorMethods +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+ + + + diff --git a/tmp/rdoc/JSON/Pure/Generator/GeneratorMethods/Array.html b/tmp/rdoc/JSON/Pure/Generator/GeneratorMethods/Array.html new file mode 100644 index 000000000..992c29076 --- /dev/null +++ b/tmp/rdoc/JSON/Pure/Generator/GeneratorMethods/Array.html @@ -0,0 +1,153 @@ + + + + + + +module JSON::Pure::Generator::GeneratorMethods::Array - RDoc Documentation + + + + + + + + + + + + + + +
+

+ module JSON::Pure::Generator::GeneratorMethods::Array +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Instance Methods

+
+ + +
+ +
+ to_json(state = nil, *) + + click to toggle source + +
+ + +
+ +

Returns a JSON string containing a JSON array, that is unparsed from this Array instance. state is a JSON::State +object, that can also be used to configure the produced JSON string output further.

+ + + + +
+
# File lib/json/pure/generator.rb, line 328
+def to_json(state = nil, *)
+  state = State.from_state(state)
+  state.check_max_nesting
+  json_transform(state)
+end
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/JSON/Pure/Generator/GeneratorMethods/FalseClass.html b/tmp/rdoc/JSON/Pure/Generator/GeneratorMethods/FalseClass.html new file mode 100644 index 000000000..8144d5494 --- /dev/null +++ b/tmp/rdoc/JSON/Pure/Generator/GeneratorMethods/FalseClass.html @@ -0,0 +1,146 @@ + + + + + + +module JSON::Pure::Generator::GeneratorMethods::FalseClass - RDoc Documentation + + + + + + + + + + + + + + +
+

+ module JSON::Pure::Generator::GeneratorMethods::FalseClass +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Instance Methods

+
+ + +
+ +
+ to_json(*) + + click to toggle source + +
+ + +
+ +

Returns a JSON string for false: +'false'.

+ + + + +
+
# File lib/json/pure/generator.rb, line 448
+def to_json(*) 'false' end
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/JSON/Pure/Generator/GeneratorMethods/Float.html b/tmp/rdoc/JSON/Pure/Generator/GeneratorMethods/Float.html new file mode 100644 index 000000000..2f574012e --- /dev/null +++ b/tmp/rdoc/JSON/Pure/Generator/GeneratorMethods/Float.html @@ -0,0 +1,164 @@ + + + + + + +module JSON::Pure::Generator::GeneratorMethods::Float - RDoc Documentation + + + + + + + + + + + + + + +
+

+ module JSON::Pure::Generator::GeneratorMethods::Float +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Instance Methods

+
+ + +
+ +
+ to_json(state = nil, *) + + click to toggle source + +
+ + +
+ +

Returns a JSON string representation +for this Float number.

+ + + + +
+
# File lib/json/pure/generator.rb, line 368
+def to_json(state = nil, *)
+  state = State.from_state(state)
+  case
+  when infinite?
+    if state.allow_nan?
+      to_s
+    else
+      raise GeneratorError, "#{self} not allowed in JSON"
+    end
+  when nan?
+    if state.allow_nan?
+      to_s
+    else
+      raise GeneratorError, "#{self} not allowed in JSON"
+    end
+  else
+    to_s
+  end
+end
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/JSON/Pure/Generator/GeneratorMethods/Hash.html b/tmp/rdoc/JSON/Pure/Generator/GeneratorMethods/Hash.html new file mode 100644 index 000000000..67c4a5c71 --- /dev/null +++ b/tmp/rdoc/JSON/Pure/Generator/GeneratorMethods/Hash.html @@ -0,0 +1,154 @@ + + + + + + +module JSON::Pure::Generator::GeneratorMethods::Hash - RDoc Documentation + + + + + + + + + + + + + + +
+

+ module JSON::Pure::Generator::GeneratorMethods::Hash +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Instance Methods

+
+ + +
+ +
+ to_json(state = nil, *) + + click to toggle source + +
+ + +
+ +

Returns a JSON string containing a JSON object, that is unparsed from this Hash instance. state is a JSON::State object, +that can also be used to configure the produced JSON string output further. depth +is used to find out nesting depth, to indent accordingly.

+ + + + +
+
# File lib/json/pure/generator.rb, line 280
+def to_json(state = nil, *)
+  state = State.from_state(state)
+  state.check_max_nesting
+  json_transform(state)
+end
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/JSON/Pure/Generator/GeneratorMethods/Integer.html b/tmp/rdoc/JSON/Pure/Generator/GeneratorMethods/Integer.html new file mode 100644 index 000000000..f96e800bb --- /dev/null +++ b/tmp/rdoc/JSON/Pure/Generator/GeneratorMethods/Integer.html @@ -0,0 +1,146 @@ + + + + + + +module JSON::Pure::Generator::GeneratorMethods::Integer - RDoc Documentation + + + + + + + + + + + + + + +
+

+ module JSON::Pure::Generator::GeneratorMethods::Integer +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Instance Methods

+
+ + +
+ +
+ to_json(*) + + click to toggle source + +
+ + +
+ +

Returns a JSON string representation +for this Integer number.

+ + + + +
+
# File lib/json/pure/generator.rb, line 363
+def to_json(*) to_s end
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/JSON/Pure/Generator/GeneratorMethods/NilClass.html b/tmp/rdoc/JSON/Pure/Generator/GeneratorMethods/NilClass.html new file mode 100644 index 000000000..3643ffa0e --- /dev/null +++ b/tmp/rdoc/JSON/Pure/Generator/GeneratorMethods/NilClass.html @@ -0,0 +1,146 @@ + + + + + + +module JSON::Pure::Generator::GeneratorMethods::NilClass - RDoc Documentation + + + + + + + + + + + + + + +
+

+ module JSON::Pure::Generator::GeneratorMethods::NilClass +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Instance Methods

+
+ + +
+ +
+ to_json(*) + + click to toggle source + +
+ + +
+ +

Returns a JSON string for nil: +'null'.

+ + + + +
+
# File lib/json/pure/generator.rb, line 453
+def to_json(*) 'null' end
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/JSON/Pure/Generator/GeneratorMethods/Object.html b/tmp/rdoc/JSON/Pure/Generator/GeneratorMethods/Object.html new file mode 100644 index 000000000..79b610d65 --- /dev/null +++ b/tmp/rdoc/JSON/Pure/Generator/GeneratorMethods/Object.html @@ -0,0 +1,149 @@ + + + + + + +module JSON::Pure::Generator::GeneratorMethods::Object - RDoc Documentation + + + + + + + + + + + + + + +
+

+ module JSON::Pure::Generator::GeneratorMethods::Object +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Instance Methods

+
+ + +
+ +
+ to_json(*) + + click to toggle source + +
+ + +
+ +

Converts this object to a string (calling to_s), converts it to a JSON string, and returns the result. This +is a fallback, if no special method to_json was defined for some +object.

+ + + + +
+
# File lib/json/pure/generator.rb, line 271
+def to_json(*) to_s.to_json end
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/JSON/Pure/Generator/GeneratorMethods/String.html b/tmp/rdoc/JSON/Pure/Generator/GeneratorMethods/String.html new file mode 100644 index 000000000..1b5bc1f02 --- /dev/null +++ b/tmp/rdoc/JSON/Pure/Generator/GeneratorMethods/String.html @@ -0,0 +1,294 @@ + + + + + + +module JSON::Pure::Generator::GeneratorMethods::String - RDoc Documentation + + + + + + + + + + + + + + +
+

+ module JSON::Pure::Generator::GeneratorMethods::String +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Class Methods

+
+ + +
+ +
+ included(modul) + + click to toggle source + +
+ + +
+ +

Extends modul with the String::Extend module.

+ + + + +
+
# File lib/json/pure/generator.rb, line 419
+def self.included(modul)
+  modul.extend Extend
+end
+
+ +
+ + + + +
+ + +
+ +
+
+

Public Instance Methods

+
+ + +
+ +
+ to_json(state = nil, *args) + + click to toggle source + +
+ + +
+ +

This string should be encoded with UTF-8 A call to this method returns a JSON string encoded with UTF16 big endian +characters as u????.

+ + + + +
+
# File lib/json/pure/generator.rb, line 393
+def to_json(state = nil, *args)
+  state = State.from_state(state)
+  if encoding == ::Encoding::UTF_8
+    string = self
+  else
+    string = encode(::Encoding::UTF_8)
+  end
+  if state.ascii_only?
+    '"' << JSON.utf8_to_json_ascii(string) << '"'
+  else
+    '"' << JSON.utf8_to_json(string) << '"'
+  end
+end
+
+ +
+ + + + +
+ + +
+ +
+ to_json_raw(*args) + + click to toggle source + +
+ + +
+ +

This method creates a JSON text from +the result of a call to #to_json_raw_object of +this String.

+ + + + +
+
# File lib/json/pure/generator.rb, line 436
+def to_json_raw(*args)
+  to_json_raw_object.to_json(*args)
+end
+
+ +
+ + + + +
+ + +
+ +
+ to_json_raw_object() + + click to toggle source + +
+ + +
+ +

This method creates a raw object hash, that can be nested into other data +structures and will be unparsed as a raw string. This method should be +used, if you want to convert raw strings to JSON instead of UTF-8 strings, e. g. +binary data.

+ + + + +
+
# File lib/json/pure/generator.rb, line 427
+def to_json_raw_object
+  {
+    JSON.create_id  => self.class.name,
+    'raw'           => self.unpack('C*'),
+  }
+end
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/JSON/Pure/Generator/GeneratorMethods/String/Extend.html b/tmp/rdoc/JSON/Pure/Generator/GeneratorMethods/String/Extend.html new file mode 100644 index 000000000..3b5dcfd1f --- /dev/null +++ b/tmp/rdoc/JSON/Pure/Generator/GeneratorMethods/String/Extend.html @@ -0,0 +1,152 @@ + + + + + + +module JSON::Pure::Generator::GeneratorMethods::String::Extend - RDoc Documentation + + + + + + + + + + + + + + +
+

+ module JSON::Pure::Generator::GeneratorMethods::String::Extend +

+ +
+ +

Module that holds the extinding methods if, the String module is included.

+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Instance Methods

+
+ + +
+ +
+ json_create(o) + + click to toggle source + +
+ + +
+ +

Raw Strings are JSON Objects (the +raw bytes are stored in an array for the key “raw”). The Ruby String can be created by this module method.

+ + + + +
+
# File lib/json/pure/generator.rb, line 413
+def json_create(o)
+  o['raw'].pack('C*')
+end
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/JSON/Pure/Generator/GeneratorMethods/TrueClass.html b/tmp/rdoc/JSON/Pure/Generator/GeneratorMethods/TrueClass.html new file mode 100644 index 000000000..a2e76a6bd --- /dev/null +++ b/tmp/rdoc/JSON/Pure/Generator/GeneratorMethods/TrueClass.html @@ -0,0 +1,146 @@ + + + + + + +module JSON::Pure::Generator::GeneratorMethods::TrueClass - RDoc Documentation + + + + + + + + + + + + + + +
+

+ module JSON::Pure::Generator::GeneratorMethods::TrueClass +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Instance Methods

+
+ + +
+ +
+ to_json(*) + + click to toggle source + +
+ + +
+ +

Returns a JSON string for true: +'true'.

+ + + + +
+
# File lib/json/pure/generator.rb, line 443
+def to_json(*) 'true' end
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/JSON/Pure/Generator/State.html b/tmp/rdoc/JSON/Pure/Generator/State.html new file mode 100644 index 000000000..fbab5ddde --- /dev/null +++ b/tmp/rdoc/JSON/Pure/Generator/State.html @@ -0,0 +1,760 @@ + + + + + + +class JSON::Pure::Generator::State - RDoc Documentation + + + + + + + + + + + + + + +
+

+ class JSON::Pure::Generator::State +

+ +
+ +

This class is used to create State instances, that +are use to hold data while generating a JSON text from a Ruby data structure.

+ +
+ + + + +
+ + + + + + + +
+
+

Attributes

+
+ + +
+
+ array_nl[RW] +
+ +
+ +

This string is put at the end of a line that holds a JSON array.

+ +
+
+ +
+
+ depth[RW] +
+ +
+ +

This integer returns the current depth data structure nesting in the +generated JSON.

+ +
+
+ +
+
+ indent[RW] +
+ +
+ +

This string is used to indent levels in the JSON text.

+ +
+
+ +
+
+ max_nesting[RW] +
+ +
+ +

This integer returns the maximum level of data structure nesting in the +generated JSON, #max_nesting = 0 if no +maximum is checked.

+ +
+
+ +
+
+ object_nl[RW] +
+ +
+ +

This string is put at the end of a line that holds a JSON object (or Hash).

+ +
+
+ +
+
+ space[RW] +
+ +
+ +

This string is used to insert a space between the tokens in a JSON string.

+ +
+
+ +
+
+ space_before[RW] +
+ +
+ +

This string is used to insert a space before the ':' in JSON objects.

+ +
+
+ +
+ + + +
+
+

Public Class Methods

+
+ + +
+ +
+ from_state(opts) + + click to toggle source + +
+ + +
+ +

Creates a State object from opts, which +ought to be Hash to create a new State instance +configured by opts, something else to create an unconfigured +instance. If opts is a State object, it +is just returned.

+ + + + +
+
# File lib/json/pure/generator.rb, line 90
+def self.from_state(opts)
+  case
+  when self === opts
+    opts
+  when opts.respond_to?(:to_hash)
+    new(opts.to_hash)
+  when opts.respond_to?(:to_h)
+    new(opts.to_h)
+  else
+    SAFE_STATE_PROTOTYPE.dup
+  end
+end
+
+ +
+ + + + +
+ + +
+ +
+ new(opts = {}) + + click to toggle source + +
+ + +
+ +

Instantiates a new State object, configured by +opts.

+ +

opts can have the following keys:

+
  • +

    indent: a string used to indent levels (default: +''),

    +
  • +

    space: a string that is put after, a : or , delimiter +(default: ''),

    +
  • +

    space_before: a string that is put before a : pair +delimiter (default: ''),

    +
  • +

    object_nl: a string that is put at the end of a JSON object (default: ''),

    +
  • +

    array_nl: a string that is put at the end of a JSON array (default: ''),

    +
  • +

    check_circular: is deprecated now, use the :max_nesting +option instead,

    +
  • +

    max_nesting: sets the maximum level of data structure +nesting in the generated JSON, #max_nesting = 0 if no +maximum should be checked.

    +
  • +

    allow_nan: true if NaN, Infinity, and -Infinity should be +generated, otherwise an exception is thrown, if these values are +encountered. This options defaults to false.

    +
+ + + + +
+
# File lib/json/pure/generator.rb, line 118
+def initialize(opts = {})
+  @indent                = ''
+  @space                 = ''
+  @space_before          = ''
+  @object_nl             = ''
+  @array_nl              = ''
+  @allow_nan             = false
+  @ascii_only            = false
+  @buffer_initial_length = 1024
+  configure opts
+end
+
+ +
+ + + + +
+ + +
+ +
+
+

Public Instance Methods

+
+ + +
+ +
+ [](name) + + click to toggle source + +
+ + +
+ +

Return the value returned by method name.

+ + + + +
+
# File lib/json/pure/generator.rb, line 249
+def [](name)
+  if respond_to?(name)
+    __send__(name)
+  else
+    instance_variable_get("@#{name}")
+  end
+end
+
+ +
+ + + + +
+ + +
+ +
+ []=(name, value) + + click to toggle source + +
+ + +
+ + + + + + +
+
# File lib/json/pure/generator.rb, line 257
+def []=(name, value)
+  if respond_to?(name_writer = "#{name}=")
+    __send__ name_writer, value
+  else
+    instance_variable_set "@#{name}", value
+  end
+end
+
+ +
+ + + + +
+ + +
+ +
+ allow_nan?() + + click to toggle source + +
+ + +
+ +

Returns true if NaN, Infinity, and -Infinity should be considered as valid +JSON and output.

+ + + + +
+
# File lib/json/pure/generator.rb, line 180
+def allow_nan?
+  @allow_nan
+end
+
+ +
+ + + + +
+ + +
+ +
+ ascii_only?() + + click to toggle source + +
+ + +
+ +

Returns true, if only ASCII characters should be generated. Otherwise +returns false.

+ + + + +
+
# File lib/json/pure/generator.rb, line 186
+def ascii_only?
+  @ascii_only
+end
+
+ +
+ + + + +
+ + +
+ +
+ check_circular?() + + click to toggle source + +
+ + +
+ +

Returns true, if circular data structures are checked, otherwise returns +false.

+ + + + +
+
# File lib/json/pure/generator.rb, line 174
+def check_circular?
+  !@max_nesting.zero?
+end
+
+ +
+ + + + +
+ + +
+ +
+ configure(opts) + + click to toggle source + +
+ + +
+ +

Configure this State instance with the Hash +opts, and return itself.

+ + + + +
+
# File lib/json/pure/generator.rb, line 192
+def configure(opts)
+  if opts.respond_to?(:to_hash)
+    opts = opts.to_hash
+  elsif opts.respond_to?(:to_h)
+    opts = opts.to_h
+  else
+    raise TypeError, "can't convert #{opts.class} into Hash"
+  end
+  for key, value in opts
+    instance_variable_set "@#{key}", value
+  end
+  @indent                = opts[:indent] if opts.key?(:indent)
+  @space                 = opts[:space] if opts.key?(:space)
+  @space_before          = opts[:space_before] if opts.key?(:space_before)
+  @object_nl             = opts[:object_nl] if opts.key?(:object_nl)
+  @array_nl              = opts[:array_nl] if opts.key?(:array_nl)
+  @allow_nan             = !!opts[:allow_nan] if opts.key?(:allow_nan)
+  @ascii_only            = opts[:ascii_only] if opts.key?(:ascii_only)
+  @depth                 = opts[:depth] || 0
+  @buffer_initial_length ||= opts[:buffer_initial_length]
+
+  if !opts.key?(:max_nesting) # defaults to 100
+    @max_nesting = 100
+  elsif opts[:max_nesting]
+    @max_nesting = opts[:max_nesting]
+  else
+    @max_nesting = 0
+  end
+  self
+end
+
+ +
+ + +
+ Also aliased as: merge +
+ + + +
+ + +
+ +
+ generate(obj) + + click to toggle source + +
+ + +
+ +

Generates a valid JSON document from +object obj and returns the result. If no valid JSON document can be created this method +raises a GeneratorError exception.

+ + + + +
+
# File lib/json/pure/generator.rb, line 241
+def generate(obj)
+  result = obj.to_json(self)
+  JSON.valid_utf8?(result) or raise GeneratorError,
+    "source sequence #{result.inspect} is illegal/malformed utf-8"
+  result
+end
+
+ +
+ + + + +
+ + +
+ +
+ merge(opts) + +
+ + +
+ + + + + + +
+ + + + +
+ Alias for: configure +
+ +
+ + +
+ +
+ to_h() + + click to toggle source + +
+ + +
+ +

Returns the configuration instance variables as a hash, that can be passed +to the configure method.

+ + + + +
+
# File lib/json/pure/generator.rb, line 226
+def to_h
+  result = {}
+  for iv in instance_variables
+    iv = iv.to_s[1..-1]
+    result[iv.to_sym] = self[iv]
+  end
+  result
+end
+
+ +
+ + +
+ Also aliased as: to_hash +
+ + + +
+ + +
+ +
+ to_hash() + +
+ + +
+ + + + + + +
+ + + + +
+ Alias for: to_h +
+ +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/JSON/Pure/Parser.html b/tmp/rdoc/JSON/Pure/Parser.html new file mode 100644 index 000000000..c45fd1013 --- /dev/null +++ b/tmp/rdoc/JSON/Pure/Parser.html @@ -0,0 +1,918 @@ + + + + + + +class JSON::Pure::Parser - RDoc Documentation + + + + + + + + + + + + + + +
+

+ class JSON::Pure::Parser +

+ +
+ +

This class implements the JSON parser that is +used to parse a JSON string into a Ruby data +structure.

+ +
+ + + + +
+ + + + + +
+
+

Constants

+
+
+ +
ARRAY_CLOSE + +
+ + +
ARRAY_OPEN + +
+ + +
COLLECTION_DELIMITER + +
+ + +
EMPTY_8BIT_STRING + +
+ + +
FALSE + +
+ + +
FLOAT + +
+ + +
IGNORE + +
+ + +
INFINITY + +
+ + +
INTEGER + +
+ + +
MINUS_INFINITY + +
+ + +
NAN + +
+ + +
NULL + +
+ + +
OBJECT_CLOSE + +
+ + +
OBJECT_OPEN + +
+ + +
PAIR_DELIMITER + +
+ + +
STRING + +
+ + +
TRUE + +
+ + +
UNESCAPE_MAP + +

Unescape characters in strings.

+ + +
UNPARSED + +
+ + +
+
+ + + + + +
+
+

Public Class Methods

+
+ + +
+ +
+ new(source, opts = {}) + + click to toggle source + +
+ + +
+ +

Creates a new JSON::Pure::Parser instance for the +string source.

+ +

It will be configured by the opts hash. opts can have the +following keys:

+
  • +

    max_nesting: The maximum depth of nesting allowed in the +parsed data structures. Disable depth checking with :max_nesting => +false|nil|0, it defaults to 100.

    +
  • +

    allow_nan: If set to true, allow NaN, Infinity and +-Infinity in defiance of RFC 7159 to be parsed by the Parser. This option defaults to false.

    +
  • +

    symbolize_names: If set to true, returns symbols for the +names (keys) in a JSON object. Otherwise +strings are returned, which is also the default. It's not possible to +use this option in conjunction with the create_additions +option.

    +
  • +

    create_additions: If set to true, the Parser creates additions when if a matching class +and create_id was found. This option defaults to false.

    +
  • +

    object_class: Defaults to Hash

    +
  • +

    array_class: Defaults to Array

    +
  • +

    decimal_class: Specifies which class to use instead of the +default

    + +
    (Float) when parsing decimal numbers. This class must accept a single
    +string argument in its constructor.
    +
+ + +
+ Calls superclass method + +
+ + + +
+
# File lib/json/pure/parser.rb, line 76
+def initialize(source, opts = {})
+  opts ||= {}
+  source = convert_encoding source
+  super source
+  if !opts.key?(:max_nesting) # defaults to 100
+    @max_nesting = 100
+  elsif opts[:max_nesting]
+    @max_nesting = opts[:max_nesting]
+  else
+    @max_nesting = 0
+  end
+  @allow_nan = !!opts[:allow_nan]
+  @symbolize_names = !!opts[:symbolize_names]
+  if opts.key?(:create_additions)
+    @create_additions = !!opts[:create_additions]
+  else
+    @create_additions = false
+  end
+  @symbolize_names && @create_additions and raise ArgumentError,
+    'options :symbolize_names and :create_additions cannot be used '           'in conjunction'
+  @create_id = @create_additions ? JSON.create_id : nil
+  @object_class = opts[:object_class] || Hash
+  @array_class  = opts[:array_class] || Array
+  @decimal_class = opts[:decimal_class]
+  @match_string = opts[:match_string]
+end
+
+ +
+ + + + +
+ + +
+ +
+
+

Public Instance Methods

+
+ + +
+ +
+ convert_encoding(source) + + click to toggle source + +
+ + +
+ + + + + + +
+
# File lib/json/pure/parser.rb, line 131
+def convert_encoding(source)
+  if source.respond_to?(:to_str)
+    source = source.to_str
+  else
+    raise TypeError,
+      "#{source.inspect} is not like a string"
+  end
+  if source.encoding != ::Encoding::ASCII_8BIT
+    source = source.encode(::Encoding::UTF_8)
+    source.force_encoding(::Encoding::ASCII_8BIT)
+  end
+  source
+end
+
+ +
+ + + + +
+ + +
+ +
+ parse() + + click to toggle source + +
+ + +
+ +

Parses the current JSON string +source and returns the complete data structure as a result.

+ + + + +
+
# File lib/json/pure/parser.rb, line 113
+    def parse
+      reset
+      obj = nil
+      while !eos? && skip(IGNORE) do end
+      if eos?
+        raise ParserError, "source is not valid JSON!"
+      else
+        obj = parse_value
+        UNPARSED.equal?(obj) and raise ParserError,
+          "source is not valid JSON!"
+      end
+      while !eos? && skip(IGNORE) do end
+      eos? or raise ParserError, "source is not valid JSON!"
+      obj
+    end
+
+    private
+
+    def convert_encoding(source)
+      if source.respond_to?(:to_str)
+        source = source.to_str
+      else
+        raise TypeError,
+          "#{source.inspect} is not like a string"
+      end
+      if source.encoding != ::Encoding::ASCII_8BIT
+        source = source.encode(::Encoding::UTF_8)
+        source.force_encoding(::Encoding::ASCII_8BIT)
+      end
+      source
+    end
+
+    # Unescape characters in strings.
+    UNESCAPE_MAP = Hash.new { |h, k| h[k] = k.chr }
+    UNESCAPE_MAP.update({
+      ?"  => '"',
+      ?\\ => '\',
+      ?/  => '/',
+      ?b  => "\b",
+      ?f  => "\f",
+      ?n  => "\n",
+      ?r  => "\r",
+      ?t  => "\t",
+      ?u  => nil,
+    })
+
+    EMPTY_8BIT_STRING = ''
+    if ::String.method_defined?(:encode)
+      EMPTY_8BIT_STRING.force_encoding Encoding::ASCII_8BIT
+    end
+
+    def parse_string
+      if scan(STRING)
+        return '' if self[1].empty?
+        string = self[1].gsub(%r((?:\[\bfnrt"/]|(?:\u(?:[A-Fa-f\d]{4}))+|\[\x20-\xff]))n) do |c|
+          if u = UNESCAPE_MAP[$&[1]]
+            u
+          else # \uXXXX
+            bytes = EMPTY_8BIT_STRING.dup
+            i = 0
+            while c[6 * i] == ?\\ && c[6 * i + 1] == ?u
+              bytes << c[6 * i + 2, 2].to_i(16) << c[6 * i + 4, 2].to_i(16)
+              i += 1
+            end
+            JSON.iconv('utf-8', 'utf-16be', bytes)
+          end
+        end
+        if string.respond_to?(:force_encoding)
+          string.force_encoding(::Encoding::UTF_8)
+        end
+        if @create_additions and @match_string
+          for (regexp, klass) in @match_string
+            klass.json_creatable? or next
+            string =~ regexp and return klass.json_create(string)
+          end
+        end
+        string
+      else
+        UNPARSED
+      end
+    rescue => e
+      raise ParserError, "Caught #{e.class} at '#{peek(20)}': #{e}"
+    end
+
+    def parse_value
+      case
+      when scan(FLOAT)
+        @decimal_class && @decimal_class.new(self[1]) || Float(self[1])
+      when scan(INTEGER)
+        Integer(self[1])
+      when scan(TRUE)
+        true
+      when scan(FALSE)
+        false
+      when scan(NULL)
+        nil
+      when !UNPARSED.equal?(string = parse_string)
+        string
+      when scan(ARRAY_OPEN)
+        @current_nesting += 1
+        ary = parse_array
+        @current_nesting -= 1
+        ary
+      when scan(OBJECT_OPEN)
+        @current_nesting += 1
+        obj = parse_object
+        @current_nesting -= 1
+        obj
+      when @allow_nan && scan(NAN)
+        NaN
+      when @allow_nan && scan(INFINITY)
+        Infinity
+      when @allow_nan && scan(MINUS_INFINITY)
+        MinusInfinity
+      else
+        UNPARSED
+      end
+    end
+
+    def parse_array
+      raise NestingError, "nesting of #@current_nesting is too deep" if
+        @max_nesting.nonzero? && @current_nesting > @max_nesting
+      result = @array_class.new
+      delim = false
+      until eos?
+        case
+        when !UNPARSED.equal?(value = parse_value)
+          delim = false
+          result << value
+          skip(IGNORE)
+          if scan(COLLECTION_DELIMITER)
+            delim = true
+          elsif match?(ARRAY_CLOSE)
+            ;
+          else
+            raise ParserError, "expected ',' or ']' in array at '#{peek(20)}'!"
+          end
+        when scan(ARRAY_CLOSE)
+          if delim
+            raise ParserError, "expected next element in array at '#{peek(20)}'!"
+          end
+          break
+        when skip(IGNORE)
+          ;
+        else
+          raise ParserError, "unexpected token in array at '#{peek(20)}'!"
+        end
+      end
+      result
+    end
+
+    def parse_object
+      raise NestingError, "nesting of #@current_nesting is too deep" if
+        @max_nesting.nonzero? && @current_nesting > @max_nesting
+      result = @object_class.new
+      delim = false
+      until eos?
+        case
+        when !UNPARSED.equal?(string = parse_string)
+          skip(IGNORE)
+          unless scan(PAIR_DELIMITER)
+            raise ParserError, "expected ':' in object at '#{peek(20)}'!"
+          end
+          skip(IGNORE)
+          unless UNPARSED.equal?(value = parse_value)
+            result[@symbolize_names ? string.to_sym : string] = value
+            delim = false
+            skip(IGNORE)
+            if scan(COLLECTION_DELIMITER)
+              delim = true
+            elsif match?(OBJECT_CLOSE)
+              ;
+            else
+              raise ParserError, "expected ',' or '}' in object at '#{peek(20)}'!"
+            end
+          else
+            raise ParserError, "expected value in object at '#{peek(20)}'!"
+          end
+        when scan(OBJECT_CLOSE)
+          if delim
+            raise ParserError, "expected next name, value pair in object at '#{peek(20)}'!"
+          end
+          if @create_additions and klassname = result[@create_id]
+            klass = JSON.deep_const_get klassname
+            break unless klass and klass.json_creatable?
+            result = klass.json_create(result)
+          end
+          break
+        when skip(IGNORE)
+          ;
+        else
+          raise ParserError, "unexpected token in object at '#{peek(20)}'!"
+        end
+      end
+      result
+    end
+  end
+end
+
+ +
+ + + + +
+ + +
+ +
+ parse_array() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File lib/json/pure/parser.rb, line 232
+def parse_array
+  raise NestingError, "nesting of #@current_nesting is too deep" if
+    @max_nesting.nonzero? && @current_nesting > @max_nesting
+  result = @array_class.new
+  delim = false
+  until eos?
+    case
+    when !UNPARSED.equal?(value = parse_value)
+      delim = false
+      result << value
+      skip(IGNORE)
+      if scan(COLLECTION_DELIMITER)
+        delim = true
+      elsif match?(ARRAY_CLOSE)
+        ;
+      else
+        raise ParserError, "expected ',' or ']' in array at '#{peek(20)}'!"
+      end
+    when scan(ARRAY_CLOSE)
+      if delim
+        raise ParserError, "expected next element in array at '#{peek(20)}'!"
+      end
+      break
+    when skip(IGNORE)
+      ;
+    else
+      raise ParserError, "unexpected token in array at '#{peek(20)}'!"
+    end
+  end
+  result
+end
+
+ +
+ + + + +
+ + +
+ +
+ parse_object() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File lib/json/pure/parser.rb, line 264
+def parse_object
+  raise NestingError, "nesting of #@current_nesting is too deep" if
+    @max_nesting.nonzero? && @current_nesting > @max_nesting
+  result = @object_class.new
+  delim = false
+  until eos?
+    case
+    when !UNPARSED.equal?(string = parse_string)
+      skip(IGNORE)
+      unless scan(PAIR_DELIMITER)
+        raise ParserError, "expected ':' in object at '#{peek(20)}'!"
+      end
+      skip(IGNORE)
+      unless UNPARSED.equal?(value = parse_value)
+        result[@symbolize_names ? string.to_sym : string] = value
+        delim = false
+        skip(IGNORE)
+        if scan(COLLECTION_DELIMITER)
+          delim = true
+        elsif match?(OBJECT_CLOSE)
+          ;
+        else
+          raise ParserError, "expected ',' or '}' in object at '#{peek(20)}'!"
+        end
+      else
+        raise ParserError, "expected value in object at '#{peek(20)}'!"
+      end
+    when scan(OBJECT_CLOSE)
+      if delim
+        raise ParserError, "expected next name, value pair in object at '#{peek(20)}'!"
+      end
+      if @create_additions and klassname = result[@create_id]
+        klass = JSON.deep_const_get klassname
+        break unless klass and klass.json_creatable?
+        result = klass.json_create(result)
+      end
+      break
+    when skip(IGNORE)
+      ;
+    else
+      raise ParserError, "unexpected token in object at '#{peek(20)}'!"
+    end
+  end
+  result
+end
+
+ +
+ + + + +
+ + +
+ +
+ parse_string() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File lib/json/pure/parser.rb, line 164
+def parse_string
+  if scan(STRING)
+    return '' if self[1].empty?
+    string = self[1].gsub(%r((?:\[\bfnrt"/]|(?:\u(?:[A-Fa-f\d]{4}))+|\[\x20-\xff]))n) do |c|
+      if u = UNESCAPE_MAP[$&[1]]
+        u
+      else # \uXXXX
+        bytes = EMPTY_8BIT_STRING.dup
+        i = 0
+        while c[6 * i] == ?\\ && c[6 * i + 1] == ?u
+          bytes << c[6 * i + 2, 2].to_i(16) << c[6 * i + 4, 2].to_i(16)
+          i += 1
+        end
+        JSON.iconv('utf-8', 'utf-16be', bytes)
+      end
+    end
+    if string.respond_to?(:force_encoding)
+      string.force_encoding(::Encoding::UTF_8)
+    end
+    if @create_additions and @match_string
+      for (regexp, klass) in @match_string
+        klass.json_creatable? or next
+        string =~ regexp and return klass.json_create(string)
+      end
+    end
+    string
+  else
+    UNPARSED
+  end
+rescue => e
+  raise ParserError, "Caught #{e.class} at '#{peek(20)}': #{e}"
+end
+
+ +
+ + + + +
+ + +
+ +
+ parse_value() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File lib/json/pure/parser.rb, line 197
+def parse_value
+  case
+  when scan(FLOAT)
+    @decimal_class && @decimal_class.new(self[1]) || Float(self[1])
+  when scan(INTEGER)
+    Integer(self[1])
+  when scan(TRUE)
+    true
+  when scan(FALSE)
+    false
+  when scan(NULL)
+    nil
+  when !UNPARSED.equal?(string = parse_string)
+    string
+  when scan(ARRAY_OPEN)
+    @current_nesting += 1
+    ary = parse_array
+    @current_nesting -= 1
+    ary
+  when scan(OBJECT_OPEN)
+    @current_nesting += 1
+    obj = parse_object
+    @current_nesting -= 1
+    obj
+  when @allow_nan && scan(NAN)
+    NaN
+  when @allow_nan && scan(INFINITY)
+    Infinity
+  when @allow_nan && scan(MINUS_INFINITY)
+    MinusInfinity
+  else
+    UNPARSED
+  end
+end
+
+ +
+ + + + +
+ + +
+ +
+ reset() + + click to toggle source + +
+ + +
+ + + + +
+ Calls superclass method + +
+ + + +
+
# File lib/json/pure/parser.rb, line 106
+def reset
+  super
+  @current_nesting = 0
+end
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/JSONAdditionTest.html b/tmp/rdoc/JSONAdditionTest.html new file mode 100644 index 000000000..5542b1f6a --- /dev/null +++ b/tmp/rdoc/JSONAdditionTest.html @@ -0,0 +1,648 @@ + + + + + + +class JSONAdditionTest - RDoc Documentation + + + + + + + + + + + + + + +
+

+ class JSONAdditionTest +

+ +
+ +
+ + + + +
+ + + + + +
+
+

Constants

+
+
+ +
MyJsonStruct + +
+ + +
+
+ + + + + +
+
+

Public Instance Methods

+
+ + +
+ +
+ test_bigdecimal() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_addition_test.rb, line 183
+def test_bigdecimal
+  assert_equal BigDecimal('3.141', 23), JSON(JSON(BigDecimal('3.141', 23)), :create_additions => true)
+  assert_equal BigDecimal('3.141', 666), JSON(JSON(BigDecimal('3.141', 666)), :create_additions => true)
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_core() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_addition_test.rb, line 137
+def test_core
+  t = Time.now
+  assert_equal t, JSON(JSON(t), :create_additions => true)
+  d = Date.today
+  assert_equal d, JSON(JSON(d), :create_additions => true)
+  d = DateTime.civil(2007, 6, 14, 14, 57, 10, Rational(1, 12), 2299161)
+  assert_equal d, JSON(JSON(d), :create_additions => true)
+  assert_equal 1..10, JSON(JSON(1..10), :create_additions => true)
+  assert_equal 1...10, JSON(JSON(1...10), :create_additions => true)
+  assert_equal "a".."c", JSON(JSON("a".."c"), :create_additions => true)
+  assert_equal "a"..."c", JSON(JSON("a"..."c"), :create_additions => true)
+  s = MyJsonStruct.new 4711, 'foot'
+  assert_equal s, JSON(JSON(s), :create_additions => true)
+  struct = Struct.new :foo, :bar
+  s = struct.new 4711, 'foot'
+  assert_raise(JSONError) { JSON(s) }
+  begin
+    raise TypeError, "test me"
+  rescue TypeError => e
+    e_json = JSON.generate e
+    e_again = JSON e_json, :create_additions => true
+    assert_kind_of TypeError, e_again
+    assert_equal e.message, e_again.message
+    assert_equal e.backtrace, e_again.backtrace
+  end
+  assert_equal(/foo/, JSON(JSON(/foo/), :create_additions => true))
+  assert_equal(/foo/i, JSON(JSON(/foo/i), :create_additions => true))
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_extended_json() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_addition_test.rb, line 70
+def test_extended_json
+  a = A.new(666)
+  assert A.json_creatable?
+  json = generate(a)
+  a_again = parse(json, :create_additions => true)
+  assert_kind_of a.class, a_again
+  assert_equal a, a_again
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_extended_json_default() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_addition_test.rb, line 79
+def test_extended_json_default
+  a = A.new(666)
+  assert A.json_creatable?
+  json = generate(a)
+  a_hash = parse(json)
+  assert_kind_of Hash, a_hash
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_extended_json_disabled() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_addition_test.rb, line 87
+def test_extended_json_disabled
+  a = A.new(666)
+  assert A.json_creatable?
+  json = generate(a)
+  a_again = parse(json, :create_additions => true)
+  assert_kind_of a.class, a_again
+  assert_equal a, a_again
+  a_hash = parse(json, :create_additions => false)
+  assert_kind_of Hash, a_hash
+  assert_equal(
+    {"args"=>[666], "json_class"=>"JSONAdditionTest::A"}.sort_by { |k,| k },
+    a_hash.sort_by { |k,| k }
+  )
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_extended_json_fail1() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_addition_test.rb, line 102
+def test_extended_json_fail1
+  b = B.new
+  assert !B.json_creatable?
+  json = generate(b)
+  assert_equal({ "json_class"=>"JSONAdditionTest::B" }, parse(json))
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_extended_json_fail2() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_addition_test.rb, line 109
+def test_extended_json_fail2
+  c = C.new
+  assert !C.json_creatable?
+  json = generate(c)
+  assert_raise(ArgumentError, NameError) { parse(json, :create_additions => true) }
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_ostruct() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_addition_test.rb, line 188
+def test_ostruct
+  o = OpenStruct.new
+  # XXX this won't work; o.foo = { :bar => true }
+  o.foo = { 'bar' => true }
+  assert_equal o, parse(JSON(o), :create_additions => true)
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_rational_complex() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_addition_test.rb, line 178
+def test_rational_complex
+  assert_equal Rational(2, 9), parse(JSON(Rational(2, 9)), :create_additions => true)
+  assert_equal Complex(2, 9), parse(JSON(Complex(2, 9)), :create_additions => true)
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_raw_strings() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_addition_test.rb, line 116
+def test_raw_strings
+  raw = ''
+  raw.respond_to?(:encode!) and raw.encode!(Encoding::ASCII_8BIT)
+  raw_array = []
+  for i in 0..255
+    raw << i
+    raw_array << i
+  end
+  json = raw.to_json_raw
+  json_raw_object = raw.to_json_raw_object
+  hash = { 'json_class' => 'String', 'raw'=> raw_array }
+  assert_equal hash, json_raw_object
+  assert_match(/\A\{.*\}\z/, json)
+  assert_match(/"json_class":"String"/, json)
+  assert_match(/"raw":\[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255\]/, json)
+  raw_again = parse(json, :create_additions => true)
+  assert_equal raw, raw_again
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_set() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_addition_test.rb, line 195
+def test_set
+  s = Set.new([:a, :b, :c, :a])
+  assert_equal s, JSON.parse(JSON(s), :create_additions => true)
+  ss = SortedSet.new([:d, :b, :a, :c])
+  ss_again = JSON.parse(JSON(ss), :create_additions => true)
+  assert_kind_of ss.class, ss_again
+  assert_equal ss, ss_again
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_utc_datetime() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_addition_test.rb, line 166
+def test_utc_datetime
+  now = Time.now
+  d = DateTime.parse(now.to_s, :create_additions => true) # usual case
+  assert_equal d, parse(d.to_json, :create_additions => true)
+  d = DateTime.parse(now.utc.to_s) # of = 0
+  assert_equal d, parse(d.to_json, :create_additions => true)
+  d = DateTime.civil(2008, 6, 17, 11, 48, 32, Rational(1,24))
+  assert_equal d, parse(d.to_json, :create_additions => true)
+  d = DateTime.civil(2008, 6, 17, 11, 48, 32, Rational(12,24))
+  assert_equal d, parse(d.to_json, :create_additions => true)
+end
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/JSONAdditionTest/A.html b/tmp/rdoc/JSONAdditionTest/A.html new file mode 100644 index 000000000..9262011f4 --- /dev/null +++ b/tmp/rdoc/JSONAdditionTest/A.html @@ -0,0 +1,291 @@ + + + + + + +class JSONAdditionTest::A - RDoc Documentation + + + + + + + + + + + + + + +
+

+ class JSONAdditionTest::A +

+ +
+ +
+ + + + +
+ + + + + + + +
+
+

Attributes

+
+ + +
+
+ a[R] +
+ +
+ + + +
+
+ +
+ + + +
+
+

Public Class Methods

+
+ + +
+ +
+ json_create(object) + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_addition_test.rb, line 25
+def self.json_create(object)
+  new(*object['args'])
+end
+
+ +
+ + + + +
+ + +
+ +
+ new(a) + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_addition_test.rb, line 15
+def initialize(a)
+  @a = a
+end
+
+ +
+ + + + +
+ + +
+ +
+
+

Public Instance Methods

+
+ + +
+ +
+ ==(other) + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_addition_test.rb, line 21
+def ==(other)
+  a == other.a
+end
+
+ +
+ + + + +
+ + +
+ +
+ to_json(*args) + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_addition_test.rb, line 29
+def to_json(*args)
+  {
+    'json_class'  => self.class.name,
+    'args'        => [ @a ],
+  }.to_json(*args)
+end
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/JSONAdditionTest/A2.html b/tmp/rdoc/JSONAdditionTest/A2.html new file mode 100644 index 000000000..0c7db4f18 --- /dev/null +++ b/tmp/rdoc/JSONAdditionTest/A2.html @@ -0,0 +1,157 @@ + + + + + + +class JSONAdditionTest::A2 - RDoc Documentation + + + + + + + + + + + + + + +
+

+ class JSONAdditionTest::A2 +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Instance Methods

+
+ + +
+ +
+ to_json(*args) + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_addition_test.rb, line 38
+def to_json(*args)
+  {
+    'json_class'  => self.class.name,
+    'args'        => [ @a ],
+  }.to_json(*args)
+end
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/JSONAdditionTest/B.html b/tmp/rdoc/JSONAdditionTest/B.html new file mode 100644 index 000000000..b0aa0013d --- /dev/null +++ b/tmp/rdoc/JSONAdditionTest/B.html @@ -0,0 +1,199 @@ + + + + + + +class JSONAdditionTest::B - RDoc Documentation + + + + + + + + + + + + + + +
+

+ class JSONAdditionTest::B +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Class Methods

+
+ + +
+ +
+ json_creatable?() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_addition_test.rb, line 47
+def self.json_creatable?
+  false
+end
+
+ +
+ + + + +
+ + +
+ +
+
+

Public Instance Methods

+
+ + +
+ +
+ to_json(*args) + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_addition_test.rb, line 51
+def to_json(*args)
+  {
+    'json_class'  => self.class.name,
+  }.to_json(*args)
+end
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/JSONAdditionTest/C.html b/tmp/rdoc/JSONAdditionTest/C.html new file mode 100644 index 000000000..9d68b0710 --- /dev/null +++ b/tmp/rdoc/JSONAdditionTest/C.html @@ -0,0 +1,199 @@ + + + + + + +class JSONAdditionTest::C - RDoc Documentation + + + + + + + + + + + + + + +
+

+ class JSONAdditionTest::C +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Class Methods

+
+ + +
+ +
+ json_creatable?() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_addition_test.rb, line 59
+def self.json_creatable?
+  false
+end
+
+ +
+ + + + +
+ + +
+ +
+
+

Public Instance Methods

+
+ + +
+ +
+ to_json(*args) + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_addition_test.rb, line 63
+def to_json(*args)
+  {
+    'json_class'  => 'JSONAdditionTest::Nix',
+  }.to_json(*args)
+end
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/JSONCommonInterfaceTest.html b/tmp/rdoc/JSONCommonInterfaceTest.html new file mode 100644 index 000000000..53e2f70a2 --- /dev/null +++ b/tmp/rdoc/JSONCommonInterfaceTest.html @@ -0,0 +1,805 @@ + + + + + + +class JSONCommonInterfaceTest - RDoc Documentation + + + + + + + + + + + + + + +
+

+ class JSONCommonInterfaceTest +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Instance Methods

+
+ + +
+ +
+ setup() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_common_interface_test.rb, line 9
+def setup
+  @hash = {
+    'a' => 2,
+    'b' => 3.141,
+    'c' => 'c',
+    'd' => [ 1, "b", 3.14 ],
+    'e' => { 'foo' => 'bar' },
+    'g' => "\"\0\037",
+    'h' => 1000.0,
+    'i' => 0.001
+  }
+  @json = '{"a":2,"b":3.141,"c":"c","d":[1,"b",3.14],"e":{"foo":"bar"},'       '"g":"\"\u0000\u001f","h":1000.0,"i":0.001}'
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_JSON() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_common_interface_test.rb, line 122
+def test_JSON
+  assert_equal @json, JSON(@hash)
+  assert_equal @hash, JSON(@json)
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_create_id() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_common_interface_test.rb, line 41
+def test_create_id
+  assert_equal 'json_class', JSON.create_id
+  JSON.create_id = 'foo_bar'
+  assert_equal 'foo_bar', JSON.create_id
+ensure
+  JSON.create_id = 'json_class'
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_deep_const_get() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_common_interface_test.rb, line 49
+def test_deep_const_get
+  assert_raise(ArgumentError) { JSON.deep_const_get('Nix::Da') }
+  assert_equal File::SEPARATOR, JSON.deep_const_get('File::SEPARATOR')
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_dump() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_common_interface_test.rb, line 100
+def test_dump
+  too_deep = '[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]'
+  assert_equal too_deep, dump(eval(too_deep))
+  assert_kind_of String, Marshal.dump(eval(too_deep))
+  assert_raise(ArgumentError) { dump(eval(too_deep), 100) }
+  assert_raise(ArgumentError) { Marshal.dump(eval(too_deep), 100) }
+  assert_equal too_deep, dump(eval(too_deep), 101)
+  assert_kind_of String, Marshal.dump(eval(too_deep), 101)
+  output = StringIO.new
+  dump(eval(too_deep), output)
+  assert_equal too_deep, output.string
+  output = StringIO.new
+  dump(eval(too_deep), output, 101)
+  assert_equal too_deep, output.string
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_dump_should_modify_defaults() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_common_interface_test.rb, line 116
+def test_dump_should_modify_defaults
+  max_nesting = JSON.dump_default_options[:max_nesting]
+  dump([], StringIO.new, 10)
+  assert_equal max_nesting, JSON.dump_default_options[:max_nesting]
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_fast_generate() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_common_interface_test.rb, line 66
+def test_fast_generate
+  assert_equal '[1,2,3]', JSON.generate([ 1, 2, 3 ])
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_generate() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_common_interface_test.rb, line 62
+def test_generate
+  assert_equal '[1,2,3]', JSON.generate([ 1, 2, 3 ])
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_generator() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_common_interface_test.rb, line 33
+def test_generator
+  assert_match /::Generator\z/, JSON.generator.name
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_index() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_common_interface_test.rb, line 24
+def test_index
+  assert_equal @json, JSON[@hash]
+  assert_equal @hash, JSON[@json]
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_load() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_common_interface_test.rb, line 74
+def test_load
+  assert_equal @hash, JSON.load(@json)
+  tempfile = Tempfile.open('@json')
+  tempfile.write @json
+  tempfile.rewind
+  assert_equal @hash, JSON.load(tempfile)
+  stringio = StringIO.new(@json)
+  stringio.rewind
+  assert_equal @hash, JSON.load(stringio)
+  assert_equal nil, JSON.load(nil)
+  assert_equal nil, JSON.load('')
+ensure
+  tempfile.close!
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_load_null() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_common_interface_test.rb, line 94
+def test_load_null
+  assert_equal nil, JSON.load(nil, nil, :allow_blank => true)
+  assert_raise(TypeError) { JSON.load(nil, nil, :allow_blank => false) }
+  assert_raise(JSON::ParserError) { JSON.load('', nil, :allow_blank => false) }
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_load_with_options() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_common_interface_test.rb, line 89
+def test_load_with_options
+  json  = '{ "foo": NaN }'
+  assert JSON.load(json, nil, :allow_nan => true)['foo'].nan?
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_parse() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_common_interface_test.rb, line 54
+def test_parse
+  assert_equal [ 1, 2, 3, ], JSON.parse('[ 1, 2, 3 ]')
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_parse_bang() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_common_interface_test.rb, line 58
+def test_parse_bang
+  assert_equal [ 1, NaN, 3, ], JSON.parse!('[ 1, NaN, 3 ]')
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_parser() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_common_interface_test.rb, line 29
+def test_parser
+  assert_match /::Parser\z/, JSON.parser.name
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_pretty_generate() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_common_interface_test.rb, line 70
+def test_pretty_generate
+  assert_equal "[\n  1,\n  2,\n  3\n]", JSON.pretty_generate([ 1, 2, 3 ])
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_state() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_common_interface_test.rb, line 37
+def test_state
+  assert_match /::Generator::State\z/, JSON.state.name
+end
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/JSONEncodingTest.html b/tmp/rdoc/JSONEncodingTest.html new file mode 100644 index 000000000..e7601bdab --- /dev/null +++ b/tmp/rdoc/JSONEncodingTest.html @@ -0,0 +1,385 @@ + + + + + + +class JSONEncodingTest - RDoc Documentation + + + + + + + + + + + + + + +
+

+ class JSONEncodingTest +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Instance Methods

+
+ + +
+ +
+ setup() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_encoding_test.rb, line 7
+def setup
+  @utf_8      = '"© ≠ €!"'
+  @ascii_8bit = @utf_8.dup.force_encoding('ascii-8bit')
+  @parsed     = "© ≠ €!"
+  @generated  = '"\u00a9 \u2260 \u20ac!"'
+  if String.method_defined?(:encode)
+    @utf_16_data = @parsed.encode('utf-16be', 'utf-8')
+    @utf_16be = @utf_8.encode('utf-16be', 'utf-8')
+    @utf_16le = @utf_8.encode('utf-16le', 'utf-8')
+    @utf_32be = @utf_8.encode('utf-32be', 'utf-8')
+    @utf_32le = @utf_8.encode('utf-32le', 'utf-8')
+  else
+    require 'iconv'
+    @utf_16_data, = Iconv.iconv('utf-16be', 'utf-8', @parsed)
+    @utf_16be, = Iconv.iconv('utf-16be', 'utf-8', @utf_8)
+    @utf_16le, = Iconv.iconv('utf-16le', 'utf-8', @utf_8)
+    @utf_32be, = Iconv.iconv('utf-32be', 'utf-8', @utf_8)
+    @utf_32le, = Iconv.iconv('utf-32le', 'utf-8', @utf_8)
+  end
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_chars() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_encoding_test.rb, line 85
+def test_chars
+  (0..0x7f).each do |i|
+    json = '["\u%04x"]' % i
+    if RUBY_VERSION >= "1.9."
+      i = i.chr
+    end
+    assert_equal i, parse(json).first[0]
+    if i == ?\b
+      generated = generate(["" << i])
+      assert '["\b"]' == generated || '["\10"]' == generated
+    elsif [?\n, ?\r, ?\t, ?\f].include?(i)
+      assert_equal '[' << ('' << i).dump << ']', generate(["" << i])
+    elsif i.chr < 0x20.chr
+      assert_equal json, generate(["" << i])
+    end
+  end
+  assert_raise(JSON::GeneratorError) do
+    generate(["\x80"], :ascii_only => true)
+  end
+  assert_equal "\302\200", parse('["\u0080"]').first
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_generate() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_encoding_test.rb, line 37
+def test_generate
+  assert_equal @generated, JSON.generate(@parsed, :ascii_only => true)
+  assert_equal @generated, JSON.generate(@utf_16_data, :ascii_only => true)
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_parse() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_encoding_test.rb, line 28
+def test_parse
+  assert_equal @parsed, JSON.parse(@ascii_8bit)
+  assert_equal @parsed, JSON.parse(@utf_8)
+  assert_equal @parsed, JSON.parse(@utf_16be)
+  assert_equal @parsed, JSON.parse(@utf_16le)
+  assert_equal @parsed, JSON.parse(@utf_32be)
+  assert_equal @parsed, JSON.parse(@utf_32le)
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_unicode() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_encoding_test.rb, line 42
+def test_unicode
+  assert_equal '""', ''.to_json
+  assert_equal '"\b"', "\b".to_json
+  assert_equal '"\u0001"', 0x1.chr.to_json
+  assert_equal '"\u001f"', 0x1f.chr.to_json
+  assert_equal '" "', ' '.to_json
+  assert_equal "\"#{0x7f.chr}\"", 0x7f.chr.to_json
+  utf8 = [ "© ≠ €! \01" ]
+  json = '["© ≠ €! \u0001"]'
+  assert_equal json, utf8.to_json(:ascii_only => false)
+  assert_equal utf8, parse(json)
+  json = '["\u00a9 \u2260 \u20ac! \u0001"]'
+  assert_equal json, utf8.to_json(:ascii_only => true)
+  assert_equal utf8, parse(json)
+  utf8 = ["\343\201\202\343\201\204\343\201\206\343\201\210\343\201\212"]
+  json = "[\"\343\201\202\343\201\204\343\201\206\343\201\210\343\201\212\"]"
+  assert_equal utf8, parse(json)
+  assert_equal json, utf8.to_json(:ascii_only => false)
+  utf8 = ["\343\201\202\343\201\204\343\201\206\343\201\210\343\201\212"]
+  assert_equal utf8, parse(json)
+  json = "[\"\\u3042\\u3044\\u3046\\u3048\\u304a\"]"
+  assert_equal json, utf8.to_json(:ascii_only => true)
+  assert_equal utf8, parse(json)
+  utf8 = ['საქართველო']
+  json = '["საქართველო"]'
+  assert_equal json, utf8.to_json(:ascii_only => false)
+  json = "[\"\\u10e1\\u10d0\\u10e5\\u10d0\\u10e0\\u10d7\\u10d5\\u10d4\\u10da\\u10dd\"]"
+  assert_equal json, utf8.to_json(:ascii_only => true)
+  assert_equal utf8, parse(json)
+  assert_equal '["Ã"]', generate(["Ã"], :ascii_only => false)
+  assert_equal '["\u00c3"]', generate(["Ã"], :ascii_only => true)
+  assert_equal ["€"], parse('["\u20ac"]')
+  utf8 = ["\xf0\xa0\x80\x81"]
+  json = "[\"\xf0\xa0\x80\x81\"]"
+  assert_equal json, generate(utf8, :ascii_only => false)
+  assert_equal utf8, parse(json)
+  json = '["\ud840\udc01"]'
+  assert_equal json, generate(utf8, :ascii_only => true)
+  assert_equal utf8, parse(json)
+  assert_raise(JSON::ParserError) { parse('"\u"') }
+  assert_raise(JSON::ParserError) { parse('"\ud800"') }
+end
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/JSONExtParserTest.html b/tmp/rdoc/JSONExtParserTest.html new file mode 100644 index 000000000..f021aea6f --- /dev/null +++ b/tmp/rdoc/JSONExtParserTest.html @@ -0,0 +1,159 @@ + + + + + + +class JSONExtParserTest - RDoc Documentation + + + + + + + + + + + + + + +
+

+ class JSONExtParserTest +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Instance Methods

+
+ + +
+ +
+ test_allocate() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_ext_parser_test.rb, line 6
+def test_allocate
+  parser = JSON::Ext::Parser.new("{}")
+  assert_raise(TypeError, '[ruby-core:35079]') do
+    parser.__send__(:initialize, "{}")
+  end
+  parser = JSON::Ext::Parser.allocate
+  assert_raise(TypeError, '[ruby-core:35079]') { parser.source }
+end
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/JSONFixturesTest.html b/tmp/rdoc/JSONFixturesTest.html new file mode 100644 index 000000000..54fe47bea --- /dev/null +++ b/tmp/rdoc/JSONFixturesTest.html @@ -0,0 +1,240 @@ + + + + + + +class JSONFixturesTest - RDoc Documentation + + + + + + + + + + + + + + +
+

+ class JSONFixturesTest +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Instance Methods

+
+ + +
+ +
+ setup() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_fixtures_test.rb, line 5
+def setup
+  fixtures = File.join(File.dirname(__FILE__), 'fixtures/{fail,pass}.json')
+  passed, failed = Dir[fixtures].partition { |f| f['pass'] }
+  @passed = passed.inject([]) { |a, f| a << [ f, File.read(f) ] }.sort
+  @failed = failed.inject([]) { |a, f| a << [ f, File.read(f) ] }.sort
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_failing() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_fixtures_test.rb, line 24
+def test_failing
+  for name, source in @failed
+    assert_raise(JSON::ParserError, JSON::NestingError,
+      "Did not fail for fixture '#{name}': #{source.inspect}") do
+      JSON.parse(source)
+    end
+  end
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_passing() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_fixtures_test.rb, line 12
+def test_passing
+  for name, source in @passed
+    begin
+      assert JSON.parse(source),
+        "Did not pass for fixture '#{name}': #{source.inspect}"
+    rescue => e
+      warn "\nCaught #{e.class}(#{e}) for fixture '#{name}': #{source.inspect}\n#{e.backtrace * "\n"}"
+      raise e
+    end
+  end
+end
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/JSONGeneratorTest.html b/tmp/rdoc/JSONGeneratorTest.html new file mode 100644 index 000000000..035851008 --- /dev/null +++ b/tmp/rdoc/JSONGeneratorTest.html @@ -0,0 +1,1239 @@ + + + + + + +class JSONGeneratorTest - RDoc Documentation + + + + + + + + + + + + + + +
+

+ class JSONGeneratorTest +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Instance Methods

+
+ + +
+ +
+ setup() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_generator_test.rb, line 8
+  def setup
+    @hash = {
+      'a' => 2,
+      'b' => 3.141,
+      'c' => 'c',
+      'd' => [ 1, "b", 3.14 ],
+      'e' => { 'foo' => 'bar' },
+      'g' => "\"\0\037",
+      'h' => 1000.0,
+      'i' => 0.001
+    }
+    @json2 = '{"a":2,"b":3.141,"c":"c","d":[1,"b",3.14],"e":{"foo":"bar"},' +
+      '"g":"\"\u0000\u001f","h":1000.0,"i":0.001}'
+    @json3 = "{
+  "a": 2,
+  "b": 3.141,
+  "c": "c",
+  "d": [
+    1,
+    "b",
+    3.14
+  ],
+  "e": {
+    "foo": "bar"
+  },
+  "g": "\"\u0000\u001f",
+  "h": 1000.0,
+  "i": 0.001
+}
+".chomp
+  end
+
+ +
+ + + + +
+ + +
+ +
+ test_allow_nan() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_generator_test.rb, line 177
+def test_allow_nan
+  assert_raise(GeneratorError) { generate([JSON::NaN]) }
+  assert_equal '[NaN]', generate([JSON::NaN], :allow_nan => true)
+  assert_raise(GeneratorError) { fast_generate([JSON::NaN]) }
+  assert_raise(GeneratorError) { pretty_generate([JSON::NaN]) }
+  assert_equal "[\n  NaN\n]", pretty_generate([JSON::NaN], :allow_nan => true)
+  assert_raise(GeneratorError) { generate([JSON::Infinity]) }
+  assert_equal '[Infinity]', generate([JSON::Infinity], :allow_nan => true)
+  assert_raise(GeneratorError) { fast_generate([JSON::Infinity]) }
+  assert_raise(GeneratorError) { pretty_generate([JSON::Infinity]) }
+  assert_equal "[\n  Infinity\n]", pretty_generate([JSON::Infinity], :allow_nan => true)
+  assert_raise(GeneratorError) { generate([JSON::MinusInfinity]) }
+  assert_equal '[-Infinity]', generate([JSON::MinusInfinity], :allow_nan => true)
+  assert_raise(GeneratorError) { fast_generate([JSON::MinusInfinity]) }
+  assert_raise(GeneratorError) { pretty_generate([JSON::MinusInfinity]) }
+  assert_equal "[\n  -Infinity\n]", pretty_generate([JSON::MinusInfinity], :allow_nan => true)
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_backslash() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_generator_test.rb, line 344
+def test_backslash
+  data = [ '\.(?i:gif|jpe?g|png)$' ]
+  json = '["\\.(?i:gif|jpe?g|png)$"]'
+  assert_equal json, generate(data)
+  #
+  data = [ '\"' ]
+  json = '["\\\""]'
+  assert_equal json, generate(data)
+  #
+  data = [ '/' ]
+  json = '["/"]'
+  assert_equal json, generate(data)
+  #
+  data = ['"']
+  json = '["\""]'
+  assert_equal json, generate(data)
+  #
+  data = ["'"]
+  json = '["\\"]'
+  assert_equal '["\"]', generate(data)
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_broken_bignum() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_generator_test.rb, line 276
+def test_broken_bignum # [ruby-core:38867]
+  pid = fork do
+    x = 1 << 64
+    x.class.class_eval do
+      def to_s
+      end
+    end
+    begin
+      JSON::Ext::Generator::State.new.generate(x)
+      exit 1
+    rescue TypeError
+      exit 0
+    end
+  end
+  _, status = Process.waitpid2(pid)
+  assert status.success?
+rescue NotImplementedError
+  # forking to avoid modifying core class of a parent process and
+  # introducing race conditions of tests are run in parallel
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_buffer_initial_length() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_generator_test.rb, line 209
+def test_buffer_initial_length
+  s = JSON.state.new
+  assert_equal 1024, s.buffer_initial_length
+  s.buffer_initial_length = 0
+  assert_equal 1024, s.buffer_initial_length
+  s.buffer_initial_length = -1
+  assert_equal 1024, s.buffer_initial_length
+  s.buffer_initial_length = 128
+  assert_equal 128, s.buffer_initial_length
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_configure_hash_conversion() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_generator_test.rb, line 259
+def test_configure_hash_conversion
+  state = JSON.state.new
+  state.configure(:indent => '1')
+  assert_equal '1', state.indent
+  state = JSON.state.new
+  foo = 'foo'
+  assert_raise(TypeError) do
+    state.configure(foo)
+  end
+  def foo.to_h
+    { :indent => '2' }
+  end
+  state.configure(foo)
+  assert_equal '2', state.indent
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_configure_using_configure_and_merge() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_generator_test.rb, line 235
+def test_configure_using_configure_and_merge
+  numbered_state = {
+    :indent       => "1",
+    :space        => '2',
+    :space_before => '3',
+    :object_nl    => '4',
+    :array_nl     => '5'
+  }
+  state1 = JSON.state.new
+  state1.merge(numbered_state)
+  assert_equal '1', state1.indent
+  assert_equal '2', state1.space
+  assert_equal '3', state1.space_before
+  assert_equal '4', state1.object_nl
+  assert_equal '5', state1.array_nl
+  state2 = JSON.state.new
+  state2.configure(numbered_state)
+  assert_equal '1', state2.indent
+  assert_equal '2', state2.space
+  assert_equal '3', state2.space_before
+  assert_equal '4', state2.object_nl
+  assert_equal '5', state2.array_nl
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_depth() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_generator_test.rb, line 195
+def test_depth
+  ary = []; ary << ary
+  assert_equal 0, JSON::SAFE_STATE_PROTOTYPE.depth
+  assert_raise(JSON::NestingError) { generate(ary) }
+  assert_equal 0, JSON::SAFE_STATE_PROTOTYPE.depth
+  assert_equal 0, JSON::PRETTY_STATE_PROTOTYPE.depth
+  assert_raise(JSON::NestingError) { JSON.pretty_generate(ary) }
+  assert_equal 0, JSON::PRETTY_STATE_PROTOTYPE.depth
+  s = JSON.state.new
+  assert_equal 0, s.depth
+  assert_raise(JSON::NestingError) { ary.to_json(s) }
+  assert_equal 100, s.depth
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_fast_generate() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_generator_test.rb, line 86
+def test_fast_generate
+  json = fast_generate(@hash)
+  assert_equal(parse(@json2), parse(json))
+  parsed_json = parse(json)
+  assert_equal(@hash, parsed_json)
+  json = fast_generate({1=>2})
+  assert_equal('{"1":2}', json)
+  parsed_json = parse(json)
+  assert_equal({"1"=>2}, parsed_json)
+  assert_equal '666', fast_generate(666)
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_fast_state() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_generator_test.rb, line 161
+def test_fast_state
+  state = FAST_STATE_PROTOTYPE.dup
+  assert_equal({
+    :allow_nan             => false,
+    :array_nl              => "",
+    :ascii_only            => false,
+    :buffer_initial_length => 1024,
+    :depth                 => 0,
+    :indent                => "",
+    :max_nesting           => 0,
+    :object_nl             => "",
+    :space                 => "",
+    :space_before          => "",
+  }.sort_by { |n,| n.to_s }, state.to_h.sort_by { |n,| n.to_s })
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_gc() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_generator_test.rb, line 220
+  def test_gc
+    if respond_to?(:assert_in_out_err)
+      assert_in_out_err(%w[-rjson --disable-gems], "        bignum_too_long_to_embed_as_string = 1234567890123456789012345
+        expect = bignum_too_long_to_embed_as_string.to_s
+        GC.stress = true
+
+        10.times do |i|
+          tmp = bignum_too_long_to_embed_as_string.to_json
+          raise "'\#{expect}' is expected, but '\#{tmp}'" unless tmp == expect
+        end
+", [], [])
+    end
+  end
+
+ +
+ + + + +
+ + +
+ +
+ test_generate() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_generator_test.rb, line 41
+def test_generate
+  json = generate(@hash)
+  assert_equal(parse(@json2), parse(json))
+  json = JSON[@hash]
+  assert_equal(parse(@json2), parse(json))
+  parsed_json = parse(json)
+  assert_equal(@hash, parsed_json)
+  json = generate({1=>2})
+  assert_equal('{"1":2}', json)
+  parsed_json = parse(json)
+  assert_equal({"1"=>2}, parsed_json)
+  assert_equal '666', generate(666)
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_generate_custom() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_generator_test.rb, line 73
+  def test_generate_custom
+    state = State.new(:space_before => " ", :space => "   ", :indent => "<i>", :object_nl => "\n", :array_nl => "<a_nl>")
+    json = generate({1=>{2=>3,4=>[5,6]}}, state)
+    assert_equal("{
+<i>"1" :   {
+<i><i>"2" :   3,
+<i><i>"4" :   [<a_nl><i><i><i>5,<a_nl><i><i><i>6<a_nl><i><i>]
+<i>}
+}
+".chomp, json)
+  end
+
+ +
+ + + + +
+ + +
+ +
+ test_generate_pretty() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_generator_test.rb, line 55
+  def test_generate_pretty
+    json = pretty_generate(@hash)
+    # hashes aren't (insertion) ordered on every ruby implementation
+    # assert_equal(@json3, json)
+    assert_equal(parse(@json3), parse(json))
+    parsed_json = parse(json)
+    assert_equal(@hash, parsed_json)
+    json = pretty_generate({1=>2})
+    assert_equal("{
+  "1": 2
+}
+".chomp, json)
+    parsed_json = parse(json)
+    assert_equal({"1"=>2}, parsed_json)
+    assert_equal '666', pretty_generate(666)
+  end
+
+ +
+ + + + +
+ + +
+ +
+ test_hash_likeness_set_string() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_generator_test.rb, line 311
+def test_hash_likeness_set_string
+  state = JSON.state.new
+  assert_equal nil, state[:foo]
+  assert_equal nil, state['foo']
+  state['foo'] = :bar
+  assert_equal :bar, state[:foo]
+  assert_equal :bar, state['foo']
+  state_hash = state.to_hash
+  assert_kind_of Hash, state_hash
+  assert_equal :bar, state_hash[:foo]
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_hash_likeness_set_symbol() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_generator_test.rb, line 298
+def test_hash_likeness_set_symbol
+  state = JSON.state.new
+  assert_equal nil, state[:foo]
+  assert_equal nil.class, state[:foo].class
+  assert_equal nil, state['foo']
+  state[:foo] = :bar
+  assert_equal :bar, state[:foo]
+  assert_equal :bar, state['foo']
+  state_hash = state.to_hash
+  assert_kind_of Hash, state_hash
+  assert_equal :bar, state_hash[:foo]
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_json_generate() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_generator_test.rb, line 323
+def test_json_generate
+  assert_raise JSON::GeneratorError do
+    assert_equal true, generate(["\xea"])
+  end
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_nesting() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_generator_test.rb, line 329
+def test_nesting
+  too_deep = '[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]'
+  too_deep_ary = eval too_deep
+  assert_raise(JSON::NestingError) { generate too_deep_ary }
+  assert_raise(JSON::NestingError) { generate too_deep_ary, :max_nesting => 100 }
+  ok = generate too_deep_ary, :max_nesting => 101
+  assert_equal too_deep, ok
+  ok = generate too_deep_ary, :max_nesting => nil
+  assert_equal too_deep, ok
+  ok = generate too_deep_ary, :max_nesting => false
+  assert_equal too_deep, ok
+  ok = generate too_deep_ary, :max_nesting => 0
+  assert_equal too_deep, ok
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_own_state() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_generator_test.rb, line 98
+def test_own_state
+  state = State.new
+  json = generate(@hash, state)
+  assert_equal(parse(@json2), parse(json))
+  parsed_json = parse(json)
+  assert_equal(@hash, parsed_json)
+  json = generate({1=>2}, state)
+  assert_equal('{"1":2}', json)
+  parsed_json = parse(json)
+  assert_equal({"1"=>2}, parsed_json)
+  assert_equal '666', generate(666, state)
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_pretty_state() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_generator_test.rb, line 129
+def test_pretty_state
+  state = PRETTY_STATE_PROTOTYPE.dup
+  assert_equal({
+    :allow_nan             => false,
+    :array_nl              => "\n",
+    :ascii_only            => false,
+    :buffer_initial_length => 1024,
+    :depth                 => 0,
+    :indent                => "  ",
+    :max_nesting           => 100,
+    :object_nl             => "\n",
+    :space                 => " ",
+    :space_before          => "",
+  }.sort_by { |n,| n.to_s }, state.to_h.sort_by { |n,| n.to_s })
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_safe_state() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_generator_test.rb, line 145
+def test_safe_state
+  state = SAFE_STATE_PROTOTYPE.dup
+  assert_equal({
+    :allow_nan             => false,
+    :array_nl              => "",
+    :ascii_only            => false,
+    :buffer_initial_length => 1024,
+    :depth                 => 0,
+    :indent                => "",
+    :max_nesting           => 100,
+    :object_nl             => "",
+    :space                 => "",
+    :space_before          => "",
+  }.sort_by { |n,| n.to_s }, state.to_h.sort_by { |n,| n.to_s })
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_states() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_generator_test.rb, line 111
+def test_states
+  json = generate({1=>2}, nil)
+  assert_equal('{"1":2}', json)
+  s = JSON.state.new
+  assert s.check_circular?
+  assert s[:check_circular?]
+  h = { 1=>2 }
+  h[3] = h
+  assert_raise(JSON::NestingError) {  generate(h) }
+  assert_raise(JSON::NestingError) {  generate(h, s) }
+  s = JSON.state.new
+  a = [ 1, 2 ]
+  a << a
+  assert_raise(JSON::NestingError) {  generate(a, s) }
+  assert s.check_circular?
+  assert s[:check_circular?]
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_string_subclass() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_generator_test.rb, line 366
+def test_string_subclass
+  s = Class.new(String) do
+    def to_s; self; end
+    undef to_json
+  end
+  assert_nothing_raised(SystemStackError) do
+    assert_equal '["foo"]', JSON.generate([s.new('foo')])
+  end
+end
+
+ +
+ + + + +
+ + +
+ +
+ to_s() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_generator_test.rb, line 280
+def to_s
+end
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/JSONGenericObjectTest.html b/tmp/rdoc/JSONGenericObjectTest.html new file mode 100644 index 000000000..1df7453c5 --- /dev/null +++ b/tmp/rdoc/JSONGenericObjectTest.html @@ -0,0 +1,383 @@ + + + + + + +class JSONGenericObjectTest - RDoc Documentation + + + + + + + + + + + + + + +
+

+ class JSONGenericObjectTest +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Instance Methods

+
+ + +
+ +
+ setup() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_generic_object_test.rb, line 7
+def setup
+  @go = GenericObject[ :a => 1, :b => 2 ]
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_attributes() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_generic_object_test.rb, line 11
+def test_attributes
+  assert_equal 1, @go.a
+  assert_equal 1, @go[:a]
+  assert_equal 2, @go.b
+  assert_equal 2, @go[:b]
+  assert_nil @go.c
+  assert_nil @go[:c]
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_from_hash() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_generic_object_test.rb, line 48
+def test_from_hash
+  result  = GenericObject.from_hash(
+    :foo => { :bar => { :baz => true }, :quux => [ { :foobar => true } ] })
+  assert_kind_of GenericObject, result.foo
+  assert_kind_of GenericObject, result.foo.bar
+  assert_equal   true, result.foo.bar.baz
+  assert_kind_of GenericObject, result.foo.quux.first
+  assert_equal   true, result.foo.quux.first.foobar
+  assert_equal   true, GenericObject.from_hash(true)
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_generate_json() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_generic_object_test.rb, line 20
+def test_generate_json
+  switch_json_creatable do
+    assert_equal @go, JSON(JSON(@go), :create_additions => true)
+  end
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_json_generic_object_load() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_generic_object_test.rb, line 59
+def test_json_generic_object_load
+  empty = JSON::GenericObject.load(nil)
+  assert_kind_of JSON::GenericObject, empty
+  simple_json = '{"json_class":"JSON::GenericObject","hello":"world"}'
+  simple = JSON::GenericObject.load(simple_json)
+  assert_kind_of JSON::GenericObject, simple
+  assert_equal "world", simple.hello
+  converting = JSON::GenericObject.load('{ "hello": "world" }')
+  assert_kind_of JSON::GenericObject, converting
+  assert_equal "world", converting.hello
+
+  json = JSON::GenericObject.dump(JSON::GenericObject[:hello => 'world'])
+  assert_equal JSON(json), JSON('{"json_class":"JSON::GenericObject","hello":"world"}')
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_parse_json() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_generic_object_test.rb, line 26
+def test_parse_json
+  assert_kind_of Hash,
+    JSON(
+      '{ "json_class": "JSON::GenericObject", "a": 1, "b": 2 }',
+      :create_additions => true
+    )
+  switch_json_creatable do
+    assert_equal @go, l =
+      JSON(
+        '{ "json_class": "JSON::GenericObject", "a": 1, "b": 2 }',
+           :create_additions => true
+      )
+    assert_equal 1, l.a
+    assert_equal @go,
+      l = JSON('{ "a": 1, "b": 2 }', :object_class => GenericObject)
+    assert_equal 1, l.a
+    assert_equal GenericObject[:a => GenericObject[:b => 2]],
+      l = JSON('{ "a": { "b": 2 } }', :object_class => GenericObject)
+    assert_equal 2, l.a.b
+  end
+end
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/JSONParserTest.html b/tmp/rdoc/JSONParserTest.html new file mode 100644 index 000000000..f96cf1ee8 --- /dev/null +++ b/tmp/rdoc/JSONParserTest.html @@ -0,0 +1,1457 @@ + + + + + + +class JSONParserTest - RDoc Documentation + + + + + + + + + + + + + + +
+

+ class JSONParserTest +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Instance Methods

+
+ + +
+ +
+ test_argument_encoding() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_parser_test.rb, line 15
+def test_argument_encoding
+  source = "{}".encode("UTF-16")
+  JSON::Parser.new(source)
+  assert_equal Encoding::UTF_16, source.encoding
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_backslash() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_parser_test.rb, line 274
+def test_backslash
+  data = [ '\.(?i:gif|jpe?g|png)$' ]
+  json = '["\\.(?i:gif|jpe?g|png)$"]'
+  assert_equal data, parse(json)
+  #
+  data = [ '\"' ]
+  json = '["\\\""]'
+  assert_equal data, parse(json)
+  #
+  json = '["/"]'
+  data = [ '/' ]
+  assert_equal data, parse(json)
+  #
+  json = '["\""]'
+  data = ['"']
+  assert_equal data, parse(json)
+  #
+  json = '["\\"]'
+  data = ["'"]
+  assert_equal data, parse(json)
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_construction() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_parser_test.rb, line 10
+def test_construction
+  parser = JSON::Parser.new('test')
+  assert_equal 'test', parser.source
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_error_message_encoding() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_parser_test.rb, line 21
+def test_error_message_encoding
+  bug10705 = '[ruby-core:67386] [Bug #10705]'
+  json = ".\"\xE2\x88\x9A\"".force_encoding(Encoding::UTF_8)
+  e = assert_raise(JSON::ParserError) {
+    JSON::Ext::Parser.new(json).parse
+  }
+  assert_equal(Encoding::UTF_8, e.message.encoding, bug10705)
+  assert_include(e.message, json, bug10705)
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_generate_core_subclasses_with_default_to_json() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_parser_test.rb, line 441
+def test_generate_core_subclasses_with_default_to_json
+  assert_equal '{"foo":"bar"}', JSON(SubHash["foo" => "bar"])
+  assert_equal '["foo"]', JSON(SubArray["foo"])
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_generate_core_subclasses_with_new_to_json() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_parser_test.rb, line 429
+def test_generate_core_subclasses_with_new_to_json
+  obj = SubHash2["foo" => SubHash2["bar" => true]]
+  obj_json = JSON(obj)
+  obj_again = parse(obj_json, :create_additions => true)
+  assert_kind_of SubHash2, obj_again
+  assert_kind_of SubHash2, obj_again['foo']
+  assert obj_again['foo']['bar']
+  assert_equal obj, obj_again
+  assert_equal ["foo"],
+    JSON(JSON(SubArray2["foo"]), :create_additions => true)
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_generate_of_core_subclasses() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_parser_test.rb, line 446
+def test_generate_of_core_subclasses
+  obj = SubHash["foo" => SubHash["bar" => true]]
+  obj_json = JSON(obj)
+  obj_again = JSON(obj_json)
+  assert_kind_of Hash, obj_again
+  assert_kind_of Hash, obj_again['foo']
+  assert obj_again['foo']['bar']
+  assert_equal obj, obj_again
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_nesting() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_parser_test.rb, line 259
+def test_nesting
+  too_deep = '[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]'
+  too_deep_ary = eval too_deep
+  assert_raise(JSON::NestingError) { parse too_deep }
+  assert_raise(JSON::NestingError) { parse too_deep, :max_nesting => 100 }
+  ok = parse too_deep, :max_nesting => 101
+  assert_equal too_deep_ary, ok
+  ok = parse too_deep, :max_nesting => nil
+  assert_equal too_deep_ary, ok
+  ok = parse too_deep, :max_nesting => false
+  assert_equal too_deep_ary, ok
+  ok = parse too_deep, :max_nesting => 0
+  assert_equal too_deep_ary, ok
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_parse_array_custom_array_derived_class() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_parser_test.rb, line 342
+def test_parse_array_custom_array_derived_class
+  res = parse('[1,2]', :array_class => SubArray)
+  assert_equal([1,2], res)
+  assert_equal(SubArray, res.class)
+  assert res.shifted?
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_parse_array_custom_non_array_derived_class() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_parser_test.rb, line 349
+def test_parse_array_custom_non_array_derived_class
+  res = parse('[1,2]', :array_class => SubArrayWrapper)
+  assert_equal([1,2], res.data)
+  assert_equal(SubArrayWrapper, res.class)
+  assert res.shifted?
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_parse_arrays() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_parser_test.rb, line 135
+def test_parse_arrays
+  assert_equal([1,2,3], parse('[1,2,3]'))
+  assert_equal([1.2,2,3], parse('[1.2,2,3]'))
+  assert_equal([[],[[],[]]], parse('[[],[[],[]]]'))
+  assert_equal([], parse('[]'))
+  assert_equal([], parse('  [  ]  '))
+  assert_equal([1], parse('[1]'))
+  assert_equal([1], parse('  [ 1  ]  '))
+  ary = [[1], ["foo"], [3.14], [4711.0], [2.718], [nil],
+    [[1, -2, 3]], [false], [true]]
+  assert_equal(ary,
+    parse('[[1],["foo"],[3.14],[47.11e+2],[2718.0E-3],[null],[[1,-2,3]],[false],[true]]'))
+  assert_equal(ary, parse(%Q{   [   [1] , ["foo"]  ,  [3.14] \t ,  [47.11e+2]\s
+    , [2718.0E-3 ],\r[ null] , [[1, -2, 3 ]], [false ],[ true]\n ]  }))
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_parse_big_integers() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_parser_test.rb, line 180
+def test_parse_big_integers
+  json1 = JSON(orig = (1 << 31) - 1)
+  assert_equal orig, parse(json1)
+  json2 = JSON(orig = 1 << 31)
+  assert_equal orig, parse(json2)
+  json3 = JSON(orig = (1 << 62) - 1)
+  assert_equal orig, parse(json3)
+  json4 = JSON(orig = 1 << 62)
+  assert_equal orig, parse(json4)
+  json5 = JSON(orig = 1 << 64)
+  assert_equal orig, parse(json5)
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_parse_bigdecimals() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_parser_test.rb, line 110
+def test_parse_bigdecimals
+  assert_equal(BigDecimal,                                 JSON.parse('{"foo": 9.01234567890123456789}', decimal_class: BigDecimal)["foo"].class)
+  assert_equal(BigDecimal.new("0.901234567890123456789E1"),JSON.parse('{"foo": 9.01234567890123456789}', decimal_class: BigDecimal)["foo"]      )
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_parse_comments() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_parser_test.rb, line 219
+  def test_parse_comments
+    json = <<EOT
+{
+  "key1":"value1", // eol comment
+  "key2":"value2"  /* multi line
+                    *  comment */,
+  "key3":"value3"  /* multi line
+                    // nested eol comment
+                    *  comment */
+}
+EOT
+    assert_equal(
+      { "key1" => "value1", "key2" => "value2", "key3" => "value3" },
+      parse(json))
+    json = <<EOT
+{
+  "key1":"value1"  /* multi line
+                    // nested eol comment
+                    /* illegal nested multi line comment */
+                    *  comment */
+}
+EOT
+    assert_raise(ParserError) { parse(json) }
+    json = <<EOT
+{
+  "key1":"value1"  /* multi line
+                   // nested eol comment
+                   closed multi comment */
+                   and again, throw an Error */
+}
+EOT
+    assert_raise(ParserError) { parse(json) }
+    json = <<EOT
+{
+  "key1":"value1"  /*/*/
+}
+EOT
+    assert_equal({ "key1" => "value1" }, parse(json))
+  end
+
+ +
+ + + + +
+ + +
+ +
+ test_parse_complex_objects() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_parser_test.rb, line 124
+def test_parse_complex_objects
+  a = [ nil, false, true, "foßbar", [ "n€st€d", true ], { "nested" => true, "n€ßt€ð2" => {} }]
+  a.permutation.each do |perm|
+    s = "a"
+    orig_obj = perm.inject({}) { |h, x| h[s.dup] = x; s = s.succ; h }
+    json = pretty_generate(orig_obj)
+    assert_equal orig_obj, parse(json)
+  end
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_parse_generic_object() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_parser_test.rb, line 416
+def test_parse_generic_object
+  res = parse(
+    '{"foo":"bar", "baz":{}}',
+    :object_class => JSON::GenericObject
+  )
+  assert_equal(JSON::GenericObject, res.class)
+  assert_equal "bar", res.foo
+  assert_equal "bar", res["foo"]
+  assert_equal "bar", res[:foo]
+  assert_equal "bar", res.to_hash[:foo]
+  assert_equal(JSON::GenericObject, res.baz.class)
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_parse_json_primitive_values() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_parser_test.rb, line 151
+def test_parse_json_primitive_values
+  assert_raise(JSON::ParserError) { parse('') }
+  assert_raise(TypeError) { parse(nil) }
+  assert_raise(JSON::ParserError) { parse('  /* foo */ ') }
+  assert_equal nil, parse('null')
+  assert_equal false, parse('false')
+  assert_equal true, parse('true')
+  assert_equal 23, parse('23')
+  assert_equal 1, parse('1')
+  assert_equal_float 3.141, parse('3.141'), 1E-3
+  assert_equal 2 ** 64, parse('18446744073709551616')
+  assert_equal 'foo', parse('"foo"')
+  assert parse('NaN', :allow_nan => true).nan?
+  assert parse('Infinity', :allow_nan => true).infinite?
+  assert parse('-Infinity', :allow_nan => true).infinite?
+  assert_raise(JSON::ParserError) { parse('[ 1, ]') }
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_parse_more_complex_arrays() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_parser_test.rb, line 116
+def test_parse_more_complex_arrays
+  a = [ nil, false, true, "foßbar", [ "n€st€d", true ], { "nested" => true, "n€ßt€ð2" => {} }]
+  a.permutation.each do |perm|
+    json = pretty_generate(perm)
+    assert_equal perm, parse(json)
+  end
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_parse_numbers() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_parser_test.rb, line 87
+def test_parse_numbers
+  assert_raise(JSON::ParserError) { parse('+23.2') }
+  assert_raise(JSON::ParserError) { parse('+23') }
+  assert_raise(JSON::ParserError) { parse('.23') }
+  assert_raise(JSON::ParserError) { parse('023') }
+  assert_equal 23, parse('23')
+  assert_equal -23, parse('-23')
+  assert_equal_float 3.141, parse('3.141')
+  assert_equal_float -3.141, parse('-3.141')
+  assert_equal_float 3.141, parse('3141e-3')
+  assert_equal_float 3.141, parse('3141.1e-3')
+  assert_equal_float 3.141, parse('3141E-3')
+  assert_equal_float 3.141, parse('3141.0E-3')
+  assert_equal_float -3.141, parse('-3141.0e-3')
+  assert_equal_float -3.141, parse('-3141e-3')
+  assert_raise(ParserError) { parse('NaN') }
+  assert parse('NaN', :allow_nan => true).nan?
+  assert_raise(ParserError) { parse('Infinity') }
+  assert_equal 1.0/0, parse('Infinity', :allow_nan => true)
+  assert_raise(ParserError) { parse('-Infinity') }
+  assert_equal -1.0/0, parse('-Infinity', :allow_nan => true)
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_parse_object() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_parser_test.rb, line 356
+def test_parse_object
+  assert_equal({}, parse('{}'))
+  assert_equal({}, parse('  {  }  '))
+  assert_equal({'foo'=>'bar'}, parse('{"foo":"bar"}'))
+  assert_equal({'foo'=>'bar'}, parse('    { "foo"  :   "bar"   }   '))
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_parse_object_custom_hash_derived_class() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_parser_test.rb, line 402
+def test_parse_object_custom_hash_derived_class
+  res = parse('{"foo":"bar"}', :object_class => SubHash)
+  assert_equal({"foo" => "bar"}, res)
+  assert_equal(SubHash, res.class)
+  assert res.item_set?
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_parse_object_custom_non_hash_derived_class() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_parser_test.rb, line 409
+def test_parse_object_custom_non_hash_derived_class
+  res = parse('{"foo":"bar"}', :object_class => SubOpenStruct)
+  assert_equal "bar", res.foo
+  assert_equal(SubOpenStruct, res.class)
+  assert res.item_set?
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_parse_simple_arrays() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_parser_test.rb, line 54
+def test_parse_simple_arrays
+  assert_equal([],             parse('[]'))
+  assert_equal([],             parse('  [  ] '))
+  assert_equal([ nil ],        parse('[null]'))
+  assert_equal([ false ],      parse('[false]'))
+  assert_equal([ true ],       parse('[true]'))
+  assert_equal([ -23 ],        parse('[-23]'))
+  assert_equal([ 23 ],         parse('[23]'))
+  assert_equal_float([ 0.23 ], parse('[0.23]'))
+  assert_equal_float([ 0.0 ],  parse('[0e0]'))
+  assert_equal([""],           parse('[""]'))
+  assert_equal(["foobar"],     parse('["foobar"]'))
+  assert_equal([{}],           parse('[{}]'))
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_parse_simple_objects() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_parser_test.rb, line 69
+def test_parse_simple_objects
+  assert_equal({}, parse('{}'))
+  assert_equal({}, parse(' {   }   '))
+  assert_equal({ "a" => nil }, parse('{   "a"   :  null}'))
+  assert_equal({ "a" => nil }, parse('{"a":null}'))
+  assert_equal({ "a" => false }, parse('{   "a"  :  false  }  '))
+  assert_equal({ "a" => false }, parse('{"a":false}'))
+  assert_raise(JSON::ParserError) { parse('{false}') }
+  assert_equal({ "a" => true }, parse('{"a":true}'))
+  assert_equal({ "a" => true }, parse('  { "a" :  true  }   '))
+  assert_equal({ "a" => -23 }, parse('  {  "a"  :  -23  }  '))
+  assert_equal({ "a" => -23 }, parse('  { "a" : -23 } '))
+  assert_equal({ "a" => 23 }, parse('{"a":23  } '))
+  assert_equal({ "a" => 23 }, parse('  { "a"  : 23  } '))
+  assert_equal({ "a" => 0.23 }, parse(' { "a"  :  0.23 }  '))
+  assert_equal({ "a" => 0.23 }, parse('  {  "a"  :  0.23  }  '))
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_parse_some_strings() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_parser_test.rb, line 169
+def test_parse_some_strings
+  assert_equal([""], parse('[""]'))
+  assert_equal(["\\"], parse('["\\"]'))
+  assert_equal(['"'], parse('["\""]'))
+  assert_equal(['\"\'], parse('["\\\"\\"]'))
+  assert_equal(
+    ["\"\b\n\r\t\0\037"],
+    parse('["\"\b\n\r\t\u0000\u001f"]')
+  )
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_parse_values() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_parser_test.rb, line 42
+def test_parse_values
+  assert_equal(nil,      parse('null'))
+  assert_equal(false,    parse('false'))
+  assert_equal(true,     parse('true'))
+  assert_equal(-23,      parse('-23'))
+  assert_equal(23,       parse('23'))
+  assert_in_delta(0.23,  parse('0.23'), 1e-2)
+  assert_in_delta(0.0,   parse('0e0'), 1e-2)
+  assert_equal("",       parse('""'))
+  assert_equal("foobar", parse('"foobar"'))
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_parser_reset() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_parser_test.rb, line 36
+def test_parser_reset
+  parser = Parser.new('{"a":"b"}')
+  assert_equal({ 'a' => 'b' }, parser.parse)
+  assert_equal({ 'a' => 'b' }, parser.parse)
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_parsing() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_parser_test.rb, line 31
+def test_parsing
+  parser = JSON::Parser.new('"test"')
+  assert_equal 'test', parser.parse
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_parsing_frozen_ascii8bit_string() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_parser_test.rb, line 456
+def test_parsing_frozen_ascii8bit_string
+  assert_equal(
+    { 'foo' => 'bar' },
+    JSON('{ "foo": "bar" }'.force_encoding(Encoding::ASCII_8BIT).freeze)
+  )
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_some_wrong_inputs() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_parser_test.rb, line 193
+def test_some_wrong_inputs
+  assert_raise(ParserError) { parse('[] bla') }
+  assert_raise(ParserError) { parse('[] 1') }
+  assert_raise(ParserError) { parse('[] []') }
+  assert_raise(ParserError) { parse('[] {}') }
+  assert_raise(ParserError) { parse('{} []') }
+  assert_raise(ParserError) { parse('{} {}') }
+  assert_raise(ParserError) { parse('[NULL]') }
+  assert_raise(ParserError) { parse('[FALSE]') }
+  assert_raise(ParserError) { parse('[TRUE]') }
+  assert_raise(ParserError) { parse('[07]    ') }
+  assert_raise(ParserError) { parse('[0a]') }
+  assert_raise(ParserError) { parse('[1.]') }
+  assert_raise(ParserError) { parse('     ') }
+end
+
+ +
+ + + + +
+ + +
+ +
+ test_symbolize_names() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_parser_test.rb, line 209
+def test_symbolize_names
+  assert_equal({ "foo" => "bar", "baz" => "quux" },
+    parse('{"foo":"bar", "baz":"quux"}'))
+  assert_equal({ :foo => "bar", :baz => "quux" },
+    parse('{"foo":"bar", "baz":"quux"}', :symbolize_names => true))
+  assert_raise(ArgumentError) do
+    parse('{}', :symbolize_names => true, :create_additions => true)
+  end
+end
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/JSONParserTest/Encoding.html b/tmp/rdoc/JSONParserTest/Encoding.html new file mode 100644 index 000000000..4be74ff1a --- /dev/null +++ b/tmp/rdoc/JSONParserTest/Encoding.html @@ -0,0 +1,96 @@ + + + + + + +module JSONParserTest::Encoding - RDoc Documentation + + + + + + + + + + + + + + +
+

+ module JSONParserTest::Encoding +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+ + + + diff --git a/tmp/rdoc/JSONParserTest/SubArray.html b/tmp/rdoc/JSONParserTest/SubArray.html new file mode 100644 index 000000000..356af59e2 --- /dev/null +++ b/tmp/rdoc/JSONParserTest/SubArray.html @@ -0,0 +1,195 @@ + + + + + + +class JSONParserTest::SubArray - RDoc Documentation + + + + + + + + + + + + + + +
+

+ class JSONParserTest::SubArray +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Instance Methods

+
+ + +
+ +
+ <<(v) + + click to toggle source + +
+ + +
+ + + + +
+ Calls superclass method + +
+ + + +
+
# File tests/json_parser_test.rb, line 297
+def <<(v)
+  @shifted = true
+  super
+end
+
+ +
+ + + + +
+ + +
+ +
+ shifted?() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_parser_test.rb, line 302
+def shifted?
+  @shifted
+end
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/JSONParserTest/SubArray2.html b/tmp/rdoc/JSONParserTest/SubArray2.html new file mode 100644 index 000000000..e44110c9f --- /dev/null +++ b/tmp/rdoc/JSONParserTest/SubArray2.html @@ -0,0 +1,201 @@ + + + + + + +class JSONParserTest::SubArray2 - RDoc Documentation + + + + + + + + + + + + + + +
+

+ class JSONParserTest::SubArray2 +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Class Methods

+
+ + +
+ +
+ json_create(o) + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_parser_test.rb, line 315
+def self.json_create(o)
+  o.delete JSON.create_id
+  o['ary']
+end
+
+ +
+ + + + +
+ + +
+ +
+
+

Public Instance Methods

+
+ + +
+ +
+ to_json(*a) + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_parser_test.rb, line 308
+def to_json(*a)
+  {
+    JSON.create_id => self.class.name,
+    'ary'          => to_a,
+  }.to_json(*a)
+end
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/JSONParserTest/SubArrayWrapper.html b/tmp/rdoc/JSONParserTest/SubArrayWrapper.html new file mode 100644 index 000000000..8431ee384 --- /dev/null +++ b/tmp/rdoc/JSONParserTest/SubArrayWrapper.html @@ -0,0 +1,289 @@ + + + + + + +class JSONParserTest::SubArrayWrapper - RDoc Documentation + + + + + + + + + + + + + + +
+

+ class JSONParserTest::SubArrayWrapper +

+ +
+ +
+ + + + +
+ + + + + + + +
+
+

Attributes

+
+ + +
+
+ data[R] +
+ +
+ + + +
+
+ +
+ + + +
+
+

Public Class Methods

+
+ + +
+ +
+ new() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_parser_test.rb, line 322
+def initialize
+  @data = []
+end
+
+ +
+ + + + +
+ + +
+ +
+
+

Public Instance Methods

+
+ + +
+ +
+ <<(value) + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_parser_test.rb, line 332
+def <<(value)
+  @data << value
+  @shifted = true
+end
+
+ +
+ + + + +
+ + +
+ +
+ [](index) + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_parser_test.rb, line 328
+def [](index)
+  @data[index]
+end
+
+ +
+ + + + +
+ + +
+ +
+ shifted?() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_parser_test.rb, line 337
+def shifted?
+  @shifted
+end
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/JSONParserTest/SubHash.html b/tmp/rdoc/JSONParserTest/SubHash.html new file mode 100644 index 000000000..baae26c84 --- /dev/null +++ b/tmp/rdoc/JSONParserTest/SubHash.html @@ -0,0 +1,195 @@ + + + + + + +class JSONParserTest::SubHash - RDoc Documentation + + + + + + + + + + + + + + +
+

+ class JSONParserTest::SubHash +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Instance Methods

+
+ + +
+ +
+ []=(k, v) + + click to toggle source + +
+ + +
+ + + + +
+ Calls superclass method + +
+ + + +
+
# File tests/json_parser_test.rb, line 364
+def []=(k, v)
+  @item_set = true
+  super
+end
+
+ +
+ + + + +
+ + +
+ +
+ item_set?() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_parser_test.rb, line 369
+def item_set?
+  @item_set
+end
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/JSONParserTest/SubHash2.html b/tmp/rdoc/JSONParserTest/SubHash2.html new file mode 100644 index 000000000..a733cd09b --- /dev/null +++ b/tmp/rdoc/JSONParserTest/SubHash2.html @@ -0,0 +1,200 @@ + + + + + + +class JSONParserTest::SubHash2 - RDoc Documentation + + + + + + + + + + + + + + +
+

+ class JSONParserTest::SubHash2 +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Class Methods

+
+ + +
+ +
+ json_create(o) + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_parser_test.rb, line 381
+def self.json_create(o)
+  o.delete JSON.create_id
+  self[o]
+end
+
+ +
+ + + + +
+ + +
+ +
+
+

Public Instance Methods

+
+ + +
+ +
+ to_json(*a) + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_parser_test.rb, line 375
+def to_json(*a)
+  {
+    JSON.create_id => self.class.name,
+  }.merge(self).to_json(*a)
+end
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/JSONParserTest/SubOpenStruct.html b/tmp/rdoc/JSONParserTest/SubOpenStruct.html new file mode 100644 index 000000000..5cb22bd24 --- /dev/null +++ b/tmp/rdoc/JSONParserTest/SubOpenStruct.html @@ -0,0 +1,225 @@ + + + + + + +class JSONParserTest::SubOpenStruct - RDoc Documentation + + + + + + + + + + + + + + +
+

+ class JSONParserTest::SubOpenStruct +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Instance Methods

+
+ + +
+ +
+ [](k) + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_parser_test.rb, line 388
+def [](k)
+  __send__(k)
+end
+
+ +
+ + + + +
+ + +
+ +
+ []=(k, v) + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_parser_test.rb, line 392
+def []=(k, v)
+  @item_set = true
+  __send__("#{k}=", v)
+end
+
+ +
+ + + + +
+ + +
+ +
+ item_set?() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_parser_test.rb, line 397
+def item_set?
+  @item_set
+end
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/JSONServlet.html b/tmp/rdoc/JSONServlet.html new file mode 100644 index 000000000..cddb4d0fd --- /dev/null +++ b/tmp/rdoc/JSONServlet.html @@ -0,0 +1,170 @@ + + + + + + +class JSONServlet - RDoc Documentation + + + + + + + + + + + + + + +
+

+ class JSONServlet +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Instance Methods

+
+ + +
+ +
+ do_GET(req, res) + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tools/server.rb, line 12
+def do_GET(req, res)
+  obj = {
+    "TIME" => Time.now.strftime("%FT%T"),
+    "foo" => "Bär",
+    "bar" => "© ≠ €!",
+    'a' => 2,
+    'b' => 3.141,
+    'COUNT' => @@count += 1,
+    'c' => 'c',
+    'd' => [ 1, "b", 3.14 ],
+    'e' => { 'foo' => 'bar' },
+    'g' => "松本行弘",
+    'h' => 1000.0,
+    'i' => 0.001,
+    'j' => "\xf0\xa0\x80\x81",
+  }
+  res.body = JSON.generate obj
+  res['Content-Type'] = "application/json"
+end
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/JSONStringMatchingTest.html b/tmp/rdoc/JSONStringMatchingTest.html new file mode 100644 index 000000000..eb62d24e4 --- /dev/null +++ b/tmp/rdoc/JSONStringMatchingTest.html @@ -0,0 +1,178 @@ + + + + + + +class JSONStringMatchingTest - RDoc Documentation + + + + + + + + + + + + + + +
+

+ class JSONStringMatchingTest +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Instance Methods

+
+ + +
+ +
+ test_match_date() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_string_matching_test.rb, line 22
+def test_match_date
+  t = TestTime.new
+  t_json = [ t ].to_json
+  time_regexp = /\A\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}[+-]\d{4}\z/
+  assert_equal [ t ],
+    parse(
+      t_json,
+      :create_additions => true,
+      :match_string => { time_regexp => TestTime }
+    )
+  assert_equal [ t.strftime('%FT%T%z') ],
+    parse(
+      t_json,
+      :match_string => { time_regexp => TestTime }
+    )
+end
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/JSONStringMatchingTest/TestTime.html b/tmp/rdoc/JSONStringMatchingTest/TestTime.html new file mode 100644 index 000000000..07ca994d8 --- /dev/null +++ b/tmp/rdoc/JSONStringMatchingTest/TestTime.html @@ -0,0 +1,232 @@ + + + + + + +class JSONStringMatchingTest::TestTime - RDoc Documentation + + + + + + + + + + + + + + +
+

+ class JSONStringMatchingTest::TestTime +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Class Methods

+
+ + +
+ +
+ json_create(string) + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_string_matching_test.rb, line 9
+def self.json_create(string)
+  Time.parse(string)
+end
+
+ +
+ + + + +
+ + +
+ +
+
+

Public Instance Methods

+
+ + +
+ +
+ ==(other) + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_string_matching_test.rb, line 17
+def ==(other)
+  to_i == other.to_i
+end
+
+ +
+ + + + +
+ + +
+ +
+ to_json(*) + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tests/json_string_matching_test.rb, line 13
+def to_json(*)
+  %Q{"#{strftime('%FT%T%z')}"}
+end
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/Kernel.html b/tmp/rdoc/Kernel.html new file mode 100644 index 000000000..6a38f1ec5 --- /dev/null +++ b/tmp/rdoc/Kernel.html @@ -0,0 +1,96 @@ + + + + + + +module Kernel - RDoc Documentation + + + + + + + + + + + + + + +
+

+ module Kernel +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+ + + + diff --git a/tmp/rdoc/MyState.html b/tmp/rdoc/MyState.html new file mode 100644 index 000000000..786874fad --- /dev/null +++ b/tmp/rdoc/MyState.html @@ -0,0 +1,225 @@ + + + + + + +class MyState - RDoc Documentation + + + + + + + + + + + + + + +
+

+ class MyState +

+ +
+ +
+ + + + +
+ + + + + +
+
+

Constants

+
+
+ +
WS + +
+ + +
+
+ + + + + +
+
+

Public Class Methods

+
+ + +
+ +
+ new() + + click to toggle source + +
+ + +
+ + + + +
+ Calls superclass method + +
+ + + +
+
# File tools/fuzz.rb, line 80
+def initialize
+  super(
+        :indent       => make_spaces,
+        :space        => make_spaces,
+        :space_before => make_spaces,
+        :object_nl    => make_spaces,
+        :array_nl     => make_spaces,
+        :max_nesting  => false
+       )
+end
+
+ +
+ + + + +
+ + +
+ +
+
+

Public Instance Methods

+
+ + +
+ +
+ make_spaces() + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tools/fuzz.rb, line 91
+def make_spaces
+  s = ''
+  rand(1).times { s << WS[rand(WS.size)] }
+  s
+end
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/Object.html b/tmp/rdoc/Object.html new file mode 100644 index 000000000..9cea924cb --- /dev/null +++ b/tmp/rdoc/Object.html @@ -0,0 +1,183 @@ + + + + + + +class Object - RDoc Documentation + + + + + + + + + + + + + + +
+

+ class Object +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Instance Methods

+
+ + +
+ +
+ create_server(err, dir, port) + + click to toggle source + +
+ + +
+ + + + + + +
+
# File tools/server.rb, line 33
+def create_server(err, dir, port)
+  dir = File.expand_path(dir)
+  err.puts "Surf to:", "http://#{Socket.gethostname}:#{port}"
+
+  s = HTTPServer.new(
+    :Port         => port,
+    :DocumentRoot => dir,
+    :Logger       => WEBrick::Log.new(err),
+    :AccessLog    => [
+      [ err, WEBrick::AccessLog::COMMON_LOG_FORMAT  ],
+      [ err, WEBrick::AccessLog::REFERER_LOG_FORMAT ],
+      [ err, WEBrick::AccessLog::AGENT_LOG_FORMAT   ]
+    ]
+  )
+  s.mount("/json", JSONServlet)
+  s
+end
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/OpenStruct.html b/tmp/rdoc/OpenStruct.html new file mode 100644 index 000000000..6aee64eb4 --- /dev/null +++ b/tmp/rdoc/OpenStruct.html @@ -0,0 +1,241 @@ + + + + + + +class OpenStruct - RDoc Documentation + + + + + + + + + + + + + + +
+

+ class OpenStruct +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Class Methods

+
+ + +
+ +
+ json_create(object) + + click to toggle source + +
+ + +
+ +

Deserializes JSON string by constructing new Struct object with values t serialized +by to_json.

+ + + + +
+
# File lib/json/add/ostruct.rb, line 11
+def self.json_create(object)
+  new(object['t'] || object[:t])
+end
+
+ +
+ + + + +
+ + +
+ +
+
+

Public Instance Methods

+
+ + +
+ +
+ as_json(*) + + click to toggle source + +
+ + +
+ +

Returns a hash, that will be turned into a JSON +object and represent this object.

+ + + + +
+
# File lib/json/add/ostruct.rb, line 17
+def as_json(*)
+  klass = self.class.name
+  klass.to_s.empty? and raise JSON::JSONError, "Only named structs are supported!"
+  {
+    JSON.create_id => klass,
+    't'            => table,
+  }
+end
+
+ +
+ + + + +
+ + +
+ +
+ to_json(*args) + + click to toggle source + +
+ + +
+ +

Stores class name (OpenStruct) with this struct's values v +as a JSON string.

+ + + + +
+
# File lib/json/add/ostruct.rb, line 28
+def to_json(*args)
+  as_json.to_json(*args)
+end
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/README-json-jruby_md.html b/tmp/rdoc/README-json-jruby_md.html new file mode 100644 index 000000000..74a0a1067 --- /dev/null +++ b/tmp/rdoc/README-json-jruby_md.html @@ -0,0 +1,241 @@ + + + + + + +README-json-jruby - RDoc Documentation + + + + + + + + + + + + + + +
+ +

JSON-JRuby

+ +

JSON-JRuby is a port of Florian Frank's native json library to JRuby. It aims to be +a perfect drop-in replacement for json_pure.

+ +

Development version

+ +

The latest version is available from the Git repository:

+ +
git clone git://github.com/mernen/json-jruby.git
+ +

Compiling

+ +

You'll need JRuby version 1.2 or greater to build JSON-JRuby. Its path +must be set on the jruby.dir property of +nbproject/project.properties (defaults to +../jruby).

+ +

Additionally, you'll need Ant, and +Ragel 6.4 or +greater.

+ +

Then, from the folder where the sources are located, type:

+ +
ant clean jar
+
+ +

to clean any leftovers from previous builds and generate the +.jar files. To generate a RubyGem, specify the +gem action rather than jar.

+
+ + + + + diff --git a/tmp/rdoc/README_md.html b/tmp/rdoc/README_md.html new file mode 100644 index 000000000..e95a58a10 --- /dev/null +++ b/tmp/rdoc/README_md.html @@ -0,0 +1,627 @@ + + + + + + +README - RDoc Documentation + + + + + + + + + + + + + + +
+ +

JSON implementation for Ruby travis-ci.org/flori/json.svg?branch=master

+ +

Description

+ +

This is a implementation of the JSON specification +according to RFC 7159 www.ietf.org/rfc/rfc7159.txt +. Starting from version 1.0.0 on there will be two variants available:

+ + +

Both variants of the JSON generator generate UTF-8 +character sequences by default. If an :ascii_only option with a true value +is given, they escape all non-ASCII and control characters with uXXXX +escape sequences, and support UTF-16 surrogate pairs in order to be able to +generate the whole range of unicode code points.

+ +

All strings, that are to be encoded as JSON +strings, should be UTF-8 byte sequences on the Ruby side. To encode raw +binary strings, that aren't UTF-8 encoded, please use the +to_json_raw_object method of String (which produces an object, that +contains a byte array) and decode the result on the receiving endpoint.

+ +

Installation

+ +

It's recommended to use the extension variant of JSON, because it's faster than the pure ruby +variant. If you cannot build it on your system, you can settle for the +latter.

+ +

Just type into the command line as root:

+ +
# rake install
+
+ +

The above command will build the extensions and install them on your +system.

+ +
# rake install_pure
+
+ +

or

+ +
# ruby install.rb
+
+ +

will just install the pure ruby implementation of JSON.

+ +

If you use Rubygems you can type

+ +
# gem install json
+
+ +

instead, to install the newest JSON version.

+ +

There is also a pure ruby json only variant of the gem, that can be +installed with:

+ +
# gem install json_pure
+
+ +

Compiling the extensions yourself

+ +

If you want to create the parser.c file from its +parser.rl file or draw nice graphviz images of the state +machines, you need ragel from: www.complang.org/ragel/

+ +

Usage

+ +

To use JSON you can

+ +
require 'json'
+
+ +

to load the installed variant (either the extension +'json' or the pure variant +'json_pure'). If you have installed the extension +variant, you can pick either the extension variant or the pure variant by +typing

+ +
require 'json/ext'
+
+ +

or

+ +
require 'json/pure'
+
+ +

Now you can parse a JSON document into a ruby data +structure by calling

+ +
JSON.parse(document)
+
+ +

If you want to generate a JSON document from a ruby +data structure call ruby JSON.generate(data)

+ +

You can also use the pretty_generate method (which formats the +output more verbosely and nicely) or fast_generate (which +doesn't do any of the security checks generate performs, e. g. nesting +deepness checks).

+ +

There are also the JSON and JSON[] methods which +use parse on a String or generate a JSON document +from an array or hash:

+ +
document = JSON 'test'  => 23 # => "{\"test\":23}"
+document = JSON['test' => 23] # => "{\"test\":23}"
+
+ +

and

+ +
data = JSON '{"test":23}'  # => {"test"=>23}
+data = JSON['{"test":23}'] # => {"test"=>23}
+
+ +

You can choose to load a set of common additions to ruby core's objects +if you

+ +
require 'json/add/core'
+
+ +

After requiring this you can, e. g., serialise/deserialise Ruby ranges:

+ +
JSON JSON(1..10) # => 1..10
+
+ +

To find out how to add JSON support to other or +your own classes, read the section “More Examples” below.

+ +

To get the best compatibility to rails' JSON +implementation, you can

+ +
require 'json/add/rails'
+
+ +

Both of the additions attempt to require 'json' (like +above) first, if it has not been required yet.

+ +

Serializing exceptions

+ +

The JSON module doesn't extend +Exception by default. If you convert an Exception +object to JSON, it will by default only include the +exception message.

+ +

To include the full details, you must either load the load the +json/add/core mentioned above, or specifically load the +exception addition:

+ +
require 'json/add/exception'
+
+ +

More Examples

+ +

To create a JSON document from a ruby data +structure, you can call JSON.generate like that:

+ +
json = JSON.generate [1, 2, {"a"=>3.141}, false, true, nil, 4..10]
+# => "[1,2,{\"a\":3.141},false,true,null,\"4..10\"]"
+
+ +

To get back a ruby data structure from a JSON +document, you have to call JSON#parse on it:

+ +
JSON.parse json
+# => [1, 2, {"a"=>3.141}, false, true, nil, "4..10"]
+
+ +

Note, that the range from the original data structure is a simple string +now. The reason for this is, that JSON doesn't +support ranges or arbitrary classes. In this case the json library falls +back to call Object#to_json, which is the same as +#to_s.to_json.

+ +

It's possible to add JSON support serialization +to arbitrary classes by simply implementing a more specialized version of +the #to_json method, that should return a JSON object (a hash converted to JSON with #to_json) like this (don't +forget the *a for all the arguments):

+ +
class Range
+  def to_json(*a)
+    {
+      'json_class'   => self.class.name, # = 'Range'
+      'data'         => [ first, last, exclude_end? ]
+    }.to_json(*a)
+  end
+end
+
+ +

The hash key json_class is the class, that will be asked to +deserialise the JSON representation later. In this +case it's Range, but any namespace of the form +A::B or ::A::B will do. All other keys are +arbitrary and can be used to store the necessary data to configure the +object to be deserialised.

+ +

If a the key json_class is found in a JSON object, the JSON parser +checks if the given class responds to the json_create class +method. If so, it is called with the JSON object +converted to a Ruby hash. So a range can be deserialised by implementing +Range.json_create like this:

+ +
class Range
+  def self.json_create(o)
+    new(*o['data'])
+  end
+end
+
+ +

Now it possible to serialise/deserialise ranges as well:

+ +
json = JSON.generate [1, 2, {"a"=>3.141}, false, true, nil, 4..10]
+# => "[1,2,{\"a\":3.141},false,true,null,{\"json_class\":\"Range\",\"data\":[4,10,false]}]"
+JSON.parse json
+# => [1, 2, {"a"=>3.141}, false, true, nil, 4..10]
+json = JSON.generate [1, 2, {"a"=>3.141}, false, true, nil, 4..10]
+# => "[1,2,{\"a\":3.141},false,true,null,{\"json_class\":\"Range\",\"data\":[4,10,false]}]"
+JSON.parse json, :create_additions => true
+# => [1, 2, {"a"=>3.141}, false, true, nil, 4..10]
+
+ +

JSON.generate always creates the shortest possible string +representation of a ruby data structure in one line. This is good for data +storage or network protocols, but not so good for humans to read. +Fortunately there's also JSON.pretty_generate (or +JSON.pretty_generate) that creates a more readable output:

+ +
puts JSON.pretty_generate([1, 2, {"a"=>3.141}, false, true, nil, 4..10])
+ [
+   1,
+   2,
+   {
+     "a": 3.141
+   },
+   false,
+   true,
+   null,
+   {
+     "json_class": "Range",
+     "data": [
+       4,
+       10,
+       false
+     ]
+   }
+ ]
+
+ +

There are also the methods Kernel#j for generate, and +Kernel#jj for pretty_generate output to the +console, that work analogous to Core Ruby's p and the +pp library's pp methods.

+ +

The script tools/server.rb contains a small example if you +want to test, how receiving a JSON object from a +webrick server in your browser with the javasript prototype library www.prototypejs.org works.

+ +

Speed Comparisons

+ +

I have created some benchmark results (see the benchmarks/data-p4-3Ghz +subdir of the package) for the JSON-parser to estimate the speed up in the +C extension:

+ +
Comparing times (call_time_mean):
+  1 ParserBenchmarkExt#parser   900 repeats:
+        553.922304770 (  real) ->   21.500x
+          0.001805307
+  2 ParserBenchmarkYAML#parser  1000 repeats:
+        224.513358139 (  real) ->    8.714x
+          0.004454078
+  3 ParserBenchmarkPure#parser  1000 repeats:
+         26.755020642 (  real) ->    1.038x
+          0.037376163
+  4 ParserBenchmarkRails#parser 1000 repeats:
+         25.763381731 (  real) ->    1.000x
+          0.038814780
+            calls/sec (  time) ->    speed  covers
+            secs/call
+ +

In the table above 1 is JSON::Ext::Parser, 2 is +YAML.load with YAML compatbile JSON +document, 3 is is JSON::Pure::Parser, and 4 is +ActiveSupport::JSON.decode. The ActiveSupport JSON-decoder +converts the input first to YAML and then uses the YAML-parser, the +conversion seems to slow it down so much that it is only as fast as the +JSON::Pure::Parser!

+ +

If you look at the benchmark data you can see that this is mostly caused by +the frequent high outliers - the median of the Rails-parser runs is still +overall smaller than the median of the JSON::Pure::Parser +runs:

+ +
Comparing times (call_time_median):
+  1 ParserBenchmarkExt#parser   900 repeats:
+        800.592479481 (  real) ->   26.936x
+          0.001249075
+  2 ParserBenchmarkYAML#parser  1000 repeats:
+        271.002390644 (  real) ->    9.118x
+          0.003690004
+  3 ParserBenchmarkRails#parser 1000 repeats:
+         30.227910865 (  real) ->    1.017x
+          0.033082008
+  4 ParserBenchmarkPure#parser  1000 repeats:
+         29.722384421 (  real) ->    1.000x
+          0.033644676
+            calls/sec (  time) ->    speed  covers
+            secs/call
+ +

I have benchmarked the JSON-Generator as well. This generated +a few more values, because there are different modes that also influence +the achieved speed:

+ +
Comparing times (call_time_mean):
+  1 GeneratorBenchmarkExt#generator_fast    1000 repeats:
+        547.354332608 (  real) ->   15.090x
+          0.001826970
+  2 GeneratorBenchmarkExt#generator_safe    1000 repeats:
+        443.968212317 (  real) ->   12.240x
+          0.002252414
+  3 GeneratorBenchmarkExt#generator_pretty  900 repeats:
+        375.104545883 (  real) ->   10.341x
+          0.002665923
+  4 GeneratorBenchmarkPure#generator_fast   1000 repeats:
+         49.978706968 (  real) ->    1.378x
+          0.020008521
+  5 GeneratorBenchmarkRails#generator       1000 repeats:
+         38.531868759 (  real) ->    1.062x
+          0.025952543
+  6 GeneratorBenchmarkPure#generator_safe   1000 repeats:
+         36.927649925 (  real) ->    1.018x 7 (>=3859)
+          0.027079979
+  7 GeneratorBenchmarkPure#generator_pretty 1000 repeats:
+         36.272134441 (  real) ->    1.000x 6 (>=3859)
+          0.027569373
+            calls/sec (  time) ->    speed  covers
+            secs/call
+ +

In the table above 1-3 are JSON::Ext::Generator methods. 4, 6, +and 7 are JSON::Pure::Generator methods and 5 is the Rails JSON generator. It is now a bit faster than the +generator_safe and generator_pretty methods of +the pure variant but slower than the others.

+ +

To achieve the fastest JSON document output, you +can use the fast_generate method. Beware, that this will +disable the checking for circular Ruby data structures, which may cause JSON to go into an infinite loop.

+ +

Here are the median comparisons for completeness' sake:

+ +
Comparing times (call_time_median):
+  1 GeneratorBenchmarkExt#generator_fast    1000 repeats:
+        708.258020939 (  real) ->   16.547x
+          0.001411915
+  2 GeneratorBenchmarkExt#generator_safe    1000 repeats:
+        569.105020353 (  real) ->   13.296x
+          0.001757145
+  3 GeneratorBenchmarkExt#generator_pretty  900 repeats:
+        482.825371244 (  real) ->   11.280x
+          0.002071142
+  4 GeneratorBenchmarkPure#generator_fast   1000 repeats:
+         62.717626652 (  real) ->    1.465x
+          0.015944481
+  5 GeneratorBenchmarkRails#generator       1000 repeats:
+         43.965681162 (  real) ->    1.027x
+          0.022745013
+  6 GeneratorBenchmarkPure#generator_safe   1000 repeats:
+         43.929073409 (  real) ->    1.026x 7 (>=3859)
+          0.022763968
+  7 GeneratorBenchmarkPure#generator_pretty 1000 repeats:
+         42.802514491 (  real) ->    1.000x 6 (>=3859)
+          0.023363113
+            calls/sec (  time) ->    speed  covers
+            secs/call
+ +

Author

+ +

Florian Frank flori@ping.de

+ +

License

+ +

Ruby License, see www.ruby-lang.org/en/about/license.txt.

+ +

Download

+ +

The latest version of this library can be downloaded at

+ + +

Online Documentation should be located at

+ +
+ + + + + diff --git a/tmp/rdoc/Rakefile.html b/tmp/rdoc/Rakefile.html new file mode 100644 index 000000000..7a8c2bf90 --- /dev/null +++ b/tmp/rdoc/Rakefile.html @@ -0,0 +1,641 @@ + + + + + + +Rakefile - RDoc Documentation + + + + + + + + + + + + + + +
+ +

begin

+ +
require 'rubygems/package_task'
+
+ +

rescue LoadError end

+ +

require 'rbconfig' include\

+ +
begin
+  RbConfig
+rescue NameError
+  Config
+end
+
+ +

require 'rake/clean' CLOBBER.include 'doc', +'Gemfile.lock' CLEAN.include FileList['diagrams .*'], +'doc', 'coverage', 'tmp',

+ +
FileList["ext/   {Makefile,mkmf.log}"], 'build', 'dist', FileList['**  .rbc'],
+FileList["{ext,lib}/   *.{so,bundle,#{CONFIG['DLEXT']},o,obj,pdb,lib,manifest,exp,def,jar,class,dSYM}"],
+FileList['java/src/**/*.class']
+ +

require 'rake/testtask' class UndocumentedTestTask < +Rake::TestTask

+ +
def desc(*) end
+
+ +

end

+ +

MAKE = ENV || %w[gmake make].find { |c| system(c, +'-v') } BUNDLE = ENV || %w.find { |c| system(c, '-v') } PKG_NAME += 'json' PKG_TITLE = 'JSON Implementation for Ruby' +PKG_VERSION = File.read('VERSION').chomp PKG_FILES = +FileList[`git ls-files`.split(/n/)]

+ +

EXT_ROOT_DIR = 'ext/json/ext' EXT_PARSER_DIR = +“#{EXT_ROOT_DIR}/parser” EXT_PARSER_DL = “#{EXT_PARSER_DIR}/parser.#{CONFIG}” RAGEL_PATH = +“#{EXT_PARSER_DIR}/parser.rl” EXT_PARSER_SRC = +“#{EXT_PARSER_DIR}/parser.c” EXT_GENERATOR_DIR = +“#{EXT_ROOT_DIR}/generator” EXT_GENERATOR_DL = +“#{EXT_GENERATOR_DIR}/generator.#{CONFIG}” +EXT_GENERATOR_SRC = “#{EXT_GENERATOR_DIR}/generator.c”

+ +

JAVA_DIR = “java/src/json/ext” JAVA_RAGEL_PATH = +“#{JAVA_DIR}/Parser.rl” JAVA_PARSER_SRC = “#{JAVA_DIR}/Parser.java” +JAVA_SOURCES = FileList +JAVA_CLASSES = [] JRUBY_PARSER_JAR = +File.expand_path(“lib/json/ext/parser.jar”) JRUBY_GENERATOR_JAR = +File.expand_path(“lib/json/ext/generator.jar”)

+ +

RAGEL_CODEGEN = %w[rlcodegen rlgen-cd ragel].find { |c| system(c, +'-v') } RAGEL_DOTGEN = %w[rlgen-dot rlgen-cd ragel].find { |c| +system(c, '-v') }

+ +

desc “Installing library (pure)” task :install_pure => :version do

+ +
ruby 'install.rb'
+
+ +

end

+ +

task :install_ext_really do

+ +
sitearchdir = CONFIG["sitearchdir"]
+cd 'ext' do
+  for file in Dir["json/ext/*.#{CONFIG['DLEXT']}"]
+    d = File.join(sitearchdir, file)
+    mkdir_p File.dirname(d)
+    install(file, d)
+  end
+  warn " *** Installed EXT ruby library."
+end
+
+ +

end

+ +

desc “Installing library (extension)” task :install_ext => [ :compile, +:install_pure, :install_ext_really ]

+ +

desc “Installing library (extension)” task :install => :install_ext

+ +

if defined?(Gem) and defined?(Gem::PackageTask)

+ +
spec_pure = Gem::Specification.new do |s|
+  s.name = 'json_pure'
+  s.version = PKG_VERSION
+  s.summary = PKG_TITLE
+  s.description = "This is a JSON implementation in pure Ruby."
+
+  s.files = PKG_FILES
+
+  s.require_path = 'lib'
+  s.add_development_dependency 'rake'
+  s.add_development_dependency 'test-unit', '~> 2.0'
+
+  s.extra_rdoc_files << 'README.md'
+  s.rdoc_options <<
+    '--title' <<  'JSON implemention for ruby' << '--main' << 'README.md'
+  s.test_files.concat Dir['./tests/test_*.rb']
+
+  s.author = "Florian Frank"
+  s.email = "flori@ping.de"
+  s.homepage = "http://flori.github.com/#{PKG_NAME}"
+  s.license = 'Ruby'
+  s.required_ruby_version = '>= 1.9'
+end
+
+desc 'Creates a json_pure.gemspec file'
+task :gemspec_pure => :version do
+  File.open('json_pure.gemspec', 'w') do |gemspec|
+    gemspec.write spec_pure.to_ruby
+  end
+end
+
+Gem::PackageTask.new(spec_pure) do |pkg|
+    pkg.need_tar = true
+    pkg.package_files = PKG_FILES
+end
+
+spec_ext = Gem::Specification.new do |s|
+  s.name = 'json'
+  s.version = PKG_VERSION
+  s.summary = PKG_TITLE
+  s.description = "This is a JSON implementation as a Ruby extension in C."
+
+  s.files = PKG_FILES
+
+  s.extensions = FileList['ext/**/extconf.rb']
+
+  s.require_path = 'lib'
+  s.add_development_dependency 'rake'
+  s.add_development_dependency 'test-unit', '~> 2.0'
+
+  s.extra_rdoc_files << 'README.md'
+  s.rdoc_options <<
+    '--title' <<  'JSON implemention for Ruby' << '--main' << 'README.md'
+  s.test_files.concat Dir['./tests/test_*.rb']
+
+  s.author = "Florian Frank"
+  s.email = "flori@ping.de"
+  s.homepage = "http://flori.github.com/#{PKG_NAME}"
+  s.license = 'Ruby'
+  s.required_ruby_version = '>= 1.9'
+end
+
+desc 'Creates a json.gemspec file'
+task :gemspec_ext => :version do
+  File.open('json.gemspec', 'w') do |gemspec|
+    gemspec.write spec_ext.to_ruby
+  end
+end
+
+Gem::PackageTask.new(spec_ext) do |pkg|
+  pkg.need_tar      = true
+  pkg.package_files = PKG_FILES
+end
+
+desc 'Create all gemspec files'
+task :gemspec => [ :gemspec_pure, :gemspec_ext ]
+
+ +

end

+ +

desc m = “Writing version information for #{PKG_VERSION}” task :version do

+ +
puts m
+File.open(File.join('lib', 'json', 'version.rb'), 'w') do |v|
+  v.puts <<EOT
+ +

# frozen_string_literal: false module JSON

+ +
# JSON version
+VERSION         = '#{PKG_VERSION}'
+VERSION_ARRAY   = VERSION.split(/\./).map { |x| x.to_i } # :nodoc:
+VERSION_MAJOR   = VERSION_ARRAY[0] # :nodoc:
+VERSION_MINOR   = VERSION_ARRAY[1] # :nodoc:
+VERSION_BUILD   = VERSION_ARRAY[2] # :nodoc:
+
+ +

end EOT

+ +
end
+ +

end

+ +

task :check_env do

+ +
ENV.key?('JSON') or fail "JSON env var is required"
+
+ +

end

+ +

desc “Testing library (pure ruby)” task :test_pure => [ :clean, +:check_env, :do_test_pure ]

+ +

UndocumentedTestTask.new do |t|

+ +
t.name = 'do_test_pure'
+t.libs << 'lib' << 'tests'
+t.test_files = FileList['tests/*_test.rb']
+t.verbose = true
+t.options = '-v'
+
+ +

end

+ +

desc “Testing library (pure ruby and extension)” task :test do

+ +
sh "env JSON=pure #{BUNDLE} exec rake test_pure" or exit 1
+sh "env JSON=ext #{BUNDLE} exec rake test_ext"  or exit 1
+
+ +

end

+ +

namespace :gems do

+ +
desc 'Install all development gems'
+task :install do
+  sh "#{BUNDLE}"
+end
+
+ +

end

+ +

if defined?(RUBY_ENGINE) and RUBY_ENGINE == 'jruby'

+ +
ENV['JAVA_HOME'] ||= [
+  '/usr/local/java/jdk',
+  '/usr/lib/jvm/java-6-openjdk',
+  '/Library/Java/Home',
+].find { |c| File.directory?(c) }
+if ENV['JAVA_HOME']
+  warn " *** JAVA_HOME is set to #{ENV['JAVA_HOME'].inspect}"
+  ENV['PATH'] = ENV['PATH'].split(/:/).unshift(java_path = "#{ENV['JAVA_HOME']}/bin") * ':'
+  warn " *** java binaries are assumed to be in #{java_path.inspect}"
+else
+  warn " *** JAVA_HOME was not set or could not be guessed!"
+  exit 1
+end
+
+file JAVA_PARSER_SRC => JAVA_RAGEL_PATH do
+  cd JAVA_DIR do
+    if RAGEL_CODEGEN == 'ragel'
+      sh "ragel Parser.rl -J -o Parser.java"
+    else
+      sh "ragel -x Parser.rl | #{RAGEL_CODEGEN} -J"
+    end
+  end
+end
+
+desc "Generate parser for java with ragel"
+task :ragel => JAVA_PARSER_SRC
+
+desc "Delete the ragel generated Java source"
+task :ragel_clean do
+  rm_rf JAVA_PARSER_SRC
+end
+
+JRUBY_JAR = File.join(CONFIG["libdir"], "jruby.jar")
+if File.exist?(JRUBY_JAR)
+  JAVA_SOURCES.each do |src|
+    classpath = (Dir['java/lib/*.jar'] << 'java/src' << JRUBY_JAR) * ':'
+    obj = src.sub(/\.java\Z/, '.class')
+    file obj => src do
+      sh 'javac', '-classpath', classpath, '-source', '1.5', '-target', '1.5', src
+    end
+    JAVA_CLASSES << obj
+  end
+else
+  warn "WARNING: Cannot find jruby in path => Cannot build jruby extension!"
+end
+
+desc "Compiling jruby extension"
+task :compile => JAVA_CLASSES
+
+desc "Package the jruby gem"
+task :jruby_gem => :create_jar do
+  sh 'gem build json-java.gemspec'
+  mkdir_p 'pkg'
+  mv "json-#{PKG_VERSION}-java.gem", 'pkg'
+end
+
+desc "Testing library (jruby)"
+task :test_ext => [ :check_env, :create_jar, :do_test_ext ]
+
+UndocumentedTestTask.new do |t|
+  t.name = 'do_test_ext'
+  t.libs << 'lib' << 'tests'
+  t.test_files = FileList['tests/*_test.rb']
+  t.verbose = true
+  t.options = '-v'
+end
+
+file JRUBY_PARSER_JAR => :compile do
+  cd 'java/src' do
+    parser_classes = FileList[
+      "json/ext/ByteListTranscoder*.class",
+      "json/ext/OptionsReader*.class",
+      "json/ext/Parser*.class",
+      "json/ext/RuntimeInfo*.class",
+      "json/ext/StringDecoder*.class",
+      "json/ext/Utils*.class"
+    ]
+    sh 'jar', 'cf', File.basename(JRUBY_PARSER_JAR), *parser_classes
+    mv File.basename(JRUBY_PARSER_JAR), File.dirname(JRUBY_PARSER_JAR)
+  end
+end
+
+desc "Create parser jar"
+task :create_parser_jar => JRUBY_PARSER_JAR
+
+file JRUBY_GENERATOR_JAR => :compile do
+  cd 'java/src' do
+    generator_classes = FileList[
+      "json/ext/ByteListTranscoder*.class",
+      "json/ext/OptionsReader*.class",
+      "json/ext/Generator*.class",
+      "json/ext/RuntimeInfo*.class",
+      "json/ext/StringEncoder*.class",
+      "json/ext/Utils*.class"
+    ]
+    sh 'jar', 'cf', File.basename(JRUBY_GENERATOR_JAR), *generator_classes
+    mv File.basename(JRUBY_GENERATOR_JAR), File.dirname(JRUBY_GENERATOR_JAR)
+  end
+end
+
+desc "Create generator jar"
+task :create_generator_jar => JRUBY_GENERATOR_JAR
+
+desc "Create parser and generator jars"
+task :create_jar => [ :create_parser_jar, :create_generator_jar ]
+
+desc "Build all gems and archives for a new release of the jruby extension."
+task :build => [ :clean, :version, :jruby_gem ]
+
+task :release => :build
+
+ +

else

+ +
desc "Compiling extension"
+task :compile => [ EXT_PARSER_DL, EXT_GENERATOR_DL ]
+
+file EXT_PARSER_DL => EXT_PARSER_SRC do
+  cd EXT_PARSER_DIR do
+    ruby 'extconf.rb'
+    sh MAKE
+  end
+  cp "#{EXT_PARSER_DIR}/parser.#{CONFIG['DLEXT']}", EXT_ROOT_DIR
+end
+
+file EXT_GENERATOR_DL => EXT_GENERATOR_SRC do
+  cd EXT_GENERATOR_DIR do
+    ruby 'extconf.rb'
+    sh MAKE
+  end
+  cp "#{EXT_GENERATOR_DIR}/generator.#{CONFIG['DLEXT']}", EXT_ROOT_DIR
+end
+
+desc "Testing library (extension)"
+task :test_ext => [ :check_env, :compile, :do_test_ext ]
+
+UndocumentedTestTask.new do |t|
+  t.name = 'do_test_ext'
+  t.libs << 'ext' << 'lib' << 'tests'
+  t.test_files = FileList['tests/*_test.rb']
+  t.verbose = true
+  t.options = '-v'
+end
+
+desc "Generate parser with ragel"
+task :ragel => EXT_PARSER_SRC
+
+desc "Delete the ragel generated C source"
+task :ragel_clean do
+  rm_rf EXT_PARSER_SRC
+end
+
+desc "Update the tags file"
+task :tags do
+  system 'ctags', *Dir['**/*.{rb,c,h,java}']
+end
+
+file EXT_PARSER_SRC => RAGEL_PATH do
+  cd EXT_PARSER_DIR do
+    if RAGEL_CODEGEN == 'ragel'
+      sh "ragel parser.rl -G2 -o parser.c"
+    else
+      sh "ragel -x parser.rl | #{RAGEL_CODEGEN} -G2"
+    end
+    src = File.read("parser.c").gsub(/[ \t]+$/, '')
+    src.gsub!(/^static const int (JSON_.*=.*);$/, 'enum {\1};')
+    File.open("parser.c", "w") {|f| f.print src}
+  end
+end
+
+desc "Generate diagrams of ragel parser (ps)"
+task :ragel_dot_ps do
+  root = 'diagrams'
+  specs = []
+  File.new(RAGEL_PATH).grep(/^\s*machine\s*(\S+);\s*$/) { specs << $1 }
+  for s in specs
+    if RAGEL_DOTGEN == 'ragel'
+      sh "ragel #{RAGEL_PATH} -S#{s} -p -V | dot -Tps -o#{root}/#{s}.ps"
+    else
+      sh "ragel -x #{RAGEL_PATH} -S#{s} | #{RAGEL_DOTGEN} -p|dot -Tps -o#{root}/#{s}.ps"
+    end
+  end
+end
+
+desc "Generate diagrams of ragel parser (png)"
+task :ragel_dot_png do
+  root = 'diagrams'
+  specs = []
+  File.new(RAGEL_PATH).grep(/^\s*machine\s*(\S+);\s*$/) { specs << $1 }
+  for s in specs
+    if RAGEL_DOTGEN == 'ragel'
+      sh "ragel #{RAGEL_PATH} -S#{s} -p -V | dot -Tpng -o#{root}/#{s}.png"
+    else
+      sh "ragel -x #{RAGEL_PATH} -S#{s} | #{RAGEL_DOTGEN} -p|dot -Tpng -o#{root}/#{s}.png"
+    end
+  end
+end
+
+desc "Generate diagrams of ragel parser"
+task :ragel_dot => [ :ragel_dot_png, :ragel_dot_ps ]
+
+desc "Build all gems and archives for a new release of json and json_pure."
+task :build => [ :clean, :gemspec, :package ]
+
+task :release => :build
+
+ +

end

+ +

desc “Compile in the the source directory” task :default => [ :clean, +:gemspec, :test ]

+
+ + + + + diff --git a/tmp/rdoc/Range.html b/tmp/rdoc/Range.html new file mode 100644 index 000000000..9ef4038fc --- /dev/null +++ b/tmp/rdoc/Range.html @@ -0,0 +1,241 @@ + + + + + + +class Range - RDoc Documentation + + + + + + + + + + + + + + +
+

+ class Range +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Class Methods

+
+ + +
+ +
+ json_create(object) + + click to toggle source + +
+ + +
+ +

Deserializes JSON string by constructing new Range object with arguments a serialized +by to_json.

+ + + + +
+
# File lib/json/add/range.rb, line 10
+def self.json_create(object)
+  new(*object['a'])
+end
+
+ +
+ + + + +
+ + +
+ +
+
+

Public Instance Methods

+
+ + +
+ +
+ as_json(*) + + click to toggle source + +
+ + +
+ +

Returns a hash, that will be turned into a JSON +object and represent this object.

+ + + + +
+
# File lib/json/add/range.rb, line 16
+def as_json(*)
+  {
+    JSON.create_id  => self.class.name,
+    'a'             => [ first, last, exclude_end? ]
+  }
+end
+
+ +
+ + + + +
+ + +
+ +
+ to_json(*args) + + click to toggle source + +
+ + +
+ +

Stores class name (Range) with JSON array of +arguments a which include first (integer), +last (integer), and exclude_end? (boolean) as JSON string.

+ + + + +
+
# File lib/json/add/range.rb, line 26
+def to_json(*args)
+  as_json.to_json(*args)
+end
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/Rational.html b/tmp/rdoc/Rational.html new file mode 100644 index 000000000..9eeab1383 --- /dev/null +++ b/tmp/rdoc/Rational.html @@ -0,0 +1,240 @@ + + + + + + +class Rational - RDoc Documentation + + + + + + + + + + + + + + +
+

+ class Rational +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Class Methods

+
+ + +
+ +
+ json_create(object) + + click to toggle source + +
+ + +
+ +

Deserializes JSON string by converting numerator +value n, denominator value d, to a Rational object.

+ + + + +
+
# File lib/json/add/rational.rb, line 10
+def self.json_create(object)
+  Rational(object['n'], object['d'])
+end
+
+ +
+ + + + +
+ + +
+ +
+
+

Public Instance Methods

+
+ + +
+ +
+ as_json(*) + + click to toggle source + +
+ + +
+ +

Returns a hash, that will be turned into a JSON +object and represent this object.

+ + + + +
+
# File lib/json/add/rational.rb, line 16
+def as_json(*)
+  {
+    JSON.create_id => self.class.name,
+    'n'            => numerator,
+    'd'            => denominator,
+  }
+end
+
+ +
+ + + + +
+ + +
+ +
+ to_json(*) + + click to toggle source + +
+ + +
+ +

Stores class name (Rational) along with numerator value n and +denominator value d as JSON string

+ + + + +
+
# File lib/json/add/rational.rb, line 25
+def to_json(*)
+  as_json.to_json
+end
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/Regexp.html b/tmp/rdoc/Regexp.html new file mode 100644 index 000000000..1c930d75a --- /dev/null +++ b/tmp/rdoc/Regexp.html @@ -0,0 +1,240 @@ + + + + + + +class Regexp - RDoc Documentation + + + + + + + + + + + + + + +
+

+ class Regexp +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Class Methods

+
+ + +
+ +
+ json_create(object) + + click to toggle source + +
+ + +
+ +

Deserializes JSON string by constructing new Regexp object with source s (Regexp or +String) and options o serialized by to_json

+ + + + +
+
# File lib/json/add/regexp.rb, line 11
+def self.json_create(object)
+  new(object['s'], object['o'])
+end
+
+ +
+ + + + +
+ + +
+ +
+
+

Public Instance Methods

+
+ + +
+ +
+ as_json(*) + + click to toggle source + +
+ + +
+ +

Returns a hash, that will be turned into a JSON +object and represent this object.

+ + + + +
+
# File lib/json/add/regexp.rb, line 17
+def as_json(*)
+  {
+    JSON.create_id => self.class.name,
+    'o'            => options,
+    's'            => source,
+  }
+end
+
+ +
+ + + + +
+ + +
+ +
+ to_json(*) + + click to toggle source + +
+ + +
+ +

Stores class name (Regexp) with options o and source +s (Regexp or String) as JSON string

+ + + + +
+
# File lib/json/add/regexp.rb, line 27
+def to_json(*)
+  as_json.to_json
+end
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/Set.html b/tmp/rdoc/Set.html new file mode 100644 index 000000000..dece7b815 --- /dev/null +++ b/tmp/rdoc/Set.html @@ -0,0 +1,239 @@ + + + + + + +class Set - RDoc Documentation + + + + + + + + + + + + + + +
+

+ class Set +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Class Methods

+
+ + +
+ +
+ json_create(object) + + click to toggle source + +
+ + +
+ +

Import a JSON Marshalled object.

+ +

method used for JSON marshalling support.

+ + + + +
+
# File lib/json/add/set.rb, line 10
+def self.json_create(object)
+  new object['a']
+end
+
+ +
+ + + + +
+ + +
+ +
+
+

Public Instance Methods

+
+ + +
+ +
+ as_json(*) + + click to toggle source + +
+ + +
+ +

Marshal the object to JSON.

+ +

method used for JSON marshalling support.

+ + + + +
+
# File lib/json/add/set.rb, line 17
+def as_json(*)
+  {
+    JSON.create_id => self.class.name,
+    'a'            => to_a,
+  }
+end
+
+ +
+ + + + +
+ + +
+ +
+ to_json(*args) + + click to toggle source + +
+ + +
+ +

return the JSON value

+ + + + +
+
# File lib/json/add/set.rb, line 25
+def to_json(*args)
+  as_json.to_json(*args)
+end
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/Struct.html b/tmp/rdoc/Struct.html new file mode 100644 index 000000000..e8e411e4c --- /dev/null +++ b/tmp/rdoc/Struct.html @@ -0,0 +1,242 @@ + + + + + + +class Struct - RDoc Documentation + + + + + + + + + + + + + + +
+

+ class Struct +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Class Methods

+
+ + +
+ +
+ json_create(object) + + click to toggle source + +
+ + +
+ +

Deserializes JSON string by constructing new Struct object with values v serialized +by to_json.

+ + + + +
+
# File lib/json/add/struct.rb, line 10
+def self.json_create(object)
+  new(*object['v'])
+end
+
+ +
+ + + + +
+ + +
+ +
+
+

Public Instance Methods

+
+ + +
+ +
+ as_json(*) + + click to toggle source + +
+ + +
+ +

Returns a hash, that will be turned into a JSON +object and represent this object.

+ + + + +
+
# File lib/json/add/struct.rb, line 16
+def as_json(*)
+  klass = self.class.name
+  klass.to_s.empty? and raise JSON::JSONError, "Only named structs are supported!"
+  {
+    JSON.create_id => klass,
+    'v'            => values,
+  }
+end
+
+ +
+ + + + +
+ + +
+ +
+ to_json(*args) + + click to toggle source + +
+ + +
+ +

Stores class name (Struct) with Struct values +v as a JSON string. Only named structs +are supported.

+ + + + +
+
# File lib/json/add/struct.rb, line 27
+def to_json(*args)
+  as_json.to_json(*args)
+end
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/Symbol.html b/tmp/rdoc/Symbol.html new file mode 100644 index 000000000..ffb2d811e --- /dev/null +++ b/tmp/rdoc/Symbol.html @@ -0,0 +1,239 @@ + + + + + + +class Symbol - RDoc Documentation + + + + + + + + + + + + + + +
+

+ class Symbol +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Class Methods

+
+ + +
+ +
+ json_create(o) + + click to toggle source + +
+ + +
+ +

Deserializes JSON string by converting the +string value stored in the object to a Symbol

+ + + + +
+
# File lib/json/add/symbol.rb, line 22
+def self.json_create(o)
+  o['s'].to_sym
+end
+
+ +
+ + + + +
+ + +
+ +
+
+

Public Instance Methods

+
+ + +
+ +
+ as_json(*) + + click to toggle source + +
+ + +
+ +

Returns a hash, that will be turned into a JSON +object and represent this object.

+ + + + +
+
# File lib/json/add/symbol.rb, line 9
+def as_json(*)
+  {
+    JSON.create_id => self.class.name,
+    's'            => to_s,
+  }
+end
+
+ +
+ + + + +
+ + +
+ +
+ to_json(*a) + + click to toggle source + +
+ + +
+ +

Stores class name (Symbol) with String representation of Symbol as a JSON string.

+ + + + +
+
# File lib/json/add/symbol.rb, line 17
+def to_json(*a)
+  as_json.to_json(*a)
+end
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/Time.html b/tmp/rdoc/Time.html new file mode 100644 index 000000000..1da51f65f --- /dev/null +++ b/tmp/rdoc/Time.html @@ -0,0 +1,250 @@ + + + + + + +class Time - RDoc Documentation + + + + + + + + + + + + + + +
+

+ class Time +

+ +
+ +
+ + + + +
+ + + + + + + + + +
+
+

Public Class Methods

+
+ + +
+ +
+ json_create(object) + + click to toggle source + +
+ + +
+ +

Deserializes JSON string by converting time since +epoch to Time

+ + + + +
+
# File lib/json/add/time.rb, line 9
+def self.json_create(object)
+  if usec = object.delete('u') # used to be tv_usec -> tv_nsec
+    object['n'] = usec * 1000
+  end
+  if method_defined?(:tv_nsec)
+    at(object['s'], Rational(object['n'], 1000))
+  else
+    at(object['s'], object['n'] / 1000)
+  end
+end
+
+ +
+ + + + +
+ + +
+ +
+
+

Public Instance Methods

+
+ + +
+ +
+ as_json(*) + + click to toggle source + +
+ + +
+ +

Returns a hash, that will be turned into a JSON +object and represent this object.

+ + + + +
+
# File lib/json/add/time.rb, line 22
+def as_json(*)
+  nanoseconds = [ tv_usec * 1000 ]
+  respond_to?(:tv_nsec) and nanoseconds << tv_nsec
+  nanoseconds = nanoseconds.max
+  {
+    JSON.create_id => self.class.name,
+    's'            => tv_sec,
+    'n'            => nanoseconds,
+  }
+end
+
+ +
+ + + + +
+ + +
+ +
+ to_json(*args) + + click to toggle source + +
+ + +
+ +

Stores class name (Time) with number of seconds since epoch and number of +microseconds for Time as JSON string

+ + + + +
+
# File lib/json/add/time.rb, line 35
+def to_json(*args)
+  as_json.to_json(*args)
+end
+
+ +
+ + + + +
+ + +
+ +
+
+ + + + diff --git a/tmp/rdoc/VERSION.html b/tmp/rdoc/VERSION.html new file mode 100644 index 000000000..c8a1e723f --- /dev/null +++ b/tmp/rdoc/VERSION.html @@ -0,0 +1,200 @@ + + + + + + +VERSION - RDoc Documentation + + + + + + + + + + + + + + +
+ +

2.1.0

+
+ + + + + diff --git a/tmp/rdoc/created.rid b/tmp/rdoc/created.rid new file mode 100644 index 000000000..f0619f358 --- /dev/null +++ b/tmp/rdoc/created.rid @@ -0,0 +1,34 @@ +Thu, 08 Mar 2018 20:31:11 +0200 +lib/json/pure.rb Thu, 08 Mar 2018 17:24:05 +0200 +lib/json/pure/parser.rb Thu, 08 Mar 2018 17:24:05 +0200 +lib/json/pure/generator.rb Thu, 08 Mar 2018 17:24:05 +0200 +lib/json/generic_object.rb Thu, 08 Mar 2018 17:24:05 +0200 +lib/json/common.rb Thu, 08 Mar 2018 20:18:41 +0200 +lib/json/version.rb Thu, 08 Mar 2018 17:24:05 +0200 +lib/json/add/exception.rb Thu, 08 Mar 2018 17:24:05 +0200 +lib/json/add/complex.rb Thu, 08 Mar 2018 17:24:05 +0200 +lib/json/add/range.rb Thu, 08 Mar 2018 17:24:05 +0200 +lib/json/add/set.rb Thu, 08 Mar 2018 17:24:05 +0200 +lib/json/add/struct.rb Thu, 08 Mar 2018 17:24:05 +0200 +lib/json/add/rational.rb Thu, 08 Mar 2018 17:24:05 +0200 +lib/json/add/ostruct.rb Thu, 08 Mar 2018 17:24:05 +0200 +lib/json/add/core.rb Thu, 08 Mar 2018 17:24:05 +0200 +lib/json/add/regexp.rb Thu, 08 Mar 2018 17:24:05 +0200 +lib/json/add/symbol.rb Thu, 08 Mar 2018 17:24:05 +0200 +lib/json/add/date_time.rb Thu, 08 Mar 2018 17:24:05 +0200 +lib/json/add/date.rb Thu, 08 Mar 2018 17:24:05 +0200 +lib/json/add/bigdecimal.rb Thu, 08 Mar 2018 17:24:05 +0200 +lib/json/add/time.rb Thu, 08 Mar 2018 17:24:05 +0200 +lib/json/ext.rb Thu, 08 Mar 2018 17:24:05 +0200 +lib/json.rb Thu, 08 Mar 2018 20:18:41 +0200 +ext/json/extconf.rb Thu, 08 Mar 2018 17:24:05 +0200 +ext/json/ext/fbuffer/fbuffer.h Thu, 08 Mar 2018 17:24:05 +0200 +ext/json/ext/generator/extconf.rb Thu, 08 Mar 2018 17:24:05 +0200 +ext/json/ext/generator/generator.h Thu, 08 Mar 2018 17:24:05 +0200 +ext/json/ext/generator/generator.c Thu, 08 Mar 2018 20:29:50 +0200 +ext/json/ext/generator/depend Thu, 08 Mar 2018 17:24:05 +0200 +ext/json/ext/parser/extconf.rb Thu, 08 Mar 2018 17:24:05 +0200 +ext/json/ext/parser/depend Thu, 08 Mar 2018 17:24:05 +0200 +ext/json/ext/parser/parser.c Thu, 08 Mar 2018 17:24:05 +0200 +ext/json/ext/parser/parser.h Thu, 08 Mar 2018 17:24:05 +0200 +ext/json/ext/parser/parser.rl Thu, 08 Mar 2018 17:24:05 +0200 diff --git a/tmp/rdoc/css/fonts.css b/tmp/rdoc/css/fonts.css new file mode 100644 index 000000000..57302b518 --- /dev/null +++ b/tmp/rdoc/css/fonts.css @@ -0,0 +1,167 @@ +/* + * Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), + * with Reserved Font Name "Source". All Rights Reserved. Source is a + * trademark of Adobe Systems Incorporated in the United States and/or other + * countries. + * + * This Font Software is licensed under the SIL Open Font License, Version + * 1.1. + * + * This license is copied below, and is also available with a FAQ at: + * http://scripts.sil.org/OFL + */ + +@font-face { + font-family: "Source Code Pro"; + font-style: normal; + font-weight: 400; + src: local("Source Code Pro"), + local("SourceCodePro-Regular"), + url("../fonts/SourceCodePro-Regular.ttf") format("truetype"); +} + +@font-face { + font-family: "Source Code Pro"; + font-style: normal; + font-weight: 700; + src: local("Source Code Pro Bold"), + local("SourceCodePro-Bold"), + url("../fonts/SourceCodePro-Bold.ttf") format("truetype"); +} + +/* + * Copyright (c) 2010, Łukasz Dziedzic (dziedzic@typoland.com), + * with Reserved Font Name Lato. + * + * This Font Software is licensed under the SIL Open Font License, Version + * 1.1. + * + * This license is copied below, and is also available with a FAQ at: + * http://scripts.sil.org/OFL + */ + +@font-face { + font-family: "Lato"; + font-style: normal; + font-weight: 300; + src: local("Lato Light"), + local("Lato-Light"), + url("../fonts/Lato-Light.ttf") format("truetype"); +} + +@font-face { + font-family: "Lato"; + font-style: italic; + font-weight: 300; + src: local("Lato Light Italic"), + local("Lato-LightItalic"), + url("../fonts/Lato-LightItalic.ttf") format("truetype"); +} + +@font-face { + font-family: "Lato"; + font-style: normal; + font-weight: 700; + src: local("Lato Regular"), + local("Lato-Regular"), + url("../fonts/Lato-Regular.ttf") format("truetype"); +} + +@font-face { + font-family: "Lato"; + font-style: italic; + font-weight: 700; + src: local("Lato Italic"), + local("Lato-Italic"), + url("../fonts/Lato-RegularItalic.ttf") format("truetype"); +} + +/* + * ----------------------------------------------------------- + * SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 + * ----------------------------------------------------------- + * + * PREAMBLE + * The goals of the Open Font License (OFL) are to stimulate worldwide + * development of collaborative font projects, to support the font creation + * efforts of academic and linguistic communities, and to provide a free and + * open framework in which fonts may be shared and improved in partnership + * with others. + * + * The OFL allows the licensed fonts to be used, studied, modified and + * redistributed freely as long as they are not sold by themselves. The + * fonts, including any derivative works, can be bundled, embedded, + * redistributed and/or sold with any software provided that any reserved + * names are not used by derivative works. The fonts and derivatives, + * however, cannot be released under any other type of license. The + * requirement for fonts to remain under this license does not apply + * to any document created using the fonts or their derivatives. + * + * DEFINITIONS + * "Font Software" refers to the set of files released by the Copyright + * Holder(s) under this license and clearly marked as such. This may + * include source files, build scripts and documentation. + * + * "Reserved Font Name" refers to any names specified as such after the + * copyright statement(s). + * + * "Original Version" refers to the collection of Font Software components as + * distributed by the Copyright Holder(s). + * + * "Modified Version" refers to any derivative made by adding to, deleting, + * or substituting -- in part or in whole -- any of the components of the + * Original Version, by changing formats or by porting the Font Software to a + * new environment. + * + * "Author" refers to any designer, engineer, programmer, technical + * writer or other person who contributed to the Font Software. + * + * PERMISSION & CONDITIONS + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of the Font Software, to use, study, copy, merge, embed, modify, + * redistribute, and sell modified and unmodified copies of the Font + * Software, subject to the following conditions: + * + * 1) Neither the Font Software nor any of its individual components, + * in Original or Modified Versions, may be sold by itself. + * + * 2) Original or Modified Versions of the Font Software may be bundled, + * redistributed and/or sold with any software, provided that each copy + * contains the above copyright notice and this license. These can be + * included either as stand-alone text files, human-readable headers or + * in the appropriate machine-readable metadata fields within text or + * binary files as long as those fields can be easily viewed by the user. + * + * 3) No Modified Version of the Font Software may use the Reserved Font + * Name(s) unless explicit written permission is granted by the corresponding + * Copyright Holder. This restriction only applies to the primary font name as + * presented to the users. + * + * 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font + * Software shall not be used to promote, endorse or advertise any + * Modified Version, except to acknowledge the contribution(s) of the + * Copyright Holder(s) and the Author(s) or with their explicit written + * permission. + * + * 5) The Font Software, modified or unmodified, in part or in whole, + * must be distributed entirely under this license, and must not be + * distributed under any other license. The requirement for fonts to + * remain under this license does not apply to any document created + * using the Font Software. + * + * TERMINATION + * This license becomes null and void if any of the above conditions are + * not met. + * + * DISCLAIMER + * THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT + * OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL + * DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM + * OTHER DEALINGS IN THE FONT SOFTWARE. + */ + diff --git a/tmp/rdoc/css/rdoc.css b/tmp/rdoc/css/rdoc.css new file mode 100644 index 000000000..2f4dca7e0 --- /dev/null +++ b/tmp/rdoc/css/rdoc.css @@ -0,0 +1,590 @@ +/* + * "Darkfish" Rdoc CSS + * $Id: rdoc.css 54 2009-01-27 01:09:48Z deveiant $ + * + * Author: Michael Granger + * + */ + +/* vim: ft=css et sw=2 ts=2 sts=2 */ +/* Base Green is: #6C8C22 */ + +* { padding: 0; margin: 0; } + +body { + background: #fafafa; + font-family: Lato, sans-serif; + font-weight: 300; +} + +h1 span, +h2 span, +h3 span, +h4 span, +h5 span, +h6 span { + position: relative; + + display: none; + padding-left: 1em; + line-height: 0; + vertical-align: baseline; + font-size: 10px; +} + +h1 span { top: -1.3em; } +h2 span { top: -1.2em; } +h3 span { top: -1.0em; } +h4 span { top: -0.8em; } +h5 span { top: -0.5em; } +h6 span { top: -0.5em; } + +h1:hover span, +h2:hover span, +h3:hover span, +h4:hover span, +h5:hover span, +h6:hover span { + display: inline; +} + +:link, +:visited { + color: #6C8C22; + text-decoration: none; +} + +:link:hover, +:visited:hover { + border-bottom: 1px dotted #6C8C22; +} + +code, +pre { + font-family: "Source Code Pro", Monaco, monospace; +} + +/* @group Generic Classes */ + +.initially-hidden { + display: none; +} + +#search-field { + width: 98%; + background: white; + border: none; + height: 1.5em; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + text-align: left; +} +#search-field:focus { + background: #f1edba; +} +#search-field:-moz-placeholder, +#search-field::-webkit-input-placeholder { + font-weight: bold; + color: #666; +} + +.missing-docs { + font-size: 120%; + background: white url(images/wrench_orange.png) no-repeat 4px center; + color: #ccc; + line-height: 2em; + border: 1px solid #d00; + opacity: 1; + padding-left: 20px; + text-indent: 24px; + letter-spacing: 3px; + font-weight: bold; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; +} + +.target-section { + border: 2px solid #dcce90; + border-left-width: 8px; + padding: 0 1em; + background: #fff3c2; +} + +/* @end */ + +/* @group Index Page, Standalone file pages */ +.table-of-contents ul { + margin: 1em; + list-style: none; +} + +.table-of-contents ul ul { + margin-top: 0.25em; +} + +.table-of-contents ul :link, +.table-of-contents ul :visited { + font-size: 16px; +} + +.table-of-contents li { + margin-bottom: 0.25em; +} + +.table-of-contents li .toc-toggle { + width: 16px; + height: 16px; + background: url(images/add.png) no-repeat; +} + +.table-of-contents li .toc-toggle.open { + background: url(images/delete.png) no-repeat; +} + +/* @end */ + +/* @group Top-Level Structure */ + +nav { + float: left; + width: 260px; + font-family: Helvetica, sans-serif; + font-size: 14px; +} + +main { + display: block; + margin: 0 2em 5em 260px; + padding-left: 20px; + min-width: 340px; + font-size: 16px; +} + +main h1, +main h2, +main h3, +main h4, +main h5, +main h6 { + font-family: Helvetica, sans-serif; +} + +.table-of-contents main { + margin-left: 2em; +} + +#validator-badges { + clear: both; + margin: 1em 1em 2em; + font-size: smaller; +} + +/* @end */ + +/* @group navigation */ +nav { + margin-bottom: 1em; +} + +nav .nav-section { + margin-top: 2em; + border-top: 2px solid #aaa; + font-size: 90%; + overflow: hidden; +} + +nav h2 { + margin: 0; + padding: 2px 8px 2px 8px; + background-color: #e8e8e8; + color: #555; + font-size: 125%; + text-align: center; +} + +nav h3, +#table-of-contents-navigation { + margin: 0; + padding: 2px 8px 2px 8px; + text-align: right; + background-color: #e8e8e8; + color: #555; +} + +nav ul, +nav dl, +nav p { + padding: 4px 8px 0; + list-style: none; +} + +#project-navigation .nav-section { + margin: 0; + border-top: 0; +} + +#home-section h2 { + text-align: center; +} + +#table-of-contents-navigation { + font-size: 1.2em; + font-weight: bold; + text-align: center; +} + +#search-section { + margin-top: 0; + border-top: 0; +} + +#search-field-wrapper { + border-top: 1px solid #aaa; + border-bottom: 1px solid #aaa; + padding: 3px 8px; + background-color: #e8e8e8; + color: #555; +} + +ul.link-list li { + white-space: nowrap; + line-height: 1.4em; +} + +ul.link-list .type { + font-size: 8px; + text-transform: uppercase; + color: white; + background: #969696; + padding: 2px 4px; + -webkit-border-radius: 5px; +} + +.calls-super { + background: url(images/arrow_up.png) no-repeat right center; +} + +/* @end */ + +/* @group Documentation Section */ +main { + color: #333; +} + +main > h1:first-child, +main > h2:first-child, +main > h3:first-child, +main > h4:first-child, +main > h5:first-child, +main > h6:first-child { + margin-top: 0px; +} + +main sup { + vertical-align: super; + font-size: 0.8em; +} + +/* The heading with the class name */ +main h1[class] { + margin-top: 0; + margin-bottom: 1em; + font-size: 2em; + color: #6C8C22; +} + +main h1 { + margin: 2em 0 0.5em; + font-size: 1.7em; +} + +main h2 { + margin: 2em 0 0.5em; + font-size: 1.5em; +} + +main h3 { + margin: 2em 0 0.5em; + font-size: 1.2em; +} + +main h4 { + margin: 2em 0 0.5em; + font-size: 1.1em; +} + +main h5 { + margin: 2em 0 0.5em; + font-size: 1em; +} + +main h6 { + margin: 2em 0 0.5em; + font-size: 1em; +} + +main p { + margin: 0 0 0.5em; + line-height: 1.4em; +} + +main pre { + margin: 1.2em 0.5em; + padding: 1em; + font-size: 0.8em; +} + +main hr { + margin: 1.5em 1em; + border: 2px solid #ddd; +} + +main blockquote { + margin: 0 2em 1.2em 1.2em; + padding-left: 0.5em; + border-left: 2px solid #ddd; +} + +main ol, +main ul { + margin: 1em 2em; +} + +main li > p { + margin-bottom: 0.5em; +} + +main dl { + margin: 1em 0.5em; +} + +main dt { + margin-bottom: 0.5em; + font-weight: bold; +} + +main dd { + margin: 0 1em 1em 0.5em; +} + +main header h2 { + margin-top: 2em; + border-width: 0; + border-top: 4px solid #bbb; + font-size: 130%; +} + +main header h3 { + margin: 2em 0 1.5em; + border-width: 0; + border-top: 3px solid #bbb; + font-size: 120%; +} + +.documentation-section-title { + position: relative; +} +.documentation-section-title .section-click-top { + position: absolute; + top: 6px; + left: 12px; + font-size: 10px; + color: #9b9877; + visibility: hidden; + padding-left: 0.5px; +} + +.documentation-section-title:hover .section-click-top { + visibility: visible; +} + +.constants-list > dl { + margin: 1em 0 2em; + border: 0; +} + +.constants-list > dl dt { + margin-bottom: 0.75em; + padding-left: 0; + font-family: "Source Code Pro", Monaco, monospace; + font-size: 110%; +} + +.constants-list > dl dt a { + color: inherit; +} + +.constants-list > dl dd { + margin: 0 0 2em 0; + padding: 0; + color: #666; +} + +.documentation-section h2 { + position: relative; +} + +.documentation-section h2 a { + position: absolute; + top: 8px; + right: 10px; + font-size: 12px; + color: #9b9877; + visibility: hidden; +} + +.documentation-section h2:hover a { + visibility: visible; +} + +/* @group Method Details */ + +main .method-source-code { + display: none; +} + +main .method-description .method-calls-super { + color: #333; + font-weight: bold; +} + +main .method-detail { + margin-bottom: 2.5em; + cursor: pointer; +} + +main .method-detail:target { + margin-left: -10px; + border-left: 10px solid #f1edba; +} + +main .method-heading { + position: relative; + font-family: "Source Code Pro", Monaco, monospace; + font-size: 110%; + font-weight: bold; + color: #333; +} +main .method-heading :link, +main .method-heading :visited { + color: inherit; +} +main .method-click-advice { + position: absolute; + top: 2px; + right: 5px; + font-size: 12px; + color: #9b9877; + visibility: hidden; + padding-right: 20px; + line-height: 20px; + background: url(images/zoom.png) no-repeat right top; +} +main .method-heading:hover .method-click-advice { + visibility: visible; +} + +main .method-alias .method-heading { + color: #666; +} + +main .method-description, +main .aliases { + margin-top: 0.75em; + color: #333; +} + +main .aliases { + padding-top: 4px; + font-style: italic; + cursor: default; +} +main .method-description ul { + margin-left: 1.5em; +} + +main #attribute-method-details .method-detail:hover { + background-color: transparent; + cursor: default; +} +main .attribute-access-type { + text-transform: uppercase; + padding: 0 1em; +} +/* @end */ + +/* @end */ + +/* @group Source Code */ + +pre { + margin: 0.5em 0; + border: 1px dashed #999; + padding: 0.5em; + background: #262626; + color: white; + overflow: auto; +} + +.ruby-constant { color: #7fffd4; background: transparent; } +.ruby-keyword { color: #00ffff; background: transparent; } +.ruby-ivar { color: #eedd82; background: transparent; } +.ruby-operator { color: #00ffee; background: transparent; } +.ruby-identifier { color: #ffdead; background: transparent; } +.ruby-node { color: #ffa07a; background: transparent; } +.ruby-comment { color: #dc0000; background: transparent; } +.ruby-regexp { color: #ffa07a; background: transparent; } +.ruby-value { color: #7fffd4; background: transparent; } + +/* @end */ + + +/* @group search results */ +#search-results { + font-family: Lato, sans-serif; + font-weight: 300; +} + +#search-results .search-match { + font-family: Helvetica, sans-serif; + font-weight: normal; +} + +#search-results .search-selected { + background: #e8e8e8; + border-bottom: 1px solid transparent; +} + +#search-results li { + list-style: none; + border-bottom: 1px solid #aaa; + margin-bottom: 0.5em; +} + +#search-results li:last-child { + border-bottom: none; + margin-bottom: 0; +} + +#search-results li p { + padding: 0; + margin: 0.5em; +} + +#search-results .search-namespace { + font-weight: bold; +} + +#search-results li em { + background: yellow; + font-style: normal; +} + +#search-results pre { + margin: 0.5em; + font-family: "Source Code Pro", Monaco, monospace; +} + +/* @end */ + diff --git a/tmp/rdoc/data/example_json.html b/tmp/rdoc/data/example_json.html new file mode 100644 index 000000000..4d8296e99 --- /dev/null +++ b/tmp/rdoc/data/example_json.html @@ -0,0 +1,202 @@ + + + + + + +example.json - RDoc Documentation + + + + + + + + + + + + + + +
+ +

{“a”:2,“b”:3.141,“TIME”:“2007-03-14T11:52:40”,“c”:“c”,“d”:,“COUNT”:666,“e”:{“foo”:“bar”},“foo”:“Bu00e4r”,“g”:“u677eu672cu884cu5f18”,“h”:1000.0,“bar”:“u00a9 +u2260 u20ac!”,“i”:0.001,“j”:“ud840udc01”}

+
+ + + + + diff --git a/tmp/rdoc/data/index_html.html b/tmp/rdoc/data/index_html.html new file mode 100644 index 000000000..f4d26b6c9 --- /dev/null +++ b/tmp/rdoc/data/index_html.html @@ -0,0 +1,243 @@ + + + + + + +index.html - RDoc Documentation + + + + + + + + + + + + + + +
+ +

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Strict//EN”

+ +
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+ +

<html xmlns=“www.w3.org/1999/xhtml” lang=“en” +xml:lang=“en”>

+ +
<head>
+  <title>Javascript Example</title>
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>    
+  <script src="prototype.js" type="text/javascript"></script>
+</head>
+
+<body>
+  <h1>Fetching object from server</h1>
+  <div id="list">
+    Wait...<br/>
+    <noscript><p>Switch on Javascript!</p></noscript>
+  </div>
+  <script type="text/javascript">
+  <!--
+  function pollJSON() {
+    new Ajax.Request('/json',
+      {
+        method: 'get',
+        onSuccess: function(transport) {
+          var response = transport.responseText || "no response text";
+          response = eval("(" + response + ")");
+          var text = "";
+          for (var k in response) {
+            text = text + "<b>" + k + "</b>: " + response[k] + "<br/>"
+          }
+          $("list").update(text);
+        },
+        onFailure: function() { alert('Something went wrong...') }
+      });
+  }
+  new PeriodicalExecuter(pollJSON, 1);
+  -->
+  </script>
+</body>
+ +

</html>

+
+ + + + + diff --git a/tmp/rdoc/data/prototype_js.html b/tmp/rdoc/data/prototype_js.html new file mode 100644 index 000000000..4f483f9a6 --- /dev/null +++ b/tmp/rdoc/data/prototype_js.html @@ -0,0 +1,4566 @@ + + + + + + +prototype.js - RDoc Documentation + + + + + + + + + + + + + + +
+ +
  Prototype JavaScript framework, version 1.6.0
+  (c) 2005-2007 Sam Stephenson
+
+  Prototype is freely distributable under the terms of an MIT-style license.
+  For details, see the Prototype web site: http://www.prototypejs.org/
+
+--------------------------------------------------------------------------
+ +

var Prototype = {

+ +
Version: '1.6.0',
+
+Browser: {
+  IE:     !!(window.attachEvent && !window.opera),
+  Opera:  !!window.opera,
+  WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1,
+  Gecko:  navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1,
+  MobileSafari: !!navigator.userAgent.match(/Apple.*Mobile.*Safari/)
+},
+
+BrowserFeatures: {
+  XPath: !!document.evaluate,
+  ElementExtensions: !!window.HTMLElement,
+  SpecificElementExtensions:
+    document.createElement('div').__proto__ &&
+    document.createElement('div').__proto__ !==
+      document.createElement('form').__proto__
+},
+
+ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script>',
+JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/,
+
+emptyFunction: function() { },
+K: function(x) { return x }
+ +

};

+ +

if (Prototype.Browser.MobileSafari)

+ +
Prototype.BrowserFeatures.SpecificElementExtensions = false;
+
+ +

if (Prototype.Browser.WebKit)

+ +
Prototype.BrowserFeatures.XPath = false;
+
+ Based on Alex Arnell's inheritance implementation.
+ +

var Class = {

+ +
create: function() {
+  var parent = null, properties = $A(arguments);
+  if (Object.isFunction(properties[0]))
+    parent = properties.shift();
+
+  function klass() {
+    this.initialize.apply(this, arguments);
+  }
+
+  Object.extend(klass, Class.Methods);
+  klass.superclass = parent;
+  klass.subclasses = [];
+
+  if (parent) {
+    var subclass = function() { };
+    subclass.prototype = parent.prototype;
+    klass.prototype = new subclass;
+    parent.subclasses.push(klass);
+  }
+
+  for (var i = 0; i < properties.length; i++)
+    klass.addMethods(properties[i]);
+
+  if (!klass.prototype.initialize)
+    klass.prototype.initialize = Prototype.emptyFunction;
+
+  klass.prototype.constructor = klass;
+
+  return klass;
+}
+ +

};

+ +

Class.Methods = {

+ +
addMethods: function(source) {
+  var ancestor   = this.superclass && this.superclass.prototype;
+  var properties = Object.keys(source);
+
+  if (!Object.keys({ toString: true }).length)
+    properties.push("toString", "valueOf");
+
+  for (var i = 0, length = properties.length; i < length; i++) {
+    var property = properties[i], value = source[property];
+    if (ancestor && Object.isFunction(value) &&
+        value.argumentNames().first() == "$super") {
+      var method = value, value = Object.extend((function(m) {
+        return function() { return ancestor[m].apply(this, arguments) };
+      })(property).wrap(method), {
+        valueOf:  function() { return method },
+        toString: function() { return method.toString() }
+      });
+    }
+    this.prototype[property] = value;
+  }
+
+  return this;
+}
+ +

};

+ +

var Abstract = { };

+ +

Object.extend = function(destination, source) {

+ +
for (var property in source)
+  destination[property] = source[property];
+return destination;
+ +

};

+ +

Object.extend(Object, {

+ +
inspect: function(object) {
+  try {
+    if (object === undefined) return 'undefined';
+    if (object === null) return 'null';
+    return object.inspect ? object.inspect() : object.toString();
+  } catch (e) {
+    if (e instanceof RangeError) return '...';
+    throw e;
+  }
+},
+
+toJSON: function(object) {
+  var type = typeof object;
+  switch (type) {
+    case 'undefined':
+    case 'function':
+    case 'unknown': return;
+    case 'boolean': return object.toString();
+  }
+
+  if (object === null) return 'null';
+  if (object.toJSON) return object.toJSON();
+  if (Object.isElement(object)) return;
+
+  var results = [];
+  for (var property in object) {
+    var value = Object.toJSON(object[property]);
+    if (value !== undefined)
+      results.push(property.toJSON() + ': ' + value);
+  }
+
+  return '{' + results.join(', ') + '}';
+},
+
+toQueryString: function(object) {
+  return $H(object).toQueryString();
+},
+
+toHTML: function(object) {
+  return object && object.toHTML ? object.toHTML() : String.interpret(object);
+},
+
+keys: function(object) {
+  var keys = [];
+  for (var property in object)
+    keys.push(property);
+  return keys;
+},
+
+values: function(object) {
+  var values = [];
+  for (var property in object)
+    values.push(object[property]);
+  return values;
+},
+
+clone: function(object) {
+  return Object.extend({ }, object);
+},
+
+isElement: function(object) {
+  return object && object.nodeType == 1;
+},
+
+isArray: function(object) {
+  return object && object.constructor === Array;
+},
+
+isHash: function(object) {
+  return object instanceof Hash;
+},
+
+isFunction: function(object) {
+  return typeof object == "function";
+},
+
+isString: function(object) {
+  return typeof object == "string";
+},
+
+isNumber: function(object) {
+  return typeof object == "number";
+},
+
+isUndefined: function(object) {
+  return typeof object == "undefined";
+}
+ +

});

+ +

Object.extend(Function.prototype, {

+ +
argumentNames: function() {
+  var names = this.toString().match(/^[\s\(]*function[^(]*\((.*?)\)/)[1].split(",").invoke("strip");
+  return names.length == 1 && !names[0] ? [] : names;
+},
+
+bind: function() {
+  if (arguments.length < 2 && arguments[0] === undefined) return this;
+  var __method = this, args = $A(arguments), object = args.shift();
+  return function() {
+    return __method.apply(object, args.concat($A(arguments)));
+  }
+},
+
+bindAsEventListener: function() {
+  var __method = this, args = $A(arguments), object = args.shift();
+  return function(event) {
+    return __method.apply(object, [event || window.event].concat(args));
+  }
+},
+
+curry: function() {
+  if (!arguments.length) return this;
+  var __method = this, args = $A(arguments);
+  return function() {
+    return __method.apply(this, args.concat($A(arguments)));
+  }
+},
+
+delay: function() {
+  var __method = this, args = $A(arguments), timeout = args.shift() * 1000;
+  return window.setTimeout(function() {
+    return __method.apply(__method, args);
+  }, timeout);
+},
+
+wrap: function(wrapper) {
+  var __method = this;
+  return function() {
+    return wrapper.apply(this, [__method.bind(this)].concat($A(arguments)));
+  }
+},
+
+methodize: function() {
+  if (this._methodized) return this._methodized;
+  var __method = this;
+  return this._methodized = function() {
+    return __method.apply(null, [this].concat($A(arguments)));
+  };
+}
+ +

});

+ +

Function.prototype.defer = Function.prototype.delay.curry(0.01);

+ +

Date.prototype.toJSON = function() {

+ +
return '"' + this.getUTCFullYear() + '-' +
+  (this.getUTCMonth() + 1).toPaddedString(2) + '-' +
+  this.getUTCDate().toPaddedString(2) + 'T' +
+  this.getUTCHours().toPaddedString(2) + ':' +
+  this.getUTCMinutes().toPaddedString(2) + ':' +
+  this.getUTCSeconds().toPaddedString(2) + 'Z"';
+
+ +

};

+ +

var Try = {

+ +
these: function() {
+  var returnValue;
+
+  for (var i = 0, length = arguments.length; i < length; i++) {
+    var lambda = arguments[i];
+    try {
+      returnValue = lambda();
+      break;
+    } catch (e) { }
+  }
+
+  return returnValue;
+}
+ +

};

+ +

RegExp.prototype.match = RegExp.prototype.test;

+ +

RegExp.escape = function(str) {

+ +
return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
+ +

};

+ +

/————————————————————————–/

+ +

var PeriodicalExecuter = Class.create({

+ +
initialize: function(callback, frequency) {
+  this.callback = callback;
+  this.frequency = frequency;
+  this.currentlyExecuting = false;
+
+  this.registerCallback();
+},
+
+registerCallback: function() {
+  this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
+},
+
+execute: function() {
+  this.callback(this);
+},
+
+stop: function() {
+  if (!this.timer) return;
+  clearInterval(this.timer);
+  this.timer = null;
+},
+
+onTimerEvent: function() {
+  if (!this.currentlyExecuting) {
+    try {
+      this.currentlyExecuting = true;
+      this.execute();
+    } finally {
+      this.currentlyExecuting = false;
+    }
+  }
+}
+ +

}); Object.extend(String, {

+ +
interpret: function(value) {
+  return value == null ? '' : String(value);
+},
+specialChar: {
+  '\b': '\\b',
+  '\t': '\\t',
+  '\n': '\\n',
+  '\f': '\\f',
+  '\r': '\\r',
+  '\\': '\\\\'
+}
+ +

});

+ +

Object.extend(String.prototype, {

+ +
gsub: function(pattern, replacement) {
+  var result = '', source = this, match;
+  replacement = arguments.callee.prepareReplacement(replacement);
+
+  while (source.length > 0) {
+    if (match = source.match(pattern)) {
+      result += source.slice(0, match.index);
+      result += String.interpret(replacement(match));
+      source  = source.slice(match.index + match[0].length);
+    } else {
+      result += source, source = '';
+    }
+  }
+  return result;
+},
+
+sub: function(pattern, replacement, count) {
+  replacement = this.gsub.prepareReplacement(replacement);
+  count = count === undefined ? 1 : count;
+
+  return this.gsub(pattern, function(match) {
+    if (--count < 0) return match[0];
+    return replacement(match);
+  });
+},
+
+scan: function(pattern, iterator) {
+  this.gsub(pattern, iterator);
+  return String(this);
+},
+
+truncate: function(length, truncation) {
+  length = length || 30;
+  truncation = truncation === undefined ? '...' : truncation;
+  return this.length > length ?
+    this.slice(0, length - truncation.length) + truncation : String(this);
+},
+
+strip: function() {
+  return this.replace(/^\s+/, '').replace(/\s+$/, '');
+},
+
+stripTags: function() {
+  return this.replace(/<\/?[^>]+>/gi, '');
+},
+
+stripScripts: function() {
+  return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
+},
+
+extractScripts: function() {
+  var matchAll = new RegExp(Prototype.ScriptFragment, 'img');
+  var matchOne = new RegExp(Prototype.ScriptFragment, 'im');
+  return (this.match(matchAll) || []).map(function(scriptTag) {
+    return (scriptTag.match(matchOne) || ['', ''])[1];
+  });
+},
+
+evalScripts: function() {
+  return this.extractScripts().map(function(script) { return eval(script) });
+},
+
+escapeHTML: function() {
+  var self = arguments.callee;
+  self.text.data = this;
+  return self.div.innerHTML;
+},
+
+unescapeHTML: function() {
+  var div = new Element('div');
+  div.innerHTML = this.stripTags();
+  return div.childNodes[0] ? (div.childNodes.length > 1 ?
+    $A(div.childNodes).inject('', function(memo, node) { return memo+node.nodeValue }) :
+    div.childNodes[0].nodeValue) : '';
+},
+
+toQueryParams: function(separator) {
+  var match = this.strip().match(/([^?#]*)(#.*)?$/);
+  if (!match) return { };
+
+  return match[1].split(separator || '&').inject({ }, function(hash, pair) {
+    if ((pair = pair.split('='))[0]) {
+      var key = decodeURIComponent(pair.shift());
+      var value = pair.length > 1 ? pair.join('=') : pair[0];
+      if (value != undefined) value = decodeURIComponent(value);
+
+      if (key in hash) {
+        if (!Object.isArray(hash[key])) hash[key] = [hash[key]];
+        hash[key].push(value);
+      }
+      else hash[key] = value;
+    }
+    return hash;
+  });
+},
+
+toArray: function() {
+  return this.split('');
+},
+
+succ: function() {
+  return this.slice(0, this.length - 1) +
+    String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
+},
+
+times: function(count) {
+  return count < 1 ? '' : new Array(count + 1).join(this);
+},
+
+camelize: function() {
+  var parts = this.split('-'), len = parts.length;
+  if (len == 1) return parts[0];
+
+  var camelized = this.charAt(0) == '-'
+    ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1)
+    : parts[0];
+
+  for (var i = 1; i < len; i++)
+    camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1);
+
+  return camelized;
+},
+
+capitalize: function() {
+  return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
+},
+
+underscore: function() {
+  return this.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'#{1}_#{2}').gsub(/([a-z\d])([A-Z])/,'#{1}_#{2}').gsub(/-/,'_').toLowerCase();
+},
+
+dasherize: function() {
+  return this.gsub(/_/,'-');
+},
+
+inspect: function(useDoubleQuotes) {
+  var escapedString = this.gsub(/[\x00-\x1f\\]/, function(match) {
+    var character = String.specialChar[match[0]];
+    return character ? character : '\\u00' + match[0].charCodeAt().toPaddedString(2, 16);
+  });
+  if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"';
+  return "'" + escapedString.replace(/'/g, '\\\'') + "'";
+},
+
+toJSON: function() {
+  return this.inspect(true);
+},
+
+unfilterJSON: function(filter) {
+  return this.sub(filter || Prototype.JSONFilter, '#{1}');
+},
+
+isJSON: function() {
+  var str = this.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, '');
+  return (/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(str);
+},
+
+evalJSON: function(sanitize) {
+  var json = this.unfilterJSON();
+  try {
+    if (!sanitize || json.isJSON()) return eval('(' + json + ')');
+  } catch (e) { }
+  throw new SyntaxError('Badly formed JSON string: ' + this.inspect());
+},
+
+include: function(pattern) {
+  return this.indexOf(pattern) > -1;
+},
+
+startsWith: function(pattern) {
+  return this.indexOf(pattern) === 0;
+},
+
+endsWith: function(pattern) {
+  var d = this.length - pattern.length;
+  return d >= 0 && this.lastIndexOf(pattern) === d;
+},
+
+empty: function() {
+  return this == '';
+},
+
+blank: function() {
+  return /^\s*$/.test(this);
+},
+
+interpolate: function(object, pattern) {
+  return new Template(this, pattern).evaluate(object);
+}
+ +

});

+ +

if (Prototype.Browser.WebKit || Prototype.Browser.IE) +Object.extend(String.prototype, {

+ +
escapeHTML: function() {
+  return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
+},
+unescapeHTML: function() {
+  return this.replace(/&amp;/g,'&').replace(/&lt;/g,'<').replace(/&gt;/g,'>');
+}
+ +

});

+ +

String.prototype.gsub.prepareReplacement = function(replacement) {

+ +
if (Object.isFunction(replacement)) return replacement;
+var template = new Template(replacement);
+return function(match) { return template.evaluate(match) };
+ +

};

+ +

String.prototype.parseQuery = String.prototype.toQueryParams;

+ +

Object.extend(String.prototype.escapeHTML, {

+ +
div:  document.createElement('div'),
+text: document.createTextNode('')
+ +

});

+ +

with (String.prototype.escapeHTML) div.appendChild(text);

+ +

var Template = Class.create({

+ +
initialize: function(template, pattern) {
+  this.template = template.toString();
+  this.pattern = pattern || Template.Pattern;
+},
+
+evaluate: function(object) {
+  if (Object.isFunction(object.toTemplateReplacements))
+    object = object.toTemplateReplacements();
+
+  return this.template.gsub(this.pattern, function(match) {
+    if (object == null) return '';
+
+    var before = match[1] || '';
+    if (before == '\\') return match[2];
+
+    var ctx = object, expr = match[3];
+    var pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/, match = pattern.exec(expr);
+    if (match == null) return before;
+
+    while (match != null) {
+      var comp = match[1].startsWith('[') ? match[2].gsub('\\\\]', ']') : match[1];
+      ctx = ctx[comp];
+      if (null == ctx || '' == match[3]) break;
+      expr = expr.substring('[' == match[3] ? match[1].length : match[0].length);
+      match = pattern.exec(expr);
+    }
+
+    return before + String.interpret(ctx);
+  }.bind(this));
+}
+ +

}); Template.Pattern = /(^|.|r|n)(#{(.*?)})/;

+ +

var $break = { };

+ +

var Enumerable = {

+ +
each: function(iterator, context) {
+  var index = 0;
+  iterator = iterator.bind(context);
+  try {
+    this._each(function(value) {
+      iterator(value, index++);
+    });
+  } catch (e) {
+    if (e != $break) throw e;
+  }
+  return this;
+},
+
+eachSlice: function(number, iterator, context) {
+  iterator = iterator ? iterator.bind(context) : Prototype.K;
+  var index = -number, slices = [], array = this.toArray();
+  while ((index += number) < array.length)
+    slices.push(array.slice(index, index+number));
+  return slices.collect(iterator, context);
+},
+
+all: function(iterator, context) {
+  iterator = iterator ? iterator.bind(context) : Prototype.K;
+  var result = true;
+  this.each(function(value, index) {
+    result = result && !!iterator(value, index);
+    if (!result) throw $break;
+  });
+  return result;
+},
+
+any: function(iterator, context) {
+  iterator = iterator ? iterator.bind(context) : Prototype.K;
+  var result = false;
+  this.each(function(value, index) {
+    if (result = !!iterator(value, index))
+      throw $break;
+  });
+  return result;
+},
+
+collect: function(iterator, context) {
+  iterator = iterator ? iterator.bind(context) : Prototype.K;
+  var results = [];
+  this.each(function(value, index) {
+    results.push(iterator(value, index));
+  });
+  return results;
+},
+
+detect: function(iterator, context) {
+  iterator = iterator.bind(context);
+  var result;
+  this.each(function(value, index) {
+    if (iterator(value, index)) {
+      result = value;
+      throw $break;
+    }
+  });
+  return result;
+},
+
+findAll: function(iterator, context) {
+  iterator = iterator.bind(context);
+  var results = [];
+  this.each(function(value, index) {
+    if (iterator(value, index))
+      results.push(value);
+  });
+  return results;
+},
+
+grep: function(filter, iterator, context) {
+  iterator = iterator ? iterator.bind(context) : Prototype.K;
+  var results = [];
+
+  if (Object.isString(filter))
+    filter = new RegExp(filter);
+
+  this.each(function(value, index) {
+    if (filter.match(value))
+      results.push(iterator(value, index));
+  });
+  return results;
+},
+
+include: function(object) {
+  if (Object.isFunction(this.indexOf))
+    if (this.indexOf(object) != -1) return true;
+
+  var found = false;
+  this.each(function(value) {
+    if (value == object) {
+      found = true;
+      throw $break;
+    }
+  });
+  return found;
+},
+
+inGroupsOf: function(number, fillWith) {
+  fillWith = fillWith === undefined ? null : fillWith;
+  return this.eachSlice(number, function(slice) {
+    while(slice.length < number) slice.push(fillWith);
+    return slice;
+  });
+},
+
+inject: function(memo, iterator, context) {
+  iterator = iterator.bind(context);
+  this.each(function(value, index) {
+    memo = iterator(memo, value, index);
+  });
+  return memo;
+},
+
+invoke: function(method) {
+  var args = $A(arguments).slice(1);
+  return this.map(function(value) {
+    return value[method].apply(value, args);
+  });
+},
+
+max: function(iterator, context) {
+  iterator = iterator ? iterator.bind(context) : Prototype.K;
+  var result;
+  this.each(function(value, index) {
+    value = iterator(value, index);
+    if (result == undefined || value >= result)
+      result = value;
+  });
+  return result;
+},
+
+min: function(iterator, context) {
+  iterator = iterator ? iterator.bind(context) : Prototype.K;
+  var result;
+  this.each(function(value, index) {
+    value = iterator(value, index);
+    if (result == undefined || value < result)
+      result = value;
+  });
+  return result;
+},
+
+partition: function(iterator, context) {
+  iterator = iterator ? iterator.bind(context) : Prototype.K;
+  var trues = [], falses = [];
+  this.each(function(value, index) {
+    (iterator(value, index) ?
+      trues : falses).push(value);
+  });
+  return [trues, falses];
+},
+
+pluck: function(property) {
+  var results = [];
+  this.each(function(value) {
+    results.push(value[property]);
+  });
+  return results;
+},
+
+reject: function(iterator, context) {
+  iterator = iterator.bind(context);
+  var results = [];
+  this.each(function(value, index) {
+    if (!iterator(value, index))
+      results.push(value);
+  });
+  return results;
+},
+
+sortBy: function(iterator, context) {
+  iterator = iterator.bind(context);
+  return this.map(function(value, index) {
+    return {value: value, criteria: iterator(value, index)};
+  }).sort(function(left, right) {
+    var a = left.criteria, b = right.criteria;
+    return a < b ? -1 : a > b ? 1 : 0;
+  }).pluck('value');
+},
+
+toArray: function() {
+  return this.map();
+},
+
+zip: function() {
+  var iterator = Prototype.K, args = $A(arguments);
+  if (Object.isFunction(args.last()))
+    iterator = args.pop();
+
+  var collections = [this].concat(args).map($A);
+  return this.map(function(value, index) {
+    return iterator(collections.pluck(index));
+  });
+},
+
+size: function() {
+  return this.toArray().length;
+},
+
+inspect: function() {
+  return '#<Enumerable:' + this.toArray().inspect() + '>';
+}
+ +

};

+ +

Object.extend(Enumerable, {

+ +
map:     Enumerable.collect,
+find:    Enumerable.detect,
+select:  Enumerable.findAll,
+filter:  Enumerable.findAll,
+member:  Enumerable.include,
+entries: Enumerable.toArray,
+every:   Enumerable.all,
+some:    Enumerable.any
+ +

}); function $A(iterable) {

+ +
if (!iterable) return [];
+if (iterable.toArray) return iterable.toArray();
+var length = iterable.length, results = new Array(length);
+while (length--) results[length] = iterable[length];
+return results;
+ +

}

+ +

if (Prototype.Browser.WebKit) {

+ +
function $A(iterable) {
+  if (!iterable) return [];
+  if (!(Object.isFunction(iterable) && iterable == '[object NodeList]') &&
+      iterable.toArray) return iterable.toArray();
+  var length = iterable.length, results = new Array(length);
+  while (length--) results[length] = iterable[length];
+  return results;
+}
+ +

}

+ +

Array.from = $A;

+ +

Object.extend(Array.prototype, Enumerable);

+ +

if (!Array.prototype._reverse) Array.prototype._reverse = +Array.prototype.reverse;

+ +

Object.extend(Array.prototype, {

+ +
_each: function(iterator) {
+  for (var i = 0, length = this.length; i < length; i++)
+    iterator(this[i]);
+},
+
+clear: function() {
+  this.length = 0;
+  return this;
+},
+
+first: function() {
+  return this[0];
+},
+
+last: function() {
+  return this[this.length - 1];
+},
+
+compact: function() {
+  return this.select(function(value) {
+    return value != null;
+  });
+},
+
+flatten: function() {
+  return this.inject([], function(array, value) {
+    return array.concat(Object.isArray(value) ?
+      value.flatten() : [value]);
+  });
+},
+
+without: function() {
+  var values = $A(arguments);
+  return this.select(function(value) {
+    return !values.include(value);
+  });
+},
+
+reverse: function(inline) {
+  return (inline !== false ? this : this.toArray())._reverse();
+},
+
+reduce: function() {
+  return this.length > 1 ? this : this[0];
+},
+
+uniq: function(sorted) {
+  return this.inject([], function(array, value, index) {
+    if (0 == index || (sorted ? array.last() != value : !array.include(value)))
+      array.push(value);
+    return array;
+  });
+},
+
+intersect: function(array) {
+  return this.uniq().findAll(function(item) {
+    return array.detect(function(value) { return item === value });
+  });
+},
+
+clone: function() {
+  return [].concat(this);
+},
+
+size: function() {
+  return this.length;
+},
+
+inspect: function() {
+  return '[' + this.map(Object.inspect).join(', ') + ']';
+},
+
+toJSON: function() {
+  var results = [];
+  this.each(function(object) {
+    var value = Object.toJSON(object);
+    if (value !== undefined) results.push(value);
+  });
+  return '[' + results.join(', ') + ']';
+}
+ +

});

+ +

// use native browser JS 1.6 implementation if available if +(Object.isFunction(Array.prototype.forEach))

+ +
Array.prototype._each = Array.prototype.forEach;
+
+ +

if (!Array.prototype.indexOf) Array.prototype.indexOf = function(item, i) {

+ +
i || (i = 0);
+var length = this.length;
+if (i < 0) i = length + i;
+for (; i < length; i++)
+  if (this[i] === item) return i;
+return -1;
+ +

};

+ +

if (!Array.prototype.lastIndexOf) Array.prototype.lastIndexOf = +function(item, i) {

+ +
i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1;
+var n = this.slice(0, i).reverse().indexOf(item);
+return (n < 0) ? n : i - n - 1;
+
+ +

};

+ +

Array.prototype.toArray = Array.prototype.clone;

+ +

function $w(string) {

+ +
if (!Object.isString(string)) return [];
+string = string.strip();
+return string ? string.split(/\s+/) : [];
+ +

}

+ +

if (Prototype.Browser.Opera){

+ +
Array.prototype.concat = function() {
+  var array = [];
+  for (var i = 0, length = this.length; i < length; i++) array.push(this[i]);
+  for (var i = 0, length = arguments.length; i < length; i++) {
+    if (Object.isArray(arguments[i])) {
+      for (var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++)
+        array.push(arguments[i][j]);
+    } else {
+      array.push(arguments[i]);
+    }
+  }
+  return array;
+};
+ +

} Object.extend(Number.prototype, {

+ +
toColorPart: function() {
+  return this.toPaddedString(2, 16);
+},
+
+succ: function() {
+  return this + 1;
+},
+
+times: function(iterator) {
+  $R(0, this, true).each(iterator);
+  return this;
+},
+
+toPaddedString: function(length, radix) {
+  var string = this.toString(radix || 10);
+  return '0'.times(length - string.length) + string;
+},
+
+toJSON: function() {
+  return isFinite(this) ? this.toString() : 'null';
+}
+ +

});

+ +

$w('abs round ceil floor').each(function(method){

+ +
Number.prototype[method] = Math[method].methodize();
+
+ +

}); function $H(object) {

+ +
return new Hash(object);
+
+ +

};

+ +

var Hash = Class.create(Enumerable, (function() {

+ +
if (function() {
+  var i = 0, Test = function(value) { this.key = value };
+  Test.prototype.key = 'foo';
+  for (var property in new Test('bar')) i++;
+  return i > 1;
+}()) {
+  function each(iterator) {
+    var cache = [];
+    for (var key in this._object) {
+      var value = this._object[key];
+      if (cache.include(key)) continue;
+      cache.push(key);
+      var pair = [key, value];
+      pair.key = key;
+      pair.value = value;
+      iterator(pair);
+    }
+  }
+} else {
+  function each(iterator) {
+    for (var key in this._object) {
+      var value = this._object[key], pair = [key, value];
+      pair.key = key;
+      pair.value = value;
+      iterator(pair);
+    }
+  }
+}
+
+function toQueryPair(key, value) {
+  if (Object.isUndefined(value)) return key;
+  return key + '=' + encodeURIComponent(String.interpret(value));
+}
+
+return {
+  initialize: function(object) {
+    this._object = Object.isHash(object) ? object.toObject() : Object.clone(object);
+  },
+
+  _each: each,
+
+  set: function(key, value) {
+    return this._object[key] = value;
+  },
+
+  get: function(key) {
+    return this._object[key];
+  },
+
+  unset: function(key) {
+    var value = this._object[key];
+    delete this._object[key];
+    return value;
+  },
+
+  toObject: function() {
+    return Object.clone(this._object);
+  },
+
+  keys: function() {
+    return this.pluck('key');
+  },
+
+  values: function() {
+    return this.pluck('value');
+  },
+
+  index: function(value) {
+    var match = this.detect(function(pair) {
+      return pair.value === value;
+    });
+    return match && match.key;
+  },
+
+  merge: function(object) {
+    return this.clone().update(object);
+  },
+
+  update: function(object) {
+    return new Hash(object).inject(this, function(result, pair) {
+      result.set(pair.key, pair.value);
+      return result;
+    });
+  },
+
+  toQueryString: function() {
+    return this.map(function(pair) {
+      var key = encodeURIComponent(pair.key), values = pair.value;
+
+      if (values && typeof values == 'object') {
+        if (Object.isArray(values))
+          return values.map(toQueryPair.curry(key)).join('&');
+      }
+      return toQueryPair(key, values);
+    }).join('&');
+  },
+
+  inspect: function() {
+    return '#<Hash:{' + this.map(function(pair) {
+      return pair.map(Object.inspect).join(': ');
+    }).join(', ') + '}>';
+  },
+
+  toJSON: function() {
+    return Object.toJSON(this.toObject());
+  },
+
+  clone: function() {
+    return new Hash(this);
+  }
+}
+ +

})());

+ +

Hash.prototype.toTemplateReplacements = Hash.prototype.toObject; Hash.from += $H; var ObjectRange = Class.create(Enumerable, {

+ +
initialize: function(start, end, exclusive) {
+  this.start = start;
+  this.end = end;
+  this.exclusive = exclusive;
+},
+
+_each: function(iterator) {
+  var value = this.start;
+  while (this.include(value)) {
+    iterator(value);
+    value = value.succ();
+  }
+},
+
+include: function(value) {
+  if (value < this.start)
+    return false;
+  if (this.exclusive)
+    return value < this.end;
+  return value <= this.end;
+}
+ +

});

+ +

var $R = function(start, end, exclusive) {

+ +
return new ObjectRange(start, end, exclusive);
+ +

};

+ +

var Ajax = {

+ +
getTransport: function() {
+  return Try.these(
+    function() {return new XMLHttpRequest()},
+    function() {return new ActiveXObject('Msxml2.XMLHTTP')},
+    function() {return new ActiveXObject('Microsoft.XMLHTTP')}
+  ) || false;
+},
+
+activeRequestCount: 0
+ +

};

+ +

Ajax.Responders = {

+ +
responders: [],
+
+_each: function(iterator) {
+  this.responders._each(iterator);
+},
+
+register: function(responder) {
+  if (!this.include(responder))
+    this.responders.push(responder);
+},
+
+unregister: function(responder) {
+  this.responders = this.responders.without(responder);
+},
+
+dispatch: function(callback, request, transport, json) {
+  this.each(function(responder) {
+    if (Object.isFunction(responder[callback])) {
+      try {
+        responder[callback].apply(responder, [request, transport, json]);
+      } catch (e) { }
+    }
+  });
+}
+ +

};

+ +

Object.extend(Ajax.Responders, Enumerable);

+ +

Ajax.Responders.register({

+ +
onCreate:   function() { Ajax.activeRequestCount++ },
+onComplete: function() { Ajax.activeRequestCount-- }
+ +

});

+ +

Ajax.Base = Class.create({

+ +
initialize: function(options) {
+  this.options = {
+    method:       'post',
+    asynchronous: true,
+    contentType:  'application/x-www-form-urlencoded',
+    encoding:     'UTF-8',
+    parameters:   '',
+    evalJSON:     true,
+    evalJS:       true
+  };
+  Object.extend(this.options, options || { });
+
+  this.options.method = this.options.method.toLowerCase();
+  if (Object.isString(this.options.parameters))
+    this.options.parameters = this.options.parameters.toQueryParams();
+}
+ +

});

+ +

Ajax.Request = Class.create(Ajax.Base, {

+ +
_complete: false,
+
+initialize: function($super, url, options) {
+  $super(options);
+  this.transport = Ajax.getTransport();
+  this.request(url);
+},
+
+request: function(url) {
+  this.url = url;
+  this.method = this.options.method;
+  var params = Object.clone(this.options.parameters);
+
+  if (!['get', 'post'].include(this.method)) {
+    // simulate other verbs over post
+    params['_method'] = this.method;
+    this.method = 'post';
+  }
+
+  this.parameters = params;
+
+  if (params = Object.toQueryString(params)) {
+    // when GET, append parameters to URL
+    if (this.method == 'get')
+      this.url += (this.url.include('?') ? '&' : '?') + params;
+    else if (/Konqueror|Safari|KHTML/.test(navigator.userAgent))
+      params += '&_=';
+  }
+
+  try {
+    var response = new Ajax.Response(this);
+    if (this.options.onCreate) this.options.onCreate(response);
+    Ajax.Responders.dispatch('onCreate', this, response);
+
+    this.transport.open(this.method.toUpperCase(), this.url,
+      this.options.asynchronous);
+
+    if (this.options.asynchronous) this.respondToReadyState.bind(this).defer(1);
+
+    this.transport.onreadystatechange = this.onStateChange.bind(this);
+    this.setRequestHeaders();
+
+    this.body = this.method == 'post' ? (this.options.postBody || params) : null;
+    this.transport.send(this.body);
+
+    /* Force Firefox to handle ready state 4 for synchronous requests */
+    if (!this.options.asynchronous && this.transport.overrideMimeType)
+      this.onStateChange();
+
+  }
+  catch (e) {
+    this.dispatchException(e);
+  }
+},
+
+onStateChange: function() {
+  var readyState = this.transport.readyState;
+  if (readyState > 1 && !((readyState == 4) && this._complete))
+    this.respondToReadyState(this.transport.readyState);
+},
+
+setRequestHeaders: function() {
+  var headers = {
+    'X-Requested-With': 'XMLHttpRequest',
+    'X-Prototype-Version': Prototype.Version,
+    'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
+  };
+
+  if (this.method == 'post') {
+    headers['Content-type'] = this.options.contentType +
+      (this.options.encoding ? '; charset=' + this.options.encoding : '');
+
+    /* Force "Connection: close" for older Mozilla browsers to work
+       around a bug where XMLHttpRequest sends an incorrect
+       Content-length header. See Mozilla Bugzilla #246651.
+      /
+    if (this.transport.overrideMimeType &&
+        (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005)
+          headers['Connection'] = 'close';
+  }
+
+  // user-defined headers
+  if (typeof this.options.requestHeaders == 'object') {
+    var extras = this.options.requestHeaders;
+
+    if (Object.isFunction(extras.push))
+      for (var i = 0, length = extras.length; i < length; i += 2)
+        headers[extras[i]] = extras[i+1];
+    else
+      $H(extras).each(function(pair) { headers[pair.key] = pair.value });
+  }
+
+  for (var name in headers)
+    this.transport.setRequestHeader(name, headers[name]);
+},
+
+success: function() {
+  var status = this.getStatus();
+  return !status || (status >= 200 && status < 300);
+},
+
+getStatus: function() {
+  try {
+    return this.transport.status || 0;
+  } catch (e) { return 0 }
+},
+
+respondToReadyState: function(readyState) {
+  var state = Ajax.Request.Events[readyState], response = new Ajax.Response(this);
+
+  if (state == 'Complete') {
+    try {
+      this._complete = true;
+      (this.options['on' + response.status]
+       || this.options['on' + (this.success() ? 'Success' : 'Failure')]
+       || Prototype.emptyFunction)(response, response.headerJSON);
+    } catch (e) {
+      this.dispatchException(e);
+    }
+
+    var contentType = response.getHeader('Content-type');
+    if (this.options.evalJS == 'force'
+        || (this.options.evalJS && contentType
+        && contentType.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i)))
+      this.evalResponse();
+  }
+
+  try {
+    (this.options['on' + state] || Prototype.emptyFunction)(response, response.headerJSON);
+    Ajax.Responders.dispatch('on' + state, this, response, response.headerJSON);
+  } catch (e) {
+    this.dispatchException(e);
+  }
+
+  if (state == 'Complete') {
+    // avoid memory leak in MSIE: clean up
+    this.transport.onreadystatechange = Prototype.emptyFunction;
+  }
+},
+
+getHeader: function(name) {
+  try {
+    return this.transport.getResponseHeader(name);
+  } catch (e) { return null }
+},
+
+evalResponse: function() {
+  try {
+    return eval((this.transport.responseText || '').unfilterJSON());
+  } catch (e) {
+    this.dispatchException(e);
+  }
+},
+
+dispatchException: function(exception) {
+  (this.options.onException || Prototype.emptyFunction)(this, exception);
+  Ajax.Responders.dispatch('onException', this, exception);
+}
+ +

});

+ +

Ajax.Request.Events =

+ +
['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
+
+ +

Ajax.Response = Class.create({

+ +
initialize: function(request){
+  this.request = request;
+  var transport  = this.transport  = request.transport,
+      readyState = this.readyState = transport.readyState;
+
+  if((readyState > 2 && !Prototype.Browser.IE) || readyState == 4) {
+    this.status       = this.getStatus();
+    this.statusText   = this.getStatusText();
+    this.responseText = String.interpret(transport.responseText);
+    this.headerJSON   = this._getHeaderJSON();
+  }
+
+  if(readyState == 4) {
+    var xml = transport.responseXML;
+    this.responseXML  = xml === undefined ? null : xml;
+    this.responseJSON = this._getResponseJSON();
+  }
+},
+
+status:      0,
+statusText: '',
+
+getStatus: Ajax.Request.prototype.getStatus,
+
+getStatusText: function() {
+  try {
+    return this.transport.statusText || '';
+  } catch (e) { return '' }
+},
+
+getHeader: Ajax.Request.prototype.getHeader,
+
+getAllHeaders: function() {
+  try {
+    return this.getAllResponseHeaders();
+  } catch (e) { return null }
+},
+
+getResponseHeader: function(name) {
+  return this.transport.getResponseHeader(name);
+},
+
+getAllResponseHeaders: function() {
+  return this.transport.getAllResponseHeaders();
+},
+
+_getHeaderJSON: function() {
+  var json = this.getHeader('X-JSON');
+  if (!json) return null;
+  json = decodeURIComponent(escape(json));
+  try {
+    return json.evalJSON(this.request.options.sanitizeJSON);
+  } catch (e) {
+    this.request.dispatchException(e);
+  }
+},
+
+_getResponseJSON: function() {
+  var options = this.request.options;
+  if (!options.evalJSON || (options.evalJSON != 'force' &&
+    !(this.getHeader('Content-type') || '').include('application/json')))
+      return null;
+  try {
+    return this.transport.responseText.evalJSON(options.sanitizeJSON);
+  } catch (e) {
+    this.request.dispatchException(e);
+  }
+}
+ +

});

+ +

Ajax.Updater = Class.create(Ajax.Request, {

+ +
initialize: function($super, container, url, options) {
+  this.container = {
+    success: (container.success || container),
+    failure: (container.failure || (container.success ? null : container))
+  };
+
+  options = options || { };
+  var onComplete = options.onComplete;
+  options.onComplete = (function(response, param) {
+    this.updateContent(response.responseText);
+    if (Object.isFunction(onComplete)) onComplete(response, param);
+  }).bind(this);
+
+  $super(url, options);
+},
+
+updateContent: function(responseText) {
+  var receiver = this.container[this.success() ? 'success' : 'failure'],
+      options = this.options;
+
+  if (!options.evalScripts) responseText = responseText.stripScripts();
+
+  if (receiver = $(receiver)) {
+    if (options.insertion) {
+      if (Object.isString(options.insertion)) {
+        var insertion = { }; insertion[options.insertion] = responseText;
+        receiver.insert(insertion);
+      }
+      else options.insertion(receiver, responseText);
+    }
+    else receiver.update(responseText);
+  }
+
+  if (this.success()) {
+    if (this.onComplete) this.onComplete.bind(this).defer();
+  }
+}
+ +

});

+ +

Ajax.PeriodicalUpdater = Class.create(Ajax.Base, {

+ +
initialize: function($super, container, url, options) {
+  $super(options);
+  this.onComplete = this.options.onComplete;
+
+  this.frequency = (this.options.frequency || 2);
+  this.decay = (this.options.decay || 1);
+
+  this.updater = { };
+  this.container = container;
+  this.url = url;
+
+  this.start();
+},
+
+start: function() {
+  this.options.onComplete = this.updateComplete.bind(this);
+  this.onTimerEvent();
+},
+
+stop: function() {
+  this.updater.options.onComplete = undefined;
+  clearTimeout(this.timer);
+  (this.onComplete || Prototype.emptyFunction).apply(this, arguments);
+},
+
+updateComplete: function(response) {
+  if (this.options.decay) {
+    this.decay = (response.responseText == this.lastText ?
+      this.decay * this.options.decay : 1);
+
+    this.lastText = response.responseText;
+  }
+  this.timer = this.onTimerEvent.bind(this).delay(this.decay * this.frequency);
+},
+
+onTimerEvent: function() {
+  this.updater = new Ajax.Updater(this.container, this.url, this.options);
+}
+ +

}); function $(element) {

+ +
if (arguments.length > 1) {
+  for (var i = 0, elements = [], length = arguments.length; i < length; i++)
+    elements.push($(arguments[i]));
+  return elements;
+}
+if (Object.isString(element))
+  element = document.getElementById(element);
+return Element.extend(element);
+ +

}

+ +

if (Prototype.BrowserFeatures.XPath) {

+ +
document._getElementsByXPath = function(expression, parentElement) {
+  var results = [];
+  var query = document.evaluate(expression, $(parentElement) || document,
+    null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
+  for (var i = 0, length = query.snapshotLength; i < length; i++)
+    results.push(Element.extend(query.snapshotItem(i)));
+  return results;
+};
+ +

}

+ +

/————————————————————————–/

+ +

if (!window.Node) var Node = { };

+ +

if (!Node.ELEMENT_NODE) {

+ +
// DOM level 2 ECMAScript Language Binding
+Object.extend(Node, {
+  ELEMENT_NODE: 1,
+  ATTRIBUTE_NODE: 2,
+  TEXT_NODE: 3,
+  CDATA_SECTION_NODE: 4,
+  ENTITY_REFERENCE_NODE: 5,
+  ENTITY_NODE: 6,
+  PROCESSING_INSTRUCTION_NODE: 7,
+  COMMENT_NODE: 8,
+  DOCUMENT_NODE: 9,
+  DOCUMENT_TYPE_NODE: 10,
+  DOCUMENT_FRAGMENT_NODE: 11,
+  NOTATION_NODE: 12
+});
+ +

}

+ +

(function() {

+ +
var element = this.Element;
+this.Element = function(tagName, attributes) {
+  attributes = attributes || { };
+  tagName = tagName.toLowerCase();
+  var cache = Element.cache;
+  if (Prototype.Browser.IE && attributes.name) {
+    tagName = '<' + tagName + ' name="' + attributes.name + '">';
+    delete attributes.name;
+    return Element.writeAttribute(document.createElement(tagName), attributes);
+  }
+  if (!cache[tagName]) cache[tagName] = Element.extend(document.createElement(tagName));
+  return Element.writeAttribute(cache[tagName].cloneNode(false), attributes);
+};
+Object.extend(this.Element, element || { });
+ +

}).call(window);

+ +

Element.cache = { };

+ +

Element.Methods = {

+ +
visible: function(element) {
+  return $(element).style.display != 'none';
+},
+
+toggle: function(element) {
+  element = $(element);
+  Element[Element.visible(element) ? 'hide' : 'show'](element);
+  return element;
+},
+
+hide: function(element) {
+  $(element).style.display = 'none';
+  return element;
+},
+
+show: function(element) {
+  $(element).style.display = '';
+  return element;
+},
+
+remove: function(element) {
+  element = $(element);
+  element.parentNode.removeChild(element);
+  return element;
+},
+
+update: function(element, content) {
+  element = $(element);
+  if (content && content.toElement) content = content.toElement();
+  if (Object.isElement(content)) return element.update().insert(content);
+  content = Object.toHTML(content);
+  element.innerHTML = content.stripScripts();
+  content.evalScripts.bind(content).defer();
+  return element;
+},
+
+replace: function(element, content) {
+  element = $(element);
+  if (content && content.toElement) content = content.toElement();
+  else if (!Object.isElement(content)) {
+    content = Object.toHTML(content);
+    var range = element.ownerDocument.createRange();
+    range.selectNode(element);
+    content.evalScripts.bind(content).defer();
+    content = range.createContextualFragment(content.stripScripts());
+  }
+  element.parentNode.replaceChild(content, element);
+  return element;
+},
+
+insert: function(element, insertions) {
+  element = $(element);
+
+  if (Object.isString(insertions) || Object.isNumber(insertions) ||
+      Object.isElement(insertions) || (insertions && (insertions.toElement || insertions.toHTML)))
+        insertions = {bottom:insertions};
+
+  var content, t, range;
+
+  for (position in insertions) {
+    content  = insertions[position];
+    position = position.toLowerCase();
+    t = Element._insertionTranslations[position];
+
+    if (content && content.toElement) content = content.toElement();
+    if (Object.isElement(content)) {
+      t.insert(element, content);
+      continue;
+    }
+
+    content = Object.toHTML(content);
+
+    range = element.ownerDocument.createRange();
+    t.initializeRange(element, range);
+    t.insert(element, range.createContextualFragment(content.stripScripts()));
+
+    content.evalScripts.bind(content).defer();
+  }
+
+  return element;
+},
+
+wrap: function(element, wrapper, attributes) {
+  element = $(element);
+  if (Object.isElement(wrapper))
+    $(wrapper).writeAttribute(attributes || { });
+  else if (Object.isString(wrapper)) wrapper = new Element(wrapper, attributes);
+  else wrapper = new Element('div', wrapper);
+  if (element.parentNode)
+    element.parentNode.replaceChild(wrapper, element);
+  wrapper.appendChild(element);
+  return wrapper;
+},
+
+inspect: function(element) {
+  element = $(element);
+  var result = '<' + element.tagName.toLowerCase();
+  $H({'id': 'id', 'className': 'class'}).each(function(pair) {
+    var property = pair.first(), attribute = pair.last();
+    var value = (element[property] || '').toString();
+    if (value) result += ' ' + attribute + '=' + value.inspect(true);
+  });
+  return result + '>';
+},
+
+recursivelyCollect: function(element, property) {
+  element = $(element);
+  var elements = [];
+  while (element = element[property])
+    if (element.nodeType == 1)
+      elements.push(Element.extend(element));
+  return elements;
+},
+
+ancestors: function(element) {
+  return $(element).recursivelyCollect('parentNode');
+},
+
+descendants: function(element) {
+  return $A($(element).getElementsByTagName('*')).each(Element.extend);
+},
+
+firstDescendant: function(element) {
+  element = $(element).firstChild;
+  while (element && element.nodeType != 1) element = element.nextSibling;
+  return $(element);
+},
+
+immediateDescendants: function(element) {
+  if (!(element = $(element).firstChild)) return [];
+  while (element && element.nodeType != 1) element = element.nextSibling;
+  if (element) return [element].concat($(element).nextSiblings());
+  return [];
+},
+
+previousSiblings: function(element) {
+  return $(element).recursivelyCollect('previousSibling');
+},
+
+nextSiblings: function(element) {
+  return $(element).recursivelyCollect('nextSibling');
+},
+
+siblings: function(element) {
+  element = $(element);
+  return element.previousSiblings().reverse().concat(element.nextSiblings());
+},
+
+match: function(element, selector) {
+  if (Object.isString(selector))
+    selector = new Selector(selector);
+  return selector.match($(element));
+},
+
+up: function(element, expression, index) {
+  element = $(element);
+  if (arguments.length == 1) return $(element.parentNode);
+  var ancestors = element.ancestors();
+  return expression ? Selector.findElement(ancestors, expression, index) :
+    ancestors[index || 0];
+},
+
+down: function(element, expression, index) {
+  element = $(element);
+  if (arguments.length == 1) return element.firstDescendant();
+  var descendants = element.descendants();
+  return expression ? Selector.findElement(descendants, expression, index) :
+    descendants[index || 0];
+},
+
+previous: function(element, expression, index) {
+  element = $(element);
+  if (arguments.length == 1) return $(Selector.handlers.previousElementSibling(element));
+  var previousSiblings = element.previousSiblings();
+  return expression ? Selector.findElement(previousSiblings, expression, index) :
+    previousSiblings[index || 0];
+},
+
+next: function(element, expression, index) {
+  element = $(element);
+  if (arguments.length == 1) return $(Selector.handlers.nextElementSibling(element));
+  var nextSiblings = element.nextSiblings();
+  return expression ? Selector.findElement(nextSiblings, expression, index) :
+    nextSiblings[index || 0];
+},
+
+select: function() {
+  var args = $A(arguments), element = $(args.shift());
+  return Selector.findChildElements(element, args);
+},
+
+adjacent: function() {
+  var args = $A(arguments), element = $(args.shift());
+  return Selector.findChildElements(element.parentNode, args).without(element);
+},
+
+identify: function(element) {
+  element = $(element);
+  var id = element.readAttribute('id'), self = arguments.callee;
+  if (id) return id;
+  do { id = 'anonymous_element_' + self.counter++ } while ($(id));
+  element.writeAttribute('id', id);
+  return id;
+},
+
+readAttribute: function(element, name) {
+  element = $(element);
+  if (Prototype.Browser.IE) {
+    var t = Element._attributeTranslations.read;
+    if (t.values[name]) return t.values[name](element, name);
+    if (t.names[name]) name = t.names[name];
+    if (name.include(':')) {
+      return (!element.attributes || !element.attributes[name]) ? null :
+       element.attributes[name].value;
+    }
+  }
+  return element.getAttribute(name);
+},
+
+writeAttribute: function(element, name, value) {
+  element = $(element);
+  var attributes = { }, t = Element._attributeTranslations.write;
+
+  if (typeof name == 'object') attributes = name;
+  else attributes[name] = value === undefined ? true : value;
+
+  for (var attr in attributes) {
+    var name = t.names[attr] || attr, value = attributes[attr];
+    if (t.values[attr]) name = t.values[attr](element, value);
+    if (value === false || value === null)
+      element.removeAttribute(name);
+    else if (value === true)
+      element.setAttribute(name, name);
+    else element.setAttribute(name, value);
+  }
+  return element;
+},
+
+getHeight: function(element) {
+  return $(element).getDimensions().height;
+},
+
+getWidth: function(element) {
+  return $(element).getDimensions().width;
+},
+
+classNames: function(element) {
+  return new Element.ClassNames(element);
+},
+
+hasClassName: function(element, className) {
+  if (!(element = $(element))) return;
+  var elementClassName = element.className;
+  return (elementClassName.length > 0 && (elementClassName == className ||
+    new RegExp("(^|\\s)" + className + "(\\s|$)").test(elementClassName)));
+},
+
+addClassName: function(element, className) {
+  if (!(element = $(element))) return;
+  if (!element.hasClassName(className))
+    element.className += (element.className ? ' ' : '') + className;
+  return element;
+},
+
+removeClassName: function(element, className) {
+  if (!(element = $(element))) return;
+  element.className = element.className.replace(
+    new RegExp("(^|\\s+)" + className + "(\\s+|$)"), ' ').strip();
+  return element;
+},
+
+toggleClassName: function(element, className) {
+  if (!(element = $(element))) return;
+  return element[element.hasClassName(className) ?
+    'removeClassName' : 'addClassName'](className);
+},
+
+// removes whitespace-only text node children
+cleanWhitespace: function(element) {
+  element = $(element);
+  var node = element.firstChild;
+  while (node) {
+    var nextNode = node.nextSibling;
+    if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
+      element.removeChild(node);
+    node = nextNode;
+  }
+  return element;
+},
+
+empty: function(element) {
+  return $(element).innerHTML.blank();
+},
+
+descendantOf: function(element, ancestor) {
+  element = $(element), ancestor = $(ancestor);
+
+  if (element.compareDocumentPosition)
+    return (element.compareDocumentPosition(ancestor) & 8) === 8;
+
+  if (element.sourceIndex && !Prototype.Browser.Opera) {
+    var e = element.sourceIndex, a = ancestor.sourceIndex,
+     nextAncestor = ancestor.nextSibling;
+    if (!nextAncestor) {
+      do { ancestor = ancestor.parentNode; }
+      while (!(nextAncestor = ancestor.nextSibling) && ancestor.parentNode);
+    }
+    if (nextAncestor) return (e > a && e < nextAncestor.sourceIndex);
+  }
+
+  while (element = element.parentNode)
+    if (element == ancestor) return true;
+  return false;
+},
+
+scrollTo: function(element) {
+  element = $(element);
+  var pos = element.cumulativeOffset();
+  window.scrollTo(pos[0], pos[1]);
+  return element;
+},
+
+getStyle: function(element, style) {
+  element = $(element);
+  style = style == 'float' ? 'cssFloat' : style.camelize();
+  var value = element.style[style];
+  if (!value) {
+    var css = document.defaultView.getComputedStyle(element, null);
+    value = css ? css[style] : null;
+  }
+  if (style == 'opacity') return value ? parseFloat(value) : 1.0;
+  return value == 'auto' ? null : value;
+},
+
+getOpacity: function(element) {
+  return $(element).getStyle('opacity');
+},
+
+setStyle: function(element, styles) {
+  element = $(element);
+  var elementStyle = element.style, match;
+  if (Object.isString(styles)) {
+    element.style.cssText += ';' + styles;
+    return styles.include('opacity') ?
+      element.setOpacity(styles.match(/opacity:\s*(\d?\.?\d*)/)[1]) : element;
+  }
+  for (var property in styles)
+    if (property == 'opacity') element.setOpacity(styles[property]);
+    else
+      elementStyle[(property == 'float' || property == 'cssFloat') ?
+        (elementStyle.styleFloat === undefined ? 'cssFloat' : 'styleFloat') :
+          property] = styles[property];
+
+  return element;
+},
+
+setOpacity: function(element, value) {
+  element = $(element);
+  element.style.opacity = (value == 1 || value === '') ? '' :
+    (value < 0.00001) ? 0 : value;
+  return element;
+},
+
+getDimensions: function(element) {
+  element = $(element);
+  var display = $(element).getStyle('display');
+  if (display != 'none' && display != null) // Safari bug
+    return {width: element.offsetWidth, height: element.offsetHeight};
+
+  // All *Width and *Height properties give 0 on elements with display none,
+  // so enable the element temporarily
+  var els = element.style;
+  var originalVisibility = els.visibility;
+  var originalPosition = els.position;
+  var originalDisplay = els.display;
+  els.visibility = 'hidden';
+  els.position = 'absolute';
+  els.display = 'block';
+  var originalWidth = element.clientWidth;
+  var originalHeight = element.clientHeight;
+  els.display = originalDisplay;
+  els.position = originalPosition;
+  els.visibility = originalVisibility;
+  return {width: originalWidth, height: originalHeight};
+},
+
+makePositioned: function(element) {
+  element = $(element);
+  var pos = Element.getStyle(element, 'position');
+  if (pos == 'static' || !pos) {
+    element._madePositioned = true;
+    element.style.position = 'relative';
+    // Opera returns the offset relative to the positioning context, when an
+    // element is position relative but top and left have not been defined
+    if (window.opera) {
+      element.style.top = 0;
+      element.style.left = 0;
+    }
+  }
+  return element;
+},
+
+undoPositioned: function(element) {
+  element = $(element);
+  if (element._madePositioned) {
+    element._madePositioned = undefined;
+    element.style.position =
+      element.style.top =
+      element.style.left =
+      element.style.bottom =
+      element.style.right = '';
+  }
+  return element;
+},
+
+makeClipping: function(element) {
+  element = $(element);
+  if (element._overflow) return element;
+  element._overflow = Element.getStyle(element, 'overflow') || 'auto';
+  if (element._overflow !== 'hidden')
+    element.style.overflow = 'hidden';
+  return element;
+},
+
+undoClipping: function(element) {
+  element = $(element);
+  if (!element._overflow) return element;
+  element.style.overflow = element._overflow == 'auto' ? '' : element._overflow;
+  element._overflow = null;
+  return element;
+},
+
+cumulativeOffset: function(element) {
+  var valueT = 0, valueL = 0;
+  do {
+    valueT += element.offsetTop  || 0;
+    valueL += element.offsetLeft || 0;
+    element = element.offsetParent;
+  } while (element);
+  return Element._returnOffset(valueL, valueT);
+},
+
+positionedOffset: function(element) {
+  var valueT = 0, valueL = 0;
+  do {
+    valueT += element.offsetTop  || 0;
+    valueL += element.offsetLeft || 0;
+    element = element.offsetParent;
+    if (element) {
+      if (element.tagName == 'BODY') break;
+      var p = Element.getStyle(element, 'position');
+      if (p == 'relative' || p == 'absolute') break;
+    }
+  } while (element);
+  return Element._returnOffset(valueL, valueT);
+},
+
+absolutize: function(element) {
+  element = $(element);
+  if (element.getStyle('position') == 'absolute') return;
+  // Position.prepare(); // To be done manually by Scripty when it needs it.
+
+  var offsets = element.positionedOffset();
+  var top     = offsets[1];
+  var left    = offsets[0];
+  var width   = element.clientWidth;
+  var height  = element.clientHeight;
+
+  element._originalLeft   = left - parseFloat(element.style.left  || 0);
+  element._originalTop    = top  - parseFloat(element.style.top || 0);
+  element._originalWidth  = element.style.width;
+  element._originalHeight = element.style.height;
+
+  element.style.position = 'absolute';
+  element.style.top    = top + 'px';
+  element.style.left   = left + 'px';
+  element.style.width  = width + 'px';
+  element.style.height = height + 'px';
+  return element;
+},
+
+relativize: function(element) {
+  element = $(element);
+  if (element.getStyle('position') == 'relative') return;
+  // Position.prepare(); // To be done manually by Scripty when it needs it.
+
+  element.style.position = 'relative';
+  var top  = parseFloat(element.style.top  || 0) - (element._originalTop || 0);
+  var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);
+
+  element.style.top    = top + 'px';
+  element.style.left   = left + 'px';
+  element.style.height = element._originalHeight;
+  element.style.width  = element._originalWidth;
+  return element;
+},
+
+cumulativeScrollOffset: function(element) {
+  var valueT = 0, valueL = 0;
+  do {
+    valueT += element.scrollTop  || 0;
+    valueL += element.scrollLeft || 0;
+    element = element.parentNode;
+  } while (element);
+  return Element._returnOffset(valueL, valueT);
+},
+
+getOffsetParent: function(element) {
+  if (element.offsetParent) return $(element.offsetParent);
+  if (element == document.body) return $(element);
+
+  while ((element = element.parentNode) && element != document.body)
+    if (Element.getStyle(element, 'position') != 'static')
+      return $(element);
+
+  return $(document.body);
+},
+
+viewportOffset: function(forElement) {
+  var valueT = 0, valueL = 0;
+
+  var element = forElement;
+  do {
+    valueT += element.offsetTop  || 0;
+    valueL += element.offsetLeft || 0;
+
+    // Safari fix
+    if (element.offsetParent == document.body &&
+      Element.getStyle(element, 'position') == 'absolute') break;
+
+  } while (element = element.offsetParent);
+
+  element = forElement;
+  do {
+    if (!Prototype.Browser.Opera || element.tagName == 'BODY') {
+      valueT -= element.scrollTop  || 0;
+      valueL -= element.scrollLeft || 0;
+    }
+  } while (element = element.parentNode);
+
+  return Element._returnOffset(valueL, valueT);
+},
+
+clonePosition: function(element, source) {
+  var options = Object.extend({
+    setLeft:    true,
+    setTop:     true,
+    setWidth:   true,
+    setHeight:  true,
+    offsetTop:  0,
+    offsetLeft: 0
+  }, arguments[2] || { });
+
+  // find page position of source
+  source = $(source);
+  var p = source.viewportOffset();
+
+  // find coordinate system to use
+  element = $(element);
+  var delta = [0, 0];
+  var parent = null;
+  // delta [0,0] will do fine with position: fixed elements,
+  // position:absolute needs offsetParent deltas
+  if (Element.getStyle(element, 'position') == 'absolute') {
+    parent = element.getOffsetParent();
+    delta = parent.viewportOffset();
+  }
+
+  // correct by body offsets (fixes Safari)
+  if (parent == document.body) {
+    delta[0] -= document.body.offsetLeft;
+    delta[1] -= document.body.offsetTop;
+  }
+
+  // set position
+  if (options.setLeft)   element.style.left  = (p[0] - delta[0] + options.offsetLeft) + 'px';
+  if (options.setTop)    element.style.top   = (p[1] - delta[1] + options.offsetTop) + 'px';
+  if (options.setWidth)  element.style.width = source.offsetWidth + 'px';
+  if (options.setHeight) element.style.height = source.offsetHeight + 'px';
+  return element;
+}
+ +

};

+ +

Element.Methods.identify.counter = 1;

+ +

Object.extend(Element.Methods, {

+ +
getElementsBySelector: Element.Methods.select,
+childElements: Element.Methods.immediateDescendants
+ +

});

+ +

Element._attributeTranslations = {

+ +
write: {
+  names: {
+    className: 'class',
+    htmlFor:   'for'
+  },
+  values: { }
+}
+ +

};

+ +

if (!document.createRange || Prototype.Browser.Opera) {

+ +
Element.Methods.insert = function(element, insertions) {
+  element = $(element);
+
+  if (Object.isString(insertions) || Object.isNumber(insertions) ||
+      Object.isElement(insertions) || (insertions && (insertions.toElement || insertions.toHTML)))
+        insertions = { bottom: insertions };
+
+  var t = Element._insertionTranslations, content, position, pos, tagName;
+
+  for (position in insertions) {
+    content  = insertions[position];
+    position = position.toLowerCase();
+    pos      = t[position];
+
+    if (content && content.toElement) content = content.toElement();
+    if (Object.isElement(content)) {
+      pos.insert(element, content);
+      continue;
+    }
+
+    content = Object.toHTML(content);
+    tagName = ((position == 'before' || position == 'after')
+      ? element.parentNode : element).tagName.toUpperCase();
+
+    if (t.tags[tagName]) {
+      var fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
+      if (position == 'top' || position == 'after') fragments.reverse();
+      fragments.each(pos.insert.curry(element));
+    }
+    else element.insertAdjacentHTML(pos.adjacency, content.stripScripts());
+
+    content.evalScripts.bind(content).defer();
+  }
+
+  return element;
+};
+ +

}

+ +

if (Prototype.Browser.Opera) {

+ +
Element.Methods._getStyle = Element.Methods.getStyle;
+Element.Methods.getStyle = function(element, style) {
+  switch(style) {
+    case 'left':
+    case 'top':
+    case 'right':
+    case 'bottom':
+      if (Element._getStyle(element, 'position') == 'static') return null;
+    default: return Element._getStyle(element, style);
+  }
+};
+Element.Methods._readAttribute = Element.Methods.readAttribute;
+Element.Methods.readAttribute = function(element, attribute) {
+  if (attribute == 'title') return element.title;
+  return Element._readAttribute(element, attribute);
+};
+ +

}

+ +

else if (Prototype.Browser.IE) {

+ +
$w('positionedOffset getOffsetParent viewportOffset').each(function(method) {
+  Element.Methods[method] = Element.Methods[method].wrap(
+    function(proceed, element) {
+      element = $(element);
+      var position = element.getStyle('position');
+      if (position != 'static') return proceed(element);
+      element.setStyle({ position: 'relative' });
+      var value = proceed(element);
+      element.setStyle({ position: position });
+      return value;
+    }
+  );
+});
+
+Element.Methods.getStyle = function(element, style) {
+  element = $(element);
+  style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.camelize();
+  var value = element.style[style];
+  if (!value && element.currentStyle) value = element.currentStyle[style];
+
+  if (style == 'opacity') {
+    if (value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/))
+      if (value[1]) return parseFloat(value[1]) / 100;
+    return 1.0;
+  }
+
+  if (value == 'auto') {
+    if ((style == 'width' || style == 'height') && (element.getStyle('display') != 'none'))
+      return element['offset' + style.capitalize()] + 'px';
+    return null;
+  }
+  return value;
+};
+
+Element.Methods.setOpacity = function(element, value) {
+  function stripAlpha(filter){
+    return filter.replace(/alpha\([^\)]*\)/gi,'');
+  }
+  element = $(element);
+  var currentStyle = element.currentStyle;
+  if ((currentStyle && !currentStyle.hasLayout) ||
+    (!currentStyle && element.style.zoom == 'normal'))
+      element.style.zoom = 1;
+
+  var filter = element.getStyle('filter'), style = element.style;
+  if (value == 1 || value === '') {
+    (filter = stripAlpha(filter)) ?
+      style.filter = filter : style.removeAttribute('filter');
+    return element;
+  } else if (value < 0.00001) value = 0;
+  style.filter = stripAlpha(filter) +
+    'alpha(opacity=' + (value * 100) + ')';
+  return element;
+};
+
+Element._attributeTranslations = {
+  read: {
+    names: {
+      'class': 'className',
+      'for':   'htmlFor'
+    },
+    values: {
+      _getAttr: function(element, attribute) {
+        return element.getAttribute(attribute, 2);
+      },
+      _getAttrNode: function(element, attribute) {
+        var node = element.getAttributeNode(attribute);
+        return node ? node.value : "";
+      },
+      _getEv: function(element, attribute) {
+        var attribute = element.getAttribute(attribute);
+        return attribute ? attribute.toString().slice(23, -2) : null;
+      },
+      _flag: function(element, attribute) {
+        return $(element).hasAttribute(attribute) ? attribute : null;
+      },
+      style: function(element) {
+        return element.style.cssText.toLowerCase();
+      },
+      title: function(element) {
+        return element.title;
+      }
+    }
+  }
+};
+
+Element._attributeTranslations.write = {
+  names: Object.clone(Element._attributeTranslations.read.names),
+  values: {
+    checked: function(element, value) {
+      element.checked = !!value;
+    },
+
+    style: function(element, value) {
+      element.style.cssText = value ? value : '';
+    }
+  }
+};
+
+Element._attributeTranslations.has = {};
+
+$w('colSpan rowSpan vAlign dateTime accessKey tabIndex ' +
+    'encType maxLength readOnly longDesc').each(function(attr) {
+  Element._attributeTranslations.write.names[attr.toLowerCase()] = attr;
+  Element._attributeTranslations.has[attr.toLowerCase()] = attr;
+});
+
+(function(v) {
+  Object.extend(v, {
+    href:        v._getAttr,
+    src:         v._getAttr,
+    type:        v._getAttr,
+    action:      v._getAttrNode,
+    disabled:    v._flag,
+    checked:     v._flag,
+    readonly:    v._flag,
+    multiple:    v._flag,
+    onload:      v._getEv,
+    onunload:    v._getEv,
+    onclick:     v._getEv,
+    ondblclick:  v._getEv,
+    onmousedown: v._getEv,
+    onmouseup:   v._getEv,
+    onmouseover: v._getEv,
+    onmousemove: v._getEv,
+    onmouseout:  v._getEv,
+    onfocus:     v._getEv,
+    onblur:      v._getEv,
+    onkeypress:  v._getEv,
+    onkeydown:   v._getEv,
+    onkeyup:     v._getEv,
+    onsubmit:    v._getEv,
+    onreset:     v._getEv,
+    onselect:    v._getEv,
+    onchange:    v._getEv
+  });
+})(Element._attributeTranslations.read.values);
+ +

}

+ +

else if (Prototype.Browser.Gecko && +/rv:1.8.0/.test(navigator.userAgent)) {

+ +
Element.Methods.setOpacity = function(element, value) {
+  element = $(element);
+  element.style.opacity = (value == 1) ? 0.999999 :
+    (value === '') ? '' : (value < 0.00001) ? 0 : value;
+  return element;
+};
+ +

}

+ +

else if (Prototype.Browser.WebKit) {

+ +
Element.Methods.setOpacity = function(element, value) {
+  element = $(element);
+  element.style.opacity = (value == 1 || value === '') ? '' :
+    (value < 0.00001) ? 0 : value;
+
+  if (value == 1)
+    if(element.tagName == 'IMG' && element.width) {
+      element.width++; element.width--;
+    } else try {
+      var n = document.createTextNode(' ');
+      element.appendChild(n);
+      element.removeChild(n);
+    } catch (e) { }
+
+  return element;
+};
+
+// Safari returns margins on body which is incorrect if the child is absolutely
+// positioned.  For performance reasons, redefine Position.cumulativeOffset for
+// KHTML/WebKit only.
+Element.Methods.cumulativeOffset = function(element) {
+  var valueT = 0, valueL = 0;
+  do {
+    valueT += element.offsetTop  || 0;
+    valueL += element.offsetLeft || 0;
+    if (element.offsetParent == document.body)
+      if (Element.getStyle(element, 'position') == 'absolute') break;
+
+    element = element.offsetParent;
+  } while (element);
+
+  return Element._returnOffset(valueL, valueT);
+};
+ +

}

+ +

if (Prototype.Browser.IE || Prototype.Browser.Opera) {

+ +
// IE and Opera are missing .innerHTML support for TABLE-related and SELECT elements
+Element.Methods.update = function(element, content) {
+  element = $(element);
+
+  if (content && content.toElement) content = content.toElement();
+  if (Object.isElement(content)) return element.update().insert(content);
+
+  content = Object.toHTML(content);
+  var tagName = element.tagName.toUpperCase();
+
+  if (tagName in Element._insertionTranslations.tags) {
+    $A(element.childNodes).each(function(node) { element.removeChild(node) });
+    Element._getContentFromAnonymousElement(tagName, content.stripScripts())
+      .each(function(node) { element.appendChild(node) });
+  }
+  else element.innerHTML = content.stripScripts();
+
+  content.evalScripts.bind(content).defer();
+  return element;
+};
+ +

}

+ +

if (document.createElement('div').outerHTML) {

+ +
Element.Methods.replace = function(element, content) {
+  element = $(element);
+
+  if (content && content.toElement) content = content.toElement();
+  if (Object.isElement(content)) {
+    element.parentNode.replaceChild(content, element);
+    return element;
+  }
+
+  content = Object.toHTML(content);
+  var parent = element.parentNode, tagName = parent.tagName.toUpperCase();
+
+  if (Element._insertionTranslations.tags[tagName]) {
+    var nextSibling = element.next();
+    var fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
+    parent.removeChild(element);
+    if (nextSibling)
+      fragments.each(function(node) { parent.insertBefore(node, nextSibling) });
+    else
+      fragments.each(function(node) { parent.appendChild(node) });
+  }
+  else element.outerHTML = content.stripScripts();
+
+  content.evalScripts.bind(content).defer();
+  return element;
+};
+ +

}

+ +

Element._returnOffset = function(l, t) {

+ +
var result = [l, t];
+result.left = l;
+result.top = t;
+return result;
+
+ +

};

+ +

Element._getContentFromAnonymousElement = function(tagName, html) {

+ +
var div = new Element('div'), t = Element._insertionTranslations.tags[tagName];
+div.innerHTML = t[0] + html + t[1];
+t[2].times(function() { div = div.firstChild });
+return $A(div.childNodes);
+ +

};

+ +

Element._insertionTranslations = {

+ +
before: {
+  adjacency: 'beforeBegin',
+  insert: function(element, node) {
+    element.parentNode.insertBefore(node, element);
+  },
+  initializeRange: function(element, range) {
+    range.setStartBefore(element);
+  }
+},
+top: {
+  adjacency: 'afterBegin',
+  insert: function(element, node) {
+    element.insertBefore(node, element.firstChild);
+  },
+  initializeRange: function(element, range) {
+    range.selectNodeContents(element);
+    range.collapse(true);
+  }
+},
+bottom: {
+  adjacency: 'beforeEnd',
+  insert: function(element, node) {
+    element.appendChild(node);
+  }
+},
+after: {
+  adjacency: 'afterEnd',
+  insert: function(element, node) {
+    element.parentNode.insertBefore(node, element.nextSibling);
+  },
+  initializeRange: function(element, range) {
+    range.setStartAfter(element);
+  }
+},
+tags: {
+  TABLE:  ['<table>',                '</table>',                   1],
+  TBODY:  ['<table><tbody>',         '</tbody></table>',           2],
+  TR:     ['<table><tbody><tr>',     '</tr></tbody></table>',      3],
+  TD:     ['<table><tbody><tr><td>', '</td></tr></tbody></table>', 4],
+  SELECT: ['<select>',               '</select>',                  1]
+}
+ +

};

+ +

(function() {

+ +
this.bottom.initializeRange = this.top.initializeRange;
+Object.extend(this.tags, {
+  THEAD: this.tags.TBODY,
+  TFOOT: this.tags.TBODY,
+  TH:    this.tags.TD
+});
+
+ +

}).call(Element._insertionTranslations);

+ +

Element.Methods.Simulated = {

+ +
hasAttribute: function(element, attribute) {
+  attribute = Element._attributeTranslations.has[attribute] || attribute;
+  var node = $(element).getAttributeNode(attribute);
+  return node && node.specified;
+}
+ +

};

+ +

Element.Methods.ByTag = { };

+ +

Object.extend(Element, Element.Methods);

+ +

if (!Prototype.BrowserFeatures.ElementExtensions &&

+ +
  document.createElement('div').__proto__) {
+window.HTMLElement = { };
+window.HTMLElement.prototype = document.createElement('div').__proto__;
+Prototype.BrowserFeatures.ElementExtensions = true;
+ +

}

+ +

Element.extend = (function() {

+ +
if (Prototype.BrowserFeatures.SpecificElementExtensions)
+  return Prototype.K;
+
+var Methods = { }, ByTag = Element.Methods.ByTag;
+
+var extend = Object.extend(function(element) {
+  if (!element || element._extendedByPrototype ||
+      element.nodeType != 1 || element == window) return element;
+
+  var methods = Object.clone(Methods),
+    tagName = element.tagName, property, value;
+
+  // extend methods for specific tags
+  if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]);
+
+  for (property in methods) {
+    value = methods[property];
+    if (Object.isFunction(value) && !(property in element))
+      element[property] = value.methodize();
+  }
+
+  element._extendedByPrototype = Prototype.emptyFunction;
+  return element;
+
+}, {
+  refresh: function() {
+    // extend methods for all tags (Safari doesn't need this)
+    if (!Prototype.BrowserFeatures.ElementExtensions) {
+      Object.extend(Methods, Element.Methods);
+      Object.extend(Methods, Element.Methods.Simulated);
+    }
+  }
+});
+
+extend.refresh();
+return extend;
+ +

})();

+ +

Element.hasAttribute = function(element, attribute) {

+ +
if (element.hasAttribute) return element.hasAttribute(attribute);
+return Element.Methods.Simulated.hasAttribute(element, attribute);
+ +

};

+ +

Element.addMethods = function(methods) {

+ +
var F = Prototype.BrowserFeatures, T = Element.Methods.ByTag;
+
+if (!methods) {
+  Object.extend(Form, Form.Methods);
+  Object.extend(Form.Element, Form.Element.Methods);
+  Object.extend(Element.Methods.ByTag, {
+    "FORM":     Object.clone(Form.Methods),
+    "INPUT":    Object.clone(Form.Element.Methods),
+    "SELECT":   Object.clone(Form.Element.Methods),
+    "TEXTAREA": Object.clone(Form.Element.Methods)
+  });
+}
+
+if (arguments.length == 2) {
+  var tagName = methods;
+  methods = arguments[1];
+}
+
+if (!tagName) Object.extend(Element.Methods, methods || { });
+else {
+  if (Object.isArray(tagName)) tagName.each(extend);
+  else extend(tagName);
+}
+
+function extend(tagName) {
+  tagName = tagName.toUpperCase();
+  if (!Element.Methods.ByTag[tagName])
+    Element.Methods.ByTag[tagName] = { };
+  Object.extend(Element.Methods.ByTag[tagName], methods);
+}
+
+function copy(methods, destination, onlyIfAbsent) {
+  onlyIfAbsent = onlyIfAbsent || false;
+  for (var property in methods) {
+    var value = methods[property];
+    if (!Object.isFunction(value)) continue;
+    if (!onlyIfAbsent || !(property in destination))
+      destination[property] = value.methodize();
+  }
+}
+
+function findDOMClass(tagName) {
+  var klass;
+  var trans = {
+    "OPTGROUP": "OptGroup", "TEXTAREA": "TextArea", "P": "Paragraph",
+    "FIELDSET": "FieldSet", "UL": "UList", "OL": "OList", "DL": "DList",
+    "DIR": "Directory", "H1": "Heading", "H2": "Heading", "H3": "Heading",
+    "H4": "Heading", "H5": "Heading", "H6": "Heading", "Q": "Quote",
+    "INS": "Mod", "DEL": "Mod", "A": "Anchor", "IMG": "Image", "CAPTION":
+    "TableCaption", "COL": "TableCol", "COLGROUP": "TableCol", "THEAD":
+    "TableSection", "TFOOT": "TableSection", "TBODY": "TableSection", "TR":
+    "TableRow", "TH": "TableCell", "TD": "TableCell", "FRAMESET":
+    "FrameSet", "IFRAME": "IFrame"
+  };
+  if (trans[tagName]) klass = 'HTML' + trans[tagName] + 'Element';
+  if (window[klass]) return window[klass];
+  klass = 'HTML' + tagName + 'Element';
+  if (window[klass]) return window[klass];
+  klass = 'HTML' + tagName.capitalize() + 'Element';
+  if (window[klass]) return window[klass];
+
+  window[klass] = { };
+  window[klass].prototype = document.createElement(tagName).__proto__;
+  return window[klass];
+}
+
+if (F.ElementExtensions) {
+  copy(Element.Methods, HTMLElement.prototype);
+  copy(Element.Methods.Simulated, HTMLElement.prototype, true);
+}
+
+if (F.SpecificElementExtensions) {
+  for (var tag in Element.Methods.ByTag) {
+    var klass = findDOMClass(tag);
+    if (Object.isUndefined(klass)) continue;
+    copy(T[tag], klass.prototype);
+  }
+}
+
+Object.extend(Element, Element.Methods);
+delete Element.ByTag;
+
+if (Element.extend.refresh) Element.extend.refresh();
+Element.cache = { };
+ +

};

+ +

document.viewport = {

+ +
getDimensions: function() {
+  var dimensions = { };
+  $w('width height').each(function(d) {
+    var D = d.capitalize();
+    dimensions[d] = self['inner' + D] ||
+     (document.documentElement['client' + D] || document.body['client' + D]);
+  });
+  return dimensions;
+},
+
+getWidth: function() {
+  return this.getDimensions().width;
+},
+
+getHeight: function() {
+  return this.getDimensions().height;
+},
+
+getScrollOffsets: function() {
+  return Element._returnOffset(
+    window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft,
+    window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop);
+}
+ +

}; /* Portions of the Selector class are derived from Jack Slocum’s +DomQuery,

+ +
part of YUI-Ext version 0.40, distributed under the terms of an MIT-style
+license.  Please see http://www.yui-ext.com/ for more information. */
+ +

var Selector = Class.create({

+ +
initialize: function(expression) {
+  this.expression = expression.strip();
+  this.compileMatcher();
+},
+
+compileMatcher: function() {
+  // Selectors with namespaced attributes can't use the XPath version
+  if (Prototype.BrowserFeatures.XPath && !(/(\[[\w-]*?:|:checked)/).test(this.expression))
+    return this.compileXPathMatcher();
+
+  var e = this.expression, ps = Selector.patterns, h = Selector.handlers,
+      c = Selector.criteria, le, p, m;
+
+  if (Selector._cache[e]) {
+    this.matcher = Selector._cache[e];
+    return;
+  }
+
+  this.matcher = ["this.matcher = function(root) {",
+                  "var r = root, h = Selector.handlers, c = false, n;"];
+
+  while (e && le != e && (/\S/).test(e)) {
+    le = e;
+    for (var i in ps) {
+      p = ps[i];
+      if (m = e.match(p)) {
+        this.matcher.push(Object.isFunction(c[i]) ? c[i](m) :
+            new Template(c[i]).evaluate(m));
+        e = e.replace(m[0], '');
+        break;
+      }
+    }
+  }
+
+  this.matcher.push("return h.unique(n);\n}");
+  eval(this.matcher.join('\n'));
+  Selector._cache[this.expression] = this.matcher;
+},
+
+compileXPathMatcher: function() {
+  var e = this.expression, ps = Selector.patterns,
+      x = Selector.xpath, le, m;
+
+  if (Selector._cache[e]) {
+    this.xpath = Selector._cache[e]; return;
+  }
+
+  this.matcher = ['.//*'];
+  while (e && le != e && (/\S/).test(e)) {
+    le = e;
+    for (var i in ps) {
+      if (m = e.match(ps[i])) {
+        this.matcher.push(Object.isFunction(x[i]) ? x[i](m) :
+          new Template(x[i]).evaluate(m));
+        e = e.replace(m[0], '');
+        break;
+      }
+    }
+  }
+
+  this.xpath = this.matcher.join('');
+  Selector._cache[this.expression] = this.xpath;
+},
+
+findElements: function(root) {
+  root = root || document;
+  if (this.xpath) return document._getElementsByXPath(this.xpath, root);
+  return this.matcher(root);
+},
+
+match: function(element) {
+  this.tokens = [];
+
+  var e = this.expression, ps = Selector.patterns, as = Selector.assertions;
+  var le, p, m;
+
+  while (e && le !== e && (/\S/).test(e)) {
+    le = e;
+    for (var i in ps) {
+      p = ps[i];
+      if (m = e.match(p)) {
+        // use the Selector.assertions methods unless the selector
+        // is too complex.
+        if (as[i]) {
+          this.tokens.push([i, Object.clone(m)]);
+          e = e.replace(m[0], '');
+        } else {
+          // reluctantly do a document-wide search
+          // and look for a match in the array
+          return this.findElements(document).include(element);
+        }
+      }
+    }
+  }
+
+  var match = true, name, matches;
+  for (var i = 0, token; token = this.tokens[i]; i++) {
+    name = token[0], matches = token[1];
+    if (!Selector.assertions[name](element, matches)) {
+      match = false; break;
+    }
+  }
+
+  return match;
+},
+
+toString: function() {
+  return this.expression;
+},
+
+inspect: function() {
+  return "#<Selector:" + this.expression.inspect() + ">";
+}
+ +

});

+ +

Object.extend(Selector, {

+ +
_cache: { },
+
+xpath: {
+  descendant:   "//*",
+  child:        "/*",
+  adjacent:     "/following-sibling::*[1]",
+  laterSibling: '/following-sibling::*',
+  tagName:      function(m) {
+    if (m[1] == '*') return '';
+    return "[local-name()='" + m[1].toLowerCase() +
+           "' or local-name()='" + m[1].toUpperCase() + "']";
+  },
+  className:    "[contains(concat(' ', @class, ' '), ' #{1} ')]",
+  id:           "[@id='#{1}']",
+  attrPresence: "[@#{1}]",
+  attr: function(m) {
+    m[3] = m[5] || m[6];
+    return new Template(Selector.xpath.operators[m[2]]).evaluate(m);
+  },
+  pseudo: function(m) {
+    var h = Selector.xpath.pseudos[m[1]];
+    if (!h) return '';
+    if (Object.isFunction(h)) return h(m);
+    return new Template(Selector.xpath.pseudos[m[1]]).evaluate(m);
+  },
+  operators: {
+    '=':  "[@#{1}='#{3}']",
+    '!=': "[@#{1}!='#{3}']",
+    '^=': "[starts-with(@#{1}, '#{3}')]",
+    '$=': "[substring(@#{1}, (string-length(@#{1}) - string-length('#{3}') + 1))='#{3}']",
+    '*=': "[contains(@#{1}, '#{3}')]",
+    '~=': "[contains(concat(' ', @#{1}, ' '), ' #{3} ')]",
+    '|=': "[contains(concat('-', @#{1}, '-'), '-#{3}-')]"
+  },
+  pseudos: {
+    'first-child': '[not(preceding-sibling::*)]',
+    'last-child':  '[not(following-sibling::*)]',
+    'only-child':  '[not(preceding-sibling::* or following-sibling::*)]',
+    'empty':       "[count(*) = 0 and (count(text()) = 0 or translate(text(), ' \t\r\n', '') = '')]",
+    'checked':     "[@checked]",
+    'disabled':    "[@disabled]",
+    'enabled':     "[not(@disabled)]",
+    'not': function(m) {
+      var e = m[6], p = Selector.patterns,
+          x = Selector.xpath, le, m, v;
+
+      var exclusion = [];
+      while (e && le != e && (/\S/).test(e)) {
+        le = e;
+        for (var i in p) {
+          if (m = e.match(p[i])) {
+            v = Object.isFunction(x[i]) ? x[i](m) : new Template(x[i]).evaluate(m);
+            exclusion.push("(" + v.substring(1, v.length - 1) + ")");
+            e = e.replace(m[0], '');
+            break;
+          }
+        }
+      }
+      return "[not(" + exclusion.join(" and ") + ")]";
+    },
+    'nth-child':      function(m) {
+      return Selector.xpath.pseudos.nth("(count(./preceding-sibling::*) + 1) ", m);
+    },
+    'nth-last-child': function(m) {
+      return Selector.xpath.pseudos.nth("(count(./following-sibling::*) + 1) ", m);
+    },
+    'nth-of-type':    function(m) {
+      return Selector.xpath.pseudos.nth("position() ", m);
+    },
+    'nth-last-of-type': function(m) {
+      return Selector.xpath.pseudos.nth("(last() + 1 - position()) ", m);
+    },
+    'first-of-type':  function(m) {
+      m[6] = "1"; return Selector.xpath.pseudos['nth-of-type'](m);
+    },
+    'last-of-type':   function(m) {
+      m[6] = "1"; return Selector.xpath.pseudos['nth-last-of-type'](m);
+    },
+    'only-of-type':   function(m) {
+      var p = Selector.xpath.pseudos; return p['first-of-type'](m) + p['last-of-type'](m);
+    },
+    nth: function(fragment, m) {
+      var mm, formula = m[6], predicate;
+      if (formula == 'even') formula = '2n+0';
+      if (formula == 'odd')  formula = '2n+1';
+      if (mm = formula.match(/^(\d+)$/)) // digit only
+        return '[' + fragment + "= " + mm[1] + ']';
+      if (mm = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b
+        if (mm[1] == "-") mm[1] = -1;
+        var a = mm[1] ? Number(mm[1]) : 1;
+        var b = mm[2] ? Number(mm[2]) : 0;
+        predicate = "[((#{fragment} - #{b}) mod #{a} = 0) and " +
+        "((#{fragment} - #{b}) div #{a} >= 0)]";
+        return new Template(predicate).evaluate({
+          fragment: fragment, a: a, b: b });
+      }
+    }
+  }
+},
+
+criteria: {
+  tagName:      'n = h.tagName(n, r, "#{1}", c);   c = false;',
+  className:    'n = h.className(n, r, "#{1}", c); c = false;',
+  id:           'n = h.id(n, r, "#{1}", c);        c = false;',
+  attrPresence: 'n = h.attrPresence(n, r, "#{1}"); c = false;',
+  attr: function(m) {
+    m[3] = (m[5] || m[6]);
+    return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}"); c = false;').evaluate(m);
+  },
+  pseudo: function(m) {
+    if (m[6]) m[6] = m[6].replace(/"/g, '\\"');
+    return new Template('n = h.pseudo(n, "#{1}", "#{6}", r, c); c = false;').evaluate(m);
+  },
+  descendant:   'c = "descendant";',
+  child:        'c = "child";',
+  adjacent:     'c = "adjacent";',
+  laterSibling: 'c = "laterSibling";'
+},
+
+patterns: {
+  // combinators must be listed first
+  // (and descendant needs to be last combinator)
+  laterSibling: /^\s*~\s*/,
+  child:        /^\s*>\s*/,
+  adjacent:     /^\s*\+\s*/,
+  descendant:   /^\s/,
+
+  // selectors follow
+  tagName:      /^\s*(\*|[\w\-]+)(\b|$)?/,
+  id:           /^#([\w\-\*]+)(\b|$)/,
+  className:    /^\.([\w\-\*]+)(\b|$)/,
+  pseudo:       /^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s)|(?=:))/,
+  attrPresence: /^\[([\w]+)\]/,
+  attr:         /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/
+},
+
+// for Selector.match and Element#match
+assertions: {
+  tagName: function(element, matches) {
+    return matches[1].toUpperCase() == element.tagName.toUpperCase();
+  },
+
+  className: function(element, matches) {
+    return Element.hasClassName(element, matches[1]);
+  },
+
+  id: function(element, matches) {
+    return element.id === matches[1];
+  },
+
+  attrPresence: function(element, matches) {
+    return Element.hasAttribute(element, matches[1]);
+  },
+
+  attr: function(element, matches) {
+    var nodeValue = Element.readAttribute(element, matches[1]);
+    return Selector.operators[matches[2]](nodeValue, matches[3]);
+  }
+},
+
+handlers: {
+  // UTILITY FUNCTIONS
+  // joins two collections
+  concat: function(a, b) {
+    for (var i = 0, node; node = b[i]; i++)
+      a.push(node);
+    return a;
+  },
+
+  // marks an array of nodes for counting
+  mark: function(nodes) {
+    for (var i = 0, node; node = nodes[i]; i++)
+      node._counted = true;
+    return nodes;
+  },
+
+  unmark: function(nodes) {
+    for (var i = 0, node; node = nodes[i]; i++)
+      node._counted = undefined;
+    return nodes;
+  },
+
+  // mark each child node with its position (for nth calls)
+  // "ofType" flag indicates whether we're indexing for nth-of-type
+  // rather than nth-child
+  index: function(parentNode, reverse, ofType) {
+    parentNode._counted = true;
+    if (reverse) {
+      for (var nodes = parentNode.childNodes, i = nodes.length - 1, j = 1; i >= 0; i--) {
+        var node = nodes[i];
+        if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++;
+      }
+    } else {
+      for (var i = 0, j = 1, nodes = parentNode.childNodes; node = nodes[i]; i++)
+        if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++;
+    }
+  },
+
+  // filters out duplicates and extends all nodes
+  unique: function(nodes) {
+    if (nodes.length == 0) return nodes;
+    var results = [], n;
+    for (var i = 0, l = nodes.length; i < l; i++)
+      if (!(n = nodes[i])._counted) {
+        n._counted = true;
+        results.push(Element.extend(n));
+      }
+    return Selector.handlers.unmark(results);
+  },
+
+  // COMBINATOR FUNCTIONS
+  descendant: function(nodes) {
+    var h = Selector.handlers;
+    for (var i = 0, results = [], node; node = nodes[i]; i++)
+      h.concat(results, node.getElementsByTagName('*'));
+    return results;
+  },
+
+  child: function(nodes) {
+    var h = Selector.handlers;
+    for (var i = 0, results = [], node; node = nodes[i]; i++) {
+      for (var j = 0, children = [], child; child = node.childNodes[j]; j++)
+        if (child.nodeType == 1 && child.tagName != '!') results.push(child);
+    }
+    return results;
+  },
+
+  adjacent: function(nodes) {
+    for (var i = 0, results = [], node; node = nodes[i]; i++) {
+      var next = this.nextElementSibling(node);
+      if (next) results.push(next);
+    }
+    return results;
+  },
+
+  laterSibling: function(nodes) {
+    var h = Selector.handlers;
+    for (var i = 0, results = [], node; node = nodes[i]; i++)
+      h.concat(results, Element.nextSiblings(node));
+    return results;
+  },
+
+  nextElementSibling: function(node) {
+    while (node = node.nextSibling)
+            if (node.nodeType == 1) return node;
+    return null;
+  },
+
+  previousElementSibling: function(node) {
+    while (node = node.previousSibling)
+      if (node.nodeType == 1) return node;
+    return null;
+  },
+
+  // TOKEN FUNCTIONS
+  tagName: function(nodes, root, tagName, combinator) {
+    tagName = tagName.toUpperCase();
+    var results = [], h = Selector.handlers;
+    if (nodes) {
+      if (combinator) {
+        // fastlane for ordinary descendant combinators
+        if (combinator == "descendant") {
+          for (var i = 0, node; node = nodes[i]; i++)
+            h.concat(results, node.getElementsByTagName(tagName));
+          return results;
+        } else nodes = this[combinator](nodes);
+        if (tagName == "*") return nodes;
+      }
+      for (var i = 0, node; node = nodes[i]; i++)
+        if (node.tagName.toUpperCase() == tagName) results.push(node);
+      return results;
+    } else return root.getElementsByTagName(tagName);
+  },
+
+  id: function(nodes, root, id, combinator) {
+    var targetNode = $(id), h = Selector.handlers;
+    if (!targetNode) return [];
+    if (!nodes && root == document) return [targetNode];
+    if (nodes) {
+      if (combinator) {
+        if (combinator == 'child') {
+          for (var i = 0, node; node = nodes[i]; i++)
+            if (targetNode.parentNode == node) return [targetNode];
+        } else if (combinator == 'descendant') {
+          for (var i = 0, node; node = nodes[i]; i++)
+            if (Element.descendantOf(targetNode, node)) return [targetNode];
+        } else if (combinator == 'adjacent') {
+          for (var i = 0, node; node = nodes[i]; i++)
+            if (Selector.handlers.previousElementSibling(targetNode) == node)
+              return [targetNode];
+        } else nodes = h[combinator](nodes);
+      }
+      for (var i = 0, node; node = nodes[i]; i++)
+        if (node == targetNode) return [targetNode];
+      return [];
+    }
+    return (targetNode && Element.descendantOf(targetNode, root)) ? [targetNode] : [];
+  },
+
+  className: function(nodes, root, className, combinator) {
+    if (nodes && combinator) nodes = this[combinator](nodes);
+    return Selector.handlers.byClassName(nodes, root, className);
+  },
+
+  byClassName: function(nodes, root, className) {
+    if (!nodes) nodes = Selector.handlers.descendant([root]);
+    var needle = ' ' + className + ' ';
+    for (var i = 0, results = [], node, nodeClassName; node = nodes[i]; i++) {
+      nodeClassName = node.className;
+      if (nodeClassName.length == 0) continue;
+      if (nodeClassName == className || (' ' + nodeClassName + ' ').include(needle))
+        results.push(node);
+    }
+    return results;
+  },
+
+  attrPresence: function(nodes, root, attr) {
+    if (!nodes) nodes = root.getElementsByTagName("*");
+    var results = [];
+    for (var i = 0, node; node = nodes[i]; i++)
+      if (Element.hasAttribute(node, attr)) results.push(node);
+    return results;
+  },
+
+  attr: function(nodes, root, attr, value, operator) {
+    if (!nodes) nodes = root.getElementsByTagName("*");
+    var handler = Selector.operators[operator], results = [];
+    for (var i = 0, node; node = nodes[i]; i++) {
+      var nodeValue = Element.readAttribute(node, attr);
+      if (nodeValue === null) continue;
+      if (handler(nodeValue, value)) results.push(node);
+    }
+    return results;
+  },
+
+  pseudo: function(nodes, name, value, root, combinator) {
+    if (nodes && combinator) nodes = this[combinator](nodes);
+    if (!nodes) nodes = root.getElementsByTagName("*");
+    return Selector.pseudos[name](nodes, value, root);
+  }
+},
+
+pseudos: {
+  'first-child': function(nodes, value, root) {
+    for (var i = 0, results = [], node; node = nodes[i]; i++) {
+      if (Selector.handlers.previousElementSibling(node)) continue;
+        results.push(node);
+    }
+    return results;
+  },
+  'last-child': function(nodes, value, root) {
+    for (var i = 0, results = [], node; node = nodes[i]; i++) {
+      if (Selector.handlers.nextElementSibling(node)) continue;
+        results.push(node);
+    }
+    return results;
+  },
+  'only-child': function(nodes, value, root) {
+    var h = Selector.handlers;
+    for (var i = 0, results = [], node; node = nodes[i]; i++)
+      if (!h.previousElementSibling(node) && !h.nextElementSibling(node))
+        results.push(node);
+    return results;
+  },
+  'nth-child':        function(nodes, formula, root) {
+    return Selector.pseudos.nth(nodes, formula, root);
+  },
+  'nth-last-child':   function(nodes, formula, root) {
+    return Selector.pseudos.nth(nodes, formula, root, true);
+  },
+  'nth-of-type':      function(nodes, formula, root) {
+    return Selector.pseudos.nth(nodes, formula, root, false, true);
+  },
+  'nth-last-of-type': function(nodes, formula, root) {
+    return Selector.pseudos.nth(nodes, formula, root, true, true);
+  },
+  'first-of-type':    function(nodes, formula, root) {
+    return Selector.pseudos.nth(nodes, "1", root, false, true);
+  },
+  'last-of-type':     function(nodes, formula, root) {
+    return Selector.pseudos.nth(nodes, "1", root, true, true);
+  },
+  'only-of-type':     function(nodes, formula, root) {
+    var p = Selector.pseudos;
+    return p['last-of-type'](p['first-of-type'](nodes, formula, root), formula, root);
+  },
+
+  // handles the an+b logic
+  getIndices: function(a, b, total) {
+    if (a == 0) return b > 0 ? [b] : [];
+    return $R(1, total).inject([], function(memo, i) {
+      if (0 == (i - b) % a && (i - b) / a >= 0) memo.push(i);
+      return memo;
+    });
+  },
+
+  // handles nth(-last)-child, nth(-last)-of-type, and (first|last)-of-type
+  nth: function(nodes, formula, root, reverse, ofType) {
+    if (nodes.length == 0) return [];
+    if (formula == 'even') formula = '2n+0';
+    if (formula == 'odd')  formula = '2n+1';
+    var h = Selector.handlers, results = [], indexed = [], m;
+    h.mark(nodes);
+    for (var i = 0, node; node = nodes[i]; i++) {
+      if (!node.parentNode._counted) {
+        h.index(node.parentNode, reverse, ofType);
+        indexed.push(node.parentNode);
+      }
+    }
+    if (formula.match(/^\d+$/)) { // just a number
+      formula = Number(formula);
+      for (var i = 0, node; node = nodes[i]; i++)
+        if (node.nodeIndex == formula) results.push(node);
+    } else if (m = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b
+      if (m[1] == "-") m[1] = -1;
+      var a = m[1] ? Number(m[1]) : 1;
+      var b = m[2] ? Number(m[2]) : 0;
+      var indices = Selector.pseudos.getIndices(a, b, nodes.length);
+      for (var i = 0, node, l = indices.length; node = nodes[i]; i++) {
+        for (var j = 0; j < l; j++)
+          if (node.nodeIndex == indices[j]) results.push(node);
+      }
+    }
+    h.unmark(nodes);
+    h.unmark(indexed);
+    return results;
+  },
+
+  'empty': function(nodes, value, root) {
+    for (var i = 0, results = [], node; node = nodes[i]; i++) {
+      // IE treats comments as element nodes
+      if (node.tagName == '!' || (node.firstChild && !node.innerHTML.match(/^\s*$/))) continue;
+      results.push(node);
+    }
+    return results;
+  },
+
+  'not': function(nodes, selector, root) {
+    var h = Selector.handlers, selectorType, m;
+    var exclusions = new Selector(selector).findElements(root);
+    h.mark(exclusions);
+    for (var i = 0, results = [], node; node = nodes[i]; i++)
+      if (!node._counted) results.push(node);
+    h.unmark(exclusions);
+    return results;
+  },
+
+  'enabled': function(nodes, value, root) {
+    for (var i = 0, results = [], node; node = nodes[i]; i++)
+      if (!node.disabled) results.push(node);
+    return results;
+  },
+
+  'disabled': function(nodes, value, root) {
+    for (var i = 0, results = [], node; node = nodes[i]; i++)
+      if (node.disabled) results.push(node);
+    return results;
+  },
+
+  'checked': function(nodes, value, root) {
+    for (var i = 0, results = [], node; node = nodes[i]; i++)
+      if (node.checked) results.push(node);
+    return results;
+  }
+},
+
+operators: {
+  '=':  function(nv, v) { return nv == v; },
+  '!=': function(nv, v) { return nv != v; },
+  '^=': function(nv, v) { return nv.startsWith(v); },
+  '$=': function(nv, v) { return nv.endsWith(v); },
+  '*=': function(nv, v) { return nv.include(v); },
+  '~=': function(nv, v) { return (' ' + nv + ' ').include(' ' + v + ' '); },
+  '|=': function(nv, v) { return ('-' + nv.toUpperCase() + '-').include('-' + v.toUpperCase() + '-'); }
+},
+
+matchElements: function(elements, expression) {
+  var matches = new Selector(expression).findElements(), h = Selector.handlers;
+  h.mark(matches);
+  for (var i = 0, results = [], element; element = elements[i]; i++)
+    if (element._counted) results.push(element);
+  h.unmark(matches);
+  return results;
+},
+
+findElement: function(elements, expression, index) {
+  if (Object.isNumber(expression)) {
+    index = expression; expression = false;
+  }
+  return Selector.matchElements(elements, expression || '*')[index || 0];
+},
+
+findChildElements: function(element, expressions) {
+  var exprs = expressions.join(','), expressions = [];
+  exprs.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/, function(m) {
+    expressions.push(m[1].strip());
+  });
+  var results = [], h = Selector.handlers;
+  for (var i = 0, l = expressions.length, selector; i < l; i++) {
+    selector = new Selector(expressions[i].strip());
+    h.concat(results, selector.findElements(element));
+  }
+  return (l > 1) ? h.unique(results) : results;
+}
+ +

});

+ +

function $$() {

+ +
return Selector.findChildElements(document, $A(arguments));
+ +

} var Form = {

+ +
reset: function(form) {
+  $(form).reset();
+  return form;
+},
+
+serializeElements: function(elements, options) {
+  if (typeof options != 'object') options = { hash: !!options };
+  else if (options.hash === undefined) options.hash = true;
+  var key, value, submitted = false, submit = options.submit;
+
+  var data = elements.inject({ }, function(result, element) {
+    if (!element.disabled && element.name) {
+      key = element.name; value = $(element).getValue();
+      if (value != null && (element.type != 'submit' || (!submitted &&
+          submit !== false && (!submit || key == submit) && (submitted = true)))) {
+        if (key in result) {
+          // a key is already present; construct an array of values
+          if (!Object.isArray(result[key])) result[key] = [result[key]];
+          result[key].push(value);
+        }
+        else result[key] = value;
+      }
+    }
+    return result;
+  });
+
+  return options.hash ? data : Object.toQueryString(data);
+}
+ +

};

+ +

Form.Methods = {

+ +
serialize: function(form, options) {
+  return Form.serializeElements(Form.getElements(form), options);
+},
+
+getElements: function(form) {
+  return $A($(form).getElementsByTagName('*')).inject([],
+    function(elements, child) {
+      if (Form.Element.Serializers[child.tagName.toLowerCase()])
+        elements.push(Element.extend(child));
+      return elements;
+    }
+  );
+},
+
+getInputs: function(form, typeName, name) {
+  form = $(form);
+  var inputs = form.getElementsByTagName('input');
+
+  if (!typeName && !name) return $A(inputs).map(Element.extend);
+
+  for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) {
+    var input = inputs[i];
+    if ((typeName && input.type != typeName) || (name && input.name != name))
+      continue;
+    matchingInputs.push(Element.extend(input));
+  }
+
+  return matchingInputs;
+},
+
+disable: function(form) {
+  form = $(form);
+  Form.getElements(form).invoke('disable');
+  return form;
+},
+
+enable: function(form) {
+  form = $(form);
+  Form.getElements(form).invoke('enable');
+  return form;
+},
+
+findFirstElement: function(form) {
+  var elements = $(form).getElements().findAll(function(element) {
+    return 'hidden' != element.type && !element.disabled;
+  });
+  var firstByIndex = elements.findAll(function(element) {
+    return element.hasAttribute('tabIndex') && element.tabIndex >= 0;
+  }).sortBy(function(element) { return element.tabIndex }).first();
+
+  return firstByIndex ? firstByIndex : elements.find(function(element) {
+    return ['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
+  });
+},
+
+focusFirstElement: function(form) {
+  form = $(form);
+  form.findFirstElement().activate();
+  return form;
+},
+
+request: function(form, options) {
+  form = $(form), options = Object.clone(options || { });
+
+  var params = options.parameters, action = form.readAttribute('action') || '';
+  if (action.blank()) action = window.location.href;
+  options.parameters = form.serialize(true);
+
+  if (params) {
+    if (Object.isString(params)) params = params.toQueryParams();
+    Object.extend(options.parameters, params);
+  }
+
+  if (form.hasAttribute('method') && !options.method)
+    options.method = form.method;
+
+  return new Ajax.Request(action, options);
+}
+ +

};

+ +

/————————————————————————–/

+ +

Form.Element = {

+ +
focus: function(element) {
+  $(element).focus();
+  return element;
+},
+
+select: function(element) {
+  $(element).select();
+  return element;
+}
+ +

};

+ +

Form.Element.Methods = {

+ +
serialize: function(element) {
+  element = $(element);
+  if (!element.disabled && element.name) {
+    var value = element.getValue();
+    if (value != undefined) {
+      var pair = { };
+      pair[element.name] = value;
+      return Object.toQueryString(pair);
+    }
+  }
+  return '';
+},
+
+getValue: function(element) {
+  element = $(element);
+  var method = element.tagName.toLowerCase();
+  return Form.Element.Serializers[method](element);
+},
+
+setValue: function(element, value) {
+  element = $(element);
+  var method = element.tagName.toLowerCase();
+  Form.Element.Serializers[method](element, value);
+  return element;
+},
+
+clear: function(element) {
+  $(element).value = '';
+  return element;
+},
+
+present: function(element) {
+  return $(element).value != '';
+},
+
+activate: function(element) {
+  element = $(element);
+  try {
+    element.focus();
+    if (element.select && (element.tagName.toLowerCase() != 'input' ||
+        !['button', 'reset', 'submit'].include(element.type)))
+      element.select();
+  } catch (e) { }
+  return element;
+},
+
+disable: function(element) {
+  element = $(element);
+  element.blur();
+  element.disabled = true;
+  return element;
+},
+
+enable: function(element) {
+  element = $(element);
+  element.disabled = false;
+  return element;
+}
+ +

};

+ +

/————————————————————————–/

+ +

var Field = Form.Element; var $F = Form.Element.Methods.getValue;

+ +

/————————————————————————–/

+ +

Form.Element.Serializers = {

+ +
input: function(element, value) {
+  switch (element.type.toLowerCase()) {
+    case 'checkbox':
+    case 'radio':
+      return Form.Element.Serializers.inputSelector(element, value);
+    default:
+      return Form.Element.Serializers.textarea(element, value);
+  }
+},
+
+inputSelector: function(element, value) {
+  if (value === undefined) return element.checked ? element.value : null;
+  else element.checked = !!value;
+},
+
+textarea: function(element, value) {
+  if (value === undefined) return element.value;
+  else element.value = value;
+},
+
+select: function(element, index) {
+  if (index === undefined)
+    return this[element.type == 'select-one' ?
+      'selectOne' : 'selectMany'](element);
+  else {
+    var opt, value, single = !Object.isArray(index);
+    for (var i = 0, length = element.length; i < length; i++) {
+      opt = element.options[i];
+      value = this.optionValue(opt);
+      if (single) {
+        if (value == index) {
+          opt.selected = true;
+          return;
+        }
+      }
+      else opt.selected = index.include(value);
+    }
+  }
+},
+
+selectOne: function(element) {
+  var index = element.selectedIndex;
+  return index >= 0 ? this.optionValue(element.options[index]) : null;
+},
+
+selectMany: function(element) {
+  var values, length = element.length;
+  if (!length) return null;
+
+  for (var i = 0, values = []; i < length; i++) {
+    var opt = element.options[i];
+    if (opt.selected) values.push(this.optionValue(opt));
+  }
+  return values;
+},
+
+optionValue: function(opt) {
+  // extend element because hasAttribute may not be native
+  return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text;
+}
+ +

};

+ +

/————————————————————————–/

+ +

Abstract.TimedObserver = Class.create(PeriodicalExecuter, {

+ +
initialize: function($super, element, frequency, callback) {
+  $super(callback, frequency);
+  this.element   = $(element);
+  this.lastValue = this.getValue();
+},
+
+execute: function() {
+  var value = this.getValue();
+  if (Object.isString(this.lastValue) && Object.isString(value) ?
+      this.lastValue != value : String(this.lastValue) != String(value)) {
+    this.callback(this.element, value);
+    this.lastValue = value;
+  }
+}
+ +

});

+ +

Form.Element.Observer = Class.create(Abstract.TimedObserver, {

+ +
getValue: function() {
+  return Form.Element.getValue(this.element);
+}
+ +

});

+ +

Form.Observer = Class.create(Abstract.TimedObserver, {

+ +
getValue: function() {
+  return Form.serialize(this.element);
+}
+ +

});

+ +

/————————————————————————–/

+ +

Abstract.EventObserver = Class.create({

+ +
initialize: function(element, callback) {
+  this.element  = $(element);
+  this.callback = callback;
+
+  this.lastValue = this.getValue();
+  if (this.element.tagName.toLowerCase() == 'form')
+    this.registerFormCallbacks();
+  else
+    this.registerCallback(this.element);
+},
+
+onElementEvent: function() {
+  var value = this.getValue();
+  if (this.lastValue != value) {
+    this.callback(this.element, value);
+    this.lastValue = value;
+  }
+},
+
+registerFormCallbacks: function() {
+  Form.getElements(this.element).each(this.registerCallback, this);
+},
+
+registerCallback: function(element) {
+  if (element.type) {
+    switch (element.type.toLowerCase()) {
+      case 'checkbox':
+      case 'radio':
+        Event.observe(element, 'click', this.onElementEvent.bind(this));
+        break;
+      default:
+        Event.observe(element, 'change', this.onElementEvent.bind(this));
+        break;
+    }
+  }
+}
+ +

});

+ +

Form.Element.EventObserver = Class.create(Abstract.EventObserver, {

+ +
getValue: function() {
+  return Form.Element.getValue(this.element);
+}
+ +

});

+ +

Form.EventObserver = Class.create(Abstract.EventObserver, {

+ +
getValue: function() {
+  return Form.serialize(this.element);
+}
+ +

}); if (!window.Event) var Event = { };

+ +

Object.extend(Event, {

+ +
KEY_BACKSPACE: 8,
+KEY_TAB:       9,
+KEY_RETURN:   13,
+KEY_ESC:      27,
+KEY_LEFT:     37,
+KEY_UP:       38,
+KEY_RIGHT:    39,
+KEY_DOWN:     40,
+KEY_DELETE:   46,
+KEY_HOME:     36,
+KEY_END:      35,
+KEY_PAGEUP:   33,
+KEY_PAGEDOWN: 34,
+KEY_INSERT:   45,
+
+cache: { },
+
+relatedTarget: function(event) {
+  var element;
+  switch(event.type) {
+    case 'mouseover': element = event.fromElement; break;
+    case 'mouseout':  element = event.toElement;   break;
+    default: return null;
+  }
+  return Element.extend(element);
+}
+ +

});

+ +

Event.Methods = (function() {

+ +
var isButton;
+
+if (Prototype.Browser.IE) {
+  var buttonMap = { 0: 1, 1: 4, 2: 2 };
+  isButton = function(event, code) {
+    return event.button == buttonMap[code];
+  };
+
+} else if (Prototype.Browser.WebKit) {
+  isButton = function(event, code) {
+    switch (code) {
+      case 0: return event.which == 1 && !event.metaKey;
+      case 1: return event.which == 1 && event.metaKey;
+      default: return false;
+    }
+  };
+
+} else {
+  isButton = function(event, code) {
+    return event.which ? (event.which === code + 1) : (event.button === code);
+  };
+}
+
+return {
+  isLeftClick:   function(event) { return isButton(event, 0) },
+  isMiddleClick: function(event) { return isButton(event, 1) },
+  isRightClick:  function(event) { return isButton(event, 2) },
+
+  element: function(event) {
+    var node = Event.extend(event).target;
+    return Element.extend(node.nodeType == Node.TEXT_NODE ? node.parentNode : node);
+  },
+
+  findElement: function(event, expression) {
+    var element = Event.element(event);
+    return element.match(expression) ? element : element.up(expression);
+  },
+
+  pointer: function(event) {
+    return {
+      x: event.pageX || (event.clientX +
+        (document.documentElement.scrollLeft || document.body.scrollLeft)),
+      y: event.pageY || (event.clientY +
+        (document.documentElement.scrollTop || document.body.scrollTop))
+    };
+  },
+
+  pointerX: function(event) { return Event.pointer(event).x },
+  pointerY: function(event) { return Event.pointer(event).y },
+
+  stop: function(event) {
+    Event.extend(event);
+    event.preventDefault();
+    event.stopPropagation();
+    event.stopped = true;
+  }
+};
+ +

})();

+ +

Event.extend = (function() {

+ +
var methods = Object.keys(Event.Methods).inject({ }, function(m, name) {
+  m[name] = Event.Methods[name].methodize();
+  return m;
+});
+
+if (Prototype.Browser.IE) {
+  Object.extend(methods, {
+    stopPropagation: function() { this.cancelBubble = true },
+    preventDefault:  function() { this.returnValue = false },
+    inspect: function() { return "[object Event]" }
+  });
+
+  return function(event) {
+    if (!event) return false;
+    if (event._extendedByPrototype) return event;
+
+    event._extendedByPrototype = Prototype.emptyFunction;
+    var pointer = Event.pointer(event);
+    Object.extend(event, {
+      target: event.srcElement,
+      relatedTarget: Event.relatedTarget(event),
+      pageX:  pointer.x,
+      pageY:  pointer.y
+    });
+    return Object.extend(event, methods);
+  };
+
+} else {
+  Event.prototype = Event.prototype || document.createEvent("HTMLEvents").__proto__;
+  Object.extend(Event.prototype, methods);
+  return Prototype.K;
+}
+ +

})();

+ +

Object.extend(Event, (function() {

+ +
var cache = Event.cache;
+
+function getEventID(element) {
+  if (element._eventID) return element._eventID;
+  arguments.callee.id = arguments.callee.id || 1;
+  return element._eventID = ++arguments.callee.id;
+}
+
+function getDOMEventName(eventName) {
+  if (eventName && eventName.include(':')) return "dataavailable";
+  return eventName;
+}
+
+function getCacheForID(id) {
+  return cache[id] = cache[id] || { };
+}
+
+function getWrappersForEventName(id, eventName) {
+  var c = getCacheForID(id);
+  return c[eventName] = c[eventName] || [];
+}
+
+function createWrapper(element, eventName, handler) {
+  var id = getEventID(element);
+  var c = getWrappersForEventName(id, eventName);
+  if (c.pluck("handler").include(handler)) return false;
+
+  var wrapper = function(event) {
+    if (!Event || !Event.extend ||
+      (event.eventName && event.eventName != eventName))
+        return false;
+
+    Event.extend(event);
+    handler.call(element, event)
+  };
+
+  wrapper.handler = handler;
+  c.push(wrapper);
+  return wrapper;
+}
+
+function findWrapper(id, eventName, handler) {
+  var c = getWrappersForEventName(id, eventName);
+  return c.find(function(wrapper) { return wrapper.handler == handler });
+}
+
+function destroyWrapper(id, eventName, handler) {
+  var c = getCacheForID(id);
+  if (!c[eventName]) return false;
+  c[eventName] = c[eventName].without(findWrapper(id, eventName, handler));
+}
+
+function destroyCache() {
+  for (var id in cache)
+    for (var eventName in cache[id])
+      cache[id][eventName] = null;
+}
+
+if (window.attachEvent) {
+  window.attachEvent("onunload", destroyCache);
+}
+
+return {
+  observe: function(element, eventName, handler) {
+    element = $(element);
+    var name = getDOMEventName(eventName);
+
+    var wrapper = createWrapper(element, eventName, handler);
+    if (!wrapper) return element;
+
+    if (element.addEventListener) {
+      element.addEventListener(name, wrapper, false);
+    } else {
+      element.attachEvent("on" + name, wrapper);
+    }
+
+    return element;
+  },
+
+  stopObserving: function(element, eventName, handler) {
+    element = $(element);
+    var id = getEventID(element), name = getDOMEventName(eventName);
+
+    if (!handler && eventName) {
+      getWrappersForEventName(id, eventName).each(function(wrapper) {
+        element.stopObserving(eventName, wrapper.handler);
+      });
+      return element;
+
+    } else if (!eventName) {
+      Object.keys(getCacheForID(id)).each(function(eventName) {
+        element.stopObserving(eventName);
+      });
+      return element;
+    }
+
+    var wrapper = findWrapper(id, eventName, handler);
+    if (!wrapper) return element;
+
+    if (element.removeEventListener) {
+      element.removeEventListener(name, wrapper, false);
+    } else {
+      element.detachEvent("on" + name, wrapper);
+    }
+
+    destroyWrapper(id, eventName, handler);
+
+    return element;
+  },
+
+  fire: function(element, eventName, memo) {
+    element = $(element);
+    if (element == document && document.createEvent && !element.dispatchEvent)
+      element = document.documentElement;
+
+    if (document.createEvent) {
+      var event = document.createEvent("HTMLEvents");
+      event.initEvent("dataavailable", true, true);
+    } else {
+      var event = document.createEventObject();
+      event.eventType = "ondataavailable";
+    }
+
+    event.eventName = eventName;
+    event.memo = memo || { };
+
+    if (document.createEvent) {
+      element.dispatchEvent(event);
+    } else {
+      element.fireEvent(event.eventType, event);
+    }
+
+    return event;
+  }
+};
+ +

})());

+ +

Object.extend(Event, Event.Methods);

+ +

Element.addMethods({

+ +
fire:          Event.fire,
+observe:       Event.observe,
+stopObserving: Event.stopObserving
+ +

});

+ +

Object.extend(document, {

+ +
fire:          Element.Methods.fire.methodize(),
+observe:       Element.Methods.observe.methodize(),
+stopObserving: Element.Methods.stopObserving.methodize()
+ +

});

+ +

(function() {

+ +
/* Support for the DOMContentLoaded event is based on work by Dan Webb,
+   Matthias Miller, Dean Edwards and John Resig. */
+
+var timer, fired = false;
+
+function fireContentLoadedEvent() {
+  if (fired) return;
+  if (timer) window.clearInterval(timer);
+  document.fire("dom:loaded");
+  fired = true;
+}
+
+if (document.addEventListener) {
+  if (Prototype.Browser.WebKit) {
+    timer = window.setInterval(function() {
+      if (/loaded|complete/.test(document.readyState))
+        fireContentLoadedEvent();
+    }, 0);
+
+    Event.observe(window, "load", fireContentLoadedEvent);
+
+  } else {
+    document.addEventListener("DOMContentLoaded",
+      fireContentLoadedEvent, false);
+  }
+
+} else {
+  document.write("<script id=__onDOMContentLoaded defer src=//:><\/script>");
+  $("__onDOMContentLoaded").onreadystatechange = function() {
+    if (this.readyState == "complete") {
+      this.onreadystatechange = null;
+      fireContentLoadedEvent();
+    }
+  };
+}
+ +

})(); /*——————————- DEPRECATED ——————————-*/

+ +

Hash.toQueryString = Object.toQueryString;

+ +

var Toggle = { display: Element.toggle };

+ +

Element.Methods.childOf = Element.Methods.descendantOf;

+ +

var Insertion = {

+ +
Before: function(element, content) {
+  return Element.insert(element, {before:content});
+},
+
+Top: function(element, content) {
+  return Element.insert(element, {top:content});
+},
+
+Bottom: function(element, content) {
+  return Element.insert(element, {bottom:content});
+},
+
+After: function(element, content) {
+  return Element.insert(element, {after:content});
+}
+ +

};

+ +

var $continue = new Error('“throw $continue” is deprecated, use +“return” instead');

+ +

// This should be moved to script.aculo.us; notice the deprecated methods +// further below, that map to the newer Element methods. var Position = {

+ +
// set to true if needed, warning: firefox performance problems
+// NOT neeeded for page scrolling, only if draggable contained in
+// scrollable elements
+includeScrollOffsets: false,
+
+// must be called before calling withinIncludingScrolloffset, every time the
+// page is scrolled
+prepare: function() {
+  this.deltaX =  window.pageXOffset
+              || document.documentElement.scrollLeft
+              || document.body.scrollLeft
+              || 0;
+  this.deltaY =  window.pageYOffset
+              || document.documentElement.scrollTop
+              || document.body.scrollTop
+              || 0;
+},
+
+// caches x/y coordinate pair to use with overlap
+within: function(element, x, y) {
+  if (this.includeScrollOffsets)
+    return this.withinIncludingScrolloffsets(element, x, y);
+  this.xcomp = x;
+  this.ycomp = y;
+  this.offset = Element.cumulativeOffset(element);
+
+  return (y >= this.offset[1] &&
+          y <  this.offset[1] + element.offsetHeight &&
+          x >= this.offset[0] &&
+          x <  this.offset[0] + element.offsetWidth);
+},
+
+withinIncludingScrolloffsets: function(element, x, y) {
+  var offsetcache = Element.cumulativeScrollOffset(element);
+
+  this.xcomp = x + offsetcache[0] - this.deltaX;
+  this.ycomp = y + offsetcache[1] - this.deltaY;
+  this.offset = Element.cumulativeOffset(element);
+
+  return (this.ycomp >= this.offset[1] &&
+          this.ycomp <  this.offset[1] + element.offsetHeight &&
+          this.xcomp >= this.offset[0] &&
+          this.xcomp <  this.offset[0] + element.offsetWidth);
+},
+
+// within must be called directly before
+overlap: function(mode, element) {
+  if (!mode) return 0;
+  if (mode == 'vertical')
+    return ((this.offset[1] + element.offsetHeight) - this.ycomp) /
+      element.offsetHeight;
+  if (mode == 'horizontal')
+    return ((this.offset[0] + element.offsetWidth) - this.xcomp) /
+      element.offsetWidth;
+},
+
+// Deprecation layer -- use newer Element methods now (1.5.2).
+
+cumulativeOffset: Element.Methods.cumulativeOffset,
+
+positionedOffset: Element.Methods.positionedOffset,
+
+absolutize: function(element) {
+  Position.prepare();
+  return Element.absolutize(element);
+},
+
+relativize: function(element) {
+  Position.prepare();
+  return Element.relativize(element);
+},
+
+realOffset: Element.Methods.cumulativeScrollOffset,
+
+offsetParent: Element.Methods.getOffsetParent,
+
+page: Element.Methods.viewportOffset,
+
+clone: function(source, target, options) {
+  options = options || { };
+  return Element.clonePosition(target, source, options);
+}
+ +

};

+ +

/————————————————————————–/

+ +

if (!document.getElementsByClassName) document.getElementsByClassName = +function(instanceMethods){

+ +
function iter(name) {
+  return name.blank() ? null : "[contains(concat(' ', @class, ' '), ' " + name + " ')]";
+}
+
+instanceMethods.getElementsByClassName = Prototype.BrowserFeatures.XPath ?
+function(element, className) {
+  className = className.toString().strip();
+  var cond = /\s/.test(className) ? $w(className).map(iter).join('') : iter(className);
+  return cond ? document._getElementsByXPath('.//*' + cond, element) : [];
+} : function(element, className) {
+  className = className.toString().strip();
+  var elements = [], classNames = (/\s/.test(className) ? $w(className) : null);
+  if (!classNames && !className) return elements;
+
+  var nodes = $(element).getElementsByTagName('*');
+  className = ' ' + className + ' ';
+
+  for (var i = 0, child, cn; child = nodes[i]; i++) {
+    if (child.className && (cn = ' ' + child.className + ' ') && (cn.include(className) ||
+        (classNames && classNames.all(function(name) {
+          return !name.toString().blank() && cn.include(' ' + name + ' ');
+        }))))
+      elements.push(Element.extend(child));
+  }
+  return elements;
+};
+
+return function(className, parentElement) {
+  return $(parentElement || document.body).getElementsByClassName(className);
+};
+ +

}(Element.Methods);

+ +

/————————————————————————–/

+ +

Element.ClassNames = Class.create(); Element.ClassNames.prototype = {

+ +
initialize: function(element) {
+  this.element = $(element);
+},
+
+_each: function(iterator) {
+  this.element.className.split(/\s+/).select(function(name) {
+    return name.length > 0;
+  })._each(iterator);
+},
+
+set: function(className) {
+  this.element.className = className;
+},
+
+add: function(classNameToAdd) {
+  if (this.include(classNameToAdd)) return;
+  this.set($A(this).concat(classNameToAdd).join(' '));
+},
+
+remove: function(classNameToRemove) {
+  if (!this.include(classNameToRemove)) return;
+  this.set($A(this).without(classNameToRemove).join(' '));
+},
+
+toString: function() {
+  return $A(this).join(' ');
+}
+ +

};

+ +

Object.extend(Element.ClassNames.prototype, Enumerable);

+ +

/————————————————————————–/

+ +

Element.addMethods();

+
+ + + + + diff --git a/tmp/rdoc/ext/json/ext/generator/depend.html b/tmp/rdoc/ext/json/ext/generator/depend.html new file mode 100644 index 000000000..3fb5790e5 --- /dev/null +++ b/tmp/rdoc/ext/json/ext/generator/depend.html @@ -0,0 +1,86 @@ + + + + + + +depend - RDoc Documentation + + + + + + + + + + + + + + +
+ +

generator.o: generator.c generator.h $(srcdir)/../fbuffer/fbuffer.h

+
+ + + + + diff --git a/tmp/rdoc/ext/json/ext/parser/depend.html b/tmp/rdoc/ext/json/ext/parser/depend.html new file mode 100644 index 000000000..877480332 --- /dev/null +++ b/tmp/rdoc/ext/json/ext/parser/depend.html @@ -0,0 +1,86 @@ + + + + + + +depend - RDoc Documentation + + + + + + + + + + + + + + +
+ +

parser.o: parser.c parser.h $(srcdir)/../fbuffer/fbuffer.h

+
+ + + + + diff --git a/tmp/rdoc/ext/json/ext/parser/parser_rl.html b/tmp/rdoc/ext/json/ext/parser/parser_rl.html new file mode 100644 index 000000000..a3cda9852 --- /dev/null +++ b/tmp/rdoc/ext/json/ext/parser/parser_rl.html @@ -0,0 +1,1022 @@ + + + + + + +parser.rl - RDoc Documentation + + + + + + + + + + + + + + +
+ +

include “../fbuffer/fbuffer.h” include “parser.h”

+ +

if defined HAVE_RUBY_ENCODING_H # define EXC_ENCODING rb_utf8_encoding(), # +ifndef HAVE_RB_ENC_RAISE static void enc_raise(rb_encoding *enc, VALUE exc, +const char *fmt, …) {

+ +
va_list args;
+VALUE mesg;
+
+va_start(args, fmt);
+mesg = rb_enc_vsprintf(enc, fmt, args);
+va_end(args);
+
+rb_exc_raise(rb_exc_new3(exc, mesg));
+
+ +

} # define rb_enc_raise enc_raise # endif else # define EXC_ENCODING +nothing

+ +

# define rb_enc_raise rb_raise endif

+ +
unicode
+
+ +

static const char digit_values = {

+ +
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1,
+-1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1,
+-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+-1, -1, -1, -1, -1, -1, -1
+ +

};

+ +

static UTF32 unescape_unicode(const unsigned char *p) {

+ +
char b;
+UTF32 result = 0;
+b = digit_values[p[0]];
+if (b < 0) return UNI_REPLACEMENT_CHAR;
+result = (result << 4) | (unsigned char)b;
+b = digit_values[p[1]];
+if (b < 0) return UNI_REPLACEMENT_CHAR;
+result = (result << 4) | (unsigned char)b;
+b = digit_values[p[2]];
+if (b < 0) return UNI_REPLACEMENT_CHAR;
+result = (result << 4) | (unsigned char)b;
+b = digit_values[p[3]];
+if (b < 0) return UNI_REPLACEMENT_CHAR;
+result = (result << 4) | (unsigned char)b;
+return result;
+ +

}

+ +

static int convert_UTF32_to_UTF8(char *buf, UTF32 ch) {

+ +
int len = 1;
+if (ch <= 0x7F) {
+    buf[0] = (char) ch;
+} else if (ch <= 0x07FF) {
+    buf[0] = (char) ((ch >> 6) | 0xC0);
+    buf[1] = (char) ((ch & 0x3F) | 0x80);
+    len++;
+} else if (ch <= 0xFFFF) {
+    buf[0] = (char) ((ch >> 12) | 0xE0);
+    buf[1] = (char) (((ch >> 6) & 0x3F) | 0x80);
+    buf[2] = (char) ((ch & 0x3F) | 0x80);
+    len += 2;
+} else if (ch <= 0x1fffff) {
+    buf[0] =(char) ((ch >> 18) | 0xF0);
+    buf[1] =(char) (((ch >> 12) & 0x3F) | 0x80);
+    buf[2] =(char) (((ch >> 6) & 0x3F) | 0x80);
+    buf[3] =(char) ((ch & 0x3F) | 0x80);
+    len += 3;
+} else {
+    buf[0] = '?';
+}
+return len;
+ +

}

+ +

static VALUE mJSON, mExt, cParser, eParserError, eNestingError; static +VALUE CNaN, CInfinity, CMinusInfinity;

+ +

static ID i_json_creatable_p, i_json_create, i_create_id, +i_create_additions,

+ +
i_chr, i_max_nesting, i_allow_nan, i_symbolize_names,
+i_object_class, i_array_class, i_decimal_class, i_key_p,
+i_deep_const_get, i_match, i_match_string, i_aset, i_aref,
+i_leftshift, i_new;
+ +

%%{

+ +
machine JSON_common;
+
+cr                  = '\n';
+cr_neg              = [^\n];
+ws                  = [ \t\r\n];
+c_comment           = '/*' ( any* - (any* '*/' any* ) ) '*/';
+cpp_comment         = '//' cr_neg* cr;
+comment             = c_comment | cpp_comment;
+ignore              = ws | comment;
+name_separator      = ':';
+value_separator     = ',';
+Vnull               = 'null';
+Vfalse              = 'false';
+Vtrue               = 'true';
+VNaN                = 'NaN';
+VInfinity           = 'Infinity';
+VMinusInfinity      = '-Infinity';
+begin_value         = [nft\"\-\[\{NI] | digit;
+begin_object        = '{';
+end_object          = '}';
+begin_array         = '[';
+end_array           = ']';
+begin_string        = '"';
+begin_name          = begin_string;
+begin_number        = digit | '-';
+ +

}%%

+ +

%%{

+ +
machine JSON_object;
+include JSON_common;
+
+write data;
+
+action parse_value {
+    VALUE v = Qnil;
+    char *np = JSON_parse_value(json, fpc, pe, &v, current_nesting);
+    if (np == NULL) {
+        fhold; fbreak;
+    } else {
+        if (NIL_P(json->object_class)) {
+            rb_hash_aset(*result, last_name, v);
+        } else {
+            rb_funcall(*result, i_aset, 2, last_name, v);
+        }
+        fexec np;
+    }
+}
+
+action parse_name {
+    char *np;
+    json->parsing_name = 1;
+    np = JSON_parse_string(json, fpc, pe, &last_name);
+    json->parsing_name = 0;
+    if (np == NULL) { fhold; fbreak; } else fexec np;
+}
+
+action exit { fhold; fbreak; }
+
+pair  = ignore* begin_name >parse_name ignore* name_separator ignore* begin_value >parse_value;
+next_pair   = ignore* value_separator pair;
+
+main := (
+  begin_object
+  (pair (next_pair)*)? ignore*
+  end_object
+) @exit;
+ +

}%%

+ +

static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE +*result, int current_nesting) {

+ +
int cs = EVIL;
+VALUE last_name = Qnil;
+VALUE object_class = json->object_class;
+
+if (json->max_nesting && current_nesting > json->max_nesting) {
+    rb_raise(eNestingError, "nesting of %d is too deep", current_nesting);
+}
+
+ result = NIL_P(object_class) ? rb_hash_new() : rb_class_new_instance(0, 0, object_class);
+
+%% write init;
+%% write exec;
+
+if (cs >= JSON_object_first_final) {
+    if (json->create_additions) {
+        VALUE klassname;
+        if (NIL_P(json->object_class)) {
+          klassname = rb_hash_aref(*result, json->create_id);
+        } else {
+          klassname = rb_funcall(*result, i_aref, 1, json->create_id);
+        }
+        if (!NIL_P(klassname)) {
+            VALUE klass = rb_funcall(mJSON, i_deep_const_get, 1, klassname);
+            if (RTEST(rb_funcall(klass, i_json_creatable_p, 0))) {
+                 result = rb_funcall(klass, i_json_create, 1, *result);
+            }
+        }
+    }
+    return p + 1;
+} else {
+    return NULL;
+}
+ +

}

+ +

%%{

+ +
machine JSON_value;
+include JSON_common;
+
+write data;
+
+action parse_null {
+     result = Qnil;
+}
+action parse_false {
+     result = Qfalse;
+}
+action parse_true {
+     result = Qtrue;
+}
+action parse_nan {
+    if (json->allow_nan) {
+         result = CNaN;
+    } else {
+        rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p - 2);
+    }
+}
+action parse_infinity {
+    if (json->allow_nan) {
+         result = CInfinity;
+    } else {
+        rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p - 8);
+    }
+}
+action parse_string {
+    char *np = JSON_parse_string(json, fpc, pe, result);
+    if (np == NULL) { fhold; fbreak; } else fexec np;
+}
+
+action parse_number {
+    char *np;
+    if(pe > fpc + 8 && !strncmp(MinusInfinity, fpc, 9)) {
+        if (json->allow_nan) {
+             result = CMinusInfinity;
+            fexec p + 10;
+            fhold; fbreak;
+        } else {
+            rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
+        }
+    }
+    np = JSON_parse_float(json, fpc, pe, result);
+    if (np != NULL) fexec np;
+    np = JSON_parse_integer(json, fpc, pe, result);
+    if (np != NULL) fexec np;
+    fhold; fbreak;
+}
+
+action parse_array {
+    char *np;
+    np = JSON_parse_array(json, fpc, pe, result, current_nesting + 1);
+    if (np == NULL) { fhold; fbreak; } else fexec np;
+}
+
+action parse_object {
+    char *np;
+    np =  JSON_parse_object(json, fpc, pe, result, current_nesting + 1);
+    if (np == NULL) { fhold; fbreak; } else fexec np;
+}
+
+action exit { fhold; fbreak; }
+ +

main := ignore* (

+ +
      Vnull @parse_null |
+      Vfalse @parse_false |
+      Vtrue @parse_true |
+      VNaN @parse_nan |
+      VInfinity @parse_infinity |
+      begin_number >parse_number |
+      begin_string >parse_string |
+      begin_array >parse_array |
+      begin_object >parse_object
+) ignore* %*exit;
+ +

}%%

+ +

static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE +*result, int current_nesting) {

+ +
int cs = EVIL;
+
+%% write init;
+%% write exec;
+
+if (cs >= JSON_value_first_final) {
+    return p;
+} else {
+    return NULL;
+}
+ +

}

+ +

%%{

+ +
machine JSON_integer;
+
+write data;
+
+action exit { fhold; fbreak; }
+
+main := '-'? ('0' | [1-9][0-9]*) (^[0-9]? @exit);
+ +

}%%

+ +

static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE +*result) {

+ +
int cs = EVIL;
+
+%% write init;
+json->memo = p;
+%% write exec;
+
+if (cs >= JSON_integer_first_final) {
+    long len = p - json->memo;
+    fbuffer_clear(json->fbuffer);
+    fbuffer_append(json->fbuffer, json->memo, len);
+    fbuffer_append_char(json->fbuffer, '\0');
+     result = rb_cstr2inum(FBUFFER_PTR(json->fbuffer), 10);
+    return p + 1;
+} else {
+    return NULL;
+}
+ +

}

+ +

%%{

+ +
machine JSON_float;
+include JSON_common;
+
+write data;
+
+action exit { fhold; fbreak; }
+
+main := '-'? (
+          (('0' | [1-9][0-9]*) '.' [0-9]+ ([Ee] [+\-]?[0-9]+)?)
+          | (('0' | [1-9][0-9]*) ([Ee] [+\-]?[0-9]+))
+         )  (^[0-9Ee.\-]? @exit );
+ +

}%%

+ +

static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE +*result) {

+ +
int cs = EVIL;
+
+%% write init;
+json->memo = p;
+%% write exec;
+
+if (cs >= JSON_float_first_final) {
+    long len = p - json->memo;
+    fbuffer_clear(json->fbuffer);
+    fbuffer_append(json->fbuffer, json->memo, len);
+    fbuffer_append_char(json->fbuffer, '\0');
+    if (NIL_P(json->decimal_class)) {
+       result = rb_float_new(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1));
+    } else {
+      VALUE text;
+      text = rb_str_new2(FBUFFER_PTR(json->fbuffer));
+       result = rb_funcall(json->decimal_class, i_new, 1, text);
+    }
+    return p + 1;
+} else {
+    return NULL;
+}
+ +

}

+ +

%%{

+ +
machine JSON_array;
+include JSON_common;
+
+write data;
+
+action parse_value {
+    VALUE v = Qnil;
+    char *np = JSON_parse_value(json, fpc, pe, &v, current_nesting);
+    if (np == NULL) {
+        fhold; fbreak;
+    } else {
+        if (NIL_P(json->array_class)) {
+            rb_ary_push(*result, v);
+        } else {
+            rb_funcall(*result, i_leftshift, 1, v);
+        }
+        fexec np;
+    }
+}
+
+action exit { fhold; fbreak; }
+
+next_element  = value_separator ignore* begin_value >parse_value;
+
+main := begin_array ignore*
+      ((begin_value >parse_value ignore*)
+       (ignore* next_element ignore*)*)?
+      end_array @exit;
+ +

}%%

+ +

static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE +*result, int current_nesting) {

+ +
int cs = EVIL;
+VALUE array_class = json->array_class;
+
+if (json->max_nesting && current_nesting > json->max_nesting) {
+    rb_raise(eNestingError, "nesting of %d is too deep", current_nesting);
+}
+ result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class);
+
+%% write init;
+%% write exec;
+
+if(cs >= JSON_array_first_final) {
+    return p + 1;
+} else {
+    rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
+    return NULL;
+}
+ +

}

+ +

static VALUE json_string_unescape(VALUE result, char *string, char +*stringEnd) {

+ +
char *p = string, *pe = string, *unescape;
+int unescape_len;
+char buf[4];
+
+while (pe < stringEnd) {
+    if (*pe == '\\') {
+        unescape = (char *) "?";
+        unescape_len = 1;
+        if (pe > p) rb_str_buf_cat(result, p, pe - p);
+        switch (*++pe) {
+            case 'n':
+                unescape = (char *) "\n";
+                break;
+            case 'r':
+                unescape = (char *) "\r";
+                break;
+            case 't':
+                unescape = (char *) "\t";
+                break;
+            case '"':
+                unescape = (char *) "\"";
+                break;
+            case '\\':
+                unescape = (char *) "\\";
+                break;
+            case 'b':
+                unescape = (char *) "\b";
+                break;
+            case 'f':
+                unescape = (char *) "\f";
+                break;
+            case 'u':
+                if (pe > stringEnd - 4) {
+                  rb_enc_raise(
+                    EXC_ENCODING eParserError,
+                    "%u: incomplete unicode character escape sequence at '%s'", __LINE__, p
+                  );
+                } else {
+                    UTF32 ch = unescape_unicode((unsigned char *) ++pe);
+                    pe += 3;
+                    if (UNI_SUR_HIGH_START == (ch & 0xFC00)) {
+                        pe++;
+                        if (pe > stringEnd - 6) {
+                          rb_enc_raise(
+                            EXC_ENCODING eParserError,
+                            "%u: incomplete surrogate pair at '%s'", __LINE__, p
+                            );
+                        }
+                        if (pe[0] == '\\' && pe[1] == 'u') {
+                            UTF32 sur = unescape_unicode((unsigned char *) pe + 2);
+                            ch = (((ch & 0x3F) << 10) | ((((ch >> 6) & 0xF) + 1) << 16)
+                                    | (sur & 0x3FF));
+                            pe += 5;
+                        } else {
+                            unescape = (char *) "?";
+                            break;
+                        }
+                    }
+                    unescape_len = convert_UTF32_to_UTF8(buf, ch);
+                    unescape = buf;
+                }
+                break;
+            default:
+                p = pe;
+                continue;
+        }
+        rb_str_buf_cat(result, unescape, unescape_len);
+        p = ++pe;
+    } else {
+        pe++;
+    }
+}
+rb_str_buf_cat(result, p, pe - p);
+return result;
+ +

}

+ +

%%{

+ +
machine JSON_string;
+include JSON_common;
+
+write data;
+
+action parse_string {
+     result = json_string_unescape(*result, json->memo + 1, p);
+    if (NIL_P(*result)) {
+        fhold;
+        fbreak;
+    } else {
+        FORCE_UTF8(*result);
+        fexec p + 1;
+    }
+}
+
+action exit { fhold; fbreak; }
+
+main := '"' ((^([\"\\] | 0..0x1f) | '\\'[\"\\/bfnrt] | '\\u'[0-9a-fA-F]{4} | '\\'^([\"\\/bfnrtu]|0..0x1f))* %parse_string) '"' @exit;
+ +

}%%

+ +

static int match_i(VALUE regexp, VALUE klass, VALUE memo) {

+ +
if (regexp == Qundef) return ST_STOP;
+if (RTEST(rb_funcall(klass, i_json_creatable_p, 0)) &&
+  RTEST(rb_funcall(regexp, i_match, 1, rb_ary_entry(memo, 0)))) {
+    rb_ary_push(memo, klass);
+    return ST_STOP;
+}
+return ST_CONTINUE;
+ +

}

+ +

static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE +*result) {

+ +
int cs = EVIL;
+VALUE match_string;
+
+ result = rb_str_buf_new(0);
+%% write init;
+json->memo = p;
+%% write exec;
+
+if (json->create_additions && RTEST(match_string = json->match_string)) {
+      VALUE klass;
+      VALUE memo = rb_ary_new2(2);
+      rb_ary_push(memo, *result);
+      rb_hash_foreach(match_string, match_i, memo);
+      klass = rb_ary_entry(memo, 1);
+      if (RTEST(klass)) {
+           result = rb_funcall(klass, i_json_create, 1, *result);
+      }
+}
+
+if (json->symbolize_names && json->parsing_name) {
+   result = rb_str_intern(*result);
+} else {
+  rb_str_resize(*result, RSTRING_LEN(*result));
+}
+if (cs >= JSON_string_first_final) {
+    return p + 1;
+} else {
+    return NULL;
+}
+ +

}

+ +

/*

+ +
 Document-class: JSON::Ext::Parser
+
+ This is the JSON parser implemented as a C extension. It can be configured
+ to be used by setting
+
+  JSON.parser = JSON::Ext::Parser
+
+ with the method parser= in JSON.
+
+/
+ +

static VALUE convert_encoding(VALUE source) { ifdef HAVE_RUBY_ENCODING_H

+ +
rb_encoding *enc = rb_enc_get(source);
+if (enc == rb_ascii8bit_encoding()) {
+  if (OBJ_FROZEN(source)) {
+    source = rb_str_dup(source);
+  }
+  FORCE_UTF8(source);
+} else {
+  source = rb_str_conv_enc(source, rb_enc_get(source), rb_utf8_encoding());
+}
+ +

endif

+ +
return source;
+
+ +

}

+ +

/*

+ +
 call-seq: new(source, opts => {})
+
+ Creates a new JSON::Ext::Parser instance for the string _source_.
+
+ Creates a new JSON::Ext::Parser instance for the string _source_.
+
+ It will be configured by the _opts_ hash. _opts_ can have the following
+ keys:
+
+ _opts_ can have the following keys:
+   *max_nesting*: The maximum depth of nesting allowed in the parsed data
+   structures. Disable depth checking with :max_nesting => false|nil|0, it
+   defaults to 100.
+   *allow_nan*: If set to true, allow NaN, Infinity and -Infinity in
+   defiance of RFC 4627 to be parsed by the Parser. This option defaults to
+   false.
+   *symbolize_names*: If set to true, returns symbols for the names
+   (keys) in a JSON object. Otherwise strings are returned, which is
+   also the default. It's not possible to use this option in
+   conjunction with the *create_additions* option.
+   *create_additions*: If set to false, the Parser doesn't create
+   additions even if a matching class and create_id was found. This option
+   defaults to false.
+   *object_class*: Defaults to Hash
+   *array_class*: Defaults to Array
+/
+ +

static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) {

+ +
VALUE source, opts;
+GET_PARSER_INIT;
+
+if (json->Vsource) {
+    rb_raise(rb_eTypeError, "already initialized instance");
+}
+ +

ifdef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH

+ +
rb_scan_args(argc, argv, "1:", &source, &opts);
+ +

else

+ +
rb_scan_args(argc, argv, "11", &source, &opts);
+ +

endif

+ +
if (!NIL_P(opts)) {
+ +

ifndef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH

+ +
opts = rb_convert_type(opts, T_HASH, "Hash", "to_hash");
+if (NIL_P(opts)) {
+    rb_raise(rb_eArgError, "opts needs to be like a hash");
+} else {
+ +

endif

+ +
VALUE tmp = ID2SYM(i_max_nesting);
+if (option_given_p(opts, tmp)) {
+    VALUE max_nesting = rb_hash_aref(opts, tmp);
+    if (RTEST(max_nesting)) {
+        Check_Type(max_nesting, T_FIXNUM);
+        json->max_nesting = FIX2INT(max_nesting);
+    } else {
+        json->max_nesting = 0;
+    }
+} else {
+    json->max_nesting = 100;
+}
+tmp = ID2SYM(i_allow_nan);
+if (option_given_p(opts, tmp)) {
+    json->allow_nan = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
+} else {
+    json->allow_nan = 0;
+}
+tmp = ID2SYM(i_symbolize_names);
+if (option_given_p(opts, tmp)) {
+    json->symbolize_names = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
+} else {
+    json->symbolize_names = 0;
+}
+tmp = ID2SYM(i_create_additions);
+if (option_given_p(opts, tmp)) {
+    json->create_additions = RTEST(rb_hash_aref(opts, tmp));
+} else {
+    json->create_additions = 0;
+}
+if (json->symbolize_names && json->create_additions) {
+  rb_raise(rb_eArgError,
+    "options :symbolize_names and :create_additions cannot be "
+    " used in conjunction");
+}
+tmp = ID2SYM(i_create_id);
+if (option_given_p(opts, tmp)) {
+    json->create_id = rb_hash_aref(opts, tmp);
+} else {
+    json->create_id = rb_funcall(mJSON, i_create_id, 0);
+}
+tmp = ID2SYM(i_object_class);
+if (option_given_p(opts, tmp)) {
+    json->object_class = rb_hash_aref(opts, tmp);
+} else {
+    json->object_class = Qnil;
+}
+tmp = ID2SYM(i_array_class);
+if (option_given_p(opts, tmp)) {
+    json->array_class = rb_hash_aref(opts, tmp);
+} else {
+    json->array_class = Qnil;
+}
+tmp = ID2SYM(i_decimal_class);
+if (option_given_p(opts, tmp)) {
+    json->decimal_class = rb_hash_aref(opts, tmp);
+} else {
+    json->decimal_class = Qnil;
+}
+tmp = ID2SYM(i_match_string);
+if (option_given_p(opts, tmp)) {
+    VALUE match_string = rb_hash_aref(opts, tmp);
+    json->match_string = RTEST(match_string) ? match_string : Qnil;
+} else {
+    json->match_string = Qnil;
+}
+ +

ifndef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH

+ +
}
+ +

endif

+ +
} else {
+    json->max_nesting = 100;
+    json->allow_nan = 0;
+    json->create_additions = 1;
+    json->create_id = rb_funcall(mJSON, i_create_id, 0);
+    json->object_class = Qnil;
+    json->array_class = Qnil;
+    json->decimal_class = Qnil;
+}
+source = convert_encoding(StringValue(source));
+StringValue(source);
+json->len = RSTRING_LEN(source);
+json->source = RSTRING_PTR(source);;
+json->Vsource = source;
+return self;
+ +

}

+ +

%%{

+ +
machine JSON;
+
+write data;
+
+include JSON_common;
+
+action parse_value {
+    char *np = JSON_parse_value(json, fpc, pe, &result, 0);
+    if (np == NULL) { fhold; fbreak; } else fexec np;
+}
+
+main := ignore* (
+        begin_value >parse_value
+        ) ignore*;
+ +

}%%

+ +

/*

+ +
 call-seq: parse()
+
+  Parses the current JSON text _source_ and returns the complete data
+  structure as a result.
+/
+ +

static VALUE cParser_parse(VALUE self) {

+ +
char *p, *pe;
+int cs = EVIL;
+VALUE result = Qnil;
+GET_PARSER;
+
+%% write init;
+p = json->source;
+pe = p + json->len;
+%% write exec;
+
+if (cs >= JSON_first_final && p == pe) {
+  return result;
+} else {
+  rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
+  return Qnil;
+}
+ +

}

+ +

static void JSON_mark(void *ptr) {

+ +
JSON_Parser *json = ptr;
+rb_gc_mark_maybe(json->Vsource);
+rb_gc_mark_maybe(json->create_id);
+rb_gc_mark_maybe(json->object_class);
+rb_gc_mark_maybe(json->array_class);
+rb_gc_mark_maybe(json->decimal_class);
+rb_gc_mark_maybe(json->match_string);
+ +

}

+ +

static void JSON_free(void *ptr) {

+ +
JSON_Parser *json = ptr;
+fbuffer_free(json->fbuffer);
+ruby_xfree(json);
+ +

}

+ +

static size_t JSON_memsize(const void *ptr) {

+ +
const JSON_Parser *json = ptr;
+return sizeof(*json) + FBUFFER_CAPA(json->fbuffer);
+ +

}

+ +

ifdef NEW_TYPEDDATA_WRAPPER static const rb_data_type_t JSON_Parser_type = +{

+ +
"JSON/Parser",
+{JSON_mark, JSON_free, JSON_memsize,},
+ +

ifdef RUBY_TYPED_FREE_IMMEDIATELY

+ +
0, 0,
+RUBY_TYPED_FREE_IMMEDIATELY,
+ +

endif }; endif

+ +

static VALUE cJSON_parser_s_allocate(VALUE klass) {

+ +
JSON_Parser *json;
+VALUE obj = TypedData_Make_Struct(klass, JSON_Parser, &JSON_Parser_type, json);
+json->fbuffer = fbuffer_alloc(0);
+return obj;
+ +

}

+ +

/*

+ +
 call-seq: source()
+
+ Returns a copy of the current _source_ string, that was used to construct
+ this Parser.
+/
+ +

static VALUE cParser_source(VALUE self) {

+ +
GET_PARSER;
+return rb_str_dup(json->Vsource);
+ +

}

+ +

void Init_parser(void) {

+ +
rb_require("json/common");
+mJSON = rb_define_module("JSON");
+mExt = rb_define_module_under(mJSON, "Ext");
+cParser = rb_define_class_under(mExt, "Parser", rb_cObject);
+eParserError = rb_path2class("JSON::ParserError");
+eNestingError = rb_path2class("JSON::NestingError");
+rb_define_alloc_func(cParser, cJSON_parser_s_allocate);
+rb_define_method(cParser, "initialize", cParser_initialize, -1);
+rb_define_method(cParser, "parse", cParser_parse, 0);
+rb_define_method(cParser, "source", cParser_source, 0);
+
+CNaN = rb_const_get(mJSON, rb_intern("NaN"));
+CInfinity = rb_const_get(mJSON, rb_intern("Infinity"));
+CMinusInfinity = rb_const_get(mJSON, rb_intern("MinusInfinity"));
+
+i_json_creatable_p = rb_intern("json_creatable?");
+i_json_create = rb_intern("json_create");
+i_create_id = rb_intern("create_id");
+i_create_additions = rb_intern("create_additions");
+i_chr = rb_intern("chr");
+i_max_nesting = rb_intern("max_nesting");
+i_allow_nan = rb_intern("allow_nan");
+i_symbolize_names = rb_intern("symbolize_names");
+i_object_class = rb_intern("object_class");
+i_array_class = rb_intern("array_class");
+i_decimal_class = rb_intern("decimal_class");
+i_match = rb_intern("match");
+i_match_string = rb_intern("match_string");
+i_key_p = rb_intern("key?");
+i_deep_const_get = rb_intern("deep_const_get");
+i_aset = rb_intern("[]=");
+i_aref = rb_intern("[]");
+i_leftshift = rb_intern("<<");
+i_new = rb_intern("new");
+
+ +

}

+ +

/*

+ +
 Local variables:
+ mode: c
+ c-file-style: ruby
+ indent-tabs-mode: nil
+ End:
+/
+
+ + + + + diff --git a/tmp/rdoc/fonts/Lato-Light.ttf b/tmp/rdoc/fonts/Lato-Light.ttf new file mode 100644 index 0000000000000000000000000000000000000000..b49dd43729d456e489a8f4c8ec323a47ab8b9ae8 GIT binary patch literal 94668 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

FsulxL_Yn=fqW!JSYn4UZz_VI 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 literal 0 HcmV?d00001 diff --git a/tmp/rdoc/fonts/Lato-LightItalic.ttf b/tmp/rdoc/fonts/Lato-LightItalic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..7959fef0756e905627298817d86513fdf26d6922 GIT binary patch literal 94196 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 Sv(kH?wp@?o-S`p3*#7{ysOP%? literal 0 HcmV?d00001 diff --git a/tmp/rdoc/fonts/Lato-Regular.ttf b/tmp/rdoc/fonts/Lato-Regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..839cd589dc5eba0da98b43451b4ec6c328ca48b8 GIT binary patch literal 96184 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

ucu-&%9a>XM7550A4YWv99%x~0LA&?HZ)eRytM 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 literal 0 HcmV?d00001 diff --git a/tmp/rdoc/fonts/Lato-RegularItalic.ttf b/tmp/rdoc/fonts/Lato-RegularItalic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..bababa09e3fad2aa3e788898e7753ff8d80a8e8f GIT binary patch literal 95316 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 Zdy6Gm=sD%RPg|bPWWD$h#s3t#{x=NUkZJ$` literal 0 HcmV?d00001 diff --git a/tmp/rdoc/fonts/SourceCodePro-Bold.ttf b/tmp/rdoc/fonts/SourceCodePro-Bold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..61e3090c1c6944db11572b8d1e3177402f128c02 GIT binary patch literal 71200 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 P00000NkvXXu0mjf^IS-S literal 0 HcmV?d00001 diff --git a/tmp/rdoc/images/arrow_up.png b/tmp/rdoc/images/arrow_up.png new file mode 100644 index 0000000000000000000000000000000000000000..1ebb193243780b8eb1919a51ef27c2a0d36ccec2 GIT binary patch literal 372 zcmV-)0gL{LP)6w#wHUuW*nL5>vZR zlg{G&%mT~|kL3ei%GW0*UOHUMs5XI$4uxe-L?I@SAefq*207}Iqtjm#e5*fP53AiC z)C|RQfwzxx<#_WfANRGZx{+tFDl8~Q?;~Ve=lM^*8UTTnVL?HTDz8uta0D@d28E9S z_)i8aLz^UE6PPKymi;2GJ`34{eIia-CtfAt0H61rk0 SPTNud0000Pdwe5?6tW?r-ok|b$oDQj8FV%kZPq;(MWOV8?8;<)(iP}>hNMU> z7fbz%jjlr7h8uuoQ~J6}n}@Y@PdTk=)PxO{%7zmL?dchpZX*~n;I{!C>*(8cU;q(~ zAS%Po_@naEU!xidrBXD?;hN|x^%W|Ij)0y*r5vi|?W&Fub(NqJ@z0o=O&SR3v>A``^efOSo-hEdApp;^Jd;9y!%1UfzX6Bh- z%-mbG|0Na{7Ruai_Y+DEb1s+b!*9k%Q!whMxjtZKA*?o;i1g&jy0@( zaU=-@d-h+o%gal6JRXEXA&L3`d2 z%jIxzZ~*p9O-;EJp_Ds0If38rM<5W8ic~K>FOK&2_p!CLg^i63OioVb6k$)zWHLx3 z5;!|M!}<9+#QSi1dRlbEcxPt^;cysUuU8@%3}RwpLRIGG<|IKnoyP6$Eh3SKw7a*r zSDXP=IYc&YZf;7@?fCe($^l9ORaJ3wbAx0uiC8QqRr$2t-Cfy8%XCI3B%pxJW>XdM zw~zPt_s}#A@pxQ5Ly)4szaMtH9lgE1SXx@b+S(fW`ub$fYPE8J7#bSNDzme*Ub07{ zQKV8SjEs!%0@v5ql8ggm!@$6Rbi^E8vBqpRM-}l+@5OSMrl+TWj*gC^qoV@>u{fQb zov5v?g~?>X@bEC&+uLPaQ&Ypn-y~^mZA}+f(&2EFH8eE%dU|@ENpN*_1-)L6_4Rc* zFuq@`IjX9vp1QiaK9ZojyZhnQURP99d=u;%37VRkpwsD4U0sd3x;hEQB&e^i|3QN0 z=H|Os1fRqaw!?#igLmS4HE!G3*ce(`TF} zlgUq0Q544c8(ae&UR$8ps&snq6^bPY3v3xAmMW74Di$h~GCH6E3TaYs2#6A<7K*gC z777H71_Wa;(dfp+g-drPCSWu)#PInZi72LJ;o?i~$-U=y&UbQ89Dul3%3P+Axkzc* zbH-y;QF=hR{qLItf%ci2_&e5wNo0gnVatG?ul6Zw=o$I9Ljfn*ic3`U?>IfEim3g{ zujU&$-hy6wn;w(xme|zJm;lWJxtTFfM)q0`kX!Vu0+d${$}LCddK1<^htTe-fUYL3 zB`SdNsZD>RgvLj1<^@h6_+cDRK2Brcr2~>%$*5S)hyV33PV^teac3%|4lz@8p4?)5 z?t5o^?q+%^%)Yygo~I^U4VR!bTnWuE35hcWrfCDR3q+sxJ79e7Fg`&)RCqLA^2^y^ z0laVfadW90_Fz8Brm|r47sB^u1VgI>kanj)Z4`zMSfHlm8>CwXa$JVM`$2RrmZB-3 zN10m-!;BvH*Br3V8t`DH7m`jf#2upVDXl{5ff18_pzCPK1Zu$$CKKvd8FGeFf)+K<|x33pc7P&S#3GZT4mEw;nr(Ze*F z3&*?-4U-lm*#tber5 z%S_ceqB`b3ko6r~BbvDwdohTvP(3a(pq{x#T$yQsu#OKwEe}KuH^Mh@nxg_(Nw136 zq#a^3xNBke)In+!?qk3%4wB69{pF`Tzg`07*qoM6N<$ Eg55P&8UO$Q literal 0 HcmV?d00001 diff --git a/tmp/rdoc/images/bullet_black.png b/tmp/rdoc/images/bullet_black.png new file mode 100644 index 0000000000000000000000000000000000000000..57619706d10d9736b1849a83f2c5694fbe09c53b GIT binary patch literal 211 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^zbpD<_bdI{u9mbgZg z1m~xflqVLYGB~E>C#5QQ<|d}62BjvZR2H60wE-$h^>lFz(Kw&{<9vg>5sw~gS5O!4 zr|{HuUFIBKiQyL}eBJ-L{`UVT|6_O~L{G%N{Wbre{kQtZ_0LvEhC#5QQ<|d}62BjvZR2H60wE-$h^mK6y(Kw&{<9vg>(S^W+6Zii9 z|Nhthr~iNb*Z!}6uiN$Dz5neG3a-`baBX8yz1H+_;eX)`ni0%X8XBDc-`=Ph(Uan2 zYsR{H!kvIN--9isvHznRsC#5QQ<|d}62BjvZR2H60wE-$h_H=O!(Kw&{<9vg>(S^W+6Zii9 z|Nhthr~iNb*Z!}6uiN$Dz5neG3a-`baBX8yz4q@v|B?28{s)#N@CGn3@%_y|zAV9T z66e<&B4?b6oF&azg|C(V&1ZbI_D}pL`}(^FT2yXwG1Ph~$Q@h8mJYOz!PC{xWt~$( F699+YQR)By literal 0 HcmV?d00001 diff --git a/tmp/rdoc/images/date.png b/tmp/rdoc/images/date.png new file mode 100644 index 0000000000000000000000000000000000000000..783c83357fdf90a1c7c024358e1d768b5c09c135 GIT binary patch literal 626 zcmV-&0*(ENP)5OC%H;f`~O(q$Q#t2<^v$A>fbmv%e#dKTwK=Ku{5lS|}<-`a#7b zzTCOnnT>at)D}AMFuOZ5&%EqFN(lyumd$2ASF6=;nM~%2?gqc@U=#|4PqkX@EBo-9 z7pD#bO_RUa>*faM`8;MYfVi$JnB-zcBFc6gjl$d!bF98Q!!!(Z1_R~P?e!pt#6CHJ9S&n_n&@=9 z%GP;!@Co4c*at+6vNz7o(6en^Q1%qHrc;1)9IRaz-$@S$Z-qdC^ds3X0NvQH;KS)D z-dh&rW&@X;1cS(45z)J&BVt+tv&GMVJ%!EiW) zLBGZW)#Z+gl-Lih&?>X3SS-S#ujQ;9JRXmIB7X)8`d6ETj)D#Q2+$s|<_b7-B9Xvq zwNfqlEp%y3$uY`h{Y$(Gn5@}sqEsq95lpAkFO5dyBmP6^H-51G4J|rN2Ujt<`2YX_ M07*qoM6N<$fC4}Mrzlg<+1Y8PEBfUp0jJpx4B>@E+cy3`^(Gw`Mf+2&yxZm<$to~Vpgvg&QKNR z_f#1(r6svZt%iF?s+n<8X?B&!h3g9Dbb8_=MX}!;HiQSAh`bp^WMl~Z-44teO7W_Y zV4thSL{h;rJY7!l3%5J4H1!tIzB`Dv+YxO(haWeausGZYkI8^hWj6mzo=L0{%;yxzh{5!Htr?51 zvG|W62MzC8BZ76hRpCyO2zOn<%e)K>NHge!-~)Ap33OdWw6hsLYbCxGNt0%wk_2z7 zfyYvXheSG)5HRK1VB~%mq7Dmurw#bi@hEcOr3&G1ZiF*$M=&9nB#VNf&Q^r$4G5kp zTURh&s)E0%5&hyVD}sp<72~zmAY`Y(9aqO6CXF%=zFHGzO-A&I(pE}v70YQxCPJ{Y z4L+?5-crdLn3ZRPEs!A4ehEY3ZRpL~w9>@aMN+{F4dI@v&>(QDHQum!mG~E^$OS8l z!7?%Uwib*ROP67Hw`ika)gX-(8Ia`-u_IEhxG7U<13kSsMW+$lbb2dUMm5p6pa}cjgA+U$^mJ^AjD?&bdi)8~y+Q002ovPDHLkV1g8IMc@Dc literal 0 HcmV?d00001 diff --git a/tmp/rdoc/images/find.png b/tmp/rdoc/images/find.png new file mode 100644 index 0000000000000000000000000000000000000000..1547479646722bda4647df52cf3e8bc9b77428c6 GIT binary patch literal 659 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 Dl)1NK literal 0 HcmV?d00001 diff --git a/tmp/rdoc/images/macFFBgHack.png b/tmp/rdoc/images/macFFBgHack.png new file mode 100644 index 0000000000000000000000000000000000000000..c6473b324ee1dae1faaacc0826639833f551116c GIT binary patch literal 207 zcmeAS@N?(olHy`uVBq!ia0vp^k|4~%1|*NXY)uAIEX7WqAsj$Z!;#Vf4nJ za0`Jjl>Qs8<JF;+Fd5q0wCR k?u=~bH}2*0f`J3~k>FVdQ&MBb@0BAfpf&c&j literal 0 HcmV?d00001 diff --git a/tmp/rdoc/images/package.png b/tmp/rdoc/images/package.png new file mode 100644 index 0000000000000000000000000000000000000000..da3c2a2d74bab159ba0f65d7db601768258afcb2 GIT binary patch literal 853 zcmV-b1FHOqP)5TQ^(M5v$(QKVE?W+9X! z*o}&~6c?_FreF)9NJB7b5Nbn{G0n4+%uJhR9(V5R|NFTpb|HgjefT!tIhLx@DR+N) zV+fHiR5Yt19}k|KnCsND{tH-`IMJ)3AE?OtyZ4>Un|6(d%h#JK`i&a7^xW9>`yBy` zS4SOHeOpC7$?hH5-#7Rswiue_8Ju*2N@$58=a#2OTA3png`w3v->gWif7t%e$ z$NLVS!tFT#8WL|Wa&K~+{%4P2cRfwesYV1_!F=3OaRVHl(>=`%&{x*s30c}#CNE@&;ItrAv!f!)Oy$Q9t$uS=(sD$-J{T*^(8Eez1E-l3}} zPrfHZ1`qsIFe&gipuL8-IZbo2Yg{lFGKs?ZZWcOaOdk*3`5T;$?AjbG1#`B510Er^h2)2r3Y{!8_2Gj=$KzuN5 zaErtW8W_Y2iJJjY)5pmTVJoPJYpanPOEuYHclM^C1F>${hFRpdi8a<2H|Xudf78bm(zwJ9`K%6I?q*Ua~ fW9JvIbn5*B+_J)rUMBs>00000NkvXXu0mjfH&TkY literal 0 HcmV?d00001 diff --git a/tmp/rdoc/images/page_green.png b/tmp/rdoc/images/page_green.png new file mode 100644 index 0000000000000000000000000000000000000000..de8e003f9fb8752c09e7f3655d5d8664b5c62fc3 GIT binary patch literal 621 zcmV-z0+RiSP)QqUjAtB;_Vvt6}AS_5YgM`Uqu`yva+H8^=4U$e4gHb}u zAQ2N{V3A%pO|?Pv?tb6z=jC}SiRa$G^v3q?*6XcYz$p|cq{uLj@#~Fi`J(>5{@&&N zy%T^+;>8cXx%|o77anP?&W1?1A(>-T49z9pyeCl@7YI+Si zKti7=B~``}TImz(G{0PnlQA3P#MAd}sorMjkP!50B7$nAkU^%#nl{Q9lW0@}9fE-> zN(q7tRuiC_T1r|BBtVBTlQ2+70$Rf;eF`Z;lx46Cpu-rEgb)EBKq(b^W8l<^We(`D z43?0=01z<3G6+UUv6`CsWCk6^93!#+<;ws7007{zS3k2k9-zZKFO~(k`>s0y006+1 zgF_jyIhsL-`FMf~JL~C=cV75(CrJ|q;MVO961G=O zm9d)YpJg5g(4i_HKL75eSE}mq$Y}r}hyVdcV~p>6a}oXr80q`oj%+s700000NkvXX Hu0mjfPs|!l literal 0 HcmV?d00001 diff --git a/tmp/rdoc/images/page_white_text.png b/tmp/rdoc/images/page_white_text.png new file mode 100644 index 0000000000000000000000000000000000000000..813f712f726c935f9adf8d2f2dd0d7683791ef11 GIT binary patch literal 342 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^zbpD<_bdI{u9mbgZg z1m~xflqVLYGB~E>C#5QQ<|d}62BjvZR2H60wE-%6;pyTSA|c6o&@eC9QG)Hj&ExYL zO&oVL^)+cM^qd@ApywS>pwx0H@RDN}hq;7mU-SKczYQ-hnrr=;iDAQMZQ+*g=YOM= z!QlMQEn7FbaD->uKAYgo_j9)W&$$zS*W9}m(ey0q$&7l-XEWO0Y(9M=SnhLbwy;d>@~SY$Ku*0xPvIOQeV1x7u_z-2-X>_74(yfh7C znXL|3GZ+d2`3re2hs?MKC#5QQ<|d}62BjvZR2H60wE-$R?&;zfqH(@;q9b3Efq-lM(nr^( z=EYR73-9e)UYMWsXy%?aZsD68Yyv^2$~6QgEcljw%kx>O(f-gQ?@fOOx3A-0+Qw?O zRx~W)kn~Qe2d6f9nMG#g9Q04Mk==M~N!Dglvxk!fgVh#w@ZV$IY1+Xc`d{d2UcaP~ zfWp)_Ivqj}l2SPy^9ZWy6rG9Yx4v67_uA&&9|XA~5-#3)W3%em1peD8RWH^#O%XoM zxMPud%}GTj#~*+7JMxTd!`{^Q+>(D3*|@KV`*G2;{QnANOxu1$r2xIe;OXk;vd$@? F2>@zac~<}c literal 0 HcmV?d00001 diff --git a/tmp/rdoc/images/plugin.png b/tmp/rdoc/images/plugin.png new file mode 100644 index 0000000000000000000000000000000000000000..6187b15aec001b7080b51a5f944f07591f26cc15 GIT binary patch literal 591 zcmV-V0eEcNHZMNv|IbJ-M`( zKwWL~opzjJe^WpCmV9E;(0&ut2;4va_(#>M8)>9$R5viQnf(Nkh~VM$y>J(jqb$cj z+nL1Nm|mV)Gm|9MnHf*7Ja4OEAQz__^LRKOLEwqpiGV^^A*T=#&inGm-62Xs;dnSp zKj&H9T*boh2i)W+(n27l!C)>fq|L%VB1i ziC4p;NwV_}ZjW7$LRW#(_bKF#hp=!IqNO26Z*w2+LEwx{PVnZ&Sn}T;mtzb$;qA*nT@@+ zV5uQ@iXDTPoTbV#FRr~z04|PPh`wXTNoCm9*tG&?e3+fYl>K6+&3|Cc$KOpL`ER+_ dcRl5U#9zn6ZO}GFk7R5;7c zlif>`Q5?tj7Yw@ZCMtTF^Q|ZedeJhM%QPCR*bs8V79p$QTo7e94yQNXRs-{0?hOn_-8n0AMO@u1Ts zNl8QzJs1#rz%RBt?ux>l+amAvh+J!{$lkaqv}+Erb-6j2xp>K4GLQnNB*W`hFg*?P z^AL@~(h~Z+wfcWEXHqV^Tq-#z$7Y#o0;yFxA!00F}F2dX# zjE$iOgT#G4*1TR6kB1Gnn@>$meCh2a>c5YuIvFn-R2W@>4@M*m@-|jiDV?b)bccgA zyPfsMM!rjy>+1O2)5Eg29Z_*2p&qGnmS!OH?vZ(4>QB01d>j%9n4QINxkyT(Dos?I zjaWF$*IQmh`SF-?xU%xMEfjq1=6qY*g&lgG_cXv$BGoIWyfO5 zp>pdV*O+y=&6@N2WWFo(%RtT`Q(H^6zn^a%epE~Kx^mEJ{c8`luC$nc*z9j|4Ms8aJK-ladKLpnAK z!yd|CC&>l1b7`m$MH$ScEIP@XgT41O>|DzL{-38CH68OyX#u=G?d7;y&_o&o)f@3U z2(tr%Ok88caOL`xiQA8o;Vzr-$A$SOu6o|$&0DQAJ1Z7?OACaeoy+)PWu&~aueW<| z*KW^(^2}#30u*~<_mXScFNd6U&sxh5*GGMNytZGxkIGqL%v6329^u`FD6T?b?K!4B z@Hzh?O2Au=((Gu;rvgLMt^pS|u1rEkBgC8$oH%zgT`TvZiK#VDrVG?-i~6a_+WZb> zc1>>lb)xcuo^Cl8k%q3c_d*It_Vtj>RSovF&w;hS=6uYrT2e@-@l@P~uBN`zu!v>e zTm(is&jcQ6vuP?|;!e+(n8w)-Xjd!hwk@r2D0i00ygdKo2Xvs?&w_lajj5DHS@9I! z;_&ji2e{!uusGnVn};Pu|dl5x-FhQyC8^-4Uo_;BLiOXzcE z&4PS2TBWSC=hsw0og;z#(mly@Ed2E1E$_VDaM?kloE4ob2XK&K;OS~-nhIGlA4~UZrJu6*|}wi#TT?|yWUH+_&n($t0xta zBwTzSfE)uAw*L0>+`pTps}L-$jIP5Q_E$Am+l|{XfsKr0Vi~`Em?SJQ#0y)8vsxb1 zMdxJl^){_CDwI^}>)Pw${G?Ajc@P}x{Fvhoi0jbY^427?KPmoA_G)sqK}u$2(79Xg zC%}xm5JDcrsm5^vQEQpGEdJDc^yfuNAlqV1pZQVkOSceV<|{=|=@?=o4i_1RFUZth zC7cu<6%V3dVCI}P6DL4iUgTc@&(nXY)ox}HZ z(a#EgiNj%{kjRLL2t?{m_aKN`{5-&u+HAtQ-Qq#@!I@<(M+B3i@|g=LY6 z90tpW!JuMn_Lcy1q7g&LUSuLE3XS}K#P^nHVUmL`L)dbP| z0bt(+Cp#M-bH!LM*DzJ0Lfn;eTBV@|JvGSgpdoc1RhhV>(G-2(vE|>MrVgA9+?+0m4OzUqbT>-U-jg|v zLZMntq`r?fy1UCMh>z2Koi1SL-~N2ZrIf+dZW|;SWszsde}Dl!HOMc1Fa>K9)e&RI z)A?aK zcviCdKDUg_%#u7YAE`A`Y3$(P4&m^@fEWAvjAwVmRWeUnmkrxA;E!fKoc{9Vi=lvFL}KmoS;g* zdjL?Y!VHUFq63aLj6VZE+tHts?Z1pFkiO9^k*5pGpFpU&5#5G4ATd{t>a&9zKBVB9=Ns^HFU|DTGH8C+Xr2UqOU`Zxe)!|%j4=-QojGePq)pRGe;!f)Czk!u3vP_Jxu8(e6 zf4Q`F$Qio2Jw@N*E@k?c`+Sw}AYQjkT+x)OAe6eq(AT!iRuksKQn%Ao_Ac1T-p#Js I_CnHs0qX}mlmGw# literal 0 HcmV?d00001 diff --git a/tmp/rdoc/images/tag_green.png b/tmp/rdoc/images/tag_green.png new file mode 100644 index 0000000000000000000000000000000000000000..83ec984bd73364134da0f98d27a800c5d3264180 GIT binary patch literal 613 zcmV-r0-F7aP)^5T)AZ%#@G{_P{NCN^P z(J0zvSn~SSm(Ur);-M~8^*;61*VRI`T1BN&LAhK;sZ>I-SVW;vfUfJv=ko^ugnc0x zhJodBxe>iyk3%w<%wC8holUJ4(iv>tL{`DQt zPOsyUbO_Cmc&*iHkqbm3ku`|GcC^OhF>jj9W*GkH;^g!iUVpib_h*=@udp4h(P+e*zL_~ZmJjh(y^BxULwq>9zXoYE8sq{#pN~U0C6!8vY)5N2 z9P*}mw}7X$O^qTtJef1ACWvJT9^wt-)Zh0r~j#0bT`f;-zv6 z^Tmw22!%rMcs!TaUX<-8s;X-B`+Xbo+_uWuFa z1yIPc?DTrQ7KvRhmt*TG|L=EYQ=LqFX;=Lp`4}jx6BE-@00000NkvXXu0mjf=s_29 literal 0 HcmV?d00001 diff --git a/tmp/rdoc/images/transparent.png b/tmp/rdoc/images/transparent.png new file mode 100644 index 0000000000000000000000000000000000000000..d665e179efd797451084235f105425247fea0a14 GIT binary patch literal 97 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!D3?x-;bCrM;bAV5X>;M1%mmiTn0pv241o;Is pI6S+N2ITN~x;Tb#$R;N!@B(=T42&&nK2`x)44$rjF6*2UngG277DE64 literal 0 HcmV?d00001 diff --git a/tmp/rdoc/images/wrench.png b/tmp/rdoc/images/wrench.png new file mode 100644 index 0000000000000000000000000000000000000000..5c8213fef5ab969f03189d4367e32e597e38bd7f GIT binary patch literal 610 zcmV-o0-gPdP)^jb z4`0v}DG1te)wmeb(>p90leRz?_mO+^JKy=v&2<29Od6?F%9%(c8los#f*@G`-%W&* z$)uBj2i@u-@SgX}gtyWPe6d*|w6h%R? zScK2#Yn%$sum0cy>90DmY*i{1XqpClEtktsRTZ)lCUe z<FogV^*tm>8*AlX za4oiR!&85LrobG57qUHUX#{>Vz(RHpB5|@>9O6N$jqB8>%($0wxE5R3)b>Y~xtCo$ zCgEk&A?_#IxHdN)9tqre^o{ho4{?hmPuf@^@I3-wncaRd%|~O3xbrKY=&TiwPYkJroM{;WUQTuMY8vpg}f4o)2%U3C;eEDoiEh?94d(rV57VIF#8VqzW$HrDC|#U`x@QDbgi zVl)t9GGz&YY#D?gc%>hISA+_EBpnXt#pnC`p6@xw0$8TCbULjhlgVx(kuc)%xbgqq zR5+DNDFRN0!y)7Gm}oT0i39}h4h928qY?Rho^UvPGJ#kuW|-Amtrn`Pmd&+bFo@sp z$LI4IQw7BG?|#2ewOS<<3VjL$0=lMY^m;wqZujv5kx1l%Sl;V&Iy4#$ip3&@LV2!7vhhN=PCz%^9v24`qb(+m4W?!q-&~=?ssf5GfnAmJKV;3bvpDm0(NhahZ=&^sqo6Odj6>)Dq_3p~4~ zvb`d3Mydwjt&Df^hVmLtI2x=U&h9(JVYX-!y~z3zi;1>=LY;o(bL$(Yf$lf)dMf0-u^0HrpTG Wk@)HE*94aU0000m+BBgry{~j2fHLegbHP( zrgXNbr0}2;^nywdjLjZe?uxtrd3D(pZH@fFFc0{BW_~jxoO1w7-VX;6vK@ROA$$R6 zEmo;Ht-Mj|>5jUy{bQ^V5@53LRI8AgLpUm|m+15sqcz@QtVSo|oz7ArM8?pIn+>gN z0b=4_b5O|4A*;Q+vc9Vqr~%3V155*NV~@gTz}KSUiKB-uJzjMZ>5%Q#n24H!V{ zTY(LLAE*NAHZ}C#wnj%Bw5OFIkRhkkAW#kDC3j9Wm0YXRaXlyyp>#mVfYG)eC;@ab zDb=T-BCAY4LI(Z@GOTr2V_A{pRwSmz+8Be>CjAw(=gnbVWAeguvZa93JmL(EDxv1m z0OP4q=fpAK1Mq!C2`OkEn37o;m#wF#(t(8Pu#S?2f#x<~4EO{@fmm`p9veD6RZ_jp z@Au4};q&`XuKEYgIiB4((kgxOs#YdqJw0fY>9^K_agEu5+$#k;w#%I2N>n_?)YIqu z`tq&#_^p?-%K*U0^}|7+9U(&k0?s;=r=uCZ%)H9_edH8wK}gB(nUB1FFk+2Ol%BXV zHoFY`D~2x|2 + + + + + +RDoc Documentation + + + + + + + + + + + + + + +
+

This is the API documentation for RDoc Documentation. +

+ + + + + diff --git a/tmp/rdoc/java/src/json/ext/ByteListTranscoder_java.html b/tmp/rdoc/java/src/json/ext/ByteListTranscoder_java.html new file mode 100644 index 000000000..3c7210780 --- /dev/null +++ b/tmp/rdoc/java/src/json/ext/ByteListTranscoder_java.html @@ -0,0 +1,363 @@ + + + + + + +ByteListTranscoder.java - RDoc Documentation + + + + + + + + + + + + + + +
+ +
This code is copyrighted work by Daniel Luz <dev at mernen dot com>.
+
+Distributed under the Ruby license: https://www.ruby-lang.org/en/about/license.txt
+ +

package json.ext;

+ +

import org.jruby.exceptions.RaiseException; import +org.jruby.runtime.ThreadContext; import org.jruby.util.ByteList;

+ +
 A class specialized in transcoding a certain String format into another,
+ using UTF-8 ByteLists as both input and output.
+/
+ +

abstract class ByteListTranscoder {

+ +
protected final ThreadContext context;
+
+protected ByteList src;
+protected int srcEnd;
+/** Position where the last read character started   
+protected int charStart;
+/** Position of the next character to read */
+protected int pos;
+
+private ByteList out;
+/**
+   When a character that can be copied straight into the output is found,
+   its index is stored on this variable, and copying is delayed until
+   the sequence of characters that can be copied ends.
+
+   <p>The variable stores -1 when not in a plain sequence.
+  /
+private int quoteStart = -1;
+
+protected ByteListTranscoder(ThreadContext context) {
+    this.context = context;
+}
+
+protected void init(ByteList src, ByteList out) {
+    this.init(src, 0, src.length(), out);
+}
+
+protected void init(ByteList src, int start, int end, ByteList out) {
+    this.src = src;
+    this.pos = start;
+    this.charStart = start;
+    this.srcEnd = end;
+    this.out = out;
+}
+
+/**
+   Returns whether there are any characters left to be read.
+  /
+protected boolean hasNext() {
+    return pos < srcEnd;
+}
+
+/**
+   Returns the next character in the buffer.
+  /
+private char next() {
+    return src.charAt(pos++);
+}
+
+/**
+   Reads an UTF-8 character from the input and returns its code point,
+   while advancing the input position.
+
+   <p>Raises an {@link #invalidUtf8()} exception if an invalid byte
+   is found.
+  /
+protected int readUtf8Char() {
+    charStart = pos;
+    char head = next();
+    if (head <= 0x7f) { // 0b0xxxxxxx (ASCII)
+        return head;
+    }
+    if (head <= 0xbf) { // 0b10xxxxxx
+        throw invalidUtf8(); // tail byte with no head
+    }
+    if (head <= 0xdf) { // 0b110xxxxx
+        ensureMin(1);
+        int cp = ((head  & 0x1f) << 6)
+                 | nextPart();
+        if (cp < 0x0080) throw invalidUtf8();
+        return cp;
+    }
+    if (head <= 0xef) { // 0b1110xxxx
+        ensureMin(2);
+        int cp = ((head & 0x0f) << 12)
+                 | (nextPart()  << 6)
+                 | nextPart();
+        if (cp < 0x0800) throw invalidUtf8();
+        return cp;
+    }
+    if (head <= 0xf7) { // 0b11110xxx
+        ensureMin(3);
+        int cp = ((head & 0x07) << 18)
+                 | (nextPart()  << 12)
+                 | (nextPart()  << 6)
+                 | nextPart();
+        if (!Character.isValidCodePoint(cp)) throw invalidUtf8();
+        return cp;
+    }
+    // 0b11111xxx?
+    throw invalidUtf8();
+}
+
+/**
+   Throws a GeneratorError if the input list doesn't have at least this
+   many bytes left.
+  /
+protected void ensureMin(int n) {
+    if (pos + n > srcEnd) throw incompleteUtf8();
+}
+
+/**
+   Reads the next byte of a multi-byte UTF-8 character and returns its
+   contents (lower 6 bits).
+
+   <p>Throws a GeneratorError if the byte is not a valid tail.
+  /
+private int nextPart() {
+    char c = next();
+    // tail bytes must be 0b10xxxxxx
+    if ((c & 0xc0) != 0x80) throw invalidUtf8();
+    return c & 0x3f;
+}
+
+protected void quoteStart() {
+    if (quoteStart == -1) quoteStart = charStart;
+}
+
+/**
+   When in a sequence of characters that can be copied directly,
+   interrupts the sequence and copies it to the output buffer.
+
+   @param endPos The offset until which the direct character quoting should
+                 occur. You may pass {@link #pos} to quote until the most
+                 recently read character, or {@link #charStart} to quote
+                 until the character before it.
+  /
+protected void quoteStop(int endPos) {
+    if (quoteStart != -1) {
+        out.append(src, quoteStart, endPos - quoteStart);
+        quoteStart = -1;
+    }
+}
+
+protected void append(int b) {
+    out.append(b);
+}
+
+protected void append(byte[] origin, int start, int length) {
+    out.append(origin, start, length);
+}
+
+protected abstract RaiseException invalidUtf8();
+
+protected RaiseException incompleteUtf8() {
+    return invalidUtf8();
+}
+ +

}

+
+ + + + + diff --git a/tmp/rdoc/java/src/json/ext/GeneratorMethods_java.html b/tmp/rdoc/java/src/json/ext/GeneratorMethods_java.html new file mode 100644 index 000000000..658895af9 --- /dev/null +++ b/tmp/rdoc/java/src/json/ext/GeneratorMethods_java.html @@ -0,0 +1,425 @@ + + + + + + +GeneratorMethods.java - RDoc Documentation + + + + + + + + + + + + + + +
+ +
This code is copyrighted work by Daniel Luz <dev at mernen dot com>.
+
+Distributed under the Ruby license: https://www.ruby-lang.org/en/about/license.txt
+ +

package json.ext;

+ +

import java.lang.ref.WeakReference; import org.jruby.Ruby; import +org.jruby.RubyArray; import org.jruby.RubyBoolean; import +org.jruby.RubyFixnum; import org.jruby.RubyFloat; import +org.jruby.RubyHash; import org.jruby.RubyInteger; import +org.jruby.RubyModule; import org.jruby.RubyNumeric; import +org.jruby.RubyString; import org.jruby.anno.JRubyMethod; import +org.jruby.runtime.ThreadContext; import +org.jruby.runtime.builtin.IRubyObject; import org.jruby.util.ByteList;

+ +

/**

+ +
 A class that populates the
+ <code>Json::Ext::Generator::GeneratorMethods</code> module.
+
+ @author mernen
+/
+ +

class GeneratorMethods {

+ +
/**
+   Populates the given module with all modules and their methods
+   @param info
+   @param generatorMethodsModule The module to populate
+   (normally <code>JSON::Generator::GeneratorMethods</code>)
+  /
+static void populate(RuntimeInfo info, RubyModule module) {
+    defineMethods(module, "Array",      RbArray.class);
+    defineMethods(module, "FalseClass", RbFalse.class);
+    defineMethods(module, "Float",      RbFloat.class);
+    defineMethods(module, "Hash",       RbHash.class);
+    defineMethods(module, "Integer",    RbInteger.class);
+    defineMethods(module, "NilClass",   RbNil.class);
+    defineMethods(module, "Object",     RbObject.class);
+    defineMethods(module, "String",     RbString.class);
+    defineMethods(module, "TrueClass",  RbTrue.class);
+
+    info.stringExtendModule = new WeakReference<RubyModule>(module.defineModuleUnder("String")
+                                        .defineModuleUnder("Extend"));
+    info.stringExtendModule.get().defineAnnotatedMethods(StringExtend.class);
+}
+
+/**
+   Convenience method for defining methods on a submodule.
+   @param parentModule
+   @param submoduleName
+   @param klass
+  /
+private static void defineMethods(RubyModule parentModule,
+        String submoduleName, Class klass) {
+    RubyModule submodule = parentModule.defineModuleUnder(submoduleName);
+    submodule.defineAnnotatedMethods(klass);
+}
+
+public static class RbHash {
+    @JRubyMethod(rest=true)
+    public static IRubyObject to_json(ThreadContext context,
+            IRubyObject vSelf, IRubyObject[] args) {
+        return Generator.generateJson(context, (RubyHash)vSelf,
+                Generator.HASH_HANDLER, args);
+    }
+}
+
+public static class RbArray {
+    @JRubyMethod(rest=true)
+    public static IRubyObject to_json(ThreadContext context,
+            IRubyObject vSelf, IRubyObject[] args) {
+        return Generator.generateJson(context, (RubyArray)vSelf,
+                Generator.ARRAY_HANDLER, args);
+    }
+}
+
+public static class RbInteger {
+    @JRubyMethod(rest=true)
+    public static IRubyObject to_json(ThreadContext context,
+            IRubyObject vSelf, IRubyObject[] args) {
+        return Generator.generateJson(context, vSelf, args);
+    }
+}
+
+public static class RbFloat {
+    @JRubyMethod(rest=true)
+    public static IRubyObject to_json(ThreadContext context,
+            IRubyObject vSelf, IRubyObject[] args) {
+        return Generator.generateJson(context, (RubyFloat)vSelf,
+                Generator.FLOAT_HANDLER, args);
+    }
+}
+
+public static class RbString {
+    @JRubyMethod(rest=true)
+    public static IRubyObject to_json(ThreadContext context,
+            IRubyObject vSelf, IRubyObject[] args) {
+        return Generator.generateJson(context, (RubyString)vSelf,
+                Generator.STRING_HANDLER, args);
+    }
+
+    /**
+       <code>{@link RubyString String}#to_json_raw(*)</code>
+
+       <p>This method creates a JSON text from the result of a call to
+       {@link #to_json_raw_object} of this String.
+      /
+    @JRubyMethod(rest=true)
+    public static IRubyObject to_json_raw(ThreadContext context,
+            IRubyObject vSelf, IRubyObject[] args) {
+        RubyHash obj = toJsonRawObject(context, Utils.ensureString(vSelf));
+        return Generator.generateJson(context, obj,
+                Generator.HASH_HANDLER, args);
+    }
+
+    /**
+       <code>{@link RubyString String}#to_json_raw_object(*)</code>
+
+       <p>This method creates a raw object Hash, that can be nested into
+       other data structures and will be unparsed as a raw string. This
+       method should be used if you want to convert raw strings to JSON
+       instead of UTF-8 strings, e.g. binary data.
+      /
+    @JRubyMethod(rest=true)
+    public static IRubyObject to_json_raw_object(ThreadContext context,
+            IRubyObject vSelf, IRubyObject[] args) {
+        return toJsonRawObject(context, Utils.ensureString(vSelf));
+    }
+
+    private static RubyHash toJsonRawObject(ThreadContext context,
+                                            RubyString self) {
+        Ruby runtime = context.getRuntime();
+        RubyHash result = RubyHash.newHash(runtime);
+
+        IRubyObject createId = RuntimeInfo.forRuntime(runtime)
+                .jsonModule.get().callMethod(context, "create_id");
+        result.op_aset(context, createId, self.getMetaClass().to_s());
+
+        ByteList bl = self.getByteList();
+        byte[] uBytes = bl.unsafeBytes();
+        RubyArray array = runtime.newArray(bl.length());
+        for (int i = bl.begin(), t = bl.begin() + bl.length(); i < t; i++) {
+            array.store(i, runtime.newFixnum(uBytes[i] & 0xff));
+        }
+
+        result.op_aset(context, runtime.newString("raw"), array);
+        return result;
+    }
+
+    @JRubyMethod(required=1, module=true)
+    public static IRubyObject included(ThreadContext context,
+            IRubyObject vSelf, IRubyObject module) {
+        RuntimeInfo info = RuntimeInfo.forRuntime(context.getRuntime());
+        return module.callMethod(context, "extend", info.stringExtendModule.get());
+    }
+}
+
+public static class StringExtend {
+    /**
+       <code>{@link RubyString String}#json_create(o)</code>
+
+       <p>Raw Strings are JSON Objects (the raw bytes are stored in an
+       array for the key "raw"). The Ruby String can be created by this
+       module method.
+      /
+    @JRubyMethod(required=1)
+    public static IRubyObject json_create(ThreadContext context,
+            IRubyObject vSelf, IRubyObject vHash) {
+        Ruby runtime = context.getRuntime();
+        RubyHash o = vHash.convertToHash();
+        IRubyObject rawData = o.fastARef(runtime.newString("raw"));
+        if (rawData == null) {
+            throw runtime.newArgumentError("\"raw\" value not defined "
+                                           + "for encoded String");
+        }
+        RubyArray ary = Utils.ensureArray(rawData);
+        byte[] bytes = new byte[ary.getLength()];
+        for (int i = 0, t = ary.getLength(); i < t; i++) {
+            IRubyObject element = ary.eltInternal(i);
+            if (element instanceof RubyFixnum) {
+                bytes[i] = (byte)RubyNumeric.fix2long(element);
+            } else {
+                throw runtime.newTypeError(element, runtime.getFixnum());
+            }
+        }
+        return runtime.newString(new ByteList(bytes, false));
+    }
+}
+
+public static class RbTrue {
+    @JRubyMethod(rest=true)
+    public static IRubyObject to_json(ThreadContext context,
+            IRubyObject vSelf, IRubyObject[] args) {
+        return Generator.generateJson(context, (RubyBoolean)vSelf,
+                Generator.TRUE_HANDLER, args);
+    }
+}
+
+public static class RbFalse {
+    @JRubyMethod(rest=true)
+    public static IRubyObject to_json(ThreadContext context,
+            IRubyObject vSelf, IRubyObject[] args) {
+        return Generator.generateJson(context, (RubyBoolean)vSelf,
+                Generator.FALSE_HANDLER, args);
+    }
+}
+
+public static class RbNil {
+    @JRubyMethod(rest=true)
+    public static IRubyObject to_json(ThreadContext context,
+            IRubyObject vSelf, IRubyObject[] args) {
+        return Generator.generateJson(context, vSelf,
+                Generator.NIL_HANDLER, args);
+    }
+}
+
+public static class RbObject {
+    @JRubyMethod(rest=true)
+    public static IRubyObject to_json(ThreadContext context,
+            IRubyObject self, IRubyObject[] args) {
+        return RbString.to_json(context, self.asString(), args);
+    }
+}
+ +

}

+
+ + + + + diff --git a/tmp/rdoc/java/src/json/ext/GeneratorService_java.html b/tmp/rdoc/java/src/json/ext/GeneratorService_java.html new file mode 100644 index 000000000..32944f49b --- /dev/null +++ b/tmp/rdoc/java/src/json/ext/GeneratorService_java.html @@ -0,0 +1,241 @@ + + + + + + +GeneratorService.java - RDoc Documentation + + + + + + + + + + + + + + +
+ +
This code is copyrighted work by Daniel Luz <dev at mernen dot com>.
+
+Distributed under the Ruby license: https://www.ruby-lang.org/en/about/license.txt
+ +

package json.ext;

+ +

import java.io.IOException; import java.lang.ref.WeakReference;

+ +

import org.jruby.Ruby; import org.jruby.RubyClass; import +org.jruby.RubyModule; import org.jruby.runtime.load.BasicLibraryService;

+ +

/**

+ +
 The service invoked by JRuby's {@link org.jruby.runtime.load.LoadService LoadService}.
+ Defines the <code>JSON::Ext::Generator</code> module.
+ @author mernen
+/
+ +

public class GeneratorService implements BasicLibraryService {

+ +
public boolean basicLoad(Ruby runtime) throws IOException {
+    runtime.getLoadService().require("json/common");
+    RuntimeInfo info = RuntimeInfo.initRuntime(runtime);
+
+    info.jsonModule = new WeakReference<RubyModule>(runtime.defineModule("JSON"));
+    RubyModule jsonExtModule = info.jsonModule.get().defineModuleUnder("Ext");
+    RubyModule generatorModule = jsonExtModule.defineModuleUnder("Generator");
+
+    RubyClass stateClass =
+        generatorModule.defineClassUnder("State", runtime.getObject(),
+                                         GeneratorState.ALLOCATOR);
+    stateClass.defineAnnotatedMethods(GeneratorState.class);
+    info.generatorStateClass = new WeakReference<RubyClass>(stateClass);
+
+    RubyModule generatorMethods =
+        generatorModule.defineModuleUnder("GeneratorMethods");
+    GeneratorMethods.populate(info, generatorMethods);
+
+    return true;
+}
+ +

}

+
+ + + + + diff --git a/tmp/rdoc/java/src/json/ext/GeneratorState_java.html b/tmp/rdoc/java/src/json/ext/GeneratorState_java.html new file mode 100644 index 000000000..c89bb42ea --- /dev/null +++ b/tmp/rdoc/java/src/json/ext/GeneratorState_java.html @@ -0,0 +1,686 @@ + + + + + + +GeneratorState.java - RDoc Documentation + + + + + + + + + + + + + + +
+ +
This code is copyrighted work by Daniel Luz <dev at mernen dot com>.
+
+Distributed under the Ruby license: https://www.ruby-lang.org/en/about/license.txt
+ +

package json.ext;

+ +

import org.jruby.Ruby; import org.jruby.RubyBoolean; import +org.jruby.RubyClass; import org.jruby.RubyHash; import +org.jruby.RubyInteger; import org.jruby.RubyNumeric; import +org.jruby.RubyObject; import org.jruby.RubyString; import +org.jruby.anno.JRubyMethod; import org.jruby.runtime.Block; import +org.jruby.runtime.ObjectAllocator; import org.jruby.runtime.ThreadContext; +import org.jruby.runtime.Visibility; import +org.jruby.runtime.builtin.IRubyObject; import org.jruby.util.ByteList;

+ +

/**

+ +
 The <code>JSON::Ext::Generator::State</code> class.
+
+ <p>This class is used to create State instances, that are use to hold data
+ while generating a JSON text from a a Ruby data structure.
+
+ @author mernen
+/
+
+ +

public class GeneratorState extends RubyObject {

+ +
  /**
+     The indenting unit string. Will be repeated several times for larger
+     indenting levels.
+    /
+  private ByteList indent = ByteList.EMPTY_BYTELIST;
+  /**
+     The spacing to be added after a semicolon on a JSON object.
+     @see #spaceBefore
+    /
+  private ByteList space = ByteList.EMPTY_BYTELIST;
+  /**
+     The spacing to be added before a semicolon on a JSON object.
+     @see #space
+    /
+  private ByteList spaceBefore = ByteList.EMPTY_BYTELIST;
+  /**
+     Any suffix to be added after the comma for each element on a JSON object.
+     It is assumed to be a newline, if set.
+    /
+  private ByteList objectNl = ByteList.EMPTY_BYTELIST;
+  /**
+     Any suffix to be added after the comma for each element on a JSON Array.
+     It is assumed to be a newline, if set.
+    /
+  private ByteList arrayNl = ByteList.EMPTY_BYTELIST;
+
+  /**
+     The maximum level of nesting of structures allowed.
+     <code>0</code> means disabled.
+    /
+  private int maxNesting = DEFAULT_MAX_NESTING;
+  static final int DEFAULT_MAX_NESTING = 100;
+  /**
+     Whether special float values (<code>NaN</code>, <code>Infinity</code>,
+     <code>-Infinity</code>) are accepted.
+     If set to <code>false</code>, an exception will be thrown upon
+     encountering one.
+    /
+  private boolean allowNaN = DEFAULT_ALLOW_NAN;
+  static final boolean DEFAULT_ALLOW_NAN = false;
+  /**
+     If set to <code>true</code> all JSON documents generated do not contain
+     any other characters than ASCII characters.
+    /
+  private boolean asciiOnly = DEFAULT_ASCII_ONLY;
+  static final boolean DEFAULT_ASCII_ONLY = false;
+  /**
+     If set to <code>true</code> all JSON values generated might not be
+     RFC-conform JSON documents.
+    /
+  private boolean quirksMode = DEFAULT_QUIRKS_MODE;
+  static final boolean DEFAULT_QUIRKS_MODE = false;
+  /**
+     The initial buffer length of this state. (This isn't really used on all
+     non-C implementations.)
+    /
+  private int bufferInitialLength = DEFAULT_BUFFER_INITIAL_LENGTH;
+  static final int DEFAULT_BUFFER_INITIAL_LENGTH = 1024;
+
+  /**
+     The current depth (inside a #to_json call)
+    /
+  private int depth = 0;
+
+  static final ObjectAllocator ALLOCATOR = new ObjectAllocator() {
+      public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
+          return new GeneratorState(runtime, klazz);
+      }
+  };
+
+  public GeneratorState(Ruby runtime, RubyClass metaClass) {
+      super(runtime, metaClass);
+  }
+
+  /**
+     <code>State.from_state(opts)</code>
+
+     <p>Creates a State object from <code>opts</code>, which ought to be
+     {@link RubyHash Hash} to create a new <code>State</code> instance
+     configured by <codes>opts</code>, something else to create an
+     unconfigured instance. If <code>opts</code> is a <code>State</code>
+     object, it is just returned.
+     @param clazzParam The receiver of the method call
+                       ({@link RubyClass} <code>State</code>)
+     @param opts The object to use as a base for the new <code>State</code>
+     @param block The block passed to the method
+     @return A <code>GeneratorState</code> as determined above
+    /
+  @JRubyMethod(meta=true)
+  public static IRubyObject from_state(ThreadContext context,
+          IRubyObject klass, IRubyObject opts) {
+      return fromState(context, opts);
+  }
+
+  static GeneratorState fromState(ThreadContext context, IRubyObject opts) {
+      return fromState(context, RuntimeInfo.forRuntime(context.getRuntime()), opts);
+  }
+
+  static GeneratorState fromState(ThreadContext context, RuntimeInfo info,
+                                  IRubyObject opts) {
+      RubyClass klass = info.generatorStateClass.get();
+      if (opts != null) {
+          // if the given parameter is a Generator::State, return itself
+          if (klass.isInstance(opts)) return (GeneratorState)opts;
+
+          // if the given parameter is a Hash, pass it to the instantiator
+          if (context.getRuntime().getHash().isInstance(opts)) {
+              return (GeneratorState)klass.newInstance(context,
+                      new IRubyObject[] {opts}, Block.NULL_BLOCK);
+          }
+      }
+
+      // for other values, return the safe prototype
+      return (GeneratorState)info.getSafeStatePrototype(context).dup();
+  }
+
+  /**
+     <code>State#initialize(opts = {})</code>
+
+     Instantiates a new <code>State</code> object, configured by <code>opts</code>.
+
+     <code>opts</code> can have the following keys:
+
+     <dl>
+     <dt><code>:indent</code>
+     <dd>a {@link RubyString String} used to indent levels (default: <code>""</code>)
+     <dt><code>:space</code>
+     <dd>a String that is put after a <code>':'</code> or <code>','</code>
+     delimiter (default: <code>""</code>)
+     <dt><code>:space_before</code>
+     <dd>a String that is put before a <code>":"</code> pair delimiter
+     (default: <code>""</code>)
+     <dt><code>:object_nl</code>
+     <dd>a String that is put at the end of a JSON object (default: <code>""</code>)
+     <dt><code>:array_nl</code>
+     <dd>a String that is put at the end of a JSON array (default: <code>""</code>)
+     <dt><code>:allow_nan</code>
+     <dd><code>true</code> if <code>NaN</code>, <code>Infinity</code>, and
+     <code>-Infinity</code> should be generated, otherwise an exception is
+     thrown if these values are encountered.
+     This options defaults to <code>false</code>.
+    /
+  @JRubyMethod(optional=1, visibility=Visibility.PRIVATE)
+  public IRubyObject initialize(ThreadContext context, IRubyObject[] args) {
+      configure(context, args.length > 0 ? args[0] : null);
+      return this;
+  }
+
+  @JRubyMethod
+  public IRubyObject initialize_copy(ThreadContext context, IRubyObject vOrig) {
+      Ruby runtime = context.getRuntime();
+      if (!(vOrig instanceof GeneratorState)) {
+          throw runtime.newTypeError(vOrig, getType());
+      }
+      GeneratorState orig = (GeneratorState)vOrig;
+      this.indent = orig.indent;
+      this.space = orig.space;
+      this.spaceBefore = orig.spaceBefore;
+      this.objectNl = orig.objectNl;
+      this.arrayNl = orig.arrayNl;
+      this.maxNesting = orig.maxNesting;
+      this.allowNaN = orig.allowNaN;
+      this.asciiOnly = orig.asciiOnly;
+      this.quirksMode = orig.quirksMode;
+      this.bufferInitialLength = orig.bufferInitialLength;
+      this.depth = orig.depth;
+      return this;
+  }
+
+  /**
+     Generates a valid JSON document from object <code>obj</code> and returns
+     the result. If no valid JSON document can be created this method raises
+     a GeneratorError exception.
+    /
+  @JRubyMethod
+  public IRubyObject generate(ThreadContext context, IRubyObject obj) {
+      RubyString result = Generator.generateJson(context, obj, this);
+      RuntimeInfo info = RuntimeInfo.forRuntime(context.getRuntime());
+      result.force_encoding(context, info.utf8.get());
+      return result;
+  }
+
+  private static boolean matchClosingBrace(ByteList bl, int pos, int len,
+                                           int brace) {
+      for (int endPos = len - 1; endPos > pos; endPos--) {
+          int b = bl.get(endPos);
+          if (Character.isWhitespace(b)) continue;
+          return b == brace;
+      }
+      return false;
+  }
+
+  @JRubyMethod(name="[]", required=1)
+  public IRubyObject op_aref(ThreadContext context, IRubyObject vName) {
+      String name = vName.asJavaString();
+      if (getMetaClass().isMethodBound(name, true)) {
+          return send(context, vName, Block.NULL_BLOCK);
+      } else {
+          IRubyObject value = getInstanceVariables().getInstanceVariable("@" + name);
+          return value == null ? context.nil : value;
+      }
+  }
+
+  @JRubyMethod(name="[]=", required=2)
+  public IRubyObject op_aset(ThreadContext context, IRubyObject vName, IRubyObject value) {
+      String name = vName.asJavaString();
+      String nameWriter = name + "=";
+      if (getMetaClass().isMethodBound(nameWriter, true)) {
+          return send(context, context.getRuntime().newString(nameWriter), value, Block.NULL_BLOCK);
+      } else {
+          getInstanceVariables().setInstanceVariable("@" + name, value);
+      }
+      return context.getRuntime().getNil();
+  }
+
+  public ByteList getIndent() {
+      return indent;
+  }
+
+  @JRubyMethod(name="indent")
+  public RubyString indent_get(ThreadContext context) {
+      return context.getRuntime().newString(indent);
+  }
+
+  @JRubyMethod(name="indent=")
+  public IRubyObject indent_set(ThreadContext context, IRubyObject indent) {
+      this.indent = prepareByteList(context, indent);
+      return indent;
+  }
+
+  public ByteList getSpace() {
+      return space;
+  }
+
+  @JRubyMethod(name="space")
+  public RubyString space_get(ThreadContext context) {
+      return context.getRuntime().newString(space);
+  }
+
+  @JRubyMethod(name="space=")
+  public IRubyObject space_set(ThreadContext context, IRubyObject space) {
+      this.space = prepareByteList(context, space);
+      return space;
+  }
+
+  public ByteList getSpaceBefore() {
+      return spaceBefore;
+  }
+
+  @JRubyMethod(name="space_before")
+  public RubyString space_before_get(ThreadContext context) {
+      return context.getRuntime().newString(spaceBefore);
+  }
+
+  @JRubyMethod(name="space_before=")
+  public IRubyObject space_before_set(ThreadContext context,
+                                      IRubyObject spaceBefore) {
+      this.spaceBefore = prepareByteList(context, spaceBefore);
+      return spaceBefore;
+  }
+
+  public ByteList getObjectNl() {
+      return objectNl;
+  }
+
+  @JRubyMethod(name="object_nl")
+  public RubyString object_nl_get(ThreadContext context) {
+      return context.getRuntime().newString(objectNl);
+  }
+
+  @JRubyMethod(name="object_nl=")
+  public IRubyObject object_nl_set(ThreadContext context,
+                                   IRubyObject objectNl) {
+      this.objectNl = prepareByteList(context, objectNl);
+      return objectNl;
+  }
+
+  public ByteList getArrayNl() {
+      return arrayNl;
+  }
+
+  @JRubyMethod(name="array_nl")
+  public RubyString array_nl_get(ThreadContext context) {
+      return context.getRuntime().newString(arrayNl);
+  }
+
+  @JRubyMethod(name="array_nl=")
+  public IRubyObject array_nl_set(ThreadContext context,
+                                  IRubyObject arrayNl) {
+      this.arrayNl = prepareByteList(context, arrayNl);
+      return arrayNl;
+  }
+
+  @JRubyMethod(name="check_circular?")
+  public RubyBoolean check_circular_p(ThreadContext context) {
+      return context.getRuntime().newBoolean(maxNesting != 0);
+  }
+
+  /**
+     Returns the maximum level of nesting configured for this state.
+    /
+  public int getMaxNesting() {
+      return maxNesting;
+  }
+
+  @JRubyMethod(name="max_nesting")
+  public RubyInteger max_nesting_get(ThreadContext context) {
+      return context.getRuntime().newFixnum(maxNesting);
+  }
+
+  @JRubyMethod(name="max_nesting=")
+  public IRubyObject max_nesting_set(IRubyObject max_nesting) {
+      maxNesting = RubyNumeric.fix2int(max_nesting);
+      return max_nesting;
+  }
+
+  public boolean allowNaN() {
+      return allowNaN;
+  }
+
+  @JRubyMethod(name="allow_nan?")
+  public RubyBoolean allow_nan_p(ThreadContext context) {
+      return context.getRuntime().newBoolean(allowNaN);
+  }
+
+  public boolean asciiOnly() {
+      return asciiOnly;
+  }
+
+  @JRubyMethod(name="ascii_only?")
+  public RubyBoolean ascii_only_p(ThreadContext context) {
+      return context.getRuntime().newBoolean(asciiOnly);
+  }
+
+  @JRubyMethod(name="buffer_initial_length")
+  public RubyInteger buffer_initial_length_get(ThreadContext context) {
+      return context.getRuntime().newFixnum(bufferInitialLength);
+  }
+
+  @JRubyMethod(name="buffer_initial_length=")
+  public IRubyObject buffer_initial_length_set(IRubyObject buffer_initial_length) {
+      int newLength = RubyNumeric.fix2int(buffer_initial_length);
+      if (newLength > 0) bufferInitialLength = newLength;
+      return buffer_initial_length;
+  }
+
+  public int getDepth() {
+      return depth;
+  }
+
+  @JRubyMethod(name="depth")
+  public RubyInteger depth_get(ThreadContext context) {
+      return context.getRuntime().newFixnum(depth);
+  }
+
+  @JRubyMethod(name="depth=")
+  public IRubyObject depth_set(IRubyObject vDepth) {
+      depth = RubyNumeric.fix2int(vDepth);
+      return vDepth;
+  }
+
+  private ByteList prepareByteList(ThreadContext context, IRubyObject value) {
+      RubyString str = value.convertToString();
+      RuntimeInfo info = RuntimeInfo.forRuntime(context.getRuntime());
+      if (str.encoding(context) != info.utf8.get()) {
+          str = (RubyString)str.encode(context, info.utf8.get());
+      }
+      return str.getByteList().dup();
+  }
+
+  /**
+     <code>State#configure(opts)</code>
+
+     <p>Configures this State instance with the {@link RubyHash Hash}
+     <code>opts</code>, and returns itself.
+     @param vOpts The options hash
+     @return The receiver
+    /
+@JRubyMethod(alias = "merge")
+  public IRubyObject configure(ThreadContext context, IRubyObject vOpts) {
+      OptionsReader opts = new OptionsReader(context, vOpts);
+
+      ByteList indent = opts.getString("indent");
+      if (indent != null) this.indent = indent;
+
+      ByteList space = opts.getString("space");
+      if (space != null) this.space = space;
+
+      ByteList spaceBefore = opts.getString("space_before");
+      if (spaceBefore != null) this.spaceBefore = spaceBefore;
+
+      ByteList arrayNl = opts.getString("array_nl");
+      if (arrayNl != null) this.arrayNl = arrayNl;
+
+      ByteList objectNl = opts.getString("object_nl");
+      if (objectNl != null) this.objectNl = objectNl;
+
+      maxNesting = opts.getInt("max_nesting", DEFAULT_MAX_NESTING);
+      allowNaN   = opts.getBool("allow_nan",  DEFAULT_ALLOW_NAN);
+      asciiOnly  = opts.getBool("ascii_only", DEFAULT_ASCII_ONLY);
+      bufferInitialLength = opts.getInt("buffer_initial_length", DEFAULT_BUFFER_INITIAL_LENGTH);
+
+      depth = opts.getInt("depth", 0);
+
+      return this;
+  }
+
+  /**
+     <code>State#to_h()</code>
+
+     <p>Returns the configuration instance variables as a hash, that can be
+     passed to the configure method.
+     @return the hash
+    /
+  @JRubyMethod(alias = "to_hash")
+  public RubyHash to_h(ThreadContext context) {
+      Ruby runtime = context.getRuntime();
+      RubyHash result = RubyHash.newHash(runtime);
+
+      result.op_aset(context, runtime.newSymbol("indent"), indent_get(context));
+      result.op_aset(context, runtime.newSymbol("space"), space_get(context));
+      result.op_aset(context, runtime.newSymbol("space_before"), space_before_get(context));
+      result.op_aset(context, runtime.newSymbol("object_nl"), object_nl_get(context));
+      result.op_aset(context, runtime.newSymbol("array_nl"), array_nl_get(context));
+      result.op_aset(context, runtime.newSymbol("allow_nan"), allow_nan_p(context));
+      result.op_aset(context, runtime.newSymbol("ascii_only"), ascii_only_p(context));
+      result.op_aset(context, runtime.newSymbol("max_nesting"), max_nesting_get(context));
+      result.op_aset(context, runtime.newSymbol("depth"), depth_get(context));
+      result.op_aset(context, runtime.newSymbol("buffer_initial_length"), buffer_initial_length_get(context));
+      for (String name: getInstanceVariableNameList()) {
+          result.op_aset(context, runtime.newSymbol(name.substring(1)), getInstanceVariables().getInstanceVariable(name));
+      }
+      return result;
+  }
+
+  public int increaseDepth() {
+      depth++;
+      checkMaxNesting();
+      return depth;
+  }
+
+  public int decreaseDepth() {
+      return --depth;
+  }
+
+  /**
+     Checks if the current depth is allowed as per this state's options.
+     @param context
+     @param depth The corrent depth
+    /
+  private void checkMaxNesting() {
+      if (maxNesting != 0 && depth > maxNesting) {
+          depth--;
+          throw Utils.newException(getRuntime().getCurrentContext(),
+                  Utils.M_NESTING_ERROR, "nesting of " + depth + " is too deep");
+      }
+  }
+ +

}

+
+ + + + + diff --git a/tmp/rdoc/java/src/json/ext/Generator_java.html b/tmp/rdoc/java/src/json/ext/Generator_java.html new file mode 100644 index 000000000..ec0ef475c --- /dev/null +++ b/tmp/rdoc/java/src/json/ext/Generator_java.html @@ -0,0 +1,633 @@ + + + + + + +Generator.java - RDoc Documentation + + + + + + + + + + + + + + +
+ +
This code is copyrighted work by Daniel Luz <dev at mernen dot com>.
+
+Distributed under the Ruby license: https://www.ruby-lang.org/en/about/license.txt
+ +

package json.ext;

+ +

import org.jruby.Ruby; import org.jruby.RubyArray; import +org.jruby.RubyBignum; import org.jruby.RubyBoolean; import +org.jruby.RubyClass; import org.jruby.RubyFixnum; import +org.jruby.RubyFloat; import org.jruby.RubyHash; import +org.jruby.RubyNumeric; import org.jruby.RubyString; import +org.jruby.runtime.ThreadContext; import +org.jruby.runtime.builtin.IRubyObject; import org.jruby.util.ByteList;

+ +

public final class Generator {

+ +
private Generator() {
+    throw new RuntimeException();
+}
+
+   Encodes the given object as a JSON string, using the given handler.
+  /
+static <T extends IRubyObject> RubyString
+        generateJson(ThreadContext context, T object,
+                     Handler<? super T> handler, IRubyObject[] args) {
+    Session session = new Session(context, args.length > 0 ? args[0]
+                                                           : null);
+    return session.infect(handler.generateNew(session, object));
+}
+
+/**
+   Encodes the given object as a JSON string, detecting the appropriate handler
+   for the given object.
+  /
+static <T extends IRubyObject> RubyString
+        generateJson(ThreadContext context, T object, IRubyObject[] args) {
+    Handler<? super T> handler = getHandlerFor(context.getRuntime(), object);
+    return generateJson(context, object, handler, args);
+}
+
+/**
+   Encodes the given object as a JSON string, using the appropriate
+   handler if one is found or calling #to_json if not.
+  /
+public static <T extends IRubyObject> RubyString
+        generateJson(ThreadContext context, T object,
+                     GeneratorState config) {
+    Session session = new Session(context, config);
+    Handler<? super T> handler = getHandlerFor(context.getRuntime(), object);
+    return handler.generateNew(session, object);
+}
+
+/**
+   Returns the best serialization handler for the given object.
+  /
+// Java's generics can't handle this satisfactorily, so I'll just leave
+// the best I could get and ignore the warnings
+@SuppressWarnings("unchecked")
+private static <T extends IRubyObject>
+        Handler<? super T> getHandlerFor(Ruby runtime, T object) {
+    RubyClass metaClass = object.getMetaClass();
+    if (metaClass == runtime.getString()) return (Handler)STRING_HANDLER;
+    if (metaClass == runtime.getFixnum()) return (Handler)FIXNUM_HANDLER;
+    if (metaClass == runtime.getHash())   return (Handler)HASH_HANDLER;
+    if (metaClass == runtime.getArray())  return (Handler)ARRAY_HANDLER;
+    if (object.isNil())                   return (Handler)NIL_HANDLER;
+    if (object == runtime.getTrue())      return (Handler)TRUE_HANDLER;
+    if (object == runtime.getFalse())     return (Handler)FALSE_HANDLER;
+    if (metaClass == runtime.getFloat())  return (Handler)FLOAT_HANDLER;
+    if (metaClass == runtime.getBignum()) return (Handler)BIGNUM_HANDLER;
+    return GENERIC_HANDLER;
+}
+
+/* Generator context   
+
+/**
+   A class that concentrates all the information that is shared by
+   generators working on a single session.
+
+   <p>A session is defined as the process of serializing a single root
+   object; any handler directly called by container handlers (arrays and
+   hashes/objects) shares this object with its caller.
+
+   <p>Note that anything called indirectly (via {@link GENERIC_HANDLER})
+   won't be part of the session.
+  /
+static class Session {
+    private final ThreadContext context;
+    private GeneratorState state;
+    private IRubyObject possibleState;
+    private RuntimeInfo info;
+    private StringEncoder stringEncoder;
+
+    private boolean tainted = false;
+    private boolean untrusted = false;
+
+    Session(ThreadContext context, GeneratorState state) {
+        this.context = context;
+        this.state = state;
+    }
+
+    Session(ThreadContext context, IRubyObject possibleState) {
+        this.context = context;
+        this.possibleState = possibleState == null || possibleState.isNil()
+                ? null : possibleState;
+    }
+
+    public ThreadContext getContext() {
+        return context;
+    }
+
+    public Ruby getRuntime() {
+        return context.getRuntime();
+    }
+
+    public GeneratorState getState() {
+        if (state == null) {
+            state = GeneratorState.fromState(context, getInfo(), possibleState);
+        }
+        return state;
+    }
+
+    public RuntimeInfo getInfo() {
+        if (info == null) info = RuntimeInfo.forRuntime(getRuntime());
+        return info;
+    }
+
+    public StringEncoder getStringEncoder() {
+        if (stringEncoder == null) {
+            stringEncoder = new StringEncoder(context, getState().asciiOnly());
+        }
+        return stringEncoder;
+    }
+
+    public void infectBy(IRubyObject object) {
+        if (object.isTaint()) tainted = true;
+        if (object.isUntrusted()) untrusted = true;
+    }
+
+    public <T extends IRubyObject> T infect(T object) {
+        if (tainted) object.setTaint(true);
+        if (untrusted) object.setUntrusted(true);
+        return object;
+    }
+}
+
+/* Handler base classes */
+
+private static abstract class Handler<T extends IRubyObject> {
+    /**
+       Returns an estimative of how much space the serialization of the
+       given object will take. Used for allocating enough buffer space
+       before invoking other methods.
+      /
+    int guessSize(Session session, T object) {
+        return 4;
+    }
+
+    RubyString generateNew(Session session, T object) {
+        RubyString result;
+        ByteList buffer = new ByteList(guessSize(session, object));
+        generate(session, object, buffer);
+        result = RubyString.newString(session.getRuntime(), buffer);
+        ThreadContext context = session.getContext();
+        RuntimeInfo info = session.getInfo();
+        result.force_encoding(context, info.utf8.get());
+        return result;
+    }
+
+    abstract void generate(Session session, T object, ByteList buffer);
+}
+
+/**
+   A handler that returns a fixed keyword regardless of the passed object.
+  /
+private static class KeywordHandler<T extends IRubyObject>
+        extends Handler<T> {
+    private final ByteList keyword;
+
+    private KeywordHandler(String keyword) {
+        this.keyword = new ByteList(ByteList.plain(keyword), false);
+    }
+
+    @Override
+    int guessSize(Session session, T object) {
+        return keyword.length();
+    }
+
+    @Override
+    RubyString generateNew(Session session, T object) {
+        return RubyString.newStringShared(session.getRuntime(), keyword);
+    }
+
+    @Override
+    void generate(Session session, T object, ByteList buffer) {
+        buffer.append(keyword);
+    }
+}
+
+/* Handlers */
+
+static final Handler<RubyBignum> BIGNUM_HANDLER =
+    new Handler<RubyBignum>() {
+        @Override
+        void generate(Session session, RubyBignum object, ByteList buffer) {
+            // JRUBY-4751: RubyBignum.to_s() returns generic object
+            // representation (fixed in 1.5, but we maintain backwards
+            // compatibility; call to_s(IRubyObject[]) then
+            buffer.append(((RubyString)object.to_s(IRubyObject.NULL_ARRAY)).getByteList());
+        }
+    };
+
+static final Handler<RubyFixnum> FIXNUM_HANDLER =
+    new Handler<RubyFixnum>() {
+        @Override
+        void generate(Session session, RubyFixnum object, ByteList buffer) {
+            buffer.append(object.to_s().getByteList());
+        }
+    };
+
+static final Handler<RubyFloat> FLOAT_HANDLER =
+    new Handler<RubyFloat>() {
+        @Override
+        void generate(Session session, RubyFloat object, ByteList buffer) {
+            double value = RubyFloat.num2dbl(object);
+
+            if (Double.isInfinite(value) || Double.isNaN(value)) {
+                if (!session.getState().allowNaN()) {
+                    throw Utils.newException(session.getContext(),
+                            Utils.M_GENERATOR_ERROR,
+                            object + " not allowed in JSON");
+                }
+            }
+            buffer.append(((RubyString)object.to_s()).getByteList());
+        }
+    };
+
+static final Handler<RubyArray> ARRAY_HANDLER =
+    new Handler<RubyArray>() {
+        @Override
+        int guessSize(Session session, RubyArray object) {
+            GeneratorState state = session.getState();
+            int depth = state.getDepth();
+            int perItem =
+                4                                           // prealloc
+                + (depth + 1) * state.getIndent().length()  // indent
+                + 1 + state.getArrayNl().length();          // ',' arrayNl
+            return 2 + object.size() * perItem;
+        }
+
+        @Override
+        void generate(Session session, RubyArray object, ByteList buffer) {
+            ThreadContext context = session.getContext();
+            Ruby runtime = context.getRuntime();
+            GeneratorState state = session.getState();
+            int depth = state.increaseDepth();
+
+            ByteList indentUnit = state.getIndent();
+            byte[] shift = Utils.repeat(indentUnit, depth);
+
+            ByteList arrayNl = state.getArrayNl();
+            byte[] delim = new byte[1 + arrayNl.length()];
+            delim[0] = ',';
+            System.arraycopy(arrayNl.unsafeBytes(), arrayNl.begin(), delim, 1,
+                    arrayNl.length());
+
+            session.infectBy(object);
+
+            buffer.append((byte)'[');
+            buffer.append(arrayNl);
+            boolean firstItem = true;
+            for (int i = 0, t = object.getLength(); i < t; i++) {
+                IRubyObject element = object.eltInternal(i);
+                session.infectBy(element);
+                if (firstItem) {
+                    firstItem = false;
+                } else {
+                    buffer.append(delim);
+                }
+                buffer.append(shift);
+                Handler<IRubyObject> handler = getHandlerFor(runtime, element);
+                handler.generate(session, element, buffer);
+            }
+
+            state.decreaseDepth();
+            if (arrayNl.length() != 0) {
+                buffer.append(arrayNl);
+                buffer.append(shift, 0, state.getDepth() * indentUnit.length());
+            }
+
+            buffer.append((byte)']');
+        }
+    };
+
+static final Handler<RubyHash> HASH_HANDLER =
+    new Handler<RubyHash>() {
+        @Override
+        int guessSize(Session session, RubyHash object) {
+            GeneratorState state = session.getState();
+            int perItem =
+                12    // key, colon, comma
+                + (state.getDepth() + 1) * state.getIndent().length()
+                + state.getSpaceBefore().length()
+                + state.getSpace().length();
+            return 2 + object.size() * perItem;
+        }
+
+        @Override
+        void generate(final Session session, RubyHash object,
+                      final ByteList buffer) {
+            ThreadContext context = session.getContext();
+            final Ruby runtime = context.getRuntime();
+            final GeneratorState state = session.getState();
+            final int depth = state.increaseDepth();
+
+            final ByteList objectNl = state.getObjectNl();
+            final byte[] indent = Utils.repeat(state.getIndent(), depth);
+            final ByteList spaceBefore = state.getSpaceBefore();
+            final ByteList space = state.getSpace();
+
+            buffer.append((byte)'{');
+            buffer.append(objectNl);
+            object.visitAll(new RubyHash.Visitor() {
+                private boolean firstPair = true;
+
+                @Override
+                public void visit(IRubyObject key, IRubyObject value) {
+                    if (firstPair) {
+                        firstPair = false;
+                    } else {
+                        buffer.append((byte)',');
+                        buffer.append(objectNl);
+                    }
+                    if (objectNl.length() != 0) buffer.append(indent);
+
+                    STRING_HANDLER.generate(session, key.asString(), buffer);
+                    session.infectBy(key);
+
+                    buffer.append(spaceBefore);
+                    buffer.append((byte)':');
+                    buffer.append(space);
+
+                    Handler<IRubyObject> valueHandler = getHandlerFor(runtime, value);
+                    valueHandler.generate(session, value, buffer);
+                    session.infectBy(value);
+                }
+            });
+            state.decreaseDepth();
+            if (objectNl.length() != 0) {
+                buffer.append(objectNl);
+                buffer.append(Utils.repeat(state.getIndent(), state.getDepth()));
+            }
+            buffer.append((byte)'}');
+        }
+    };
+
+static final Handler<RubyString> STRING_HANDLER =
+    new Handler<RubyString>() {
+        @Override
+        int guessSize(Session session, RubyString object) {
+            // for most applications, most strings will be just a set of
+            // printable ASCII characters without any escaping, so let's
+            // just allocate enough space for that + the quotes
+            return 2 + object.getByteList().length();
+        }
+
+        @Override
+        void generate(Session session, RubyString object, ByteList buffer) {
+            RuntimeInfo info = session.getInfo();
+            RubyString src;
+
+            if (object.encoding(session.getContext()) != info.utf8.get()) {
+                src = (RubyString)object.encode(session.getContext(),
+                                                info.utf8.get());
+            } else {
+                src = object;
+            }
+
+            session.getStringEncoder().encode(src.getByteList(), buffer);
+        }
+    };
+
+static final Handler<RubyBoolean> TRUE_HANDLER =
+    new KeywordHandler<RubyBoolean>("true");
+static final Handler<RubyBoolean> FALSE_HANDLER =
+    new KeywordHandler<RubyBoolean>("false");
+static final Handler<IRubyObject> NIL_HANDLER =
+    new KeywordHandler<IRubyObject>("null");
+
+/**
+   The default handler (<code>Object#to_json</code>): coerces the object
+   to string using <code>#to_s</code>, and serializes that string.
+  /
+static final Handler<IRubyObject> OBJECT_HANDLER =
+    new Handler<IRubyObject>() {
+        @Override
+        RubyString generateNew(Session session, IRubyObject object) {
+            RubyString str = object.asString();
+            return STRING_HANDLER.generateNew(session, str);
+        }
+
+        @Override
+        void generate(Session session, IRubyObject object, ByteList buffer) {
+            RubyString str = object.asString();
+            STRING_HANDLER.generate(session, str, buffer);
+        }
+    };
+
+/**
+   A handler that simply calls <code>#to_json(state)</code> on the
+   given object.
+  /
+static final Handler<IRubyObject> GENERIC_HANDLER =
+    new Handler<IRubyObject>() {
+        @Override
+        RubyString generateNew(Session session, IRubyObject object) {
+            if (object.respondsTo("to_json")) {
+                IRubyObject result = object.callMethod(session.getContext(), "to_json",
+                          new IRubyObject[] {session.getState()});
+                if (result instanceof RubyString) return (RubyString)result;
+                throw session.getRuntime().newTypeError("to_json must return a String");
+            } else {
+                return OBJECT_HANDLER.generateNew(session, object);
+            }
+        }
+
+        @Override
+        void generate(Session session, IRubyObject object, ByteList buffer) {
+            RubyString result = generateNew(session, object);
+            buffer.append(result.getByteList());
+        }
+    };
+ +

}

+
+ + + + + diff --git a/tmp/rdoc/java/src/json/ext/OptionsReader_java.html b/tmp/rdoc/java/src/json/ext/OptionsReader_java.html new file mode 100644 index 000000000..e0072a509 --- /dev/null +++ b/tmp/rdoc/java/src/json/ext/OptionsReader_java.html @@ -0,0 +1,309 @@ + + + + + + +OptionsReader.java - RDoc Documentation + + + + + + + + + + + + + + +
+ +
This code is copyrighted work by Daniel Luz <dev at mernen dot com>.
+
+Distributed under the Ruby license: https://www.ruby-lang.org/en/about/license.txt
+ +

package json.ext;

+ +

import org.jruby.Ruby; import org.jruby.RubyClass; import +org.jruby.RubyHash; import org.jruby.RubyNumeric; import +org.jruby.RubyString; import org.jruby.runtime.ThreadContext; import +org.jruby.runtime.builtin.IRubyObject; import org.jruby.util.ByteList;

+ +

final class OptionsReader {

+ +
private final ThreadContext context;
+private final Ruby runtime;
+private final RubyHash opts;
+private RuntimeInfo info;
+
+OptionsReader(ThreadContext context, IRubyObject vOpts) {
+    this.context = context;
+    this.runtime = context.getRuntime();
+    if (vOpts == null || vOpts.isNil()) {
+        opts = null;
+    } else if (vOpts.respondsTo("to_hash")) {
+        opts = vOpts.convertToHash();
+    } else if (vOpts.respondsTo("to_h")) {
+        opts = vOpts.callMethod(context, "to_h").convertToHash();
+    } else {
+        opts = vOpts.convertToHash();    Should just raise the correct TypeError   
+    }
+}
+
+private RuntimeInfo getRuntimeInfo() {
+    if (info != null) return info;
+    info = RuntimeInfo.forRuntime(runtime);
+    return info;
+}
+
+/**
+   Efficiently looks up items with a {@link RubySymbol Symbol} key
+   @param key The Symbol name to look up for
+   @return The item in the {@link RubyHash Hash}, or <code>null</code>
+           if not found
+  /
+IRubyObject get(String key) {
+    return opts == null ? null : opts.fastARef(runtime.newSymbol(key));
+}
+
+boolean getBool(String key, boolean defaultValue) {
+    IRubyObject value = get(key);
+    return value == null ? defaultValue : value.isTrue();
+}
+
+int getInt(String key, int defaultValue) {
+    IRubyObject value = get(key);
+    if (value == null) return defaultValue;
+    if (!value.isTrue()) return 0;
+    return RubyNumeric.fix2int(value);
+}
+
+/**
+   Reads the setting from the options hash. If no entry is set for this
+   key or if it evaluates to <code>false</code>, returns null; attempts to
+   coerce the value to {@link RubyString String} otherwise.
+   @param key The Symbol name to look up for
+   @return <code>null</code> if the key is not in the Hash or if
+           its value evaluates to <code>false</code>
+   @throws RaiseException <code>TypeError</code> if the value does not
+                          evaluate to <code>false</code> and can't be
+                          converted to string
+  /
+ByteList getString(String key) {
+    RubyString str = getString(key, null);
+    return str == null ? null : str.getByteList().dup();
+}
+
+RubyString getString(String key, RubyString defaultValue) {
+    IRubyObject value = get(key);
+    if (value == null || !value.isTrue()) return defaultValue;
+
+    RubyString str = value.convertToString();
+    RuntimeInfo info = getRuntimeInfo();
+    if (str.encoding(context) != info.utf8.get()) {
+        str = (RubyString)str.encode(context, info.utf8.get());
+    }
+    return str;
+}
+
+/**
+   Reads the setting from the options hash. If it is <code>nil</code> or
+   undefined, returns the default value given.
+   If not, ensures it is a RubyClass instance and shares the same
+   allocator as the default value (i.e. for the basic types which have
+   their specific allocators, this ensures the passed value is
+   a subclass of them).
+  /
+RubyClass getClass(String key, RubyClass defaultValue) {
+    IRubyObject value = get(key);
+
+    if (value == null || value.isNil()) return defaultValue;
+    return (RubyClass)value;
+}
+
+public RubyHash getHash(String key) {
+    IRubyObject value = get(key);
+    if (value == null || value.isNil()) return new RubyHash(runtime);
+    return (RubyHash) value;
+}
+ +

}

+
+ + + + + diff --git a/tmp/rdoc/java/src/json/ext/ParserService_java.html b/tmp/rdoc/java/src/json/ext/ParserService_java.html new file mode 100644 index 000000000..84e6f3f48 --- /dev/null +++ b/tmp/rdoc/java/src/json/ext/ParserService_java.html @@ -0,0 +1,233 @@ + + + + + + +ParserService.java - RDoc Documentation + + + + + + + + + + + + + + +
+ +
This code is copyrighted work by Daniel Luz <dev at mernen dot com>.
+
+Distributed under the Ruby license: https://www.ruby-lang.org/en/about/license.txt
+ +

package json.ext;

+ +

import java.io.IOException; import java.lang.ref.WeakReference;

+ +

import org.jruby.Ruby; import org.jruby.RubyClass; import +org.jruby.RubyModule; import org.jruby.runtime.load.BasicLibraryService;

+ +

/**

+ +
 The service invoked by JRuby's {@link org.jruby.runtime.load.LoadService LoadService}.
+ Defines the <code>JSON::Ext::Parser</code> class.
+ @author mernen
+/
+ +

public class ParserService implements BasicLibraryService {

+ +
public boolean basicLoad(Ruby runtime) throws IOException {
+    runtime.getLoadService().require("json/common");
+    RuntimeInfo info = RuntimeInfo.initRuntime(runtime);
+
+    info.jsonModule = new WeakReference<RubyModule>(runtime.defineModule("JSON"));
+    RubyModule jsonExtModule = info.jsonModule.get().defineModuleUnder("Ext");
+    RubyClass parserClass =
+        jsonExtModule.defineClassUnder("Parser", runtime.getObject(),
+                                       Parser.ALLOCATOR);
+    parserClass.defineAnnotatedMethods(Parser.class);
+    return true;
+}
+ +

}

+
+ + + + + diff --git a/tmp/rdoc/java/src/json/ext/Parser_java.html b/tmp/rdoc/java/src/json/ext/Parser_java.html new file mode 100644 index 000000000..e88d87d70 --- /dev/null +++ b/tmp/rdoc/java/src/json/ext/Parser_java.html @@ -0,0 +1,2681 @@ + + + + + + +Parser.java - RDoc Documentation + + + + + + + + + + + + + + +
+ +

// line 1 “Parser.rl”

+ +
This code is copyrighted work by Daniel Luz <dev at mernen dot com>.
+
+Distributed under the Ruby license: https://www.ruby-lang.org/en/about/license.txt
+ +

package json.ext;

+ +

import org.jruby.Ruby; import org.jruby.RubyArray; import +org.jruby.RubyClass; import org.jruby.RubyEncoding; import +org.jruby.RubyFloat; import org.jruby.RubyHash; import +org.jruby.RubyInteger; import org.jruby.RubyModule; import +org.jruby.RubyNumeric; import org.jruby.RubyObject; import +org.jruby.RubyString; import org.jruby.anno.JRubyMethod; import +org.jruby.exceptions.JumpException; import +org.jruby.exceptions.RaiseException; import org.jruby.runtime.Block; import +org.jruby.runtime.ObjectAllocator; import org.jruby.runtime.ThreadContext; +import org.jruby.runtime.Visibility; import +org.jruby.runtime.builtin.IRubyObject; import org.jruby.util.ByteList; +import org.jruby.util.ConvertBytes; import static +org.jruby.util.ConvertDouble.DoubleConverter;

+ +

/**

+ +
 The <code>JSON::Ext::Parser</code> class.
+
+ <p>This is the JSON parser implemented as a Java class. To use it as the
+ standard parser, set
+   <pre>JSON.parser = JSON::Ext::Parser</pre>
+ This is performed for you when you <code>include "json/ext"</code>.
+
+ <p>This class does not perform the actual parsing, just acts as an interface
+ to Ruby code. When the {@link #parse()} method is invoked, a
+ Parser.ParserSession object is instantiated, which handles the process.
+
+ @author mernen
+/
+ +

public class Parser extends RubyObject {

+ +
private final RuntimeInfo info;
+private RubyString vSource;
+private RubyString createId;
+private boolean createAdditions;
+private int maxNesting;
+private boolean allowNaN;
+private boolean symbolizeNames;
+private RubyClass objectClass;
+private RubyClass arrayClass;
+private RubyClass decimalClass;
+private RubyHash matchString;
+
+private static final int DEFAULT_MAX_NESTING = 100;
+
+private static final ByteList JSON_MINUS_INFINITY = new ByteList(ByteList.plain("-Infinity"));
+// constant names in the JSON module containing those values
+private static final String CONST_NAN = "NaN";
+private static final String CONST_INFINITY = "Infinity";
+private static final String CONST_MINUS_INFINITY = "MinusInfinity";
+
+static final ObjectAllocator ALLOCATOR = new ObjectAllocator() {
+    public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
+        return new Parser(runtime, klazz);
+    }
+};
+
+/**
+   Multiple-value return for internal parser methods.
+
+   <p>All the <code>parse<var>Stuff</var></code> methods return instances of
+   <code>ParserResult</code> when successful, or <code>null</code> when
+   there's a problem with the input data.
+  /
+static final class ParserResult {
+    /**
+       The result of the successful parsing. Should never be
+       <code>null</code>.
+      /
+    IRubyObject result;
+    /**
+       The point where the parser returned.
+      /
+    int p;
+
+    void update(IRubyObject result, int p) {
+        this.result = result;
+        this.p = p;
+    }
+}
+
+public Parser(Ruby runtime, RubyClass metaClass) {
+    super(runtime, metaClass);
+    info = RuntimeInfo.forRuntime(runtime);
+}
+
+/**
+   <code>Parser.new(source, opts = {})</code>
+
+   <p>Creates a new <code>JSON::Ext::Parser</code> instance for the string
+   <code>source</code>.
+   It will be configured by the <code>opts</code> Hash.
+   <code>opts</code> can have the following keys:
+
+   <dl>
+   <dt><code>:max_nesting</code>
+   <dd>The maximum depth of nesting allowed in the parsed data
+   structures. Disable depth checking with <code>:max_nesting => false|nil|0</code>,
+   it defaults to 100.
+
+   <dt><code>:allow_nan</code>
+   <dd>If set to <code>true</code>, allow <code>NaN</code>,
+   <code>Infinity</code> and <code>-Infinity</code> in defiance of RFC 4627
+   to be parsed by the Parser. This option defaults to <code>false</code>.
+
+   <dt><code>:symbolize_names</code>
+   <dd>If set to <code>true</code>, returns symbols for the names (keys) in
+   a JSON object. Otherwise strings are returned, which is also the default.
+
+   <dt><code>:create_additions</code>
+   <dd>If set to <code>false</code>, the Parser doesn't create additions
+   even if a matching class and <code>create_id</code> was found. This option
+   defaults to <code>true</code>.
+
+   <dt><code>:object_class</code>
+   <dd>Defaults to Hash.
+
+   <dt><code>:array_class</code>
+   <dd>Defaults to Array.
+
+   <dt><code>:decimal_class</code>
+   <dd>Specifies which class to use instead of the default (Float) when
+   parsing decimal numbers. This class must accept a single string argument
+   in its constructor.
+   </dl>
+  /
+@JRubyMethod(name = "new", required = 1, optional = 1, meta = true)
+public static IRubyObject newInstance(IRubyObject clazz, IRubyObject[] args, Block block) {
+    Parser parser = (Parser)((RubyClass)clazz).allocate();
+
+    parser.callInit(args, block);
+
+    return parser;
+}
+
+@JRubyMethod(required = 1, optional = 1, visibility = Visibility.PRIVATE)
+public IRubyObject initialize(ThreadContext context, IRubyObject[] args) {
+    Ruby runtime = context.getRuntime();
+    if (this.vSource != null) {
+        throw runtime.newTypeError("already initialized instance");
+     }
+
+    OptionsReader opts   = new OptionsReader(context, args.length > 1 ? args[1] : null);
+    this.maxNesting      = opts.getInt("max_nesting", DEFAULT_MAX_NESTING);
+    this.allowNaN        = opts.getBool("allow_nan", false);
+    this.symbolizeNames  = opts.getBool("symbolize_names", false);
+    this.createId        = opts.getString("create_id", getCreateId(context));
+    this.createAdditions = opts.getBool("create_additions", false);
+    this.objectClass     = opts.getClass("object_class", runtime.getHash());
+    this.arrayClass      = opts.getClass("array_class", runtime.getArray());
+    this.decimalClass    = opts.getClass("decimal_class", null);
+    this.matchString    = opts.getHash("match_string");
+
+    if(symbolizeNames && createAdditions) {
+      throw runtime.newArgumentError(
+        "options :symbolize_names and :create_additions cannot be " +
+        " used in conjunction"
+      );
+    }
+    this.vSource = args[0].convertToString();
+    this.vSource = convertEncoding(context, vSource);
+
+    return this;
+}
+
+/**
+   Checks the given string's encoding. If a non-UTF-8 encoding is detected,
+   a converted copy is returned.
+   Returns the source string if no conversion is needed.
+  /
+private RubyString convertEncoding(ThreadContext context, RubyString source) {
+  RubyEncoding encoding = (RubyEncoding)source.encoding(context);
+  if (encoding == info.ascii8bit.get()) {
+      if (source.isFrozen()) {
+        source = (RubyString) source.dup();
+      }
+      source.force_encoding(context, info.utf8.get());
+  } else {
+    source = (RubyString) source.encode(context, info.utf8.get());
+  }
+  return source;
+}
+
+/**
+   Checks the first four bytes of the given ByteList to infer its encoding,
+   using the principle demonstrated on section 3 of RFC 4627 (JSON).
+  /
+private static String sniffByteList(ByteList bl) {
+    if (bl.length() < 4) return null;
+    if (bl.get(0) == 0 && bl.get(2) == 0) {
+        return bl.get(1) == 0 ? "utf-32be" : "utf-16be";
+    }
+    if (bl.get(1) == 0 && bl.get(3) == 0) {
+        return bl.get(2) == 0 ? "utf-32le" : "utf-16le";
+    }
+    return null;
+}
+
+/**
+   Assumes the given (binary) RubyString to be in the given encoding, then
+   converts it to UTF-8.
+  /
+private RubyString reinterpretEncoding(ThreadContext context,
+        RubyString str, String sniffedEncoding) {
+    RubyEncoding actualEncoding = info.getEncoding(context, sniffedEncoding);
+    RubyEncoding targetEncoding = info.utf8.get();
+    RubyString dup = (RubyString)str.dup();
+    dup.force_encoding(context, actualEncoding);
+    return (RubyString)dup.encode_bang(context, targetEncoding);
+}
+
+/**
+   <code>Parser#parse()</code>
+
+   <p>Parses the current JSON text <code>source</code> and returns the
+   complete data structure as a result.
+  /
+@JRubyMethod
+public IRubyObject parse(ThreadContext context) {
+    return new ParserSession(this, context, info).parse();
+}
+
+/**
+   <code>Parser#source()</code>
+
+   <p>Returns a copy of the current <code>source</code> string, that was
+   used to construct this Parser.
+  /
+@JRubyMethod(name = "source")
+public IRubyObject source_get() {
+    return checkAndGetSource().dup();
+}
+
+public RubyString checkAndGetSource() {
+  if (vSource != null) {
+    return vSource;
+  } else {
+    throw getRuntime().newTypeError("uninitialized instance");
+  }
+}
+
+/**
+   Queries <code>JSON.create_id</code>. Returns <code>null</code> if it is
+   set to <code>nil</code> or <code>false</code>, and a String if not.
+  /
+private RubyString getCreateId(ThreadContext context) {
+    IRubyObject v = info.jsonModule.get().callMethod(context, "create_id");
+    return v.isTrue() ? v.convertToString() : null;
+}
+
+/**
+   A string parsing session.
+
+   <p>Once a ParserSession is instantiated, the source string should not
+   change until the parsing is complete. The ParserSession object assumes
+   the source {@link RubyString} is still associated to its original
+   {@link ByteList}, which in turn must still be bound to the same
+   <code>byte[]</code> value (and on the same offset).
+  /
+// Ragel uses lots of fall-through
+@SuppressWarnings("fallthrough")
+private static class ParserSession {
+    private final Parser parser;
+    private final ThreadContext context;
+    private final RuntimeInfo info;
+    private final ByteList byteList;
+    private final ByteList view;
+    private final byte[] data;
+    private final StringDecoder decoder;
+    private int currentNesting = 0;
+    private final DoubleConverter dc;
+
+    // initialization value for all state variables.
+    // no idea about the origins of this value, ask Flori ;)
+    private static final int EVIL = 0x666;
+
+    private ParserSession(Parser parser, ThreadContext context, RuntimeInfo info) {
+        this.parser = parser;
+        this.context = context;
+        this.info = info;
+        this.byteList = parser.checkAndGetSource().getByteList();
+        this.data = byteList.unsafeBytes();
+        this.view = new ByteList(data, false);
+        this.decoder = new StringDecoder(context);
+        this.dc = new DoubleConverter();
+    }
+
+    private RaiseException unexpectedToken(int absStart, int absEnd) {
+        RubyString msg = getRuntime().newString("unexpected token at '")
+                .cat(data, absStart, absEnd - absStart)
+                .cat((byte)'\'');
+        return newException(Utils.M_PARSER_ERROR, msg);
+    }
+
+    private Ruby getRuntime() {
+        return context.getRuntime();
+    }
+ +

// line 339 “Parser.rl”

+ +

// line 321 “Parser.java” private static byte[] +init__JSON_value_actions_0() {

+ +
return new byte [] {
+    0,    1,    0,    1,    1,    1,    2,    1,    3,    1,    4,    1,
+    5,    1,    6,    1,    7,    1,    8,    1,    9
+};
+ +

}

+ +

private static final byte _JSON_value_actions[] = +init__JSON_value_actions_0();

+ +

private static byte[] init__JSON_value_key_offsets_0() {

+ +
return new byte [] {
+    0,    0,   11,   12,   13,   14,   15,   16,   17,   18,   19,   20,
+   21,   22,   23,   24,   25,   26,   27,   28,   29,   30
+};
+ +

}

+ +

private static final byte _JSON_value_key_offsets[] = +init__JSON_value_key_offsets_0();

+ +

private static char[] init__JSON_value_trans_keys_0() {

+ +
return new char [] {
+   34,   45,   73,   78,   91,  102,  110,  116,  123,   48,   57,  110,
+  102,  105,  110,  105,  116,  121,   97,   78,   97,  108,  115,  101,
+  117,  108,  108,  114,  117,  101,    0
+};
+ +

}

+ +

private static final char _JSON_value_trans_keys[] = +init__JSON_value_trans_keys_0();

+ +

private static byte[] init__JSON_value_single_lengths_0() {

+ +
return new byte [] {
+    0,    9,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+    1,    1,    1,    1,    1,    1,    1,    1,    1,    0
+};
+ +

}

+ +

private static final byte _JSON_value_single_lengths[] = +init__JSON_value_single_lengths_0();

+ +

private static byte[] init__JSON_value_range_lengths_0() {

+ +
return new byte [] {
+    0,    1,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0
+};
+ +

}

+ +

private static final byte _JSON_value_range_lengths[] = +init__JSON_value_range_lengths_0();

+ +

private static byte[] init__JSON_value_index_offsets_0() {

+ +
return new byte [] {
+    0,    0,   11,   13,   15,   17,   19,   21,   23,   25,   27,   29,
+   31,   33,   35,   37,   39,   41,   43,   45,   47,   49
+};
+ +

}

+ +

private static final byte _JSON_value_index_offsets[] = +init__JSON_value_index_offsets_0();

+ +

private static byte[] init__JSON_value_trans_targs_0() {

+ +
return new byte [] {
+   21,   21,    2,    9,   21,   11,   15,   18,   21,   21,    0,    3,
+    0,    4,    0,    5,    0,    6,    0,    7,    0,    8,    0,   21,
+    0,   10,    0,   21,    0,   12,    0,   13,    0,   14,    0,   21,
+    0,   16,    0,   17,    0,   21,    0,   19,    0,   20,    0,   21,
+    0,    0,    0
+};
+ +

}

+ +

private static final byte _JSON_value_trans_targs[] = +init__JSON_value_trans_targs_0();

+ +

private static byte[] init__JSON_value_trans_actions_0() {

+ +
return new byte [] {
+   13,   11,    0,    0,   15,    0,    0,    0,   17,   11,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    9,
+    0,    0,    0,    7,    0,    0,    0,    0,    0,    0,    0,    3,
+    0,    0,    0,    0,    0,    1,    0,    0,    0,    0,    0,    5,
+    0,    0,    0
+};
+ +

}

+ +

private static final byte _JSON_value_trans_actions[] = +init__JSON_value_trans_actions_0();

+ +

private static byte[] init__JSON_value_from_state_actions_0() {

+ +
return new byte [] {
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,   19
+};
+ +

}

+ +

private static final byte _JSON_value_from_state_actions[] = +init__JSON_value_from_state_actions_0();

+ +

static final int JSON_value_start = 1; static final int +JSON_value_first_final = 21; static final int JSON_value_error = 0;

+ +

static final int JSON_value_en_main = 1;

+ +

// line 445 “Parser.rl”

+ +
void parseValue(ParserResult res, int p, int pe) {
+    int cs = EVIL;
+    IRubyObject result = null;
+ +

// line 443 “Parser.java”

+ +
{
+cs = JSON_value_start;
+}
+ +

// line 452 “Parser.rl”

+ +

// line 450 “Parser.java”

+ +
{
+int _klen;
+int _trans = 0;
+int _acts;
+int _nacts;
+int _keys;
+int _goto_targ = 0;
+
+_goto: while (true) {
+switch ( _goto_targ ) {
+case 0:
+if ( p == pe ) {
+        _goto_targ = 4;
+        continue _goto;
+}
+if ( cs == 0 ) {
+        _goto_targ = 5;
+        continue _goto;
+}
+ +

case 1:

+ +
_acts = _JSON_value_from_state_actions[cs];
+_nacts = (int) _JSON_value_actions[_acts++];
+while ( _nacts-- > 0 ) {
+        switch ( _JSON_value_actions[_acts++] ) {
+case 9:
+ +

// line 430 “Parser.rl”

+ +
{
+        p--;
+        { p += 1; _goto_targ = 5; if (true)  continue _goto;}
+    }
+break;
+ +

// line 482 “Parser.java”

+ +
        }
+}
+
+_match: do {
+_keys = _JSON_value_key_offsets[cs];
+_trans = _JSON_value_index_offsets[cs];
+_klen = _JSON_value_single_lengths[cs];
+if ( _klen > 0 ) {
+        int _lower = _keys;
+        int _mid;
+        int _upper = _keys + _klen - 1;
+        while (true) {
+                if ( _upper < _lower )
+                        break;
+
+                _mid = _lower + ((_upper-_lower) >> 1);
+                if ( data[p] < _JSON_value_trans_keys[_mid] )
+                        _upper = _mid - 1;
+                else if ( data[p] > _JSON_value_trans_keys[_mid] )
+                        _lower = _mid + 1;
+                else {
+                        _trans += (_mid - _keys);
+                        break _match;
+                }
+        }
+        _keys += _klen;
+        _trans += _klen;
+}
+
+_klen = _JSON_value_range_lengths[cs];
+if ( _klen > 0 ) {
+        int _lower = _keys;
+        int _mid;
+        int _upper = _keys + (_klen<<1) - 2;
+        while (true) {
+                if ( _upper < _lower )
+                        break;
+
+                _mid = _lower + (((_upper-_lower) >> 1) & ~1);
+                if ( data[p] < _JSON_value_trans_keys[_mid] )
+                        _upper = _mid - 2;
+                else if ( data[p] > _JSON_value_trans_keys[_mid+1] )
+                        _lower = _mid + 2;
+                else {
+                        _trans += ((_mid - _keys)>>1);
+                        break _match;
+                }
+        }
+        _trans += _klen;
+}
+} while (false);
+
+cs = _JSON_value_trans_targs[_trans];
+
+if ( _JSON_value_trans_actions[_trans] != 0 ) {
+        _acts = _JSON_value_trans_actions[_trans];
+        _nacts = (int) _JSON_value_actions[_acts++];
+        while ( _nacts-- > 0 )
+{
+                switch ( _JSON_value_actions[_acts++] )
+                {
+case 0:
+ +

// line 347 “Parser.rl”

+ +
{
+        result = getRuntime().getNil();
+    }
+break;
+case 1:
+ +

// line 350 “Parser.rl”

+ +
{
+        result = getRuntime().getFalse();
+    }
+break;
+case 2:
+ +

// line 353 “Parser.rl”

+ +
{
+        result = getRuntime().getTrue();
+    }
+break;
+case 3:
+ +

// line 356 “Parser.rl”

+ +
{
+        if (parser.allowNaN) {
+            result = getConstant(CONST_NAN);
+        } else {
+            throw unexpectedToken(p - 2, pe);
+        }
+    }
+break;
+case 4:
+ +

// line 363 “Parser.rl”

+ +
{
+        if (parser.allowNaN) {
+            result = getConstant(CONST_INFINITY);
+        } else {
+            throw unexpectedToken(p - 7, pe);
+        }
+    }
+break;
+case 5:
+ +

// line 370 “Parser.rl”

+ +
{
+        if (pe > p + 8 &&
+            absSubSequence(p, p + 9).equals(JSON_MINUS_INFINITY)) {
+
+            if (parser.allowNaN) {
+                result = getConstant(CONST_MINUS_INFINITY);
+                {p = (( p + 10))-1;}
+                p--;
+                { p += 1; _goto_targ = 5; if (true)  continue _goto;}
+            } else {
+                throw unexpectedToken(p, pe);
+            }
+        }
+        parseFloat(res, p, pe);
+        if (res.result != null) {
+            result = res.result;
+            {p = (( res.p))-1;}
+        }
+        parseInteger(res, p, pe);
+        if (res.result != null) {
+            result = res.result;
+            {p = (( res.p))-1;}
+        }
+        p--;
+        { p += 1; _goto_targ = 5; if (true)  continue _goto;}
+    }
+break;
+case 6:
+ +

// line 396 “Parser.rl”

+ +
{
+        parseString(res, p, pe);
+        if (res.result == null) {
+            p--;
+            { p += 1; _goto_targ = 5; if (true)  continue _goto;}
+        } else {
+            result = res.result;
+            {p = (( res.p))-1;}
+        }
+    }
+break;
+case 7:
+ +

// line 406 “Parser.rl”

+ +
{
+        currentNesting++;
+        parseArray(res, p, pe);
+        currentNesting--;
+        if (res.result == null) {
+            p--;
+            { p += 1; _goto_targ = 5; if (true)  continue _goto;}
+        } else {
+            result = res.result;
+            {p = (( res.p))-1;}
+        }
+    }
+break;
+case 8:
+ +

// line 418 “Parser.rl”

+ +
{
+        currentNesting++;
+        parseObject(res, p, pe);
+        currentNesting--;
+        if (res.result == null) {
+            p--;
+            { p += 1; _goto_targ = 5; if (true)  continue _goto;}
+        } else {
+            result = res.result;
+            {p = (( res.p))-1;}
+        }
+    }
+break;
+ +

// line 654 “Parser.java”

+ +
                }
+        }
+}
+ +

case 2:

+ +
if ( cs == 0 ) {
+        _goto_targ = 5;
+        continue _goto;
+}
+if ( ++p != pe ) {
+        _goto_targ = 1;
+        continue _goto;
+}
+ +

case 4: case 5:

+ +
}
+break; }
+}
+ +

// line 453 “Parser.rl”

+ +
    if (cs >= JSON_value_first_final && result != null) {
+        res.update(result, p);
+    } else {
+        res.update(null, p);
+    }
+}
+ +

// line 684 “Parser.java” private static byte[] +init__JSON_integer_actions_0() {

+ +
return new byte [] {
+    0,    1,    0
+};
+ +

}

+ +

private static final byte _JSON_integer_actions[] = +init__JSON_integer_actions_0();

+ +

private static byte[] init__JSON_integer_key_offsets_0() {

+ +
return new byte [] {
+    0,    0,    4,    7,    9,    9
+};
+ +

}

+ +

private static final byte _JSON_integer_key_offsets[] = +init__JSON_integer_key_offsets_0();

+ +

private static char[] init__JSON_integer_trans_keys_0() {

+ +
return new char [] {
+   45,   48,   49,   57,   48,   49,   57,   48,   57,   48,   57,    0
+};
+ +

}

+ +

private static final char _JSON_integer_trans_keys[] = +init__JSON_integer_trans_keys_0();

+ +

private static byte[] init__JSON_integer_single_lengths_0() {

+ +
return new byte [] {
+    0,    2,    1,    0,    0,    0
+};
+ +

}

+ +

private static final byte _JSON_integer_single_lengths[] = +init__JSON_integer_single_lengths_0();

+ +

private static byte[] init__JSON_integer_range_lengths_0() {

+ +
return new byte [] {
+    0,    1,    1,    1,    0,    1
+};
+ +

}

+ +

private static final byte _JSON_integer_range_lengths[] = +init__JSON_integer_range_lengths_0();

+ +

private static byte[] init__JSON_integer_index_offsets_0() {

+ +
return new byte [] {
+    0,    0,    4,    7,    9,   10
+};
+ +

}

+ +

private static final byte _JSON_integer_index_offsets[] = +init__JSON_integer_index_offsets_0();

+ +

private static byte[] init__JSON_integer_indicies_0() {

+ +
return new byte [] {
+    0,    2,    3,    1,    2,    3,    1,    1,    4,    1,    3,    4,
+    0
+};
+ +

}

+ +

private static final byte _JSON_integer_indicies[] = +init__JSON_integer_indicies_0();

+ +

private static byte[] init__JSON_integer_trans_targs_0() {

+ +
return new byte [] {
+    2,    0,    3,    5,    4
+};
+ +

}

+ +

private static final byte _JSON_integer_trans_targs[] = +init__JSON_integer_trans_targs_0();

+ +

private static byte[] init__JSON_integer_trans_actions_0() {

+ +
return new byte [] {
+    0,    0,    0,    0,    1
+};
+ +

}

+ +

private static final byte _JSON_integer_trans_actions[] = +init__JSON_integer_trans_actions_0();

+ +

static final int JSON_integer_start = 1; static final int +JSON_integer_first_final = 3; static final int JSON_integer_error = 0;

+ +

static final int JSON_integer_en_main = 1;

+ +

// line 472 “Parser.rl”

+ +
void parseInteger(ParserResult res, int p, int pe) {
+    int new_p = parseIntegerInternal(p, pe);
+    if (new_p == -1) {
+        res.update(null, p);
+        return;
+    }
+    RubyInteger number = createInteger(p, new_p);
+    res.update(number, new_p + 1);
+    return;
+}
+
+int parseIntegerInternal(int p, int pe) {
+    int cs = EVIL;
+ +

// line 801 “Parser.java”

+ +
{
+cs = JSON_integer_start;
+}
+ +

// line 489 “Parser.rl”

+ +
int memo = p;
+
+ +

// line 809 “Parser.java”

+ +
{
+int _klen;
+int _trans = 0;
+int _acts;
+int _nacts;
+int _keys;
+int _goto_targ = 0;
+
+_goto: while (true) {
+switch ( _goto_targ ) {
+case 0:
+if ( p == pe ) {
+        _goto_targ = 4;
+        continue _goto;
+}
+if ( cs == 0 ) {
+        _goto_targ = 5;
+        continue _goto;
+}
+ +

case 1:

+ +
_match: do {
+_keys = _JSON_integer_key_offsets[cs];
+_trans = _JSON_integer_index_offsets[cs];
+_klen = _JSON_integer_single_lengths[cs];
+if ( _klen > 0 ) {
+        int _lower = _keys;
+        int _mid;
+        int _upper = _keys + _klen - 1;
+        while (true) {
+                if ( _upper < _lower )
+                        break;
+
+                _mid = _lower + ((_upper-_lower) >> 1);
+                if ( data[p] < _JSON_integer_trans_keys[_mid] )
+                        _upper = _mid - 1;
+                else if ( data[p] > _JSON_integer_trans_keys[_mid] )
+                        _lower = _mid + 1;
+                else {
+                        _trans += (_mid - _keys);
+                        break _match;
+                }
+        }
+        _keys += _klen;
+        _trans += _klen;
+}
+
+_klen = _JSON_integer_range_lengths[cs];
+if ( _klen > 0 ) {
+        int _lower = _keys;
+        int _mid;
+        int _upper = _keys + (_klen<<1) - 2;
+        while (true) {
+                if ( _upper < _lower )
+                        break;
+
+                _mid = _lower + (((_upper-_lower) >> 1) & ~1);
+                if ( data[p] < _JSON_integer_trans_keys[_mid] )
+                        _upper = _mid - 2;
+                else if ( data[p] > _JSON_integer_trans_keys[_mid+1] )
+                        _lower = _mid + 2;
+                else {
+                        _trans += ((_mid - _keys)>>1);
+                        break _match;
+                }
+        }
+        _trans += _klen;
+}
+} while (false);
+
+_trans = _JSON_integer_indicies[_trans];
+cs = _JSON_integer_trans_targs[_trans];
+
+if ( _JSON_integer_trans_actions[_trans] != 0 ) {
+        _acts = _JSON_integer_trans_actions[_trans];
+        _nacts = (int) _JSON_integer_actions[_acts++];
+        while ( _nacts-- > 0 )
+{
+                switch ( _JSON_integer_actions[_acts++] )
+                {
+case 0:
+ +

// line 466 “Parser.rl”

+ +
{
+        p--;
+        { p += 1; _goto_targ = 5; if (true)  continue _goto;}
+    }
+break;
+ +

// line 896 “Parser.java”

+ +
                }
+        }
+}
+ +

case 2:

+ +
if ( cs == 0 ) {
+        _goto_targ = 5;
+        continue _goto;
+}
+if ( ++p != pe ) {
+        _goto_targ = 1;
+        continue _goto;
+}
+ +

case 4: case 5:

+ +
}
+break; }
+}
+ +

// line 491 “Parser.rl”

+ +
    if (cs < JSON_integer_first_final) {
+        return -1;
+    }
+
+    return p;
+}
+
+RubyInteger createInteger(int p, int new_p) {
+    Ruby runtime = getRuntime();
+    ByteList num = absSubSequence(p, new_p);
+    return bytesToInum(runtime, num);
+}
+
+RubyInteger bytesToInum(Ruby runtime, ByteList num) {
+    return runtime.is1_9() ?
+            ConvertBytes.byteListToInum19(runtime, num, 10, true) :
+            ConvertBytes.byteListToInum(runtime, num, 10, true);
+}
+ +

// line 938 “Parser.java” private static byte[] +init__JSON_float_actions_0() {

+ +
return new byte [] {
+    0,    1,    0
+};
+ +

}

+ +

private static final byte _JSON_float_actions[] = +init__JSON_float_actions_0();

+ +

private static byte[] init__JSON_float_key_offsets_0() {

+ +
return new byte [] {
+    0,    0,    4,    7,   10,   12,   16,   18,   23,   29,   29
+};
+ +

}

+ +

private static final byte _JSON_float_key_offsets[] = +init__JSON_float_key_offsets_0();

+ +

private static char[] init__JSON_float_trans_keys_0() {

+ +
return new char [] {
+   45,   48,   49,   57,   48,   49,   57,   46,   69,  101,   48,   57,
+   43,   45,   48,   57,   48,   57,   46,   69,  101,   48,   57,   69,
+  101,   45,   46,   48,   57,   69,  101,   45,   46,   48,   57,    0
+};
+ +

}

+ +

private static final char _JSON_float_trans_keys[] = +init__JSON_float_trans_keys_0();

+ +

private static byte[] init__JSON_float_single_lengths_0() {

+ +
return new byte [] {
+    0,    2,    1,    3,    0,    2,    0,    3,    2,    0,    2
+};
+ +

}

+ +

private static final byte _JSON_float_single_lengths[] = +init__JSON_float_single_lengths_0();

+ +

private static byte[] init__JSON_float_range_lengths_0() {

+ +
return new byte [] {
+    0,    1,    1,    0,    1,    1,    1,    1,    2,    0,    2
+};
+ +

}

+ +

private static final byte _JSON_float_range_lengths[] = +init__JSON_float_range_lengths_0();

+ +

private static byte[] init__JSON_float_index_offsets_0() {

+ +
return new byte [] {
+    0,    0,    4,    7,   11,   13,   17,   19,   24,   29,   30
+};
+ +

}

+ +

private static final byte _JSON_float_index_offsets[] = +init__JSON_float_index_offsets_0();

+ +

private static byte[] init__JSON_float_indicies_0() {

+ +
return new byte [] {
+    0,    2,    3,    1,    2,    3,    1,    4,    5,    5,    1,    6,
+    1,    7,    7,    8,    1,    8,    1,    4,    5,    5,    3,    1,
+    5,    5,    1,    6,    9,    1,    1,    1,    1,    8,    9,    0
+};
+ +

}

+ +

private static final byte _JSON_float_indicies[] = +init__JSON_float_indicies_0();

+ +

private static byte[] init__JSON_float_trans_targs_0() {

+ +
return new byte [] {
+    2,    0,    3,    7,    4,    5,    8,    6,   10,    9
+};
+ +

}

+ +

private static final byte _JSON_float_trans_targs[] = +init__JSON_float_trans_targs_0();

+ +

private static byte[] init__JSON_float_trans_actions_0() {

+ +
return new byte [] {
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    1
+};
+ +

}

+ +

private static final byte _JSON_float_trans_actions[] = +init__JSON_float_trans_actions_0();

+ +

static final int JSON_float_start = 1; static final int +JSON_float_first_final = 8; static final int JSON_float_error = 0;

+ +

static final int JSON_float_en_main = 1;

+ +

// line 526 “Parser.rl”

+ +
void parseFloat(ParserResult res, int p, int pe) {
+    int new_p = parseFloatInternal(p, pe);
+    if (new_p == -1) {
+        res.update(null, p);
+        return;
+    }
+    IRubyObject number = parser.decimalClass == null ?
+        createFloat(p, new_p) : createCustomDecimal(p, new_p);
+
+    res.update(number, new_p + 1);
+    return;
+}
+
+int parseFloatInternal(int p, int pe) {
+    int cs = EVIL;
+ +

// line 1060 “Parser.java”

+ +
{
+cs = JSON_float_start;
+}
+ +

// line 545 “Parser.rl”

+ +
int memo = p;
+
+ +

// line 1068 “Parser.java”

+ +
{
+int _klen;
+int _trans = 0;
+int _acts;
+int _nacts;
+int _keys;
+int _goto_targ = 0;
+
+_goto: while (true) {
+switch ( _goto_targ ) {
+case 0:
+if ( p == pe ) {
+        _goto_targ = 4;
+        continue _goto;
+}
+if ( cs == 0 ) {
+        _goto_targ = 5;
+        continue _goto;
+}
+ +

case 1:

+ +
_match: do {
+_keys = _JSON_float_key_offsets[cs];
+_trans = _JSON_float_index_offsets[cs];
+_klen = _JSON_float_single_lengths[cs];
+if ( _klen > 0 ) {
+        int _lower = _keys;
+        int _mid;
+        int _upper = _keys + _klen - 1;
+        while (true) {
+                if ( _upper < _lower )
+                        break;
+
+                _mid = _lower + ((_upper-_lower) >> 1);
+                if ( data[p] < _JSON_float_trans_keys[_mid] )
+                        _upper = _mid - 1;
+                else if ( data[p] > _JSON_float_trans_keys[_mid] )
+                        _lower = _mid + 1;
+                else {
+                        _trans += (_mid - _keys);
+                        break _match;
+                }
+        }
+        _keys += _klen;
+        _trans += _klen;
+}
+
+_klen = _JSON_float_range_lengths[cs];
+if ( _klen > 0 ) {
+        int _lower = _keys;
+        int _mid;
+        int _upper = _keys + (_klen<<1) - 2;
+        while (true) {
+                if ( _upper < _lower )
+                        break;
+
+                _mid = _lower + (((_upper-_lower) >> 1) & ~1);
+                if ( data[p] < _JSON_float_trans_keys[_mid] )
+                        _upper = _mid - 2;
+                else if ( data[p] > _JSON_float_trans_keys[_mid+1] )
+                        _lower = _mid + 2;
+                else {
+                        _trans += ((_mid - _keys)>>1);
+                        break _match;
+                }
+        }
+        _trans += _klen;
+}
+} while (false);
+
+_trans = _JSON_float_indicies[_trans];
+cs = _JSON_float_trans_targs[_trans];
+
+if ( _JSON_float_trans_actions[_trans] != 0 ) {
+        _acts = _JSON_float_trans_actions[_trans];
+        _nacts = (int) _JSON_float_actions[_acts++];
+        while ( _nacts-- > 0 )
+{
+                switch ( _JSON_float_actions[_acts++] )
+                {
+case 0:
+ +

// line 517 “Parser.rl”

+ +
{
+        p--;
+        { p += 1; _goto_targ = 5; if (true)  continue _goto;}
+    }
+break;
+ +

// line 1155 “Parser.java”

+ +
                }
+        }
+}
+ +

case 2:

+ +
if ( cs == 0 ) {
+        _goto_targ = 5;
+        continue _goto;
+}
+if ( ++p != pe ) {
+        _goto_targ = 1;
+        continue _goto;
+}
+ +

case 4: case 5:

+ +
}
+break; }
+}
+ +

// line 547 “Parser.rl”

+ +
    if (cs < JSON_float_first_final) {
+        return -1;
+    }
+
+    return p;
+}
+
+RubyFloat createFloat(int p, int new_p) {
+    Ruby runtime = getRuntime();
+    ByteList num = absSubSequence(p, new_p);
+    return RubyFloat.newFloat(runtime, dc.parse(num, true, runtime.is1_9()));
+}
+
+IRubyObject createCustomDecimal(int p, int new_p) {
+    Ruby runtime = getRuntime();
+    ByteList num = absSubSequence(p, new_p);
+    IRubyObject numString = runtime.newString(num.toString());
+    return parser.decimalClass.callMethod(context, "new", numString);
+}
+ +

// line 1198 “Parser.java” private static byte[] +init__JSON_string_actions_0() {

+ +
return new byte [] {
+    0,    2,    0,    1
+};
+ +

}

+ +

private static final byte _JSON_string_actions[] = +init__JSON_string_actions_0();

+ +

private static byte[] init__JSON_string_key_offsets_0() {

+ +
return new byte [] {
+    0,    0,    1,    5,    8,   14,   20,   26,   32
+};
+ +

}

+ +

private static final byte _JSON_string_key_offsets[] = +init__JSON_string_key_offsets_0();

+ +

private static char[] init__JSON_string_trans_keys_0() {

+ +
return new char [] {
+   34,   34,   92,    0,   31,  117,    0,   31,   48,   57,   65,   70,
+   97,  102,   48,   57,   65,   70,   97,  102,   48,   57,   65,   70,
+   97,  102,   48,   57,   65,   70,   97,  102,    0
+};
+ +

}

+ +

private static final char _JSON_string_trans_keys[] = +init__JSON_string_trans_keys_0();

+ +

private static byte[] init__JSON_string_single_lengths_0() {

+ +
return new byte [] {
+    0,    1,    2,    1,    0,    0,    0,    0,    0
+};
+ +

}

+ +

private static final byte _JSON_string_single_lengths[] = +init__JSON_string_single_lengths_0();

+ +

private static byte[] init__JSON_string_range_lengths_0() {

+ +
return new byte [] {
+    0,    0,    1,    1,    3,    3,    3,    3,    0
+};
+ +

}

+ +

private static final byte _JSON_string_range_lengths[] = +init__JSON_string_range_lengths_0();

+ +

private static byte[] init__JSON_string_index_offsets_0() {

+ +
return new byte [] {
+    0,    0,    2,    6,    9,   13,   17,   21,   25
+};
+ +

}

+ +

private static final byte _JSON_string_index_offsets[] = +init__JSON_string_index_offsets_0();

+ +

private static byte[] init__JSON_string_indicies_0() {

+ +
return new byte [] {
+    0,    1,    2,    3,    1,    0,    4,    1,    0,    5,    5,    5,
+    1,    6,    6,    6,    1,    7,    7,    7,    1,    0,    0,    0,
+    1,    1,    0
+};
+ +

}

+ +

private static final byte _JSON_string_indicies[] = +init__JSON_string_indicies_0();

+ +

private static byte[] init__JSON_string_trans_targs_0() {

+ +
return new byte [] {
+    2,    0,    8,    3,    4,    5,    6,    7
+};
+ +

}

+ +

private static final byte _JSON_string_trans_targs[] = +init__JSON_string_trans_targs_0();

+ +

private static byte[] init__JSON_string_trans_actions_0() {

+ +
return new byte [] {
+    0,    0,    1,    0,    0,    0,    0,    0
+};
+ +

}

+ +

private static final byte _JSON_string_trans_actions[] = +init__JSON_string_trans_actions_0();

+ +

static final int JSON_string_start = 1; static final int +JSON_string_first_final = 8; static final int JSON_string_error = 0;

+ +

static final int JSON_string_en_main = 1;

+ +

// line 599 “Parser.rl”

+ +
void parseString(ParserResult res, int p, int pe) {
+    int cs = EVIL;
+    IRubyObject result = null;
+ +

// line 1308 “Parser.java”

+ +
{
+cs = JSON_string_start;
+}
+ +

// line 606 “Parser.rl”

+ +
int memo = p;
+
+ +

// line 1316 “Parser.java”

+ +
{
+int _klen;
+int _trans = 0;
+int _acts;
+int _nacts;
+int _keys;
+int _goto_targ = 0;
+
+_goto: while (true) {
+switch ( _goto_targ ) {
+case 0:
+if ( p == pe ) {
+        _goto_targ = 4;
+        continue _goto;
+}
+if ( cs == 0 ) {
+        _goto_targ = 5;
+        continue _goto;
+}
+ +

case 1:

+ +
_match: do {
+_keys = _JSON_string_key_offsets[cs];
+_trans = _JSON_string_index_offsets[cs];
+_klen = _JSON_string_single_lengths[cs];
+if ( _klen > 0 ) {
+        int _lower = _keys;
+        int _mid;
+        int _upper = _keys + _klen - 1;
+        while (true) {
+                if ( _upper < _lower )
+                        break;
+
+                _mid = _lower + ((_upper-_lower) >> 1);
+                if ( data[p] < _JSON_string_trans_keys[_mid] )
+                        _upper = _mid - 1;
+                else if ( data[p] > _JSON_string_trans_keys[_mid] )
+                        _lower = _mid + 1;
+                else {
+                        _trans += (_mid - _keys);
+                        break _match;
+                }
+        }
+        _keys += _klen;
+        _trans += _klen;
+}
+
+_klen = _JSON_string_range_lengths[cs];
+if ( _klen > 0 ) {
+        int _lower = _keys;
+        int _mid;
+        int _upper = _keys + (_klen<<1) - 2;
+        while (true) {
+                if ( _upper < _lower )
+                        break;
+
+                _mid = _lower + (((_upper-_lower) >> 1) & ~1);
+                if ( data[p] < _JSON_string_trans_keys[_mid] )
+                        _upper = _mid - 2;
+                else if ( data[p] > _JSON_string_trans_keys[_mid+1] )
+                        _lower = _mid + 2;
+                else {
+                        _trans += ((_mid - _keys)>>1);
+                        break _match;
+                }
+        }
+        _trans += _klen;
+}
+} while (false);
+
+_trans = _JSON_string_indicies[_trans];
+cs = _JSON_string_trans_targs[_trans];
+
+if ( _JSON_string_trans_actions[_trans] != 0 ) {
+        _acts = _JSON_string_trans_actions[_trans];
+        _nacts = (int) _JSON_string_actions[_acts++];
+        while ( _nacts-- > 0 )
+{
+                switch ( _JSON_string_actions[_acts++] )
+                {
+case 0:
+ +

// line 574 “Parser.rl”

+ +
{
+        int offset = byteList.begin();
+        ByteList decoded = decoder.decode(byteList, memo + 1 - offset,
+                                          p - offset);
+        result = getRuntime().newString(decoded);
+        if (result == null) {
+            p--;
+            { p += 1; _goto_targ = 5; if (true)  continue _goto;}
+        } else {
+            {p = (( p + 1))-1;}
+        }
+    }
+break;
+case 1:
+ +

// line 587 “Parser.rl”

+ +
{
+        p--;
+        { p += 1; _goto_targ = 5; if (true)  continue _goto;}
+    }
+break;
+ +

// line 1418 “Parser.java”

+ +
                }
+        }
+}
+ +

case 2:

+ +
if ( cs == 0 ) {
+        _goto_targ = 5;
+        continue _goto;
+}
+if ( ++p != pe ) {
+        _goto_targ = 1;
+        continue _goto;
+}
+ +

case 4: case 5:

+ +
}
+break; }
+}
+ +

// line 608 “Parser.rl”

+ +
    if (parser.createAdditions) {
+        RubyHash matchString = parser.matchString;
+        if (matchString != null) {
+            final IRubyObject[] memoArray = { result, null };
+            try {
+              matchString.visitAll(new RubyHash.Visitor() {
+                  @Override
+                  public void visit(IRubyObject pattern, IRubyObject klass) {
+                      if (pattern.callMethod(context, "===", memoArray[0]).isTrue()) {
+                          memoArray[1] = klass;
+                          throw JumpException.SPECIAL_JUMP;
+                      }
+                  }
+              });
+            } catch (JumpException e) { }
+            if (memoArray[1] != null) {
+                RubyClass klass = (RubyClass) memoArray[1];
+                if (klass.respondsTo("json_creatable?") &&
+                    klass.callMethod(context, "json_creatable?").isTrue()) {
+                    result = klass.callMethod(context, "json_create", result);
+                }
+            }
+        }
+    }
+
+    if (cs >= JSON_string_first_final && result != null) {
+        if (result instanceof RubyString) {
+          ((RubyString)result).force_encoding(context, info.utf8.get());
+        }
+        res.update(result, p + 1);
+    } else {
+        res.update(null, p + 1);
+    }
+}
+ +

// line 1476 “Parser.java” private static byte[] +init__JSON_array_actions_0() {

+ +
return new byte [] {
+    0,    1,    0,    1,    1
+};
+ +

}

+ +

private static final byte _JSON_array_actions[] = +init__JSON_array_actions_0();

+ +

private static byte[] init__JSON_array_key_offsets_0() {

+ +
return new byte [] {
+    0,    0,    1,   18,   25,   41,   43,   44,   46,   47,   49,   50,
+   52,   53,   55,   56,   58,   59
+};
+ +

}

+ +

private static final byte _JSON_array_key_offsets[] = +init__JSON_array_key_offsets_0();

+ +

private static char[] init__JSON_array_trans_keys_0() {

+ +
return new char [] {
+   91,   13,   32,   34,   45,   47,   73,   78,   91,   93,  102,  110,
+  116,  123,    9,   10,   48,   57,   13,   32,   44,   47,   93,    9,
+   10,   13,   32,   34,   45,   47,   73,   78,   91,  102,  110,  116,
+  123,    9,   10,   48,   57,   42,   47,   42,   42,   47,   10,   42,
+   47,   42,   42,   47,   10,   42,   47,   42,   42,   47,   10,    0
+};
+ +

}

+ +

private static final char _JSON_array_trans_keys[] = +init__JSON_array_trans_keys_0();

+ +

private static byte[] init__JSON_array_single_lengths_0() {

+ +
return new byte [] {
+    0,    1,   13,    5,   12,    2,    1,    2,    1,    2,    1,    2,
+    1,    2,    1,    2,    1,    0
+};
+ +

}

+ +

private static final byte _JSON_array_single_lengths[] = +init__JSON_array_single_lengths_0();

+ +

private static byte[] init__JSON_array_range_lengths_0() {

+ +
return new byte [] {
+    0,    0,    2,    1,    2,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0
+};
+ +

}

+ +

private static final byte _JSON_array_range_lengths[] = +init__JSON_array_range_lengths_0();

+ +

private static byte[] init__JSON_array_index_offsets_0() {

+ +
return new byte [] {
+    0,    0,    2,   18,   25,   40,   43,   45,   48,   50,   53,   55,
+   58,   60,   63,   65,   68,   70
+};
+ +

}

+ +

private static final byte _JSON_array_index_offsets[] = +init__JSON_array_index_offsets_0();

+ +

private static byte[] init__JSON_array_indicies_0() {

+ +
return new byte [] {
+    0,    1,    0,    0,    2,    2,    3,    2,    2,    2,    4,    2,
+    2,    2,    2,    0,    2,    1,    5,    5,    6,    7,    4,    5,
+    1,    6,    6,    2,    2,    8,    2,    2,    2,    2,    2,    2,
+    2,    6,    2,    1,    9,   10,    1,   11,    9,   11,    6,    9,
+    6,   10,   12,   13,    1,   14,   12,   14,    5,   12,    5,   13,
+   15,   16,    1,   17,   15,   17,    0,   15,    0,   16,    1,    0
+};
+ +

}

+ +

private static final byte _JSON_array_indicies[] = +init__JSON_array_indicies_0();

+ +

private static byte[] init__JSON_array_trans_targs_0() {

+ +
return new byte [] {
+    2,    0,    3,   13,   17,    3,    4,    9,    5,    6,    8,    7,
+   10,   12,   11,   14,   16,   15
+};
+ +

}

+ +

private static final byte _JSON_array_trans_targs[] = +init__JSON_array_trans_targs_0();

+ +

private static byte[] init__JSON_array_trans_actions_0() {

+ +
return new byte [] {
+    0,    0,    1,    0,    3,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0
+};
+ +

}

+ +

private static final byte _JSON_array_trans_actions[] = +init__JSON_array_trans_actions_0();

+ +

static final int JSON_array_start = 1; static final int +JSON_array_first_final = 17; static final int JSON_array_error = 0;

+ +

static final int JSON_array_en_main = 1;

+ +

// line 681 “Parser.rl”

+ +
void parseArray(ParserResult res, int p, int pe) {
+    int cs = EVIL;
+
+    if (parser.maxNesting > 0 && currentNesting > parser.maxNesting) {
+        throw newException(Utils.M_NESTING_ERROR,
+            "nesting of " + currentNesting + " is too deep");
+    }
+
+    IRubyObject result;
+    if (parser.arrayClass == getRuntime().getArray()) {
+        result = RubyArray.newArray(getRuntime());
+    } else {
+        result = parser.arrayClass.newInstance(context,
+                IRubyObject.NULL_ARRAY, Block.NULL_BLOCK);
+    }
+ +

// line 1609 “Parser.java”

+ +
{
+cs = JSON_array_start;
+}
+ +

// line 700 “Parser.rl”

+ +

// line 1616 “Parser.java”

+ +
{
+int _klen;
+int _trans = 0;
+int _acts;
+int _nacts;
+int _keys;
+int _goto_targ = 0;
+
+_goto: while (true) {
+switch ( _goto_targ ) {
+case 0:
+if ( p == pe ) {
+        _goto_targ = 4;
+        continue _goto;
+}
+if ( cs == 0 ) {
+        _goto_targ = 5;
+        continue _goto;
+}
+ +

case 1:

+ +
_match: do {
+_keys = _JSON_array_key_offsets[cs];
+_trans = _JSON_array_index_offsets[cs];
+_klen = _JSON_array_single_lengths[cs];
+if ( _klen > 0 ) {
+        int _lower = _keys;
+        int _mid;
+        int _upper = _keys + _klen - 1;
+        while (true) {
+                if ( _upper < _lower )
+                        break;
+
+                _mid = _lower + ((_upper-_lower) >> 1);
+                if ( data[p] < _JSON_array_trans_keys[_mid] )
+                        _upper = _mid - 1;
+                else if ( data[p] > _JSON_array_trans_keys[_mid] )
+                        _lower = _mid + 1;
+                else {
+                        _trans += (_mid - _keys);
+                        break _match;
+                }
+        }
+        _keys += _klen;
+        _trans += _klen;
+}
+
+_klen = _JSON_array_range_lengths[cs];
+if ( _klen > 0 ) {
+        int _lower = _keys;
+        int _mid;
+        int _upper = _keys + (_klen<<1) - 2;
+        while (true) {
+                if ( _upper < _lower )
+                        break;
+
+                _mid = _lower + (((_upper-_lower) >> 1) & ~1);
+                if ( data[p] < _JSON_array_trans_keys[_mid] )
+                        _upper = _mid - 2;
+                else if ( data[p] > _JSON_array_trans_keys[_mid+1] )
+                        _lower = _mid + 2;
+                else {
+                        _trans += ((_mid - _keys)>>1);
+                        break _match;
+                }
+        }
+        _trans += _klen;
+}
+} while (false);
+
+_trans = _JSON_array_indicies[_trans];
+cs = _JSON_array_trans_targs[_trans];
+
+if ( _JSON_array_trans_actions[_trans] != 0 ) {
+        _acts = _JSON_array_trans_actions[_trans];
+        _nacts = (int) _JSON_array_actions[_acts++];
+        while ( _nacts-- > 0 )
+{
+                switch ( _JSON_array_actions[_acts++] )
+                {
+case 0:
+ +

// line 650 “Parser.rl”

+ +
{
+        parseValue(res, p, pe);
+        if (res.result == null) {
+            p--;
+            { p += 1; _goto_targ = 5; if (true)  continue _goto;}
+        } else {
+            if (parser.arrayClass == getRuntime().getArray()) {
+                ((RubyArray)result).append(res.result);
+            } else {
+                result.callMethod(context, "<<", res.result);
+            }
+            {p = (( res.p))-1;}
+        }
+    }
+break;
+case 1:
+ +

// line 665 “Parser.rl”

+ +
{
+        p--;
+        { p += 1; _goto_targ = 5; if (true)  continue _goto;}
+    }
+break;
+ +

// line 1720 “Parser.java”

+ +
                }
+        }
+}
+ +

case 2:

+ +
if ( cs == 0 ) {
+        _goto_targ = 5;
+        continue _goto;
+}
+if ( ++p != pe ) {
+        _goto_targ = 1;
+        continue _goto;
+}
+ +

case 4: case 5:

+ +
}
+break; }
+}
+ +

// line 701 “Parser.rl”

+ +
    if (cs >= JSON_array_first_final) {
+        res.update(result, p + 1);
+    } else {
+        throw unexpectedToken(p, pe);
+    }
+}
+ +

// line 1750 “Parser.java” private static byte[] +init__JSON_object_actions_0() {

+ +
return new byte [] {
+    0,    1,    0,    1,    1,    1,    2
+};
+ +

}

+ +

private static final byte _JSON_object_actions[] = +init__JSON_object_actions_0();

+ +

private static byte[] init__JSON_object_key_offsets_0() {

+ +
return new byte [] {
+    0,    0,    1,    8,   14,   16,   17,   19,   20,   36,   43,   49,
+   51,   52,   54,   55,   57,   58,   60,   61,   63,   64,   66,   67,
+   69,   70,   72,   73
+};
+ +

}

+ +

private static final byte _JSON_object_key_offsets[] = +init__JSON_object_key_offsets_0();

+ +

private static char[] init__JSON_object_trans_keys_0() {

+ +
return new char [] {
+  123,   13,   32,   34,   47,  125,    9,   10,   13,   32,   47,   58,
+    9,   10,   42,   47,   42,   42,   47,   10,   13,   32,   34,   45,
+   47,   73,   78,   91,  102,  110,  116,  123,    9,   10,   48,   57,
+   13,   32,   44,   47,  125,    9,   10,   13,   32,   34,   47,    9,
+   10,   42,   47,   42,   42,   47,   10,   42,   47,   42,   42,   47,
+   10,   42,   47,   42,   42,   47,   10,   42,   47,   42,   42,   47,
+   10,    0
+};
+ +

}

+ +

private static final char _JSON_object_trans_keys[] = +init__JSON_object_trans_keys_0();

+ +

private static byte[] init__JSON_object_single_lengths_0() {

+ +
return new byte [] {
+    0,    1,    5,    4,    2,    1,    2,    1,   12,    5,    4,    2,
+    1,    2,    1,    2,    1,    2,    1,    2,    1,    2,    1,    2,
+    1,    2,    1,    0
+};
+ +

}

+ +

private static final byte _JSON_object_single_lengths[] = +init__JSON_object_single_lengths_0();

+ +

private static byte[] init__JSON_object_range_lengths_0() {

+ +
return new byte [] {
+    0,    0,    1,    1,    0,    0,    0,    0,    2,    1,    1,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0
+};
+ +

}

+ +

private static final byte _JSON_object_range_lengths[] = +init__JSON_object_range_lengths_0();

+ +

private static byte[] init__JSON_object_index_offsets_0() {

+ +
return new byte [] {
+    0,    0,    2,    9,   15,   18,   20,   23,   25,   40,   47,   53,
+   56,   58,   61,   63,   66,   68,   71,   73,   76,   78,   81,   83,
+   86,   88,   91,   93
+};
+ +

}

+ +

private static final byte _JSON_object_index_offsets[] = +init__JSON_object_index_offsets_0();

+ +

private static byte[] init__JSON_object_indicies_0() {

+ +
return new byte [] {
+    0,    1,    0,    0,    2,    3,    4,    0,    1,    5,    5,    6,
+    7,    5,    1,    8,    9,    1,   10,    8,   10,    5,    8,    5,
+    9,    7,    7,   11,   11,   12,   11,   11,   11,   11,   11,   11,
+   11,    7,   11,    1,   13,   13,   14,   15,    4,   13,    1,   14,
+   14,    2,   16,   14,    1,   17,   18,    1,   19,   17,   19,   14,
+   17,   14,   18,   20,   21,    1,   22,   20,   22,   13,   20,   13,
+   21,   23,   24,    1,   25,   23,   25,    7,   23,    7,   24,   26,
+   27,    1,   28,   26,   28,    0,   26,    0,   27,    1,    0
+};
+ +

}

+ +

private static final byte _JSON_object_indicies[] = +init__JSON_object_indicies_0();

+ +

private static byte[] init__JSON_object_trans_targs_0() {

+ +
return new byte [] {
+    2,    0,    3,   23,   27,    3,    4,    8,    5,    7,    6,    9,
+   19,    9,   10,   15,   11,   12,   14,   13,   16,   18,   17,   20,
+   22,   21,   24,   26,   25
+};
+ +

}

+ +

private static final byte _JSON_object_trans_targs[] = +init__JSON_object_trans_targs_0();

+ +

private static byte[] init__JSON_object_trans_actions_0() {

+ +
return new byte [] {
+    0,    0,    3,    0,    5,    0,    0,    0,    0,    0,    0,    1,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0
+};
+ +

}

+ +

private static final byte _JSON_object_trans_actions[] = +init__JSON_object_trans_actions_0();

+ +

static final int JSON_object_start = 1; static final int +JSON_object_first_final = 27; static final int JSON_object_error = 0;

+ +

static final int JSON_object_en_main = 1;

+ +

// line 760 “Parser.rl”

+ +
void parseObject(ParserResult res, int p, int pe) {
+    int cs = EVIL;
+    IRubyObject lastName = null;
+    boolean objectDefault = true;
+
+    if (parser.maxNesting > 0 && currentNesting > parser.maxNesting) {
+        throw newException(Utils.M_NESTING_ERROR,
+            "nesting of " + currentNesting + " is too deep");
+    }
+
+    // this is guaranteed to be a RubyHash due to the earlier
+    // allocator test at OptionsReader#getClass
+    IRubyObject result;
+    if (parser.objectClass == getRuntime().getHash()) {
+        result = RubyHash.newHash(getRuntime());
+    } else {
+        objectDefault = false;
+        result = parser.objectClass.newInstance(context,
+                IRubyObject.NULL_ARRAY, Block.NULL_BLOCK);
+    }
+ +

// line 1898 “Parser.java”

+ +
{
+cs = JSON_object_start;
+}
+ +

// line 784 “Parser.rl”

+ +

// line 1905 “Parser.java”

+ +
{
+int _klen;
+int _trans = 0;
+int _acts;
+int _nacts;
+int _keys;
+int _goto_targ = 0;
+
+_goto: while (true) {
+switch ( _goto_targ ) {
+case 0:
+if ( p == pe ) {
+        _goto_targ = 4;
+        continue _goto;
+}
+if ( cs == 0 ) {
+        _goto_targ = 5;
+        continue _goto;
+}
+ +

case 1:

+ +
_match: do {
+_keys = _JSON_object_key_offsets[cs];
+_trans = _JSON_object_index_offsets[cs];
+_klen = _JSON_object_single_lengths[cs];
+if ( _klen > 0 ) {
+        int _lower = _keys;
+        int _mid;
+        int _upper = _keys + _klen - 1;
+        while (true) {
+                if ( _upper < _lower )
+                        break;
+
+                _mid = _lower + ((_upper-_lower) >> 1);
+                if ( data[p] < _JSON_object_trans_keys[_mid] )
+                        _upper = _mid - 1;
+                else if ( data[p] > _JSON_object_trans_keys[_mid] )
+                        _lower = _mid + 1;
+                else {
+                        _trans += (_mid - _keys);
+                        break _match;
+                }
+        }
+        _keys += _klen;
+        _trans += _klen;
+}
+
+_klen = _JSON_object_range_lengths[cs];
+if ( _klen > 0 ) {
+        int _lower = _keys;
+        int _mid;
+        int _upper = _keys + (_klen<<1) - 2;
+        while (true) {
+                if ( _upper < _lower )
+                        break;
+
+                _mid = _lower + (((_upper-_lower) >> 1) & ~1);
+                if ( data[p] < _JSON_object_trans_keys[_mid] )
+                        _upper = _mid - 2;
+                else if ( data[p] > _JSON_object_trans_keys[_mid+1] )
+                        _lower = _mid + 2;
+                else {
+                        _trans += ((_mid - _keys)>>1);
+                        break _match;
+                }
+        }
+        _trans += _klen;
+}
+} while (false);
+
+_trans = _JSON_object_indicies[_trans];
+cs = _JSON_object_trans_targs[_trans];
+
+if ( _JSON_object_trans_actions[_trans] != 0 ) {
+        _acts = _JSON_object_trans_actions[_trans];
+        _nacts = (int) _JSON_object_actions[_acts++];
+        while ( _nacts-- > 0 )
+{
+                switch ( _JSON_object_actions[_acts++] )
+                {
+case 0:
+ +

// line 715 “Parser.rl”

+ +
{
+        parseValue(res, p, pe);
+        if (res.result == null) {
+            p--;
+            { p += 1; _goto_targ = 5; if (true)  continue _goto;}
+        } else {
+            if (parser.objectClass == getRuntime().getHash()) {
+                ((RubyHash)result).op_aset(context, lastName, res.result);
+            } else {
+                result.callMethod(context, "[]=", new IRubyObject[] { lastName, res.result });
+            }
+            {p = (( res.p))-1;}
+        }
+    }
+break;
+case 1:
+ +

// line 730 “Parser.rl”

+ +
{
+        parseString(res, p, pe);
+        if (res.result == null) {
+            p--;
+            { p += 1; _goto_targ = 5; if (true)  continue _goto;}
+        } else {
+            RubyString name = (RubyString)res.result;
+            if (parser.symbolizeNames) {
+                lastName = context.getRuntime().is1_9()
+                               ? name.intern19()
+                               : name.intern();
+            } else {
+                lastName = name;
+            }
+            {p = (( res.p))-1;}
+        }
+    }
+break;
+case 2:
+ +

// line 748 “Parser.rl”

+ +
{
+        p--;
+        { p += 1; _goto_targ = 5; if (true)  continue _goto;}
+    }
+break;
+ +

// line 2029 “Parser.java”

+ +
                }
+        }
+}
+ +

case 2:

+ +
if ( cs == 0 ) {
+        _goto_targ = 5;
+        continue _goto;
+}
+if ( ++p != pe ) {
+        _goto_targ = 1;
+        continue _goto;
+}
+ +

case 4: case 5:

+ +
}
+break; }
+}
+ +

// line 785 “Parser.rl”

+ +
    if (cs < JSON_object_first_final) {
+        res.update(null, p + 1);
+        return;
+    }
+
+    IRubyObject returnedResult = result;
+
+    // attempt to de-serialize object
+    if (parser.createAdditions) {
+        IRubyObject vKlassName;
+        if (objectDefault) {
+            vKlassName = ((RubyHash)result).op_aref(context, parser.createId);
+        } else {
+            vKlassName = result.callMethod(context, "[]", parser.createId);
+        }
+
+        if (!vKlassName.isNil()) {
+            // might throw ArgumentError, we let it propagate
+            IRubyObject klass = parser.info.jsonModule.get().
+                    callMethod(context, "deep_const_get", vKlassName);
+            if (klass.respondsTo("json_creatable?") &&
+                klass.callMethod(context, "json_creatable?").isTrue()) {
+
+                returnedResult = klass.callMethod(context, "json_create", result);
+            }
+        }
+    }
+    res.update(returnedResult, p + 1);
+}
+ +

// line 2082 “Parser.java” private static byte[] init__JSON_actions_0() {

+ +
return new byte [] {
+    0,    1,    0
+};
+ +

}

+ +

private static final byte _JSON_actions[] = init__JSON_actions_0();

+ +

private static byte[] init__JSON_key_offsets_0() {

+ +
return new byte [] {
+    0,    0,   16,   18,   19,   21,   22,   24,   25,   27,   28
+};
+ +

}

+ +

private static final byte _JSON_key_offsets[] = init__JSON_key_offsets_0();

+ +

private static char[] init__JSON_trans_keys_0() {

+ +
return new char [] {
+   13,   32,   34,   45,   47,   73,   78,   91,  102,  110,  116,  123,
+    9,   10,   48,   57,   42,   47,   42,   42,   47,   10,   42,   47,
+   42,   42,   47,   10,   13,   32,   47,    9,   10,    0
+};
+ +

}

+ +

private static final char _JSON_trans_keys[] = init__JSON_trans_keys_0();

+ +

private static byte[] init__JSON_single_lengths_0() {

+ +
return new byte [] {
+    0,   12,    2,    1,    2,    1,    2,    1,    2,    1,    3
+};
+ +

}

+ +

private static final byte _JSON_single_lengths[] = +init__JSON_single_lengths_0();

+ +

private static byte[] init__JSON_range_lengths_0() {

+ +
return new byte [] {
+    0,    2,    0,    0,    0,    0,    0,    0,    0,    0,    1
+};
+ +

}

+ +

private static final byte _JSON_range_lengths[] = +init__JSON_range_lengths_0();

+ +

private static byte[] init__JSON_index_offsets_0() {

+ +
return new byte [] {
+    0,    0,   15,   18,   20,   23,   25,   28,   30,   33,   35
+};
+ +

}

+ +

private static final byte _JSON_index_offsets[] = +init__JSON_index_offsets_0();

+ +

private static byte[] init__JSON_indicies_0() {

+ +
return new byte [] {
+    0,    0,    2,    2,    3,    2,    2,    2,    2,    2,    2,    2,
+    0,    2,    1,    4,    5,    1,    6,    4,    6,    7,    4,    7,
+    5,    8,    9,    1,   10,    8,   10,    0,    8,    0,    9,    7,
+    7,   11,    7,    1,    0
+};
+ +

}

+ +

private static final byte _JSON_indicies[] = init__JSON_indicies_0();

+ +

private static byte[] init__JSON_trans_targs_0() {

+ +
return new byte [] {
+    1,    0,   10,    6,    3,    5,    4,   10,    7,    9,    8,    2
+};
+ +

}

+ +

private static final byte _JSON_trans_targs[] = init__JSON_trans_targs_0();

+ +

private static byte[] init__JSON_trans_actions_0() {

+ +
return new byte [] {
+    0,    0,    1,    0,    0,    0,    0,    0,    0,    0,    0,    0
+};
+ +

}

+ +

private static final byte _JSON_trans_actions[] = +init__JSON_trans_actions_0();

+ +

static final int JSON_start = 1; static final int JSON_first_final = 10; +static final int JSON_error = 0;

+ +

static final int JSON_en_main = 1;

+ +

// line 836 “Parser.rl”

+ +
public IRubyObject parseImplemetation() {
+    int cs = EVIL;
+    int p, pe;
+    IRubyObject result = null;
+    ParserResult res = new ParserResult();
+ +

// line 2195 “Parser.java”

+ +
{
+cs = JSON_start;
+}
+ +

// line 845 “Parser.rl”

+ +
p = byteList.begin();
+pe = p + byteList.length();
+
+ +

// line 2204 “Parser.java”

+ +
{
+int _klen;
+int _trans = 0;
+int _acts;
+int _nacts;
+int _keys;
+int _goto_targ = 0;
+
+_goto: while (true) {
+switch ( _goto_targ ) {
+case 0:
+if ( p == pe ) {
+        _goto_targ = 4;
+        continue _goto;
+}
+if ( cs == 0 ) {
+        _goto_targ = 5;
+        continue _goto;
+}
+ +

case 1:

+ +
_match: do {
+_keys = _JSON_key_offsets[cs];
+_trans = _JSON_index_offsets[cs];
+_klen = _JSON_single_lengths[cs];
+if ( _klen > 0 ) {
+        int _lower = _keys;
+        int _mid;
+        int _upper = _keys + _klen - 1;
+        while (true) {
+                if ( _upper < _lower )
+                        break;
+
+                _mid = _lower + ((_upper-_lower) >> 1);
+                if ( data[p] < _JSON_trans_keys[_mid] )
+                        _upper = _mid - 1;
+                else if ( data[p] > _JSON_trans_keys[_mid] )
+                        _lower = _mid + 1;
+                else {
+                        _trans += (_mid - _keys);
+                        break _match;
+                }
+        }
+        _keys += _klen;
+        _trans += _klen;
+}
+
+_klen = _JSON_range_lengths[cs];
+if ( _klen > 0 ) {
+        int _lower = _keys;
+        int _mid;
+        int _upper = _keys + (_klen<<1) - 2;
+        while (true) {
+                if ( _upper < _lower )
+                        break;
+
+                _mid = _lower + (((_upper-_lower) >> 1) & ~1);
+                if ( data[p] < _JSON_trans_keys[_mid] )
+                        _upper = _mid - 2;
+                else if ( data[p] > _JSON_trans_keys[_mid+1] )
+                        _lower = _mid + 2;
+                else {
+                        _trans += ((_mid - _keys)>>1);
+                        break _match;
+                }
+        }
+        _trans += _klen;
+}
+} while (false);
+
+_trans = _JSON_indicies[_trans];
+cs = _JSON_trans_targs[_trans];
+
+if ( _JSON_trans_actions[_trans] != 0 ) {
+        _acts = _JSON_trans_actions[_trans];
+        _nacts = (int) _JSON_actions[_acts++];
+        while ( _nacts-- > 0 )
+{
+                switch ( _JSON_actions[_acts++] )
+                {
+case 0:
+ +

// line 822 “Parser.rl”

+ +
{
+        parseValue(res, p, pe);
+        if (res.result == null) {
+            p--;
+            { p += 1; _goto_targ = 5; if (true)  continue _goto;}
+        } else {
+            result = res.result;
+            {p = (( res.p))-1;}
+        }
+    }
+break;
+ +

// line 2297 “Parser.java”

+ +
                }
+        }
+}
+ +

case 2:

+ +
if ( cs == 0 ) {
+        _goto_targ = 5;
+        continue _goto;
+}
+if ( ++p != pe ) {
+        _goto_targ = 1;
+        continue _goto;
+}
+ +

case 4: case 5:

+ +
}
+break; }
+}
+ +

// line 848 “Parser.rl”

+ +
        if (cs >= JSON_first_final && p == pe) {
+            return result;
+        } else {
+            throw unexpectedToken(p, pe);
+        }
+    }
+
+    public IRubyObject parse() {
+        return parseImplemetation();
+    }
+
+    /**
+       Updates the "view" bytelist with the new offsets and returns it.
+       @param start
+       @param end
+      /
+    private ByteList absSubSequence(int absStart, int absEnd) {
+        view.setBegin(absStart);
+        view.setRealSize(absEnd - absStart);
+        return view;
+    }
+
+    /**
+       Retrieves a constant directly descended from the <code>JSON</code> module.
+       @param name The constant name
+      /
+    private IRubyObject getConstant(String name) {
+        return parser.info.jsonModule.get().getConstant(name);
+    }
+
+    private RaiseException newException(String className, String message) {
+        return Utils.newException(context, className, message);
+    }
+
+    private RaiseException newException(String className, RubyString message) {
+        return Utils.newException(context, className, message);
+    }
+
+    private RaiseException newException(String className,
+            String messageBegin, ByteList messageEnd) {
+        return newException(className,
+                getRuntime().newString(messageBegin).cat(messageEnd));
+    }
+}
+ +

}

+
+ + + + + diff --git a/tmp/rdoc/java/src/json/ext/Parser_rl.html b/tmp/rdoc/java/src/json/ext/Parser_rl.html new file mode 100644 index 000000000..ee5e79ccc --- /dev/null +++ b/tmp/rdoc/java/src/json/ext/Parser_rl.html @@ -0,0 +1,1084 @@ + + + + + + +Parser.rl - RDoc Documentation + + + + + + + + + + + + + + +
+ +
This code is copyrighted work by Daniel Luz <dev at mernen dot com>.
+
+Distributed under the Ruby license: https://www.ruby-lang.org/en/about/license.txt
+ +

package json.ext;

+ +

import org.jruby.Ruby; import org.jruby.RubyArray; import +org.jruby.RubyClass; import org.jruby.RubyEncoding; import +org.jruby.RubyFloat; import org.jruby.RubyHash; import +org.jruby.RubyInteger; import org.jruby.RubyModule; import +org.jruby.RubyNumeric; import org.jruby.RubyObject; import +org.jruby.RubyString; import org.jruby.anno.JRubyMethod; import +org.jruby.exceptions.JumpException; import +org.jruby.exceptions.RaiseException; import org.jruby.runtime.Block; import +org.jruby.runtime.ObjectAllocator; import org.jruby.runtime.ThreadContext; +import org.jruby.runtime.Visibility; import +org.jruby.runtime.builtin.IRubyObject; import org.jruby.util.ByteList; +import org.jruby.util.ConvertBytes; import static +org.jruby.util.ConvertDouble.DoubleConverter;

+ +
 The <code>JSON::Ext::Parser</code> class.
+
+ <p>This is the JSON parser implemented as a Java class. To use it as the
+ standard parser, set
+   <pre>JSON.parser = JSON::Ext::Parser</pre>
+ This is performed for you when you <code>include "json/ext"</code>.
+
+ <p>This class does not perform the actual parsing, just acts as an interface
+ to Ruby code. When the {@link #parse()} method is invoked, a
+ Parser.ParserSession object is instantiated, which handles the process.
+
+ @author mernen
+/
+ +

public class Parser extends RubyObject {

+ +
private final RuntimeInfo info;
+private RubyString vSource;
+private RubyString createId;
+private boolean createAdditions;
+private int maxNesting;
+private boolean allowNaN;
+private boolean symbolizeNames;
+private RubyClass objectClass;
+private RubyClass arrayClass;
+private RubyClass decimalClass;
+private RubyHash match_string;
+
+private static final int DEFAULT_MAX_NESTING = 100;
+
+private static final ByteList JSON_MINUS_INFINITY = new ByteList(ByteList.plain("-Infinity"));
+// constant names in the JSON module containing those values
+private static final String CONST_NAN = "NaN";
+private static final String CONST_INFINITY = "Infinity";
+private static final String CONST_MINUS_INFINITY = "MinusInfinity";
+
+static final ObjectAllocator ALLOCATOR = new ObjectAllocator() {
+    public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
+        return new Parser(runtime, klazz);
+    }
+};
+
+/**
+   Multiple-value return for internal parser methods.
+
+   <p>All the <code>parse<var>Stuff</var></code> methods return instances of
+   <code>ParserResult</code> when successful, or <code>null</code> when
+   there's a problem with the input data.
+  /
+static final class ParserResult {
+    /**
+       The result of the successful parsing. Should never be
+       <code>null</code>.
+      /
+    IRubyObject result;
+    /**
+       The point where the parser returned.
+      /
+    int p;
+
+    void update(IRubyObject result, int p) {
+        this.result = result;
+        this.p = p;
+    }
+}
+
+public Parser(Ruby runtime, RubyClass metaClass) {
+    super(runtime, metaClass);
+    info = RuntimeInfo.forRuntime(runtime);
+}
+
+/**
+   <code>Parser.new(source, opts = {})</code>
+
+   <p>Creates a new <code>JSON::Ext::Parser</code> instance for the string
+   <code>source</code>.
+   It will be configured by the <code>opts</code> Hash.
+   <code>opts</code> can have the following keys:
+
+   <dl>
+   <dt><code>:max_nesting</code>
+   <dd>The maximum depth of nesting allowed in the parsed data
+   structures. Disable depth checking with <code>:max_nesting => false|nil|0</code>,
+   it defaults to 100.
+
+   <dt><code>:allow_nan</code>
+   <dd>If set to <code>true</code>, allow <code>NaN</code>,
+   <code>Infinity</code> and <code>-Infinity</code> in defiance of RFC 4627
+   to be parsed by the Parser. This option defaults to <code>false</code>.
+
+   <dt><code>:symbolize_names</code>
+   <dd>If set to <code>true</code>, returns symbols for the names (keys) in
+   a JSON object. Otherwise strings are returned, which is also the default.
+
+   <dt><code>:create_additions</code>
+   <dd>If set to <code>false</code>, the Parser doesn't create additions
+   even if a matching class and <code>create_id</code> was found. This option
+   defaults to <code>true</code>.
+
+   <dt><code>:object_class</code>
+   <dd>Defaults to Hash.
+
+   <dt><code>:array_class</code>
+   <dd>Defaults to Array.
+
+   <dt><code>:decimal_class</code>
+   <dd>Specifies which class to use instead of the default (Float) when
+   parsing decimal numbers. This class must accept a single string argument
+   in its constructor.
+   </dl>
+  /
+@JRubyMethod(name = "new", required = 1, optional = 1, meta = true)
+public static IRubyObject newInstance(IRubyObject clazz, IRubyObject[] args, Block block) {
+    Parser parser = (Parser)((RubyClass)clazz).allocate();
+
+    parser.callInit(args, block);
+
+    return parser;
+}
+
+@JRubyMethod(required = 1, optional = 1, visibility = Visibility.PRIVATE)
+public IRubyObject initialize(ThreadContext context, IRubyObject[] args) {
+    Ruby runtime = context.getRuntime();
+    if (this.vSource != null) {
+        throw runtime.newTypeError("already initialized instance");
+     }
+
+    OptionsReader opts   = new OptionsReader(context, args.length > 1 ? args[1] : null);
+    this.maxNesting      = opts.getInt("max_nesting", DEFAULT_MAX_NESTING);
+    this.allowNaN        = opts.getBool("allow_nan", false);
+    this.symbolizeNames  = opts.getBool("symbolize_names", false);
+    this.createId        = opts.getString("create_id", getCreateId(context));
+    this.createAdditions = opts.getBool("create_additions", false);
+    this.objectClass     = opts.getClass("object_class", runtime.getHash());
+    this.arrayClass      = opts.getClass("array_class", runtime.getArray());
+    this.decimalClass    = opts.getClass("decimal_class", null);
+    this.match_string    = opts.getHash("match_string");
+
+    if(symbolizeNames && createAdditions) {
+      throw runtime.newArgumentError(
+        "options :symbolize_names and :create_additions cannot be " +
+        " used in conjunction"
+      );
+    }
+    this.vSource = args[0].convertToString();
+    this.vSource = convertEncoding(context, vSource);
+
+    return this;
+}
+
+/**
+   Checks the given string's encoding. If a non-UTF-8 encoding is detected,
+   a converted copy is returned.
+   Returns the source string if no conversion is needed.
+  /
+private RubyString convertEncoding(ThreadContext context, RubyString source) {
+  RubyEncoding encoding = (RubyEncoding)source.encoding(context);
+  if (encoding == info.ascii8bit.get()) {
+      if (source.isFrozen()) {
+        source = (RubyString) source.dup();
+      }
+      source.force_encoding(context, info.utf8.get());
+  } else {
+    source = (RubyString) source.encode(context, info.utf8.get());
+  }
+  return source;
+}
+
+/**
+   Checks the first four bytes of the given ByteList to infer its encoding,
+   using the principle demonstrated on section 3 of RFC 4627 (JSON).
+  /
+private static String sniffByteList(ByteList bl) {
+    if (bl.length() < 4) return null;
+    if (bl.get(0) == 0 && bl.get(2) == 0) {
+        return bl.get(1) == 0 ? "utf-32be" : "utf-16be";
+    }
+    if (bl.get(1) == 0 && bl.get(3) == 0) {
+        return bl.get(2) == 0 ? "utf-32le" : "utf-16le";
+    }
+    return null;
+}
+
+/**
+   Assumes the given (binary) RubyString to be in the given encoding, then
+   converts it to UTF-8.
+  /
+private RubyString reinterpretEncoding(ThreadContext context,
+        RubyString str, String sniffedEncoding) {
+    RubyEncoding actualEncoding = info.getEncoding(context, sniffedEncoding);
+    RubyEncoding targetEncoding = info.utf8.get();
+    RubyString dup = (RubyString)str.dup();
+    dup.force_encoding(context, actualEncoding);
+    return (RubyString)dup.encode_bang(context, targetEncoding);
+}
+
+/**
+   <code>Parser#parse()</code>
+
+   <p>Parses the current JSON text <code>source</code> and returns the
+   complete data structure as a result.
+  /
+@JRubyMethod
+public IRubyObject parse(ThreadContext context) {
+    return new ParserSession(this, context, info).parse();
+}
+
+/**
+   <code>Parser#source()</code>
+
+   <p>Returns a copy of the current <code>source</code> string, that was
+   used to construct this Parser.
+  /
+@JRubyMethod(name = "source")
+public IRubyObject source_get() {
+    return checkAndGetSource().dup();
+}
+
+public RubyString checkAndGetSource() {
+  if (vSource != null) {
+    return vSource;
+  } else {
+    throw getRuntime().newTypeError("uninitialized instance");
+  }
+}
+
+/**
+   Queries <code>JSON.create_id</code>. Returns <code>null</code> if it is
+   set to <code>nil</code> or <code>false</code>, and a String if not.
+  /
+private RubyString getCreateId(ThreadContext context) {
+    IRubyObject v = info.jsonModule.get().callMethod(context, "create_id");
+    return v.isTrue() ? v.convertToString() : null;
+}
+
+/**
+   A string parsing session.
+
+   <p>Once a ParserSession is instantiated, the source string should not
+   change until the parsing is complete. The ParserSession object assumes
+   the source {@link RubyString} is still associated to its original
+   {@link ByteList}, which in turn must still be bound to the same
+   <code>byte[]</code> value (and on the same offset).
+  /
+// Ragel uses lots of fall-through
+@SuppressWarnings("fallthrough")
+private static class ParserSession {
+    private final Parser parser;
+    private final ThreadContext context;
+    private final RuntimeInfo info;
+    private final ByteList byteList;
+    private final ByteList view;
+    private final byte[] data;
+    private final StringDecoder decoder;
+    private int currentNesting = 0;
+    private final DoubleConverter dc;
+
+    // initialization value for all state variables.
+    // no idea about the origins of this value, ask Flori ;)
+    private static final int EVIL = 0x666;
+
+    private ParserSession(Parser parser, ThreadContext context, RuntimeInfo info) {
+        this.parser = parser;
+        this.context = context;
+        this.info = info;
+        this.byteList = parser.checkAndGetSource().getByteList();
+        this.data = byteList.unsafeBytes();
+        this.view = new ByteList(data, false);
+        this.decoder = new StringDecoder(context);
+        this.dc = new DoubleConverter();
+    }
+
+    private RaiseException unexpectedToken(int absStart, int absEnd) {
+        RubyString msg = getRuntime().newString("unexpected token at '")
+                .cat(data, absStart, absEnd - absStart)
+                .cat((byte)'\'');
+        return newException(Utils.M_PARSER_ERROR, msg);
+    }
+
+    private Ruby getRuntime() {
+        return context.getRuntime();
+    }
+
+    %%{
+        machine JSON_common;
+
+        cr                  = '\n';
+        cr_neg              = [^\n];
+        ws                  = [ \t\r\n];
+        c_comment           = '/*' ( any* - (any* '  ' any* ) ) '*/';
+        cpp_comment         = '//' cr_neg* cr;
+        comment             = c_comment | cpp_comment;
+        ignore              = ws | comment;
+        name_separator      = ':';
+        value_separator     = ',';
+        Vnull               = 'null';
+        Vfalse              = 'false';
+        Vtrue               = 'true';
+        VNaN                = 'NaN';
+        VInfinity           = 'Infinity';
+        VMinusInfinity      = '-Infinity';
+        begin_value         = [nft"\-[{NI] | digit;
+        begin_object        = '{';
+        end_object          = '}';
+        begin_array         = '[';
+        end_array           = ']';
+        begin_string        = '"';
+        begin_name          = begin_string;
+        begin_number        = digit | '-';
+    }%%
+
+    %%{
+        machine JSON_value;
+        include JSON_common;
+
+        write data;
+
+        action parse_null {
+            result = getRuntime().getNil();
+        }
+        action parse_false {
+            result = getRuntime().getFalse();
+        }
+        action parse_true {
+            result = getRuntime().getTrue();
+        }
+        action parse_nan {
+            if (parser.allowNaN) {
+                result = getConstant(CONST_NAN);
+            } else {
+                throw unexpectedToken(p - 2, pe);
+            }
+        }
+        action parse_infinity {
+            if (parser.allowNaN) {
+                result = getConstant(CONST_INFINITY);
+            } else {
+                throw unexpectedToken(p - 7, pe);
+            }
+        }
+        action parse_number {
+            if (pe > fpc + 8 &&
+                absSubSequence(fpc, fpc + 9).equals(JSON_MINUS_INFINITY)) {
+
+                if (parser.allowNaN) {
+                    result = getConstant(CONST_MINUS_INFINITY);
+                    fexec p + 10;
+                    fhold;
+                    fbreak;
+                } else {
+                    throw unexpectedToken(p, pe);
+                }
+            }
+            parseFloat(res, fpc, pe);
+            if (res.result != null) {
+                result = res.result;
+                fexec res.p;
+            }
+            parseInteger(res, fpc, pe);
+            if (res.result != null) {
+                result = res.result;
+                fexec res.p;
+            }
+            fhold;
+            fbreak;
+        }
+        action parse_string {
+            parseString(res, fpc, pe);
+            if (res.result == null) {
+                fhold;
+                fbreak;
+            } else {
+                result = res.result;
+                fexec res.p;
+            }
+        }
+        action parse_array {
+            currentNesting++;
+            parseArray(res, fpc, pe);
+            currentNesting--;
+            if (res.result == null) {
+                fhold;
+                fbreak;
+            } else {
+                result = res.result;
+                fexec res.p;
+            }
+        }
+        action parse_object {
+            currentNesting++;
+            parseObject(res, fpc, pe);
+            currentNesting--;
+            if (res.result == null) {
+                fhold;
+                fbreak;
+            } else {
+                result = res.result;
+                fexec res.p;
+            }
+        }
+        action exit {
+            fhold;
+            fbreak;
+        }
+
+        main := ( Vnull @parse_null |
+                  Vfalse @parse_false |
+                  Vtrue @parse_true |
+                  VNaN @parse_nan |
+                  VInfinity @parse_infinity |
+                  begin_number >parse_number |
+                  begin_string >parse_string |
+                  begin_array >parse_array |
+                  begin_object >parse_object
+                ) %*exit;
+    }%%
+
+    void parseValue(ParserResult res, int p, int pe) {
+        int cs = EVIL;
+        IRubyObject result = null;
+
+        %% write init;
+        %% write exec;
+
+        if (cs >= JSON_value_first_final && result != null) {
+            res.update(result, p);
+        } else {
+            res.update(null, p);
+        }
+    }
+
+    %%{
+        machine JSON_integer;
+
+        write data;
+
+        action exit {
+            fhold;
+            fbreak;
+        }
+
+        main := '-'? ( '0' | [1-9][0-9]* ) ( ^[0-9]? @exit );
+    }%%
+
+    void parseInteger(ParserResult res, int p, int pe) {
+        int new_p = parseIntegerInternal(p, pe);
+        if (new_p == -1) {
+            res.update(null, p);
+            return;
+        }
+        RubyInteger number = createInteger(p, new_p);
+        res.update(number, new_p + 1);
+        return;
+    }
+
+    int parseIntegerInternal(int p, int pe) {
+        int cs = EVIL;
+
+        %% write init;
+        int memo = p;
+        %% write exec;
+
+        if (cs < JSON_integer_first_final) {
+            return -1;
+        }
+
+        return p;
+    }
+
+    RubyInteger createInteger(int p, int new_p) {
+        Ruby runtime = getRuntime();
+        ByteList num = absSubSequence(p, new_p);
+        return bytesToInum(runtime, num);
+    }
+
+    RubyInteger bytesToInum(Ruby runtime, ByteList num) {
+        return runtime.is1_9() ?
+                ConvertBytes.byteListToInum19(runtime, num, 10, true) :
+                ConvertBytes.byteListToInum(runtime, num, 10, true);
+    }
+
+    %%{
+        machine JSON_float;
+        include JSON_common;
+
+        write data;
+
+        action exit {
+            fhold;
+            fbreak;
+        }
+
+        main := '-'?
+                ( ( ( '0' | [1-9][0-9]* ) '.' [0-9]+ ( [Ee] [+\-]?[0-9]+ )? )
+                | ( ( '0' | [1-9][0-9]* ) ( [Ee] [+\-]? [0-9]+ ) ) )
+                ( ^[0-9Ee.\-]? @exit );
+    }%%
+
+    void parseFloat(ParserResult res, int p, int pe) {
+        int new_p = parseFloatInternal(p, pe);
+        if (new_p == -1) {
+            res.update(null, p);
+            return;
+        }
+        IRubyObject number = parser.decimalClass == null ?
+            createFloat(p, new_p) : createCustomDecimal(p, new_p);
+
+        res.update(number, new_p + 1);
+        return;
+    }
+
+    int parseFloatInternal(int p, int pe) {
+        int cs = EVIL;
+
+        %% write init;
+        int memo = p;
+        %% write exec;
+
+        if (cs < JSON_float_first_final) {
+            return -1;
+        }
+
+        return p;
+    }
+
+    RubyFloat createFloat(int p, int new_p) {
+        Ruby runtime = getRuntime();
+        ByteList num = absSubSequence(p, new_p);
+        return RubyFloat.newFloat(runtime, dc.parse(num, true, runtime.is1_9()));
+    }
+
+    IRubyObject createCustomDecimal(int p, int new_p) {
+        Ruby runtime = getRuntime();
+        ByteList num = absSubSequence(p, new_p);
+        IRubyObject numString = runtime.newString(num.toString());
+        return parser.decimalClass.callMethod(context, "new", numString);
+    }
+
+    %%{
+        machine JSON_string;
+        include JSON_common;
+
+        write data;
+
+        action parse_string {
+            int offset = byteList.begin();
+            ByteList decoded = decoder.decode(byteList, memo + 1 - offset,
+                                              p - offset);
+            result = getRuntime().newString(decoded);
+            if (result == null) {
+                fhold;
+                fbreak;
+            } else {
+                fexec p + 1;
+            }
+        }
+
+        action exit {
+            fhold;
+            fbreak;
+        }
+
+        main := '"'
+                ( ( ^(["\\]|0..0x1f)
+                  | '\\'["\\/bfnrt]
+                  | '\\u'[0-9a-fA-F]{4}
+                  | '\\'^(["\\/bfnrtu]|0..0x1f)
+                  )* %parse_string
+                ) '"' @exit;
+    }%%
+
+    void parseString(ParserResult res, int p, int pe) {
+        int cs = EVIL;
+        IRubyObject result = null;
+
+        %% write init;
+        int memo = p;
+        %% write exec;
+
+        if (parser.createAdditions) {
+            RubyHash matchString = parser.matchString;
+            if (matchString != null) {
+                final IRubyObject[] memoArray = { result, null };
+                try {
+                  matchString.visitAll(new RubyHash.Visitor() {
+                      @Override
+                      public void visit(IRubyObject pattern, IRubyObject klass) {
+                          if (pattern.callMethod(context, "===", memoArray[0]).isTrue()) {
+                              memoArray[1] = klass;
+                              throw JumpException.SPECIAL_JUMP;
+                          }
+                      }
+                  });
+                } catch (JumpException e) { }
+                if (memoArray[1] != null) {
+                    RubyClass klass = (RubyClass) memoArray[1];
+                    if (klass.respondsTo("json_creatable?") &&
+                        klass.callMethod(context, "json_creatable?").isTrue()) {
+                        result = klass.callMethod(context, "json_create", result);
+                    }
+                }
+            }
+        }
+
+        if (cs >= JSON_string_first_final && result != null) {
+            if (result instanceof RubyString) {
+              ((RubyString)result).force_encoding(context, info.utf8.get());
+            }
+            res.update(result, p + 1);
+        } else {
+            res.update(null, p + 1);
+        }
+    }
+
+    %%{
+        machine JSON_array;
+        include JSON_common;
+
+        write data;
+
+        action parse_value {
+            parseValue(res, fpc, pe);
+            if (res.result == null) {
+                fhold;
+                fbreak;
+            } else {
+                if (parser.arrayClass == getRuntime().getArray()) {
+                    ((RubyArray)result).append(res.result);
+                } else {
+                    result.callMethod(context, "<<", res.result);
+                }
+                fexec res.p;
+            }
+        }
+
+        action exit {
+            fhold;
+            fbreak;
+        }
+
+        next_element = value_separator ignore* begin_value >parse_value;
+
+        main := begin_array
+                ignore*
+                ( ( begin_value >parse_value
+                    ignore* )
+                  ( ignore*
+                    next_element
+                    ignore* )* )?
+                ignore*
+                end_array @exit;
+    }%%
+
+    void parseArray(ParserResult res, int p, int pe) {
+        int cs = EVIL;
+
+        if (parser.maxNesting > 0 && currentNesting > parser.maxNesting) {
+            throw newException(Utils.M_NESTING_ERROR,
+                "nesting of " + currentNesting + " is too deep");
+        }
+
+        IRubyObject result;
+        if (parser.arrayClass == getRuntime().getArray()) {
+            result = RubyArray.newArray(getRuntime());
+        } else {
+            result = parser.arrayClass.newInstance(context,
+                    IRubyObject.NULL_ARRAY, Block.NULL_BLOCK);
+        }
+
+        %% write init;
+        %% write exec;
+
+        if (cs >= JSON_array_first_final) {
+            res.update(result, p + 1);
+        } else {
+            throw unexpectedToken(p, pe);
+        }
+    }
+
+    %%{
+        machine JSON_object;
+        include JSON_common;
+
+        write data;
+
+        action parse_value {
+            parseValue(res, fpc, pe);
+            if (res.result == null) {
+                fhold;
+                fbreak;
+            } else {
+                if (parser.objectClass == getRuntime().getHash()) {
+                    ((RubyHash)result).op_aset(context, lastName, res.result);
+                } else {
+                    result.callMethod(context, "[]=", new IRubyObject[] { lastName, res.result });
+                }
+                fexec res.p;
+            }
+        }
+
+        action parse_name {
+            parseString(res, fpc, pe);
+            if (res.result == null) {
+                fhold;
+                fbreak;
+            } else {
+                RubyString name = (RubyString)res.result;
+                if (parser.symbolizeNames) {
+                    lastName = context.getRuntime().is1_9()
+                                   ? name.intern19()
+                                   : name.intern();
+                } else {
+                    lastName = name;
+                }
+                fexec res.p;
+            }
+        }
+
+        action exit {
+            fhold;
+            fbreak;
+        }
+
+        pair      = ignore* begin_name >parse_name ignore* name_separator
+          ignore* begin_value >parse_value;
+        next_pair = ignore* value_separator pair;
+
+        main := (
+          begin_object (pair (next_pair)*)? ignore* end_object
+        ) @exit;
+    }%%
+
+    void parseObject(ParserResult res, int p, int pe) {
+        int cs = EVIL;
+        IRubyObject lastName = null;
+        boolean objectDefault = true;
+
+        if (parser.maxNesting > 0 && currentNesting > parser.maxNesting) {
+            throw newException(Utils.M_NESTING_ERROR,
+                "nesting of " + currentNesting + " is too deep");
+        }
+
+        // this is guaranteed to be a RubyHash due to the earlier
+        // allocator test at OptionsReader#getClass
+        IRubyObject result;
+        if (parser.objectClass == getRuntime().getHash()) {
+            result = RubyHash.newHash(getRuntime());
+        } else {
+            objectDefault = false;
+            result = parser.objectClass.newInstance(context,
+                    IRubyObject.NULL_ARRAY, Block.NULL_BLOCK);
+        }
+
+        %% write init;
+        %% write exec;
+
+        if (cs < JSON_object_first_final) {
+            res.update(null, p + 1);
+            return;
+        }
+
+        IRubyObject returnedResult = result;
+
+        // attempt to de-serialize object
+        if (parser.createAdditions) {
+            IRubyObject vKlassName;
+            if (objectDefault) {
+                vKlassName = ((RubyHash)result).op_aref(context, parser.createId);
+            } else {
+                vKlassName = result.callMethod(context, "[]", parser.createId);
+            }
+
+            if (!vKlassName.isNil()) {
+                // might throw ArgumentError, we let it propagate
+                IRubyObject klass = parser.info.jsonModule.get().
+                        callMethod(context, "deep_const_get", vKlassName);
+                if (klass.respondsTo("json_creatable?") &&
+                    klass.callMethod(context, "json_creatable?").isTrue()) {
+
+                    returnedResult = klass.callMethod(context, "json_create", result);
+                }
+            }
+        }
+        res.update(returnedResult, p + 1);
+    }
+
+    %%{
+        machine JSON;
+        include JSON_common;
+
+        write data;
+
+        action parse_value {
+            parseValue(res, fpc, pe);
+            if (res.result == null) {
+                fhold;
+                fbreak;
+            } else {
+                result = res.result;
+                fexec res.p;
+            }
+        }
+
+        main := ignore*
+                ( begin_value >parse_value)
+                ignore*;
+    }%%
+
+    public IRubyObject parseImplemetation() {
+        int cs = EVIL;
+        int p, pe;
+        IRubyObject result = null;
+        ParserResult res = new ParserResult();
+
+        %% write init;
+        p = byteList.begin();
+        pe = p + byteList.length();
+        %% write exec;
+
+        if (cs >= JSON_first_final && p == pe) {
+            return result;
+        } else {
+            throw unexpectedToken(p, pe);
+        }
+    }
+
+    public IRubyObject parse() {
+        return parseImplemetation();
+    }
+
+    /**
+       Updates the "view" bytelist with the new offsets and returns it.
+       @param start
+       @param end
+      /
+    private ByteList absSubSequence(int absStart, int absEnd) {
+        view.setBegin(absStart);
+        view.setRealSize(absEnd - absStart);
+        return view;
+    }
+
+    /**
+       Retrieves a constant directly descended from the <code>JSON</code> module.
+       @param name The constant name
+      /
+    private IRubyObject getConstant(String name) {
+        return parser.info.jsonModule.get().getConstant(name);
+    }
+
+    private RaiseException newException(String className, String message) {
+        return Utils.newException(context, className, message);
+    }
+
+    private RaiseException newException(String className, RubyString message) {
+        return Utils.newException(context, className, message);
+    }
+
+    private RaiseException newException(String className,
+            String messageBegin, ByteList messageEnd) {
+        return newException(className,
+                getRuntime().newString(messageBegin).cat(messageEnd));
+    }
+}
+ +

}

+
+ + + + + diff --git a/tmp/rdoc/java/src/json/ext/RuntimeInfo_java.html b/tmp/rdoc/java/src/json/ext/RuntimeInfo_java.html new file mode 100644 index 000000000..8ee747702 --- /dev/null +++ b/tmp/rdoc/java/src/json/ext/RuntimeInfo_java.html @@ -0,0 +1,310 @@ + + + + + + +RuntimeInfo.java - RDoc Documentation + + + + + + + + + + + + + + +
+ +
This code is copyrighted work by Daniel Luz <dev at mernen dot com>.
+
+Distributed under the Ruby license: https://www.ruby-lang.org/en/about/license.txt
+ +

package json.ext;

+ +

import java.lang.ref.WeakReference; import java.util.HashMap; import +java.util.Map; import java.util.WeakHashMap; import org.jruby.Ruby; import +org.jruby.RubyClass; import org.jruby.RubyEncoding; import +org.jruby.RubyModule; import org.jruby.runtime.ThreadContext; import +org.jruby.runtime.builtin.IRubyObject;

+ +

final class RuntimeInfo {

+ +
// since the vast majority of cases runs just one runtime,
+// we optimize for that
+private static WeakReference<Ruby> runtime1 = new WeakReference<Ruby>(null);
+private static RuntimeInfo info1;
+// store remaining runtimes here (does not include runtime1)
+private static Map<Ruby, RuntimeInfo> runtimes;
+
+// these fields are filled by the service loaders
+// Use WeakReferences so that RuntimeInfo doesn't indirectly hold a hard reference to
+// the Ruby runtime object, which would cause memory leaks in the runtimes map above.
+    JSON   
+WeakReference<RubyModule> jsonModule;
+/** JSON::Ext::Generator::GeneratorMethods::String::Extend */
+WeakReference<RubyModule> stringExtendModule;
+/** JSON::Ext::Generator::State */
+WeakReference<RubyClass> generatorStateClass;
+/** JSON::SAFE_STATE_PROTOTYPE */
+WeakReference<GeneratorState> safeStatePrototype;
+
+final WeakReference<RubyEncoding> utf8;
+final WeakReference<RubyEncoding> ascii8bit;
+// other encodings
+private final Map<String, WeakReference<RubyEncoding>> encodings;
+
+private RuntimeInfo(Ruby runtime) {
+    RubyClass encodingClass = runtime.getEncoding();
+    if (encodingClass == null) { // 1.8 mode
+        utf8 = ascii8bit = null;
+        encodings = null;
+    } else {
+        ThreadContext context = runtime.getCurrentContext();
+
+        utf8 = new WeakReference<RubyEncoding>((RubyEncoding)RubyEncoding.find(context,
+                encodingClass, runtime.newString("utf-8")));
+        ascii8bit = new WeakReference<RubyEncoding>((RubyEncoding)RubyEncoding.find(context,
+                encodingClass, runtime.newString("ascii-8bit")));
+        encodings = new HashMap<String, WeakReference<RubyEncoding>>();
+    }
+}
+
+static RuntimeInfo initRuntime(Ruby runtime) {
+    synchronized (RuntimeInfo.class) {
+        if (runtime1.get() == runtime) {
+            return info1;
+        } else if (runtime1.get() == null) {
+            runtime1 = new WeakReference<Ruby>(runtime);
+            info1 = new RuntimeInfo(runtime);
+            return info1;
+        } else {
+            if (runtimes == null) {
+                runtimes = new WeakHashMap<Ruby, RuntimeInfo>(1);
+            }
+            RuntimeInfo cache = runtimes.get(runtime);
+            if (cache == null) {
+                cache = new RuntimeInfo(runtime);
+                runtimes.put(runtime, cache);
+            }
+            return cache;
+        }
+    }
+}
+
+public static RuntimeInfo forRuntime(Ruby runtime) {
+    synchronized (RuntimeInfo.class) {
+        if (runtime1.get() == runtime) return info1;
+        RuntimeInfo cache = null;
+        if (runtimes != null) cache = runtimes.get(runtime);
+        assert cache != null : "Runtime given has not initialized JSON::Ext";
+        return cache;
+    }
+}
+
+public RubyEncoding getEncoding(ThreadContext context, String name) {
+    synchronized (encodings) {
+        WeakReference<RubyEncoding> encoding = encodings.get(name);
+        if (encoding == null) {
+            Ruby runtime = context.getRuntime();
+            encoding = new WeakReference<RubyEncoding>((RubyEncoding)RubyEncoding.find(context,
+                    runtime.getEncoding(), runtime.newString(name)));
+            encodings.put(name, encoding);
+        }
+        return encoding.get();
+    }
+}
+
+public GeneratorState getSafeStatePrototype(ThreadContext context) {
+    if (safeStatePrototype == null) {
+        IRubyObject value = jsonModule.get().getConstant("SAFE_STATE_PROTOTYPE");
+        if (!(value instanceof GeneratorState)) {
+            throw context.getRuntime().newTypeError(value, generatorStateClass.get());
+        }
+        safeStatePrototype = new WeakReference<GeneratorState>((GeneratorState)value);
+    }
+    return safeStatePrototype.get();
+}
+ +

}

+
+ + + + + diff --git a/tmp/rdoc/java/src/json/ext/StringDecoder_java.html b/tmp/rdoc/java/src/json/ext/StringDecoder_java.html new file mode 100644 index 000000000..ce53fba21 --- /dev/null +++ b/tmp/rdoc/java/src/json/ext/StringDecoder_java.html @@ -0,0 +1,367 @@ + + + + + + +StringDecoder.java - RDoc Documentation + + + + + + + + + + + + + + +
+ +
This code is copyrighted work by Daniel Luz <dev at mernen dot com>.
+
+Distributed under the Ruby license: https://www.ruby-lang.org/en/about/license.txt
+ +

package json.ext;

+ +

import org.jruby.exceptions.RaiseException; import +org.jruby.runtime.ThreadContext; import org.jruby.util.ByteList;

+ +

/**

+ +
 A decoder that reads a JSON-encoded string from the given sources and
+ returns its decoded form on a new ByteList. Escaped Unicode characters
+ are encoded as UTF-8.
+/
+ +

final class StringDecoder extends ByteListTranscoder {

+ +
/**
+   Stores the offset of the high surrogate when reading a surrogate pair,
+   or -1 when not.
+  /
+private int surrogatePairStart = -1;
+
+// Array used for writing multi-byte characters into the buffer at once
+private final byte[] aux = new byte[4];
+
+StringDecoder(ThreadContext context) {
+    super(context);
+}
+
+ByteList decode(ByteList src, int start, int end) {
+    ByteList out = new ByteList(end - start);
+    out.setEncoding(src.getEncoding());
+    init(src, start, end, out);
+    while (hasNext()) {
+        handleChar(readUtf8Char());
+    }
+    quoteStop(pos);
+    return out;
+}
+
+private void handleChar(int c) {
+    if (c == '\\') {
+        quoteStop(charStart);
+        handleEscapeSequence();
+    } else {
+        quoteStart();
+    }
+}
+
+private void handleEscapeSequence() {
+    ensureMin(1);
+    switch (readUtf8Char()) {
+    case 'b':
+        append('\b');
+        break;
+    case 'f':
+        append('\f');
+        break;
+    case 'n':
+        append('\n');
+        break;
+    case 'r':
+        append('\r');
+        break;
+    case 't':
+        append('\t');
+        break;
+    case 'u':
+        ensureMin(4);
+        int cp = readHex();
+        if (Character.isHighSurrogate((char)cp)) {
+            handleLowSurrogate((char)cp);
+        } else if (Character.isLowSurrogate((char)cp)) {
+            // low surrogate with no high surrogate
+            throw invalidUtf8();
+        } else {
+            writeUtf8Char(cp);
+        }
+        break;
+    default: // '\\', '"', '/'...
+        quoteStart();
+    }
+}
+
+private void handleLowSurrogate(char highSurrogate) {
+    surrogatePairStart = charStart;
+    ensureMin(1);
+    int lowSurrogate = readUtf8Char();
+
+    if (lowSurrogate == '\\') {
+        ensureMin(5);
+        if (readUtf8Char() != 'u') throw invalidUtf8();
+        lowSurrogate = readHex();
+    }
+
+    if (Character.isLowSurrogate((char)lowSurrogate)) {
+        writeUtf8Char(Character.toCodePoint(highSurrogate,
+                                            (char)lowSurrogate));
+        surrogatePairStart = -1;
+    } else {
+        throw invalidUtf8();
+    }
+}
+
+private void writeUtf8Char(int codePoint) {
+    if (codePoint < 0x80) {
+        append(codePoint);
+    } else if (codePoint < 0x800) {
+        aux[0] = (byte)(0xc0 | (codePoint >>> 6));
+        aux[1] = tailByte(codePoint & 0x3f);
+        append(aux, 0, 2);
+    } else if (codePoint < 0x10000) {
+        aux[0] = (byte)(0xe0 | (codePoint >>> 12));
+        aux[1] = tailByte(codePoint >>> 6);
+        aux[2] = tailByte(codePoint);
+        append(aux, 0, 3);
+    } else {
+        aux[0] = (byte)(0xf0 | codePoint >>> 18);
+        aux[1] = tailByte(codePoint >>> 12);
+        aux[2] = tailByte(codePoint >>> 6);
+        aux[3] = tailByte(codePoint);
+        append(aux, 0, 4);
+    }
+}
+
+private byte tailByte(int value) {
+    return (byte)(0x80 | (value & 0x3f));
+}
+
+/**
+   Reads a 4-digit unsigned hexadecimal number from the source.
+  /
+private int readHex() {
+    int numberStart = pos;
+    int result = 0;
+    int length = 4;
+    for (int i = 0; i < length; i++) {
+        int digit = readUtf8Char();
+        int digitValue;
+        if (digit >= '0' && digit <= '9') {
+            digitValue = digit - '0';
+        } else if (digit >= 'a' && digit <= 'f') {
+            digitValue = 10 + digit - 'a';
+        } else if (digit >= 'A' && digit <= 'F') {
+            digitValue = 10 + digit - 'A';
+        } else {
+            throw new NumberFormatException("Invalid base 16 number "
+                    + src.subSequence(numberStart, numberStart + length));
+        }
+        result = result * 16 + digitValue;
+    }
+    return result;
+}
+
+@Override
+protected RaiseException invalidUtf8() {
+    ByteList message = new ByteList(
+            ByteList.plain("partial character in source, " +
+                           "but hit end near "));
+    int start = surrogatePairStart != -1 ? surrogatePairStart : charStart;
+    message.append(src, start, srcEnd - start);
+    return Utils.newException(context, Utils.M_PARSER_ERROR,
+                              context.getRuntime().newString(message));
+}
+ +

}

+
+ + + + + diff --git a/tmp/rdoc/java/src/json/ext/StringEncoder_java.html b/tmp/rdoc/java/src/json/ext/StringEncoder_java.html new file mode 100644 index 000000000..d087134b1 --- /dev/null +++ b/tmp/rdoc/java/src/json/ext/StringEncoder_java.html @@ -0,0 +1,310 @@ + + + + + + +StringEncoder.java - RDoc Documentation + + + + + + + + + + + + + + +
+ +
This code is copyrighted work by Daniel Luz <dev at mernen dot com>.
+
+Distributed under the Ruby license: https://www.ruby-lang.org/en/about/license.txt
+ +

package json.ext;

+ +

import org.jruby.exceptions.RaiseException; import +org.jruby.runtime.ThreadContext; import org.jruby.util.ByteList;

+ +
 An encoder that reads from the given source and outputs its representation
+ to another ByteList. The source string is fully checked for UTF-8 validity,
+ and throws a GeneratorError if any problem is found.
+/
+ +

final class StringEncoder extends ByteListTranscoder {

+ +
private final boolean asciiOnly;
+
+// Escaped characters will reuse this array, to avoid new allocations
+// or appending them byte-by-byte
+private final byte[] aux =
+    new byte[] {/* First unicode character   
+                '\\', 'u', 0, 0, 0, 0,
+                /* Second unicode character (for surrogate pairs) */
+                '\\', 'u', 0, 0, 0, 0,
+                /* "\X" characters */
+                '\\', 0};
+// offsets on the array above
+private static final int ESCAPE_UNI1_OFFSET = 0;
+private static final int ESCAPE_UNI2_OFFSET = ESCAPE_UNI1_OFFSET + 6;
+private static final int ESCAPE_CHAR_OFFSET = ESCAPE_UNI2_OFFSET + 6;
+/** Array used for code point decomposition in surrogates */
+private final char[] utf16 = new char[2];
+
+private static final byte[] HEX =
+        new byte[] {'0', '1', '2', '3', '4', '5', '6', '7',
+                    '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
+
+StringEncoder(ThreadContext context, boolean asciiOnly) {
+    super(context);
+    this.asciiOnly = asciiOnly;
+}
+
+void encode(ByteList src, ByteList out) {
+    init(src, out);
+    append('"');
+    while (hasNext()) {
+        handleChar(readUtf8Char());
+    }
+    quoteStop(pos);
+    append('"');
+}
+
+private void handleChar(int c) {
+    switch (c) {
+    case '"':
+    case '\\':
+        escapeChar((char)c);
+        break;
+    case '\n':
+        escapeChar('n');
+        break;
+    case '\r':
+        escapeChar('r');
+        break;
+    case '\t':
+        escapeChar('t');
+        break;
+    case '\f':
+        escapeChar('f');
+        break;
+    case '\b':
+        escapeChar('b');
+        break;
+    default:
+        if (c >= 0x20 && c <= 0x7f ||
+                (c >= 0x80 && !asciiOnly)) {
+            quoteStart();
+        } else {
+            quoteStop(charStart);
+            escapeUtf8Char(c);
+        }
+    }
+}
+
+private void escapeChar(char c) {
+    quoteStop(charStart);
+    aux[ESCAPE_CHAR_OFFSET + 1] = (byte)c;
+    append(aux, ESCAPE_CHAR_OFFSET, 2);
+}
+
+private void escapeUtf8Char(int codePoint) {
+    int numChars = Character.toChars(codePoint, utf16, 0);
+    escapeCodeUnit(utf16[0], ESCAPE_UNI1_OFFSET + 2);
+    if (numChars > 1) escapeCodeUnit(utf16[1], ESCAPE_UNI2_OFFSET + 2);
+    append(aux, ESCAPE_UNI1_OFFSET, 6 * numChars);
+}
+
+private void escapeCodeUnit(char c, int auxOffset) {
+    for (int i = 0; i < 4; i++) {
+        aux[auxOffset + i] = HEX[(c >>> (12 - 4 * i)) & 0xf];
+    }
+}
+
+@Override
+protected RaiseException invalidUtf8() {
+     return Utils.newException(context, Utils.M_GENERATOR_ERROR,
+             "source sequence is illegal/malformed utf-8");
+}
+ +

}

+
+ + + + + diff --git a/tmp/rdoc/java/src/json/ext/Utils_java.html b/tmp/rdoc/java/src/json/ext/Utils_java.html new file mode 100644 index 000000000..c96fc236b --- /dev/null +++ b/tmp/rdoc/java/src/json/ext/Utils_java.html @@ -0,0 +1,285 @@ + + + + + + +Utils.java - RDoc Documentation + + + + + + + + + + + + + + +
+ +
This code is copyrighted work by Daniel Luz <dev at mernen dot com>.
+
+Distributed under the Ruby license: https://www.ruby-lang.org/en/about/license.txt
+ +

package json.ext;

+ +

import org.jruby.Ruby; import org.jruby.RubyArray; import +org.jruby.RubyClass; import org.jruby.RubyException; import +org.jruby.RubyHash; import org.jruby.RubyString; import +org.jruby.exceptions.RaiseException; import org.jruby.runtime.Block; import +org.jruby.runtime.ThreadContext; import +org.jruby.runtime.builtin.IRubyObject; import org.jruby.util.ByteList;

+ +

/**

+ +
 Library of miscellaneous utility functions
+/
+ +

final class Utils {

+ +
public static final String M_GENERATOR_ERROR = "GeneratorError";
+public static final String M_NESTING_ERROR = "NestingError";
+public static final String M_PARSER_ERROR = "ParserError";
+
+private Utils() {
+    throw new RuntimeException();
+}
+
+/**
+   Safe {@link RubyArray} type-checking.
+   Returns the given object if it is an <code>Array</code>,
+   or throws an exception if not.
+   @param object The object to test
+   @return The given object if it is an <code>Array</code>
+   @throws RaiseException <code>TypeError</code> if the object is not
+                          of the expected type
+  /
+static RubyArray ensureArray(IRubyObject object) throws RaiseException {
+    if (object instanceof RubyArray) return (RubyArray)object;
+    Ruby runtime = object.getRuntime();
+    throw runtime.newTypeError(object, runtime.getArray());
+}
+
+static RubyHash ensureHash(IRubyObject object) throws RaiseException {
+    if (object instanceof RubyHash) return (RubyHash)object;
+    Ruby runtime = object.getRuntime();
+    throw runtime.newTypeError(object, runtime.getHash());
+}
+
+static RubyString ensureString(IRubyObject object) throws RaiseException {
+    if (object instanceof RubyString) return (RubyString)object;
+    Ruby runtime = object.getRuntime();
+    throw runtime.newTypeError(object, runtime.getString());
+}
+
+static RaiseException newException(ThreadContext context,
+                                   String className, String message) {
+    return newException(context, className,
+                        context.getRuntime().newString(message));
+}
+
+static RaiseException newException(ThreadContext context,
+                                   String className, RubyString message) {
+    RuntimeInfo info = RuntimeInfo.forRuntime(context.getRuntime());
+    RubyClass klazz = info.jsonModule.get().getClass(className);
+    RubyException excptn =
+        (RubyException)klazz.newInstance(context,
+            new IRubyObject[] {message}, Block.NULL_BLOCK);
+    return new RaiseException(excptn);
+}
+
+static byte[] repeat(ByteList a, int n) {
+    return repeat(a.unsafeBytes(), a.begin(), a.length(), n);
+}
+
+static byte[] repeat(byte[] a, int begin, int length, int n) {
+    if (length == 0) return ByteList.NULL_ARRAY;
+    int resultLen = length * n;
+    byte[] result = new byte[resultLen];
+    for (int pos = 0; pos < resultLen; pos += length) {
+        System.arraycopy(a, begin, result, pos, length);
+    }
+    return result;
+}
+ +

}

+
+ + + + + diff --git a/tmp/rdoc/js/darkfish.js b/tmp/rdoc/js/darkfish.js new file mode 100644 index 000000000..38f877ed4 --- /dev/null +++ b/tmp/rdoc/js/darkfish.js @@ -0,0 +1,161 @@ +/** + * + * Darkfish Page Functions + * $Id: darkfish.js 53 2009-01-07 02:52:03Z deveiant $ + * + * Author: Michael Granger + * + */ + +/* Provide console simulation for firebug-less environments */ +if (!("console" in window) || !("firebug" in console)) { + var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml", + "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"]; + + window.console = {}; + for (var i = 0; i < names.length; ++i) + window.console[names[i]] = function() {}; +}; + + +/** + * Unwrap the first element that matches the given @expr@ from the targets and return them. + */ +$.fn.unwrap = function( expr ) { + return this.each( function() { + $(this).parents( expr ).eq( 0 ).after( this ).remove(); + }); +}; + + +function showSource( e ) { + var target = e.target; + var codeSections = $(target). + parents('.method-detail'). + find('.method-source-code'); + + $(target). + parents('.method-detail'). + find('.method-source-code'). + slideToggle(); +}; + +function hookSourceViews() { + $('.method-heading').click( showSource ); +}; + +function hookSearch() { + var input = $('#search-field').eq(0); + var result = $('#search-results').eq(0); + $(result).show(); + + var search_section = $('#search-section').get(0); + $(search_section).show(); + + var search = new Search(search_data, input, result); + + search.renderItem = function(result) { + var li = document.createElement('li'); + var html = ''; + + // TODO add relative path to + + + + + + + + + + + + +
+ +

#!/usr/bin/env jruby require “rubygems”

+ +

spec = Gem::Specification.new do |s|

+ +
s.name = "json"
+s.version = File.read("VERSION").chomp
+s.summary = "JSON implementation for JRuby"
+s.description = "A JSON implementation as a JRuby extension."
+s.author = "Daniel Luz"
+s.email = "dev+ruby@mernen.com"
+s.homepage = "http://json-jruby.rubyforge.org/"
+s.platform = 'java'
+s.rubyforge_project = "json-jruby"
+s.licenses = ["Ruby"]
+
+s.files = Dir["{docs,lib,tests}   /*"]
+
+if s.respond_to? :specification_version then
+  s.specification_version = 4
+
+  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
+    s.add_development_dependency(%q<rake>, [">= 0"])
+    s.add_development_dependency(%q<test-unit>, ["~> 2.0"])
+  else
+    s.add_dependency(%q<rake>, [">= 0"])
+    s.add_dependency(%q<test-unit>, ["~> 2.0"])
+  end
+else
+  s.add_dependency(%q<rake>, [">= 0"])
+  s.add_dependency(%q<test-unit>, ["~> 2.0"])
+end
+
+ +

end

+ +

if $0 == __FILE__

+ +
Gem::Builder.new(spec).build
+
+ +

else

+ +
spec
+
+ +

end

+
+ + + + + diff --git a/tmp/rdoc/json_pure_gemspec.html b/tmp/rdoc/json_pure_gemspec.html new file mode 100644 index 000000000..b141b8a19 --- /dev/null +++ b/tmp/rdoc/json_pure_gemspec.html @@ -0,0 +1,239 @@ + + + + + + +json_pure.gemspec - RDoc Documentation + + + + + + + + + + + + + + +
+ +

# stub: json_pure 2.1.0 ruby lib

+ +

Gem::Specification.new do |s|

+ +
s.name = "json_pure".freeze
+s.version = "2.1.0"
+
+s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
+s.require_paths = ["lib".freeze]
+s.authors = ["Florian Frank".freeze]
+s.date = "2017-06-21"
+s.description = "This is a JSON implementation in pure Ruby.".freeze
+s.email = "flori@ping.de".freeze
+s.extra_rdoc_files = ["README.md".freeze]
+s.files = ["./tests/test_helper.rb".freeze, ".gitignore".freeze, ".travis.yml".freeze, "CHANGES.md".freeze, "Gemfile".freeze, "README-json-jruby.md".freeze, "README.md".freeze, "Rakefile".freeze, "VERSION".freeze, "data/example.json".freeze, "data/index.html".freeze, "data/prototype.js".freeze, "diagrams/.keep".freeze, "ext/json/ext/fbuffer/fbuffer.h".freeze, "ext/json/ext/generator/depend".freeze, "ext/json/ext/generator/extconf.rb".freeze, "ext/json/ext/generator/generator.c".freeze, "ext/json/ext/generator/generator.h".freeze, "ext/json/ext/parser/depend".freeze, "ext/json/ext/parser/extconf.rb".freeze, "ext/json/ext/parser/parser.c".freeze, "ext/json/ext/parser/parser.h".freeze, "ext/json/ext/parser/parser.rl".freeze, "ext/json/extconf.rb".freeze, "install.rb".freeze, "java/src/json/ext/ByteListTranscoder.java".freeze, "java/src/json/ext/Generator.java".freeze, "java/src/json/ext/GeneratorMethods.java".freeze, "java/src/json/ext/GeneratorService.java".freeze, "java/src/json/ext/GeneratorState.java".freeze, "java/src/json/ext/OptionsReader.java".freeze, "java/src/json/ext/Parser.java".freeze, "java/src/json/ext/Parser.rl".freeze, "java/src/json/ext/ParserService.java".freeze, "java/src/json/ext/RuntimeInfo.java".freeze, "java/src/json/ext/StringDecoder.java".freeze, "java/src/json/ext/StringEncoder.java".freeze, "java/src/json/ext/Utils.java".freeze, "json-java.gemspec".freeze, "json.gemspec".freeze, "json_pure.gemspec".freeze, "lib/json.rb".freeze, "lib/json/add/bigdecimal.rb".freeze, "lib/json/add/complex.rb".freeze, "lib/json/add/core.rb".freeze, "lib/json/add/date.rb".freeze, "lib/json/add/date_time.rb".freeze, "lib/json/add/exception.rb".freeze, "lib/json/add/ostruct.rb".freeze, "lib/json/add/range.rb".freeze, "lib/json/add/rational.rb".freeze, "lib/json/add/regexp.rb".freeze, "lib/json/add/struct.rb".freeze, "lib/json/add/symbol.rb".freeze, "lib/json/add/time.rb".freeze, "lib/json/common.rb".freeze, "lib/json/ext.rb".freeze, "lib/json/ext/.keep".freeze, "lib/json/generic_object.rb".freeze, "lib/json/pure.rb".freeze, "lib/json/pure/generator.rb".freeze, "lib/json/pure/parser.rb".freeze, "lib/json/version.rb".freeze, "references/rfc7159.txt".freeze, "tests/fixtures/fail10.json".freeze, "tests/fixtures/fail11.json".freeze, "tests/fixtures/fail12.json".freeze, "tests/fixtures/fail13.json".freeze, "tests/fixtures/fail14.json".freeze, "tests/fixtures/fail18.json".freeze, "tests/fixtures/fail19.json".freeze, "tests/fixtures/fail2.json".freeze, "tests/fixtures/fail20.json".freeze, "tests/fixtures/fail21.json".freeze, "tests/fixtures/fail22.json".freeze, "tests/fixtures/fail23.json".freeze, "tests/fixtures/fail24.json".freeze, "tests/fixtures/fail25.json".freeze, "tests/fixtures/fail27.json".freeze, "tests/fixtures/fail28.json".freeze, "tests/fixtures/fail3.json".freeze, "tests/fixtures/fail4.json".freeze, "tests/fixtures/fail5.json".freeze, "tests/fixtures/fail6.json".freeze, "tests/fixtures/fail7.json".freeze, "tests/fixtures/fail8.json".freeze, "tests/fixtures/fail9.json".freeze, "tests/fixtures/obsolete_fail1.json".freeze, "tests/fixtures/pass1.json".freeze, "tests/fixtures/pass15.json".freeze, "tests/fixtures/pass16.json".freeze, "tests/fixtures/pass17.json".freeze, "tests/fixtures/pass2.json".freeze, "tests/fixtures/pass26.json".freeze, "tests/fixtures/pass3.json".freeze, "tests/json_addition_test.rb".freeze, "tests/json_common_interface_test.rb".freeze, "tests/json_encoding_test.rb".freeze, "tests/json_ext_parser_test.rb".freeze, "tests/json_fixtures_test.rb".freeze, "tests/json_generator_test.rb".freeze, "tests/json_generic_object_test.rb".freeze, "tests/json_parser_test.rb".freeze, "tests/json_string_matching_test.rb".freeze, "tests/test_helper.rb".freeze, "tools/diff.sh".freeze, "tools/fuzz.rb".freeze, "tools/server.rb".freeze]
+s.homepage = "http://flori.github.com/json".freeze
+s.licenses = ["Ruby".freeze]
+s.rdoc_options = ["--title".freeze, "JSON implemention for ruby".freeze, "--main".freeze, "README.md".freeze]
+s.required_ruby_version = Gem::Requirement.new(">= 1.9".freeze)
+s.rubygems_version = "2.6.11".freeze
+s.summary = "JSON Implementation for Ruby".freeze
+s.test_files = ["./tests/test_helper.rb".freeze]
+
+if s.respond_to? :specification_version then
+  s.specification_version = 4
+
+  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
+    s.add_development_dependency(%q<rake>.freeze, [">= 0"])
+    s.add_development_dependency(%q<test-unit>.freeze, ["~> 2.0"])
+  else
+    s.add_dependency(%q<rake>.freeze, [">= 0"])
+    s.add_dependency(%q<test-unit>.freeze, ["~> 2.0"])
+  end
+else
+  s.add_dependency(%q<rake>.freeze, [">= 0"])
+  s.add_dependency(%q<test-unit>.freeze, ["~> 2.0"])
+end
+
+ +

end

+
+ + + + + diff --git a/tmp/rdoc/references/rfc7159_txt.html b/tmp/rdoc/references/rfc7159_txt.html new file mode 100644 index 000000000..668c6defa --- /dev/null +++ b/tmp/rdoc/references/rfc7159_txt.html @@ -0,0 +1,928 @@ + + + + + + +rfc7159 - RDoc Documentation + + + + + + + + + + + + + + +
+ +

Internet Engineering Task Force (IETF) T. Bray, Ed. +Request for Comments: 7159 Google, Inc. +Obsoletes: 4627, 7158 March 2014 +Category: Standards Track ISSN: 2070-1721

+ +
The JavaScript Object Notation (JSON) Data Interchange Format
+ +

Abstract

+ +
JavaScript Object Notation (JSON) is a lightweight, text-based,
+language-independent data interchange format.  It was derived from
+the ECMAScript Programming Language Standard.  JSON defines a small
+set of formatting rules for the portable representation of structured
+data.
+
+This document removes inconsistencies with other specifications of
+JSON, repairs specification errors, and offers experience-based
+interoperability guidance.
+ +

Status of This Memo

+ +
This is an Internet Standards Track document.
+
+This document is a product of the Internet Engineering Task Force
+(IETF).  It represents the consensus of the IETF community.  It has
+received public review and has been approved for publication by the
+Internet Engineering Steering Group (IESG).  Further information on
+Internet Standards is available in Section 2 of RFC 5741.
+
+Information about the current status of this document, any errata,
+and how to provide feedback on it may be obtained at
+http://www.rfc-editor.org/info/rfc7159.
+ +

Bray Standards Track [Page 1] +RFC 7159 JSON +March 2014

+ +

Copyright Notice

+ +
Copyright (c) 2014 IETF Trust and the persons identified as the
+document authors.  All rights reserved.
+
+This document is subject to BCP 78 and the IETF Trust's Legal
+Provisions Relating to IETF Documents
+(http://trustee.ietf.org/license-info) in effect on the date of
+publication of this document.  Please review these documents
+carefully, as they describe your rights and restrictions with respect
+to this document.  Code Components extracted from this document must
+include Simplified BSD License text as described in Section 4.e of
+the Trust Legal Provisions and are provided without warranty as
+described in the Simplified BSD License.
+
+This document may contain material from IETF Documents or IETF
+Contributions published or made publicly available before November
+10, 2008.  The person(s) controlling the copyright in some of this
+material may not have granted the IETF Trust the right to allow
+modifications of such material outside the IETF Standards Process.
+Without obtaining an adequate license from the person(s) controlling
+the copyright in such materials, this document may not be modified
+outside the IETF Standards Process, and derivative works of it may
+not be created outside the IETF Standards Process, except to format
+it for publication as an RFC or to translate it into languages other
+than English.
+ +

Bray Standards Track [Page 2] +RFC 7159 JSON +March 2014

+ +

Table of Contents

+ +
1. Introduction ....................................................3
+   1.1. Conventions Used in This Document ..........................4
+   1.2. Specifications of JSON .....................................4
+   1.3. Introduction to This Revision ..............................4
+2. JSON Grammar ....................................................4
+3. Values ..........................................................5
+4. Objects .........................................................6
+5. Arrays ..........................................................6
+6. Numbers .........................................................6
+7. Strings .........................................................8
+8. String and Character Issues .....................................9
+   8.1. Character Encoding .........................................9
+   8.2. Unicode Characters .........................................9
+   8.3. String Comparison ..........................................9
+9. Parsers ........................................................10
+10. Generators ....................................................10
+11. IANA Considerations ...........................................10
+12. Security Considerations .......................................11
+13. Examples ......................................................12
+14. Contributors ..................................................13
+15. References ....................................................13
+   15.1. Normative References .....................................13
+   15.2. Informative References ...................................13
+Appendix A. Changes from RFC 4627 .................................15
+
  1. +

    Introduction

    +
+ +
JavaScript Object Notation (JSON) is a text format for the
+serialization of structured data.  It is derived from the object
+literals of JavaScript, as defined in the ECMAScript Programming
+Language Standard, Third Edition [ECMA-262].
+
+JSON can represent four primitive types (strings, numbers, booleans,
+and null) and two structured types (objects and arrays).
+
+A string is a sequence of zero or more Unicode characters [UNICODE].
+Note that this citation references the latest version of Unicode
+rather than a specific release.  It is not expected that future
+changes in the UNICODE specification will impact the syntax of JSON.
+
+An object is an unordered collection of zero or more name/value
+pairs, where a name is a string and a value is a string, number,
+boolean, null, object, or array.
+
+An array is an ordered sequence of zero or more values.
+ +

Bray Standards Track [Page 3] +RFC 7159 JSON +March 2014

+ +
The terms "object" and "array" come from the conventions of
+JavaScript.
+
+JSON's design goals were for it to be minimal, portable, textual, and
+a subset of JavaScript.
+ +

1.1. Conventions Used in This Document

+ +
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
+"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
+document are to be interpreted as described in [RFC2119].
+
+The grammatical rules in this document are to be interpreted as
+described in [RFC5234].
+ +

1.2. Specifications of JSON

+ +
This document updates [RFC4627], which describes JSON and registers
+the media type "application/json".
+
+A description of JSON in ECMAScript terms appears in Version 5.1 of
+the ECMAScript specification [ECMA-262], Section 15.12.  JSON is also
+described in [ECMA-404].
+
+All of the specifications of JSON syntax agree on the syntactic
+elements of the language.
+ +

1.3. Introduction to This Revision

+ +
In the years since the publication of RFC 4627, JSON has found very
+wide use.  This experience has revealed certain patterns, which,
+while allowed by its specifications, have caused interoperability
+problems.
+
+Also, a small number of errata have been reported (see RFC Errata IDs
+607 [Err607] and 3607 [Err3607]).
+
+This document's goal is to apply the errata, remove inconsistencies
+with other specifications of JSON, and highlight practices that can
+lead to interoperability problems.
+
  1. +

    JSON Grammar

    +
+ +
A JSON text is a sequence of tokens.  The set of tokens includes six
+structural characters, strings, numbers, and three literal names.
+
+A JSON text is a serialized value.  Note that certain previous
+specifications of JSON constrained a JSON text to be an object or an
+ +

Bray Standards Track [Page 4] +RFC 7159 JSON +March 2014

+ +
array.  Implementations that generate only objects or arrays where a
+JSON text is called for will be interoperable in the sense that all
+implementations will accept these as conforming JSON texts.
+
+   JSON-text = ws value ws
+
+These are the six structural characters:
+
+   begin-array     = ws %x5B ws  ; [ left square bracket
+
+   begin-object    = ws %x7B ws  ; { left curly bracket
+
+   end-array       = ws %x5D ws  ; ] right square bracket
+
+   end-object      = ws %x7D ws  ; } right curly bracket
+
+   name-separator  = ws %x3A ws  ; : colon
+
+   value-separator = ws %x2C ws  ; , comma
+
+Insignificant whitespace is allowed before or after any of the six
+structural characters.
+
+   ws = *(
+           %x20 /              ; Space
+           %x09 /              ; Horizontal tab
+           %x0A /              ; Line feed or New line
+           %x0D )              ; Carriage return
+
  1. +

    Values

    +
+ +
A JSON value MUST be an object, array, number, or string, or one of
+the following three literal names:
+
+   false null true
+
+The literal names MUST be lowercase.  No other literal names are
+allowed.
+
+   value = false / null / true / object / array / number / string
+
+   false = %x66.61.6c.73.65   ; false
+
+   null  = %x6e.75.6c.6c      ; null
+
+   true  = %x74.72.75.65      ; true
+ +

Bray Standards Track [Page 5] +RFC 7159 JSON +March 2014

+
  1. +

    Objects

    +
+ +
An object structure is represented as a pair of curly brackets
+surrounding zero or more name/value pairs (or members).  A name is a
+string.  A single colon comes after each name, separating the name
+from the value.  A single comma separates a value from a following
+name.  The names within an object SHOULD be unique.
+
+   object = begin-object [ member *( value-separator member ) ]
+            end-object
+
+   member = string name-separator value
+
+An object whose names are all unique is interoperable in the sense
+that all software implementations receiving that object will agree on
+the name-value mappings.  When the names within an object are not
+unique, the behavior of software that receives such an object is
+unpredictable.  Many implementations report the last name/value pair
+only.  Other implementations report an error or fail to parse the
+object, and some implementations report all of the name/value pairs,
+including duplicates.
+
+JSON parsing libraries have been observed to differ as to whether or
+not they make the ordering of object members visible to calling
+software.  Implementations whose behavior does not depend on member
+ordering will be interoperable in the sense that they will not be
+affected by these differences.
+
  1. +

    Arrays

    +
+ +
An array structure is represented as square brackets surrounding zero
+or more values (or elements).  Elements are separated by commas.
+
+array = begin-array [ value *( value-separator value ) ] end-array
+
+There is no requirement that the values in an array be of the same
+type.
+
  1. +

    Numbers

    +
+ +
The representation of numbers is similar to that used in most
+programming languages.  A number is represented in base 10 using
+decimal digits.  It contains an integer component that may be
+prefixed with an optional minus sign, which may be followed by a
+fraction part and/or an exponent part.  Leading zeros are not
+allowed.
+
+A fraction part is a decimal point followed by one or more digits.
+ +

Bray Standards Track [Page 6] +RFC 7159 JSON +March 2014

+ +
An exponent part begins with the letter E in upper or lower case,
+which may be followed by a plus or minus sign.  The E and optional
+sign are followed by one or more digits.
+
+Numeric values that cannot be represented in the grammar below (such
+as Infinity and NaN) are not permitted.
+
+   number = [ minus ] int [ frac ] [ exp ]
+
+   decimal-point = %x2E       ; .
+
+   digit1-9 = %x31-39         ; 1-9
+
+   e = %x65 / %x45            ; e E
+
+   exp = e [ minus / plus ] 1*DIGIT
+
+   frac = decimal-point 1*DIGIT
+
+   int = zero / ( digit1-9 *DIGIT )
+
+   minus = %x2D               ; -
+
+   plus = %x2B                ; +
+
+   zero = %x30                ; 0
+
+This specification allows implementations to set limits on the range
+and precision of numbers accepted.  Since software that implements
+IEEE 754-2008 binary64 (double precision) numbers [IEEE754] is
+generally available and widely used, good interoperability can be
+achieved by implementations that expect no more precision or range
+than these provide, in the sense that implementations will
+approximate JSON numbers within the expected precision.  A JSON
+number such as 1E400 or 3.141592653589793238462643383279 may indicate
+potential interoperability problems, since it suggests that the
+software that created it expects receiving software to have greater
+capabilities for numeric magnitude and precision than is widely
+available.
+
+Note that when such software is used, numbers that are integers and
+are in the range [-(2**53)+1, (2**53)-1] are interoperable in the
+sense that implementations will agree exactly on their numeric
+values.
+ +

Bray Standards Track [Page 7] +RFC 7159 JSON +March 2014

+
  1. +

    Strings

    +
+ +
The representation of strings is similar to conventions used in the C
+family of programming languages.  A string begins and ends with
+quotation marks.  All Unicode characters may be placed within the
+quotation marks, except for the characters that must be escaped:
+quotation mark, reverse solidus, and the control characters (U+0000
+through U+001F).
+
+Any character may be escaped.  If the character is in the Basic
+Multilingual Plane (U+0000 through U+FFFF), then it may be
+represented as a six-character sequence: a reverse solidus, followed
+by the lowercase letter u, followed by four hexadecimal digits that
+encode the character's code point.  The hexadecimal letters A though
+F can be upper or lower case.  So, for example, a string containing
+only a single reverse solidus character may be represented as
+"\u005C".
+
+Alternatively, there are two-character sequence escape
+representations of some popular characters.  So, for example, a
+string containing only a single reverse solidus character may be
+represented more compactly as "\\".
+
+To escape an extended character that is not in the Basic Multilingual
+Plane, the character is represented as a 12-character sequence,
+encoding the UTF-16 surrogate pair.  So, for example, a string
+containing only the G clef character (U+1D11E) may be represented as
+"\uD834\uDD1E".
+
+   string = quotation-mark *char quotation-mark
+
+   char = unescaped /
+       escape (
+           %x22 /          ; "    quotation mark  U+0022
+           %x5C /          ; \    reverse solidus U+005C
+           %x2F /          ; /    solidus         U+002F
+           %x62 /          ; b    backspace       U+0008
+           %x66 /          ; f    form feed       U+000C
+           %x6E /          ; n    line feed       U+000A
+           %x72 /          ; r    carriage return U+000D
+           %x74 /          ; t    tab             U+0009
+           %x75 4HEXDIG )  ; uXXXX                U+XXXX
+
+   escape = %x5C              ; \
+
+   quotation-mark = %x22      ; "
+
+   unescaped = %x20-21 / %x23-5B / %x5D-10FFFF
+ +

Bray Standards Track [Page 8] +RFC 7159 JSON +March 2014

+
  1. +

    String and Character Issues

    +
+ +

8.1. Character Encoding

+ +
JSON text SHALL be encoded in UTF-8, UTF-16, or UTF-32.  The default
+encoding is UTF-8, and JSON texts that are encoded in UTF-8 are
+interoperable in the sense that they will be read successfully by the
+maximum number of implementations; there are many implementations
+that cannot successfully read texts in other encodings (such as
+UTF-16 and UTF-32).
+
+Implementations MUST NOT add a byte order mark to the beginning of a
+JSON text.  In the interests of interoperability, implementations
+that parse JSON texts MAY ignore the presence of a byte order mark
+rather than treating it as an error.
+ +

8.2. Unicode Characters

+ +
When all the strings represented in a JSON text are composed entirely
+of Unicode characters [UNICODE] (however escaped), then that JSON
+text is interoperable in the sense that all software implementations
+that parse it will agree on the contents of names and of string
+values in objects and arrays.
+
+However, the ABNF in this specification allows member names and
+string values to contain bit sequences that cannot encode Unicode
+characters; for example, "\uDEAD" (a single unpaired UTF-16
+surrogate).  Instances of this have been observed, for example, when
+a library truncates a UTF-16 string without checking whether the
+truncation split a surrogate pair.  The behavior of software that
+receives JSON texts containing such values is unpredictable; for
+example, implementations might return different values for the length
+of a string value or even suffer fatal runtime exceptions.
+ +

8.3. String Comparison

+ +
Software implementations are typically required to test names of
+object members for equality.  Implementations that transform the
+textual representation into sequences of Unicode code units and then
+perform the comparison numerically, code unit by code unit, are
+interoperable in the sense that implementations will agree in all
+cases on equality or inequality of two strings.  For example,
+implementations that compare strings with escaped characters
+unconverted may incorrectly find that "a\\b" and "a\u005Cb" are not
+equal.
+ +

Bray Standards Track [Page 9] +RFC 7159 JSON +March 2014

+
  1. +

    Parsers

    +
+ +
A JSON parser transforms a JSON text into another representation.  A
+JSON parser MUST accept all texts that conform to the JSON grammar.
+A JSON parser MAY accept non-JSON forms or extensions.
+
+An implementation may set limits on the size of texts that it
+accepts.  An implementation may set limits on the maximum depth of
+nesting.  An implementation may set limits on the range and precision
+of numbers.  An implementation may set limits on the length and
+character contents of strings.
+
  1. +

    Generators

    +
+ +
A JSON generator produces JSON text.  The resulting text MUST
+strictly conform to the JSON grammar.
+
  1. +

    IANA Considerations

    +
+ +
The MIME media type for JSON text is application/json.
+
+Type name:  application
+
+Subtype name:  json
+
+Required parameters:  n/a
+
+Optional parameters:  n/a
+
+Encoding considerations:  binary
+
+Security considerations:  See [RFC7159], Section 12.
+
+Interoperability considerations:  Described in [RFC7159]
+
+Published specification:  [RFC7159]
+
+Applications that use this media type:
+   JSON has been used to exchange data between applications written
+   in all of these programming languages: ActionScript, C, C#,
+   Clojure, ColdFusion, Common Lisp, E, Erlang, Go, Java, JavaScript,
+   Lua, Objective CAML, Perl, PHP, Python, Rebol, Ruby, Scala, and
+   Scheme.
+ +

Bray Standards Track [Page 10] +RFC 7159 JSON +March 2014

+ +
Additional information:
+   Magic number(s): n/a
+   File extension(s): .json
+   Macintosh file type code(s): TEXT
+
+Person & email address to contact for further information:
+   IESG
+   <iesg@ietf.org>
+
+Intended usage:  COMMON
+
+Restrictions on usage:  none
+
+Author:
+   Douglas Crockford
+   <douglas@crockford.com>
+
+Change controller:
+   IESG
+   <iesg@ietf.org>
+
+Note:  No "charset" parameter is defined for this registration.
+   Adding one really has no effect on compliant recipients.
+
  1. +

    Security Considerations

    +
+ +
Generally, there are security issues with scripting languages.  JSON
+is a subset of JavaScript but excludes assignment and invocation.
+
+Since JSON's syntax is borrowed from JavaScript, it is possible to
+use that language's "eval()" function to parse JSON texts.  This
+generally constitutes an unacceptable security risk, since the text
+could contain executable code along with data declarations.  The same
+consideration applies to the use of eval()-like functions in any
+other programming language in which JSON texts conform to that
+language's syntax.
+ +

Bray Standards Track [Page 11] +RFC 7159 JSON +March 2014

+
  1. +

    Examples

    +
+ +
This is a JSON object:
+
+   {
+     "Image": {
+         "Width":  800,
+         "Height": 600,
+         "Title":  "View from 15th Floor",
+         "Thumbnail": {
+             "Url":    "http://www.example.com/image/481989943",
+             "Height": 125,
+             "Width":  100
+         },
+         "Animated" : false,
+         "IDs": [116, 943, 234, 38793]
+       }
+   }
+
+Its Image member is an object whose Thumbnail member is an object and
+whose IDs member is an array of numbers.
+
+This is a JSON array containing two objects:
+
+   [
+     {
+        "precision": "zip",
+        "Latitude":  37.7668,
+        "Longitude": -122.3959,
+        "Address":   "",
+        "City":      "SAN FRANCISCO",
+        "State":     "CA",
+        "Zip":       "94107",
+        "Country":   "US"
+     },
+     {
+        "precision": "zip",
+        "Latitude":  37.371991,
+        "Longitude": -122.026020,
+        "Address":   "",
+        "City":      "SUNNYVALE",
+        "State":     "CA",
+        "Zip":       "94085",
+        "Country":   "US"
+     }
+   ]
+ +

Bray Standards Track [Page 12] +RFC 7159 JSON +March 2014

+ +
Here are three small JSON texts containing only values:
+
+"Hello world!"
+
+42
+
+true
+
+
  1. +

    Contributors

    +
+ +
RFC 4627 was written by Douglas Crockford.  This document was
+constructed by making a relatively small number of changes to that
+document; thus, the vast majority of the text here is his.
+
  1. +

    References

    +
+ +

15.1. Normative References

+ +
[IEEE754]  IEEE, "IEEE Standard for Floating-Point Arithmetic", IEEE
+           Standard 754, August 2008,
+           <http://grouper.ieee.org/groups/754/>.
+
+[RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate
+           Requirement Levels", BCP 14, RFC 2119, March 1997.
+
+[RFC5234]  Crocker, D. and P. Overell, "Augmented BNF for Syntax
+           Specifications: ABNF", STD 68, RFC 5234, January 2008.
+
+[UNICODE]  The Unicode Consortium, "The Unicode Standard",
+           <http://www.unicode.org/versions/latest/>.
+ +

15.2. Informative References

+ +
[ECMA-262] Ecma International, "ECMAScript Language Specification
+           Edition 5.1", Standard ECMA-262, June 2011,
+           <http://www.ecma-international.org/publications/standards/
+           Ecma-262.htm>.
+
+[ECMA-404] Ecma International, "The JSON Data Interchange Format",
+           Standard ECMA-404, October 2013,
+           <http://www.ecma-international.org/publications/standards/
+           Ecma-404.htm>.
+
+[Err3607]  RFC Errata, Errata ID 3607, RFC 3607,
+           <http://www.rfc-editor.org>.
+ +

Bray Standards Track [Page 13] +RFC 7159 JSON +March 2014

+ +
[Err607]   RFC Errata, Errata ID 607, RFC 607,
+           <http://www.rfc-editor.org>.
+
+[RFC4627]  Crockford, D., "The application/json Media Type for
+           JavaScript Object Notation (JSON)", RFC 4627, July 2006.
+ +

Bray Standards Track [Page 14] +RFC 7159 JSON +March 2014

+ +

Appendix A. Changes from RFC 4627

+ +
This section lists changes between this document and the text in RFC
+4627.
+
+o  Changed the title and abstract of the document.
+
+o  Changed the reference to [UNICODE] to be not version specific.
+
+o  Added a "Specifications of JSON" section.
+
+o  Added an "Introduction to This Revision" section.
+
+o  Changed the definition of "JSON text" so that it can be any JSON
+   value, removing the constraint that it be an object or array.
+
+o  Added language about duplicate object member names, member
+   ordering, and interoperability.
+
+o  Clarified the absence of a requirement that values in an array be
+   of the same JSON type.
+
+o  Applied erratum #607 from RFC 4627 to correctly align the artwork
+   for the definition of "object".
+
+o  Changed "as sequences of digits" to "in the grammar below" in the
+   "Numbers" section, and made base-10-ness explicit.
+
+o  Added language about number interoperability as a function of
+   IEEE754, and added an IEEE754 reference.
+
+o  Added language about interoperability and Unicode characters and
+   about string comparisons.  To do this, turned the old "Encoding"
+   section into a "String and Character Issues" section, with three
+   subsections: "Character Encoding", "Unicode Characters", and
+   "String Comparison".
+
+o  Changed guidance in the "Parsers" section to point out that
+   implementations may set limits on the range "and precision" of
+   numbers.
+
+o  Updated and tidied the "IANA Considerations" section.
+
+o  Made a real "Security Considerations" section and lifted the text
+   out of the previous "IANA Considerations" section.
+ +

Bray Standards Track [Page 15] +RFC 7159 JSON +March 2014

+ +
o  Applied erratum #3607 from RFC 4627 by removing the security
+   consideration that begins "A JSON text can be safely passed" and
+   the JavaScript code that went with that consideration.
+
+o  Added a note to the "Security Considerations" section pointing out
+   the risks of using the "eval()" function in JavaScript or any
+   other language in which JSON texts conform to that language's
+   syntax.
+
+o  Added a note to the "IANA Considerations" clarifying the absence
+   of a "charset" parameter for the application/json media type.
+
+o  Changed "100" to 100 and added a boolean field, both in the first
+   example.
+
+o  Added examples of JSON texts with simple values, neither objects
+   nor arrays.
+
+o  Added a "Contributors" section crediting Douglas Crockford.
+
+o  Added a reference to RFC 4627.
+
+o  Moved the ECMAScript reference from Normative to Informative and
+   updated it to reference ECMAScript 5.1, and added a reference to
+   ECMA 404.
+ +

Author's Address

+ +
Tim Bray (editor)
+Google, Inc.
+
+EMail: tbray@textuality.com
+ +

Bray Standards Track [Page 16]

+
+ + + + + diff --git a/tmp/rdoc/table_of_contents.html b/tmp/rdoc/table_of_contents.html new file mode 100644 index 000000000..1093deb5d --- /dev/null +++ b/tmp/rdoc/table_of_contents.html @@ -0,0 +1,832 @@ + + + + + + +Table of Contents - RDoc Documentation + + + + + + + + + + + + +
+

Table of Contents - RDoc Documentation

+ +

Pages

+ + +

Classes and Modules

+ + +

Methods

+ +
+ + + + diff --git a/tmp/rdoc/tests/fixtures/fail10_json.html b/tmp/rdoc/tests/fixtures/fail10_json.html new file mode 100644 index 000000000..fc30cabd7 --- /dev/null +++ b/tmp/rdoc/tests/fixtures/fail10_json.html @@ -0,0 +1,200 @@ + + + + + + +fail10.json - RDoc Documentation + + + + + + + + + + + + + + +
+ +

{“Extra value after close”: true} “misplaced quoted value”

+
+ + + + + diff --git a/tmp/rdoc/tests/fixtures/fail11_json.html b/tmp/rdoc/tests/fixtures/fail11_json.html new file mode 100644 index 000000000..5b4426fd9 --- /dev/null +++ b/tmp/rdoc/tests/fixtures/fail11_json.html @@ -0,0 +1,200 @@ + + + + + + +fail11.json - RDoc Documentation + + + + + + + + + + + + + + +
+ +

{“Illegal expression”: 1 + 2}

+
+ + + + + diff --git a/tmp/rdoc/tests/fixtures/fail12_json.html b/tmp/rdoc/tests/fixtures/fail12_json.html new file mode 100644 index 000000000..871872dfe --- /dev/null +++ b/tmp/rdoc/tests/fixtures/fail12_json.html @@ -0,0 +1,200 @@ + + + + + + +fail12.json - RDoc Documentation + + + + + + + + + + + + + + +
+ +

{“Illegal invocation”: alert()}

+
+ + + + + diff --git a/tmp/rdoc/tests/fixtures/fail13_json.html b/tmp/rdoc/tests/fixtures/fail13_json.html new file mode 100644 index 000000000..9467782f9 --- /dev/null +++ b/tmp/rdoc/tests/fixtures/fail13_json.html @@ -0,0 +1,200 @@ + + + + + + +fail13.json - RDoc Documentation + + + + + + + + + + + + + + +
+ +

{“Numbers cannot have leading zeroes”: 013}

+
+ + + + + diff --git a/tmp/rdoc/tests/fixtures/fail14_json.html b/tmp/rdoc/tests/fixtures/fail14_json.html new file mode 100644 index 000000000..c2e0c6568 --- /dev/null +++ b/tmp/rdoc/tests/fixtures/fail14_json.html @@ -0,0 +1,200 @@ + + + + + + +fail14.json - RDoc Documentation + + + + + + + + + + + + + + +
+ +

{“Numbers cannot be hex”: 0x14}

+
+ + + + + diff --git a/tmp/rdoc/tests/fixtures/fail18_json.html b/tmp/rdoc/tests/fixtures/fail18_json.html new file mode 100644 index 000000000..ae49bf6bb --- /dev/null +++ b/tmp/rdoc/tests/fixtures/fail18_json.html @@ -0,0 +1,200 @@ + + + + + + +fail18.json - RDoc Documentation + + + + + + + + + + + + + + +
+
[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[“Too deep”]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] +
+
+ + + + + diff --git a/tmp/rdoc/tests/fixtures/fail19_json.html b/tmp/rdoc/tests/fixtures/fail19_json.html new file mode 100644 index 000000000..092a56f7e --- /dev/null +++ b/tmp/rdoc/tests/fixtures/fail19_json.html @@ -0,0 +1,200 @@ + + + + + + +fail19.json - RDoc Documentation + + + + + + + + + + + + + + +
+ +

{“Missing colon” null}

+
+ + + + + diff --git a/tmp/rdoc/tests/fixtures/fail20_json.html b/tmp/rdoc/tests/fixtures/fail20_json.html new file mode 100644 index 000000000..2a31105c6 --- /dev/null +++ b/tmp/rdoc/tests/fixtures/fail20_json.html @@ -0,0 +1,202 @@ + + + + + + +fail20.json - RDoc Documentation + + + + + + + + + + + + + + +
+
{“Double colon” +
+

null}

+
+
+ + + + + diff --git a/tmp/rdoc/tests/fixtures/fail21_json.html b/tmp/rdoc/tests/fixtures/fail21_json.html new file mode 100644 index 000000000..de09fa8f1 --- /dev/null +++ b/tmp/rdoc/tests/fixtures/fail21_json.html @@ -0,0 +1,200 @@ + + + + + + +fail21.json - RDoc Documentation + + + + + + + + + + + + + + +
+ +

{“Comma instead of colon”, null}

+
+ + + + + diff --git a/tmp/rdoc/tests/fixtures/fail22_json.html b/tmp/rdoc/tests/fixtures/fail22_json.html new file mode 100644 index 000000000..3fc7f26d0 --- /dev/null +++ b/tmp/rdoc/tests/fixtures/fail22_json.html @@ -0,0 +1,200 @@ + + + + + + +fail22.json - RDoc Documentation + + + + + + + + + + + + + + +
+
“Colon instead of comma”: false +
+
+ + + + + diff --git a/tmp/rdoc/tests/fixtures/fail23_json.html b/tmp/rdoc/tests/fixtures/fail23_json.html new file mode 100644 index 000000000..0d081f6cf --- /dev/null +++ b/tmp/rdoc/tests/fixtures/fail23_json.html @@ -0,0 +1,200 @@ + + + + + + +fail23.json - RDoc Documentation + + + + + + + + + + + + + + +
+
“Bad value”, truth +
+
+ + + + + diff --git a/tmp/rdoc/tests/fixtures/fail24_json.html b/tmp/rdoc/tests/fixtures/fail24_json.html new file mode 100644 index 000000000..a20282d50 --- /dev/null +++ b/tmp/rdoc/tests/fixtures/fail24_json.html @@ -0,0 +1,200 @@ + + + + + + +fail24.json - RDoc Documentation + + + + + + + + + + + + + + +
+
'single quote' +
+
+ + + + + diff --git a/tmp/rdoc/tests/fixtures/fail25_json.html b/tmp/rdoc/tests/fixtures/fail25_json.html new file mode 100644 index 000000000..376de5fae --- /dev/null +++ b/tmp/rdoc/tests/fixtures/fail25_json.html @@ -0,0 +1,200 @@ + + + + + + +fail25.json - RDoc Documentation + + + + + + + + + + + + + + +
+
“tab character in string ” +
+
+ + + + + diff --git a/tmp/rdoc/tests/fixtures/fail27_json.html b/tmp/rdoc/tests/fixtures/fail27_json.html new file mode 100644 index 000000000..5244b9026 --- /dev/null +++ b/tmp/rdoc/tests/fixtures/fail27_json.html @@ -0,0 +1,200 @@ + + + + + + +fail27.json - RDoc Documentation + + + + + + + + + + + + + + +
+ +

[“line break”]

+
+ + + + + diff --git a/tmp/rdoc/tests/fixtures/fail28_json.html b/tmp/rdoc/tests/fixtures/fail28_json.html new file mode 100644 index 000000000..fc3f46c31 --- /dev/null +++ b/tmp/rdoc/tests/fixtures/fail28_json.html @@ -0,0 +1,200 @@ + + + + + + +fail28.json - RDoc Documentation + + + + + + + + + + + + + + +
+ +

[“line\ break”]

+
+ + + + + diff --git a/tmp/rdoc/tests/fixtures/fail2_json.html b/tmp/rdoc/tests/fixtures/fail2_json.html new file mode 100644 index 000000000..af1a574b0 --- /dev/null +++ b/tmp/rdoc/tests/fixtures/fail2_json.html @@ -0,0 +1,200 @@ + + + + + + +fail2.json - RDoc Documentation + + + + + + + + + + + + + + +
+ +

[“Unclosed array”

+
+ + + + + diff --git a/tmp/rdoc/tests/fixtures/fail3_json.html b/tmp/rdoc/tests/fixtures/fail3_json.html new file mode 100644 index 000000000..12667dd29 --- /dev/null +++ b/tmp/rdoc/tests/fixtures/fail3_json.html @@ -0,0 +1,200 @@ + + + + + + +fail3.json - RDoc Documentation + + + + + + + + + + + + + + +
+ +

{unquoted_key: “keys must be quoted”}

+
+ + + + + diff --git a/tmp/rdoc/tests/fixtures/fail4_json.html b/tmp/rdoc/tests/fixtures/fail4_json.html new file mode 100644 index 000000000..073b643da --- /dev/null +++ b/tmp/rdoc/tests/fixtures/fail4_json.html @@ -0,0 +1,200 @@ + + + + + + +fail4.json - RDoc Documentation + + + + + + + + + + + + + + +
+
“extra comma”, +
+
+ + + + + diff --git a/tmp/rdoc/tests/fixtures/fail5_json.html b/tmp/rdoc/tests/fixtures/fail5_json.html new file mode 100644 index 000000000..0acb3b6f0 --- /dev/null +++ b/tmp/rdoc/tests/fixtures/fail5_json.html @@ -0,0 +1,200 @@ + + + + + + +fail5.json - RDoc Documentation + + + + + + + + + + + + + + +
+
“double extra comma”,, +
+
+ + + + + diff --git a/tmp/rdoc/tests/fixtures/fail6_json.html b/tmp/rdoc/tests/fixtures/fail6_json.html new file mode 100644 index 000000000..02e896f9d --- /dev/null +++ b/tmp/rdoc/tests/fixtures/fail6_json.html @@ -0,0 +1,200 @@ + + + + + + +fail6.json - RDoc Documentation + + + + + + + + + + + + + + +
+
, “<– missing value” +
+
+ + + + + diff --git a/tmp/rdoc/tests/fixtures/fail7_json.html b/tmp/rdoc/tests/fixtures/fail7_json.html new file mode 100644 index 000000000..83a36b2c2 --- /dev/null +++ b/tmp/rdoc/tests/fixtures/fail7_json.html @@ -0,0 +1,200 @@ + + + + + + +fail7.json - RDoc Documentation + + + + + + + + + + + + + + +
+ +

[“Comma after the close”],

+
+ + + + + diff --git a/tmp/rdoc/tests/fixtures/fail8_json.html b/tmp/rdoc/tests/fixtures/fail8_json.html new file mode 100644 index 000000000..8dbb43555 --- /dev/null +++ b/tmp/rdoc/tests/fixtures/fail8_json.html @@ -0,0 +1,200 @@ + + + + + + +fail8.json - RDoc Documentation + + + + + + + + + + + + + + +
+
“Extra close”] +
+
+ + + + + diff --git a/tmp/rdoc/tests/fixtures/fail9_json.html b/tmp/rdoc/tests/fixtures/fail9_json.html new file mode 100644 index 000000000..2b73c9b05 --- /dev/null +++ b/tmp/rdoc/tests/fixtures/fail9_json.html @@ -0,0 +1,200 @@ + + + + + + +fail9.json - RDoc Documentation + + + + + + + + + + + + + + +
+ +

{“Extra comma”: true,}

+
+ + + + + diff --git a/tmp/rdoc/tests/fixtures/obsolete_fail1_json.html b/tmp/rdoc/tests/fixtures/obsolete_fail1_json.html new file mode 100644 index 000000000..2146b1fd8 --- /dev/null +++ b/tmp/rdoc/tests/fixtures/obsolete_fail1_json.html @@ -0,0 +1,201 @@ + + + + + + +obsolete_fail1.json - RDoc Documentation + + + + + + + + + + + + + + +
+ +

“A JSON payload should be an object or array, +not a string.”

+
+ + + + + diff --git a/tmp/rdoc/tests/fixtures/pass15_json.html b/tmp/rdoc/tests/fixtures/pass15_json.html new file mode 100644 index 000000000..9db51d0b6 --- /dev/null +++ b/tmp/rdoc/tests/fixtures/pass15_json.html @@ -0,0 +1,200 @@ + + + + + + +pass15.json - RDoc Documentation + + + + + + + + + + + + + + +
+
“Illegal backslash escape: x15” +
+
+ + + + + diff --git a/tmp/rdoc/tests/fixtures/pass16_json.html b/tmp/rdoc/tests/fixtures/pass16_json.html new file mode 100644 index 000000000..288713ac1 --- /dev/null +++ b/tmp/rdoc/tests/fixtures/pass16_json.html @@ -0,0 +1,200 @@ + + + + + + +pass16.json - RDoc Documentation + + + + + + + + + + + + + + +
+
“Illegal backslash escape: '” +
+
+ + + + + diff --git a/tmp/rdoc/tests/fixtures/pass17_json.html b/tmp/rdoc/tests/fixtures/pass17_json.html new file mode 100644 index 000000000..66b31b898 --- /dev/null +++ b/tmp/rdoc/tests/fixtures/pass17_json.html @@ -0,0 +1,200 @@ + + + + + + +pass17.json - RDoc Documentation + + + + + + + + + + + + + + +
+
“Illegal backslash escape: 017” +
+
+ + + + + diff --git a/tmp/rdoc/tests/fixtures/pass1_json.html b/tmp/rdoc/tests/fixtures/pass1_json.html new file mode 100644 index 000000000..d3a2dabbb --- /dev/null +++ b/tmp/rdoc/tests/fixtures/pass1_json.html @@ -0,0 +1,257 @@ + + + + + + +pass1.json - RDoc Documentation + + + + + + + + + + + + + + +
+ +

[

+ +
"JSON Test Pattern pass1",
+{"object with 1 member":["array with 1 element"]},
+{},
+[],
+-42,
+true,
+false,
+null,
+{
+    "integer": 1234567890,
+    "real": -9876.543210,
+    "e": 0.123456789e-12,
+    "E": 1.234567890E+34,
+    "":  23456789012E666,
+    "zero": 0,
+    "one": 1,
+    "space": " ",
+    "quote": "\"",
+    "backslash": "\\",
+    "controls": "\b\f\n\r\t",
+    "slash": "/ & \/",
+    "alpha": "abcdefghijklmnopqrstuvwyz",
+    "ALPHA": "ABCDEFGHIJKLMNOPQRSTUVWYZ",
+    "digit": "0123456789",
+    "special": "`1~!@#$%^&*()_+-={':[,]}|;.</>?",
+    "hex": "\u0123\u4567\u89AB\uCDEF\uabcd\uef4A",
+    "true": true,
+    "false": false,
+    "null": null,
+    "array":[  ],
+    "object":{  },
+    "address": "50 St. James Street",
+    "url": "http://www.JSON.org/",
+    "comment": "//    <!-- --",
+    "# -- -->   ": " ",
+    " s p a c e d " :[1,2 , 3
+ +

,

+ +

4 , 5 , 6 ,7 ],

+ +
"compact": [1,2,3,4,5,6,7],
+"jsontext": "{\"object with 1 member\":[\"array with 1 element\"]}",
+"quotes": "&#34; \u0022 %22 0x22 034 &#x22;",
+"\/\\\"\uCAFE\uBABE\uAB98\uFCDE\ubcda\uef4A\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',./<>?"
+ +

: “A key can be any string”

+ +
},
+0.5 ,98.6
+ +

, 99.44 ,

+ +

1066

+ +

,“rosebud”]

+
+ + + + + diff --git a/tmp/rdoc/tests/fixtures/pass26_json.html b/tmp/rdoc/tests/fixtures/pass26_json.html new file mode 100644 index 000000000..3adf568d3 --- /dev/null +++ b/tmp/rdoc/tests/fixtures/pass26_json.html @@ -0,0 +1,200 @@ + + + + + + +pass26.json - RDoc Documentation + + + + + + + + + + + + + + +
+
“tab\ character\ in\ string\ ” +
+
+ + + + + diff --git a/tmp/rdoc/tests/fixtures/pass2_json.html b/tmp/rdoc/tests/fixtures/pass2_json.html new file mode 100644 index 000000000..d6f000616 --- /dev/null +++ b/tmp/rdoc/tests/fixtures/pass2_json.html @@ -0,0 +1,200 @@ + + + + + + +pass2.json - RDoc Documentation + + + + + + + + + + + + + + +
+
[[[[[[[[[[[[[[[[[[“Not too deep”]]]]]]]]]]]]]]]]]] +
+
+ + + + + diff --git a/tmp/rdoc/tests/fixtures/pass3_json.html b/tmp/rdoc/tests/fixtures/pass3_json.html new file mode 100644 index 000000000..33f59d288 --- /dev/null +++ b/tmp/rdoc/tests/fixtures/pass3_json.html @@ -0,0 +1,207 @@ + + + + + + +pass3.json - RDoc Documentation + + + + + + + + + + + + + + +
+ +

{

+ +
"JSON Test Pattern pass3": {
+    "The outermost value": "must be an object or array.",
+    "In this test": "It is an object."
+}
+ +

}

+
+ + + + + diff --git a/tmp/rdoc/tools/diff_sh.html b/tmp/rdoc/tools/diff_sh.html new file mode 100644 index 000000000..4f9c7940b --- /dev/null +++ b/tmp/rdoc/tools/diff_sh.html @@ -0,0 +1,218 @@ + + + + + + +diff.sh - RDoc Documentation + + + + + + + + + + + + + + +
+ +

#!/bin/sh

+ +

files=`find ext -name '*.[ch]' -o -name parser.rl`

+ +

for f in $files do

+ +
b=`basename $f`
+g=`find ../ruby/ext/json -name $b`
+d=`diff -u $f $g`
+test -z "$d" && continue
+echo "$d"
+read -p "Edit diff of $b? " a
+case $a in
+[yY]*)
+  vimdiff $f $g
+  ;;
+esac
+ +

done

+
+ + + + +