usamin 7.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
 - data/.gitignore +16 -0
 - data/.travis.yml +5 -0
 - data/Gemfile +6 -0
 - data/Gemfile.lock +29 -0
 - data/LICENSE.txt +21 -0
 - data/README.md +255 -0
 - data/Rakefile +18 -0
 - data/bin/console +14 -0
 - data/bin/setup +8 -0
 - data/ext/usamin/extconf.rb +6 -0
 - data/ext/usamin/usamin.cpp +987 -0
 - data/lib/usamin.rb +2 -0
 - data/lib/usamin/version.rb +3 -0
 - data/usamin.gemspec +29 -0
 - metadata +115 -0
 
    
        checksums.yaml
    ADDED
    
    | 
         @@ -0,0 +1,7 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            ---
         
     | 
| 
      
 2 
     | 
    
         
            +
            SHA256:
         
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 38c48b49c05c5a95289abb777b32db4b47252fd31c5553acf09b11f3c076b500
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 023641ec4fb9fc7277044ae4c6a1dcca134ace8ed4aaddf2b64c80a4fb7ef89e
         
     | 
| 
      
 5 
     | 
    
         
            +
            SHA512:
         
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 493e984049b444963a1be108cc624bc6a426edbf3c951c860f4662f4f3121e309e1768be11a919a16353c36fc96fb90124daf68bb68ec8f5756a82850c4a7618
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 74cfe2c5148808a6be7f43a6bddf5ec1306ee3692a7833ea775392b61948fee537fc83befe55d0961d5ff3771e43a91d208294d2a8b4c41c8df20c738976cb5a
         
     | 
    
        data/.gitignore
    ADDED
    
    
    
        data/.travis.yml
    ADDED
    
    
    
        data/Gemfile
    ADDED
    
    
    
        data/Gemfile.lock
    ADDED
    
    | 
         @@ -0,0 +1,29 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            PATH
         
     | 
| 
      
 2 
     | 
    
         
            +
              remote: .
         
     | 
| 
      
 3 
     | 
    
         
            +
              specs:
         
     | 
| 
      
 4 
     | 
    
         
            +
                usamin (7.7.0)
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            GEM
         
     | 
| 
      
 7 
     | 
    
         
            +
              remote: https://rubygems.org/
         
     | 
| 
      
 8 
     | 
    
         
            +
              specs:
         
     | 
| 
      
 9 
     | 
    
         
            +
                coderay (1.1.2)
         
     | 
| 
      
 10 
     | 
    
         
            +
                method_source (0.9.0)
         
     | 
| 
      
 11 
     | 
    
         
            +
                pry (0.11.3)
         
     | 
| 
      
 12 
     | 
    
         
            +
                  coderay (~> 1.1.0)
         
     | 
| 
      
 13 
     | 
    
         
            +
                  method_source (~> 0.9.0)
         
     | 
| 
      
 14 
     | 
    
         
            +
                rake (12.3.0)
         
     | 
| 
      
 15 
     | 
    
         
            +
                rake-compiler (1.0.4)
         
     | 
| 
      
 16 
     | 
    
         
            +
                  rake
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            PLATFORMS
         
     | 
| 
      
 19 
     | 
    
         
            +
              ruby
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            DEPENDENCIES
         
     | 
| 
      
 22 
     | 
    
         
            +
              bundler (~> 1.16)
         
     | 
| 
      
 23 
     | 
    
         
            +
              pry (~> 0.11)
         
     | 
| 
      
 24 
     | 
    
         
            +
              rake (~> 12.3)
         
     | 
| 
      
 25 
     | 
    
         
            +
              rake-compiler
         
     | 
| 
      
 26 
     | 
    
         
            +
              usamin!
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
            BUNDLED WITH
         
     | 
| 
      
 29 
     | 
    
         
            +
               1.16.1
         
     | 
    
        data/LICENSE.txt
    ADDED
    
    | 
         @@ -0,0 +1,21 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            The MIT License (MIT)
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            Copyright (c) 2018 Ishotihadus
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            Permission is hereby granted, free of charge, to any person obtaining a copy
         
     | 
| 
      
 6 
     | 
    
         
            +
            of this software and associated documentation files (the "Software"), to deal
         
     | 
| 
      
 7 
     | 
    
         
            +
            in the Software without restriction, including without limitation the rights
         
     | 
| 
      
 8 
     | 
    
         
            +
            to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
         
     | 
| 
      
 9 
     | 
    
         
            +
            copies of the Software, and to permit persons to whom the Software is
         
     | 
| 
      
 10 
     | 
    
         
            +
            furnished to do so, subject to the following conditions:
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            The above copyright notice and this permission notice shall be included in
         
     | 
| 
      
 13 
     | 
    
         
            +
            all copies or substantial portions of the Software.
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
         
     | 
| 
      
 16 
     | 
    
         
            +
            IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
         
     | 
| 
      
 17 
     | 
    
         
            +
            FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
         
     | 
| 
      
 18 
     | 
    
         
            +
            AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
         
     | 
| 
      
 19 
     | 
    
         
            +
            LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
         
     | 
| 
      
 20 
     | 
    
         
            +
            OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
         
     | 
