oj 2.18.5 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +33 -226
- data/ext/oj/circarray.c +0 -25
- data/ext/oj/circarray.h +0 -25
- data/ext/oj/code.c +227 -0
- data/ext/oj/code.h +40 -0
- data/ext/oj/compat.c +126 -38
- data/ext/oj/custom.c +1097 -0
- data/ext/oj/dump.c +658 -2376
- data/ext/oj/dump.h +92 -0
- data/ext/oj/dump_compat.c +937 -0
- data/ext/oj/dump_leaf.c +254 -0
- data/ext/oj/dump_object.c +810 -0
- data/ext/oj/dump_rails.c +329 -0
- data/ext/oj/dump_strict.c +416 -0
- data/ext/oj/err.c +0 -25
- data/ext/oj/err.h +8 -2
- data/ext/oj/fast.c +24 -24
- data/ext/oj/mimic_json.c +817 -0
- data/ext/oj/mimic_rails.c +806 -0
- data/ext/oj/mimic_rails.h +17 -0
- data/ext/oj/object.c +18 -72
- data/ext/oj/odd.c +0 -25
- data/ext/oj/odd.h +2 -27
- data/ext/oj/oj.c +655 -1503
- data/ext/oj/oj.h +93 -40
- data/ext/oj/parse.c +99 -46
- data/ext/oj/parse.h +12 -26
- data/ext/oj/reader.c +1 -25
- data/ext/oj/reader.h +3 -25
- data/ext/oj/resolve.c +9 -11
- data/ext/oj/resolve.h +2 -2
- data/ext/oj/rxclass.c +133 -0
- data/ext/oj/rxclass.h +27 -0
- data/ext/oj/saj.c +4 -25
- data/ext/oj/scp.c +3 -25
- data/ext/oj/sparse.c +89 -13
- data/ext/oj/stream_writer.c +301 -0
- data/ext/oj/strict.c +4 -27
- data/ext/oj/string_writer.c +480 -0
- data/ext/oj/val_stack.h +6 -2
- data/lib/oj.rb +1 -23
- data/lib/oj/easy_hash.rb +12 -4
- data/lib/oj/json.rb +172 -0
- data/lib/oj/mimic.rb +123 -18
- data/lib/oj/state.rb +131 -0
- data/lib/oj/version.rb +1 -1
- data/pages/Advanced.md +22 -0
- data/pages/Compatibility.md +25 -0
- data/pages/Custom.md +23 -0
- data/pages/Encoding.md +65 -0
- data/pages/JsonGem.md +79 -0
- data/pages/Modes.md +140 -0
- data/pages/Options.md +250 -0
- data/pages/Rails.md +60 -0
- data/pages/Security.md +20 -0
- data/test/activesupport4/decoding_test.rb +105 -0
- data/test/activesupport4/encoding_test.rb +531 -0
- data/test/activesupport4/test_helper.rb +41 -0
- data/test/activesupport5/decoding_test.rb +125 -0
- data/test/activesupport5/encoding_test.rb +483 -0
- data/test/activesupport5/encoding_test_cases.rb +90 -0
- data/test/activesupport5/test_helper.rb +50 -0
- data/test/activesupport5/time_zone_test_helpers.rb +24 -0
- data/test/json_gem/json_addition_test.rb +216 -0
- data/test/json_gem/json_common_interface_test.rb +143 -0
- data/test/json_gem/json_encoding_test.rb +109 -0
- data/test/json_gem/json_ext_parser_test.rb +20 -0
- data/test/json_gem/json_fixtures_test.rb +35 -0
- data/test/json_gem/json_generator_test.rb +383 -0
- data/test/json_gem/json_generic_object_test.rb +90 -0
- data/test/json_gem/json_parser_test.rb +470 -0
- data/test/json_gem/json_string_matching_test.rb +42 -0
- data/test/json_gem/test_helper.rb +18 -0
- data/test/perf_compat.rb +30 -28
- data/test/perf_object.rb +1 -1
- data/test/perf_strict.rb +18 -1
- data/test/sample.rb +0 -1
- data/test/test_compat.rb +169 -93
- data/test/test_custom.rb +355 -0
- data/test/test_file.rb +0 -8
- data/test/test_null.rb +376 -0
- data/test/test_object.rb +268 -3
- data/test/test_scp.rb +22 -1
- data/test/test_strict.rb +160 -4
- data/test/test_various.rb +52 -620
- data/test/tests.rb +14 -0
- data/test/tests_mimic.rb +14 -0
- data/test/tests_mimic_addition.rb +7 -0
- metadata +89 -47
- data/test/activesupport_datetime_test.rb +0 -23
- data/test/bug.rb +0 -51
- data/test/bug2.rb +0 -10
- data/test/bug3.rb +0 -46
- data/test/bug_fast.rb +0 -32
- data/test/bug_load.rb +0 -24
- data/test/crash.rb +0 -111
- data/test/curl/curl_oj.rb +0 -46
- data/test/curl/get_oj.rb +0 -24
- data/test/curl/just_curl.rb +0 -31
- data/test/curl/just_oj.rb +0 -51
- data/test/example.rb +0 -11
- data/test/foo.rb +0 -24
- data/test/io.rb +0 -48
- data/test/isolated/test_mimic_rails_datetime.rb +0 -27
- data/test/mod.rb +0 -16
- data/test/rails.rb +0 -50
- data/test/russian.rb +0 -18
- data/test/struct.rb +0 -29
- data/test/test_serializer.rb +0 -59
- data/test/write_timebars.rb +0 -31
data/ext/oj/val_stack.h
CHANGED
@@ -58,7 +58,10 @@ typedef struct _Val {
|
|
58
58
|
char karray[32];
|
59
59
|
volatile VALUE key_val;
|
60
60
|
union {
|
61
|
-
|
61
|
+
struct {
|
62
|
+
const char *classname;
|
63
|
+
VALUE clas;
|
64
|
+
};
|
62
65
|
OddArgs odd_args;
|
63
66
|
};
|
64
67
|
uint16_t klen;
|
@@ -127,7 +130,8 @@ stack_push(ValStack stack, VALUE val, ValNext next) {
|
|
127
130
|
}
|
128
131
|
stack->tail->val = val;
|
129
132
|
stack->tail->next = next;
|
130
|
-
stack->tail->classname =
|
133
|
+
stack->tail->classname = NULL;
|
134
|
+
stack->tail->clas = Qundef;
|
131
135
|
stack->tail->key = 0;
|
132
136
|
stack->tail->key_val = Qundef;
|
133
137
|
stack->tail->clen = 0;
|
data/lib/oj.rb
CHANGED
@@ -1,26 +1,4 @@
|
|
1
|
-
|
2
|
-
# optimized JSON handling.
|
3
|
-
#
|
4
|
-
# Oj has several dump or serialization modes which control how Objects are
|
5
|
-
# converted to JSON. These modes are set with the :mode option in either the
|
6
|
-
# default options or as one of the options to the dump() method.
|
7
|
-
#
|
8
|
-
# - :strict mode will only allow the 7 basic JSON types to be serialized. Any other Object
|
9
|
-
# will raise and Exception.
|
10
|
-
#
|
11
|
-
# - :null mode replaces any Object that is not one of the JSON types is replaced by a JSON null.
|
12
|
-
#
|
13
|
-
# - :object mode will dump any Object as a JSON Object with keys that match
|
14
|
-
# the Ruby Object's variable names without the '@' character. This is the
|
15
|
-
# highest performance mode.
|
16
|
-
#
|
17
|
-
# - :compat mode is is the compatible with other systems. It will serialize
|
18
|
-
# any Object but will check to see if the Object implements a to_hash() or
|
19
|
-
# to_json() method. If either exists that method is used for serializing the
|
20
|
-
# Object. The to_hash() is more flexible and produces more consistent output
|
21
|
-
# so it has a preference over the to_json() method. If neither the to_json()
|
22
|
-
# or to_hash() methods exist then the Oj internal Object variable encoding
|
23
|
-
# is used.
|
1
|
+
|
24
2
|
module Oj
|
25
3
|
end
|
26
4
|
|
data/lib/oj/easy_hash.rb
CHANGED
@@ -33,10 +33,18 @@ module Oj
|
|
33
33
|
# @raise [ArgumentError] if an argument is given. Zero arguments expected.
|
34
34
|
# @raise [NoMethodError] if the instance variable is not defined.
|
35
35
|
def method_missing(m, *args, &block)
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
36
|
+
if m.to_s.end_with?('=')
|
37
|
+
raise ArgumentError.new("wrong number of arguments (#{args.size} for 1 with #{m}) to method #{m}") if args.nil? or 1 != args.length
|
38
|
+
m = m[0..-2]
|
39
|
+
return store(m.to_s, args[0]) if has_key?(m.to_s)
|
40
|
+
return store(m.to_sym, args[0]) if has_key?(m.to_sym)
|
41
|
+
return store(m, args[0])
|
42
|
+
else
|
43
|
+
raise ArgumentError.new("wrong number of arguments (#{args.size} for 0 with #{m}) to method #{m}") unless args.nil? or args.empty?
|
44
|
+
return fetch(m, nil) if has_key?(m)
|
45
|
+
return fetch(m.to_s, nil) if has_key?(m.to_s)
|
46
|
+
return fetch(m.to_sym, nil) if has_key?(m.to_sym)
|
47
|
+
end
|
40
48
|
raise NoMethodError.new("undefined method #{m}", m)
|
41
49
|
end
|
42
50
|
|
data/lib/oj/json.rb
ADDED
@@ -0,0 +1,172 @@
|
|
1
|
+
|
2
|
+
require 'ostruct'
|
3
|
+
require 'oj/state'
|
4
|
+
|
5
|
+
module JSON
|
6
|
+
NaN = 0.0/0.0 unless defined?(::JSON::NaN)
|
7
|
+
Infinity = 1.0/0.0 unless defined?(::JSON::Infinity)
|
8
|
+
MinusInfinity = -1.0/0.0 unless defined?(::JSON::MinusInfinity)
|
9
|
+
# Taken from the unit test. Note that items like check_circular? are not
|
10
|
+
# present.
|
11
|
+
PRETTY_STATE_PROTOTYPE = Ext::Generator::State.from_state({
|
12
|
+
:allow_nan => false,
|
13
|
+
:array_nl => "\n",
|
14
|
+
:ascii_only => false,
|
15
|
+
:buffer_initial_length => 1024,
|
16
|
+
:depth => 0,
|
17
|
+
:indent => " ",
|
18
|
+
:max_nesting => 100,
|
19
|
+
:object_nl => "\n",
|
20
|
+
:space => " ",
|
21
|
+
:space_before => "",
|
22
|
+
}) unless defined?(::JSON::PRETTY_STATE_PROTOTYPE)
|
23
|
+
SAFE_STATE_PROTOTYPE = Ext::Generator::State.from_state({
|
24
|
+
:allow_nan => false,
|
25
|
+
:array_nl => "",
|
26
|
+
:ascii_only => false,
|
27
|
+
:buffer_initial_length => 1024,
|
28
|
+
:depth => 0,
|
29
|
+
:indent => "",
|
30
|
+
:max_nesting => 100,
|
31
|
+
:object_nl => "",
|
32
|
+
:space => "",
|
33
|
+
:space_before => "",
|
34
|
+
}) unless defined?(::JSON::SAFE_STATE_PROTOTYPE)
|
35
|
+
FAST_STATE_PROTOTYPE = Ext::Generator::State.from_state({
|
36
|
+
:allow_nan => false,
|
37
|
+
:array_nl => "",
|
38
|
+
:ascii_only => false,
|
39
|
+
:buffer_initial_length => 1024,
|
40
|
+
:depth => 0,
|
41
|
+
:indent => "",
|
42
|
+
:max_nesting => 0,
|
43
|
+
:object_nl => "",
|
44
|
+
:space => "",
|
45
|
+
:space_before => "",
|
46
|
+
}) unless defined?(::JSON::FAST_STATE_PROTOTYPE)
|
47
|
+
|
48
|
+
def self.dump_default_options
|
49
|
+
Oj::MimicDumpOption.new
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.dump_default_options=(h)
|
53
|
+
m = Oj::MimicDumpOption.new
|
54
|
+
h.each do |k,v|
|
55
|
+
m[k] = v
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.parser=(p)
|
60
|
+
@@parser = p
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.parser()
|
64
|
+
@@parser
|
65
|
+
end
|
66
|
+
|
67
|
+
def self.generator=(g)
|
68
|
+
@@generator = g
|
69
|
+
end
|
70
|
+
|
71
|
+
def self.generator()
|
72
|
+
@@generator
|
73
|
+
end
|
74
|
+
|
75
|
+
module Ext
|
76
|
+
class Parser
|
77
|
+
def initialize(src)
|
78
|
+
raise TypeError.new("already initialized") unless @source.nil?
|
79
|
+
@source = src
|
80
|
+
end
|
81
|
+
|
82
|
+
def source()
|
83
|
+
raise TypeError.new("already initialized") if @source.nil?
|
84
|
+
@source
|
85
|
+
end
|
86
|
+
|
87
|
+
def parse()
|
88
|
+
raise TypeError.new("already initialized") if @source.nil?
|
89
|
+
JSON.parse(@source)
|
90
|
+
end
|
91
|
+
|
92
|
+
end # Parser
|
93
|
+
end # Ext
|
94
|
+
|
95
|
+
State = ::JSON::Ext::Generator::State
|
96
|
+
|
97
|
+
Parser = ::JSON::Ext::Parser
|
98
|
+
self.parser = ::JSON::Ext::Parser
|
99
|
+
self.generator = ::JSON::Ext::Generator
|
100
|
+
|
101
|
+
# Taken directly from the json gem. Shamelessly copied. It is similar in
|
102
|
+
# some ways to the Oj::Bag class or the Oj::EasyHash class.
|
103
|
+
class GenericObject < OpenStruct
|
104
|
+
class << self
|
105
|
+
alias [] new
|
106
|
+
|
107
|
+
def json_creatable?
|
108
|
+
@json_creatable
|
109
|
+
end
|
110
|
+
|
111
|
+
attr_writer :json_creatable
|
112
|
+
|
113
|
+
def json_create(data)
|
114
|
+
data = data.dup
|
115
|
+
data.delete JSON.create_id
|
116
|
+
self[data]
|
117
|
+
end
|
118
|
+
|
119
|
+
def from_hash(object)
|
120
|
+
case
|
121
|
+
when object.respond_to?(:to_hash)
|
122
|
+
result = new
|
123
|
+
object.to_hash.each do |key, value|
|
124
|
+
result[key] = from_hash(value)
|
125
|
+
end
|
126
|
+
result
|
127
|
+
when object.respond_to?(:to_ary)
|
128
|
+
object.to_ary.map { |a| from_hash(a) }
|
129
|
+
else
|
130
|
+
object
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def load(source, proc = nil, opts = {})
|
135
|
+
result = ::JSON.load(source, proc, opts.merge(:object_class => self))
|
136
|
+
result.nil? ? new : result
|
137
|
+
end
|
138
|
+
|
139
|
+
def dump(obj, *args)
|
140
|
+
::JSON.dump(obj, *args)
|
141
|
+
end
|
142
|
+
|
143
|
+
end # self
|
144
|
+
|
145
|
+
self.json_creatable = false
|
146
|
+
|
147
|
+
def to_hash
|
148
|
+
table
|
149
|
+
end
|
150
|
+
|
151
|
+
def [](name)
|
152
|
+
__send__(name)
|
153
|
+
end unless method_defined?(:[])
|
154
|
+
|
155
|
+
def []=(name, value)
|
156
|
+
__send__("#{name}=", value)
|
157
|
+
end unless method_defined?(:[]=)
|
158
|
+
|
159
|
+
def |(other)
|
160
|
+
self.class[other.to_hash.merge(to_hash)]
|
161
|
+
end
|
162
|
+
|
163
|
+
def as_json(*)
|
164
|
+
{ JSON.create_id => self.class.name }.merge to_hash
|
165
|
+
end
|
166
|
+
|
167
|
+
def to_json(*a)
|
168
|
+
as_json.to_json(*a)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
end # JSON
|
data/lib/oj/mimic.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
|
2
|
+
require 'bigdecimal'
|
2
3
|
begin
|
3
4
|
require 'ostruct'
|
4
5
|
rescue Exception
|
@@ -29,6 +30,8 @@ module Oj
|
|
29
30
|
end
|
30
31
|
end
|
31
32
|
|
33
|
+
# Loads mimic-ed JSON paths. Used by Oj.mimic_JSON().
|
34
|
+
# @param mimic_path [Array] additional paths to add to the Ruby loaded features.
|
32
35
|
def self.mimic_loaded(mimic_paths=[])
|
33
36
|
$LOAD_PATH.each do |d|
|
34
37
|
next unless File.exist?(d)
|
@@ -37,12 +40,15 @@ module Oj
|
|
37
40
|
$LOADED_FEATURES << jfile unless $LOADED_FEATURES.include?(jfile) if File.exist?(jfile)
|
38
41
|
|
39
42
|
Dir.glob(File.join(d, 'json', '**', '*.rb')).each do |file|
|
40
|
-
|
43
|
+
# allow json/add/xxx to be loaded. User can override with Oj.add_to_json(xxx).
|
44
|
+
$LOADED_FEATURES << file unless $LOADED_FEATURES.include?(file) unless file.include?('add')
|
41
45
|
end
|
42
46
|
end
|
43
47
|
mimic_paths.each { |p| $LOADED_FEATURES << p }
|
44
48
|
$LOADED_FEATURES << 'json' unless $LOADED_FEATURES.include?('json')
|
45
49
|
|
50
|
+
require 'oj/json'
|
51
|
+
|
46
52
|
if Object.const_defined?('OpenStruct')
|
47
53
|
OpenStruct.class_eval do
|
48
54
|
# Both the JSON gem and Rails monkey patch as_json. Let them battle it out.
|
@@ -54,9 +60,100 @@ module Oj
|
|
54
60
|
end
|
55
61
|
end
|
56
62
|
def self.json_create(h)
|
57
|
-
new(h['t'])
|
63
|
+
new(h['t'] || h[:t])
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
BigDecimal.class_eval do
|
69
|
+
# Both the JSON gem and Rails monkey patch as_json. Let them battle it out.
|
70
|
+
unless defined?(self.as_json)
|
71
|
+
def as_json(*)
|
72
|
+
{JSON.create_id => 'BigDecimal', 'b' => _dump }
|
73
|
+
end
|
74
|
+
end
|
75
|
+
def self.json_create(h)
|
76
|
+
BigDecimal._load(h['b'])
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
Complex.class_eval do
|
81
|
+
# Both the JSON gem and Rails monkey patch as_json. Let them battle it out.
|
82
|
+
unless defined?(self.as_json)
|
83
|
+
def as_json(*)
|
84
|
+
{JSON.create_id => 'Complex', 'r' => real, 'i' => imag }
|
85
|
+
end
|
86
|
+
end
|
87
|
+
def self.json_create(h)
|
88
|
+
Complex(h['r'], h['i'])
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
Date.class_eval do
|
93
|
+
# Both the JSON gem and Rails monkey patch as_json. Let them battle it out.
|
94
|
+
unless defined?(self.as_json)
|
95
|
+
def as_json(*)
|
96
|
+
{ JSON.create_id => 'Date', 'y' => year, 'm' => month, 'd' => day, 'sg' => start }
|
97
|
+
end
|
98
|
+
end
|
99
|
+
def self.json_create(h)
|
100
|
+
civil(h['y'], h['m'], h['d'], h['sg'])
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
DateTime.class_eval do
|
105
|
+
# Both the JSON gem and Rails monkey patch as_json. Let them battle it out.
|
106
|
+
unless defined?(self.as_json)
|
107
|
+
def as_json(*)
|
108
|
+
{ JSON.create_id => 'DateTime',
|
109
|
+
'y' => year,
|
110
|
+
'm' => month,
|
111
|
+
'd' => day,
|
112
|
+
'H' => hour,
|
113
|
+
'M' => min,
|
114
|
+
'S' => sec,
|
115
|
+
'of' => offset.to_s,
|
116
|
+
'sg' => start }
|
58
117
|
end
|
59
118
|
end
|
119
|
+
def self.json_create(h)
|
120
|
+
# offset is a rational as a string
|
121
|
+
as, bs = h['of'].split('/')
|
122
|
+
a = as.to_i
|
123
|
+
b = bs.to_i
|
124
|
+
if 0 == b
|
125
|
+
off = a
|
126
|
+
else
|
127
|
+
off = Rational(a, b)
|
128
|
+
end
|
129
|
+
civil(h['y'], h['m'], h['d'], h['H'], h['M'], h['S'], off, h['sg'])
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
Date.class_eval do
|
134
|
+
# Both the JSON gem and Rails monkey patch as_json. Let them battle it out.
|
135
|
+
unless defined?(self.as_json)
|
136
|
+
def as_json(*)
|
137
|
+
{ JSON.create_id => 'Date', 'y' => year, 'm' => month, 'd' => day, 'sg' => start }
|
138
|
+
end
|
139
|
+
end
|
140
|
+
def self.json_create(h)
|
141
|
+
civil(h['y'], h['m'], h['d'], h['sg'])
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
Exception.class_eval do
|
146
|
+
# Both the JSON gem and Rails monkey patch as_json. Let them battle it out.
|
147
|
+
unless defined?(self.as_json)
|
148
|
+
def as_json(*)
|
149
|
+
{JSON.create_id => self.class.name, 'm' => message, 'b' => backtrace }
|
150
|
+
end
|
151
|
+
end
|
152
|
+
def self.json_create(h)
|
153
|
+
e = new(h['m'])
|
154
|
+
e.set_backtrace(h['b'])
|
155
|
+
e
|
156
|
+
end
|
60
157
|
end
|
61
158
|
|
62
159
|
Range.class_eval do
|
@@ -67,7 +164,7 @@ module Oj
|
|
67
164
|
end
|
68
165
|
end
|
69
166
|
def self.json_create(h)
|
70
|
-
new(h['a'])
|
167
|
+
new(*h['a'])
|
71
168
|
end
|
72
169
|
end
|
73
170
|
|
@@ -105,7 +202,7 @@ module Oj
|
|
105
202
|
end
|
106
203
|
end
|
107
204
|
def self.json_create(h)
|
108
|
-
new(h['v'])
|
205
|
+
new(*h['v'])
|
109
206
|
end
|
110
207
|
end
|
111
208
|
|
@@ -125,7 +222,6 @@ module Oj
|
|
125
222
|
# Both the JSON gem and Rails monkey patch as_json. Let them battle it out.
|
126
223
|
unless defined?(self.as_json)
|
127
224
|
def as_json(*)
|
128
|
-
{JSON.create_id => 'Symbol', 's' => to_s }
|
129
225
|
nsecs = [ tv_usec * 1000 ]
|
130
226
|
nsecs << tv_nsec if respond_to?(:tv_nsec)
|
131
227
|
nsecs = nsecs.max
|
@@ -144,19 +240,28 @@ module Oj
|
|
144
240
|
end
|
145
241
|
end
|
146
242
|
|
147
|
-
JSON.module_eval do
|
148
|
-
def self.dump_default_options
|
149
|
-
Oj::MimicDumpOption.new
|
150
|
-
end
|
151
|
-
|
152
|
-
def self.dump_default_options=(h)
|
153
|
-
m = Oj::MimicDumpOption.new
|
154
|
-
h.each do |k,v|
|
155
|
-
m[k] = v
|
156
|
-
end
|
157
|
-
end
|
158
|
-
end
|
159
|
-
|
160
243
|
end # self.mimic_loaded
|
161
244
|
|
162
245
|
end # Oj
|
246
|
+
|
247
|
+
# More monkey patches.
|
248
|
+
class String
|
249
|
+
def to_json_raw_object
|
250
|
+
{
|
251
|
+
JSON.create_id => self.class.name,
|
252
|
+
'raw' => self.bytes
|
253
|
+
}
|
254
|
+
end
|
255
|
+
def to_json_raw(*)
|
256
|
+
to_json_raw_object().to_json()
|
257
|
+
end
|
258
|
+
def self.json_create(obj)
|
259
|
+
s = ''
|
260
|
+
s.encode!(Encoding::ASCII_8BIT) if s.respond_to?(:encode!)
|
261
|
+
raw = obj['raw']
|
262
|
+
if raw.is_a? Array
|
263
|
+
raw.each { |v| s << v }
|
264
|
+
end
|
265
|
+
s
|
266
|
+
end
|
267
|
+
end
|
data/lib/oj/state.rb
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
|
2
|
+
module JSON
|
3
|
+
module Ext
|
4
|
+
module Generator
|
5
|
+
unless defined?(::JSON::Ext::Generator::State)
|
6
|
+
# This class exists for json gem compatibility only. While it can be
|
7
|
+
# used as the options for other than compatibility a simple Hash is
|
8
|
+
# recommended as it is simpler and performs better. The only bit
|
9
|
+
# missing by not using a state object is the depth availability which
|
10
|
+
# may be the depth during dumping or maybe not since it can be set and
|
11
|
+
# the docs for depth= is the same as max_nesting. Note: Had to make
|
12
|
+
# this a subclass of Object instead of Hash like EashyHash due to
|
13
|
+
# conflicts with the json gem.
|
14
|
+
class State
|
15
|
+
|
16
|
+
def self.from_state(opts)
|
17
|
+
s = self.new()
|
18
|
+
s.clear()
|
19
|
+
s.merge(opts)
|
20
|
+
s
|
21
|
+
end
|
22
|
+
|
23
|
+
def initialize(opts = {})
|
24
|
+
@attrs = {}
|
25
|
+
|
26
|
+
# Populate with all vars then merge in opts. This class deviates from
|
27
|
+
# the json gem in that any of the options can be set with the opts
|
28
|
+
# argument. The json gem limits the opts use to 7 of the options.
|
29
|
+
@attrs[:indent] = ''
|
30
|
+
@attrs[:space] = ''
|
31
|
+
@attrs[:space_before] = ''
|
32
|
+
@attrs[:array_nl] = ''
|
33
|
+
@attrs[:object_nl] = ''
|
34
|
+
@attrs[:allow_nan] = false
|
35
|
+
@attrs[:buffer_initial_length] = 1024 # completely ignored by Oj
|
36
|
+
@attrs[:depth] = 0
|
37
|
+
@attrs[:max_nesting] = 100
|
38
|
+
@attrs[:check_circular?] = true
|
39
|
+
@attrs[:ascii_only] = false
|
40
|
+
|
41
|
+
@attrs.merge!(opts)
|
42
|
+
end
|
43
|
+
|
44
|
+
def to_h()
|
45
|
+
return @attrs.dup
|
46
|
+
end
|
47
|
+
|
48
|
+
def to_hash()
|
49
|
+
return @attrs.dup
|
50
|
+
end
|
51
|
+
|
52
|
+
def allow_nan?()
|
53
|
+
@attrs[:allow_nan]
|
54
|
+
end
|
55
|
+
|
56
|
+
def ascii_only?()
|
57
|
+
@attrs[:ascii_only]
|
58
|
+
end
|
59
|
+
|
60
|
+
def configure(opts)
|
61
|
+
raise TypeError.new('expected a Hash') unless opts.respond_to?(:to_h)
|
62
|
+
@attrs.merge!(opts.to_h)
|
63
|
+
end
|
64
|
+
|
65
|
+
def generate(obj)
|
66
|
+
JSON.generate(obj)
|
67
|
+
end
|
68
|
+
|
69
|
+
def merge(opts)
|
70
|
+
@attrs.merge!(opts)
|
71
|
+
end
|
72
|
+
|
73
|
+
# special rule for this.
|
74
|
+
def buffer_initial_length=(len)
|
75
|
+
len = 1024 if 0 >= len
|
76
|
+
@attrs[:buffer_initial_length] = len
|
77
|
+
end
|
78
|
+
|
79
|
+
# Replaces the Object.respond_to?() method.
|
80
|
+
# @param [Symbol] m method symbol
|
81
|
+
# @return [Boolean] true for any method that matches an instance
|
82
|
+
# variable reader, otherwise false.
|
83
|
+
def respond_to?(m)
|
84
|
+
return true if super
|
85
|
+
return true if has_key?(key)
|
86
|
+
return true if has_key?(key.to_s)
|
87
|
+
has_key?(key.to_sym)
|
88
|
+
end
|
89
|
+
|
90
|
+
def [](key)
|
91
|
+
key = key.to_sym
|
92
|
+
@attrs.fetch(key, nil)
|
93
|
+
end
|
94
|
+
|
95
|
+
def []=(key, value)
|
96
|
+
key = key.to_sym
|
97
|
+
@attrs[key] = value
|
98
|
+
end
|
99
|
+
|
100
|
+
def clear()
|
101
|
+
@attrs.clear()
|
102
|
+
end
|
103
|
+
|
104
|
+
def has_key?(k)
|
105
|
+
@attrs.has_key?(key.to_sym)
|
106
|
+
end
|
107
|
+
|
108
|
+
# Handles requests for Hash values. Others cause an Exception to be raised.
|
109
|
+
# @param [Symbol|String] m method symbol
|
110
|
+
# @return [Boolean] the value of the specified instance variable.
|
111
|
+
# @raise [ArgumentError] if an argument is given. Zero arguments expected.
|
112
|
+
# @raise [NoMethodError] if the instance variable is not defined.
|
113
|
+
def method_missing(m, *args, &block)
|
114
|
+
if m.to_s.end_with?('=')
|
115
|
+
raise ArgumentError.new("wrong number of arguments (#{args.size} for 1 with #{m}) to method #{m}") if args.nil? or 1 != args.length
|
116
|
+
m = m.to_s[0..-2]
|
117
|
+
m = m.to_sym
|
118
|
+
return @attrs.store(m, args[0])
|
119
|
+
else
|
120
|
+
raise ArgumentError.new("wrong number of arguments (#{args.size} for 0 with #{m}) to method #{m}") unless args.nil? or args.empty?
|
121
|
+
return @attrs[m.to_sym]
|
122
|
+
end
|
123
|
+
raise NoMethodError.new("undefined method #{m}", m)
|
124
|
+
end
|
125
|
+
|
126
|
+
end # State
|
127
|
+
end # defined check
|
128
|
+
end # Generator
|
129
|
+
end # Ext
|
130
|
+
|
131
|
+
end # JSON
|