├── test ├── okjson │ ├── t │ │ ├── err-root.rb │ │ ├── encode-int.rb │ │ ├── err-key.rb │ │ ├── err-other.rb │ │ ├── err-symbol.rb │ │ ├── encode-obj.rb │ │ ├── valid-0.json │ │ ├── valid-0.json.exp │ │ ├── valid-1.json │ │ ├── valid-1.json.exp │ │ ├── encode-int.rb.exp │ │ ├── encode-obj.rb.exp │ │ ├── invalid4.json │ │ ├── invalid8.json │ │ ├── valid-array-empty.json │ │ ├── valid-false.json │ │ ├── valid-null.json │ │ ├── valid-quote.json │ │ ├── valid-slash.json │ │ ├── valid-space.json │ │ ├── valid-true.json │ │ ├── encode-badutf8.rb.exp │ │ ├── encode-utf8.rb │ │ ├── encode-utf8.rb.exp │ │ ├── err-naninf.rb │ │ ├── invalid2.json │ │ ├── invalid23.json │ │ ├── invalid24.json │ │ ├── valid-array-empty.json.exp │ │ ├── valid-array-single.json │ │ ├── valid-backslash.json │ │ ├── valid-false.json.exp │ │ ├── valid-frac.json │ │ ├── valid-hex.json.exp │ │ ├── valid-null.json.exp │ │ ├── valid-object-empty.json │ │ ├── valid-object-empty.json.exp │ │ ├── valid-quote.json.exp │ │ ├── valid-slash.json.exp │ │ ├── valid-space.json.exp │ │ ├── valid-true.json.exp │ │ ├── decode-bignum-e.json.exp │ │ ├── encode-badutf8.rb │ │ ├── invalid-key.json │ │ ├── invalid19.json │ │ ├── invalid20.json │ │ ├── invalid5.json │ │ ├── invalid6.json │ │ ├── invalid7.json │ │ ├── invalid9.json │ │ ├── valid-array-single.json.exp │ │ ├── valid-backslash.json.exp │ │ ├── valid-comment2.json │ │ ├── valid-compact.json │ │ ├── valid-escape.json │ │ ├── valid-frac.json.exp │ │ ├── valid-integer.json │ │ ├── valid-integer.json.exp │ │ ├── valid-object-single.json │ │ ├── decode-bignum-e.json │ │ ├── decode-invalid27.json │ │ ├── decode-invalid28.json │ │ ├── invalid11.json │ │ ├── valid-comment.json │ │ ├── valid-comment.json.exp │ │ ├── valid-comment2.json.exp │ │ ├── valid-compact.json.exp │ │ ├── valid-escape.json.exp │ │ ├── valid-frac-E-plus.json │ │ ├── valid-object-single.json.exp │ │ ├── valid-url.json │ │ ├── decode-invalid27.json.exp │ │ ├── decode-invalid28.json.exp │ │ ├── invalid12.json │ │ ├── invalid14.json │ │ ├── invalid21.json │ │ ├── invalid22.json │ │ ├── valid-frac-E-minus.json │ │ ├── valid-frac-E-minus.json.exp │ │ ├── valid-frac-E-plus.json.exp │ │ ├── valid-url.json.exp │ │ ├── decode-invalid16.json │ │ ├── decode-invalid25.json │ │ ├── invalid3.json │ │ ├── decode-invalid15.json │ │ ├── decode-invalid17.json │ │ ├── decode-invalid26.json │ │ ├── invalid13.json │ │ ├── valid-hex.json │ │ ├── valid-punc.json │ │ ├── valid-punc.json.exp │ │ ├── valid-quotes.json │ │ ├── valid-quotes.json.exp │ │ ├── valid-spaced.json.exp │ │ ├── decode-invalid15.json.exp │ │ ├── decode-invalid16.json.exp │ │ ├── decode-invalid17.json.exp │ │ ├── decode-invalid25.json.exp │ │ ├── decode-invalid26.json.exp │ │ ├── valid-spaced2.json.exp │ │ ├── invalid1.json │ │ ├── invalid10.json │ │ ├── invalid-uescape.json │ │ ├── valid-array-deep.json │ │ ├── valid-json.json │ │ ├── valid-array-deep.json.exp │ │ ├── valid-json.json.exp │ │ ├── valid-alnum.json │ │ ├── valid-alnum.json.exp │ │ ├── valid-key.json.exp │ │ ├── valid-spaced.json │ │ ├── valid-key.json │ │ ├── valid-spaced2.json │ │ ├── decode-bignum.json │ │ ├── encode-bignum.json │ │ ├── decode-bignum.json.exp │ │ └── encode-bignum.json.exp │ └── README.markdown ├── test_okjson.rb ├── test_decoder.rb └── test_encoder.rb ├── .rbenv-version ├── .gitignore ├── lib ├── gson-2.2.2.jar ├── gson │ └── version.rb └── gson.rb ├── Gemfile ├── benchmark ├── subjects │ ├── item.json │ ├── twitter_search.json │ ├── unicode.json │ └── ohai.json ├── profile.rb ├── README.markdown └── benchmark.rb ├── Rakefile ├── tasks ├── util.rake ├── test.rake └── compile.rake ├── gson.gemspec ├── ext └── gson_ext │ ├── GsonExtService.java │ ├── Encoder.java │ └── Decoder.java ├── README.md └── LICENSE /test/okjson/t/err-root.rb: -------------------------------------------------------------------------------- 1 | "a" -------------------------------------------------------------------------------- /.rbenv-version: -------------------------------------------------------------------------------- 1 | jruby-1.7.0 2 | -------------------------------------------------------------------------------- /test/okjson/t/encode-int.rb: -------------------------------------------------------------------------------- 1 | [123] -------------------------------------------------------------------------------- /test/okjson/t/err-key.rb: -------------------------------------------------------------------------------- 1 | {1 => 1} -------------------------------------------------------------------------------- /test/okjson/t/err-other.rb: -------------------------------------------------------------------------------- 1 | [//] -------------------------------------------------------------------------------- /test/okjson/t/err-symbol.rb: -------------------------------------------------------------------------------- 1 | [:s] -------------------------------------------------------------------------------- /test/okjson/t/encode-obj.rb: -------------------------------------------------------------------------------- 1 | {"a" => 1} -------------------------------------------------------------------------------- /test/okjson/t/valid-0.json: -------------------------------------------------------------------------------- 1 | [0] 2 | -------------------------------------------------------------------------------- /test/okjson/t/valid-0.json.exp: -------------------------------------------------------------------------------- 1 | [0] 2 | -------------------------------------------------------------------------------- /test/okjson/t/valid-1.json: -------------------------------------------------------------------------------- 1 | [1] 2 | -------------------------------------------------------------------------------- /test/okjson/t/valid-1.json.exp: -------------------------------------------------------------------------------- 1 | [1] 2 | -------------------------------------------------------------------------------- /test/okjson/t/encode-int.rb.exp: -------------------------------------------------------------------------------- 1 | [123] 2 | -------------------------------------------------------------------------------- /test/okjson/t/encode-obj.rb.exp: -------------------------------------------------------------------------------- 1 | {"a":1} 2 | -------------------------------------------------------------------------------- /test/okjson/t/invalid4.json: -------------------------------------------------------------------------------- 1 | ["extra comma",] -------------------------------------------------------------------------------- /test/okjson/t/invalid8.json: -------------------------------------------------------------------------------- 1 | ["Extra close"]] -------------------------------------------------------------------------------- /test/okjson/t/valid-array-empty.json: -------------------------------------------------------------------------------- 1 | [] 2 | -------------------------------------------------------------------------------- /test/okjson/t/valid-false.json: -------------------------------------------------------------------------------- 1 | [false] 2 | -------------------------------------------------------------------------------- /test/okjson/t/valid-null.json: -------------------------------------------------------------------------------- 1 | [null] 2 | -------------------------------------------------------------------------------- /test/okjson/t/valid-quote.json: -------------------------------------------------------------------------------- 1 | ["\""] 2 | -------------------------------------------------------------------------------- /test/okjson/t/valid-slash.json: -------------------------------------------------------------------------------- 1 | ["\/"] 2 | -------------------------------------------------------------------------------- /test/okjson/t/valid-space.json: -------------------------------------------------------------------------------- 1 | [" "] 2 | -------------------------------------------------------------------------------- /test/okjson/t/valid-true.json: -------------------------------------------------------------------------------- 1 | [true] 2 | -------------------------------------------------------------------------------- /test/okjson/t/encode-badutf8.rb.exp: -------------------------------------------------------------------------------- 1 | ["���"] 2 | -------------------------------------------------------------------------------- /test/okjson/t/encode-utf8.rb: -------------------------------------------------------------------------------- 1 | ["á$¢€園𝄞"] 2 | -------------------------------------------------------------------------------- /test/okjson/t/encode-utf8.rb.exp: -------------------------------------------------------------------------------- 1 | ["á$¢€園𝄞"] 2 | -------------------------------------------------------------------------------- /test/okjson/t/err-naninf.rb: -------------------------------------------------------------------------------- 1 | [1.0/0,0.0/0,-1.0/0] -------------------------------------------------------------------------------- /test/okjson/t/invalid2.json: -------------------------------------------------------------------------------- 1 | ["Unclosed array" -------------------------------------------------------------------------------- /test/okjson/t/invalid23.json: -------------------------------------------------------------------------------- 1 | ["Bad value", truth] -------------------------------------------------------------------------------- /test/okjson/t/invalid24.json: -------------------------------------------------------------------------------- 1 | ['single quote'] -------------------------------------------------------------------------------- /test/okjson/t/valid-array-empty.json.exp: -------------------------------------------------------------------------------- 1 | [] 2 | -------------------------------------------------------------------------------- /test/okjson/t/valid-array-single.json: -------------------------------------------------------------------------------- 1 | ["a"] 2 | -------------------------------------------------------------------------------- /test/okjson/t/valid-backslash.json: -------------------------------------------------------------------------------- 1 | ["\\"] 2 | -------------------------------------------------------------------------------- /test/okjson/t/valid-false.json.exp: -------------------------------------------------------------------------------- 1 | [false] 2 | -------------------------------------------------------------------------------- /test/okjson/t/valid-frac.json: -------------------------------------------------------------------------------- 1 | [-9876.543210] 2 | -------------------------------------------------------------------------------- /test/okjson/t/valid-hex.json.exp: -------------------------------------------------------------------------------- 1 | ["$¢€園𝄞"] 2 | -------------------------------------------------------------------------------- /test/okjson/t/valid-null.json.exp: -------------------------------------------------------------------------------- 1 | [null] 2 | -------------------------------------------------------------------------------- /test/okjson/t/valid-object-empty.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /test/okjson/t/valid-object-empty.json.exp: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /test/okjson/t/valid-quote.json.exp: -------------------------------------------------------------------------------- 1 | ["\""] 2 | -------------------------------------------------------------------------------- /test/okjson/t/valid-slash.json.exp: -------------------------------------------------------------------------------- 1 | ["/"] 2 | -------------------------------------------------------------------------------- /test/okjson/t/valid-space.json.exp: -------------------------------------------------------------------------------- 1 | [" "] 2 | -------------------------------------------------------------------------------- /test/okjson/t/valid-true.json.exp: -------------------------------------------------------------------------------- 1 | [true] 2 | -------------------------------------------------------------------------------- /test/okjson/t/decode-bignum-e.json.exp: -------------------------------------------------------------------------------- 1 | [Infinity] 2 | -------------------------------------------------------------------------------- /test/okjson/t/encode-badutf8.rb: -------------------------------------------------------------------------------- 1 | ["\x82\xAC\xEF"] 2 | -------------------------------------------------------------------------------- /test/okjson/t/invalid-key.json: -------------------------------------------------------------------------------- 1 | {3: "invalid key"} 2 | -------------------------------------------------------------------------------- /test/okjson/t/invalid19.json: -------------------------------------------------------------------------------- 1 | {"Missing colon" null} -------------------------------------------------------------------------------- /test/okjson/t/invalid20.json: -------------------------------------------------------------------------------- 1 | {"Double colon":: null} -------------------------------------------------------------------------------- /test/okjson/t/invalid5.json: -------------------------------------------------------------------------------- 1 | ["double extra comma",,] -------------------------------------------------------------------------------- /test/okjson/t/invalid6.json: -------------------------------------------------------------------------------- 1 | [ , "<-- missing value"] -------------------------------------------------------------------------------- /test/okjson/t/invalid7.json: -------------------------------------------------------------------------------- 1 | ["Comma after the close"], -------------------------------------------------------------------------------- /test/okjson/t/invalid9.json: -------------------------------------------------------------------------------- 1 | {"Extra comma": true,} -------------------------------------------------------------------------------- /test/okjson/t/valid-array-single.json.exp: -------------------------------------------------------------------------------- 1 | ["a"] 2 | -------------------------------------------------------------------------------- /test/okjson/t/valid-backslash.json.exp: -------------------------------------------------------------------------------- 1 | ["\\"] 2 | -------------------------------------------------------------------------------- /test/okjson/t/valid-comment2.json: -------------------------------------------------------------------------------- 1 | ["# -- --> */"] 2 | -------------------------------------------------------------------------------- /test/okjson/t/valid-compact.json: -------------------------------------------------------------------------------- 1 | [1,2,3,4,5,6,7] 2 | -------------------------------------------------------------------------------- /test/okjson/t/valid-escape.json: -------------------------------------------------------------------------------- 1 | ["\b\f\n\r\t"] 2 | -------------------------------------------------------------------------------- /test/okjson/t/valid-frac.json.exp: -------------------------------------------------------------------------------- 1 | [-9876.54321] 2 | -------------------------------------------------------------------------------- /test/okjson/t/valid-integer.json: -------------------------------------------------------------------------------- 1 | [1234567890] 2 | -------------------------------------------------------------------------------- /test/okjson/t/valid-integer.json.exp: -------------------------------------------------------------------------------- 1 | [1234567890] 2 | -------------------------------------------------------------------------------- /test/okjson/t/valid-object-single.json: -------------------------------------------------------------------------------- 1 | {"a":"b"} 2 | -------------------------------------------------------------------------------- /test/okjson/t/decode-bignum-e.json: -------------------------------------------------------------------------------- 1 | [23456789012E666] 2 | -------------------------------------------------------------------------------- /test/okjson/t/decode-invalid27.json: -------------------------------------------------------------------------------- 1 | ["line 2 | break"] 3 | -------------------------------------------------------------------------------- /test/okjson/t/decode-invalid28.json: -------------------------------------------------------------------------------- 1 | ["line\ 2 | break"] -------------------------------------------------------------------------------- /test/okjson/t/invalid11.json: -------------------------------------------------------------------------------- 1 | {"Illegal expression": 1 + 2} -------------------------------------------------------------------------------- /test/okjson/t/valid-comment.json: -------------------------------------------------------------------------------- 1 | ["// /* */"] 2 | -------------------------------------------------------------------------------- /test/okjson/t/valid-compact.json.exp: -------------------------------------------------------------------------------- 1 | [1,2,3,4,5,6,7] 2 | -------------------------------------------------------------------------------- /test/okjson/t/valid-escape.json.exp: -------------------------------------------------------------------------------- 1 | ["\b\f\n\r\t"] 2 | -------------------------------------------------------------------------------- /test/okjson/t/valid-frac-E-plus.json: -------------------------------------------------------------------------------- 1 | [1.23456789E34] 2 | -------------------------------------------------------------------------------- /test/okjson/t/valid-object-single.json.exp: -------------------------------------------------------------------------------- 1 | {"a":"b"} 2 | -------------------------------------------------------------------------------- /test/okjson/t/valid-url.json: -------------------------------------------------------------------------------- 1 | ["http://www.JSON.org/"] 2 | -------------------------------------------------------------------------------- /test/okjson/t/decode-invalid27.json.exp: -------------------------------------------------------------------------------- 1 | ["line\nbreak"] 2 | -------------------------------------------------------------------------------- /test/okjson/t/decode-invalid28.json.exp: -------------------------------------------------------------------------------- 1 | ["line\nbreak"] 2 | -------------------------------------------------------------------------------- /test/okjson/t/invalid12.json: -------------------------------------------------------------------------------- 1 | {"Illegal invocation": alert()} -------------------------------------------------------------------------------- /test/okjson/t/invalid14.json: -------------------------------------------------------------------------------- 1 | {"Numbers cannot be hex": 0x14} -------------------------------------------------------------------------------- /test/okjson/t/invalid21.json: -------------------------------------------------------------------------------- 1 | {"Comma instead of colon", null} -------------------------------------------------------------------------------- /test/okjson/t/invalid22.json: -------------------------------------------------------------------------------- 1 | ["Colon instead of comma": false] -------------------------------------------------------------------------------- /test/okjson/t/valid-frac-E-minus.json: -------------------------------------------------------------------------------- 1 | [0.123456789E-12] 2 | -------------------------------------------------------------------------------- /test/okjson/t/valid-frac-E-minus.json.exp: -------------------------------------------------------------------------------- 1 | [1.23456789E-13] 2 | -------------------------------------------------------------------------------- /test/okjson/t/valid-frac-E-plus.json.exp: -------------------------------------------------------------------------------- 1 | [1.23456789E34] 2 | -------------------------------------------------------------------------------- /test/okjson/t/valid-url.json.exp: -------------------------------------------------------------------------------- 1 | ["http://www.JSON.org/"] 2 | -------------------------------------------------------------------------------- /test/okjson/t/decode-invalid16.json: -------------------------------------------------------------------------------- 1 | ["Illegal backslash escape: \'"] -------------------------------------------------------------------------------- /test/okjson/t/decode-invalid25.json: -------------------------------------------------------------------------------- 1 | ["tab character in string "] 2 | -------------------------------------------------------------------------------- /test/okjson/t/invalid3.json: -------------------------------------------------------------------------------- 1 | {unquoted_key: "keys must be quoted"} -------------------------------------------------------------------------------- /test/okjson/t/decode-invalid15.json: -------------------------------------------------------------------------------- 1 | ["Illegal backslash escape: \x15"] -------------------------------------------------------------------------------- /test/okjson/t/decode-invalid17.json: -------------------------------------------------------------------------------- 1 | ["Illegal backslash escape: \017"] -------------------------------------------------------------------------------- /test/okjson/t/decode-invalid26.json: -------------------------------------------------------------------------------- 1 | ["tab\ character\ in\ string\ "] 2 | -------------------------------------------------------------------------------- /test/okjson/t/invalid13.json: -------------------------------------------------------------------------------- 1 | {"Numbers cannot have leading zeroes": 013} -------------------------------------------------------------------------------- /test/okjson/t/valid-hex.json: -------------------------------------------------------------------------------- 1 | ["\u0024\u00a2\u20ac\u5712\uD834\uDD1E"] 2 | -------------------------------------------------------------------------------- /test/okjson/t/valid-punc.json: -------------------------------------------------------------------------------- 1 | ["`1~!@#$%^&*()_+-={':[,]}|;.?"] 2 | -------------------------------------------------------------------------------- /test/okjson/t/valid-punc.json.exp: -------------------------------------------------------------------------------- 1 | ["`1~!@#$%^&*()_+-={':[,]}|;.?"] 2 | -------------------------------------------------------------------------------- /test/okjson/t/valid-quotes.json: -------------------------------------------------------------------------------- 1 | ["" \u0022 %22 0x22 034 ""] 2 | -------------------------------------------------------------------------------- /test/okjson/t/valid-quotes.json.exp: -------------------------------------------------------------------------------- 1 | ["" \" %22 0x22 034 ""] 2 | -------------------------------------------------------------------------------- /test/okjson/t/valid-spaced.json.exp: -------------------------------------------------------------------------------- 1 | {" s p a c e d ":[1,2,3,4,5,6,7]} 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | Gemfile.lock 3 | lib/gson_ext.jar 4 | pkg 5 | tmp 6 | -------------------------------------------------------------------------------- /test/okjson/t/decode-invalid15.json.exp: -------------------------------------------------------------------------------- 1 | ["Illegal backslash escape: x15"] 2 | -------------------------------------------------------------------------------- /test/okjson/t/decode-invalid16.json.exp: -------------------------------------------------------------------------------- 1 | ["Illegal backslash escape: '"] 2 | -------------------------------------------------------------------------------- /test/okjson/t/decode-invalid17.json.exp: -------------------------------------------------------------------------------- 1 | ["Illegal backslash escape: 017"] 2 | -------------------------------------------------------------------------------- /test/okjson/t/decode-invalid25.json.exp: -------------------------------------------------------------------------------- 1 | ["tab\tcharacter\tin\tstring\t"] 2 | -------------------------------------------------------------------------------- /test/okjson/t/decode-invalid26.json.exp: -------------------------------------------------------------------------------- 1 | ["tab\tcharacter\tin\tstring\t"] 2 | -------------------------------------------------------------------------------- /test/okjson/t/valid-spaced2.json.exp: -------------------------------------------------------------------------------- 1 | [{"a":"b"},0.5,98.6,99.44,1066,"rosebud"] 2 | -------------------------------------------------------------------------------- /lib/gson-2.2.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sferik/gson.rb/master/lib/gson-2.2.2.jar -------------------------------------------------------------------------------- /test/okjson/t/invalid1.json: -------------------------------------------------------------------------------- 1 | "A JSON payload should be an object or array, not a string." -------------------------------------------------------------------------------- /test/okjson/t/invalid10.json: -------------------------------------------------------------------------------- 1 | {"Extra value after close": true} "misplaced quoted value" -------------------------------------------------------------------------------- /test/okjson/t/invalid-uescape.json: -------------------------------------------------------------------------------- 1 | ["\u", "\u1", "\u01", "\u001", "\u0001", "\uxxxx"] 2 | -------------------------------------------------------------------------------- /test/okjson/t/valid-array-deep.json: -------------------------------------------------------------------------------- 1 | [[[[[[[[[[[[[[[[[[["Not too deep"]]]]]]]]]]]]]]]]]]] 2 | -------------------------------------------------------------------------------- /test/okjson/t/valid-json.json: -------------------------------------------------------------------------------- 1 | ["{\"object with 1 member\":[\"array with 1 element\"]}"] 2 | -------------------------------------------------------------------------------- /test/okjson/t/valid-array-deep.json.exp: -------------------------------------------------------------------------------- 1 | [[[[[[[[[[[[[[[[[[["Not too deep"]]]]]]]]]]]]]]]]]]] 2 | -------------------------------------------------------------------------------- /test/okjson/t/valid-json.json.exp: -------------------------------------------------------------------------------- 1 | ["{\"object with 1 member\":[\"array with 1 element\"]}"] 2 | -------------------------------------------------------------------------------- /test/okjson/t/valid-alnum.json: -------------------------------------------------------------------------------- 1 | ["abcdefghijklmnopqrstuvwyzABCDEFGHIJKLMNOPQRSTUVWYZ0123456789"] 2 | -------------------------------------------------------------------------------- /test/okjson/t/valid-alnum.json.exp: -------------------------------------------------------------------------------- 1 | ["abcdefghijklmnopqrstuvwyzABCDEFGHIJKLMNOPQRSTUVWYZ0123456789"] 2 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # Specify your gem's dependencies in gson.gemspec 4 | gemspec 5 | -------------------------------------------------------------------------------- /test/okjson/t/valid-key.json.exp: -------------------------------------------------------------------------------- 1 | {"/\\\"쫾몾ꮘﳞ볚\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',./<>?":"A key can be any string"} 2 | -------------------------------------------------------------------------------- /test/okjson/t/valid-spaced.json: -------------------------------------------------------------------------------- 1 | {" s p a c e d " :[1,2 , 3 2 | 3 | , 4 | 5 | 4 , 5 , 6 ,7 ]} 6 | -------------------------------------------------------------------------------- /test/okjson/t/valid-key.json: -------------------------------------------------------------------------------- 1 | {"\/\\\"\uCAFE\uBABE\uAB98\uFCDE\ubcda\uef4A\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',./<>?":"A key can be any string"} 2 | -------------------------------------------------------------------------------- /test/okjson/t/valid-spaced2.json: -------------------------------------------------------------------------------- 1 | [{"a" 2 | :"b"} 3 | 4 | , 5 | 0.5 ,98.6 6 | , 7 | 99.44 8 | , 9 | 10 | 1066 11 | 12 | 13 | ,"rosebud"] 14 | -------------------------------------------------------------------------------- /benchmark/subjects/item.json: -------------------------------------------------------------------------------- 1 | {"item": {"name": "generated", "cached_tag_list": "", "updated_at": "2009-03-24T05:25:09Z", "updated_by_id": null, "price": 1.99, "delta": false, "cost": 0.597, "account_id": 16, "unit": null, "import_tag": null, "taxable": true, "id": 1, "created_by_id": null, "description": null, "company_id": 0, "sku": "06317-0306", "created_at": "2009-03-24T05:25:09Z", "active": true}} -------------------------------------------------------------------------------- /test/okjson/t/decode-bignum.json: -------------------------------------------------------------------------------- 1 | [23456789012000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000] 2 | -------------------------------------------------------------------------------- /test/okjson/t/encode-bignum.json: -------------------------------------------------------------------------------- 1 | [23456789012000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000] 2 | -------------------------------------------------------------------------------- /test/okjson/t/decode-bignum.json.exp: -------------------------------------------------------------------------------- 1 | [23456789012000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000] 2 | -------------------------------------------------------------------------------- /test/okjson/t/encode-bignum.json.exp: -------------------------------------------------------------------------------- 1 | [23456789012000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000] 2 | -------------------------------------------------------------------------------- /lib/gson/version.rb: -------------------------------------------------------------------------------- 1 | # Author:: Couchbase 2 | # Copyright:: 2012 Couchbase, Inc. 3 | # License:: Apache License, Version 2.0 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | module Gson 19 | VERSION = "0.6.1" 20 | end 21 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # Author:: Couchbase 2 | # Copyright:: 2012 Couchbase, Inc. 3 | # License:: Apache License, Version 2.0 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | require "bundler/gem_tasks" 19 | 20 | Dir['tasks/*.rake'].sort.each { |f| load f } 21 | 22 | task :default => :compile 23 | -------------------------------------------------------------------------------- /tasks/util.rake: -------------------------------------------------------------------------------- 1 | # Author:: Couchbase 2 | # Copyright:: 2012 Couchbase, Inc. 3 | # License:: Apache License, Version 2.0 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | desc 'Start an irb session and load the library.' 19 | task :console => :compile do 20 | exec "irb -I. -Ilib -rgson" 21 | end 22 | -------------------------------------------------------------------------------- /test/okjson/README.markdown: -------------------------------------------------------------------------------- 1 | These tests originated at https://github.com/kr/okjson 2 | 3 | Except following changes: 4 | 5 | * GSON generates floats with uppercase 'E' 6 | * It doesn't renders Bignum's as numbers, it renders Infinity. See 7 | `*bignum*.json` tests 8 | * GSON understands escaping illegal characters like single quote and 9 | silently skip the backslash. Therefore these tests were renamed: 10 | * `invalid15.json` to `decode-invalid15.json{,.exp}` 11 | * `invalid16.json` to `decode-invalid16.json{,.exp}` 12 | * `invalid17.json` to `decode-invalid17.json{,.exp}` 13 | * GSON understands verbatim tabs and line breaks in the JSON string. 14 | Therefore these tests were renamed: 15 | * `invalid25.json` to `decode-invalid25.json{,.exp}` 16 | * `invalid26.json` to `decode-invalid26.json{,.exp}` 17 | * `invalid27.json` to `decode-invalid27.json{,.exp}` 18 | * `invalid28.json` to `decode-invalid28.json{,.exp}` 19 | -------------------------------------------------------------------------------- /tasks/test.rake: -------------------------------------------------------------------------------- 1 | # Author:: Couchbase 2 | # Copyright:: 2012 Couchbase, Inc. 3 | # License:: Apache License, Version 2.0 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | require 'rake/testtask' 19 | Rake::TestTask.new do |test| 20 | test.libs << "test" << "." 21 | test.pattern = 'test/test_*.rb' 22 | test.options = '--verbose' 23 | end 24 | 25 | Rake::Task['test'].prerequisites.unshift(:compile) 26 | -------------------------------------------------------------------------------- /lib/gson.rb: -------------------------------------------------------------------------------- 1 | # Author:: Couchbase 2 | # Copyright:: 2012 Couchbase, Inc. 3 | # License:: Apache License, Version 2.0 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | require 'java' 19 | require "gson/version" 20 | require "gson-2.2.2.jar" 21 | require "gson_ext.jar" 22 | 23 | module Gson 24 | 25 | def self.load(object, options = {}) 26 | Decoder.new(options).decode(string) 27 | end 28 | 29 | def self.dump(string, options = {}) 30 | Encoder.new(options).encode(object) 31 | end 32 | 33 | end 34 | -------------------------------------------------------------------------------- /tasks/compile.rake: -------------------------------------------------------------------------------- 1 | # Author:: Couchbase 2 | # Copyright:: 2012 Couchbase, Inc. 3 | # License:: Apache License, Version 2.0 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | gem 'rake-compiler', '>= 0.7.5' 19 | require "rake/javaextensiontask" 20 | 21 | def gemspec 22 | @clean_gemspec ||= eval(File.read(File.expand_path('../../gson.gemspec', __FILE__))) 23 | end 24 | 25 | Rake::JavaExtensionTask.new('gson_ext', gemspec) do |ext| 26 | ext.classpath = File.expand_path("../../lib/gson-2.2.2.jar", __FILE__) 27 | end 28 | 29 | require 'rubygems/package_task' 30 | Gem::PackageTask.new(gemspec) do |pkg| 31 | pkg.need_tar = true 32 | end 33 | 34 | -------------------------------------------------------------------------------- /benchmark/profile.rb: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/..') 2 | $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../lib') 3 | 4 | require 'gson' 5 | require 'optparse' 6 | 7 | options = { 8 | :times => 1_000, 9 | :file => File.expand_path(File.dirname(__FILE__) + '/subjects/ohai.json'), 10 | :type => :decode 11 | } 12 | 13 | OptionParser.new do |opts| 14 | opts.banner = "Usage: profile.rb [options]" 15 | opts.on("-t", "--type TYPE", [:decode, :encode], "Type of the operation (default: #{options[:type]}") do |v| 16 | options[:verbose] = v 17 | end 18 | opts.on("-n", "--times NUMBER", Integer, "Number of iterations (default: #{options[:times]})") do |v| 19 | options[:times] = v 20 | end 21 | opts.on("-f", "--file FILE", "File to use as JSON source (default: #{options[:file]})") do |v| 22 | options[:file] = v 23 | end 24 | opts.on_tail("-?", "--help", "Show this message") do 25 | puts opts 26 | exit 27 | end 28 | end.parse! 29 | 30 | json = File.read(options[:file]) 31 | hash = Gson::Decoder.new.decode(json) 32 | 33 | case options[:type] 34 | when :decode, "decode" 35 | decoder = Gson::Decoder.new 36 | options[:times].times do 37 | decoder.decode(json) 38 | end 39 | when :encode, "encode" 40 | encoder = Gson::Encoder.new 41 | options[:times].times do 42 | encoder.encode(hash) 43 | end 44 | else 45 | raise "Unknown type: #{options[:type].inspect}" 46 | end 47 | -------------------------------------------------------------------------------- /gson.gemspec: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | # Author:: Couchbase 3 | # Copyright:: 2012 Couchbase, Inc. 4 | # License:: Apache License, Version 2.0 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | lib = File.expand_path('../lib', __FILE__) 20 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) 21 | require 'gson/version' 22 | 23 | Gem::Specification.new do |gem| 24 | gem.name = "gson" 25 | gem.version = Gson::VERSION 26 | gem.author = "Sergey Avseyev" 27 | gem.email = "sergey.avseyev@gmail.com" 28 | gem.description = %q{Ruby wrapper for GSON. https://code.google.com/p/google-gson/} 29 | gem.summary = %q{Ruby wrapper for GSON} 30 | gem.homepage = "https://github.com/avsej/gson.rb" 31 | 32 | gem.files = `git ls-files`.split($/) 33 | gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) } 34 | gem.test_files = gem.files.grep(%r{^(test|spec|features)/}) 35 | gem.require_paths = ["lib"] 36 | 37 | gem.add_development_dependency 'rake-compiler', '>= 0.7.5' 38 | end 39 | -------------------------------------------------------------------------------- /benchmark/README.markdown: -------------------------------------------------------------------------------- 1 | These benchmarks originated at https://github.com/brianmario/yajl-ruby 2 | 3 | Benchmark using (ohai.json) 32444 bytes of JSON data 1000 times 4 | 5 | ## ENCODING JSON 6 | 7 | Rehearsal ---------------------------------------------------------------------- 8 | Gson::Encoder#encode (to a String) 1.410000 0.030000 1.440000 ( 0.872000) 9 | JSON.generate 1.200000 0.000000 1.200000 ( 0.514000) 10 | ------------------------------------------------------------- total: 2.640000sec 11 | 12 | user system total real 13 | Gson::Encoder#encode (to a String) 0.700000 0.010000 0.710000 ( 0.611000) 14 | JSON.generate 0.800000 0.010000 0.810000 ( 0.436000) 15 | 16 | 17 | ## DECODING JSON 18 | 19 | Rehearsal ------------------------------------------------------------------------ 20 | Gson::Decoder#decode (from an IO) 3.130000 0.020000 3.150000 ( 1.823000) 21 | Gson::Decoder#decode (from a String) 1.170000 0.010000 1.180000 ( 1.129000) 22 | JSON.parse 1.580000 0.000000 1.580000 ( 1.332000) 23 | --------------------------------------------------------------- total: 5.910000sec 24 | 25 | user system total real 26 | Gson::Decoder#decode (from an IO) 1.350000 0.000000 1.350000 ( 1.236000) 27 | Gson::Decoder#decode (from a String) 1.120000 0.000000 1.120000 ( 1.101000) 28 | JSON.parse 1.300000 0.000000 1.300000 ( 1.198000) 29 | -------------------------------------------------------------------------------- /test/test_okjson.rb: -------------------------------------------------------------------------------- 1 | require 'minitest/autorun' 2 | require 'gson' 3 | 4 | class TestOkjson < MiniTest::Unit::TestCase 5 | 6 | TEST_DIR = File.expand_path("../okjson/t", __FILE__) 7 | 8 | def test_valid 9 | encoder = Gson::Encoder.new(:lenient => false) 10 | decoder = Gson::Decoder.new(:lenient => false) 11 | files = Dir["#{TEST_DIR}/valid*.json"] 12 | files.each do |file| 13 | there = decoder.decode(File.read(file)) 14 | back = encoder.encode(there) 15 | assert_equal File.read("#{file}.exp").chomp, back, "#{file} failed" 16 | end 17 | end 18 | 19 | def test_encode 20 | encoder = Gson::Encoder.new(:lenient => false) 21 | files = Dir["#{TEST_DIR}/encode*.json"] 22 | files.each do |file| 23 | json = encoder.encode(eval(File.read(file))) 24 | assert_equal File.read("#{file}.exp").chomp, json, "#{file} failed" 25 | end 26 | end 27 | 28 | def test_decode 29 | decoder = Gson::Decoder.new(:lenient => false) 30 | files = Dir["#{TEST_DIR}/decode*.json"] 31 | files.each do |file| 32 | obj = decoder.decode(File.read(file)).inspect 33 | assert_equal File.read("#{file}.exp").chomp, obj, "#{file} failed" 34 | end 35 | end 36 | 37 | def test_decode_error 38 | decoder = Gson::Decoder.new(:lenient => false) 39 | files = Dir["#{TEST_DIR}/invalid*.json"] 40 | files.each do |file| 41 | assert_raises(Gson::DecodeError, "#{file} failed") do 42 | decoder.decode(File.read(file)) 43 | end 44 | end 45 | end 46 | 47 | def test_encode_error 48 | encoder = Gson::Encoder.new(:lenient => false) 49 | files = Dir["#{TEST_DIR}/err*.json"] 50 | files.each do |file| 51 | assert_raises(Gson::EncodeError, "#{file} failed") do 52 | encoder.encode(eval(File.read(file))) 53 | end 54 | end 55 | end 56 | 57 | end 58 | -------------------------------------------------------------------------------- /ext/gson_ext/GsonExtService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Couchbase, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import gson_ext.Decoder; 18 | import gson_ext.Encoder; 19 | import java.io.IOException; 20 | import org.jruby.Ruby; 21 | import org.jruby.RubyClass; 22 | import org.jruby.RubyModule; 23 | import org.jruby.runtime.ObjectAllocator; 24 | import org.jruby.runtime.builtin.IRubyObject; 25 | import org.jruby.runtime.load.BasicLibraryService; 26 | 27 | public class GsonExtService implements BasicLibraryService { 28 | 29 | public boolean basicLoad(final Ruby ruby) throws IOException { 30 | RubyModule gson = ruby.defineModule("Gson"); 31 | 32 | gson.defineClassUnder("Encoder", ruby.getObject(), new ObjectAllocator() { 33 | public IRubyObject allocate(Ruby ruby, RubyClass rubyClass) { 34 | return new Encoder(ruby, rubyClass); 35 | } 36 | }).defineAnnotatedMethods(Encoder.class); 37 | 38 | gson.defineClassUnder("Decoder", ruby.getObject(), new ObjectAllocator() { 39 | public IRubyObject allocate(Ruby ruby, RubyClass rubyClass) { 40 | return new Decoder(ruby, rubyClass); 41 | } 42 | }).defineAnnotatedMethods(Decoder.class); 43 | 44 | RubyClass standardError = ruby.getStandardError(); 45 | gson.defineClassUnder("DecodeError", standardError, standardError.getAllocator()); 46 | gson.defineClassUnder("EncodeError", standardError, standardError.getAllocator()); 47 | 48 | return true; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /benchmark/benchmark.rb: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/..') 2 | $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../lib') 3 | 4 | require 'rubygems' 5 | require 'benchmark' 6 | require 'gson' 7 | require 'optparse' 8 | begin 9 | require 'json' 10 | rescue LoadError 11 | end 12 | 13 | options = { 14 | :times => 1_000, 15 | :file => File.expand_path(File.dirname(__FILE__) + '/subjects/ohai.json'), 16 | :type => :both 17 | } 18 | 19 | OptionParser.new do |opts| 20 | opts.banner = "Usage: benchmark.rb [options]" 21 | opts.on("-t", "--type TYPE", [:decode, :encode, :both], "Type of the operation (default: #{options[:type]}") do |v| 22 | options[:verbose] = v 23 | end 24 | opts.on("-n", "--times NUMBER", Integer, "Number of iterations (default: #{options[:times]})") do |v| 25 | options[:times] = v 26 | end 27 | opts.on("-f", "--file FILE", "File to use as JSON source (default: #{options[:file]})") do |v| 28 | options[:file] = v 29 | end 30 | opts.on_tail("-?", "--help", "Show this message") do 31 | puts opts 32 | exit 33 | end 34 | end.parse! 35 | 36 | options[:json] = File.read(options[:file]) 37 | options[:hash] = Gson::Decoder.new.decode(options[:json]) 38 | options[:json_stream] = File.open(options[:file]) 39 | 40 | def encode(options) 41 | puts "\n## ENCODING JSON" 42 | encoder = Gson::Encoder.new 43 | Benchmark.bmbm do |x| 44 | x.report("Gson::Encoder#encode (to a String)") do 45 | options[:times].times do 46 | encoder.encode(options[:hash]) 47 | end 48 | end 49 | if defined?(JSON) 50 | x.report("JSON.generate") do 51 | options[:times].times do 52 | JSON.generate(options[:hash]) 53 | end 54 | end 55 | end 56 | end 57 | end 58 | 59 | def decode(options) 60 | puts "\n\n## DECODING JSON" 61 | decoder = Gson::Decoder.new 62 | Benchmark.bmbm do |x| 63 | x.report("Gson::Decoder#decode (from an IO)") do 64 | options[:times].times do 65 | options[:json_stream].rewind 66 | decoder.decode(options[:json_stream]) 67 | end 68 | end 69 | x.report("Gson::Decoder#decode (from a String)") do 70 | options[:times].times do 71 | decoder.decode(options[:json]) 72 | end 73 | end 74 | if defined?(JSON) 75 | x.report("JSON.parse") do 76 | options[:times].times do 77 | JSON.parse(options[:json], :max_nesting => false) 78 | end 79 | end 80 | end 81 | end 82 | end 83 | 84 | case options[:type] 85 | when :decode, "decode" 86 | decode(options) 87 | when :encode, "encode" 88 | encode(options) 89 | when :both, "both" 90 | encode(options) 91 | decode(options) 92 | else 93 | raise "Unknown type: #{options[:type].inspect}" 94 | end 95 | 96 | 97 | options[:json_stream].close 98 | -------------------------------------------------------------------------------- /test/test_decoder.rb: -------------------------------------------------------------------------------- 1 | require 'minitest/autorun' 2 | require 'gson' 3 | require 'stringio' 4 | 5 | class TestDecoder < MiniTest::Unit::TestCase 6 | 7 | def test_it_lenient_by_default 8 | decoder = Gson::Decoder.new 9 | assert decoder.lenient? 10 | end 11 | 12 | def test_it_doesnt_symbolize_keys_by_default 13 | decoder = Gson::Decoder.new 14 | refute decoder.symbolize_keys? 15 | end 16 | 17 | def test_it_symbolizes_keys_if_required 18 | decoder = Gson::Decoder.new(:symbolize_keys => true) 19 | expected = {:foo => "bar"} 20 | assert_equal expected, decoder.decode('{"foo":"bar"}') 21 | end 22 | 23 | def test_it_accepts_io_objects 24 | path = File.expand_path("../okjson/t/valid-object-single.json", __FILE__) 25 | File.open(path) do |io| 26 | decoder = Gson::Decoder.new 27 | expected = {"a" => "b"} 28 | assert_equal expected, decoder.decode(io) 29 | end 30 | end 31 | 32 | def test_it_accepts_stringio_objects 33 | io = StringIO.new('{"a":"b"}') 34 | decoder = Gson::Decoder.new 35 | expected = {"a" => "b"} 36 | assert_equal expected, decoder.decode(io) 37 | end 38 | 39 | def test_in_lenient_mode_it_allows_top_level_value_of_any_type 40 | assert_valid_in_lenient_mode(1, "1") 41 | end 42 | 43 | def test_in_lenient_mode_it_allows_source_to_start_with_non_execute_prefix 44 | nep = %Q|)]}'\n| 45 | assert_valid_in_lenient_mode({"foo"=>"bar"}, nep + '{"foo":"bar"}') 46 | end 47 | 48 | def test_in_lenient_mode_it_allows_source_to_include_multiple_top_level_values 49 | assert_valid_in_lenient_mode([1, 2, 3], '1 2 3') 50 | assert_valid_in_lenient_mode([{"foo"=>"bar"}, {"bar"=>"foo"}], 51 | '{"foo":"bar"}{"bar":"foo"}') 52 | end 53 | 54 | def test_in_lenient_mode_it_allows_names_to_be_unquoted 55 | assert_valid_in_lenient_mode({"foo"=>"bar"}, '{foo:"bar"}') 56 | end 57 | 58 | def test_in_lenient_mode_it_allows_names_to_be_single_quoted 59 | assert_valid_in_lenient_mode({"foo"=>"bar"}, %Q({'foo':"bar"})) 60 | end 61 | 62 | def test_in_lenient_mode_it_allows_strings_to_be_unquoted 63 | assert_valid_in_lenient_mode({"foo"=>"bar"}, '{"foo":bar}') 64 | end 65 | 66 | def test_in_lenient_mode_it_allows_strings_to_be_single_quoted 67 | assert_valid_in_lenient_mode({"foo"=>"bar"}, %Q({"foo":'bar'})) 68 | end 69 | 70 | def test_in_lenient_mode_it_allows_semicolons_as_array_separators 71 | assert_valid_in_lenient_mode({"foo"=>[1,2,3,4]}, '{"foo":[1;2;3;4]}') 72 | end 73 | 74 | def test_in_lenient_mode_it_allows_hashrockets_as_name_value_separators 75 | assert_valid_in_lenient_mode({"foo" => "bar"}, '{"foo"=>"bar"}') 76 | end 77 | 78 | def assert_valid_in_lenient_mode(expected, source) 79 | decoder = Gson::Decoder.new(:lenient => true) 80 | assert_equal expected, decoder.decode(source) 81 | 82 | decoder = Gson::Decoder.new(:lenient => false) 83 | assert_raises Gson::DecodeError do 84 | decoder.decode(source) 85 | end 86 | end 87 | 88 | end 89 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # gson.rb 2 | 3 | Ruby wrapper for [google-gson][1] library 4 | 5 | ## Installation 6 | 7 | Add this line to your application's Gemfile: 8 | 9 | gem 'gson' 10 | 11 | And then execute: 12 | 13 | $ bundle 14 | 15 | Or install it yourself as: 16 | 17 | $ gem install gson 18 | 19 | ## Usage 20 | 21 | ### Encoding 22 | 23 | Gson::Encoder.new.encode({"abc" => [123, -456.789]}) 24 | => "{\"abc\":[123,-456.789]}" 25 | 26 | `Gson::Decoder#decode` also accept optional IO or StringIO object: 27 | 28 | File.open("/tmp/gson.json", "w+") do |io| 29 | Gson::Encoder.new.encode({"foo" => "bar"}, io) 30 | end 31 | File.read("/tmp/gson.json") 32 | => "{\"foo\":\"bar\"}" 33 | 34 | Additional encoder options: 35 | 36 | * `:html_safe`, default `false`, force encoder to wrte JSON that is 37 | safe for inclusion in HTML and XML documents 38 | 39 | source = {:avatar => ''} 40 | Gson::Encoder.new(:html_safe => true).encode(source) 41 | => "{\"avatar\":\"\\u003cimg src\\u003d\\\"http://example.com/avatar.png\\\"\\u003e\"}" 42 | 43 | * `:serialize_nils`, default `true`, force encoder to write object 44 | members if their value is `nil`. This has no impact on array 45 | elements. 46 | 47 | * `:indent`, default `""`, a string containing a full set of spaces 48 | for a single level of indentation. `nil` or `""` (empty string) 49 | means not pretty printing. 50 | 51 | * `:lenient`, default `true`, configure encoder to relax its syntax 52 | rules. Setting it to lenient permits the following: 53 | 54 | * top-level values of any type. With strict writing, the top-level 55 | value must be an object or an array 56 | 57 | * numbers may be NaNs or infinities 58 | 59 | ### Decoding 60 | 61 | Gson::Decoder.new.decode('{"abc":[123,-456.789e0]}') 62 | => {"abc"=>[123, -456.789]} 63 | 64 | `Gson::Decoder#decode` also accept IO or StringIO objects: 65 | 66 | Gson::Decoder.new.decode(File.open("valid-object-single.json")) 67 | => {"a"=>"b"} 68 | 69 | Additional decoder options: 70 | 71 | * `:symbolize_keys`, default `false`, force all property names decoded 72 | to ruby symbols instead of strings. 73 | 74 | Gson::Decoder.new(:symbolize_keys => true).decode('{"a":"b"}') 75 | => {:a=>"b"} 76 | 77 | * `:lenient`, default `true`, configure this parser to be be liberal 78 | in what it accepts: 79 | 80 | * streams that start with the non-execute prefix, `")]}'\n"` 81 | 82 | * streams that include multiple top-level values. With strict 83 | parsing, each stream must contain exactly one top-level value 84 | 85 | * top-level values of any type. With strict parsing, the top-level 86 | value must be an object or an array 87 | 88 | * numbers may be NaNs or infinities 89 | 90 | * end of line comments starting with `//` or`#` and ending with a 91 | newline character 92 | 93 | * C-style comments starting with `/*` and ending with `*/`. Such 94 | comments may not be nested 95 | 96 | * names that are unquoted or `'single quoted'` 97 | 98 | * strings that are unquoted or `'single quoted'` 99 | 100 | * array elements separated by `;` instead of `,` 101 | 102 | * names and values separated by `=` or `=>` instead of `:` 103 | 104 | ## Contributing 105 | 106 | 1. Fork it 107 | 2. Create your feature branch (`git checkout -b my-new-feature`) 108 | 3. Commit your changes (`git commit -am 'Add some feature'`) 109 | 4. Push to the branch (`git push origin my-new-feature`) 110 | 5. Create new Pull Request 111 | 112 | [1]: https://code.google.com/p/google-gson/ 113 | -------------------------------------------------------------------------------- /test/test_encoder.rb: -------------------------------------------------------------------------------- 1 | require 'minitest/autorun' 2 | require 'gson' 3 | require 'stringio' 4 | 5 | class TestEncoder < MiniTest::Unit::TestCase 6 | 7 | def test_it_lenient_by_default 8 | encoder = Gson::Encoder.new 9 | assert encoder.lenient? 10 | end 11 | 12 | def test_it_serializes_nils_by_default 13 | encoder = Gson::Encoder.new 14 | assert encoder.serialize_nils? 15 | end 16 | 17 | def test_it_isnt_html_safe_by_default 18 | encoder = Gson::Encoder.new 19 | refute encoder.html_safe? 20 | end 21 | 22 | def test_it_doesnt_prettify_output_by_default 23 | encoder = Gson::Encoder.new 24 | assert_equal "", encoder.indent 25 | end 26 | 27 | def test_it_generates_html_safe_content_if_needed 28 | source = {:avatar => ''} 29 | 30 | encoder = Gson::Encoder.new(:html_safe => true) 31 | expected = '{"avatar":"\u003cimg src\u003d\"http://example.com/avatar.png\"\u003e"}' 32 | assert_equal expected, encoder.encode(source) 33 | 34 | encoder = Gson::Encoder.new(:html_safe => false) 35 | expected = '{"avatar":""}' 36 | assert_equal expected, encoder.encode(source) 37 | end 38 | 39 | def test_it_might_be_configured_to_skip_nils 40 | source = {"foo" => "bar", "baz" => nil} 41 | 42 | encoder = Gson::Encoder.new(:serialize_nils => true) 43 | expected = '{"foo":"bar","baz":null}' 44 | assert_equal expected, encoder.encode(source) 45 | 46 | encoder = Gson::Encoder.new(:serialize_nils => false) 47 | expected = '{"foo":"bar"}' 48 | assert_equal expected, encoder.encode(source) 49 | end 50 | 51 | def test_it_can_prettify_the_output 52 | source = {"foo" => "bar", "ary" => [1, 2, 3]} 53 | 54 | encoder = Gson::Encoder.new(:indent => " ") 55 | expected = < nil) 68 | expected = '{"foo":"bar","ary":[1,2,3]}' 69 | assert_equal expected, encoder.encode(source) 70 | 71 | encoder = Gson::Encoder.new(:indent => "") 72 | expected = '{"foo":"bar","ary":[1,2,3]}' 73 | assert_equal expected, encoder.encode(source) 74 | end 75 | 76 | def test_in_lenient_mode_it_allows_primitives_as_top_level_value 77 | source = 1 78 | 79 | encoder = Gson::Encoder.new(:lenient => true) 80 | expected = '1' 81 | assert_equal expected, encoder.encode(source) 82 | 83 | encoder = Gson::Encoder.new(:lenient => false) 84 | assert_raises Gson::EncodeError do 85 | encoder.encode(source) 86 | end 87 | end 88 | 89 | def test_in_lenient_mode_it_allows_nans_to_be_serialized 90 | source = {"foo" => 1/0.0} 91 | 92 | encoder = Gson::Encoder.new(:lenient => true) 93 | expected = '{"foo":Infinity}' 94 | assert_equal expected, encoder.encode(source) 95 | 96 | encoder = Gson::Encoder.new(:lenient => false) 97 | assert_raises Gson::EncodeError do 98 | encoder.encode(source) 99 | end 100 | end 101 | 102 | class Custom 103 | attr_accessor :foo, :bar 104 | 105 | def initialize(foo, bar) 106 | @foo = foo 107 | @bar = bar 108 | end 109 | 110 | def as_json(options = {}) 111 | {:foo => @foo, :bar => @bar} 112 | end 113 | end 114 | 115 | def test_it_dumps_custom_objects_wich_implement_as_json 116 | encoder = Gson::Encoder.new 117 | expected = '{"foo":1,"bar":2}' 118 | assert_equal expected, encoder.encode(Custom.new(1, 2)) 119 | end 120 | 121 | def test_it_converts_unknown_objects_to_string 122 | time = Time.at(1355218745).utc 123 | 124 | # time does not respond to to_json method 125 | def time.respond_to?(method, *args) 126 | return false if method == :to_json 127 | super 128 | end 129 | 130 | encoder = Gson::Encoder.new 131 | decoder = Gson::Decoder.new 132 | 133 | dumped_json = encoder.encode(time) 134 | expected = if RUBY_VERSION > '1.9' 135 | '2012-12-11 09:39:05 UTC' 136 | else 137 | 'Tue Dec 11 09:39:05 UTC 2012' 138 | end 139 | assert_equal(expected, decoder.decode(dumped_json)) 140 | end 141 | 142 | def test_it_supports_output_streams 143 | encoder = Gson::Encoder.new 144 | expected = '{"foo":1,"bar":2}' 145 | output = StringIO.new 146 | encoder.encode({:foo => 1, :bar => 2}, output) 147 | assert_equal expected, output.string 148 | end 149 | end 150 | -------------------------------------------------------------------------------- /benchmark/subjects/twitter_search.json: -------------------------------------------------------------------------------- 1 | {"results":[{"text":"RT @tmornini: Engine Yard Express = perfect way to test merb or rails deployment - http:\/\/express.engineyard.com\/","to_user_id":null,"from_user":"seanhealy","id":1429979943,"from_user_id":4485910,"iso_language_code":"en","source":"<a href="http:\/\/iconfactory.com\/software\/twitterrific">twitterrific<\/a>","profile_image_url":"https:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/62254150\/irish_noir_normal.jpg","created_at":"Wed, 01 Apr 2009 07:06:16 +0000"},{"text":"RT: Engine Yard Express = perfect way to test merb or rails deployment - http:\/\/express.engineyard.com\/ (via @digsby)","to_user_id":null,"from_user":"tmornini","id":1429966620,"from_user_id":168963,"iso_language_code":"en","source":"<a href="http:\/\/twitter.com\/">web<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/49018042\/Tom_Icon_64x64_normal.png","created_at":"Wed, 01 Apr 2009 07:02:00 +0000"},{"text":"Engine Yard Express = perfect way to test merb or rails deployment - http:\/\/express.engineyard.com\/","to_user_id":null,"from_user":"richardholland","id":1428644441,"from_user_id":1608628,"iso_language_code":"en","source":"<a href="http:\/\/www.digsby.com\/">digsby<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/63723025\/mesarah_normal.jpg","created_at":"Wed, 01 Apr 2009 02:07:30 +0000"},{"text":"RT @wycats: How to survive monster attacks. Some tips from your friends at EngineYard http:\/\/twitpic.com\/2nl7x","to_user_id":null,"from_user":"AmandaMorin","id":1427373261,"from_user_id":1756964,"iso_language_code":"en","source":"<a href="http:\/\/www.tweetdeck.com\/">TweetDeck<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/67971839\/avatar_normal.jpg","created_at":"Tue, 31 Mar 2009 22:19:29 +0000"},{"text":"engineyard added jarnold to mongrel: \n\n \n \n \n mongrel is at engineyard\/mongrel http:\/\/tinyurl.com\/dm7ldz","to_user_id":null,"from_user":"_snax","id":1427357028,"from_user_id":118386,"iso_language_code":"en","source":"<a href="http:\/\/twitterfeed.com">twitterfeed<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/19934062\/logo_large_normal.gif","created_at":"Tue, 31 Mar 2009 22:16:38 +0000"},{"text":"RT: LOL! RT @wycats:How to survive monster attacks. Some tips from your friends at EngineYard http:\/\/twitpic... http:\/\/tinyurl.com\/cgs2hj","to_user_id":null,"from_user":"howtotweets","id":1427228937,"from_user_id":3437258,"iso_language_code":"en","source":"<a href="http:\/\/twitterfeed.com">twitterfeed<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/81039760\/images_normal.jpg","created_at":"Tue, 31 Mar 2009 21:54:32 +0000"},{"text":"LOL! RT @wycats:How to survive monster attacks. Some tips from your friends at EngineYard http:\/\/twitpic.com\/2nl7x","to_user_id":null,"from_user":"tsykoduk","id":1427225099,"from_user_id":71236,"iso_language_code":"en","source":"<a href="http:\/\/www.nambu.com">Nambu<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/63278451\/Photo_33_normal.jpg","created_at":"Tue, 31 Mar 2009 21:53:52 +0000"},{"text":"RT @wycats: How to survive monster attacks. Some tips from your friends at EngineYard http:\/\/twitpic.com\/2nl7x","to_user_id":null,"from_user":"bratta","id":1427177698,"from_user_id":8376,"iso_language_code":"en","source":"<a href="http:\/\/thecosmicmachine.com\/eventbox\/">EventBox<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/80333638\/photo_normal.jpg","created_at":"Tue, 31 Mar 2009 21:45:46 +0000"},{"text":"additional infos on the engineyard outage: http:\/\/tinyurl.com\/cbhbkn","to_user_id":null,"from_user":"aentos","id":1427149457,"from_user_id":6459508,"iso_language_code":"en","source":"<a href="http:\/\/twitterfox.net\/">TwitterFox<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/66789130\/aentos_a_normal.png","created_at":"Tue, 31 Mar 2009 21:40:47 +0000"},{"text":"http:\/\/twitpic.com\/2nl9z - Surviving monster attacks. A PSA from your friends @engineyard","to_user_id":null,"from_user":"carllerche","id":1427108503,"from_user_id":880629,"iso_language_code":"en","source":"<a href="http:\/\/twitpic.com\/">TwitPic<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/56520194\/fry_coffee2_normal.jpg","created_at":"Tue, 31 Mar 2009 21:33:38 +0000"},{"text":"How to survive monster attacks. Some tips from your friends at EngineYard http:\/\/twitpic.com\/2nl7x","to_user_id":null,"from_user":"wycats","id":1427099726,"from_user_id":18414,"iso_language_code":"en","source":"<a href="http:\/\/twitterfon.net\/">TwitterFon<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/51747258\/Yehuda_-_Looking_at_Sky_normal.jpg","created_at":"Tue, 31 Mar 2009 21:32:07 +0000"},{"text":"RT @engineyard: Our CEO posted an update on yesterday's outage: http:\/\/bit.ly\/yA4p5 Good job keeping people in the loop!","to_user_id":null,"from_user":"fatnutz","id":1426857591,"from_user_id":706358,"iso_language_code":"en","source":"<a href="http:\/\/www.tweetdeck.com\/">TweetDeck<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/55573179\/snipe_normal.jpg","created_at":"Tue, 31 Mar 2009 20:50:21 +0000"},{"text":"loving our @entryway @engineyard solo instance, we built an integrity server in mins flat with @atmos lovely chef scripts: http:\/\/is.gd\/pVXw","to_user_id":null,"from_user":"gustin","id":1426653742,"from_user_id":3736601,"iso_language_code":"en","source":"<a href="http:\/\/83degrees.com\/to\/powertwitter">Power Twitter<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/116498033\/face_normal.png","created_at":"Tue, 31 Mar 2009 20:16:36 +0000"},{"text":"RT: Our CEO posted an update on yesterday's outage: http:\/\/bit.ly\/yA4p5 (via @engineyard)","to_user_id":null,"from_user":"tmornini","id":1426483075,"from_user_id":168963,"iso_language_code":"en","source":"<a href="http:\/\/twitter.com\/">web<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/49018042\/Tom_Icon_64x64_normal.png","created_at":"Tue, 31 Mar 2009 19:47:00 +0000"},{"text":"#engineyard #github very impressive - both the reason and the response - I must have missed the blog sorry","to_user_id":null,"from_user":"rickwindham","id":1426328592,"from_user_id":1819414,"iso_language_code":"en","source":"<a href="http:\/\/www.tweetdeck.com\/">TweetDeck<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/73617189\/me_new_normal.jpg","created_at":"Tue, 31 Mar 2009 19:16:30 +0000"}],"since_id":1386843259,"max_id":1429979943,"refresh_url":"?since_id=1429979943&q=engineyard","results_per_page":15,"next_page":"?page=2&max_id=1429979943&since_id=1386843259&q=engineyard","warning":"adjusted since_id, it was older than allowed","completed_in":0.037275,"page":1,"query":"engineyard"} -------------------------------------------------------------------------------- /ext/gson_ext/Encoder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Couchbase, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package gson_ext; 18 | 19 | import com.google.gson.stream.JsonWriter; 20 | import java.io.IOException; 21 | import java.io.OutputStream; 22 | import java.io.OutputStreamWriter; 23 | import java.io.StringWriter; 24 | import java.io.Writer; 25 | import org.jruby.Ruby; 26 | import org.jruby.RubyArray; 27 | import org.jruby.RubyBoolean; 28 | import org.jruby.RubyClass; 29 | import org.jruby.RubyException; 30 | import org.jruby.RubyFloat; 31 | import org.jruby.RubyHash; 32 | import org.jruby.RubyIO; 33 | import org.jruby.RubyInteger; 34 | import org.jruby.RubyNumeric; 35 | import org.jruby.RubyObject; 36 | import org.jruby.RubyString; 37 | import org.jruby.RubySymbol; 38 | import org.jruby.anno.JRubyClass; 39 | import org.jruby.anno.JRubyMethod; 40 | import org.jruby.exceptions.RaiseException; 41 | import org.jruby.ext.stringio.RubyStringIO; 42 | import org.jruby.java.addons.IOJavaAddons; 43 | import org.jruby.runtime.ThreadContext; 44 | import org.jruby.runtime.builtin.IRubyObject; 45 | import org.jruby.util.IOOutputStream; 46 | 47 | @JRubyClass(name = "Gson::Encoder") 48 | public class Encoder extends RubyObject { 49 | 50 | static final long serialVersionUID = 5035506147333315973L; 51 | private boolean htmlSafe = false; 52 | private boolean lenient = true; 53 | private boolean serializeNulls = true; 54 | private String indent = ""; 55 | private IRubyObject options; 56 | 57 | public Encoder(final Ruby ruby, RubyClass rubyClass) { 58 | super(ruby, rubyClass); 59 | } 60 | 61 | @JRubyMethod(name = "lenient?") 62 | public IRubyObject isLenient(ThreadContext context) { 63 | return RubyBoolean.newBoolean(context.getRuntime(), this.lenient); 64 | } 65 | 66 | @JRubyMethod(name = "html_safe?") 67 | public IRubyObject isHtmlSafe(ThreadContext context) { 68 | return RubyBoolean.newBoolean(context.getRuntime(), this.htmlSafe); 69 | } 70 | 71 | @JRubyMethod(name = "serialize_nils?") 72 | public IRubyObject isSerializeNulls(ThreadContext context) { 73 | return RubyBoolean.newBoolean(context.getRuntime(), this.serializeNulls); 74 | } 75 | 76 | @JRubyMethod(name = "indent") 77 | public IRubyObject getIndent(ThreadContext context) { 78 | return RubyString.newString(context.getRuntime(), this.indent); 79 | } 80 | 81 | @JRubyMethod(optional = 1) 82 | public IRubyObject initialize(ThreadContext context, IRubyObject[] args) { 83 | Ruby ruby = context.getRuntime(); 84 | if (args.length < 1 || args[0].isNil()) { 85 | this.options = RubyHash.newHash(ruby); 86 | return context.nil; 87 | } 88 | if (!(args[0] instanceof RubyHash)) { 89 | throw ruby.newArgumentError("expected Hash for options argument"); 90 | } 91 | this.options = args[0]; 92 | RubyHash options = (RubyHash)this.options; 93 | RubySymbol name = ruby.newSymbol("lenient"); 94 | if (options.containsKey(name)) { 95 | this.lenient = options.op_aref(context, name).isTrue(); 96 | } 97 | name = ruby.newSymbol("serialize_nils"); 98 | if (options.containsKey(name)) { 99 | this.serializeNulls = options.op_aref(context, name).isTrue(); 100 | } 101 | name = ruby.newSymbol("html_safe"); 102 | if (options.containsKey(name)) { 103 | this.htmlSafe = options.op_aref(context, name).isTrue(); 104 | } 105 | name = ruby.newSymbol("indent"); 106 | if (options.containsKey(name)) { 107 | IRubyObject val = options.op_aref(context, name); 108 | if (val.isNil()) { 109 | this.indent = ""; 110 | } else { 111 | this.indent = val.checkStringType().asJavaString(); 112 | } 113 | } 114 | return context.nil; 115 | } 116 | 117 | @JRubyClass(name="Gson::EncodeError", parent="StandardError") 118 | public static class EncodeError { 119 | 120 | public static RaiseException newEncodeError(Ruby ruby, String message) { 121 | RubyClass errorClass = ruby.getModule("Gson").getClass("EncodeError"); 122 | return new RaiseException(RubyException.newException(ruby, errorClass, message), true); 123 | } 124 | 125 | } 126 | 127 | @JRubyMethod(required = 1, optional = 1) 128 | public IRubyObject encode(ThreadContext context, IRubyObject[] args) { 129 | Ruby ruby = context.getRuntime(); 130 | Writer out = null; 131 | 132 | if (args.length < 2 || args[1].isNil()) { 133 | out = new StringWriter(); 134 | } else { 135 | IRubyObject io = args[1]; 136 | if ((io instanceof RubyIO) || (io instanceof RubyStringIO)) { 137 | IRubyObject stream = IOJavaAddons.AnyIO.any_to_outputstream(context, io); 138 | out = new OutputStreamWriter((OutputStream)stream.toJava(OutputStream.class)); 139 | } else { 140 | throw ruby.newArgumentError("Unsupported source. This method accepts IO"); 141 | } 142 | } 143 | 144 | JsonWriter writer = new JsonWriter(out); 145 | writer.setLenient(this.lenient); 146 | writer.setHtmlSafe(this.htmlSafe); 147 | writer.setIndent(this.indent); 148 | writer.setSerializeNulls(this.serializeNulls); 149 | try { 150 | encodeValue(writer, context, args[0]); 151 | } catch (Exception ex) { 152 | throw EncodeError.newEncodeError(ruby, ex.getMessage()); 153 | } 154 | if (out instanceof StringWriter) { 155 | return ruby.newString(out.toString()); 156 | } else { 157 | return context.nil; 158 | } 159 | } 160 | 161 | private void encodeValue(JsonWriter writer, ThreadContext context, IRubyObject val) 162 | throws IOException { 163 | Ruby ruby = context.getRuntime(); 164 | 165 | if (val.isNil()) { 166 | writer.nullValue(); 167 | } else if (val instanceof RubyHash) { 168 | writer.beginObject(); 169 | for (Object obj : ((RubyHash)val).directEntrySet()) { 170 | RubyHash.RubyHashEntry item = (RubyHash.RubyHashEntry)obj; 171 | writer.name(item.getKey().toString()); 172 | encodeValue(writer, context, (IRubyObject)item.getValue()); 173 | } 174 | writer.endObject(); 175 | } else if (val instanceof RubyArray) { 176 | writer.beginArray(); 177 | for (IRubyObject item : ((RubyArray)val).toJavaArray()) { 178 | encodeValue(writer, context, item); 179 | } 180 | writer.endArray(); 181 | } else if (val instanceof RubyString || val instanceof RubySymbol) { 182 | writer.value(val.toString()); 183 | } else if (val instanceof RubyInteger) { 184 | try { 185 | writer.value(((RubyInteger)val).getLongValue()); 186 | } catch (RaiseException ex) { 187 | if ("RangeError".equals(ex.getException().getType().getName())) { 188 | writer.value(((RubyInteger)val).getBigIntegerValue()); 189 | } else { 190 | throw ex; 191 | } 192 | } 193 | } else if (val instanceof RubyFloat) { 194 | writer.value((Double)((RubyFloat)val).getDoubleValue()); 195 | } else if (val instanceof RubyBoolean) { 196 | writer.value(val.isTrue()); 197 | } else if (val.respondsTo("as_json")) { 198 | encodeValue(writer, context, val.callMethod(context, "as_json", this.options)); 199 | } else if (val.respondsTo("to_s")) { 200 | writer.value(val.toString()); 201 | } else { 202 | writer.value(val.anyToString().toString()); 203 | } 204 | writer.flush(); 205 | } 206 | 207 | } 208 | -------------------------------------------------------------------------------- /benchmark/subjects/unicode.json: -------------------------------------------------------------------------------- 1 | {"results":[{"text":"#ruby \u732e\u672c\u30ad\u30bf\u30fc\u30fc\u30fc\u30fc\u30fc\u30fc\uff08\u309c\u2200\u309c\uff09\u30fc\u30fc\u30fc\u30fc\u30fc\u30fc\uff01\uff01 http:\/\/www.amazon.co.jp\/gp\/product\/4863540221","to_user_id":null,"from_user":"rubikitch","id":1843394737,"from_user_id":847295,"iso_language_code":"ja","source":"<a href="http:\/\/www.misuzilla.org\/dist\/net\/twitterircgateway\/">TwitterIrcGateway<\/a>","profile_image_url":"http:\/\/static.twitter.com\/images\/default_profile_normal.png","created_at":"Tue, 19 May 2009 03:12:47 +0000"},{"text":"Ruby on Rails\u3068CakePHP\u3001\u3069\u3063\u3061\u3067\u88fd\u9020\u3057\u3088\u3046\u304b\u3057\u3089","to_user_id":null,"from_user":"takkada","id":1842694220,"from_user_id":412519,"iso_language_code":"ja","source":"<a href="http:\/\/twitterfox.net\/">TwitterFox<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/16301882\/62305_4124481745_normal.jpg","created_at":"Tue, 19 May 2009 02:00:08 +0000"},{"text":"Ruby on Rails \u306e\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u306f\u30fc\u3058\u307e\u30fc\u308b\u3088\u30fc","to_user_id":null,"from_user":"Tomohiro","id":1842375120,"from_user_id":38704,"iso_language_code":"ja","source":"<a href="http:\/\/www.misuzilla.org\/dist\/net\/twitterircgateway\/">TwitterIrcGateway<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/20970892\/578576_3772887925_normal.jpg","created_at":"Tue, 19 May 2009 01:27:18 +0000"},{"text":"ruby winole.rb\u3067\u547c\u3073\u51fa\u3057\u305f\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u306e\u30e1\u30e2\u30ea\u304c\u9069\u5207\u306b\u958b\u653e\u3055\u308c\u3066\u306a\u304b\u3063\u305f\u3002","to_user_id":null,"from_user":"tomofusa","id":1841955169,"from_user_id":35354,"iso_language_code":"ja","source":"<a href="http:\/\/cheebow.info\/chemt\/archives\/2007\/04\/twitterwindowst.html">Twit<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/18213412\/fusa2.0_about53_normal.png","created_at":"Tue, 19 May 2009 00:43:20 +0000"},{"text":"Ruby HTTP\u4e26\u5217\u3092\u51e6\u7406\u3092\u9ad8\u901f\u5316\u3001"Typhoeus"\u767b\u5834 | \u30a8\u30f3\u30bf\u30fc\u30d7\u30e9\u30a4\u30ba | \u30de\u30a4\u30b3\u30df\u30b8\u30e3\u30fc\u30ca\u30eb http:\/\/ff.im\/-31cez","to_user_id":null,"from_user":"MyGReaderFeed","id":1841206557,"from_user_id":11923042,"iso_language_code":"ja","source":"<a href="http:\/\/friendfeed.com\/">FriendFeed<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/141487706\/3379573163_e79dab7511_normal.bmp","created_at":"Mon, 18 May 2009 23:22:26 +0000"},{"text":"\u3044\u305a\u308c\u306b\u3057\u3066\u3082\u3069\u3053\u304b\u306b Ruby 1.9.1 \u74b0\u5883\u306f\u4f5c\u3089\u306a\u3044\u3068\u30c0\u30e1\u304b\u306a\u3041\u3002Debian lenny \u4efb\u305b\u3060\u3068 1.9.0 \u3057\u304b\u8a66\u305b\u306a\u3044\u3063\u307d\u3044\u3057\u3002","to_user_id":null,"from_user":"wtnabe","id":1840166013,"from_user_id":32040,"iso_language_code":"ja","source":"<a href="http:\/\/www.misuzilla.org\/dist\/net\/twitterircgateway\/">TwitterIrcGateway<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/59828670\/200805-wtnabe-film_normal.png","created_at":"Mon, 18 May 2009 21:26:17 +0000"},{"text":"Ruby 1.9 \u3067\u306f URI#decode \u3060\u3051\u3058\u3083\u610f\u5473\u304c\u306a\u3044\u306e\u304b\u306a\uff1f \u3053\u306e\u8fba\u304b\u3089\u5206\u304b\u3089\u306a\u304f\u306a\u3063\u3066\u304f\u308b\u306a\u3002","to_user_id":null,"from_user":"wtnabe","id":1839967007,"from_user_id":32040,"iso_language_code":"ja","source":"<a href="http:\/\/www.misuzilla.org\/dist\/net\/twitterircgateway\/">TwitterIrcGateway<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/59828670\/200805-wtnabe-film_normal.png","created_at":"Mon, 18 May 2009 21:06:06 +0000"},{"text":"Star Ruby \u3067\u30d5\u30ec\u30fc\u30e0\u30b9\u30ad\u30c3\u30d7\u304c\u5b9f\u88c5\u3057\u306b\u304f\u3044\u7406\u7531\u306e\u3072\u3068\u3064\u306b\u3001\u30b9\u30af\u30ea\u30fc\u30f3\u3078\u306e\u63cf\u753b\u304c\u9045\u5ef6\u3067\u304d\u306a\u3044\u3068\u3044\u3046\u306e\u304c\u3042\u308b\u3002 Texture#[] \u306a\u3069\u3067\u30d4\u30af\u30bb\u30eb\u306e\u5024\u3092\u8aad\u307f\u53d6\u3089\u308c\u308b\u53ef\u80fd\u6027\u304c\u3042\u308b\u305f\u3081\u3002\u8aad\u307f\u53d6\u3089\u308c\u308b\u30ae\u30ea\u30ae\u30ea\u307e\u3067\u9045\u5ef6\u3059\u308b\u306e\u3082\u30a2\u30ea\u3060\u304c\u3001\u5b9f\u88c5\u306f\u9762\u5012\u3067\u3042\u308b\u3002","to_user_id":null,"from_user":"hajimehoshi","id":1837784833,"from_user_id":7543,"iso_language_code":"ja","source":"<a href="http:\/\/twitter.com\/">web<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/14446892\/michael_normal.jpg","created_at":"Mon, 18 May 2009 17:21:16 +0000"},{"text":"ruby-gem\u3092\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3057\u3066\u3001rails\u306b\u30c1\u30e3\u30ec\u30f3\u30b8","to_user_id":null,"from_user":"tom_a","id":1837459653,"from_user_id":366098,"iso_language_code":"ja","source":"<a href="http:\/\/twitterfox.net\/">TwitterFox<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/16661182\/DSC02701_normal.jpg","created_at":"Mon, 18 May 2009 16:46:36 +0000"},{"text":"@saronpasu \u4e2d\u8eab\u306b\u30a2\u30af\u30bb\u30b9\u3057\u306b\u304f\u3044\u3057\u3001\u4f55\u3088\u308a\u4e0d\u5b89\u5b9a\u3059\u304e\u3067\u3059\u306d\u2026\u4f8b\u5916\u3063\u3066\u30ec\u30d9\u30eb\u3058\u3083\u306a\u304f\u3066 ruby \u5dfb\u304d\u8fbc\u3093\u3067\u843d\u3061\u308b\u306e\u3067\u2026","to_user_id":28082,"to_user":"saronpasu","from_user":"negaton","id":1836710607,"from_user_id":5893,"iso_language_code":"ja","source":"<a href="http:\/\/cheebow.info\/chemt\/archives\/2007\/04\/twitterwindowst.html">Twit<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/35934732\/DSC00338_icon_normal.jpg","created_at":"Mon, 18 May 2009 15:28:25 +0000"},{"text":"\u6628\u65e5 CaboCha-Ruby \u306e token \u306e surface \u3092\u53e9\u3044\u305f\u3089\u843d\u3061\u305f\u306e\u306b\u4eca\u65e5\u306f\u5168\u304f\u540c\u3058\u30b3\u30fc\u30c9\u52d5\u304b\u3057\u3066\u3066\u843d\u3061\u306a\u3044\u3068\u304b\u306a\u3093\u306a\u306e\u2026","to_user_id":null,"from_user":"negaton","id":1836267822,"from_user_id":5893,"iso_language_code":"ja","source":"<a href="http:\/\/cheebow.info\/chemt\/archives\/2007\/04\/twitterwindowst.html">Twit<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/35934732\/DSC00338_icon_normal.jpg","created_at":"Mon, 18 May 2009 14:41:26 +0000"},{"text":"ruby.snippets \u3092\u773a\u3081\u3066\u307f\u3066\u3001\u3053\u308c\u306f\u81ea\u5206\u304c\u4f7f\u3044\u3053\u306a\u305b\u308b\u3082\u306e\u3067\u306f\u306a\u3044\u3068\u308f\u304b\u3063\u305f","to_user_id":null,"from_user":"ursm","id":1835699306,"from_user_id":41919,"iso_language_code":"ja","source":"<a href="http:\/\/www.nambu.com">Nambu<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/28792412\/1153147983506_normal.jpg","created_at":"Mon, 18 May 2009 13:33:59 +0000"},{"text":"\u3068\u3053\u308d\u3067\u3001PHP \u304b\u3089\u306f Ruby \u3063\u3066\u547c\u3079\u308b\u306e\uff1f","to_user_id":null,"from_user":"nov","id":1835354604,"from_user_id":76705,"iso_language_code":"ja","source":"<a href="http:\/\/twitterfon.net\/">TwitterFon<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/60572614\/nov_normal.gif","created_at":"Mon, 18 May 2009 12:47:52 +0000"},{"text":"\u3067\u304d\u3042\u304c\u3063\u305f\u3053\u308d shindig ruby ver. \u51fa\u3066\u305f\u308a\u3057\u305f\u3089\u6ce3\u304f\u3002","to_user_id":null,"from_user":"nov","id":1835155373,"from_user_id":76705,"iso_language_code":"ja","source":"<a href="http:\/\/twitterfon.net\/">TwitterFon<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/60572614\/nov_normal.gif","created_at":"Mon, 18 May 2009 12:17:17 +0000"},{"text":"@papiron ruby-dev\u3067ruby1.9\u306bsqlite\u30e9\u30a4\u30d6\u30e9\u30ea\u3092\u6a19\u6e96\u6dfb\u4ed8\u3057\u3088\u3046\u3068\u3044\u3046\u8b70\u8ad6\u304c\u3055\u308c\u3066\u307e\u3059\u3002http:\/\/bit.ly\/Limi9","to_user_id":10226526,"to_user":"papiron","from_user":"taigou","id":1834625775,"from_user_id":3915244,"iso_language_code":"ja","source":"<a href="http:\/\/twitterfox.net\/">TwitterFox<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/95583044\/me_normal.png","created_at":"Mon, 18 May 2009 10:38:40 +0000"}],"since_id":1769782474,"max_id":1843394737,"refresh_url":"?since_id=1843394737&q=ruby","results_per_page":15,"next_page":"?page=2&max_id=1843394737&lang=ja&q=ruby","warning":"adjusted since_id, it was older than allowedsince_id removed for pagination.","completed_in":0.052502,"page":1,"query":"ruby"} -------------------------------------------------------------------------------- /ext/gson_ext/Decoder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Couchbase, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package gson_ext; 18 | 19 | import com.google.gson.stream.JsonReader; 20 | import com.google.gson.stream.JsonToken; 21 | import java.io.IOException; 22 | import java.io.InputStream; 23 | import java.io.InputStreamReader; 24 | import java.io.Reader; 25 | import java.io.StringReader; 26 | import java.util.LinkedList; 27 | import java.util.regex.Pattern; 28 | import org.jruby.Ruby; 29 | import org.jruby.RubyArray; 30 | import org.jruby.RubyBoolean; 31 | import org.jruby.RubyClass; 32 | import org.jruby.RubyException; 33 | import org.jruby.RubyHash; 34 | import org.jruby.RubyIO; 35 | import org.jruby.RubyNumeric; 36 | import org.jruby.RubyObject; 37 | import org.jruby.RubyString; 38 | import org.jruby.RubySymbol; 39 | import org.jruby.anno.JRubyClass; 40 | import org.jruby.anno.JRubyMethod; 41 | import org.jruby.exceptions.RaiseException; 42 | import org.jruby.ext.stringio.RubyStringIO; 43 | import org.jruby.java.addons.IOJavaAddons; 44 | import org.jruby.runtime.ThreadContext; 45 | import org.jruby.runtime.builtin.IRubyObject; 46 | 47 | @JRubyClass(name = "Gson::Decoder") 48 | public class Decoder extends RubyObject { 49 | 50 | static final long serialVersionUID = 2328444027137249699L; 51 | private boolean lenient = true; 52 | private boolean symbolizeKeys = false; 53 | private static Pattern floatPattern = Pattern.compile("[.eE]"); 54 | 55 | public Decoder(final Ruby ruby, RubyClass rubyClass) { 56 | super(ruby, rubyClass); 57 | } 58 | 59 | @JRubyMethod(name = "lenient?") 60 | public IRubyObject isLenient(ThreadContext context) { 61 | return RubyBoolean.newBoolean(context.getRuntime(), this.lenient); 62 | } 63 | 64 | @JRubyMethod(name = "symbolize_keys?") 65 | public IRubyObject isSymbolizeKeys(ThreadContext context) { 66 | return RubyBoolean.newBoolean(context.getRuntime(), this.symbolizeKeys); 67 | } 68 | 69 | @JRubyMethod(optional = 1) 70 | public IRubyObject initialize(ThreadContext context, IRubyObject[] args) { 71 | Ruby ruby = context.getRuntime(); 72 | if (args.length < 1) { 73 | return context.nil; 74 | } 75 | if (!(args[0] instanceof RubyHash)) { 76 | throw ruby.newArgumentError("expected Hash for options argument"); 77 | } 78 | RubyHash options = (RubyHash)args[0]; 79 | RubySymbol name = ruby.newSymbol("lenient"); 80 | if (options.containsKey(name)) { 81 | this.lenient = options.op_aref(context, name).isTrue(); 82 | } 83 | name = ruby.newSymbol("symbolize_keys"); 84 | if (options.containsKey(name)) { 85 | this.symbolizeKeys = options.op_aref(context, name).isTrue(); 86 | } 87 | return context.nil; 88 | } 89 | 90 | @JRubyClass(name="Gson::DecodeError", parent="StandardError") 91 | public static class DecodeError { 92 | 93 | public static RaiseException newDecodeError(Ruby ruby, String message) { 94 | RubyClass errorClass = ruby.getModule("Gson").getClass("DecodeError"); 95 | return new RaiseException(RubyException.newException(ruby, errorClass, message), true); 96 | } 97 | 98 | } 99 | 100 | @JRubyMethod 101 | public IRubyObject decode(ThreadContext context, IRubyObject arg) { 102 | Ruby ruby = context.getRuntime(); 103 | 104 | Reader sourceReader; 105 | if (arg instanceof RubyString) { 106 | sourceReader = new StringReader(arg.toString()); 107 | } else if ((arg instanceof RubyIO) || (arg instanceof RubyStringIO)) { 108 | IRubyObject stream = IOJavaAddons.AnyIO.any_to_inputstream(context, arg); 109 | sourceReader = new InputStreamReader((InputStream)stream.toJava(InputStream.class)); 110 | } else { 111 | throw ruby.newArgumentError("Unsupported source. This method accepts String or IO"); 112 | } 113 | LinkedList stack = new LinkedList(); 114 | LinkedList res = new LinkedList(); 115 | JsonReader reader = new JsonReader(sourceReader); 116 | reader.setLenient(this.lenient); 117 | 118 | IRubyObject head, key, val; 119 | RubyHash obj; 120 | RubyArray ary; 121 | int i; 122 | try { 123 | while (true) { 124 | JsonToken token = reader.peek(); 125 | switch (token) { 126 | case END_ARRAY: 127 | reader.endArray(); 128 | val = stack.pop(); 129 | if (stack.isEmpty()) { 130 | res.add(val); 131 | } 132 | break; 133 | case END_OBJECT: 134 | reader.endObject(); 135 | val = stack.pop(); 136 | if (stack.isEmpty()) { 137 | res.add(val); 138 | } 139 | break; 140 | case NAME: 141 | if (this.symbolizeKeys) { 142 | val = RubySymbol.newSymbol(ruby, reader.nextName()); 143 | } else { 144 | val = RubyString.newString(ruby, reader.nextName()); 145 | } 146 | stack.push(val); 147 | break; 148 | case BEGIN_OBJECT: 149 | case BEGIN_ARRAY: 150 | case STRING: 151 | case NUMBER: 152 | case BOOLEAN: 153 | case NULL: 154 | head = stack.peek(); 155 | switch (token) { 156 | case BEGIN_ARRAY: 157 | reader.beginArray(); 158 | val = RubyArray.newArray(ruby); 159 | break; 160 | case BEGIN_OBJECT: 161 | reader.beginObject(); 162 | val = RubyHash.newHash(ruby); 163 | break; 164 | case STRING: 165 | val = RubyString.newString(ruby, reader.nextString()); 166 | break; 167 | case NUMBER: 168 | String tmp = reader.nextString(); 169 | if (floatPattern.matcher(tmp).find()) { 170 | val = RubyNumeric.str2fnum(ruby, RubyString.newString(ruby, tmp)); 171 | } else { 172 | val = RubyNumeric.str2inum(ruby, RubyString.newString(ruby, tmp), 10); 173 | } 174 | break; 175 | case BOOLEAN: 176 | val = RubyBoolean.newBoolean(ruby, reader.nextBoolean()); 177 | break; 178 | case NULL: 179 | reader.nextNull(); 180 | val = context.nil; 181 | break; 182 | default: 183 | throw DecodeError.newDecodeError(ruby, String.format("Unknown token: %s", token.toString())); 184 | } 185 | if (head instanceof RubyString || head instanceof RubySymbol) { 186 | key = stack.pop(); 187 | obj = (RubyHash)stack.peek(); 188 | obj.op_aset(context, key, val); 189 | } else if (head instanceof RubyArray) { 190 | ary = (RubyArray)stack.peek(); 191 | ary.append(val); 192 | } 193 | switch (token) { 194 | case BEGIN_ARRAY: 195 | case BEGIN_OBJECT: 196 | stack.push(val); 197 | break; 198 | default: 199 | if (head == null) { 200 | res.add(val); 201 | } 202 | } 203 | break; 204 | case END_DOCUMENT: 205 | switch (res.size()) { 206 | case 0: 207 | return context.nil; 208 | case 1: 209 | return res.pop(); 210 | default: 211 | return ruby.newArray(res); 212 | } 213 | default: 214 | throw DecodeError.newDecodeError(ruby, String.format("Unknown token: %s", token.toString())); 215 | } 216 | } 217 | } catch (Exception ex) { 218 | throw DecodeError.newDecodeError(ruby, ex.getMessage()); 219 | } 220 | } 221 | 222 | } 223 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /benchmark/subjects/ohai.json: -------------------------------------------------------------------------------- 1 | { 2 | "command": { 3 | "ps": "ps -ef" 4 | }, 5 | "kernel": { 6 | "modules": { 7 | "org.virtualbox.kext.VBoxDrv": { 8 | "size": 118784, 9 | "version": "2.2.0", 10 | "index": "114", 11 | "refcount": "3" 12 | }, 13 | "com.cisco.nke.ipsec": { 14 | "size": 454656, 15 | "version": "2.0.1", 16 | "index": "111", 17 | "refcount": "0" 18 | }, 19 | "com.apple.driver.AppleAPIC": { 20 | "size": 12288, 21 | "version": "1.4", 22 | "index": "26", 23 | "refcount": "0" 24 | }, 25 | "com.apple.driver.AirPort.Atheros": { 26 | "size": 593920, 27 | "version": "318.8.3", 28 | "index": "88", 29 | "refcount": "0" 30 | }, 31 | "com.apple.driver.AppleIntelCPUPowerManagement": { 32 | "size": 102400, 33 | "version": "59.0.1", 34 | "index": "22", 35 | "refcount": "0" 36 | }, 37 | "com.apple.iokit.IOStorageFamily": { 38 | "size": 98304, 39 | "version": "1.5.5", 40 | "index": "44", 41 | "refcount": "9" 42 | }, 43 | "com.apple.iokit.IOATAPIProtocolTransport": { 44 | "size": 16384, 45 | "version": "1.5.2", 46 | "index": "52", 47 | "refcount": "0" 48 | }, 49 | "com.apple.iokit.IOPCIFamily": { 50 | "size": 65536, 51 | "version": "2.5", 52 | "index": "17", 53 | "refcount": "18" 54 | }, 55 | "com.apple.driver.AppleHPET": { 56 | "size": 12288, 57 | "version": "1.3", 58 | "index": "33", 59 | "refcount": "0" 60 | }, 61 | "com.apple.driver.AppleUSBHub": { 62 | "size": 49152, 63 | "version": "3.2.7", 64 | "index": "47", 65 | "refcount": "0" 66 | }, 67 | "com.apple.iokit.IOFireWireFamily": { 68 | "size": 258048, 69 | "version": "3.4.6", 70 | "index": "49", 71 | "refcount": "2" 72 | }, 73 | "com.apple.driver.AppleUSBComposite": { 74 | "size": 16384, 75 | "version": "3.2.0", 76 | "index": "60", 77 | "refcount": "1" 78 | }, 79 | "com.apple.driver.AppleIntelPIIXATA": { 80 | "size": 36864, 81 | "version": "2.0.0", 82 | "index": "41", 83 | "refcount": "0" 84 | }, 85 | "com.apple.driver.AppleSmartBatteryManager": { 86 | "size": 28672, 87 | "version": "158.6.0", 88 | "index": "32", 89 | "refcount": "0" 90 | }, 91 | "com.apple.filesystems.udf": { 92 | "size": 233472, 93 | "version": "2.0.2", 94 | "index": "119", 95 | "refcount": "0" 96 | }, 97 | "com.apple.iokit.IOSMBusFamily": { 98 | "size": 12288, 99 | "version": "1.1", 100 | "index": "27", 101 | "refcount": "2" 102 | }, 103 | "com.apple.iokit.IOACPIFamily": { 104 | "size": 16384, 105 | "version": "1.2.0", 106 | "index": "18", 107 | "refcount": "10" 108 | }, 109 | "foo.tap": { 110 | "size": 24576, 111 | "version": "1.0", 112 | "index": "113", 113 | "refcount": "0" 114 | }, 115 | "com.vmware.kext.vmx86": { 116 | "size": 864256, 117 | "version": "2.0.4", 118 | "index": "104", 119 | "refcount": "0" 120 | }, 121 | "com.apple.iokit.CHUDUtils": { 122 | "size": 28672, 123 | "version": "200", 124 | "index": "98", 125 | "refcount": "0" 126 | }, 127 | "org.virtualbox.kext.VBoxNetAdp": { 128 | "size": 8192, 129 | "version": "2.2.0", 130 | "index": "117", 131 | "refcount": "0" 132 | }, 133 | "com.apple.filesystems.autofs": { 134 | "size": 45056, 135 | "version": "2.0.1", 136 | "index": "109", 137 | "refcount": "0" 138 | }, 139 | "com.vmware.kext.vmnet": { 140 | "size": 36864, 141 | "version": "2.0.4", 142 | "index": "108", 143 | "refcount": "0" 144 | }, 145 | "com.apple.driver.AppleACPIButtons": { 146 | "size": 16384, 147 | "version": "1.2.4", 148 | "index": "30", 149 | "refcount": "0" 150 | }, 151 | "com.apple.driver.AppleFWOHCI": { 152 | "size": 139264, 153 | "version": "3.7.2", 154 | "index": "50", 155 | "refcount": "0" 156 | }, 157 | "com.apple.iokit.IOSCSIArchitectureModelFamily": { 158 | "size": 102400, 159 | "version": "2.0.5", 160 | "index": "51", 161 | "refcount": "4" 162 | }, 163 | "com.apple.iokit.IOSCSIBlockCommandsDevice": { 164 | "size": 90112, 165 | "version": "2.0.5", 166 | "index": "57", 167 | "refcount": "1" 168 | }, 169 | "com.apple.driver.AppleACPIPCI": { 170 | "size": 12288, 171 | "version": "1.2.4", 172 | "index": "31", 173 | "refcount": "0" 174 | }, 175 | "com.apple.security.seatbelt": { 176 | "size": 98304, 177 | "version": "107.10", 178 | "index": "25", 179 | "refcount": "0" 180 | }, 181 | "com.apple.driver.AppleUpstreamUserClient": { 182 | "size": 16384, 183 | "version": "2.7.2", 184 | "index": "100", 185 | "refcount": "0" 186 | }, 187 | "com.apple.kext.OSvKernDSPLib": { 188 | "size": 12288, 189 | "version": "1.1", 190 | "index": "79", 191 | "refcount": "1" 192 | }, 193 | "com.apple.iokit.IOBDStorageFamily": { 194 | "size": 20480, 195 | "version": "1.5", 196 | "index": "58", 197 | "refcount": "1" 198 | }, 199 | "com.apple.iokit.IOGraphicsFamily": { 200 | "size": 118784, 201 | "version": "1.7.1", 202 | "index": "70", 203 | "refcount": "5" 204 | }, 205 | "com.apple.iokit.IONetworkingFamily": { 206 | "size": 90112, 207 | "version": "1.6.1", 208 | "index": "82", 209 | "refcount": "4" 210 | }, 211 | "com.apple.iokit.IOATAFamily": { 212 | "size": 53248, 213 | "version": "2.0.0", 214 | "index": "40", 215 | "refcount": "2" 216 | }, 217 | "com.apple.iokit.IOUSBHIDDriver": { 218 | "size": 20480, 219 | "version": "3.2.2", 220 | "index": "63", 221 | "refcount": "2" 222 | }, 223 | "org.virtualbox.kext.VBoxUSB": { 224 | "size": 28672, 225 | "version": "2.2.0", 226 | "index": "115", 227 | "refcount": "0" 228 | }, 229 | "com.vmware.kext.vmioplug": { 230 | "size": 24576, 231 | "version": "2.0.4", 232 | "index": "107", 233 | "refcount": "0" 234 | }, 235 | "com.apple.security.TMSafetyNet": { 236 | "size": 12288, 237 | "version": "3", 238 | "index": "23", 239 | "refcount": "0" 240 | }, 241 | "com.apple.iokit.IONDRVSupport": { 242 | "size": 57344, 243 | "version": "1.7.1", 244 | "index": "71", 245 | "refcount": "3" 246 | }, 247 | "com.apple.BootCache": { 248 | "size": 20480, 249 | "version": "30.3", 250 | "index": "20", 251 | "refcount": "0" 252 | }, 253 | "com.apple.iokit.IOUSBUserClient": { 254 | "size": 8192, 255 | "version": "3.2.4", 256 | "index": "46", 257 | "refcount": "1" 258 | }, 259 | "com.apple.iokit.IOSCSIMultimediaCommandsDevice": { 260 | "size": 90112, 261 | "version": "2.0.5", 262 | "index": "59", 263 | "refcount": "0" 264 | }, 265 | "com.apple.driver.AppleIRController": { 266 | "size": 20480, 267 | "version": "110", 268 | "index": "78", 269 | "refcount": "0" 270 | }, 271 | "com.apple.driver.AudioIPCDriver": { 272 | "size": 16384, 273 | "version": "1.0.5", 274 | "index": "81", 275 | "refcount": "0" 276 | }, 277 | "org.virtualbox.kext.VBoxNetFlt": { 278 | "size": 16384, 279 | "version": "2.2.0", 280 | "index": "116", 281 | "refcount": "0" 282 | }, 283 | "com.apple.driver.AppleLPC": { 284 | "size": 12288, 285 | "version": "1.2.11", 286 | "index": "73", 287 | "refcount": "0" 288 | }, 289 | "com.apple.iokit.CHUDKernLib": { 290 | "size": 20480, 291 | "version": "196", 292 | "index": "93", 293 | "refcount": "2" 294 | }, 295 | "com.apple.iokit.CHUDProf": { 296 | "size": 49152, 297 | "version": "207", 298 | "index": "97", 299 | "refcount": "0" 300 | }, 301 | "com.apple.NVDAResman": { 302 | "size": 2478080, 303 | "version": "5.3.6", 304 | "index": "90", 305 | "refcount": "2" 306 | }, 307 | "com.apple.driver.AppleACPIEC": { 308 | "size": 20480, 309 | "version": "1.2.4", 310 | "index": "28", 311 | "refcount": "0" 312 | }, 313 | "foo.tun": { 314 | "size": 24576, 315 | "version": "1.0", 316 | "index": "118", 317 | "refcount": "0" 318 | }, 319 | "com.apple.iokit.IOSerialFamily": { 320 | "size": 36864, 321 | "version": "9.3", 322 | "index": "102", 323 | "refcount": "1" 324 | }, 325 | "com.apple.GeForce": { 326 | "size": 622592, 327 | "version": "5.3.6", 328 | "index": "96", 329 | "refcount": "0" 330 | }, 331 | "com.apple.iokit.IOCDStorageFamily": { 332 | "size": 32768, 333 | "version": "1.5", 334 | "index": "55", 335 | "refcount": "3" 336 | }, 337 | "com.apple.driver.AppleUSBEHCI": { 338 | "size": 73728, 339 | "version": "3.2.5", 340 | "index": "39", 341 | "refcount": "0" 342 | }, 343 | "com.apple.nvidia.nv50hal": { 344 | "size": 2445312, 345 | "version": "5.3.6", 346 | "index": "91", 347 | "refcount": "0" 348 | }, 349 | "com.apple.driver.AppleSMBIOS": { 350 | "size": 16384, 351 | "version": "1.1.1", 352 | "index": "29", 353 | "refcount": "0" 354 | }, 355 | "com.apple.driver.AppleBacklight": { 356 | "size": 16384, 357 | "version": "1.4.4", 358 | "index": "72", 359 | "refcount": "0" 360 | }, 361 | "com.apple.driver.AppleACPIPlatform": { 362 | "size": 253952, 363 | "version": "1.2.4", 364 | "index": "19", 365 | "refcount": "3" 366 | }, 367 | "com.apple.iokit.SCSITaskUserClient": { 368 | "size": 24576, 369 | "version": "2.0.5", 370 | "index": "54", 371 | "refcount": "0" 372 | }, 373 | "com.apple.iokit.IOHIDFamily": { 374 | "size": 233472, 375 | "version": "1.5.3", 376 | "index": "21", 377 | "refcount": "7" 378 | }, 379 | "com.apple.driver.DiskImages": { 380 | "size": 65536, 381 | "version": "195.2.2", 382 | "index": "101", 383 | "refcount": "0" 384 | }, 385 | "com.apple.iokit.IODVDStorageFamily": { 386 | "size": 24576, 387 | "version": "1.5", 388 | "index": "56", 389 | "refcount": "2" 390 | }, 391 | "com.apple.driver.XsanFilter": { 392 | "size": 20480, 393 | "version": "2.7.91", 394 | "index": "53", 395 | "refcount": "0" 396 | }, 397 | "com.apple.driver.AppleEFIRuntime": { 398 | "size": 12288, 399 | "version": "1.2.0", 400 | "index": "35", 401 | "refcount": "1" 402 | }, 403 | "com.apple.driver.AppleRTC": { 404 | "size": 20480, 405 | "version": "1.2.3", 406 | "index": "34", 407 | "refcount": "0" 408 | }, 409 | "com.apple.iokit.IOFireWireIP": { 410 | "size": 36864, 411 | "version": "1.7.6", 412 | "index": "83", 413 | "refcount": "0" 414 | }, 415 | "com.vmware.kext.vmci": { 416 | "size": 45056, 417 | "version": "2.0.4", 418 | "index": "106", 419 | "refcount": "0" 420 | }, 421 | "com.apple.iokit.IO80211Family": { 422 | "size": 126976, 423 | "version": "215.1", 424 | "index": "87", 425 | "refcount": "1" 426 | }, 427 | "com.apple.nke.applicationfirewall": { 428 | "size": 32768, 429 | "version": "1.0.77", 430 | "index": "24", 431 | "refcount": "0" 432 | }, 433 | "com.apple.iokit.IOAHCIBlockStorage": { 434 | "size": 69632, 435 | "version": "1.2.0", 436 | "index": "48", 437 | "refcount": "0" 438 | }, 439 | "com.apple.driver.AppleUSBUHCI": { 440 | "size": 57344, 441 | "version": "3.2.5", 442 | "index": "38", 443 | "refcount": "0" 444 | }, 445 | "com.apple.iokit.IOAHCIFamily": { 446 | "size": 24576, 447 | "version": "1.5.0", 448 | "index": "42", 449 | "refcount": "2" 450 | }, 451 | "com.apple.driver.AppleAHCIPort": { 452 | "size": 53248, 453 | "version": "1.5.2", 454 | "index": "43", 455 | "refcount": "0" 456 | }, 457 | "com.apple.driver.AppleEFINVRAM": { 458 | "size": 24576, 459 | "version": "1.2.0", 460 | "index": "36", 461 | "refcount": "0" 462 | }, 463 | "com.apple.iokit.IOUSBFamily": { 464 | "size": 167936, 465 | "version": "3.2.7", 466 | "index": "37", 467 | "refcount": "13" 468 | }, 469 | "com.apple.driver.AppleUSBMergeNub": { 470 | "size": 12288, 471 | "version": "3.2.4", 472 | "index": "61", 473 | "refcount": "0" 474 | } 475 | }, 476 | "machine": "i386", 477 | "name": "Darwin", 478 | "os": "Darwin", 479 | "version": "Darwin Kernel Version 9.6.0: Mon Nov 24 17:37:00 PST 2008; root:xnu-1228.9.59~1\/RELEASE_I386", 480 | "release": "9.6.0" 481 | }, 482 | "platform_version": "10.5.6", 483 | "platform": "mac_os_x", 484 | "ipaddress": "192.168.88.1", 485 | "keys": { 486 | "ssh": { 487 | "host_dsa_public": "private", 488 | "host_rsa_public": "private" 489 | } 490 | }, 491 | "network": { 492 | "settings": { 493 | "net.inet6.ip6.forwarding": "0", 494 | "net.inet.ip.dummynet.debug": "0", 495 | "net.inet.ip.rtexpire": "10", 496 | "net.inet6.ipsec6.esp_trans_deflev": "1", 497 | "net.inet.tcp.tcbhashsize": "4096", 498 | "net.key.esp_auth": "0", 499 | "net.inet6.ip6.hlim": "64", 500 | "net.inet.ip.fw.dyn_fin_lifetime": "1", 501 | "net.inet.ip.fw.dyn_udp_lifetime": "10", 502 | "net.inet.icmp.bmcastecho": "1", 503 | "net.athforceBias": "2 2", 504 | "net.athbgscan": "1 1", 505 | "net.inet.tcp.reass.maxsegments": "2048", 506 | "net.inet6.ip6.auto_flowlabel": "1", 507 | "net.inet6.ip6.rtmaxcache": "128", 508 | "net.inet.tcp.sendspace": "131072", 509 | "net.inet.tcp.keepinit": "75000", 510 | "net.inet.ip.dummynet.max_chain_len": "16", 511 | "net.inet.tcp.rfc1644": "0", 512 | "net.inet.ip.fw.curr_dyn_buckets": "256", 513 | "net.inet.ip.dummynet.ready_heap": "0", 514 | "net.inet.ip.portrange.first": "49152", 515 | "net.inet.tcp.background_io_trigger": "5", 516 | "net.link.ether.inet.host_down_time": "20", 517 | "net.inet6.ipsec6.def_policy": "1", 518 | "net.inet6.ipsec6.ecn": "0", 519 | "net.inet.ip.fastforwarding": "0", 520 | "net.athaddbaignore": "0 0", 521 | "net.inet6.ip6.v6only": "0", 522 | "net.inet.tcp.sack": "1", 523 | "net.inet6.ip6.rtexpire": "3600", 524 | "net.link.ether.inet.proxyall": "0", 525 | "net.inet6.ip6.keepfaith": "0", 526 | "net.key.spi_trycnt": "1000", 527 | "net.link.ether.inet.prune_intvl": "300", 528 | "net.inet.tcp.ecn_initiate_out": "0", 529 | "net.inet.ip.fw.dyn_rst_lifetime": "1", 530 | "net.local.stream.sendspace": "8192", 531 | "net.inet.tcp.socket_unlocked_on_output": "1", 532 | "net.inet.ip.fw.verbose_limit": "0", 533 | "net.local.dgram.recvspace": "4096", 534 | "net.inet.ipsec.debug": "0", 535 | "net.link.ether.inet.log_arp_warnings": "0", 536 | "net.inet.tcp.ecn_negotiate_in": "0", 537 | "net.inet.tcp.rfc3465": "1", 538 | "net.inet.tcp.icmp_may_rst": "1", 539 | "net.link.ether.inet.sendllconflict": "0", 540 | "net.inet.ipsec.ah_offsetmask": "0", 541 | "net.key.blockacq_count": "10", 542 | "net.inet.tcp.delayed_ack": "3", 543 | "net.inet.ip.fw.verbose": "2", 544 | "net.inet.ip.fw.dyn_count": "0", 545 | "net.inet.tcp.slowlink_wsize": "8192", 546 | "net.inet6.ip6.fw.enable": "1", 547 | "net.inet.ip.portrange.hilast": "65535", 548 | "net.inet.icmp.maskrepl": "0", 549 | "net.link.ether.inet.apple_hwcksum_rx": "1", 550 | "net.inet.tcp.drop_synfin": "1", 551 | "net.key.spi_maxval": "268435455", 552 | "net.inet.ipsec.ecn": "0", 553 | "net.inet.ip.fw.dyn_keepalive": "1", 554 | "net.key.int_random": "60", 555 | "net.key.debug": "0", 556 | "net.inet.ip.dummynet.curr_time": "0", 557 | "net.inet.udp.blackhole": "0", 558 | "net.athaggrqmin": "1 1", 559 | "net.athppmenable": "1 1", 560 | "net.inet.ip.fw.dyn_syn_lifetime": "20", 561 | "net.inet.tcp.keepidle": "7200000", 562 | "net.inet6.ip6.tempvltime": "604800", 563 | "net.inet.tcp.recvspace": "358400", 564 | "net.inet.tcp.keepintvl": "75000", 565 | "net.inet.udp.maxdgram": "9216", 566 | "net.inet.ip.maxchainsent": "0", 567 | "net.inet.ipsec.esp_net_deflev": "1", 568 | "net.inet6.icmp6.nd6_useloopback": "1", 569 | "net.inet.tcp.slowstart_flightsize": "1", 570 | "net.inet.ip.fw.debug": "0", 571 | "net.inet.ip.linklocal.in.allowbadttl": "1", 572 | "net.key.spi_minval": "256", 573 | "net.inet.ip.forwarding": "0", 574 | "net.inet.tcp.v6mssdflt": "1024", 575 | "net.key.larval_lifetime": "30", 576 | "net.inet6.ip6.fw.verbose_limit": "0", 577 | "net.inet.ip.dummynet.red_lookup_depth": "256", 578 | "net.inet.tcp.pcbcount": "36", 579 | "net.inet.ip.fw.dyn_ack_lifetime": "300", 580 | "net.inet.ip.portrange.lowlast": "600", 581 | "net.athCCAThreshold": "28 28", 582 | "net.link.ether.inet.useloopback": "1", 583 | "net.athqdepth": "0 0", 584 | "net.inet.ip.ttl": "64", 585 | "net.inet.ip.rtmaxcache": "128", 586 | "net.inet.ipsec.bypass": "0", 587 | "net.inet6.icmp6.nd6_debug": "0", 588 | "net.inet.ip.use_route_genid": "1", 589 | "net.inet6.icmp6.rediraccept": "1", 590 | "net.inet.ip.fw.static_count": "1", 591 | "net.inet6.ip6.fw.debug": "0", 592 | "net.inet.udp.pcbcount": "104", 593 | "net.inet.ipsec.esp_randpad": "-1", 594 | "net.inet6.icmp6.nd6_maxnudhint": "0", 595 | "net.inet.tcp.always_keepalive": "0", 596 | "net.inet.udp.checksum": "1", 597 | "net.link.ether.inet.keep_announcements": "1", 598 | "net.athfixedDropThresh": "150 150", 599 | "net.inet6.ip6.kame_version": "20010528\/apple-darwin", 600 | "net.inet.ip.fw.dyn_max": "4096", 601 | "net.inet.udp.log_in_vain": "0", 602 | "net.inet6.icmp6.nd6_mmaxtries": "3", 603 | "net.inet.ip.rtminexpire": "10", 604 | "net.inet.ip.fw.dyn_buckets": "256", 605 | "net.inet6.ip6.accept_rtadv": "0", 606 | "net.inet6.ip6.rr_prune": "5", 607 | "net.key.ah_keymin": "128", 608 | "net.inet.ip.redirect": "1", 609 | "net.inet.tcp.sack_globalmaxholes": "65536", 610 | "net.inet.ip.keepfaith": "0", 611 | "net.inet.ip.dummynet.expire": "1", 612 | "net.inet.ip.gifttl": "30", 613 | "net.inet.ip.portrange.last": "65535", 614 | "net.inet.ipsec.ah_net_deflev": "1", 615 | "net.inet6.icmp6.nd6_delay": "5", 616 | "net.inet.tcp.packetchain": "50", 617 | "net.inet6.ip6.hdrnestlimit": "50", 618 | "net.inet.tcp.newreno": "0", 619 | "net.inet6.ip6.dad_count": "1", 620 | "net.inet6.ip6.auto_linklocal": "1", 621 | "net.inet6.ip6.temppltime": "86400", 622 | "net.inet.tcp.strict_rfc1948": "0", 623 | "net.athdupie": "1 1", 624 | "net.inet.ip.dummynet.red_max_pkt_size": "1500", 625 | "net.inet.ip.maxfrags": "2048", 626 | "net.inet.tcp.log_in_vain": "0", 627 | "net.inet.tcp.rfc1323": "1", 628 | "net.inet.ip.subnets_are_local": "0", 629 | "net.inet.ip.dummynet.search_steps": "0", 630 | "net.inet.icmp.icmplim": "250", 631 | "net.link.ether.inet.apple_hwcksum_tx": "1", 632 | "net.inet6.icmp6.redirtimeout": "600", 633 | "net.inet.ipsec.ah_cleartos": "1", 634 | "net.inet6.ip6.log_interval": "5", 635 | "net.link.ether.inet.max_age": "1200", 636 | "net.inet.ip.fw.enable": "1", 637 | "net.inet6.ip6.redirect": "1", 638 | "net.athaggrfmax": "28 28", 639 | "net.inet.ip.maxfragsperpacket": "128", 640 | "net.inet6.ip6.use_deprecated": "1", 641 | "net.link.generic.system.dlil_input_sanity_check": "0", 642 | "net.inet.tcp.sack_globalholes": "0", 643 | "net.inet.tcp.reass.cursegments": "0", 644 | "net.inet6.icmp6.nodeinfo": "3", 645 | "net.local.inflight": "0", 646 | "net.inet.ip.dummynet.hash_size": "64", 647 | "net.inet.ip.dummynet.red_avg_pkt_size": "512", 648 | "net.inet.ipsec.dfbit": "0", 649 | "net.inet.tcp.reass.overflows": "0", 650 | "net.inet.tcp.rexmt_thresh": "2", 651 | "net.inet6.ip6.maxfrags": "8192", 652 | "net.inet6.ip6.rtminexpire": "10", 653 | "net.inet6.ipsec6.esp_net_deflev": "1", 654 | "net.inet.tcp.blackhole": "0", 655 | "net.key.esp_keymin": "256", 656 | "net.inet.ip.check_interface": "0", 657 | "net.inet.tcp.minmssoverload": "0", 658 | "net.link.ether.inet.maxtries": "5", 659 | "net.inet.tcp.do_tcpdrain": "0", 660 | "net.inet.ipsec.esp_port": "4500", 661 | "net.inet6.ipsec6.ah_net_deflev": "1", 662 | "net.inet.ip.dummynet.extract_heap": "0", 663 | "net.inet.tcp.path_mtu_discovery": "1", 664 | "net.inet.ip.intr_queue_maxlen": "50", 665 | "net.inet.ipsec.def_policy": "1", 666 | "net.inet.ip.fw.autoinc_step": "100", 667 | "net.inet.ip.accept_sourceroute": "0", 668 | "net.inet.raw.maxdgram": "8192", 669 | "net.inet.ip.maxfragpackets": "1024", 670 | "net.inet.ip.fw.one_pass": "0", 671 | "net.appletalk.routermix": "2000", 672 | "net.inet.tcp.tcp_lq_overflow": "1", 673 | "net.link.generic.system.ifcount": "9", 674 | "net.link.ether.inet.send_conflicting_probes": "1", 675 | "net.inet.tcp.background_io_enabled": "1", 676 | "net.inet6.ipsec6.debug": "0", 677 | "net.inet.tcp.win_scale_factor": "3", 678 | "net.key.natt_keepalive_interval": "20", 679 | "net.inet.tcp.msl": "15000", 680 | "net.inet.ip.portrange.hifirst": "49152", 681 | "net.inet.ipsec.ah_trans_deflev": "1", 682 | "net.inet.tcp.rtt_min": "1", 683 | "net.inet6.ip6.defmcasthlim": "1", 684 | "net.inet6.icmp6.nd6_prune": "1", 685 | "net.inet6.ip6.fw.verbose": "0", 686 | "net.inet.ip.portrange.lowfirst": "1023", 687 | "net.inet.tcp.maxseg_unacked": "8", 688 | "net.local.dgram.maxdgram": "2048", 689 | "net.key.blockacq_lifetime": "20", 690 | "net.inet.tcp.sack_maxholes": "128", 691 | "net.inet6.ip6.maxfragpackets": "1024", 692 | "net.inet6.ip6.use_tempaddr": "0", 693 | "net.athpowermode": "0 0", 694 | "net.inet.udp.recvspace": "73728", 695 | "net.inet.tcp.isn_reseed_interval": "0", 696 | "net.inet.tcp.local_slowstart_flightsize": "8", 697 | "net.inet.ip.dummynet.searches": "0", 698 | "net.inet.ip.intr_queue_drops": "0", 699 | "net.link.generic.system.multi_threaded_input": "1", 700 | "net.inet.raw.recvspace": "8192", 701 | "net.inet.ipsec.esp_trans_deflev": "1", 702 | "net.key.prefered_oldsa": "0", 703 | "net.local.stream.recvspace": "8192", 704 | "net.inet.tcp.sockthreshold": "64", 705 | "net.inet6.icmp6.nd6_umaxtries": "3", 706 | "net.pstimeout": "20 20", 707 | "net.inet.ip.sourceroute": "0", 708 | "net.inet.ip.fw.dyn_short_lifetime": "5", 709 | "net.inet.tcp.minmss": "216", 710 | "net.inet6.ip6.gifhlim": "0", 711 | "net.athvendorie": "1 1", 712 | "net.inet.ip.check_route_selfref": "1", 713 | "net.inet6.icmp6.errppslimit": "100", 714 | "net.inet.tcp.mssdflt": "512", 715 | "net.inet.icmp.log_redirect": "0", 716 | "net.inet6.ipsec6.ah_trans_deflev": "1", 717 | "net.inet6.ipsec6.esp_randpad": "-1", 718 | "net.inet.icmp.drop_redirect": "0", 719 | "net.inet.icmp.timestamp": "0", 720 | "net.inet.ip.random_id": "1" 721 | }, 722 | "interfaces": { 723 | "vmnet1": { 724 | "flags": [ 725 | "UP", 726 | "BROADCAST", 727 | "SMART", 728 | "RUNNING", 729 | "SIMPLEX", 730 | "MULTICAST" 731 | ], 732 | "addresses": [ 733 | { 734 | "broadcast": "192.168.88.255", 735 | "netmask": "255.255.255.0", 736 | "family": "inet", 737 | "address": "192.168.88.1" 738 | }, 739 | { 740 | "family": "lladdr", 741 | "address": "private" 742 | } 743 | ], 744 | "number": "1", 745 | "mtu": "1500", 746 | "type": "vmnet", 747 | "encapsulation": "Ethernet" 748 | }, 749 | "stf0": { 750 | "flags": [ 751 | 752 | ], 753 | "number": "0", 754 | "mtu": "1280", 755 | "type": "stf", 756 | "encapsulation": "6to4" 757 | }, 758 | "vboxnet0": { 759 | "flags": [ 760 | "BROADCAST", 761 | "RUNNING", 762 | "SIMPLEX", 763 | "MULTICAST" 764 | ], 765 | "addresses": [ 766 | { 767 | "family": "lladdr", 768 | "address": "private" 769 | } 770 | ], 771 | "number": "0", 772 | "mtu": "1500", 773 | "type": "vboxnet", 774 | "encapsulation": "Ethernet" 775 | }, 776 | "lo0": { 777 | "flags": [ 778 | "UP", 779 | "LOOPBACK", 780 | "RUNNING", 781 | "MULTICAST" 782 | ], 783 | "addresses": [ 784 | { 785 | "scope": "Link", 786 | "prefixlen": "64", 787 | "family": "inet6", 788 | "address": "fe80::1" 789 | }, 790 | { 791 | "netmask": "255.0.0.0", 792 | "family": "inet", 793 | "address": "127.0.0.1" 794 | }, 795 | { 796 | "scope": "Node", 797 | "prefixlen": "128", 798 | "family": "inet6", 799 | "address": "::1" 800 | }, 801 | { 802 | "scope": "Node", 803 | "prefixlen": "128", 804 | "family": "inet6", 805 | "address": "private" 806 | } 807 | ], 808 | "number": "0", 809 | "mtu": "16384", 810 | "type": "lo", 811 | "encapsulation": "Loopback" 812 | }, 813 | "vboxn": { 814 | "counters": { 815 | "tx": { 816 | "bytes": "0", 817 | "packets": "0", 818 | "collisions": "0", 819 | "compressed": 0, 820 | "carrier": 0, 821 | "drop": 0, 822 | "errors": "0", 823 | "overrun": 0 824 | }, 825 | "rx": { 826 | "bytes": "0", 827 | "packets": "0", 828 | "compressed": 0, 829 | "drop": 0, 830 | "errors": "0", 831 | "overrun": 0, 832 | "frame": 0, 833 | "multicast": 0 834 | } 835 | } 836 | }, 837 | "gif0": { 838 | "flags": [ 839 | "POINTOPOINT", 840 | "MULTICAST" 841 | ], 842 | "number": "0", 843 | "mtu": "1280", 844 | "type": "gif", 845 | "encapsulation": "IPIP" 846 | }, 847 | "vmnet": { 848 | "counters": { 849 | "tx": { 850 | "bytes": "0", 851 | "packets": "0", 852 | "collisions": "0", 853 | "compressed": 0, 854 | "carrier": 0, 855 | "drop": 0, 856 | "errors": "0", 857 | "overrun": 0 858 | }, 859 | "rx": { 860 | "bytes": "0", 861 | "packets": "0", 862 | "compressed": 0, 863 | "drop": 0, 864 | "errors": "0", 865 | "overrun": 0, 866 | "frame": 0, 867 | "multicast": 0 868 | } 869 | } 870 | }, 871 | "vmnet8": { 872 | "flags": [ 873 | "UP", 874 | "BROADCAST", 875 | "SMART", 876 | "RUNNING", 877 | "SIMPLEX", 878 | "MULTICAST" 879 | ], 880 | "addresses": [ 881 | { 882 | "broadcast": "192.168.237.255", 883 | "netmask": "255.255.255.0", 884 | "family": "inet", 885 | "address": "192.168.237.1" 886 | }, 887 | { 888 | "family": "lladdr", 889 | "address": "private" 890 | } 891 | ], 892 | "number": "8", 893 | "mtu": "1500", 894 | "type": "vmnet", 895 | "encapsulation": "Ethernet" 896 | }, 897 | "en0": { 898 | "status": "inactive", 899 | "flags": [ 900 | "UP", 901 | "BROADCAST", 902 | "SMART", 903 | "RUNNING", 904 | "SIMPLEX", 905 | "MULTICAST" 906 | ], 907 | "addresses": [ 908 | { 909 | "family": "lladdr", 910 | "address": "private" 911 | } 912 | ], 913 | "number": "0", 914 | "mtu": "1500", 915 | "media": { 916 | "supported": [ 917 | { 918 | "autoselect": { 919 | "options": [ 920 | 921 | ] 922 | } 923 | }, 924 | { 925 | "10baseT\/UTP": { 926 | "options": [ 927 | "half-duplex" 928 | ] 929 | } 930 | }, 931 | { 932 | "10baseT\/UTP": { 933 | "options": [ 934 | "full-duplex" 935 | ] 936 | } 937 | }, 938 | { 939 | "10baseT\/UTP": { 940 | "options": [ 941 | "full-duplex", 942 | "hw-loopback" 943 | ] 944 | } 945 | }, 946 | { 947 | "10baseT\/UTP": { 948 | "options": [ 949 | "full-duplex", 950 | "flow-control" 951 | ] 952 | } 953 | }, 954 | { 955 | "100baseTX": { 956 | "options": [ 957 | "half-duplex" 958 | ] 959 | } 960 | }, 961 | { 962 | "100baseTX": { 963 | "options": [ 964 | "full-duplex" 965 | ] 966 | } 967 | }, 968 | { 969 | "100baseTX": { 970 | "options": [ 971 | "full-duplex", 972 | "hw-loopback" 973 | ] 974 | } 975 | }, 976 | { 977 | "100baseTX": { 978 | "options": [ 979 | "full-duplex", 980 | "flow-control" 981 | ] 982 | } 983 | }, 984 | { 985 | "1000baseT": { 986 | "options": [ 987 | "full-duplex" 988 | ] 989 | } 990 | }, 991 | { 992 | "1000baseT": { 993 | "options": [ 994 | "full-duplex", 995 | "hw-loopback" 996 | ] 997 | } 998 | }, 999 | { 1000 | "1000baseT": { 1001 | "options": [ 1002 | "full-duplex", 1003 | "flow-control" 1004 | ] 1005 | } 1006 | }, 1007 | { 1008 | "none": { 1009 | "options": [ 1010 | 1011 | ] 1012 | } 1013 | } 1014 | ], 1015 | "selected": [ 1016 | { 1017 | "autoselect": { 1018 | "options": [ 1019 | 1020 | ] 1021 | } 1022 | } 1023 | ] 1024 | }, 1025 | "type": "en", 1026 | "counters": { 1027 | "tx": { 1028 | "bytes": "342", 1029 | "packets": "0", 1030 | "collisions": "0", 1031 | "compressed": 0, 1032 | "carrier": 0, 1033 | "drop": 0, 1034 | "errors": "0", 1035 | "overrun": 0 1036 | }, 1037 | "rx": { 1038 | "bytes": "0", 1039 | "packets": "0", 1040 | "compressed": 0, 1041 | "drop": 0, 1042 | "errors": "0", 1043 | "overrun": 0, 1044 | "frame": 0, 1045 | "multicast": 0 1046 | } 1047 | }, 1048 | "encapsulation": "Ethernet" 1049 | }, 1050 | "en1": { 1051 | "status": "active", 1052 | "flags": [ 1053 | "UP", 1054 | "BROADCAST", 1055 | "SMART", 1056 | "RUNNING", 1057 | "SIMPLEX", 1058 | "MULTICAST" 1059 | ], 1060 | "addresses": [ 1061 | { 1062 | "scope": "Link", 1063 | "prefixlen": "64", 1064 | "family": "inet6", 1065 | "address": "private" 1066 | }, 1067 | { 1068 | "broadcast": "192.168.1.255", 1069 | "netmask": "255.255.255.0", 1070 | "family": "inet", 1071 | "address": "192.168.1.4" 1072 | }, 1073 | { 1074 | "family": "lladdr", 1075 | "address": "private" 1076 | } 1077 | ], 1078 | "number": "1", 1079 | "mtu": "1500", 1080 | "media": { 1081 | "supported": [ 1082 | { 1083 | "autoselect": { 1084 | "options": [ 1085 | 1086 | ] 1087 | } 1088 | } 1089 | ], 1090 | "selected": [ 1091 | { 1092 | "autoselect": { 1093 | "options": [ 1094 | 1095 | ] 1096 | } 1097 | } 1098 | ] 1099 | }, 1100 | "type": "en", 1101 | "counters": { 1102 | "tx": { 1103 | "bytes": "449206298", 1104 | "packets": "7041789", 1105 | "collisions": "0", 1106 | "compressed": 0, 1107 | "carrier": 0, 1108 | "drop": 0, 1109 | "errors": "95", 1110 | "overrun": 0 1111 | }, 1112 | "rx": { 1113 | "bytes": "13673879120", 1114 | "packets": "19966002", 1115 | "compressed": 0, 1116 | "drop": 0, 1117 | "errors": "1655893", 1118 | "overrun": 0, 1119 | "frame": 0, 1120 | "multicast": 0 1121 | } 1122 | }, 1123 | "arp": { 1124 | "192.168.1.7": "private" 1125 | }, 1126 | "encapsulation": "Ethernet" 1127 | }, 1128 | "fw0": { 1129 | "status": "inactive", 1130 | "flags": [ 1131 | "UP", 1132 | "BROADCAST", 1133 | "SMART", 1134 | "RUNNING", 1135 | "SIMPLEX", 1136 | "MULTICAST" 1137 | ], 1138 | "addresses": [ 1139 | { 1140 | "family": "lladdr", 1141 | "address": "private" 1142 | } 1143 | ], 1144 | "number": "0", 1145 | "mtu": "4078", 1146 | "media": { 1147 | "supported": [ 1148 | { 1149 | "autoselect": { 1150 | "options": [ 1151 | "full-duplex" 1152 | ] 1153 | } 1154 | } 1155 | ], 1156 | "selected": [ 1157 | { 1158 | "autoselect": { 1159 | "options": [ 1160 | "full-duplex" 1161 | ] 1162 | } 1163 | } 1164 | ] 1165 | }, 1166 | "type": "fw", 1167 | "counters": { 1168 | "tx": { 1169 | "bytes": "346", 1170 | "packets": "0", 1171 | "collisions": "0", 1172 | "compressed": 0, 1173 | "carrier": 0, 1174 | "drop": 0, 1175 | "errors": "0", 1176 | "overrun": 0 1177 | }, 1178 | "rx": { 1179 | "bytes": "0", 1180 | "packets": "0", 1181 | "compressed": 0, 1182 | "drop": 0, 1183 | "errors": "0", 1184 | "overrun": 0, 1185 | "frame": 0, 1186 | "multicast": 0 1187 | } 1188 | }, 1189 | "encapsulation": "1394" 1190 | } 1191 | } 1192 | }, 1193 | "fqdn": "local.local", 1194 | "ohai_time": 1240624355.08575, 1195 | "domain": "local", 1196 | "os": "darwin", 1197 | "platform_build": "9G55", 1198 | "os_version": "9.6.0", 1199 | "hostname": "local", 1200 | "macaddress": "private", 1201 | "languages": { 1202 | "ruby": { 1203 | "target_os": "darwin9.0", 1204 | "platform": "universal-darwin9.0", 1205 | "host_vendor": "apple", 1206 | "target_vendor": "apple", 1207 | "target_cpu": "i686", 1208 | "host_os": "darwin9.0", 1209 | "host_cpu": "i686", 1210 | "version": "1.8.6", 1211 | "host": "i686-apple-darwin9.0", 1212 | "target": "i686-apple-darwin9.0", 1213 | "release_date": "2008-03-03" 1214 | } 1215 | } 1216 | } 1217 | --------------------------------------------------------------------------------