| 
      
 21 
     | 
    
         
            +
            THE SOFTWARE.
         
     | 
    
        data/README.md
    ADDED
    
    | 
         @@ -0,0 +1,255 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Usamin
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            A fast JSON serializer / deserializer for Ruby with [RapidJSON](http://rapidjson.org/).
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            The name of "Usamin" is derived from [Nana Abe](https://www.project-imas.com/wiki/Nana_Abe).
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            ## Installation
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            Install RapidJSON beforehand.
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            Next, add this line to your application's Gemfile:
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 14 
     | 
    
         
            +
            gem 'usamin'
         
     | 
| 
      
 15 
     | 
    
         
            +
            ```
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
            And then execute:
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                $ bundle
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            Or install it yourself as:
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                $ gem install usamin
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
            The directory of RapidJSON can be explicitly specified with `--with-rapidjson-dir` option.
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                $ gem install usamin -- --with-rapidjson-dir=/usr/local/opt/rapidjson
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
            ## Usage
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
            ### Loading library
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 34 
     | 
    
         
            +
            require 'usamin'
         
     | 
| 
      
 35 
     | 
    
         
            +
            ```
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
            ### Parsing
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 40 
     | 
    
         
            +
            json = '{
         
     | 
| 
      
 41 
     | 
    
         
            +
                "miku maekawa": {
         
     | 
| 
      
 42 
     | 
    
         
            +
                    "age": 15,
         
     | 
| 
      
 43 
     | 
    
         
            +
                    "height": 152,
         
     | 
| 
      
 44 
     | 
    
         
            +
                    "weight": 45,
         
     | 
| 
      
 45 
     | 
    
         
            +
                    "body_size": [85, 55, 81],
         
     | 
| 
      
 46 
     | 
    
         
            +
                    "birthday": [2, 22],
         
     | 
| 
      
 47 
     | 
    
         
            +
                    "cv": "natsumi takamori"
         
     | 
| 
      
 48 
     | 
    
         
            +
                },
         
     | 
| 
      
 49 
     | 
    
         
            +
                "nana abe": {
         
     | 
| 
      
 50 
     | 
    
         
            +
                    "age": 17,
         
     | 
| 
      
 51 
     | 
    
         
            +
                    "height": 146,
         
     | 
| 
      
 52 
     | 
    
         
            +
                    "weight": 40,
         
     | 
| 
      
 53 
     | 
    
         
            +
                    "body_size": [84, 57, 84],
         
     | 
| 
      
 54 
     | 
    
         
            +
                    "birthday": [5, 15],
         
     | 
| 
      
 55 
     | 
    
         
            +
                    "cv": "marie miyake"
         
     | 
| 
      
 56 
     | 
    
         
            +
                }
         
     | 
| 
      
 57 
     | 
    
         
            +
            }'
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
            Usamin.parse(json)
         
     | 
| 
      
 60 
     | 
    
         
            +
            ```
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
            ### Lazy loading
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 65 
     | 
    
         
            +
            data = Usamin.load(json)
         
     | 
| 
      
 66 
     | 
    
         
            +
            ```
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
            Here, `data` is not a Hash, but this can be handled like a Hash.
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 71 
     | 
    
         
            +
            data.keys
         
     | 
| 
      
 72 
     | 
    
         
            +
            #=> ["miku maekawa", "nana abe"]
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
            data.map{|k, v| [k, v['age']]}.to_h
         
     | 
| 
      
 75 
     | 
    
         
            +
            #=> {"miku maekawa"=>15, "nana abe"=>17}
         
     | 
| 
      
 76 
     | 
    
         
            +
            ```
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
            Array data also can be handled like an Array object.
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 81 
     | 
    
         
            +
            data['nana abe']['body_size'].size
         
     | 
| 
      
 82 
     | 
    
         
            +
            #=> 3
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
            data['nana abe']['body_size'].inject(:+)
         
     | 
| 
      
 85 
     | 
    
         
            +
            #=> 225
         
     | 
| 
      
 86 
     | 
    
         
            +
            ```
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
            The `eval` and `eval_r` converts these data structures into the Ruby data structures. `_r` means recursiveness.
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 91 
     | 
    
         
            +
            data.eval
         
     | 
| 
      
 92 
     | 
    
         
            +
            #=> {"miku maekawa"=>#<Usamin::Hash>, "nana abe"=>#<Usamin::Hash>}
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
            data['miku maekawa'].eval_r
         
     | 
| 
      
 95 
     | 
    
         
            +
            #=> {"age"=>15, "height"=>152, "weight"=>45, "body_size"=>[85, 55, 81], "birthday"=>[2, 22], "cv"=>"natsumi takamori"}
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
      
 97 
     | 
    
         
            +
            data.eval_r
         
     | 
| 
      
 98 
     | 
    
         
            +
            #=> same as Usamin.parse(json)
         
     | 
| 
      
 99 
     | 
    
         
            +
            ```
         
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
      
 101 
     | 
    
         
            +
            #### Notes about lazy loading data
         
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
      
 103 
     | 
    
         
            +
            - Frozen. Modification is not allowed.
         
     | 
| 
      
 104 
     | 
    
         
            +
            - A key list of Hash is based on not hash tables but arrays. An index access to hash costs O(n).
         
     | 
| 
      
 105 
     | 
    
         
            +
             
     | 
| 
      
 106 
     | 
    
         
            +
            ### Generating
         
     | 
| 
      
 107 
     | 
    
         
            +
             
     | 
| 
      
 108 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 109 
     | 
    
         
            +
            data = {
         
     | 
| 
      
 110 
     | 
    
         
            +
                "miku maekawa" => {
         
     | 
| 
      
 111 
     | 
    
         
            +
                    "age"=>15,
         
     | 
| 
      
 112 
     | 
    
         
            +
                    "height"=>152,
         
     | 
| 
      
 113 
     | 
    
         
            +
                    "weight"=>45,
         
     | 
| 
      
 114 
     | 
    
         
            +
                    "body_size"=>[85, 55, 81],
         
     | 
| 
      
 115 
     | 
    
         
            +
                    "birthday"=>[2, 22],
         
     | 
| 
      
 116 
     | 
    
         
            +
                    "cv"=>"natsumi takamori"},
         
     | 
| 
      
 117 
     | 
    
         
            +
                "nana abe"=> {
         
     | 
| 
      
 118 
     | 
    
         
            +
                    "age"=>17,
         
     | 
| 
      
 119 
     | 
    
         
            +
                    "height"=>146,
         
     | 
| 
      
 120 
     | 
    
         
            +
                    "weight"=>40,
         
     | 
| 
      
 121 
     | 
    
         
            +
                    "body_size"=>[84, 57, 84],
         
     | 
| 
      
 122 
     | 
    
         
            +
                    "birthday"=>[5, 15],
         
     | 
| 
      
 123 
     | 
    
         
            +
                    "cv"=>"marie miyake"}}
         
     | 
| 
      
 124 
     | 
    
         
            +
             
     | 
| 
      
 125 
     | 
    
         
            +
            Usamin.generate(data)
         
     | 
| 
      
 126 
     | 
    
         
            +
             
     | 
| 
      
 127 
     | 
    
         
            +
            # pretty generation is also supported
         
     | 
| 
      
 128 
     | 
    
         
            +
            Usamin.pretty_generate(data)
         
     | 
| 
      
 129 
     | 
    
         
            +
            ```
         
     | 
| 
      
 130 
     | 
    
         
            +
             
     | 
| 
      
 131 
     | 
    
         
            +
            Of course, UsaminValue also can be serialized.
         
     | 
| 
      
 132 
     | 
    
         
            +
             
     | 
| 
      
 133 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 134 
     | 
    
         
            +
            data = Usamin.load(json)
         
     | 
| 
      
 135 
     | 
    
         
            +
             
     | 
| 
      
 136 
     | 
    
         
            +
            Usamin.generate(data['nana abe'])
         
     | 
| 
      
 137 
     | 
    
         
            +
            ```
         
     | 
| 
      
 138 
     | 
    
         
            +
             
     | 
| 
      
 139 
     | 
    
         
            +
            ### Fast parsing
         
     | 
| 
      
 140 
     | 
    
         
            +
             
     | 
| 
      
 141 
     | 
    
         
            +
            Usamin uses `kParseFullPrecisionFlag` by default, but this option makes parsing a little slow.
         
     | 
| 
      
 142 
     | 
    
         
            +
             
     | 
| 
      
 143 
     | 
    
         
            +
            You can use `:fast` option to avoid this.
         
     | 
| 
      
 144 
     | 
    
         
            +
             
     | 
| 
      
 145 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 146 
     | 
    
         
            +
            # default
         
     | 
| 
      
 147 
     | 
    
         
            +
            Usamin.parse('77.777700000000795')
         
     | 
| 
      
 148 
     | 
    
         
            +
            #=> 77.77770000000079
         
     | 
| 
      
 149 
     | 
    
         
            +
             
     | 
| 
      
 150 
     | 
    
         
            +
            # fast but not precise
         
     | 
| 
      
 151 
     | 
    
         
            +
            Usamin.parse('77.777700000000795', fast: true)
         
     | 
| 
      
 152 
     | 
    
         
            +
            #=> 77.7777000000008
         
     | 
| 
      
 153 
     | 
    
         
            +
            ```
         
     | 
| 
      
 154 
     | 
    
         
            +
             
     | 
| 
      
 155 
     | 
    
         
            +
            ### Error handling
         
     | 
| 
      
 156 
     | 
    
         
            +
             
     | 
| 
      
 157 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 158 
     | 
    
         
            +
            str = '{"this is bad example"'
         
     | 
| 
      
 159 
     | 
    
         
            +
            Usamin.parse(str)
         
     | 
| 
      
 160 
     | 
    
         
            +
            # Usamin::ParserError: Missing a colon after a name of object member. Offset: 22
         
     | 
| 
      
 161 
     | 
    
         
            +
            ```
         
     | 
| 
      
 162 
     | 
    
         
            +
             
     | 
| 
      
 163 
     | 
    
         
            +
            ### Documentation
         
     | 
| 
      
 164 
     | 
    
         
            +
             
     | 
| 
      
 165 
     | 
    
         
            +
            See: http://www.rubydoc.info/gems/usamin/
         
     | 
| 
      
 166 
     | 
    
         
            +
             
     | 
| 
      
 167 
     | 
    
         
            +
            ## Benchmarks
         
     | 
| 
      
 168 
     | 
    
         
            +
             
     | 
| 
      
 169 
     | 
    
         
            +
            Based on [nativejson-benchmark](https://github.com/miloyip/nativejson-benchmark).
         
     | 
| 
      
 170 
     | 
    
         
            +
             
     | 
| 
      
 171 
     | 
    
         
            +
            ### Roundtrips
         
     | 
| 
      
 172 
     | 
    
         
            +
             
     | 
| 
      
 173 
     | 
    
         
            +
            Usamin passes all roundtrips, and the results are same as official JSON package.
         
     | 
| 
      
 174 
     | 
    
         
            +
             
     | 
| 
      
 175 
     | 
    
         
            +
            ### Reliability of parsed data
         
     | 
| 
      
 176 
     | 
    
         
            +
             
     | 
| 
      
 177 
     | 
    
         
            +
            Usamin and JSON load the same data from 3 big json data in nativejson-benchmark.
         
     | 
| 
      
 178 
     | 
    
         
            +
             
     | 
| 
      
 179 
     | 
    
         
            +
            ### Performance
         
     | 
| 
      
 180 
     | 
    
         
            +
             
     | 
| 
      
 181 
     | 
    
         
            +
            The values show the elapsed time for operating 20 times.
         
     | 
| 
      
 182 
     | 
    
         
            +
             
     | 
| 
      
 183 
     | 
    
         
            +
            #### Parsing
         
     | 
| 
      
 184 
     | 
    
         
            +
             
     | 
| 
      
 185 
     | 
    
         
            +
            ```
         
     | 
| 
      
 186 
     | 
    
         
            +
            nativejson-benchmark/data/canada.json
         
     | 
| 
      
 187 
     | 
    
         
            +
            json                     0.785524   0.007927   0.793451 (  0.805269)
         
     | 
| 
      
 188 
     | 
    
         
            +
            oj                       1.833580   0.043648   1.877228 (  1.895704)
         
     | 
| 
      
 189 
     | 
    
         
            +
            usamin                   0.595523   0.012299   0.607822 (  0.612215)
         
     | 
| 
      
 190 
     | 
    
         
            +
            usamin (fast)            0.286458   0.008710   0.295168 (  0.297998)
         
     | 
| 
      
 191 
     | 
    
         
            +
            usamin (load)            0.484056   0.011770   0.495826 (  0.498110)
         
     | 
| 
      
 192 
     | 
    
         
            +
            usamin (load / fast)     0.187712   0.020202   0.207914 (  0.210711)
         
     | 
| 
      
 193 
     | 
    
         
            +
             
     | 
| 
      
 194 
     | 
    
         
            +
            nativejson-benchmark/data/citm_catalog.json
         
     | 
| 
      
 195 
     | 
    
         
            +
            json                     0.469471   0.005208   0.474679 (  0.478920)
         
     | 
| 
      
 196 
     | 
    
         
            +
            oj                       0.327143   0.002947   0.330090 (  0.331882)
         
     | 
| 
      
 197 
     | 
    
         
            +
            usamin                   0.362764   0.005633   0.368397 (  0.370940)
         
     | 
| 
      
 198 
     | 
    
         
            +
            usamin (fast)            0.359859   0.005884   0.365743 (  0.371016)
         
     | 
| 
      
 199 
     | 
    
         
            +
            usamin (load)            0.117140   0.007003   0.124143 (  0.126548)
         
     | 
| 
      
 200 
     | 
    
         
            +
            usamin (load / fast)     0.115237   0.010061   0.125298 (  0.128470)
         
     | 
| 
      
 201 
     | 
    
         
            +
             
     | 
| 
      
 202 
     | 
    
         
            +
            nativejson-benchmark/data/twitter.json
         
     | 
| 
      
 203 
     | 
    
         
            +
            json                     0.238582   0.002561   0.241143 (  0.243726)
         
     | 
| 
      
 204 
     | 
    
         
            +
            oj                       0.162212   0.001031   0.163243 (  0.165047)
         
     | 
| 
      
 205 
     | 
    
         
            +
            usamin                   0.194476   0.001523   0.195999 (  0.197920)
         
     | 
| 
      
 206 
     | 
    
         
            +
            usamin (fast)            0.192985   0.001339   0.194324 (  0.197404)
         
     | 
| 
      
 207 
     | 
    
         
            +
            usamin (load)            0.070360   0.005012   0.075372 (  0.078090)
         
     | 
| 
      
 208 
     | 
    
         
            +
            usamin (load / fast)     0.067618   0.006416   0.074034 (  0.076244)
         
     | 
| 
      
 209 
     | 
    
         
            +
            ```
         
     | 
| 
      
 210 
     | 
    
         
            +
             
     | 
| 
      
 211 
     | 
    
         
            +
            #### Generating
         
     | 
| 
      
 212 
     | 
    
         
            +
             
     | 
| 
      
 213 
     | 
    
         
            +
            ```
         
     | 
| 
      
 214 
     | 
    
         
            +
            nativejson-benchmark/data/canada.json
         
     | 
| 
      
 215 
     | 
    
         
            +
            json                     1.988155   0.029728   2.017883 (  2.023475)
         
     | 
| 
      
 216 
     | 
    
         
            +
            oj                       2.092999   0.033136   2.126135 (  2.135765)
         
     | 
| 
      
 217 
     | 
    
         
            +
            usamin                   0.296385   0.031412   0.327797 (  0.330314)
         
     | 
| 
      
 218 
     | 
    
         
            +
             
     | 
| 
      
 219 
     | 
    
         
            +
            nativejson-benchmark/data/citm_catalog.json
         
     | 
| 
      
 220 
     | 
    
         
            +
            json                     0.243795   0.007463   0.251258 (  0.256621)
         
     | 
| 
      
 221 
     | 
    
         
            +
            oj                       0.076474   0.009617   0.086091 (  0.087966)
         
     | 
| 
      
 222 
     | 
    
         
            +
            usamin                   0.059434   0.009616   0.069050 (  0.071158)
         
     | 
| 
      
 223 
     | 
    
         
            +
             
     | 
| 
      
 224 
     | 
    
         
            +
            nativejson-benchmark/data/twitter.json
         
     | 
| 
      
 225 
     | 
    
         
            +
            json                     0.159030   0.006730   0.165760 (  0.170796)
         
     | 
| 
      
 226 
     | 
    
         
            +
            oj                       0.052856   0.009164   0.062020 (  0.064344)
         
     | 
| 
      
 227 
     | 
    
         
            +
            usamin                   0.047707   0.010265   0.057972 (  0.061729)
         
     | 
| 
      
 228 
     | 
    
         
            +
            ```
         
     | 
| 
      
 229 
     | 
    
         
            +
             
     | 
| 
      
 230 
     | 
    
         
            +
            #### Pretty Generating
         
     | 
| 
      
 231 
     | 
    
         
            +
             
     | 
| 
      
 232 
     | 
    
         
            +
            ```
         
     | 
| 
      
 233 
     | 
    
         
            +
            nativejson-benchmark/data/canada.json
         
     | 
| 
      
 234 
     | 
    
         
            +
            json                     2.188493   0.066003   2.254496 (  2.260332)
         
     | 
| 
      
 235 
     | 
    
         
            +
            oj                       1.583613   0.029798   1.613411 (  1.619652)
         
     | 
| 
      
 236 
     | 
    
         
            +
            usamin                   0.399066   0.081314   0.480380 (  0.482841)
         
     | 
| 
      
 237 
     | 
    
         
            +
             
     | 
| 
      
 238 
     | 
    
         
            +
            nativejson-benchmark/data/citm_catalog.json
         
     | 
| 
      
 239 
     | 
    
         
            +
            json                     0.300601   0.029596   0.330197 (  0.335351)
         
     | 
| 
      
 240 
     | 
    
         
            +
            oj                       0.065151   0.009553   0.074704 (  0.077010)
         
     | 
| 
      
 241 
     | 
    
         
            +
            usamin                   0.089872   0.022203   0.112075 (  0.116063)
         
     | 
| 
      
 242 
     | 
    
         
            +
             
     | 
| 
      
 243 
     | 
    
         
            +
            nativejson-benchmark/data/twitter.json
         
     | 
| 
      
 244 
     | 
    
         
            +
            json                     0.189439   0.010086   0.199525 (  0.204491)
         
     | 
| 
      
 245 
     | 
    
         
            +
            oj                       0.040982   0.008203   0.049185 (  0.049352)
         
     | 
| 
      
 246 
     | 
    
         
            +
            usamin                   0.044296   0.010095   0.054391 (  0.056245)
         
     | 
| 
      
 247 
     | 
    
         
            +
            ```
         
     | 
| 
      
 248 
     | 
    
         
            +
             
     | 
| 
      
 249 
     | 
    
         
            +
            ## Contributing
         
     | 
| 
      
 250 
     | 
    
         
            +
             
     | 
| 
      
 251 
     | 
    
         
            +
            Bug reports and pull requests are welcome on GitHub at https://github.com/Ishotihadus/usamin.
         
     | 
| 
      
 252 
     | 
    
         
            +
             
     | 
| 
      
 253 
     | 
    
         
            +
            ## License
         
     | 
| 
      
 254 
     | 
    
         
            +
             
     | 
| 
      
 255 
     | 
    
         
            +
            The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT) at the request of RapidJSON.
         
     | 
    
        data/Rakefile
    ADDED
    
    | 
         @@ -0,0 +1,18 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require "bundler/gem_tasks"
         
     | 
| 
      
 2 
     | 
    
         
            +
            require "rake/testtask"
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            Rake::TestTask.new(:test) do |t|
         
     | 
| 
      
 5 
     | 
    
         
            +
              t.libs << "test"
         
     | 
| 
      
 6 
     | 
    
         
            +
              t.libs << "lib"
         
     | 
| 
      
 7 
     | 
    
         
            +
              t.test_files = FileList["test/**/*_test.rb"]
         
     | 
| 
      
 8 
     | 
    
         
            +
            end
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            require "rake/extensiontask"
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            task :build => :compile
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            Rake::ExtensionTask.new("usamin") do |ext|
         
     | 
| 
      
 15 
     | 
    
         
            +
              ext.lib_dir = "lib/usamin"
         
     | 
| 
      
 16 
     | 
    
         
            +
            end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            task :default => [:clobber, :compile, :test]
         
     | 
    
        data/bin/console
    ADDED
    
    | 
         @@ -0,0 +1,14 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #!/usr/bin/env ruby
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require "bundler/setup"
         
     | 
| 
      
 4 
     | 
    
         
            +
            require "usamin"
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            # You can add fixtures and/or initialization code here to make experimenting
         
     | 
| 
      
 7 
     | 
    
         
            +
            # with your gem easier. You can also use a different console, if you like.
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            # (If you use this, don't forget to add pry to your Gemfile!)
         
     | 
| 
      
 10 
     | 
    
         
            +
            # require "pry"
         
     | 
| 
      
 11 
     | 
    
         
            +
            # Pry.start
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            require "pry"
         
     | 
| 
      
 14 
     | 
    
         
            +
            Pry.start
         
     | 
    
        data/bin/setup
    ADDED
    
    
| 
         @@ -0,0 +1,987 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #include <string.h>
         
     | 
| 
      
 2 
     | 
    
         
            +
            #include <stdint.h>
         
     | 
| 
      
 3 
     | 
    
         
            +
            #include <ruby.h>
         
     | 
| 
      
 4 
     | 
    
         
            +
            #include <ruby/encoding.h>
         
     | 
| 
      
 5 
     | 
    
         
            +
            #define RAPIDJSON_PARSE_DEFAULT_FLAGS \
         
     | 
| 
      
 6 
     | 
    
         
            +
                rapidjson::kParseFullPrecisionFlag | rapidjson::kParseCommentsFlag | rapidjson::kParseTrailingCommasFlag | rapidjson::kParseNanAndInfFlag
         
     | 
| 
      
 7 
     | 
    
         
            +
            #define kParseFastFlags (rapidjson::kParseDefaultFlags & ~rapidjson::kParseFullPrecisionFlag)
         
     | 
| 
      
 8 
     | 
    
         
            +
            #define RAPIDJSON_WRITE_DEFAULT_FLAGS rapidjson::kWriteNanAndInfFlag
         
     | 
| 
      
 9 
     | 
    
         
            +
            #include <rapidjson/document.h>
         
     | 
| 
      
 10 
     | 
    
         
            +
            #include <rapidjson/writer.h>
         
     | 
| 
      
 11 
     | 
    
         
            +
            #include <rapidjson/prettywriter.h>
         
     | 
| 
      
 12 
     | 
    
         
            +
            #include <rapidjson/error/en.h>
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            #if SIZEOF_VALUE < SIZEOF_VOIDP
         
     | 
| 
      
 15 
     | 
    
         
            +
            #error SIZEOF_VOIDP must not be greater than SIZEOF_VALUE.
         
     | 
| 
      
 16 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            rb_encoding *utf8;
         
     | 
| 
      
 20 
     | 
    
         
            +
            int utf8index;
         
     | 
| 
      
 21 
     | 
    
         
            +
            ID id_to_s;
         
     | 
| 
      
 22 
     | 
    
         
            +
            VALUE rb_cUsaminValue, rb_cUsaminHash, rb_cUsaminArray, rb_eUsaminError, rb_eParserError;
         
     | 
| 
      
 23 
     | 
    
         
            +
            VALUE utf8value, sym_fast, sym_indent, sym_single_line_array;
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
            class UsaminValue {
         
     | 
| 
      
 26 
     | 
    
         
            +
            public:
         
     | 
| 
      
 27 
     | 
    
         
            +
                rapidjson::Value *value;
         
     | 
| 
      
 28 
     | 
    
         
            +
                bool free_flag;
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                UsaminValue(rapidjson::Value *value = nullptr, bool free_flag = false);
         
     | 
| 
      
 31 
     | 
    
         
            +
                ~UsaminValue();
         
     | 
| 
      
 32 
     | 
    
         
            +
            };
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
            static inline VALUE get_utf8_str(VALUE str) {
         
     | 
| 
      
 35 
     | 
    
         
            +
                Check_Type(str, T_STRING);
         
     | 
| 
      
 36 
     | 
    
         
            +
                int encoding = rb_enc_get_index(str);
         
     | 
| 
      
 37 
     | 
    
         
            +
                if (encoding == utf8index || rb_enc_compatible(str, utf8value) == utf8)
         
     | 
| 
      
 38 
     | 
    
         
            +
                    return str;
         
     | 
| 
      
 39 
     | 
    
         
            +
                else
         
     | 
| 
      
 40 
     | 
    
         
            +
                    return rb_str_conv_enc(str, rb_enc_from_index(encoding), utf8);
         
     | 
| 
      
 41 
     | 
    
         
            +
            }
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
            static inline VALUE new_utf8_str(const char* cstr, const long len) {
         
     | 
| 
      
 44 
     | 
    
         
            +
                VALUE ret = rb_str_new(cstr, len);
         
     | 
| 
      
 45 
     | 
    
         
            +
                rb_enc_set_index(ret, utf8index);
         
     | 
| 
      
 46 
     | 
    
         
            +
                return ret;
         
     | 
| 
      
 47 
     | 
    
         
            +
            }
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
            static inline bool str_compare(const char* str1, const long len1, const char* str2, const long len2) {
         
     | 
| 
      
 50 
     | 
    
         
            +
                if (len1 != len2 || len1 < 0)
         
     | 
| 
      
 51 
     | 
    
         
            +
                    return false;
         
     | 
| 
      
 52 
     | 
    
         
            +
                return memcmp(str1, str2, len1) == 0;
         
     | 
| 
      
 53 
     | 
    
         
            +
            }
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
            static inline void check_value(UsaminValue *ptr) {
         
     | 
| 
      
 56 
     | 
    
         
            +
                if (!ptr || !ptr->value)
         
     | 
| 
      
 57 
     | 
    
         
            +
                    rb_raise(rb_eUsaminError, "Null Reference.");
         
     | 
| 
      
 58 
     | 
    
         
            +
            }
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
            static inline void check_object(UsaminValue *ptr) {
         
     | 
| 
      
 61 
     | 
    
         
            +
                check_value(ptr);
         
     | 
| 
      
 62 
     | 
    
         
            +
                if (!ptr->value->IsObject())
         
     | 
| 
      
 63 
     | 
    
         
            +
                    rb_raise(rb_eUsaminError, "Value is not an object.");
         
     | 
| 
      
 64 
     | 
    
         
            +
            }
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
            static inline void check_array(UsaminValue *ptr) {
         
     | 
| 
      
 67 
     | 
    
         
            +
                check_value(ptr);
         
     | 
| 
      
 68 
     | 
    
         
            +
                if (!ptr->value->IsArray())
         
     | 
| 
      
 69 
     | 
    
         
            +
                    rb_raise(rb_eUsaminError, "Value is not an array.");
         
     | 
| 
      
 70 
     | 
    
         
            +
            }
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
            static VALUE usamin_free(UsaminValue **ptr) {
         
     | 
| 
      
 74 
     | 
    
         
            +
                if (*ptr)
         
     | 
| 
      
 75 
     | 
    
         
            +
                    delete *ptr;
         
     | 
| 
      
 76 
     | 
    
         
            +
                ruby_xfree(ptr);
         
     | 
| 
      
 77 
     | 
    
         
            +
                return Qnil;
         
     | 
| 
      
 78 
     | 
    
         
            +
            }
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
            static VALUE usamin_alloc(const VALUE klass) {
         
     | 
| 
      
 81 
     | 
    
         
            +
                UsaminValue** ptr = (UsaminValue**)ruby_xmalloc(sizeof(UsaminValue*));
         
     | 
| 
      
 82 
     | 
    
         
            +
                *ptr = nullptr;
         
     | 
| 
      
 83 
     | 
    
         
            +
                return Data_Wrap_Struct(klass, NULL, usamin_free, ptr);
         
     | 
| 
      
 84 
     | 
    
         
            +
            }
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
            static inline UsaminValue* get_value(VALUE value) {
         
     | 
| 
      
 88 
     | 
    
         
            +
                UsaminValue** ptr;
         
     | 
| 
      
 89 
     | 
    
         
            +
                Data_Get_Struct(value, UsaminValue*, ptr);
         
     | 
| 
      
 90 
     | 
    
         
            +
                return *ptr;
         
     | 
| 
      
 91 
     | 
    
         
            +
            }
         
     | 
| 
      
 92 
     | 
    
         
            +
             
     | 
| 
      
 93 
     | 
    
         
            +
            static inline void set_value(VALUE value, UsaminValue *usamin) {
         
     | 
| 
      
 94 
     | 
    
         
            +
                UsaminValue **ptr;
         
     | 
| 
      
 95 
     | 
    
         
            +
                Data_Get_Struct(value, UsaminValue*, ptr);
         
     | 
| 
      
 96 
     | 
    
         
            +
                *ptr = usamin;
         
     | 
| 
      
 97 
     | 
    
         
            +
            }
         
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
      
 99 
     | 
    
         
            +
            static inline VALUE make_hash(UsaminValue *value) {
         
     | 
| 
      
 100 
     | 
    
         
            +
                VALUE ret = rb_obj_alloc(rb_cUsaminHash);
         
     | 
| 
      
 101 
     | 
    
         
            +
                set_value(ret, value);
         
     | 
| 
      
 102 
     | 
    
         
            +
                return ret;
         
     | 
| 
      
 103 
     | 
    
         
            +
            }
         
     | 
| 
      
 104 
     | 
    
         
            +
             
     | 
| 
      
 105 
     | 
    
         
            +
            static inline VALUE make_array(UsaminValue *value) {
         
     | 
| 
      
 106 
     | 
    
         
            +
                VALUE ret = rb_obj_alloc(rb_cUsaminArray);
         
     | 
| 
      
 107 
     | 
    
         
            +
                set_value(ret, value);
         
     | 
| 
      
 108 
     | 
    
         
            +
                return ret;
         
     | 
| 
      
 109 
     | 
    
         
            +
            }
         
     | 
| 
      
 110 
     | 
    
         
            +
             
     | 
| 
      
 111 
     | 
    
         
            +
            static inline rapidjson::ParseResult parse(rapidjson::Document &doc, const VALUE str, bool fast = false) {
         
     | 
| 
      
 112 
     | 
    
         
            +
                VALUE v = get_utf8_str(str);
         
     | 
| 
      
 113 
     | 
    
         
            +
                return fast ? doc.Parse<kParseFastFlags>(RSTRING_PTR(v), RSTRING_LEN(v)) : doc.Parse(RSTRING_PTR(v), RSTRING_LEN(v));
         
     | 
| 
      
 114 
     | 
    
         
            +
            }
         
     | 
| 
      
 115 
     | 
    
         
            +
             
     | 
| 
      
 116 
     | 
    
         
            +
             
     | 
| 
      
 117 
     | 
    
         
            +
            static inline VALUE eval_num(rapidjson::Value &value);
         
     | 
| 
      
 118 
     | 
    
         
            +
            static inline VALUE eval_str(rapidjson::Value &value);
         
     | 
| 
      
 119 
     | 
    
         
            +
            static inline VALUE eval_object(rapidjson::Value &value);
         
     | 
| 
      
 120 
     | 
    
         
            +
            static inline VALUE eval_object_r(rapidjson::Value &value);
         
     | 
| 
      
 121 
     | 
    
         
            +
            static inline VALUE eval_array(rapidjson::Value &value);
         
     | 
| 
      
 122 
     | 
    
         
            +
            static inline VALUE eval_array_r(rapidjson::Value &value);
         
     | 
| 
      
 123 
     | 
    
         
            +
             
     | 
| 
      
 124 
     | 
    
         
            +
            static VALUE eval(rapidjson::Value &value) {
         
     | 
| 
      
 125 
     | 
    
         
            +
                switch (value.GetType()) {
         
     | 
| 
      
 126 
     | 
    
         
            +
                    case rapidjson::kObjectType:
         
     | 
| 
      
 127 
     | 
    
         
            +
                        return make_hash(new UsaminValue(&value, false));
         
     | 
| 
      
 128 
     | 
    
         
            +
                    case rapidjson::kArrayType:
         
     | 
| 
      
 129 
     | 
    
         
            +
                        return make_array(new UsaminValue(&value, false));
         
     | 
| 
      
 130 
     | 
    
         
            +
                    case rapidjson::kNullType:
         
     | 
| 
      
 131 
     | 
    
         
            +
                        return Qnil;
         
     | 
| 
      
 132 
     | 
    
         
            +
                    case rapidjson::kFalseType:
         
     | 
| 
      
 133 
     | 
    
         
            +
                        return Qfalse;
         
     | 
| 
      
 134 
     | 
    
         
            +
                    case rapidjson::kTrueType:
         
     | 
| 
      
 135 
     | 
    
         
            +
                        return Qtrue;
         
     | 
| 
      
 136 
     | 
    
         
            +
                    case rapidjson::kNumberType:
         
     | 
| 
      
 137 
     | 
    
         
            +
                        return eval_num(value);
         
     | 
| 
      
 138 
     | 
    
         
            +
                    case rapidjson::kStringType:
         
     | 
| 
      
 139 
     | 
    
         
            +
                        return eval_str(value);
         
     | 
| 
      
 140 
     | 
    
         
            +
                    default:
         
     | 
| 
      
 141 
     | 
    
         
            +
                        rb_raise(rb_eUsaminError, "Unknown Value Type: %d", value.GetType());
         
     | 
| 
      
 142 
     | 
    
         
            +
                        return Qnil;
         
     | 
| 
      
 143 
     | 
    
         
            +
                }
         
     | 
| 
      
 144 
     | 
    
         
            +
            }
         
     | 
| 
      
 145 
     | 
    
         
            +
             
     | 
| 
      
 146 
     | 
    
         
            +
            static VALUE eval_r(rapidjson::Value &value) {
         
     | 
| 
      
 147 
     | 
    
         
            +
                switch (value.GetType()) {
         
     | 
| 
      
 148 
     | 
    
         
            +
                    case rapidjson::kObjectType:
         
     | 
| 
      
 149 
     | 
    
         
            +
                        return eval_object_r(value);
         
     | 
| 
      
 150 
     | 
    
         
            +
                    case rapidjson::kArrayType:
         
     | 
| 
      
 151 
     | 
    
         
            +
                        return eval_array_r(value);
         
     | 
| 
      
 152 
     | 
    
         
            +
                    case rapidjson::kNullType:
         
     | 
| 
      
 153 
     | 
    
         
            +
                        return Qnil;
         
     | 
| 
      
 154 
     | 
    
         
            +
                    case rapidjson::kFalseType:
         
     | 
| 
      
 155 
     | 
    
         
            +
                        return Qfalse;
         
     | 
| 
      
 156 
     | 
    
         
            +
                    case rapidjson::kTrueType:
         
     | 
| 
      
 157 
     | 
    
         
            +
                        return Qtrue;
         
     | 
| 
      
 158 
     | 
    
         
            +
                    case rapidjson::kNumberType:
         
     | 
| 
      
 159 
     | 
    
         
            +
                        return eval_num(value);
         
     | 
| 
      
 160 
     | 
    
         
            +
                    case rapidjson::kStringType:
         
     | 
| 
      
 161 
     | 
    
         
            +
                        return eval_str(value);
         
     | 
| 
      
 162 
     | 
    
         
            +
                    default:
         
     | 
| 
      
 163 
     | 
    
         
            +
                        rb_raise(rb_eUsaminError, "Unknown Value Type: %d", value.GetType());
         
     | 
| 
      
 164 
     | 
    
         
            +
                        return Qnil;
         
     | 
| 
      
 165 
     | 
    
         
            +
                }
         
     | 
| 
      
 166 
     | 
    
         
            +
            }
         
     | 
| 
      
 167 
     | 
    
         
            +
             
     | 
| 
      
 168 
     | 
    
         
            +
            static inline VALUE eval_num(rapidjson::Value &value) {
         
     | 
| 
      
 169 
     | 
    
         
            +
                if (value.IsInt())
         
     | 
| 
      
 170 
     | 
    
         
            +
                    return INT2FIX(value.GetInt());
         
     | 
| 
      
 171 
     | 
    
         
            +
                else if (value.IsUint())
         
     | 
| 
      
 172 
     | 
    
         
            +
                    return UINT2NUM(value.GetUint());
         
     | 
| 
      
 173 
     | 
    
         
            +
                else if (value.IsInt64())
         
     | 
| 
      
 174 
     | 
    
         
            +
                    return LL2NUM(value.GetInt64());
         
     | 
| 
      
 175 
     | 
    
         
            +
                else if (value.IsUint64())
         
     | 
| 
      
 176 
     | 
    
         
            +
                    return ULL2NUM(value.GetUint64());
         
     | 
| 
      
 177 
     | 
    
         
            +
                else
         
     | 
| 
      
 178 
     | 
    
         
            +
                    return DBL2NUM(value.GetDouble());
         
     | 
| 
      
 179 
     | 
    
         
            +
            }
         
     | 
| 
      
 180 
     | 
    
         
            +
             
     | 
| 
      
 181 
     | 
    
         
            +
            static inline VALUE eval_str(rapidjson::Value &value) {
         
     | 
| 
      
 182 
     | 
    
         
            +
                return new_utf8_str(value.GetString(), value.GetStringLength());
         
     | 
| 
      
 183 
     | 
    
         
            +
            }
         
     | 
| 
      
 184 
     | 
    
         
            +
             
     | 
| 
      
 185 
     | 
    
         
            +
            static inline VALUE eval_object(rapidjson::Value &value) {
         
     | 
| 
      
 186 
     | 
    
         
            +
                VALUE ret = rb_hash_new();
         
     | 
| 
      
 187 
     | 
    
         
            +
                for (auto &m : value.GetObject())
         
     | 
| 
      
 188 
     | 
    
         
            +
                    rb_hash_aset(ret, eval_str(m.name), eval(m.value));
         
     | 
| 
      
 189 
     | 
    
         
            +
                return ret;
         
     | 
| 
      
 190 
     | 
    
         
            +
            }
         
     | 
| 
      
 191 
     | 
    
         
            +
             
     | 
| 
      
 192 
     | 
    
         
            +
            static inline VALUE eval_object_r(rapidjson::Value &value) {
         
     | 
| 
      
 193 
     | 
    
         
            +
                VALUE ret = rb_hash_new();
         
     | 
| 
      
 194 
     | 
    
         
            +
                for (auto &m : value.GetObject())
         
     | 
| 
      
 195 
     | 
    
         
            +
                    rb_hash_aset(ret, eval_str(m.name), eval_r(m.value));
         
     | 
| 
      
 196 
     | 
    
         
            +
                return ret;
         
     | 
| 
      
 197 
     | 
    
         
            +
            }
         
     | 
| 
      
 198 
     | 
    
         
            +
             
     | 
| 
      
 199 
     | 
    
         
            +
            static inline VALUE eval_array(rapidjson::Value &value) {
         
     | 
| 
      
 200 
     | 
    
         
            +
                VALUE ret = rb_ary_new2(value.Size());
         
     | 
| 
      
 201 
     | 
    
         
            +
                for (auto &v : value.GetArray())
         
     | 
| 
      
 202 
     | 
    
         
            +
                    rb_ary_push(ret, eval(v));
         
     | 
| 
      
 203 
     | 
    
         
            +
                return ret;
         
     | 
| 
      
 204 
     | 
    
         
            +
            }
         
     | 
| 
      
 205 
     | 
    
         
            +
             
     | 
| 
      
 206 
     | 
    
         
            +
            static inline VALUE eval_array_r(rapidjson::Value &value) {
         
     | 
| 
      
 207 
     | 
    
         
            +
                VALUE ret = rb_ary_new2(value.Size());
         
     | 
| 
      
 208 
     | 
    
         
            +
                for (auto &v : value.GetArray())
         
     | 
| 
      
 209 
     | 
    
         
            +
                    rb_ary_push(ret, eval_r(v));
         
     | 
| 
      
 210 
     | 
    
         
            +
                return ret;
         
     | 
| 
      
 211 
     | 
    
         
            +
            }
         
     | 
| 
      
 212 
     | 
    
         
            +
             
     | 
| 
      
 213 
     | 
    
         
            +
             
     | 
| 
      
 214 
     | 
    
         
            +
            UsaminValue::UsaminValue(rapidjson::Value *value, bool free_flag) {
         
     | 
| 
      
 215 
     | 
    
         
            +
                this->value = value;
         
     | 
| 
      
 216 
     | 
    
         
            +
                this->free_flag = free_flag;
         
     | 
| 
      
 217 
     | 
    
         
            +
            }
         
     | 
| 
      
 218 
     | 
    
         
            +
             
     | 
| 
      
 219 
     | 
    
         
            +
            UsaminValue::~UsaminValue() {
         
     | 
| 
      
 220 
     | 
    
         
            +
                if (value && free_flag)
         
     | 
| 
      
 221 
     | 
    
         
            +
                    delete value;
         
     | 
| 
      
 222 
     | 
    
         
            +
            }
         
     | 
| 
      
 223 
     | 
    
         
            +
             
     | 
| 
      
 224 
     | 
    
         
            +
            /*
         
     | 
| 
      
 225 
     | 
    
         
            +
             * Parse the JSON string into UsaminValue.
         
     | 
| 
      
 226 
     | 
    
         
            +
             * If the document root is not an object or an array, the same value as {#parse} will be returned.
         
     | 
| 
      
 227 
     | 
    
         
            +
             *
         
     | 
| 
      
 228 
     | 
    
         
            +
             * @overload load(source, opts = {})
         
     | 
| 
      
 229 
     | 
    
         
            +
             *   @param [String] source JSON string to parse
         
     | 
| 
      
 230 
     | 
    
         
            +
             *   @param [::Hash] opts options
         
     | 
| 
      
 231 
     | 
    
         
            +
             *   @option opts :fast fast mode (but not precise)
         
     | 
| 
      
 232 
     | 
    
         
            +
             *   @return [Object]
         
     | 
| 
      
 233 
     | 
    
         
            +
             */
         
     | 
| 
      
 234 
     | 
    
         
            +
            static VALUE w_load(const int argc, VALUE *argv, const VALUE self) {
         
     | 
| 
      
 235 
     | 
    
         
            +
                VALUE source, options;
         
     | 
| 
      
 236 
     | 
    
         
            +
                rb_scan_args(argc, argv, "1:", &source, &options);
         
     | 
| 
      
 237 
     | 
    
         
            +
                rapidjson::Document *doc = new rapidjson::Document;
         
     | 
| 
      
 238 
     | 
    
         
            +
                auto result = parse(*doc, source, argc > 1 && RTEST(rb_hash_lookup(options, sym_fast)));
         
     | 
| 
      
 239 
     | 
    
         
            +
                if (!result) {
         
     | 
| 
      
 240 
     | 
    
         
            +
                    delete doc;
         
     | 
| 
      
 241 
     | 
    
         
            +
                    rb_raise(rb_eParserError, "%s Offset: %lu", GetParseError_En(result.Code()), result.Offset());
         
     | 
| 
      
 242 
     | 
    
         
            +
                }
         
     | 
| 
      
 243 
     | 
    
         
            +
             
     | 
| 
      
 244 
     | 
    
         
            +
                VALUE ret;
         
     | 
| 
      
 245 
     | 
    
         
            +
                switch (doc->GetType()) {
         
     | 
| 
      
 246 
     | 
    
         
            +
                    case rapidjson::kObjectType:
         
     | 
| 
      
 247 
     | 
    
         
            +
                        return make_hash(new UsaminValue(doc, true));
         
     | 
| 
      
 248 
     | 
    
         
            +
                    case rapidjson::kArrayType:
         
     | 
| 
      
 249 
     | 
    
         
            +
                        return make_array(new UsaminValue(doc, true));
         
     | 
| 
      
 250 
     | 
    
         
            +
                    case rapidjson::kNullType:
         
     | 
| 
      
 251 
     | 
    
         
            +
                        delete doc;
         
     | 
| 
      
 252 
     | 
    
         
            +
                        return Qnil;
         
     | 
| 
      
 253 
     | 
    
         
            +
                    case rapidjson::kFalseType:
         
     | 
| 
      
 254 
     | 
    
         
            +
                        delete doc;
         
     | 
| 
      
 255 
     | 
    
         
            +
                        return Qfalse;
         
     | 
| 
      
 256 
     | 
    
         
            +
                    case rapidjson::kTrueType:
         
     | 
| 
      
 257 
     | 
    
         
            +
                        delete doc;
         
     | 
| 
      
 258 
     | 
    
         
            +
                        return Qtrue;
         
     | 
| 
      
 259 
     | 
    
         
            +
                    case rapidjson::kNumberType:
         
     | 
| 
      
 260 
     | 
    
         
            +
                        ret = eval_num(*doc);
         
     | 
| 
      
 261 
     | 
    
         
            +
                        delete doc;
         
     | 
| 
      
 262 
     | 
    
         
            +
                        return ret;
         
     | 
| 
      
 263 
     | 
    
         
            +
                    case rapidjson::kStringType:
         
     | 
| 
      
 264 
     | 
    
         
            +
                        ret = eval_str(*doc);
         
     | 
| 
      
 265 
     | 
    
         
            +
                        delete doc;
         
     | 
| 
      
 266 
     | 
    
         
            +
                        return ret;
         
     | 
| 
      
 267 
     | 
    
         
            +
                    default:
         
     | 
| 
      
 268 
     | 
    
         
            +
                        rb_raise(rb_eUsaminError, "Unknown Value Type: %d", doc->GetType());
         
     | 
| 
      
 269 
     | 
    
         
            +
                        return Qnil;
         
     | 
| 
      
 270 
     | 
    
         
            +
                }
         
     | 
| 
      
 271 
     | 
    
         
            +
            }
         
     | 
| 
      
 272 
     | 
    
         
            +
             
     | 
| 
      
 273 
     | 
    
         
            +
            /*
         
     | 
| 
      
 274 
     | 
    
         
            +
             * Parse the JSON string into Ruby data structures.
         
     | 
| 
      
 275 
     | 
    
         
            +
             *
         
     | 
| 
      
 276 
     | 
    
         
            +
             * @overload parse(source, opts = {})
         
     | 
| 
      
 277 
     | 
    
         
            +
             *   @param [String] source a JSON string to parse
         
     | 
| 
      
 278 
     | 
    
         
            +
             *   @param [::Hash] opts options
         
     | 
| 
      
 279 
     | 
    
         
            +
             *   @option opts :fast fast mode (but not precise)
         
     | 
| 
      
 280 
     | 
    
         
            +
             *   @return [Object]
         
     | 
| 
      
 281 
     | 
    
         
            +
             */
         
     | 
| 
      
 282 
     | 
    
         
            +
            static VALUE w_parse(const int argc, VALUE *argv, const VALUE self) {
         
     | 
| 
      
 283 
     | 
    
         
            +
                VALUE source, options;
         
     | 
| 
      
 284 
     | 
    
         
            +
                rb_scan_args(argc, argv, "1:", &source, &options);
         
     | 
| 
      
 285 
     | 
    
         
            +
                rapidjson::Document doc;
         
     | 
| 
      
 286 
     | 
    
         
            +
                auto result = parse(doc, source, argc > 1 && RTEST(rb_hash_lookup(options, sym_fast)));
         
     | 
| 
      
 287 
     | 
    
         
            +
                if (!result)
         
     | 
| 
      
 288 
     | 
    
         
            +
                    rb_raise(rb_eParserError, "%s Offset: %lu", GetParseError_En(result.Code()), result.Offset());
         
     | 
| 
      
 289 
     | 
    
         
            +
                return eval_r(doc);
         
     | 
| 
      
 290 
     | 
    
         
            +
            }
         
     | 
| 
      
 291 
     | 
    
         
            +
             
     | 
| 
      
 292 
     | 
    
         
            +
            /*
         
     | 
| 
      
 293 
     | 
    
         
            +
             * Returns whether the value is array.
         
     | 
| 
      
 294 
     | 
    
         
            +
             */
         
     | 
| 
      
 295 
     | 
    
         
            +
            static VALUE w_value_isarray(const VALUE self) {
         
     | 
| 
      
 296 
     | 
    
         
            +
                UsaminValue *value = get_value(self);
         
     | 
| 
      
 297 
     | 
    
         
            +
                check_value(value);
         
     | 
| 
      
 298 
     | 
    
         
            +
                return value->value->IsArray() ? Qtrue : Qfalse;
         
     | 
| 
      
 299 
     | 
    
         
            +
            }
         
     | 
| 
      
 300 
     | 
    
         
            +
             
     | 
| 
      
 301 
     | 
    
         
            +
            /*
         
     | 
| 
      
 302 
     | 
    
         
            +
             * Returns whether the value is object.
         
     | 
| 
      
 303 
     | 
    
         
            +
             */
         
     | 
| 
      
 304 
     | 
    
         
            +
            static VALUE w_value_isobject(const VALUE self) {
         
     | 
| 
      
 305 
     | 
    
         
            +
                UsaminValue *value = get_value(self);
         
     | 
| 
      
 306 
     | 
    
         
            +
                check_value(value);
         
     | 
| 
      
 307 
     | 
    
         
            +
                return value->value->IsObject() ? Qtrue : Qfalse;
         
     | 
| 
      
 308 
     | 
    
         
            +
            }
         
     | 
| 
      
 309 
     | 
    
         
            +
             
     | 
| 
      
 310 
     | 
    
         
            +
            /*
         
     | 
| 
      
 311 
     | 
    
         
            +
             * Convert to Ruby data structures.
         
     | 
| 
      
 312 
     | 
    
         
            +
             *
         
     | 
| 
      
 313 
     | 
    
         
            +
             * @return [Object]
         
     | 
| 
      
 314 
     | 
    
         
            +
             */
         
     | 
| 
      
 315 
     | 
    
         
            +
            static VALUE w_value_eval(const VALUE self) {
         
     | 
| 
      
 316 
     | 
    
         
            +
                UsaminValue *value = get_value(self);
         
     | 
| 
      
 317 
     | 
    
         
            +
                check_value(value);
         
     | 
| 
      
 318 
     | 
    
         
            +
                if (value->value->IsObject())
         
     | 
| 
      
 319 
     | 
    
         
            +
                    return eval_object(*(value->value));
         
     | 
| 
      
 320 
     | 
    
         
            +
                else if (value->value->IsArray())
         
     | 
| 
      
 321 
     | 
    
         
            +
                    return eval_array(*(value->value));
         
     | 
| 
      
 322 
     | 
    
         
            +
                return Qnil;
         
     | 
| 
      
 323 
     | 
    
         
            +
            }
         
     | 
| 
      
 324 
     | 
    
         
            +
             
     | 
| 
      
 325 
     | 
    
         
            +
            /*
         
     | 
| 
      
 326 
     | 
    
         
            +
             * Convert to Ruby data structures recursively.
         
     | 
| 
      
 327 
     | 
    
         
            +
             *
         
     | 
| 
      
 328 
     | 
    
         
            +
             * @return [Object]
         
     | 
| 
      
 329 
     | 
    
         
            +
             */
         
     | 
| 
      
 330 
     | 
    
         
            +
            static VALUE w_value_eval_r(const VALUE self) {
         
     | 
| 
      
 331 
     | 
    
         
            +
                UsaminValue *value = get_value(self);
         
     | 
| 
      
 332 
     | 
    
         
            +
                check_value(value);
         
     | 
| 
      
 333 
     | 
    
         
            +
                return eval_r(*(value->value));
         
     | 
| 
      
 334 
     | 
    
         
            +
            }
         
     | 
| 
      
 335 
     | 
    
         
            +
             
     | 
| 
      
 336 
     | 
    
         
            +
            /*
         
     | 
| 
      
 337 
     | 
    
         
            +
             * Always true.
         
     | 
| 
      
 338 
     | 
    
         
            +
             */
         
     | 
| 
      
 339 
     | 
    
         
            +
            static VALUE w_value_isfrozen(const VALUE self) {
         
     | 
| 
      
 340 
     | 
    
         
            +
                return Qtrue;
         
     | 
| 
      
 341 
     | 
    
         
            +
            }
         
     | 
| 
      
 342 
     | 
    
         
            +
             
     | 
| 
      
 343 
     | 
    
         
            +
            template <class Writer> static void write_value(Writer&, rapidjson::Value&);
         
     | 
| 
      
 344 
     | 
    
         
            +
             
     | 
| 
      
 345 
     | 
    
         
            +
            /*
         
     | 
| 
      
 346 
     | 
    
         
            +
             * Dumps data in JSON.
         
     | 
| 
      
 347 
     | 
    
         
            +
             *
         
     | 
| 
      
 348 
     | 
    
         
            +
             * @return [String]
         
     | 
| 
      
 349 
     | 
    
         
            +
             */
         
     | 
| 
      
 350 
     | 
    
         
            +
            static VALUE w_value_marshal_dump(const VALUE self) {
         
     | 
| 
      
 351 
     | 
    
         
            +
                UsaminValue *value = get_value(self);
         
     | 
| 
      
 352 
     | 
    
         
            +
                check_value(value);
         
     | 
| 
      
 353 
     | 
    
         
            +
                rapidjson::StringBuffer buf;
         
     | 
| 
      
 354 
     | 
    
         
            +
                rapidjson::Writer<rapidjson::StringBuffer> writer(buf);
         
     | 
| 
      
 355 
     | 
    
         
            +
                write_value(writer, *(value->value));
         
     | 
| 
      
 356 
     | 
    
         
            +
                return rb_str_new(buf.GetString(), buf.GetSize());
         
     | 
| 
      
 357 
     | 
    
         
            +
            }
         
     | 
| 
      
 358 
     | 
    
         
            +
             
     | 
| 
      
 359 
     | 
    
         
            +
            /*
         
     | 
| 
      
 360 
     | 
    
         
            +
             * Loads marshal data.
         
     | 
| 
      
 361 
     | 
    
         
            +
             *
         
     | 
| 
      
 362 
     | 
    
         
            +
             * @return [self]
         
     | 
| 
      
 363 
     | 
    
         
            +
             */
         
     | 
| 
      
 364 
     | 
    
         
            +
            static VALUE w_value_marshal_load(const VALUE self, VALUE source) {
         
     | 
| 
      
 365 
     | 
    
         
            +
                Check_Type(source, T_STRING);
         
     | 
| 
      
 366 
     | 
    
         
            +
                rapidjson::Document *doc = new rapidjson::Document();
         
     | 
| 
      
 367 
     | 
    
         
            +
                rapidjson::ParseResult result = doc->Parse<rapidjson::kParseFullPrecisionFlag | rapidjson::kParseNanAndInfFlag>(RSTRING_PTR(source), RSTRING_LEN(source));
         
     | 
| 
      
 368 
     | 
    
         
            +
                if (!result) {
         
     | 
| 
      
 369 
     | 
    
         
            +
                    delete doc;
         
     | 
| 
      
 370 
     | 
    
         
            +
                    rb_raise(rb_eParserError, "%s Offset: %lu", GetParseError_En(result.Code()), result.Offset());
         
     | 
| 
      
 371 
     | 
    
         
            +
                }
         
     | 
| 
      
 372 
     | 
    
         
            +
                if (doc->IsObject() || doc->IsArray()) {
         
     | 
| 
      
 373 
     | 
    
         
            +
                    set_value(self, new UsaminValue(doc, true));
         
     | 
| 
      
 374 
     | 
    
         
            +
                    return self;
         
     | 
| 
      
 375 
     | 
    
         
            +
                }
         
     | 
| 
      
 376 
     | 
    
         
            +
                auto type = doc->GetType();
         
     | 
| 
      
 377 
     | 
    
         
            +
                delete doc;
         
     | 
| 
      
 378 
     | 
    
         
            +
                rb_raise(rb_eUsaminError, "Invalid Value Type for marshal_load: %d", type);
         
     | 
| 
      
 379 
     | 
    
         
            +
                return Qnil;
         
     | 
| 
      
 380 
     | 
    
         
            +
            }
         
     | 
| 
      
 381 
     | 
    
         
            +
             
     | 
| 
      
 382 
     | 
    
         
            +
             
     | 
| 
      
 383 
     | 
    
         
            +
            /*
         
     | 
| 
      
 384 
     | 
    
         
            +
             * @overload [](name)
         
     | 
| 
      
 385 
     | 
    
         
            +
             *   @return [Object | nil]
         
     | 
| 
      
 386 
     | 
    
         
            +
             *
         
     | 
| 
      
 387 
     | 
    
         
            +
             * @note This method has linear time complexity.
         
     | 
| 
      
 388 
     | 
    
         
            +
             */
         
     | 
| 
      
 389 
     | 
    
         
            +
            static VALUE w_hash_operator_indexer(const VALUE self, VALUE key) {
         
     | 
| 
      
 390 
     | 
    
         
            +
                UsaminValue *value = get_value(self);
         
     | 
| 
      
 391 
     | 
    
         
            +
                check_object(value);
         
     | 
| 
      
 392 
     | 
    
         
            +
                VALUE kvalue = get_utf8_str(key);
         
     | 
| 
      
 393 
     | 
    
         
            +
                for (auto &m : value->value->GetObject())
         
     | 
| 
      
 394 
     | 
    
         
            +
                    if (str_compare(RSTRING_PTR(kvalue), RSTRING_LEN(kvalue), m.name.GetString(), m.name.GetStringLength()))
         
     | 
| 
      
 395 
     | 
    
         
            +
                        return eval(m.value);
         
     | 
| 
      
 396 
     | 
    
         
            +
                return Qnil;
         
     | 
| 
      
 397 
     | 
    
         
            +
            }
         
     | 
| 
      
 398 
     | 
    
         
            +
             
     | 
| 
      
 399 
     | 
    
         
            +
            static VALUE hash_enum_size(const VALUE self, VALUE args, VALUE eobj) {
         
     | 
| 
      
 400 
     | 
    
         
            +
                UsaminValue *value = get_value(self);
         
     | 
| 
      
 401 
     | 
    
         
            +
                check_object(value);
         
     | 
| 
      
 402 
     | 
    
         
            +
                return UINT2NUM(value->value->MemberCount());
         
     | 
| 
      
 403 
     | 
    
         
            +
            }
         
     | 
| 
      
 404 
     | 
    
         
            +
             
     | 
| 
      
 405 
     | 
    
         
            +
            /*
         
     | 
| 
      
 406 
     | 
    
         
            +
             * @yield [key, value]
         
     | 
| 
      
 407 
     | 
    
         
            +
             * @yieldparam key [String]
         
     | 
| 
      
 408 
     | 
    
         
            +
             * @return [Enumerator | self]
         
     | 
| 
      
 409 
     | 
    
         
            +
             */
         
     | 
| 
      
 410 
     | 
    
         
            +
            static VALUE w_hash_each(const VALUE self) {
         
     | 
| 
      
 411 
     | 
    
         
            +
                UsaminValue *value = get_value(self);
         
     | 
| 
      
 412 
     | 
    
         
            +
                check_object(value);
         
     | 
| 
      
 413 
     | 
    
         
            +
                RETURN_SIZED_ENUMERATOR(self, 0, nullptr, hash_enum_size);
         
     | 
| 
      
 414 
     | 
    
         
            +
                if (rb_proc_arity(rb_block_proc()) > 1) {
         
     | 
| 
      
 415 
     | 
    
         
            +
                    for (auto &m : value->value->GetObject()) {
         
     | 
| 
      
 416 
     | 
    
         
            +
                        VALUE args[] = { eval_str(m.name), eval(m.value) };
         
     | 
| 
      
 417 
     | 
    
         
            +
                        rb_yield_values2(2, args);
         
     | 
| 
      
 418 
     | 
    
         
            +
                    }
         
     | 
| 
      
 419 
     | 
    
         
            +
                } else {
         
     | 
| 
      
 420 
     | 
    
         
            +
                    for (auto &m : value->value->GetObject())
         
     | 
| 
      
 421 
     | 
    
         
            +
                        rb_yield(rb_assoc_new(eval_str(m.name), eval(m.value)));
         
     | 
| 
      
 422 
     | 
    
         
            +
                }
         
     | 
| 
      
 423 
     | 
    
         
            +
                return self;
         
     | 
| 
      
 424 
     | 
    
         
            +
            }
         
     | 
| 
      
 425 
     | 
    
         
            +
             
     | 
| 
      
 426 
     | 
    
         
            +
            /*
         
     | 
| 
      
 427 
     | 
    
         
            +
             * @yield [key]
         
     | 
| 
      
 428 
     | 
    
         
            +
             * @yieldparam key [String]
         
     | 
| 
      
 429 
     | 
    
         
            +
             * @return [Enumerator | self]
         
     | 
| 
      
 430 
     | 
    
         
            +
             */
         
     | 
| 
      
 431 
     | 
    
         
            +
            static VALUE w_hash_each_key(const VALUE self) {
         
     | 
| 
      
 432 
     | 
    
         
            +
                UsaminValue *value = get_value(self);
         
     | 
| 
      
 433 
     | 
    
         
            +
                check_object(value);
         
     | 
| 
      
 434 
     | 
    
         
            +
                RETURN_SIZED_ENUMERATOR(self, 0, nullptr, hash_enum_size);
         
     | 
| 
      
 435 
     | 
    
         
            +
                for (auto &m : value->value->GetObject())
         
     | 
| 
      
 436 
     | 
    
         
            +
                    rb_yield(eval_str(m.name));
         
     | 
| 
      
 437 
     | 
    
         
            +
                return self;
         
     | 
| 
      
 438 
     | 
    
         
            +
            }
         
     | 
| 
      
 439 
     | 
    
         
            +
             
     | 
| 
      
 440 
     | 
    
         
            +
            /*
         
     | 
| 
      
 441 
     | 
    
         
            +
             * @yield [value]
         
     | 
| 
      
 442 
     | 
    
         
            +
             * @return [Enumerator | self]
         
     | 
| 
      
 443 
     | 
    
         
            +
             */
         
     | 
| 
      
 444 
     | 
    
         
            +
            static VALUE w_hash_each_value(const VALUE self) {
         
     | 
| 
      
 445 
     | 
    
         
            +
                UsaminValue *value = get_value(self);
         
     | 
| 
      
 446 
     | 
    
         
            +
                check_object(value);
         
     | 
| 
      
 447 
     | 
    
         
            +
                RETURN_SIZED_ENUMERATOR(self, 0, nullptr, hash_enum_size);
         
     | 
| 
      
 448 
     | 
    
         
            +
                for (auto &m : value->value->GetObject())
         
     | 
| 
      
 449 
     | 
    
         
            +
                    rb_yield(eval(m.value));
         
     | 
| 
      
 450 
     | 
    
         
            +
                return self;
         
     | 
| 
      
 451 
     | 
    
         
            +
            }
         
     | 
| 
      
 452 
     | 
    
         
            +
             
     | 
| 
      
 453 
     | 
    
         
            +
            static VALUE w_hash_isempty(const VALUE self) {
         
     | 
| 
      
 454 
     | 
    
         
            +
                UsaminValue *value = get_value(self);
         
     | 
| 
      
 455 
     | 
    
         
            +
                check_object(value);
         
     | 
| 
      
 456 
     | 
    
         
            +
                return value->value->MemberCount() == 0 ? Qtrue : Qfalse;
         
     | 
| 
      
 457 
     | 
    
         
            +
            }
         
     | 
| 
      
 458 
     | 
    
         
            +
             
     | 
| 
      
 459 
     | 
    
         
            +
            /*
         
     | 
| 
      
 460 
     | 
    
         
            +
             * @note This method has linear time complexity.
         
     | 
| 
      
 461 
     | 
    
         
            +
             */
         
     | 
| 
      
 462 
     | 
    
         
            +
            static VALUE w_hash_haskey(const VALUE self, VALUE name) {
         
     | 
| 
      
 463 
     | 
    
         
            +
                UsaminValue *value = get_value(self);
         
     | 
| 
      
 464 
     | 
    
         
            +
                check_object(value);
         
     | 
| 
      
 465 
     | 
    
         
            +
                VALUE key = get_utf8_str(name);
         
     | 
| 
      
 466 
     | 
    
         
            +
                for (auto &m : value->value->GetObject())
         
     | 
| 
      
 467 
     | 
    
         
            +
                    if (str_compare(RSTRING_PTR(key), RSTRING_LEN(key), m.name.GetString(), m.name.GetStringLength()))
         
     | 
| 
      
 468 
     | 
    
         
            +
                        return Qtrue;
         
     | 
| 
      
 469 
     | 
    
         
            +
                return Qfalse;
         
     | 
| 
      
 470 
     | 
    
         
            +
            }
         
     | 
| 
      
 471 
     | 
    
         
            +
             
     | 
| 
      
 472 
     | 
    
         
            +
            /*
         
     | 
| 
      
 473 
     | 
    
         
            +
             * @return [::Array<String>]
         
     | 
| 
      
 474 
     | 
    
         
            +
             */
         
     | 
| 
      
 475 
     | 
    
         
            +
            static VALUE w_hash_keys(const VALUE self) {
         
     | 
| 
      
 476 
     | 
    
         
            +
                UsaminValue *value = get_value(self);
         
     | 
| 
      
 477 
     | 
    
         
            +
                check_object(value);
         
     | 
| 
      
 478 
     | 
    
         
            +
                VALUE ret = rb_ary_new2(value->value->MemberCount());
         
     | 
| 
      
 479 
     | 
    
         
            +
                for (auto &m : value->value->GetObject())
         
     | 
| 
      
 480 
     | 
    
         
            +
                    rb_ary_push(ret, eval_str(m.name));
         
     | 
| 
      
 481 
     | 
    
         
            +
                return ret;
         
     | 
| 
      
 482 
     | 
    
         
            +
            }
         
     | 
| 
      
 483 
     | 
    
         
            +
             
     | 
| 
      
 484 
     | 
    
         
            +
            /*
         
     | 
| 
      
 485 
     | 
    
         
            +
             * @return [Integer]
         
     | 
| 
      
 486 
     | 
    
         
            +
             */
         
     | 
| 
      
 487 
     | 
    
         
            +
            static VALUE w_hash_length(const VALUE self) {
         
     | 
| 
      
 488 
     | 
    
         
            +
                UsaminValue *value = get_value(self);
         
     | 
| 
      
 489 
     | 
    
         
            +
                check_object(value);
         
     | 
| 
      
 490 
     | 
    
         
            +
                return UINT2NUM(value->value->MemberCount());
         
     | 
| 
      
 491 
     | 
    
         
            +
            }
         
     | 
| 
      
 492 
     | 
    
         
            +
             
     | 
| 
      
 493 
     | 
    
         
            +
            /*
         
     | 
| 
      
 494 
     | 
    
         
            +
             * Convert to Ruby Hash. Same as {Value#eval}.
         
     | 
| 
      
 495 
     | 
    
         
            +
             *
         
     | 
| 
      
 496 
     | 
    
         
            +
             * @return [::Hash]
         
     | 
| 
      
 497 
     | 
    
         
            +
             */
         
     | 
| 
      
 498 
     | 
    
         
            +
            static VALUE w_hash_eval(const VALUE self) {
         
     | 
| 
      
 499 
     | 
    
         
            +
                UsaminValue *value = get_value(self);
         
     | 
| 
      
 500 
     | 
    
         
            +
                check_object(value);
         
     | 
| 
      
 501 
     | 
    
         
            +
                return eval_object(*(value->value));
         
     | 
| 
      
 502 
     | 
    
         
            +
            }
         
     | 
| 
      
 503 
     | 
    
         
            +
             
     | 
| 
      
 504 
     | 
    
         
            +
            /*
         
     | 
| 
      
 505 
     | 
    
         
            +
             * @return [::Array<Object>]
         
     | 
| 
      
 506 
     | 
    
         
            +
             */
         
     | 
| 
      
 507 
     | 
    
         
            +
            static VALUE w_hash_values(const VALUE self) {
         
     | 
| 
      
 508 
     | 
    
         
            +
                UsaminValue *value = get_value(self);
         
     | 
| 
      
 509 
     | 
    
         
            +
                check_object(value);
         
     | 
| 
      
 510 
     | 
    
         
            +
                VALUE ret = rb_ary_new2(value->value->MemberCount());
         
     | 
| 
      
 511 
     | 
    
         
            +
                for (auto &m : value->value->GetObject())
         
     | 
| 
      
 512 
     | 
    
         
            +
                    rb_ary_push(ret, eval(m.value));
         
     | 
| 
      
 513 
     | 
    
         
            +
                return ret;
         
     | 
| 
      
 514 
     | 
    
         
            +
            }
         
     | 
| 
      
 515 
     | 
    
         
            +
             
     | 
| 
      
 516 
     | 
    
         
            +
             
     | 
| 
      
 517 
     | 
    
         
            +
            /*
         
     | 
| 
      
 518 
     | 
    
         
            +
             * @overload [](nth)
         
     | 
| 
      
 519 
     | 
    
         
            +
             *   @param [Integer] nth
         
     | 
| 
      
 520 
     | 
    
         
            +
             *   @return [Object | nil]
         
     | 
| 
      
 521 
     | 
    
         
            +
             *
         
     | 
| 
      
 522 
     | 
    
         
            +
             * @overload [](start, length)
         
     | 
| 
      
 523 
     | 
    
         
            +
             *   @param [Integer] start
         
     | 
| 
      
 524 
     | 
    
         
            +
             *   @param [Integer] length
         
     | 
| 
      
 525 
     | 
    
         
            +
             *   @return [::Array<Object> | nil]
         
     | 
| 
      
 526 
     | 
    
         
            +
             *
         
     | 
| 
      
 527 
     | 
    
         
            +
             * @overload [](range)
         
     | 
| 
      
 528 
     | 
    
         
            +
             *   @param [Range] range
         
     | 
| 
      
 529 
     | 
    
         
            +
             *   @return [::Array<Object> | nil]
         
     | 
| 
      
 530 
     | 
    
         
            +
             */
         
     | 
| 
      
 531 
     | 
    
         
            +
            static VALUE w_array_operator_indexer(const int argc, VALUE* argv, const VALUE self) {
         
     | 
| 
      
 532 
     | 
    
         
            +
                rb_check_arity(argc, 1, 2);
         
     | 
| 
      
 533 
     | 
    
         
            +
                UsaminValue *value = get_value(self);
         
     | 
| 
      
 534 
     | 
    
         
            +
                check_array(value);
         
     | 
| 
      
 535 
     | 
    
         
            +
                if (argc == 2) {
         
     | 
| 
      
 536 
     | 
    
         
            +
                    long beg = NUM2LONG(argv[0]);
         
     | 
| 
      
 537 
     | 
    
         
            +
                    long len = NUM2LONG(argv[1]);
         
     | 
| 
      
 538 
     | 
    
         
            +
                    if (beg < 0)
         
     | 
| 
      
 539 
     | 
    
         
            +
                        beg = beg + value->value->Size();
         
     | 
| 
      
 540 
     | 
    
         
            +
                    if (beg >= 0 && len >= 0) {
         
     | 
| 
      
 541 
     | 
    
         
            +
                        long end = beg + len;
         
     | 
| 
      
 542 
     | 
    
         
            +
                        if (end > value->value->Size())
         
     | 
| 
      
 543 
     | 
    
         
            +
                            end = value->value->Size();
         
     | 
| 
      
 544 
     | 
    
         
            +
                        VALUE ret = rb_ary_new2(end - beg);
         
     | 
| 
      
 545 
     | 
    
         
            +
                        for (long i = beg; i < end; i++)
         
     | 
| 
      
 546 
     | 
    
         
            +
                            rb_ary_push(ret, eval((*(value->value))[static_cast<unsigned int>(i)]));
         
     | 
| 
      
 547 
     | 
    
         
            +
                        return ret;
         
     | 
| 
      
 548 
     | 
    
         
            +
                    }
         
     | 
| 
      
 549 
     | 
    
         
            +
                } else if (rb_obj_is_kind_of(argv[0], rb_cRange)) {
         
     | 
| 
      
 550 
     | 
    
         
            +
                    long beg, len;
         
     | 
| 
      
 551 
     | 
    
         
            +
                    if (rb_range_beg_len(argv[0], &beg, &len, value->value->Size(), 0) == Qtrue) {
         
     | 
| 
      
 552 
     | 
    
         
            +
                        VALUE ret = rb_ary_new2(len);
         
     | 
| 
      
 553 
     | 
    
         
            +
                        for (long i = beg; i < beg + len; i++)
         
     | 
| 
      
 554 
     | 
    
         
            +
                            rb_ary_push(ret, eval((*(value->value))[static_cast<unsigned int>(i)]));
         
     | 
| 
      
 555 
     | 
    
         
            +
                        return ret;
         
     | 
| 
      
 556 
     | 
    
         
            +
                    }
         
     | 
| 
      
 557 
     | 
    
         
            +
                } else {
         
     | 
| 
      
 558 
     | 
    
         
            +
                    long l = NUM2LONG(argv[0]);
         
     | 
| 
      
 559 
     | 
    
         
            +
                    if (l < 0)
         
     | 
| 
      
 560 
     | 
    
         
            +
                        l = l + value->value->Size();
         
     | 
| 
      
 561 
     | 
    
         
            +
                    if (l >= 0) {
         
     | 
| 
      
 562 
     | 
    
         
            +
                        unsigned int i = static_cast<unsigned int>(l);
         
     | 
| 
      
 563 
     | 
    
         
            +
                        if (i < value->value->Size())
         
     | 
| 
      
 564 
     | 
    
         
            +
                            return eval((*(value->value))[i]);
         
     | 
| 
      
 565 
     | 
    
         
            +
                    }
         
     | 
| 
      
 566 
     | 
    
         
            +
                }
         
     | 
| 
      
 567 
     | 
    
         
            +
                return Qnil;
         
     | 
| 
      
 568 
     | 
    
         
            +
            }
         
     | 
| 
      
 569 
     | 
    
         
            +
             
     | 
| 
      
 570 
     | 
    
         
            +
            static VALUE array_enum_size(const VALUE self, VALUE args, VALUE eobj) {
         
     | 
| 
      
 571 
     | 
    
         
            +
                UsaminValue *value = get_value(self);
         
     | 
| 
      
 572 
     | 
    
         
            +
                check_array(value);
         
     | 
| 
      
 573 
     | 
    
         
            +
                return UINT2NUM(value->value->Size());
         
     | 
| 
      
 574 
     | 
    
         
            +
            }
         
     | 
| 
      
 575 
     | 
    
         
            +
             
     | 
| 
      
 576 
     | 
    
         
            +
            /*
         
     | 
| 
      
 577 
     | 
    
         
            +
             * @yield [value]
         
     | 
| 
      
 578 
     | 
    
         
            +
             * @return [Enumerator | self]
         
     | 
| 
      
 579 
     | 
    
         
            +
             */
         
     | 
| 
      
 580 
     | 
    
         
            +
            static VALUE w_array_each(const VALUE self) {
         
     | 
| 
      
 581 
     | 
    
         
            +
                UsaminValue *value = get_value(self);
         
     | 
| 
      
 582 
     | 
    
         
            +
                check_array(value);
         
     | 
| 
      
 583 
     | 
    
         
            +
                RETURN_SIZED_ENUMERATOR(self, 0, nullptr, array_enum_size);
         
     | 
| 
      
 584 
     | 
    
         
            +
                for (auto &v : value->value->GetArray())
         
     | 
| 
      
 585 
     | 
    
         
            +
                    rb_yield(eval(v));
         
     | 
| 
      
 586 
     | 
    
         
            +
                return self;
         
     | 
| 
      
 587 
     | 
    
         
            +
            }
         
     | 
| 
      
 588 
     | 
    
         
            +
             
     | 
| 
      
 589 
     | 
    
         
            +
            /*
         
     | 
| 
      
 590 
     | 
    
         
            +
             * @yield [index]
         
     | 
| 
      
 591 
     | 
    
         
            +
             * @yieldparam index [Integer]
         
     | 
| 
      
 592 
     | 
    
         
            +
             * @return [Enumerator | self]
         
     | 
| 
      
 593 
     | 
    
         
            +
             */
         
     | 
| 
      
 594 
     | 
    
         
            +
            static VALUE w_array_each_index(const VALUE self) {
         
     | 
| 
      
 595 
     | 
    
         
            +
                UsaminValue *value = get_value(self);
         
     | 
| 
      
 596 
     | 
    
         
            +
                check_array(value);
         
     | 
| 
      
 597 
     | 
    
         
            +
                RETURN_SIZED_ENUMERATOR(self, 0, nullptr, array_enum_size);
         
     | 
| 
      
 598 
     | 
    
         
            +
                for (rapidjson::SizeType i = 0; i < value->value->Size(); i++)
         
     | 
| 
      
 599 
     | 
    
         
            +
                    rb_yield(UINT2NUM(i));
         
     | 
| 
      
 600 
     | 
    
         
            +
                return self;
         
     | 
| 
      
 601 
     | 
    
         
            +
            }
         
     | 
| 
      
 602 
     | 
    
         
            +
             
     | 
| 
      
 603 
     | 
    
         
            +
            static VALUE w_array_isempty(const VALUE self) {
         
     | 
| 
      
 604 
     | 
    
         
            +
                UsaminValue *value = get_value(self);
         
     | 
| 
      
 605 
     | 
    
         
            +
                check_array(value);
         
     | 
| 
      
 606 
     | 
    
         
            +
                return value->value->Size() == 0 ? Qtrue : Qfalse;
         
     | 
| 
      
 607 
     | 
    
         
            +
            }
         
     | 
| 
      
 608 
     | 
    
         
            +
             
     | 
| 
      
 609 
     | 
    
         
            +
            /*
         
     | 
| 
      
 610 
     | 
    
         
            +
             * @yield [value]
         
     | 
| 
      
 611 
     | 
    
         
            +
             * @return [Integer]
         
     | 
| 
      
 612 
     | 
    
         
            +
             */
         
     | 
| 
      
 613 
     | 
    
         
            +
            static VALUE w_array_index(int argc, VALUE* argv, const VALUE self) {
         
     | 
| 
      
 614 
     | 
    
         
            +
                rb_check_arity(argc, 0, 1);
         
     | 
| 
      
 615 
     | 
    
         
            +
                UsaminValue *value = get_value(self);
         
     | 
| 
      
 616 
     | 
    
         
            +
                check_array(value);
         
     | 
| 
      
 617 
     | 
    
         
            +
             
     | 
| 
      
 618 
     | 
    
         
            +
                if (argc == 1) {
         
     | 
| 
      
 619 
     | 
    
         
            +
                    for (rapidjson::SizeType i = 0; i < value->value->Size(); i++) {
         
     | 
| 
      
 620 
     | 
    
         
            +
                        if (rb_equal(argv[0], eval((*(value->value))[i])) == Qtrue)
         
     | 
| 
      
 621 
     | 
    
         
            +
                            return UINT2NUM(i);
         
     | 
| 
      
 622 
     | 
    
         
            +
                    }
         
     | 
| 
      
 623 
     | 
    
         
            +
                    return Qnil;
         
     | 
| 
      
 624 
     | 
    
         
            +
                }
         
     | 
| 
      
 625 
     | 
    
         
            +
             
     | 
| 
      
 626 
     | 
    
         
            +
                RETURN_SIZED_ENUMERATOR(self, 0, nullptr, array_enum_size);
         
     | 
| 
      
 627 
     | 
    
         
            +
                for (rapidjson::SizeType i = 0; i < value->value->Size(); i++) {
         
     | 
| 
      
 628 
     | 
    
         
            +
                    if (RTEST(rb_yield(eval((*(value->value))[i]))))
         
     | 
| 
      
 629 
     | 
    
         
            +
                        return UINT2NUM(i);
         
     | 
| 
      
 630 
     | 
    
         
            +
                }
         
     | 
| 
      
 631 
     | 
    
         
            +
                return Qnil;
         
     | 
| 
      
 632 
     | 
    
         
            +
            }
         
     | 
| 
      
 633 
     | 
    
         
            +
             
     | 
| 
      
 634 
     | 
    
         
            +
            /*
         
     | 
| 
      
 635 
     | 
    
         
            +
             * @overload first
         
     | 
| 
      
 636 
     | 
    
         
            +
             *   @return [Object | nil]
         
     | 
| 
      
 637 
     | 
    
         
            +
             *
         
     | 
| 
      
 638 
     | 
    
         
            +
             * @overload first(n)
         
     | 
| 
      
 639 
     | 
    
         
            +
             *   @return [::Array<Object>]
         
     | 
| 
      
 640 
     | 
    
         
            +
             */
         
     | 
| 
      
 641 
     | 
    
         
            +
            static VALUE w_array_first(const int argc, VALUE* argv, const VALUE self) {
         
     | 
| 
      
 642 
     | 
    
         
            +
                rb_check_arity(argc, 0, 1);
         
     | 
| 
      
 643 
     | 
    
         
            +
                UsaminValue *value = get_value(self);
         
     | 
| 
      
 644 
     | 
    
         
            +
                check_array(value);
         
     | 
| 
      
 645 
     | 
    
         
            +
             
     | 
| 
      
 646 
     | 
    
         
            +
                if (argc == 0) {
         
     | 
| 
      
 647 
     | 
    
         
            +
                    if (value->value->Size() == 0)
         
     | 
| 
      
 648 
     | 
    
         
            +
                        return Qnil;
         
     | 
| 
      
 649 
     | 
    
         
            +
                    return eval((*(value->value))[0]);
         
     | 
| 
      
 650 
     | 
    
         
            +
                }
         
     | 
| 
      
 651 
     | 
    
         
            +
             
     | 
| 
      
 652 
     | 
    
         
            +
                long l = NUM2LONG(argv[0]);
         
     | 
| 
      
 653 
     | 
    
         
            +
                if (l < 0)
         
     | 
| 
      
 654 
     | 
    
         
            +
                    l = 0;
         
     | 
| 
      
 655 
     | 
    
         
            +
                else if (l > value->value->Size())
         
     | 
| 
      
 656 
     | 
    
         
            +
                    l = value->value->Size();
         
     | 
| 
      
 657 
     | 
    
         
            +
                unsigned int li = static_cast<unsigned int>(l);
         
     | 
| 
      
 658 
     | 
    
         
            +
                VALUE ret = rb_ary_new2(li);
         
     | 
| 
      
 659 
     | 
    
         
            +
                for (unsigned int i = 0; i < li; i++)
         
     | 
| 
      
 660 
     | 
    
         
            +
                    rb_ary_push(ret, eval((*(value->value))[i]));
         
     | 
| 
      
 661 
     | 
    
         
            +
             
     | 
| 
      
 662 
     | 
    
         
            +
                return ret;
         
     | 
| 
      
 663 
     | 
    
         
            +
            }
         
     | 
| 
      
 664 
     | 
    
         
            +
             
     | 
| 
      
 665 
     | 
    
         
            +
            /*
         
     | 
| 
      
 666 
     | 
    
         
            +
             * @return [Integer]
         
     | 
| 
      
 667 
     | 
    
         
            +
             */
         
     | 
| 
      
 668 
     | 
    
         
            +
            static VALUE w_array_length(const VALUE self) {
         
     | 
| 
      
 669 
     | 
    
         
            +
                UsaminValue *value = get_value(self);
         
     | 
| 
      
 670 
     | 
    
         
            +
                check_array(value);
         
     | 
| 
      
 671 
     | 
    
         
            +
                return UINT2NUM(value->value->Size());
         
     | 
| 
      
 672 
     | 
    
         
            +
            }
         
     | 
| 
      
 673 
     | 
    
         
            +
             
     | 
| 
      
 674 
     | 
    
         
            +
            /*
         
     | 
| 
      
 675 
     | 
    
         
            +
             * Convert to Ruby data structures. Same as {Value#eval}.
         
     | 
| 
      
 676 
     | 
    
         
            +
             *
         
     | 
| 
      
 677 
     | 
    
         
            +
             * @return [::Array<Object>]
         
     | 
| 
      
 678 
     | 
    
         
            +
             */
         
     | 
| 
      
 679 
     | 
    
         
            +
            static VALUE w_array_eval(const VALUE self) {
         
     | 
| 
      
 680 
     | 
    
         
            +
                UsaminValue *value = get_value(self);
         
     | 
| 
      
 681 
     | 
    
         
            +
                check_array(value);
         
     | 
| 
      
 682 
     | 
    
         
            +
                return eval_array(*(value->value));
         
     | 
| 
      
 683 
     | 
    
         
            +
            }
         
     | 
| 
      
 684 
     | 
    
         
            +
             
     | 
| 
      
 685 
     | 
    
         
            +
             
     | 
| 
      
 686 
     | 
    
         
            +
            template <class Writer> static void write(Writer&, const VALUE);
         
     | 
| 
      
 687 
     | 
    
         
            +
             
     | 
| 
      
 688 
     | 
    
         
            +
            template <class Writer> static inline void write_str(Writer &writer, const VALUE value) {
         
     | 
| 
      
 689 
     | 
    
         
            +
                VALUE v = get_utf8_str(value);
         
     | 
| 
      
 690 
     | 
    
         
            +
                writer.String(RSTRING_PTR(v), static_cast<unsigned int>(RSTRING_LEN(v)));
         
     | 
| 
      
 691 
     | 
    
         
            +
            }
         
     | 
| 
      
 692 
     | 
    
         
            +
             
     | 
| 
      
 693 
     | 
    
         
            +
            template <class Writer> static inline void write_to_s(Writer &writer, const VALUE value) {
         
     | 
| 
      
 694 
     | 
    
         
            +
                write_str(writer, rb_funcall(value, id_to_s, 0));
         
     | 
| 
      
 695 
     | 
    
         
            +
            }
         
     | 
| 
      
 696 
     | 
    
         
            +
             
     | 
| 
      
 697 
     | 
    
         
            +
            template <class Writer> static inline void write_key_str(Writer &writer, const VALUE value) {
         
     | 
| 
      
 698 
     | 
    
         
            +
                VALUE v = get_utf8_str(value);
         
     | 
| 
      
 699 
     | 
    
         
            +
                writer.Key(RSTRING_PTR(v), static_cast<unsigned int>(RSTRING_LEN(v)));
         
     | 
| 
      
 700 
     | 
    
         
            +
            }
         
     | 
| 
      
 701 
     | 
    
         
            +
             
     | 
| 
      
 702 
     | 
    
         
            +
            template <class Writer> static inline void write_key_to_s(Writer &writer, const VALUE value) {
         
     | 
| 
      
 703 
     | 
    
         
            +
                write_key_str(writer, rb_funcall(value, id_to_s, 0));
         
     | 
| 
      
 704 
     | 
    
         
            +
            }
         
     | 
| 
      
 705 
     | 
    
         
            +
             
     | 
| 
      
 706 
     | 
    
         
            +
            template <class Writer> static inline void write_bignum(Writer &writer, const VALUE value) {
         
     | 
| 
      
 707 
     | 
    
         
            +
                VALUE v = rb_big2str(value, 10);
         
     | 
| 
      
 708 
     | 
    
         
            +
                writer.RawValue(RSTRING_PTR(v), static_cast<unsigned int>(RSTRING_LEN(v)), rapidjson::kNumberType);
         
     | 
| 
      
 709 
     | 
    
         
            +
            }
         
     | 
| 
      
 710 
     | 
    
         
            +
             
     | 
| 
      
 711 
     | 
    
         
            +
            template <class Writer> static inline int write_hash_each(VALUE key, VALUE value, Writer *writer) {
         
     | 
| 
      
 712 
     | 
    
         
            +
                if (RB_TYPE_P(key, T_STRING))
         
     | 
| 
      
 713 
     | 
    
         
            +
                    write_key_str(*writer, key);
         
     | 
| 
      
 714 
     | 
    
         
            +
                else if (RB_TYPE_P(key, T_SYMBOL))
         
     | 
| 
      
 715 
     | 
    
         
            +
                    write_key_str(*writer, rb_sym_to_s(key));
         
     | 
| 
      
 716 
     | 
    
         
            +
                else
         
     | 
| 
      
 717 
     | 
    
         
            +
                    write_key_to_s(*writer, key);
         
     | 
| 
      
 718 
     | 
    
         
            +
                write(*writer, value);
         
     | 
| 
      
 719 
     | 
    
         
            +
                return ST_CONTINUE;
         
     | 
| 
      
 720 
     | 
    
         
            +
            }
         
     | 
| 
      
 721 
     | 
    
         
            +
             
     | 
| 
      
 722 
     | 
    
         
            +
            template <class Writer> static inline void write_hash(Writer &writer, const VALUE hash) {
         
     | 
| 
      
 723 
     | 
    
         
            +
                writer.StartObject();
         
     | 
| 
      
 724 
     | 
    
         
            +
                rb_hash_foreach(hash, (int (*)(ANYARGS))write_hash_each<Writer>, reinterpret_cast<VALUE>((&writer)));
         
     | 
| 
      
 725 
     | 
    
         
            +
                writer.EndObject();
         
     | 
| 
      
 726 
     | 
    
         
            +
            }
         
     | 
| 
      
 727 
     | 
    
         
            +
             
     | 
| 
      
 728 
     | 
    
         
            +
            template <class Writer> static inline void write_array(Writer &writer, const VALUE value) {
         
     | 
| 
      
 729 
     | 
    
         
            +
                writer.StartArray();
         
     | 
| 
      
 730 
     | 
    
         
            +
                const VALUE *ptr = rb_array_const_ptr(value);
         
     | 
| 
      
 731 
     | 
    
         
            +
                for (long i = 0; i < rb_array_len(value); i++, ptr++)
         
     | 
| 
      
 732 
     | 
    
         
            +
                    write(writer, *ptr);
         
     | 
| 
      
 733 
     | 
    
         
            +
                writer.EndArray();
         
     | 
| 
      
 734 
     | 
    
         
            +
            }
         
     | 
| 
      
 735 
     | 
    
         
            +
             
     | 
| 
      
 736 
     | 
    
         
            +
            template <class Writer> static inline void write_struct(Writer &writer, const VALUE value) {
         
     | 
| 
      
 737 
     | 
    
         
            +
                writer.StartObject();
         
     | 
| 
      
 738 
     | 
    
         
            +
                VALUE members = rb_struct_members(value);
         
     | 
| 
      
 739 
     | 
    
         
            +
                const VALUE *ptr = rb_array_const_ptr(members);
         
     | 
| 
      
 740 
     | 
    
         
            +
                for (long i = 0; i < rb_array_len(members); i++, ptr++) {
         
     | 
| 
      
 741 
     | 
    
         
            +
                    if (RB_TYPE_P(*ptr, T_SYMBOL))
         
     | 
| 
      
 742 
     | 
    
         
            +
                        write_key_str(writer, rb_sym_to_s(*ptr));
         
     | 
| 
      
 743 
     | 
    
         
            +
                    else if (RB_TYPE_P(*ptr, T_STRING))
         
     | 
| 
      
 744 
     | 
    
         
            +
                        write_key_str(writer, *ptr);
         
     | 
| 
      
 745 
     | 
    
         
            +
                    else
         
     | 
| 
      
 746 
     | 
    
         
            +
                        write_key_to_s(writer, *ptr);
         
     | 
| 
      
 747 
     | 
    
         
            +
                    write(writer, rb_struct_aref(value, *ptr));
         
     | 
| 
      
 748 
     | 
    
         
            +
                }
         
     | 
| 
      
 749 
     | 
    
         
            +
                writer.EndObject();
         
     | 
| 
      
 750 
     | 
    
         
            +
            }
         
     | 
| 
      
 751 
     | 
    
         
            +
             
     | 
| 
      
 752 
     | 
    
         
            +
            template <class Writer> static void write_value(Writer &writer, rapidjson::Value &value) {
         
     | 
| 
      
 753 
     | 
    
         
            +
                switch (value.GetType()) {
         
     | 
| 
      
 754 
     | 
    
         
            +
                    case rapidjson::kObjectType:
         
     | 
| 
      
 755 
     | 
    
         
            +
                        writer.StartObject();
         
     | 
| 
      
 756 
     | 
    
         
            +
                        for (auto &m : value.GetObject()) {
         
     | 
| 
      
 757 
     | 
    
         
            +
                            writer.Key(m.name.GetString(), m.name.GetStringLength());
         
     | 
| 
      
 758 
     | 
    
         
            +
                            write_value(writer, m.value);
         
     | 
| 
      
 759 
     | 
    
         
            +
                        }
         
     | 
| 
      
 760 
     | 
    
         
            +
                        writer.EndObject();
         
     | 
| 
      
 761 
     | 
    
         
            +
                        break;
         
     | 
| 
      
 762 
     | 
    
         
            +
                    case rapidjson::kArrayType:
         
     | 
| 
      
 763 
     | 
    
         
            +
                        writer.StartArray();
         
     | 
| 
      
 764 
     | 
    
         
            +
                        for (auto &v : value.GetArray())
         
     | 
| 
      
 765 
     | 
    
         
            +
                            write_value(writer, v);
         
     | 
| 
      
 766 
     | 
    
         
            +
                        writer.EndArray();
         
     | 
| 
      
 767 
     | 
    
         
            +
                        break;
         
     | 
| 
      
 768 
     | 
    
         
            +
                    case rapidjson::kNullType:
         
     | 
| 
      
 769 
     | 
    
         
            +
                        writer.Null();
         
     | 
| 
      
 770 
     | 
    
         
            +
                        break;
         
     | 
| 
      
 771 
     | 
    
         
            +
                    case rapidjson::kFalseType:
         
     | 
| 
      
 772 
     | 
    
         
            +
                        writer.Bool(false);
         
     | 
| 
      
 773 
     | 
    
         
            +
                        break;
         
     | 
| 
      
 774 
     | 
    
         
            +
                    case rapidjson::kTrueType:
         
     | 
| 
      
 775 
     | 
    
         
            +
                        writer.Bool(true);
         
     | 
| 
      
 776 
     | 
    
         
            +
                        break;
         
     | 
| 
      
 777 
     | 
    
         
            +
                    case rapidjson::kNumberType:
         
     | 
| 
      
 778 
     | 
    
         
            +
                        if (value.IsInt())
         
     | 
| 
      
 779 
     | 
    
         
            +
                            writer.Int(value.GetInt());
         
     | 
| 
      
 780 
     | 
    
         
            +
                        else if (value.IsUint())
         
     | 
| 
      
 781 
     | 
    
         
            +
                            writer.Uint(value.GetUint());
         
     | 
| 
      
 782 
     | 
    
         
            +
                        else if (value.IsInt64())
         
     | 
| 
      
 783 
     | 
    
         
            +
                            writer.Int64(value.GetInt64());
         
     | 
| 
      
 784 
     | 
    
         
            +
                        else if (value.IsUint64())
         
     | 
| 
      
 785 
     | 
    
         
            +
                            writer.Uint64(value.GetUint64());
         
     | 
| 
      
 786 
     | 
    
         
            +
                        else
         
     | 
| 
      
 787 
     | 
    
         
            +
                            writer.Double(value.GetDouble());
         
     | 
| 
      
 788 
     | 
    
         
            +
                        break;
         
     | 
| 
      
 789 
     | 
    
         
            +
                    case rapidjson::kStringType:
         
     | 
| 
      
 790 
     | 
    
         
            +
                        writer.String(value.GetString(), value.GetStringLength());
         
     | 
| 
      
 791 
     | 
    
         
            +
                        break;
         
     | 
| 
      
 792 
     | 
    
         
            +
                    default:
         
     | 
| 
      
 793 
     | 
    
         
            +
                        rb_raise(rb_eUsaminError, "Unknown Value Type: %d", value.GetType());
         
     | 
| 
      
 794 
     | 
    
         
            +
                }
         
     | 
| 
      
 795 
     | 
    
         
            +
            }
         
     | 
| 
      
 796 
     | 
    
         
            +
             
     | 
| 
      
 797 
     | 
    
         
            +
            template <class Writer> static inline void write_usamin(Writer &writer, const VALUE self) {
         
     | 
| 
      
 798 
     | 
    
         
            +
                UsaminValue *value = get_value(self);
         
     | 
| 
      
 799 
     | 
    
         
            +
                check_value(value);
         
     | 
| 
      
 800 
     | 
    
         
            +
                write_value(writer, *(value->value));
         
     | 
| 
      
 801 
     | 
    
         
            +
            }
         
     | 
| 
      
 802 
     | 
    
         
            +
             
     | 
| 
      
 803 
     | 
    
         
            +
            template <class Writer> static void write(Writer &writer, const VALUE value) {
         
     | 
| 
      
 804 
     | 
    
         
            +
                if (value == Qnil) {
         
     | 
| 
      
 805 
     | 
    
         
            +
                    writer.Null();
         
     | 
| 
      
 806 
     | 
    
         
            +
                } else if (value == Qfalse) {
         
     | 
| 
      
 807 
     | 
    
         
            +
                    writer.Bool(false);
         
     | 
| 
      
 808 
     | 
    
         
            +
                } else if (value == Qtrue) {
         
     | 
| 
      
 809 
     | 
    
         
            +
                    writer.Bool(true);
         
     | 
| 
      
 810 
     | 
    
         
            +
                } else if (RB_FIXNUM_P(value)) {
         
     | 
| 
      
 811 
     | 
    
         
            +
                    writer.Int64(FIX2LONG(value));
         
     | 
| 
      
 812 
     | 
    
         
            +
                } else if (RB_FLOAT_TYPE_P(value)) {
         
     | 
| 
      
 813 
     | 
    
         
            +
                    writer.Double(NUM2DBL(value));
         
     | 
| 
      
 814 
     | 
    
         
            +
                } else if (RB_STATIC_SYM_P(value)) {
         
     | 
| 
      
 815 
     | 
    
         
            +
                    write_str(writer, rb_sym_to_s(value));
         
     | 
| 
      
 816 
     | 
    
         
            +
                } else {
         
     | 
| 
      
 817 
     | 
    
         
            +
                    switch (RB_BUILTIN_TYPE(value)) {
         
     | 
| 
      
 818 
     | 
    
         
            +
                        case T_STRING:
         
     | 
| 
      
 819 
     | 
    
         
            +
                            write_str(writer, value);
         
     | 
| 
      
 820 
     | 
    
         
            +
                            break;
         
     | 
| 
      
 821 
     | 
    
         
            +
                        case T_HASH:
         
     | 
| 
      
 822 
     | 
    
         
            +
                            write_hash(writer, value);
         
     | 
| 
      
 823 
     | 
    
         
            +
                            break;
         
     | 
| 
      
 824 
     | 
    
         
            +
                        case T_ARRAY:
         
     | 
| 
      
 825 
     | 
    
         
            +
                            write_array(writer, value);
         
     | 
| 
      
 826 
     | 
    
         
            +
                            break;
         
     | 
| 
      
 827 
     | 
    
         
            +
                        case T_BIGNUM:
         
     | 
| 
      
 828 
     | 
    
         
            +
                            write_bignum(writer, value);
         
     | 
| 
      
 829 
     | 
    
         
            +
                            break;
         
     | 
| 
      
 830 
     | 
    
         
            +
                        case T_STRUCT:
         
     | 
| 
      
 831 
     | 
    
         
            +
                            write_struct(writer, value);
         
     | 
| 
      
 832 
     | 
    
         
            +
                            break;
         
     | 
| 
      
 833 
     | 
    
         
            +
                        default:
         
     | 
| 
      
 834 
     | 
    
         
            +
                            if (rb_obj_is_kind_of(value, rb_cUsaminValue))
         
     | 
| 
      
 835 
     | 
    
         
            +
                                write_usamin(writer, value);
         
     | 
| 
      
 836 
     | 
    
         
            +
                            else
         
     | 
| 
      
 837 
     | 
    
         
            +
                                write_to_s(writer, value);
         
     | 
| 
      
 838 
     | 
    
         
            +
                            break;
         
     | 
| 
      
 839 
     | 
    
         
            +
                    }
         
     | 
| 
      
 840 
     | 
    
         
            +
                }
         
     | 
| 
      
 841 
     | 
    
         
            +
            }
         
     | 
| 
      
 842 
     | 
    
         
            +
             
     | 
| 
      
 843 
     | 
    
         
            +
            /*
         
     | 
| 
      
 844 
     | 
    
         
            +
             * Generate the JSON string from Ruby data structures.
         
     | 
| 
      
 845 
     | 
    
         
            +
             *
         
     | 
| 
      
 846 
     | 
    
         
            +
             * @overload generate(obj)
         
     | 
| 
      
 847 
     | 
    
         
            +
             *   @param [Object] obj an object to serialize
         
     | 
| 
      
 848 
     | 
    
         
            +
             *   @return [String]
         
     | 
| 
      
 849 
     | 
    
         
            +
             */
         
     | 
| 
      
 850 
     | 
    
         
            +
            static VALUE w_generate(const VALUE self, VALUE value) {
         
     | 
| 
      
 851 
     | 
    
         
            +
                rapidjson::StringBuffer buf;
         
     | 
| 
      
 852 
     | 
    
         
            +
                rapidjson::Writer<rapidjson::StringBuffer> writer(buf);
         
     | 
| 
      
 853 
     | 
    
         
            +
                write(writer, value);
         
     | 
| 
      
 854 
     | 
    
         
            +
                return new_utf8_str(buf.GetString(), buf.GetSize());
         
     | 
| 
      
 855 
     | 
    
         
            +
            }
         
     | 
| 
      
 856 
     | 
    
         
            +
             
     | 
| 
      
 857 
     | 
    
         
            +
            /*
         
     | 
| 
      
 858 
     | 
    
         
            +
             * Generate the prettified JSON string from Ruby data structures.
         
     | 
| 
      
 859 
     | 
    
         
            +
             *
         
     | 
| 
      
 860 
     | 
    
         
            +
             * @overload generate(obj, opts = {})
         
     | 
| 
      
 861 
     | 
    
         
            +
             *   @param [Object] obj an object to serialize
         
     | 
| 
      
 862 
     | 
    
         
            +
             *   @param [::Hash] opts options
         
     | 
| 
      
 863 
     | 
    
         
            +
             *   @option opts [String] :indent ('  ') a string used to indent
         
     | 
| 
      
 864 
     | 
    
         
            +
             *   @return [String]
         
     | 
| 
      
 865 
     | 
    
         
            +
             */
         
     | 
| 
      
 866 
     | 
    
         
            +
            static VALUE w_pretty_generate(const int argc, VALUE *argv, const VALUE self) {
         
     | 
| 
      
 867 
     | 
    
         
            +
                VALUE value, options;
         
     | 
| 
      
 868 
     | 
    
         
            +
                rb_scan_args(argc, argv, "1:", &value, &options);
         
     | 
| 
      
 869 
     | 
    
         
            +
                rapidjson::StringBuffer buf;
         
     | 
| 
      
 870 
     | 
    
         
            +
                rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buf);
         
     | 
| 
      
 871 
     | 
    
         
            +
             
     | 
| 
      
 872 
     | 
    
         
            +
                char indent_char = ' ';
         
     | 
| 
      
 873 
     | 
    
         
            +
                unsigned int indent_count = 2;
         
     | 
| 
      
 874 
     | 
    
         
            +
                if (argc > 1) {
         
     | 
| 
      
 875 
     | 
    
         
            +
                    VALUE v_indent = rb_hash_lookup(options, sym_indent);
         
     | 
| 
      
 876 
     | 
    
         
            +
                    VALUE v_single_line_array = rb_hash_lookup(options, sym_single_line_array);
         
     | 
| 
      
 877 
     | 
    
         
            +
             
     | 
| 
      
 878 
     | 
    
         
            +
                    if (RTEST(v_indent)) {
         
     | 
| 
      
 879 
     | 
    
         
            +
                        if (RB_FIXNUM_P(v_indent)) {
         
     | 
| 
      
 880 
     | 
    
         
            +
                            long l = FIX2LONG(v_indent);
         
     | 
| 
      
 881 
     | 
    
         
            +
                            indent_count = l > 0 ? static_cast<unsigned int>(l) : 0;
         
     | 
| 
      
 882 
     | 
    
         
            +
                        } else {
         
     | 
| 
      
 883 
     | 
    
         
            +
                            VALUE v = get_utf8_str(v_indent);
         
     | 
| 
      
 884 
     | 
    
         
            +
                            long vlen = RSTRING_LEN(v);
         
     | 
| 
      
 885 
     | 
    
         
            +
                            if (vlen == 0) {
         
     | 
| 
      
 886 
     | 
    
         
            +
                                indent_count = 0;
         
     | 
| 
      
 887 
     | 
    
         
            +
                            } else {
         
     | 
| 
      
 888 
     | 
    
         
            +
                                const char *indent_str = RSTRING_PTR(v);
         
     | 
| 
      
 889 
     | 
    
         
            +
                                switch (indent_str[0]) {
         
     | 
| 
      
 890 
     | 
    
         
            +
                                    case '\0':
         
     | 
| 
      
 891 
     | 
    
         
            +
                                        indent_count = 0;
         
     | 
| 
      
 892 
     | 
    
         
            +
                                        break;
         
     | 
| 
      
 893 
     | 
    
         
            +
                                    case ' ':
         
     | 
| 
      
 894 
     | 
    
         
            +
                                    case '\t':
         
     | 
| 
      
 895 
     | 
    
         
            +
                                    case '\r':
         
     | 
| 
      
 896 
     | 
    
         
            +
                                    case '\n':
         
     | 
| 
      
 897 
     | 
    
         
            +
                                        indent_char = indent_str[0];
         
     | 
| 
      
 898 
     | 
    
         
            +
                                        break;
         
     | 
| 
      
 899 
     | 
    
         
            +
                                    default:
         
     | 
| 
      
 900 
     | 
    
         
            +
                                        rb_raise(rb_eUsaminError, ":indent must be a repetation of \" \", \"\\t\", \"\\r\" or \"\\n\".");
         
     | 
| 
      
 901 
     | 
    
         
            +
                                }
         
     | 
| 
      
 902 
     | 
    
         
            +
             
     | 
| 
      
 903 
     | 
    
         
            +
                                for (long i = 1; i < vlen; i++)
         
     | 
| 
      
 904 
     | 
    
         
            +
                                    if (indent_str[0] != indent_str[i])
         
     | 
| 
      
 905 
     | 
    
         
            +
                                        rb_raise(rb_eUsaminError, ":indent must be a repetation of \" \", \"\\t\", \"\\r\" or \"\\n\".");
         
     | 
| 
      
 906 
     | 
    
         
            +
                                indent_count = static_cast<unsigned int>(vlen);
         
     | 
| 
      
 907 
     | 
    
         
            +
                            }
         
     | 
| 
      
 908 
     | 
    
         
            +
                        }
         
     | 
| 
      
 909 
     | 
    
         
            +
                    }
         
     | 
| 
      
 910 
     | 
    
         
            +
             
     | 
| 
      
 911 
     | 
    
         
            +
                    if (RTEST(v_single_line_array))
         
     | 
| 
      
 912 
     | 
    
         
            +
                        writer.SetFormatOptions(rapidjson::kFormatSingleLineArray);
         
     | 
| 
      
 913 
     | 
    
         
            +
                }
         
     | 
| 
      
 914 
     | 
    
         
            +
                writer.SetIndent(indent_char, indent_count);
         
     | 
| 
      
 915 
     | 
    
         
            +
             
     | 
| 
      
 916 
     | 
    
         
            +
                write(writer, value);
         
     | 
| 
      
 917 
     | 
    
         
            +
                return new_utf8_str(buf.GetString(), buf.GetSize());
         
     | 
| 
      
 918 
     | 
    
         
            +
            }
         
     | 
| 
      
 919 
     | 
    
         
            +
             
     | 
| 
      
 920 
     | 
    
         
            +
             
     | 
| 
      
 921 
     | 
    
         
            +
            extern "C" void Init_usamin(void) {
         
     | 
| 
      
 922 
     | 
    
         
            +
                utf8 = rb_utf8_encoding();
         
     | 
| 
      
 923 
     | 
    
         
            +
                utf8index = rb_enc_to_index(utf8);
         
     | 
| 
      
 924 
     | 
    
         
            +
                utf8value = rb_enc_from_encoding(utf8);
         
     | 
| 
      
 925 
     | 
    
         
            +
                sym_fast = rb_id2sym(rb_intern("fast"));
         
     | 
| 
      
 926 
     | 
    
         
            +
                sym_indent = rb_id2sym(rb_intern("indent"));
         
     | 
| 
      
 927 
     | 
    
         
            +
                sym_single_line_array = rb_id2sym(rb_intern("single_line_array"));
         
     | 
| 
      
 928 
     | 
    
         
            +
                id_to_s = rb_intern("to_s");
         
     | 
| 
      
 929 
     | 
    
         
            +
             
     | 
| 
      
 930 
     | 
    
         
            +
                VALUE rb_mUsamin = rb_define_module("Usamin");
         
     | 
| 
      
 931 
     | 
    
         
            +
                rb_define_module_function(rb_mUsamin, "load", RUBY_METHOD_FUNC(w_load), -1);
         
     | 
| 
      
 932 
     | 
    
         
            +
                rb_define_module_function(rb_mUsamin, "parse", RUBY_METHOD_FUNC(w_parse), -1);
         
     | 
| 
      
 933 
     | 
    
         
            +
                rb_define_module_function(rb_mUsamin, "generate", RUBY_METHOD_FUNC(w_generate), 1);
         
     | 
| 
      
 934 
     | 
    
         
            +
                rb_define_module_function(rb_mUsamin, "pretty_generate", RUBY_METHOD_FUNC(w_pretty_generate), -1);
         
     | 
| 
      
 935 
     | 
    
         
            +
             
     | 
| 
      
 936 
     | 
    
         
            +
                rb_cUsaminValue = rb_define_class_under(rb_mUsamin, "Value", rb_cObject);
         
     | 
| 
      
 937 
     | 
    
         
            +
                rb_define_alloc_func(rb_cUsaminValue, usamin_alloc);
         
     | 
| 
      
 938 
     | 
    
         
            +
                rb_undef_method(rb_cUsaminValue, "initialize");
         
     | 
| 
      
 939 
     | 
    
         
            +
                rb_define_method(rb_cUsaminValue, "array?", RUBY_METHOD_FUNC(w_value_isarray), 0);
         
     | 
| 
      
 940 
     | 
    
         
            +
                rb_define_method(rb_cUsaminValue, "hash?", RUBY_METHOD_FUNC(w_value_isobject), 0);
         
     | 
| 
      
 941 
     | 
    
         
            +
                rb_define_method(rb_cUsaminValue, "object?", RUBY_METHOD_FUNC(w_value_isobject), 0);
         
     | 
| 
      
 942 
     | 
    
         
            +
                rb_define_method(rb_cUsaminValue, "eval", RUBY_METHOD_FUNC(w_value_eval), 0);
         
     | 
| 
      
 943 
     | 
    
         
            +
                rb_define_method(rb_cUsaminValue, "eval_r", RUBY_METHOD_FUNC(w_value_eval_r), 0);
         
     | 
| 
      
 944 
     | 
    
         
            +
                rb_define_method(rb_cUsaminValue, "frozen?", RUBY_METHOD_FUNC(w_value_isfrozen), 0);
         
     | 
| 
      
 945 
     | 
    
         
            +
                rb_define_method(rb_cUsaminValue, "marshal_dump", RUBY_METHOD_FUNC(w_value_marshal_dump), 0);
         
     | 
| 
      
 946 
     | 
    
         
            +
                rb_define_method(rb_cUsaminValue, "marshal_load", RUBY_METHOD_FUNC(w_value_marshal_load), 1);
         
     | 
| 
      
 947 
     | 
    
         
            +
             
     | 
| 
      
 948 
     | 
    
         
            +
                rb_cUsaminHash = rb_define_class_under(rb_mUsamin, "Hash", rb_cUsaminValue);
         
     | 
| 
      
 949 
     | 
    
         
            +
                rb_include_module(rb_cUsaminHash, rb_mEnumerable);
         
     | 
| 
      
 950 
     | 
    
         
            +
                rb_define_alloc_func(rb_cUsaminHash, usamin_alloc);
         
     | 
| 
      
 951 
     | 
    
         
            +
                rb_undef_method(rb_cUsaminHash, "initialize");
         
     | 
| 
      
 952 
     | 
    
         
            +
                rb_define_method(rb_cUsaminHash, "[]", RUBY_METHOD_FUNC(w_hash_operator_indexer), 1);
         
     | 
| 
      
 953 
     | 
    
         
            +
                rb_define_method(rb_cUsaminHash, "each", RUBY_METHOD_FUNC(w_hash_each), 0);
         
     | 
| 
      
 954 
     | 
    
         
            +
                rb_define_method(rb_cUsaminHash, "each_pair", RUBY_METHOD_FUNC(w_hash_each), 0);
         
     | 
| 
      
 955 
     | 
    
         
            +
                rb_define_method(rb_cUsaminHash, "each_key", RUBY_METHOD_FUNC(w_hash_each_key), 0);
         
     | 
| 
      
 956 
     | 
    
         
            +
                rb_define_method(rb_cUsaminHash, "each_value", RUBY_METHOD_FUNC(w_hash_each_value), 0);
         
     | 
| 
      
 957 
     | 
    
         
            +
                rb_define_method(rb_cUsaminHash, "empty?", RUBY_METHOD_FUNC(w_hash_isempty), 0);
         
     | 
| 
      
 958 
     | 
    
         
            +
                rb_define_method(rb_cUsaminHash, "has_key?", RUBY_METHOD_FUNC(w_hash_haskey), 1);
         
     | 
| 
      
 959 
     | 
    
         
            +
                rb_define_method(rb_cUsaminHash, "include?", RUBY_METHOD_FUNC(w_hash_haskey), 1);
         
     | 
| 
      
 960 
     | 
    
         
            +
                rb_define_method(rb_cUsaminHash, "key?", RUBY_METHOD_FUNC(w_hash_haskey), 1);
         
     | 
| 
      
 961 
     | 
    
         
            +
                rb_define_method(rb_cUsaminHash, "member?", RUBY_METHOD_FUNC(w_hash_haskey), 1);
         
     | 
| 
      
 962 
     | 
    
         
            +
                rb_define_method(rb_cUsaminHash, "keys", RUBY_METHOD_FUNC(w_hash_keys), 0);
         
     | 
| 
      
 963 
     | 
    
         
            +
                rb_define_method(rb_cUsaminHash, "length", RUBY_METHOD_FUNC(w_hash_length), 0);
         
     | 
| 
      
 964 
     | 
    
         
            +
                rb_define_method(rb_cUsaminHash, "size", RUBY_METHOD_FUNC(w_hash_length), 0);
         
     | 
| 
      
 965 
     | 
    
         
            +
                rb_define_method(rb_cUsaminHash, "to_h", RUBY_METHOD_FUNC(w_hash_eval), 0);
         
     | 
| 
      
 966 
     | 
    
         
            +
                rb_define_method(rb_cUsaminHash, "to_hash", RUBY_METHOD_FUNC(w_hash_eval), 0);
         
     | 
| 
      
 967 
     | 
    
         
            +
                rb_define_method(rb_cUsaminHash, "values", RUBY_METHOD_FUNC(w_hash_values), 0);
         
     | 
| 
      
 968 
     | 
    
         
            +
             
     | 
| 
      
 969 
     | 
    
         
            +
                rb_cUsaminArray = rb_define_class_under(rb_mUsamin, "Array", rb_cUsaminValue);
         
     | 
| 
      
 970 
     | 
    
         
            +
                rb_include_module(rb_cUsaminArray, rb_mEnumerable);
         
     | 
| 
      
 971 
     | 
    
         
            +
                rb_define_alloc_func(rb_cUsaminArray, usamin_alloc);
         
     | 
| 
      
 972 
     | 
    
         
            +
                rb_undef_method(rb_cUsaminArray, "initialize");
         
     | 
| 
      
 973 
     | 
    
         
            +
                rb_define_method(rb_cUsaminArray, "[]", RUBY_METHOD_FUNC(w_array_operator_indexer), -1);
         
     | 
| 
      
 974 
     | 
    
         
            +
                rb_define_method(rb_cUsaminArray, "each", RUBY_METHOD_FUNC(w_array_each), 0);
         
     | 
| 
      
 975 
     | 
    
         
            +
                rb_define_method(rb_cUsaminArray, "each_index", RUBY_METHOD_FUNC(w_array_each_index), 0);
         
     | 
| 
      
 976 
     | 
    
         
            +
                rb_define_method(rb_cUsaminArray, "empty?", RUBY_METHOD_FUNC(w_array_isempty), 0);
         
     | 
| 
      
 977 
     | 
    
         
            +
                rb_define_method(rb_cUsaminArray, "index", RUBY_METHOD_FUNC(w_array_index), -1);
         
     | 
| 
      
 978 
     | 
    
         
            +
                rb_define_method(rb_cUsaminArray, "find_index", RUBY_METHOD_FUNC(w_array_index), -1);
         
     | 
| 
      
 979 
     | 
    
         
            +
                rb_define_method(rb_cUsaminArray, "first", RUBY_METHOD_FUNC(w_array_first), -1);
         
     | 
| 
      
 980 
     | 
    
         
            +
                rb_define_method(rb_cUsaminArray, "length", RUBY_METHOD_FUNC(w_array_length), 0);
         
     | 
| 
      
 981 
     | 
    
         
            +
                rb_define_method(rb_cUsaminArray, "size", RUBY_METHOD_FUNC(w_array_length), 0);
         
     | 
| 
      
 982 
     | 
    
         
            +
                rb_define_method(rb_cUsaminArray, "to_a", RUBY_METHOD_FUNC(w_array_eval), 0);
         
     | 
| 
      
 983 
     | 
    
         
            +
                rb_define_method(rb_cUsaminArray, "to_ary", RUBY_METHOD_FUNC(w_array_eval), 0);
         
     | 
| 
      
 984 
     | 
    
         
            +
             
     | 
| 
      
 985 
     | 
    
         
            +
                rb_eUsaminError = rb_define_class_under(rb_mUsamin, "UsaminError", rb_eStandardError);
         
     | 
| 
      
 986 
     | 
    
         
            +
                rb_eParserError = rb_define_class_under(rb_mUsamin, "ParserError", rb_eUsaminError);
         
     | 
| 
      
 987 
     | 
    
         
            +
            }
         
     |