oj 3.7.4 → 3.11.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +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
|
|