oj 3.7.4 → 3.11.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +12 -4
- data/ext/oj/buf.h +6 -34
- data/ext/oj/cache8.c +3 -3
- data/ext/oj/cache8.h +5 -33
- data/ext/oj/circarray.c +5 -9
- data/ext/oj/circarray.h +5 -8
- data/ext/oj/code.c +3 -6
- data/ext/oj/code.h +7 -10
- data/ext/oj/compat.c +11 -14
- data/ext/oj/custom.c +108 -75
- data/ext/oj/dump.c +132 -92
- data/ext/oj/dump.h +6 -7
- data/ext/oj/dump_compat.c +37 -34
- data/ext/oj/dump_leaf.c +3 -6
- data/ext/oj/dump_object.c +23 -17
- data/ext/oj/dump_strict.c +7 -9
- data/ext/oj/encode.h +6 -32
- data/ext/oj/err.c +2 -5
- data/ext/oj/err.h +6 -34
- data/ext/oj/extconf.rb +6 -0
- data/ext/oj/fast.c +39 -56
- data/ext/oj/hash.c +11 -39
- data/ext/oj/hash.h +5 -33
- data/ext/oj/hash_test.c +3 -31
- data/ext/oj/mimic_json.c +65 -44
- data/ext/oj/object.c +38 -69
- data/ext/oj/odd.c +18 -17
- data/ext/oj/odd.h +6 -9
- data/ext/oj/oj.c +139 -93
- data/ext/oj/oj.h +43 -35
- data/ext/oj/parse.c +164 -60
- data/ext/oj/parse.h +30 -31
- data/ext/oj/rails.c +119 -83
- data/ext/oj/rails.h +4 -7
- data/ext/oj/reader.c +5 -8
- data/ext/oj/reader.h +7 -10
- data/ext/oj/resolve.c +4 -7
- data/ext/oj/resolve.h +4 -7
- data/ext/oj/rxclass.c +8 -11
- data/ext/oj/rxclass.h +8 -11
- data/ext/oj/saj.c +9 -12
- data/ext/oj/scp.c +4 -7
- data/ext/oj/sparse.c +67 -33
- data/ext/oj/stream_writer.c +16 -15
- data/ext/oj/strict.c +9 -12
- data/ext/oj/string_writer.c +27 -8
- data/ext/oj/trace.c +5 -8
- data/ext/oj/trace.h +9 -12
- data/ext/oj/util.c +136 -0
- data/ext/oj/util.h +19 -0
- data/ext/oj/val_stack.c +28 -36
- data/ext/oj/val_stack.h +19 -50
- data/ext/oj/wab.c +29 -29
- data/lib/oj.rb +0 -8
- data/lib/oj/json.rb +1 -1
- data/lib/oj/mimic.rb +46 -2
- data/lib/oj/version.rb +2 -2
- data/pages/Modes.md +47 -45
- data/pages/Options.md +43 -10
- data/pages/Rails.md +60 -21
- data/pages/Security.md +1 -1
- data/test/activesupport5/abstract_unit.rb +45 -0
- data/test/activesupport5/decoding_test.rb +68 -60
- data/test/activesupport5/encoding_test.rb +111 -96
- data/test/activesupport5/encoding_test_cases.rb +33 -25
- data/test/activesupport5/test_helper.rb +43 -21
- data/test/activesupport5/time_zone_test_helpers.rb +18 -3
- data/test/activesupport6/abstract_unit.rb +44 -0
- data/test/activesupport6/decoding_test.rb +133 -0
- data/test/activesupport6/encoding_test.rb +507 -0
- data/test/activesupport6/encoding_test_cases.rb +98 -0
- data/test/activesupport6/test_common.rb +17 -0
- data/test/activesupport6/test_helper.rb +163 -0
- data/test/activesupport6/time_zone_test_helpers.rb +39 -0
- data/test/bar.rb +24 -6
- data/test/baz.rb +16 -0
- data/test/foo.rb +26 -57
- data/test/helper.rb +10 -0
- data/test/json_gem/json_common_interface_test.rb +8 -3
- data/test/json_gem/json_generator_test.rb +15 -3
- data/test/json_gem/test_helper.rb +8 -0
- data/test/prec.rb +23 -0
- data/test/sample_json.rb +1 -1
- data/test/test_compat.rb +21 -10
- data/test/test_custom.rb +135 -8
- data/test/test_integer_range.rb +1 -2
- data/test/test_object.rb +35 -2
- data/test/test_rails.rb +35 -0
- data/test/test_strict.rb +24 -1
- data/test/test_various.rb +52 -63
- data/test/test_writer.rb +19 -2
- data/test/tests.rb +1 -0
- data/test/zoo.rb +13 -0
- metadata +100 -75
data/ext/oj/encode.h
CHANGED
@@ -1,43 +1,17 @@
|
|
1
|
-
|
2
|
-
* Copyright (c) 2011, Peter Ohler
|
3
|
-
* All rights reserved.
|
4
|
-
*
|
5
|
-
* Redistribution and use in source and binary forms, with or without
|
6
|
-
* modification, are permitted provided that the following conditions are met:
|
7
|
-
*
|
8
|
-
* - Redistributions of source code must retain the above copyright notice, this
|
9
|
-
* list of conditions and the following disclaimer.
|
10
|
-
*
|
11
|
-
* - Redistributions in binary form must reproduce the above copyright notice,
|
12
|
-
* this list of conditions and the following disclaimer in the documentation
|
13
|
-
* and/or other materials provided with the distribution.
|
14
|
-
*
|
15
|
-
* - Neither the name of Peter Ohler nor the names of its contributors may be
|
16
|
-
* used to endorse or promote products derived from this software without
|
17
|
-
* specific prior written permission.
|
18
|
-
*
|
19
|
-
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
20
|
-
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
21
|
-
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
22
|
-
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
23
|
-
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
24
|
-
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
25
|
-
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
26
|
-
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
27
|
-
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
28
|
-
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
29
|
-
*/
|
1
|
+
// Copyright (c) 2011 Peter Ohler. All rights reserved.
|
30
2
|
|
31
|
-
#ifndef
|
32
|
-
#define
|
3
|
+
#ifndef OJ_ENCODE_H
|
4
|
+
#define OJ_ENCODE_H
|
33
5
|
|
34
6
|
#include "ruby.h"
|
35
7
|
#include "ruby/encoding.h"
|
36
8
|
|
9
|
+
#include "oj.h"
|
10
|
+
|
37
11
|
static inline VALUE
|
38
12
|
oj_encode(VALUE rstr) {
|
39
13
|
rb_enc_associate(rstr, oj_utf8_encoding);
|
40
14
|
return rstr;
|
41
15
|
}
|
42
16
|
|
43
|
-
#endif /*
|
17
|
+
#endif /* OJ_ENCODE_H */
|
data/ext/oj/err.c
CHANGED
@@ -1,7 +1,4 @@
|
|
1
|
-
|
2
|
-
* Copyright (c) 2011, Peter Ohler
|
3
|
-
* All rights reserved.
|
4
|
-
*/
|
1
|
+
// Copyright (c) 2011 Peter Ohler. All rights reserved.
|
5
2
|
|
6
3
|
#include <stdarg.h>
|
7
4
|
|
@@ -40,7 +37,7 @@ _oj_err_set_with_location(Err err, VALUE eclas, const char *msg, const char *jso
|
|
40
37
|
|
41
38
|
void
|
42
39
|
_oj_raise_error(const char *msg, const char *json, const char *current, const char* file, int line) {
|
43
|
-
struct
|
40
|
+
struct _err err;
|
44
41
|
int n = 1;
|
45
42
|
int col = 1;
|
46
43
|
|
data/ext/oj/err.h
CHANGED
@@ -1,35 +1,7 @@
|
|
1
|
-
|
2
|
-
* Copyright (c) 2011, Peter Ohler
|
3
|
-
* All rights reserved.
|
4
|
-
*
|
5
|
-
* Redistribution and use in source and binary forms, with or without
|
6
|
-
* modification, are permitted provided that the following conditions are met:
|
7
|
-
*
|
8
|
-
* - Redistributions of source code must retain the above copyright notice, this
|
9
|
-
* list of conditions and the following disclaimer.
|
10
|
-
*
|
11
|
-
* - Redistributions in binary form must reproduce the above copyright notice,
|
12
|
-
* this list of conditions and the following disclaimer in the documentation
|
13
|
-
* and/or other materials provided with the distribution.
|
14
|
-
*
|
15
|
-
* - Neither the name of Peter Ohler nor the names of its contributors may be
|
16
|
-
* used to endorse or promote products derived from this software without
|
17
|
-
* specific prior written permission.
|
18
|
-
*
|
19
|
-
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
20
|
-
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
21
|
-
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
22
|
-
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
23
|
-
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
24
|
-
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
25
|
-
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
26
|
-
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
27
|
-
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
28
|
-
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
29
|
-
*/
|
1
|
+
// Copyright (c) 2011 Peter Ohler. All rights reserved.
|
30
2
|
|
31
|
-
#ifndef
|
32
|
-
#define
|
3
|
+
#ifndef OJ_ERR_H
|
4
|
+
#define OJ_ERR_H
|
33
5
|
|
34
6
|
#include "ruby.h"
|
35
7
|
// Needed to silence 2.4.0 warnings.
|
@@ -37,9 +9,9 @@
|
|
37
9
|
# define NORETURN(x) x
|
38
10
|
#endif
|
39
11
|
|
40
|
-
#define set_error(err, eclas, msg, json, current) _oj_err_set_with_location(err, eclas, msg, json, current,
|
12
|
+
#define set_error(err, eclas, msg, json, current) _oj_err_set_with_location(err, eclas, msg, json, current, FILE, LINE)
|
41
13
|
|
42
|
-
typedef struct
|
14
|
+
typedef struct _err {
|
43
15
|
VALUE clas;
|
44
16
|
char msg[128];
|
45
17
|
} *Err;
|
@@ -67,4 +39,4 @@ err_has(Err e) {
|
|
67
39
|
return (Qnil != e->clas);
|
68
40
|
}
|
69
41
|
|
70
|
-
#endif /*
|
42
|
+
#endif /* OJ_ERR_H */
|
data/ext/oj/extconf.rb
CHANGED
@@ -28,6 +28,7 @@ have_func('rb_ivar_count')
|
|
28
28
|
have_func('rb_ivar_foreach')
|
29
29
|
have_func('stpcpy')
|
30
30
|
have_func('rb_data_object_wrap')
|
31
|
+
have_func('pthread_mutex_init')
|
31
32
|
|
32
33
|
dflags['OJ_DEBUG'] = true unless ENV['OJ_DEBUG'].nil?
|
33
34
|
|
@@ -41,6 +42,11 @@ end
|
|
41
42
|
|
42
43
|
$CPPFLAGS += ' -Wall'
|
43
44
|
#puts "*** $CPPFLAGS: #{$CPPFLAGS}"
|
45
|
+
# Adding the __attribute__ flag only works with gcc compilers and even then it
|
46
|
+
# does not work to check args with varargs so just remove the check.
|
47
|
+
CONFIG['warnflags'].slice!(/ -Wsuggest-attribute=format/)
|
48
|
+
CONFIG['warnflags'].slice!(/ -Wdeclaration-after-statement/)
|
49
|
+
CONFIG['warnflags'].slice!(/ -Wmissing-noreturn/)
|
44
50
|
|
45
51
|
create_makefile(File.join(extension_name, extension_name))
|
46
52
|
|
data/ext/oj/fast.c
CHANGED
@@ -1,32 +1,4 @@
|
|
1
|
-
|
2
|
-
* Copyright (c) 2012, Peter Ohler
|
3
|
-
* All rights reserved.
|
4
|
-
*
|
5
|
-
* Redistribution and use in source and binary forms, with or without
|
6
|
-
* modification, are permitted provided that the following conditions are met:
|
7
|
-
*
|
8
|
-
* - Redistributions of source code must retain the above copyright notice, this
|
9
|
-
* list of conditions and the following disclaimer.
|
10
|
-
*
|
11
|
-
* - Redistributions in binary form must reproduce the above copyright notice,
|
12
|
-
* this list of conditions and the following disclaimer in the documentation
|
13
|
-
* and/or other materials provided with the distribution.
|
14
|
-
*
|
15
|
-
* - Neither the name of Peter Ohler nor the names of its contributors may be
|
16
|
-
* used to endorse or promote products derived from this software without
|
17
|
-
* specific prior written permission.
|
18
|
-
*
|
19
|
-
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
20
|
-
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
21
|
-
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
22
|
-
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
23
|
-
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
24
|
-
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
25
|
-
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
26
|
-
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
27
|
-
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
28
|
-
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
29
|
-
*/
|
1
|
+
// Copyright (c) 2012 Peter Ohler. All rights reserved.
|
30
2
|
|
31
3
|
#if !IS_WINDOWS
|
32
4
|
#include <sys/resource.h> // for getrlimit() on linux
|
@@ -43,16 +15,16 @@
|
|
43
15
|
// maximum to allocate on the stack, arbitrary limit
|
44
16
|
#define SMALL_XML 65536
|
45
17
|
#define MAX_STACK 100
|
46
|
-
//#define BATCH_SIZE (4096 / sizeof(struct
|
18
|
+
//#define BATCH_SIZE (4096 / sizeof(struct _leaf) - 1)
|
47
19
|
#define BATCH_SIZE 100
|
48
20
|
|
49
|
-
typedef struct
|
50
|
-
struct
|
21
|
+
typedef struct _batch {
|
22
|
+
struct _batch *next;
|
51
23
|
int next_avail;
|
52
|
-
struct
|
24
|
+
struct _leaf leaves[BATCH_SIZE];
|
53
25
|
} *Batch;
|
54
26
|
|
55
|
-
typedef struct
|
27
|
+
typedef struct _doc {
|
56
28
|
Leaf data;
|
57
29
|
Leaf *where; // points to current location
|
58
30
|
Leaf where_path[MAX_STACK]; // points to head of path
|
@@ -60,10 +32,10 @@ typedef struct _Doc {
|
|
60
32
|
unsigned long size; // number of leaves/branches in the doc
|
61
33
|
VALUE self;
|
62
34
|
Batch batches;
|
63
|
-
struct
|
35
|
+
struct _batch batch0;
|
64
36
|
} *Doc;
|
65
37
|
|
66
|
-
typedef struct
|
38
|
+
typedef struct _parseInfo {
|
67
39
|
char *str; /* buffer being read from */
|
68
40
|
char *s; /* current position in buffer */
|
69
41
|
Doc doc;
|
@@ -121,7 +93,7 @@ VALUE oj_doc_class = Qundef;
|
|
121
93
|
#ifndef HAVE_STPCPY
|
122
94
|
char *stpcpy(char *dest, const char *src) {
|
123
95
|
size_t cnt = strlen(src);
|
124
|
-
|
96
|
+
|
125
97
|
strcpy(dest, src);
|
126
98
|
|
127
99
|
return dest + cnt;
|
@@ -204,10 +176,10 @@ leaf_new(Doc doc, int type) {
|
|
204
176
|
Leaf leaf;
|
205
177
|
|
206
178
|
if (0 == doc->batches || BATCH_SIZE == doc->batches->next_avail) {
|
207
|
-
Batch b = ALLOC(struct
|
179
|
+
Batch b = ALLOC(struct _batch);
|
208
180
|
|
209
181
|
// Initializes all leaves with a NO_VAL value_type
|
210
|
-
memset(b, 0, sizeof(struct
|
182
|
+
memset(b, 0, sizeof(struct _batch));
|
211
183
|
b->next = doc->batches;
|
212
184
|
doc->batches = b;
|
213
185
|
b->next_avail = 0;
|
@@ -322,7 +294,7 @@ leaf_fixnum_value(Leaf leaf) {
|
|
322
294
|
int64_t n = 0;
|
323
295
|
int neg = 0;
|
324
296
|
int big = 0;
|
325
|
-
|
297
|
+
|
326
298
|
if ('-' == *s) {
|
327
299
|
s++;
|
328
300
|
neg = 1;
|
@@ -337,7 +309,7 @@ leaf_fixnum_value(Leaf leaf) {
|
|
337
309
|
}
|
338
310
|
if (big) {
|
339
311
|
char c = *s;
|
340
|
-
|
312
|
+
|
341
313
|
*s = '\0';
|
342
314
|
leaf->value = rb_cstr_to_inum(leaf->str, 10, 0);
|
343
315
|
*s = c;
|
@@ -672,7 +644,7 @@ read_quoted_value(ParseInfo pi) {
|
|
672
644
|
char *value = 0;
|
673
645
|
char *h = pi->s; // head
|
674
646
|
char *t = h; // tail
|
675
|
-
|
647
|
+
|
676
648
|
h++; // skip quote character
|
677
649
|
t++;
|
678
650
|
value = h;
|
@@ -734,7 +706,7 @@ read_quoted_value(ParseInfo pi) {
|
|
734
706
|
// doc support functions
|
735
707
|
inline static void
|
736
708
|
doc_init(Doc doc) {
|
737
|
-
memset(doc, 0, sizeof(struct
|
709
|
+
memset(doc, 0, sizeof(struct _doc));
|
738
710
|
doc->where = doc->where_path;
|
739
711
|
doc->self = Qundef;
|
740
712
|
doc->batches = &doc->batch0;
|
@@ -805,7 +777,7 @@ static void
|
|
805
777
|
mark_doc(void *ptr) {
|
806
778
|
if (NULL != ptr) {
|
807
779
|
Doc doc = (Doc)ptr;
|
808
|
-
|
780
|
+
|
809
781
|
rb_gc_mark(doc->self);
|
810
782
|
mark_leaf(doc->data);
|
811
783
|
}
|
@@ -813,16 +785,18 @@ mark_doc(void *ptr) {
|
|
813
785
|
|
814
786
|
static VALUE
|
815
787
|
parse_json(VALUE clas, char *json, bool given, bool allocated) {
|
816
|
-
struct
|
788
|
+
struct _parseInfo pi;
|
817
789
|
volatile VALUE result = Qnil;
|
818
790
|
Doc doc;
|
819
791
|
int ex = 0;
|
820
792
|
volatile VALUE self;
|
821
793
|
|
794
|
+
// TBD are both needed? is stack allocation ever needed?
|
795
|
+
|
822
796
|
if (given) {
|
823
|
-
doc = ALLOCA_N(struct
|
797
|
+
doc = ALLOCA_N(struct _doc, 1);
|
824
798
|
} else {
|
825
|
-
doc = ALLOC(struct
|
799
|
+
doc = ALLOC(struct _doc);
|
826
800
|
}
|
827
801
|
/* skip UTF-8 BOM if present */
|
828
802
|
if (0xEF == (uint8_t)*json && 0xBB == (uint8_t)json[1] && 0xBF == (uint8_t)json[2]) {
|
@@ -839,7 +813,7 @@ parse_json(VALUE clas, char *json, bool given, bool allocated) {
|
|
839
813
|
{
|
840
814
|
struct rlimit lim;
|
841
815
|
|
842
|
-
if (0 == getrlimit(RLIMIT_STACK, &lim)) {
|
816
|
+
if (0 == getrlimit(RLIMIT_STACK, &lim) && RLIM_INFINITY != lim.rlim_cur) {
|
843
817
|
pi.stack_min = (void*)((char*)&lim - (lim.rlim_cur / 4 * 3)); // let 3/4ths of the stack be used only
|
844
818
|
} else {
|
845
819
|
pi.stack_min = 0; // indicates not to check stack limit
|
@@ -862,6 +836,7 @@ parse_json(VALUE clas, char *json, bool given, bool allocated) {
|
|
862
836
|
if (allocated && 0 != ex) { // will jump so caller will not free
|
863
837
|
xfree(json);
|
864
838
|
}
|
839
|
+
rb_gc_enable();
|
865
840
|
} else {
|
866
841
|
result = doc->self;
|
867
842
|
}
|
@@ -1165,8 +1140,14 @@ doc_open(VALUE clas, VALUE str) {
|
|
1165
1140
|
} else {
|
1166
1141
|
json = ALLOCA_N(char, len);
|
1167
1142
|
}
|
1143
|
+
// It should not be necessaary to stop GC but if it is not stopped and a
|
1144
|
+
// large string is parsed that string is corrupted or freed during
|
1145
|
+
// parsing. I'm not sure what is going on exactly but disabling GC avoids
|
1146
|
+
// the issue.
|
1147
|
+
rb_gc_disable();
|
1168
1148
|
memcpy(json, StringValuePtr(str), len);
|
1169
1149
|
obj = parse_json(clas, json, given, allocate);
|
1150
|
+
rb_gc_enable();
|
1170
1151
|
if (given && allocate) {
|
1171
1152
|
xfree(json);
|
1172
1153
|
}
|
@@ -1217,12 +1198,14 @@ doc_open_file(VALUE clas, VALUE filename) {
|
|
1217
1198
|
fseek(f, 0, SEEK_SET);
|
1218
1199
|
if (len != fread(json, 1, len, f)) {
|
1219
1200
|
fclose(f);
|
1220
|
-
rb_raise(rb_const_get_at(Oj, rb_intern("LoadError")),
|
1201
|
+
rb_raise(rb_const_get_at(Oj, rb_intern("LoadError")),
|
1221
1202
|
"Failed to read %lu bytes from %s.", (unsigned long)len, path);
|
1222
1203
|
}
|
1223
1204
|
fclose(f);
|
1224
1205
|
json[len] = '\0';
|
1206
|
+
rb_gc_disable();
|
1225
1207
|
obj = parse_json(clas, json, given, allocate);
|
1208
|
+
rb_gc_enable();
|
1226
1209
|
if (given && allocate) {
|
1227
1210
|
xfree(json);
|
1228
1211
|
}
|
@@ -1564,7 +1547,7 @@ doc_each_child(int argc, VALUE *argv, VALUE self) {
|
|
1564
1547
|
* result
|
1565
1548
|
* }
|
1566
1549
|
* #=> [3, 2, 1]
|
1567
|
-
*
|
1550
|
+
*
|
1568
1551
|
* Oj::Doc.open('[3,[2,1]]') { |doc|
|
1569
1552
|
* result = []
|
1570
1553
|
* doc.each_value('/2') { |v| result << v }
|
@@ -1624,7 +1607,7 @@ doc_dump(int argc, VALUE *argv, VALUE self) {
|
|
1624
1607
|
|
1625
1608
|
if (0 == filename) {
|
1626
1609
|
char buf[4096];
|
1627
|
-
struct
|
1610
|
+
struct _out out;
|
1628
1611
|
|
1629
1612
|
out.buf = buf;
|
1630
1613
|
out.end = buf + sizeof(buf) - 10;
|
@@ -1697,21 +1680,21 @@ doc_not_implemented(VALUE self) {
|
|
1697
1680
|
* extracted. Once the document is closed the document can not longer be
|
1698
1681
|
* accessed. This allows the parsing and data extraction to be extremely fast
|
1699
1682
|
* compared to other JSON parses.
|
1700
|
-
*
|
1683
|
+
*
|
1701
1684
|
* An Oj::Doc class is not created directly but the _open()_ class method is
|
1702
1685
|
* used to open a document and the yield parameter to the block of the #open()
|
1703
1686
|
* call is the Doc instance. The Doc instance can be moved across, up, and
|
1704
1687
|
* down the JSON document. At each element the data associated with the
|
1705
1688
|
* element can be extracted. It is also possible to just provide a path to the
|
1706
1689
|
* data to be extracted and retrieve the data in that manner.
|
1707
|
-
*
|
1690
|
+
*
|
1708
1691
|
* For many of the methods a path is used to describe the location of an
|
1709
1692
|
* element. Paths follow a subset of the XPath syntax. The slash ('/')
|
1710
1693
|
* character is the separator. Each step in the path identifies the next
|
1711
1694
|
* branch to take through the document. A JSON object will expect a key string
|
1712
1695
|
* while an array will expect a positive index. A .. step indicates a move up
|
1713
1696
|
* the JSON document.
|
1714
|
-
*
|
1697
|
+
*
|
1715
1698
|
* @example
|
1716
1699
|
* json = %{[
|
1717
1700
|
* {
|
@@ -1725,12 +1708,12 @@ doc_not_implemented(VALUE self) {
|
|
1725
1708
|
* ]}
|
1726
1709
|
* # move and get value
|
1727
1710
|
* Oj::Doc.open(json) do |doc|
|
1728
|
-
* doc.move('/1/two')
|
1711
|
+
* doc.move('/1/two')
|
1729
1712
|
* # doc location is now at the 'two' element of the hash that is the first element of the array.
|
1730
1713
|
* doc.fetch()
|
1731
1714
|
* end
|
1732
1715
|
* #=> 2
|
1733
|
-
*
|
1716
|
+
*
|
1734
1717
|
* # Now try again using a path to Oj::Doc.fetch() directly and not using a block.
|
1735
1718
|
* doc = Oj::Doc.open(json)
|
1736
1719
|
* doc.fetch('/2/three') #=> 3
|
data/ext/oj/hash.c
CHANGED
@@ -1,32 +1,4 @@
|
|
1
|
-
|
2
|
-
* Copyright (c) 2011, Peter Ohler
|
3
|
-
* All rights reserved.
|
4
|
-
*
|
5
|
-
* Redistribution and use in source and binary forms, with or without
|
6
|
-
* modification, are permitted provided that the following conditions are met:
|
7
|
-
*
|
8
|
-
* - Redistributions of source code must retain the above copyright notice, this
|
9
|
-
* list of conditions and the following disclaimer.
|
10
|
-
*
|
11
|
-
* - Redistributions in binary form must reproduce the above copyright notice,
|
12
|
-
* this list of conditions and the following disclaimer in the documentation
|
13
|
-
* and/or other materials provided with the distribution.
|
14
|
-
*
|
15
|
-
* - Neither the name of Peter Ohler nor the names of its contributors may be
|
16
|
-
* used to endorse or promote products derived from this software without
|
17
|
-
* specific prior written permission.
|
18
|
-
*
|
19
|
-
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
20
|
-
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
21
|
-
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
22
|
-
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
23
|
-
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
24
|
-
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
25
|
-
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
26
|
-
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
27
|
-
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
28
|
-
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
29
|
-
*/
|
1
|
+
// Copyright (c) 2011 Peter Ohler. All rights reserved.
|
30
2
|
|
31
3
|
#include "hash.h"
|
32
4
|
#include <stdint.h>
|
@@ -34,19 +6,19 @@
|
|
34
6
|
#define HASH_MASK 0x000003FF
|
35
7
|
#define HASH_SLOT_CNT 1024
|
36
8
|
|
37
|
-
typedef struct
|
38
|
-
struct
|
9
|
+
typedef struct _keyVal {
|
10
|
+
struct _keyVal *next;
|
39
11
|
const char *key;
|
40
12
|
size_t len;
|
41
13
|
VALUE val;
|
42
14
|
} *KeyVal;
|
43
15
|
|
44
|
-
struct
|
45
|
-
struct
|
16
|
+
struct _hash {
|
17
|
+
struct _keyVal slots[HASH_SLOT_CNT];
|
46
18
|
};
|
47
19
|
|
48
|
-
struct
|
49
|
-
struct
|
20
|
+
struct _hash class_hash;
|
21
|
+
struct _hash intern_hash;
|
50
22
|
|
51
23
|
// almost the Murmur hash algorithm
|
52
24
|
#define M 0x5bd1e995
|
@@ -85,7 +57,7 @@ hash_calc(const uint8_t *key, size_t len) {
|
|
85
57
|
h ^= h >> 13;
|
86
58
|
h *= M;
|
87
59
|
h ^= h >> 15;
|
88
|
-
|
60
|
+
|
89
61
|
return h;
|
90
62
|
}
|
91
63
|
|
@@ -114,8 +86,8 @@ hash_get(Hash hash, const char *key, size_t len, VALUE **slotp, VALUE def_value)
|
|
114
86
|
}
|
115
87
|
if (0 != slotp) {
|
116
88
|
if (0 != bucket->key) {
|
117
|
-
KeyVal b = ALLOC(struct
|
118
|
-
|
89
|
+
KeyVal b = ALLOC(struct _keyVal);
|
90
|
+
|
119
91
|
b->next = 0;
|
120
92
|
bucket->next = b;
|
121
93
|
bucket = b;
|
@@ -155,7 +127,7 @@ oj_attr_hash_get(const char *key, size_t len, ID **slotp) {
|
|
155
127
|
char*
|
156
128
|
oj_strndup(const char *s, size_t len) {
|
157
129
|
char *d = ALLOC_N(char, len + 1);
|
158
|
-
|
130
|
+
|
159
131
|
memcpy(d, s, len);
|
160
132
|
d[len] = '\0';
|
161
133
|
|