oj 1.2.0 → 1.2.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of oj might be problematic. Click here for more details.
- data/README.md +3 -3
- data/ext/oj/dump.c +79 -87
- data/ext/oj/extconf.rb +32 -2
- data/ext/oj/fast.c +26 -37
- data/ext/oj/load.c +83 -79
- data/ext/oj/oj.c +120 -117
- data/ext/oj/oj.h +28 -39
- data/lib/oj/version.rb +1 -1
- data/test/tests.rb +119 -15
- metadata +3 -2
data/ext/oj/oj.h
CHANGED
@@ -41,50 +41,38 @@ extern "C" {
|
|
41
41
|
#define RSTRING_NOT_MODIFIED
|
42
42
|
|
43
43
|
#include "ruby.h"
|
44
|
-
#
|
45
|
-
// HAVE_RUBY_ENCODING_H defined for Ruby 1.9
|
46
|
-
#define IVAR_HELPERS 1
|
44
|
+
#if HAS_ENCODING_SUPPORT
|
47
45
|
#include "ruby/encoding.h"
|
48
46
|
#endif
|
49
47
|
|
50
48
|
#include "cache.h"
|
51
49
|
|
52
|
-
#ifdef
|
53
|
-
#define NO_RSTRUCT 1
|
54
|
-
#endif
|
55
|
-
|
56
|
-
#if (defined RBX_Qnil && !defined RUBINIUS)
|
57
|
-
#define RUBINIUS
|
58
|
-
#endif
|
59
|
-
|
60
|
-
#ifdef RUBINIUS
|
50
|
+
#ifdef RUBINIUS_RUBY
|
61
51
|
#undef T_RATIONAL
|
62
52
|
#undef T_COMPLEX
|
63
|
-
|
64
|
-
#ifndef IVAR_HELPERS
|
65
|
-
#define IVAR_HELPERS 0
|
66
|
-
#endif
|
67
|
-
#endif
|
68
|
-
|
69
|
-
#if IVAR_HELPERS
|
70
|
-
#include "ruby/st.h"
|
53
|
+
enum st_retval {ST_CONTINUE = 0, ST_STOP = 1, ST_DELETE = 2, ST_CHECK};
|
71
54
|
#else
|
55
|
+
#if HAS_TOP_LEVEL_ST_H
|
56
|
+
// Only on travis, local is where it is for all others. Seems to vary depending on the travis machine picked up.
|
72
57
|
#include "st.h"
|
58
|
+
#else
|
59
|
+
#include "ruby/st.h"
|
60
|
+
#endif
|
73
61
|
#endif
|
74
62
|
|
75
63
|
#define raise_error(msg, xml, current) _oj_raise_error(msg, xml, current, __FILE__, __LINE__)
|
76
64
|
|
77
65
|
typedef enum {
|
78
|
-
Yes
|
79
|
-
No
|
66
|
+
Yes = 'y',
|
67
|
+
No = 'n',
|
80
68
|
NotSet = 0
|
81
69
|
} YesNo;
|
82
70
|
|
83
71
|
typedef enum {
|
84
|
-
StrictMode
|
85
|
-
ObjectMode
|
86
|
-
NullMode
|
87
|
-
CompatMode
|
72
|
+
StrictMode = 's',
|
73
|
+
ObjectMode = 'o',
|
74
|
+
NullMode = 'n',
|
75
|
+
CompatMode = 'c'
|
88
76
|
} Mode;
|
89
77
|
|
90
78
|
typedef struct _DumpOpts {
|
@@ -101,12 +89,12 @@ typedef struct _DumpOpts {
|
|
101
89
|
} *DumpOpts;
|
102
90
|
|
103
91
|
typedef struct _Options {
|
104
|
-
int
|
105
|
-
char
|
106
|
-
char
|
107
|
-
char
|
108
|
-
char
|
109
|
-
char
|
92
|
+
int indent; // indention for dump, default 2
|
93
|
+
char circular; // YesNo
|
94
|
+
char auto_define; // YesNo
|
95
|
+
char sym_key; // YesNo
|
96
|
+
char ascii_only; // YesNo
|
97
|
+
char mode; // Mode
|
110
98
|
DumpOpts dump_opts;
|
111
99
|
} *Options;
|
112
100
|
|
@@ -119,11 +107,11 @@ enum {
|
|
119
107
|
typedef struct _Leaf {
|
120
108
|
struct _Leaf *next;
|
121
109
|
union {
|
122
|
-
const char *key;
|
123
|
-
size_t index;
|
110
|
+
const char *key; // hash key
|
111
|
+
size_t index; // array index, 0 is not set
|
124
112
|
};
|
125
113
|
union {
|
126
|
-
char *str;
|
114
|
+
char *str; // pointer to location in json string
|
127
115
|
struct _Leaf *elements; // array and hash elements
|
128
116
|
VALUE value;
|
129
117
|
};
|
@@ -142,9 +130,9 @@ extern void _oj_raise_error(const char *msg, const char *xml, const char *curren
|
|
142
130
|
|
143
131
|
extern void oj_init_doc(void);
|
144
132
|
|
145
|
-
extern VALUE
|
133
|
+
extern VALUE Oj;
|
146
134
|
extern struct _Options oj_default_options;
|
147
|
-
#
|
135
|
+
#if HAS_ENCODING_SUPPORT
|
148
136
|
extern rb_encoding *oj_utf8_encoding;
|
149
137
|
#endif
|
150
138
|
|
@@ -166,9 +154,10 @@ extern ID oj_to_json_id;
|
|
166
154
|
extern ID oj_to_sym_id;
|
167
155
|
extern ID oj_tv_nsec_id;
|
168
156
|
extern ID oj_tv_sec_id;
|
157
|
+
extern ID oj_tv_usec_id;
|
169
158
|
|
170
|
-
extern Cache
|
171
|
-
extern Cache
|
159
|
+
extern Cache oj_class_cache;
|
160
|
+
extern Cache oj_attr_cache;
|
172
161
|
|
173
162
|
#if defined(__cplusplus)
|
174
163
|
#if 0
|
data/lib/oj/version.rb
CHANGED
data/test/tests.rb
CHANGED
@@ -8,6 +8,9 @@ require 'test/unit'
|
|
8
8
|
require 'stringio'
|
9
9
|
require 'oj'
|
10
10
|
|
11
|
+
$ruby = RUBY_DESCRIPTION.split(' ')[0]
|
12
|
+
$ruby = 'ree' if 'ruby' == $ruby && RUBY_DESCRIPTION.include?('Ruby Enterprise Edition')
|
13
|
+
|
11
14
|
def hash_eql(h1, h2)
|
12
15
|
return false if h1.size != h2.size
|
13
16
|
h1.keys.each do |k|
|
@@ -45,6 +48,37 @@ class Jeez < Jam
|
|
45
48
|
end
|
46
49
|
end # Jeez
|
47
50
|
|
51
|
+
# contributed by sauliusg to fix as_json
|
52
|
+
class Orange < Jam
|
53
|
+
def initialize(x, y)
|
54
|
+
super
|
55
|
+
end
|
56
|
+
|
57
|
+
def as_json()
|
58
|
+
{ :json_class => self.class,
|
59
|
+
:x => @x,
|
60
|
+
:y => @y }
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.json_create(h)
|
64
|
+
self.new(h['x'], h['y'])
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
class Melon < Jam
|
69
|
+
def initialize(x, y)
|
70
|
+
super
|
71
|
+
end
|
72
|
+
|
73
|
+
def as_json()
|
74
|
+
"#{x} #{y}"
|
75
|
+
end
|
76
|
+
|
77
|
+
def self.json_create(h)
|
78
|
+
self.new(h['x'], h['y'])
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
48
82
|
class Jazz < Jam
|
49
83
|
def initialize(x, y)
|
50
84
|
super
|
@@ -126,8 +160,8 @@ class Juice < ::Test::Unit::TestCase
|
|
126
160
|
dump_and_load(12345.6789, false)
|
127
161
|
dump_and_load(-54321.012, false)
|
128
162
|
dump_and_load(2.48e16, false)
|
129
|
-
dump_and_load(2.
|
130
|
-
dump_and_load(-2.
|
163
|
+
dump_and_load(2.48e100 * 1.0e10, false)
|
164
|
+
dump_and_load(-2.48e100 * 1.0e10, false)
|
131
165
|
end
|
132
166
|
|
133
167
|
def test_string
|
@@ -283,7 +317,7 @@ class Juice < ::Test::Unit::TestCase
|
|
283
317
|
assert_equal({ 1 => true, 'nil' => nil, :sim => 4 }, h)
|
284
318
|
end
|
285
319
|
|
286
|
-
# Object with to_json()
|
320
|
+
# Object with to_json()
|
287
321
|
def test_json_object_strict
|
288
322
|
obj = Jeez.new(true, 58)
|
289
323
|
begin
|
@@ -301,16 +335,21 @@ class Juice < ::Test::Unit::TestCase
|
|
301
335
|
Oj.default_options = { :mode => :compat }
|
302
336
|
obj = Jeez.new(true, 58)
|
303
337
|
json = Oj.dump(obj, :indent => 2)
|
304
|
-
|
338
|
+
assert(%{{"json_class":"Jeez","x":true,"y":58}} == json ||
|
339
|
+
%{{"json_class":"Jeez","y":58,"x":true}} == json)
|
305
340
|
dump_and_load(obj, false)
|
306
341
|
end
|
307
342
|
def test_json_object_object
|
308
343
|
obj = Jeez.new(true, 58)
|
309
344
|
json = Oj.dump(obj, :mode => :object, :indent => 2)
|
310
|
-
|
345
|
+
assert(%{{
|
311
346
|
"^o":"Jeez",
|
312
347
|
"x":true,
|
313
|
-
"y":58}}
|
348
|
+
"y":58}} == json ||
|
349
|
+
%{{
|
350
|
+
"^o":"Jeez",
|
351
|
+
"y":58,
|
352
|
+
"x":true}} == json)
|
314
353
|
obj2 = Oj.load(json, :mode => :object)
|
315
354
|
assert_equal(obj, obj2)
|
316
355
|
end
|
@@ -338,9 +377,58 @@ class Juice < ::Test::Unit::TestCase
|
|
338
377
|
def test_to_hash_object_object
|
339
378
|
obj = Jazz.new(true, 58)
|
340
379
|
json = Oj.dump(obj, :mode => :object, :indent => 2)
|
341
|
-
|
380
|
+
assert(%{{
|
342
381
|
"^o":"Jazz",
|
343
382
|
"x":true,
|
383
|
+
"y":58}} == json ||
|
384
|
+
%{{
|
385
|
+
"^o":"Jazz",
|
386
|
+
"y":58,
|
387
|
+
"x":true}} == json)
|
388
|
+
obj2 = Oj.load(json, :mode => :object)
|
389
|
+
assert_equal(obj, obj2)
|
390
|
+
end
|
391
|
+
|
392
|
+
# Object with as_json() # contributed by sauliusg
|
393
|
+
def test_as_json_object_strict
|
394
|
+
obj = Orange.new(true, 58)
|
395
|
+
begin
|
396
|
+
json = Oj.dump(obj, :mode => :strict)
|
397
|
+
rescue Exception => e
|
398
|
+
assert(true)
|
399
|
+
end
|
400
|
+
end
|
401
|
+
|
402
|
+
def test_as_json_object_null
|
403
|
+
obj = Orange.new(true, 58)
|
404
|
+
json = Oj.dump(obj, :mode => :null)
|
405
|
+
assert_equal('null', json)
|
406
|
+
end
|
407
|
+
|
408
|
+
def test_as_json_object_compat_hash
|
409
|
+
Oj.default_options = { :mode => :compat }
|
410
|
+
obj = Orange.new(true, 58)
|
411
|
+
json = Oj.dump(obj, :indent => 2)
|
412
|
+
assert_equal(%{{
|
413
|
+
"json_class":"Orange",
|
414
|
+
"x":true,
|
415
|
+
"y":58}}, json)
|
416
|
+
dump_and_load(obj, false)
|
417
|
+
end
|
418
|
+
|
419
|
+
def test_as_json_object_compat_non_hash
|
420
|
+
Oj.default_options = { :mode => :compat }
|
421
|
+
obj = Melon.new(true, 58)
|
422
|
+
json = Oj.dump(obj, :indent => 2)
|
423
|
+
assert_equal(%{"true 58"}, json)
|
424
|
+
end
|
425
|
+
|
426
|
+
def test_as_json_object_object
|
427
|
+
obj = Orange.new(true, 58)
|
428
|
+
json = Oj.dump(obj, :mode => :object, :indent => 2)
|
429
|
+
assert_equal(%{{
|
430
|
+
"^o":"Orange",
|
431
|
+
"x":true,
|
344
432
|
"y":58}}, json)
|
345
433
|
obj2 = Oj.load(json, :mode => :object)
|
346
434
|
assert_equal(obj, obj2)
|
@@ -363,17 +451,24 @@ class Juice < ::Test::Unit::TestCase
|
|
363
451
|
def test_object_compat
|
364
452
|
obj = Jam.new(true, 58)
|
365
453
|
json = Oj.dump(obj, :mode => :compat, :indent => 2)
|
366
|
-
|
454
|
+
assert(%{{
|
367
455
|
"x":true,
|
368
|
-
"y":58}}
|
456
|
+
"y":58}} == json ||
|
457
|
+
%{{
|
458
|
+
"y":58,
|
459
|
+
"x":true}} == json)
|
369
460
|
end
|
370
461
|
def test_object_object
|
371
462
|
obj = Jam.new(true, 58)
|
372
463
|
json = Oj.dump(obj, :mode => :object, :indent => 2)
|
373
|
-
|
464
|
+
assert(%{{
|
374
465
|
"^o":"Jam",
|
375
466
|
"x":true,
|
376
|
-
"y":58}}
|
467
|
+
"y":58}} == json ||
|
468
|
+
%{{
|
469
|
+
"^o":"Jam",
|
470
|
+
"y":58,
|
471
|
+
"x":true}} == json)
|
377
472
|
obj2 = Oj.load(json, :mode => :object)
|
378
473
|
assert_equal(obj, obj2)
|
379
474
|
end
|
@@ -390,7 +485,7 @@ class Juice < ::Test::Unit::TestCase
|
|
390
485
|
#puts "*** #{json}"
|
391
486
|
e2 = Oj.load(json, :mode => :strict)
|
392
487
|
assert_equal(err.class.to_s, e2['^o'])
|
393
|
-
unless RUBY_VERSION.start_with?('1.8')
|
488
|
+
unless RUBY_VERSION.start_with?('1.8') || 'rubinius' == $ruby
|
394
489
|
assert_equal(err.message, e2['~mesg'])
|
395
490
|
assert_equal(err.backtrace, e2['~bt'])
|
396
491
|
e2 = Oj.load(json, :mode => :object)
|
@@ -423,7 +518,11 @@ class Juice < ::Test::Unit::TestCase
|
|
423
518
|
unless RUBY_VERSION.start_with?('1.8')
|
424
519
|
Oj.default_options = { :mode => :object }
|
425
520
|
json = Oj.dump(1..7, :mode => :object, :indent => 0)
|
426
|
-
|
521
|
+
if 'rubinius' == $ruby
|
522
|
+
assert_equal(%{{"^o":"Range","excl":false,"begin":1,"end":7}}, json)
|
523
|
+
else
|
524
|
+
assert_equal(%{{"^u":["Range",1,7,false]}}, json)
|
525
|
+
end
|
427
526
|
dump_and_load(1..7, false)
|
428
527
|
dump_and_load(1..1, false)
|
429
528
|
dump_and_load(1...7, false)
|
@@ -447,11 +546,16 @@ class Juice < ::Test::Unit::TestCase
|
|
447
546
|
obj = Jam.new(nil, 58)
|
448
547
|
obj.x = obj
|
449
548
|
json = Oj.dump(obj, :mode => :object, :indent => 2, :circular => true)
|
450
|
-
|
549
|
+
assert(%{{
|
451
550
|
"^o":"Jam",
|
452
551
|
"^i":1,
|
453
552
|
"x":"^r1",
|
454
|
-
"y":58}}
|
553
|
+
"y":58}} == json ||
|
554
|
+
%{{
|
555
|
+
"^o":"Jam",
|
556
|
+
"^i":1,
|
557
|
+
"y":58,
|
558
|
+
"x":"^r1"}} == json)
|
455
559
|
obj2 = Oj.load(json, :mode => :object, :circular => true)
|
456
560
|
assert_equal(obj2.x.__id__, obj2.__id__)
|
457
561
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: oj
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
4
|
+
version: 1.2.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-03-30 00:00:00.
|
12
|
+
date: 2012-03-30 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: ! 'The fastest JSON parser and object serializer. '
|
15
15
|
email: peter@ohler.com
|
@@ -88,3 +88,4 @@ signing_key:
|
|
88
88
|
specification_version: 3
|
89
89
|
summary: A fast JSON parser and serializer.
|
90
90
|
test_files: []
|
91
|
+
has_rdoc: true
|