oj 3.11.1 → 3.11.6
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 +6 -1
- data/ext/oj/buf.h +34 -38
- data/ext/oj/cache8.c +59 -62
- data/ext/oj/cache8.h +8 -7
- data/ext/oj/circarray.c +33 -35
- data/ext/oj/circarray.h +11 -9
- data/ext/oj/code.c +170 -174
- data/ext/oj/code.h +21 -20
- data/ext/oj/compat.c +159 -166
- data/ext/oj/custom.c +802 -851
- data/ext/oj/dump.c +766 -778
- data/ext/oj/dump.h +49 -51
- data/ext/oj/dump_compat.c +1 -0
- data/ext/oj/dump_leaf.c +116 -157
- data/ext/oj/dump_object.c +609 -628
- data/ext/oj/dump_strict.c +318 -327
- data/ext/oj/encode.h +3 -4
- data/ext/oj/err.c +39 -25
- data/ext/oj/err.h +24 -15
- data/ext/oj/extconf.rb +2 -1
- data/ext/oj/fast.c +1042 -1041
- data/ext/oj/hash.c +62 -66
- data/ext/oj/hash.h +7 -6
- data/ext/oj/hash_test.c +450 -443
- data/ext/oj/mimic_json.c +412 -402
- data/ext/oj/object.c +559 -528
- data/ext/oj/odd.c +123 -128
- data/ext/oj/odd.h +27 -25
- data/ext/oj/oj.c +1123 -924
- data/ext/oj/oj.h +286 -298
- data/ext/oj/parse.c +938 -930
- data/ext/oj/parse.h +70 -69
- data/ext/oj/rails.c +836 -839
- data/ext/oj/rails.h +7 -7
- data/ext/oj/reader.c +135 -140
- data/ext/oj/reader.h +66 -79
- data/ext/oj/resolve.c +43 -43
- data/ext/oj/resolve.h +3 -2
- data/ext/oj/rxclass.c +67 -68
- data/ext/oj/rxclass.h +12 -10
- data/ext/oj/saj.c +451 -479
- data/ext/oj/scp.c +93 -103
- data/ext/oj/sparse.c +770 -730
- data/ext/oj/stream_writer.c +120 -149
- data/ext/oj/strict.c +71 -86
- data/ext/oj/string_writer.c +198 -243
- data/ext/oj/trace.c +29 -33
- data/ext/oj/trace.h +14 -11
- data/ext/oj/util.c +103 -103
- data/ext/oj/util.h +3 -2
- data/ext/oj/val_stack.c +47 -47
- data/ext/oj/val_stack.h +79 -86
- data/ext/oj/wab.c +291 -309
- data/lib/oj/bag.rb +1 -0
- data/lib/oj/easy_hash.rb +5 -4
- data/lib/oj/mimic.rb +0 -12
- data/lib/oj/version.rb +1 -1
- data/test/activerecord/result_test.rb +7 -2
- data/test/foo.rb +35 -32
- data/test/test_fast.rb +32 -2
- data/test/test_generate.rb +21 -0
- data/test/test_hash.rb +10 -0
- data/test/test_scp.rb +1 -1
- metadata +4 -2
data/ext/oj/val_stack.h
CHANGED
@@ -1,157 +1,150 @@
|
|
1
1
|
// Copyright (c) 2011 Peter Ohler. All rights reserved.
|
2
|
+
// Licensed under the MIT License. See LICENSE file in the project root for license details.
|
2
3
|
|
3
4
|
#ifndef OJ_VAL_STACK_H
|
4
5
|
#define OJ_VAL_STACK_H
|
5
6
|
|
6
|
-
#include "ruby.h"
|
7
|
-
#include "odd.h"
|
8
7
|
#include <stdint.h>
|
8
|
+
|
9
|
+
#include "odd.h"
|
10
|
+
#include "ruby.h"
|
9
11
|
#ifdef HAVE_PTHREAD_MUTEX_INIT
|
10
12
|
#include <pthread.h>
|
11
13
|
#endif
|
12
14
|
|
13
|
-
#define STACK_INC
|
15
|
+
#define STACK_INC 64
|
14
16
|
|
15
17
|
typedef enum {
|
16
|
-
NEXT_NONE
|
17
|
-
NEXT_ARRAY_NEW
|
18
|
-
NEXT_ARRAY_ELEMENT
|
19
|
-
NEXT_ARRAY_COMMA
|
20
|
-
NEXT_HASH_NEW
|
21
|
-
NEXT_HASH_KEY
|
22
|
-
NEXT_HASH_COLON
|
23
|
-
NEXT_HASH_VALUE
|
24
|
-
NEXT_HASH_COMMA
|
18
|
+
NEXT_NONE = 0,
|
19
|
+
NEXT_ARRAY_NEW = 'a',
|
20
|
+
NEXT_ARRAY_ELEMENT = 'e',
|
21
|
+
NEXT_ARRAY_COMMA = ',',
|
22
|
+
NEXT_HASH_NEW = 'h',
|
23
|
+
NEXT_HASH_KEY = 'k',
|
24
|
+
NEXT_HASH_COLON = ':',
|
25
|
+
NEXT_HASH_VALUE = 'v',
|
26
|
+
NEXT_HASH_COMMA = 'n',
|
25
27
|
} ValNext;
|
26
28
|
|
27
29
|
typedef struct _val {
|
28
|
-
volatile VALUE
|
29
|
-
const char
|
30
|
-
char
|
31
|
-
volatile VALUE
|
32
|
-
const char
|
33
|
-
VALUE
|
34
|
-
OddArgs
|
35
|
-
uint16_t
|
36
|
-
uint16_t
|
37
|
-
char
|
38
|
-
char
|
39
|
-
char
|
40
|
-
} *Val;
|
30
|
+
volatile VALUE val;
|
31
|
+
const char * key;
|
32
|
+
char karray[32];
|
33
|
+
volatile VALUE key_val;
|
34
|
+
const char * classname;
|
35
|
+
VALUE clas;
|
36
|
+
OddArgs odd_args;
|
37
|
+
uint16_t klen;
|
38
|
+
uint16_t clen;
|
39
|
+
char next; // ValNext
|
40
|
+
char k1; // first original character in the key
|
41
|
+
char kalloc;
|
42
|
+
} * Val;
|
41
43
|
|
42
44
|
typedef struct _valStack {
|
43
|
-
struct _val
|
44
|
-
Val
|
45
|
-
Val
|
46
|
-
Val
|
45
|
+
struct _val base[STACK_INC];
|
46
|
+
Val head; // current stack
|
47
|
+
Val end; // stack end
|
48
|
+
Val tail; // pointer to one past last element name on stack
|
47
49
|
#ifdef HAVE_PTHREAD_MUTEX_INIT
|
48
|
-
pthread_mutex_t
|
50
|
+
pthread_mutex_t mutex;
|
49
51
|
#else
|
50
|
-
VALUE
|
52
|
+
VALUE mutex;
|
51
53
|
#endif
|
52
54
|
|
53
|
-
} *ValStack;
|
55
|
+
} * ValStack;
|
54
56
|
|
55
|
-
extern VALUE
|
57
|
+
extern VALUE oj_stack_init(ValStack stack);
|
56
58
|
|
57
|
-
inline static int
|
58
|
-
stack_empty(ValStack stack) {
|
59
|
+
inline static int stack_empty(ValStack stack) {
|
59
60
|
return (stack->head == stack->tail);
|
60
61
|
}
|
61
62
|
|
62
|
-
inline static void
|
63
|
-
stack_cleanup(ValStack stack) {
|
63
|
+
inline static void stack_cleanup(ValStack stack) {
|
64
64
|
if (stack->base != stack->head) {
|
65
65
|
xfree(stack->head);
|
66
|
-
|
66
|
+
stack->head = NULL;
|
67
67
|
}
|
68
68
|
}
|
69
69
|
|
70
|
-
inline static void
|
71
|
-
stack_push(ValStack stack, VALUE val, ValNext next) {
|
70
|
+
inline static void stack_push(ValStack stack, VALUE val, ValNext next) {
|
72
71
|
if (stack->end <= stack->tail) {
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
72
|
+
size_t len = stack->end - stack->head;
|
73
|
+
size_t toff = stack->tail - stack->head;
|
74
|
+
Val head = stack->head;
|
75
|
+
|
76
|
+
// A realloc can trigger a GC so make sure it happens outside the lock
|
77
|
+
// but lock before changing pointers.
|
78
|
+
if (stack->base == stack->head) {
|
79
|
+
head = ALLOC_N(struct _val, len + STACK_INC);
|
80
|
+
memcpy(head, stack->base, sizeof(struct _val) * len);
|
81
|
+
} else {
|
82
|
+
REALLOC_N(head, struct _val, len + STACK_INC);
|
83
|
+
}
|
85
84
|
#ifdef HAVE_PTHREAD_MUTEX_INIT
|
86
|
-
|
85
|
+
pthread_mutex_lock(&stack->mutex);
|
87
86
|
#else
|
88
|
-
|
87
|
+
rb_mutex_lock(stack->mutex);
|
89
88
|
#endif
|
90
|
-
|
91
|
-
|
92
|
-
|
89
|
+
stack->head = head;
|
90
|
+
stack->tail = stack->head + toff;
|
91
|
+
stack->end = stack->head + len + STACK_INC;
|
93
92
|
#ifdef HAVE_PTHREAD_MUTEX_INIT
|
94
|
-
|
93
|
+
pthread_mutex_unlock(&stack->mutex);
|
95
94
|
#else
|
96
|
-
|
95
|
+
rb_mutex_unlock(stack->mutex);
|
97
96
|
#endif
|
98
97
|
}
|
99
|
-
stack->tail->val
|
100
|
-
stack->tail->next
|
98
|
+
stack->tail->val = val;
|
99
|
+
stack->tail->next = next;
|
101
100
|
stack->tail->classname = NULL;
|
102
|
-
stack->tail->clas
|
103
|
-
stack->tail->odd_args
|
104
|
-
stack->tail->key
|
105
|
-
stack->tail->key_val
|
106
|
-
stack->tail->clen
|
107
|
-
stack->tail->klen
|
108
|
-
stack->tail->kalloc
|
101
|
+
stack->tail->clas = Qundef;
|
102
|
+
stack->tail->odd_args = NULL;
|
103
|
+
stack->tail->key = 0;
|
104
|
+
stack->tail->key_val = Qundef;
|
105
|
+
stack->tail->clen = 0;
|
106
|
+
stack->tail->klen = 0;
|
107
|
+
stack->tail->kalloc = 0;
|
109
108
|
stack->tail++;
|
110
109
|
}
|
111
110
|
|
112
|
-
inline static size_t
|
113
|
-
stack_size(ValStack stack) {
|
111
|
+
inline static size_t stack_size(ValStack stack) {
|
114
112
|
return stack->tail - stack->head;
|
115
113
|
}
|
116
114
|
|
117
|
-
inline static Val
|
118
|
-
stack_peek(ValStack stack) {
|
115
|
+
inline static Val stack_peek(ValStack stack) {
|
119
116
|
if (stack->head < stack->tail) {
|
120
|
-
|
117
|
+
return stack->tail - 1;
|
121
118
|
}
|
122
119
|
return 0;
|
123
120
|
}
|
124
121
|
|
125
|
-
inline static Val
|
126
|
-
stack_peek_up(ValStack stack) {
|
122
|
+
inline static Val stack_peek_up(ValStack stack) {
|
127
123
|
if (stack->head < stack->tail - 1) {
|
128
|
-
|
124
|
+
return stack->tail - 2;
|
129
125
|
}
|
130
126
|
return 0;
|
131
127
|
}
|
132
128
|
|
133
|
-
inline static Val
|
134
|
-
stack_prev(ValStack stack) {
|
129
|
+
inline static Val stack_prev(ValStack stack) {
|
135
130
|
return stack->tail;
|
136
131
|
}
|
137
132
|
|
138
|
-
inline static VALUE
|
139
|
-
stack_head_val(ValStack stack) {
|
133
|
+
inline static VALUE stack_head_val(ValStack stack) {
|
140
134
|
if (Qundef != stack->head->val) {
|
141
|
-
|
135
|
+
return stack->head->val;
|
142
136
|
}
|
143
137
|
return Qnil;
|
144
138
|
}
|
145
139
|
|
146
|
-
inline static Val
|
147
|
-
stack_pop(ValStack stack) {
|
140
|
+
inline static Val stack_pop(ValStack stack) {
|
148
141
|
if (stack->head < stack->tail) {
|
149
|
-
|
150
|
-
|
142
|
+
stack->tail--;
|
143
|
+
return stack->tail;
|
151
144
|
}
|
152
145
|
return 0;
|
153
146
|
}
|
154
147
|
|
155
|
-
extern const char*
|
148
|
+
extern const char *oj_stack_next_string(ValNext n);
|
156
149
|
|
157
150
|
#endif /* OJ_VAL_STACK_H */
|
data/ext/oj/wab.c
CHANGED
@@ -1,23 +1,24 @@
|
|
1
1
|
// Copyright (c) 2012 Peter Ohler. All rights reserved.
|
2
|
+
// Licensed under the MIT License. See LICENSE file in the project root for license details.
|
2
3
|
|
3
|
-
#include <stdlib.h>
|
4
4
|
#include <stdio.h>
|
5
|
+
#include <stdlib.h>
|
5
6
|
#include <string.h>
|
6
7
|
#include <time.h>
|
7
8
|
#include <unistd.h>
|
8
9
|
|
9
|
-
#include "
|
10
|
+
#include "dump.h"
|
11
|
+
#include "encode.h"
|
10
12
|
#include "err.h"
|
13
|
+
#include "oj.h"
|
11
14
|
#include "parse.h"
|
12
|
-
#include "encode.h"
|
13
|
-
#include "dump.h"
|
14
15
|
#include "trace.h"
|
15
16
|
#include "util.h"
|
16
17
|
|
17
18
|
// Workaround in case INFINITY is not defined in math.h or if the OS is CentOS
|
18
|
-
#define OJ_INFINITY (1.0/0.0)
|
19
|
+
#define OJ_INFINITY (1.0 / 0.0)
|
19
20
|
|
20
|
-
static char
|
21
|
+
static char hex_chars[256] = "\
|
21
22
|
................................\
|
22
23
|
................xxxxxxxxxx......\
|
23
24
|
.xxxxxx.........................\
|
@@ -27,132 +28,128 @@ static char hex_chars[256] = "\
|
|
27
28
|
................................\
|
28
29
|
................................";
|
29
30
|
|
30
|
-
static VALUE
|
31
|
-
static VALUE
|
32
|
-
static VALUE
|
31
|
+
static VALUE wab_uuid_clas = Qundef;
|
32
|
+
static VALUE uri_clas = Qundef;
|
33
|
+
static VALUE uri_http_clas = Qundef;
|
33
34
|
|
34
35
|
///// dump functions /////
|
35
36
|
|
36
|
-
static VALUE
|
37
|
-
resolve_wab_uuid_class() {
|
37
|
+
static VALUE resolve_wab_uuid_class() {
|
38
38
|
if (Qundef == wab_uuid_clas) {
|
39
|
-
|
39
|
+
volatile VALUE wab_module;
|
40
40
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
41
|
+
wab_uuid_clas = Qnil;
|
42
|
+
if (rb_const_defined_at(rb_cObject, rb_intern("WAB"))) {
|
43
|
+
wab_module = rb_const_get_at(rb_cObject, rb_intern("WAB"));
|
44
|
+
if (rb_const_defined_at(wab_module, rb_intern("UUID"))) {
|
45
|
+
wab_uuid_clas = rb_const_get(wab_module, rb_intern("UUID"));
|
46
|
+
}
|
47
|
+
}
|
48
48
|
}
|
49
49
|
return wab_uuid_clas;
|
50
50
|
}
|
51
51
|
|
52
|
-
static VALUE
|
53
|
-
resolve_uri_class() {
|
52
|
+
static VALUE resolve_uri_class() {
|
54
53
|
if (Qundef == uri_clas) {
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
}
|
54
|
+
uri_clas = Qnil;
|
55
|
+
if (rb_const_defined_at(rb_cObject, rb_intern("URI"))) {
|
56
|
+
uri_clas = rb_const_get_at(rb_cObject, rb_intern("URI"));
|
57
|
+
}
|
60
58
|
}
|
61
59
|
return uri_clas;
|
62
60
|
}
|
63
61
|
|
64
|
-
static VALUE
|
65
|
-
resolve_uri_http_class() {
|
62
|
+
static VALUE resolve_uri_http_class() {
|
66
63
|
if (Qundef == uri_http_clas) {
|
67
|
-
|
64
|
+
volatile VALUE uri_module;
|
68
65
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
66
|
+
uri_http_clas = Qnil;
|
67
|
+
if (rb_const_defined_at(rb_cObject, rb_intern("URI"))) {
|
68
|
+
uri_module = rb_const_get_at(rb_cObject, rb_intern("URI"));
|
69
|
+
if (rb_const_defined_at(uri_module, rb_intern("HTTP"))) {
|
70
|
+
uri_http_clas = rb_const_get(uri_module, rb_intern("HTTP"));
|
71
|
+
}
|
72
|
+
}
|
76
73
|
}
|
77
74
|
return uri_http_clas;
|
78
75
|
}
|
79
76
|
|
80
|
-
static void
|
81
|
-
|
82
|
-
|
77
|
+
static void raise_wab(VALUE obj) {
|
78
|
+
rb_raise(rb_eTypeError,
|
79
|
+
"Failed to dump %s Object to JSON in wab mode.\n",
|
80
|
+
rb_class2name(rb_obj_class(obj)));
|
83
81
|
}
|
84
82
|
|
85
83
|
// Removed dependencies on math due to problems with CentOS 5.4.
|
86
|
-
static void
|
87
|
-
|
88
|
-
char
|
89
|
-
|
90
|
-
|
91
|
-
int cnt = 0;
|
84
|
+
static void dump_float(VALUE obj, int depth, Out out, bool as_ok) {
|
85
|
+
char buf[64];
|
86
|
+
char * b;
|
87
|
+
double d = rb_num2dbl(obj);
|
88
|
+
int cnt = 0;
|
92
89
|
|
93
90
|
if (0.0 == d) {
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
91
|
+
b = buf;
|
92
|
+
*b++ = '0';
|
93
|
+
*b++ = '.';
|
94
|
+
*b++ = '0';
|
95
|
+
*b++ = '\0';
|
96
|
+
cnt = 3;
|
100
97
|
} else {
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
98
|
+
if (OJ_INFINITY == d || -OJ_INFINITY == d || isnan(d)) {
|
99
|
+
raise_wab(obj);
|
100
|
+
} else if (d == (double)(long long int)d) {
|
101
|
+
cnt = snprintf(buf, sizeof(buf), "%.1f", d);
|
102
|
+
} else {
|
103
|
+
cnt = snprintf(buf, sizeof(buf), "%0.16g", d);
|
104
|
+
}
|
108
105
|
}
|
109
106
|
assure_size(out, cnt);
|
110
107
|
for (b = buf; '\0' != *b; b++) {
|
111
|
-
|
108
|
+
*out->cur++ = *b;
|
112
109
|
}
|
113
110
|
*out->cur = '\0';
|
114
111
|
}
|
115
112
|
|
116
|
-
static void
|
117
|
-
|
118
|
-
|
119
|
-
int
|
120
|
-
int d2 = depth + 1;
|
113
|
+
static void dump_array(VALUE a, int depth, Out out, bool as_ok) {
|
114
|
+
size_t size;
|
115
|
+
int i, cnt;
|
116
|
+
int d2 = depth + 1;
|
121
117
|
|
122
|
-
cnt
|
118
|
+
cnt = (int)RARRAY_LEN(a);
|
123
119
|
*out->cur++ = '[';
|
124
|
-
size
|
120
|
+
size = 2;
|
125
121
|
assure_size(out, size);
|
126
122
|
if (0 == cnt) {
|
127
|
-
|
123
|
+
*out->cur++ = ']';
|
128
124
|
} else {
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
125
|
+
size = d2 * out->indent + 2;
|
126
|
+
cnt--;
|
127
|
+
for (i = 0; i <= cnt; i++) {
|
128
|
+
assure_size(out, size);
|
129
|
+
fill_indent(out, d2);
|
130
|
+
oj_dump_wab_val(rb_ary_entry(a, i), d2, out);
|
131
|
+
if (i < cnt) {
|
132
|
+
*out->cur++ = ',';
|
133
|
+
}
|
134
|
+
}
|
135
|
+
size = depth * out->indent + 1;
|
136
|
+
assure_size(out, size);
|
137
|
+
fill_indent(out, depth);
|
138
|
+
*out->cur++ = ']';
|
143
139
|
}
|
144
140
|
*out->cur = '\0';
|
145
141
|
}
|
146
142
|
|
147
|
-
static int
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
int rtype = rb_type(key);
|
143
|
+
static int hash_cb(VALUE key, VALUE value, VALUE ov) {
|
144
|
+
Out out = (Out)ov;
|
145
|
+
int depth = out->depth;
|
146
|
+
long size;
|
147
|
+
int rtype = rb_type(key);
|
153
148
|
|
154
149
|
if (rtype != T_SYMBOL) {
|
155
|
-
|
150
|
+
rb_raise(rb_eTypeError,
|
151
|
+
"In :wab mode all Hash keys must be Symbols, not %s.\n",
|
152
|
+
rb_class2name(rb_obj_class(key)));
|
156
153
|
}
|
157
154
|
size = depth * out->indent + 1;
|
158
155
|
assure_size(out, size);
|
@@ -160,56 +157,54 @@ hash_cb(VALUE key, VALUE value, VALUE ov) {
|
|
160
157
|
oj_dump_sym(key, 0, out, false);
|
161
158
|
*out->cur++ = ':';
|
162
159
|
oj_dump_wab_val(value, depth, out);
|
163
|
-
out->depth
|
160
|
+
out->depth = depth;
|
164
161
|
*out->cur++ = ',';
|
165
162
|
|
166
163
|
return ST_CONTINUE;
|
167
164
|
}
|
168
165
|
|
169
|
-
static void
|
170
|
-
|
171
|
-
|
172
|
-
size_t size;
|
166
|
+
static void dump_hash(VALUE obj, int depth, Out out, bool as_ok) {
|
167
|
+
int cnt;
|
168
|
+
size_t size;
|
173
169
|
|
174
|
-
cnt
|
170
|
+
cnt = (int)RHASH_SIZE(obj);
|
175
171
|
size = depth * out->indent + 2;
|
176
172
|
assure_size(out, 2);
|
177
173
|
*out->cur++ = '{';
|
178
174
|
if (0 == cnt) {
|
179
|
-
|
175
|
+
*out->cur++ = '}';
|
180
176
|
} else {
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
177
|
+
out->depth = depth + 1;
|
178
|
+
rb_hash_foreach(obj, hash_cb, (VALUE)out);
|
179
|
+
if (',' == *(out->cur - 1)) {
|
180
|
+
out->cur--; // backup to overwrite last comma
|
181
|
+
}
|
182
|
+
assure_size(out, size);
|
183
|
+
fill_indent(out, depth);
|
184
|
+
*out->cur++ = '}';
|
189
185
|
}
|
190
186
|
*out->cur = '\0';
|
191
187
|
}
|
192
188
|
|
193
|
-
static void
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
long long nsec;
|
189
|
+
static void dump_time(VALUE obj, Out out) {
|
190
|
+
char buf[64];
|
191
|
+
struct _timeInfo ti;
|
192
|
+
int len;
|
193
|
+
time_t sec;
|
194
|
+
long long nsec;
|
200
195
|
|
201
196
|
#ifdef HAVE_RB_TIME_TIMESPEC
|
202
197
|
if (16 <= sizeof(struct timespec)) {
|
203
|
-
|
198
|
+
struct timespec ts = rb_time_timespec(obj);
|
204
199
|
|
205
|
-
|
206
|
-
|
200
|
+
sec = ts.tv_sec;
|
201
|
+
nsec = ts.tv_nsec;
|
207
202
|
} else {
|
208
|
-
|
209
|
-
|
203
|
+
sec = rb_num2ll(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
|
204
|
+
nsec = rb_num2ll(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
|
210
205
|
}
|
211
206
|
#else
|
212
|
-
sec
|
207
|
+
sec = rb_num2ll(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
|
213
208
|
nsec = rb_num2ll(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
|
214
209
|
#endif
|
215
210
|
|
@@ -217,210 +212,209 @@ dump_time(VALUE obj, Out out) {
|
|
217
212
|
// 2012-01-05T23:58:07.123456000Z
|
218
213
|
sec_as_time(sec, &ti);
|
219
214
|
|
220
|
-
len = sprintf(buf,
|
215
|
+
len = sprintf(buf,
|
216
|
+
"%04d-%02d-%02dT%02d:%02d:%02d.%09ldZ",
|
217
|
+
ti.year,
|
218
|
+
ti.mon,
|
219
|
+
ti.day,
|
220
|
+
ti.hour,
|
221
|
+
ti.min,
|
222
|
+
ti.sec,
|
223
|
+
(long)nsec);
|
221
224
|
oj_dump_cstr(buf, len, 0, 0, out);
|
222
225
|
}
|
223
226
|
|
224
|
-
static void
|
225
|
-
|
226
|
-
volatile VALUE clas = rb_obj_class(obj);
|
227
|
+
static void dump_obj(VALUE obj, int depth, Out out, bool as_ok) {
|
228
|
+
volatile VALUE clas = rb_obj_class(obj);
|
227
229
|
|
228
230
|
if (rb_cTime == clas) {
|
229
|
-
|
231
|
+
dump_time(obj, out);
|
230
232
|
} else if (oj_bigdecimal_class == clas) {
|
231
|
-
|
233
|
+
volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
|
232
234
|
|
233
|
-
|
235
|
+
oj_dump_raw(rb_string_value_ptr((VALUE *)&rstr), (int)RSTRING_LEN(rstr), out);
|
234
236
|
} else if (resolve_wab_uuid_class() == clas) {
|
235
|
-
|
237
|
+
oj_dump_str(rb_funcall(obj, oj_to_s_id, 0), depth, out, false);
|
236
238
|
} else if (resolve_uri_http_class() == clas) {
|
237
|
-
|
239
|
+
oj_dump_str(rb_funcall(obj, oj_to_s_id, 0), depth, out, false);
|
238
240
|
} else {
|
239
|
-
|
240
|
-
}
|
241
|
-
}
|
242
|
-
|
243
|
-
static DumpFunc
|
244
|
-
NULL,
|
245
|
-
dump_obj,
|
246
|
-
NULL,
|
247
|
-
NULL,
|
248
|
-
dump_float,
|
249
|
-
oj_dump_str,
|
250
|
-
NULL,
|
251
|
-
dump_array,
|
252
|
-
dump_hash,
|
253
|
-
NULL,
|
254
|
-
oj_dump_bignum,
|
255
|
-
NULL,
|
256
|
-
dump_obj,
|
257
|
-
NULL,
|
258
|
-
NULL,
|
259
|
-
NULL,
|
260
|
-
NULL,
|
261
|
-
oj_dump_nil,
|
262
|
-
oj_dump_true,
|
263
|
-
oj_dump_false,
|
264
|
-
oj_dump_sym,
|
265
|
-
oj_dump_fixnum,
|
241
|
+
raise_wab(obj);
|
242
|
+
}
|
243
|
+
}
|
244
|
+
|
245
|
+
static DumpFunc wab_funcs[] = {
|
246
|
+
NULL, // RUBY_T_NONE = 0x00,
|
247
|
+
dump_obj, // RUBY_T_OBJECT = 0x01,
|
248
|
+
NULL, // RUBY_T_CLASS = 0x02,
|
249
|
+
NULL, // RUBY_T_MODULE = 0x03,
|
250
|
+
dump_float, // RUBY_T_FLOAT = 0x04,
|
251
|
+
oj_dump_str, // RUBY_T_STRING = 0x05,
|
252
|
+
NULL, // RUBY_T_REGEXP = 0x06,
|
253
|
+
dump_array, // RUBY_T_ARRAY = 0x07,
|
254
|
+
dump_hash, // RUBY_T_HASH = 0x08,
|
255
|
+
NULL, // RUBY_T_STRUCT = 0x09,
|
256
|
+
oj_dump_bignum, // RUBY_T_BIGNUM = 0x0a,
|
257
|
+
NULL, // RUBY_T_FILE = 0x0b,
|
258
|
+
dump_obj, // RUBY_T_DATA = 0x0c,
|
259
|
+
NULL, // RUBY_T_MATCH = 0x0d,
|
260
|
+
NULL, // RUBY_T_COMPLEX = 0x0e,
|
261
|
+
NULL, // RUBY_T_RATIONAL = 0x0f,
|
262
|
+
NULL, // 0x10
|
263
|
+
oj_dump_nil, // RUBY_T_NIL = 0x11,
|
264
|
+
oj_dump_true, // RUBY_T_TRUE = 0x12,
|
265
|
+
oj_dump_false, // RUBY_T_FALSE = 0x13,
|
266
|
+
oj_dump_sym, // RUBY_T_SYMBOL = 0x14,
|
267
|
+
oj_dump_fixnum, // RUBY_T_FIXNUM = 0x15,
|
266
268
|
};
|
267
269
|
|
268
|
-
void
|
269
|
-
|
270
|
-
int type = rb_type(obj);
|
270
|
+
void oj_dump_wab_val(VALUE obj, int depth, Out out) {
|
271
|
+
int type = rb_type(obj);
|
271
272
|
|
272
273
|
if (Yes == out->opts->trace) {
|
273
|
-
|
274
|
+
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceIn);
|
274
275
|
}
|
275
276
|
if (MAX_DEPTH < depth) {
|
276
|
-
|
277
|
+
rb_raise(rb_eNoMemError, "Too deeply nested.\n");
|
277
278
|
}
|
278
279
|
if (0 < type && type <= RUBY_T_FIXNUM) {
|
279
|
-
|
280
|
+
DumpFunc f = wab_funcs[type];
|
280
281
|
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
282
|
+
if (NULL != f) {
|
283
|
+
f(obj, depth, out, false);
|
284
|
+
if (Yes == out->opts->trace) {
|
285
|
+
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
|
286
|
+
}
|
287
|
+
return;
|
288
|
+
}
|
288
289
|
}
|
289
290
|
raise_wab(obj);
|
290
291
|
}
|
291
292
|
|
292
293
|
///// load functions /////
|
293
294
|
|
294
|
-
static void
|
295
|
-
hash_end(ParseInfo pi) {
|
295
|
+
static void hash_end(ParseInfo pi) {
|
296
296
|
if (Yes == pi->options.trace) {
|
297
|
-
|
297
|
+
oj_trace_parse_hash_end(pi, __FILE__, __LINE__);
|
298
298
|
}
|
299
299
|
}
|
300
300
|
|
301
|
-
static void
|
302
|
-
array_end(ParseInfo pi) {
|
301
|
+
static void array_end(ParseInfo pi) {
|
303
302
|
if (Yes == pi->options.trace) {
|
304
|
-
|
303
|
+
oj_trace_parse_array_end(pi, __FILE__, __LINE__);
|
305
304
|
}
|
306
305
|
}
|
307
306
|
|
308
|
-
static VALUE
|
309
|
-
noop_hash_key(ParseInfo pi, const char *key, size_t klen) {
|
307
|
+
static VALUE noop_hash_key(ParseInfo pi, const char *key, size_t klen) {
|
310
308
|
return Qundef;
|
311
309
|
}
|
312
310
|
|
313
|
-
static void
|
314
|
-
add_value(ParseInfo pi, VALUE val) {
|
311
|
+
static void add_value(ParseInfo pi, VALUE val) {
|
315
312
|
if (Yes == pi->options.trace) {
|
316
|
-
|
313
|
+
oj_trace_parse_call("add_value", pi, __FILE__, __LINE__, val);
|
317
314
|
}
|
318
315
|
pi->stack.head->val = val;
|
319
316
|
}
|
320
317
|
|
321
318
|
// 123e4567-e89b-12d3-a456-426655440000
|
322
|
-
static bool
|
323
|
-
|
324
|
-
int i;
|
319
|
+
static bool uuid_check(const char *str, int len) {
|
320
|
+
int i;
|
325
321
|
|
326
322
|
for (i = 0; i < 8; i++, str++) {
|
327
|
-
|
328
|
-
|
329
|
-
|
323
|
+
if ('x' != hex_chars[*(uint8_t *)str]) {
|
324
|
+
return false;
|
325
|
+
}
|
330
326
|
}
|
331
327
|
str++;
|
332
328
|
for (i = 0; i < 4; i++, str++) {
|
333
|
-
|
334
|
-
|
335
|
-
|
329
|
+
if ('x' != hex_chars[*(uint8_t *)str]) {
|
330
|
+
return false;
|
331
|
+
}
|
336
332
|
}
|
337
333
|
str++;
|
338
334
|
for (i = 0; i < 4; i++, str++) {
|
339
|
-
|
340
|
-
|
341
|
-
|
335
|
+
if ('x' != hex_chars[*(uint8_t *)str]) {
|
336
|
+
return false;
|
337
|
+
}
|
342
338
|
}
|
343
339
|
str++;
|
344
340
|
for (i = 0; i < 4; i++, str++) {
|
345
|
-
|
346
|
-
|
347
|
-
|
341
|
+
if ('x' != hex_chars[*(uint8_t *)str]) {
|
342
|
+
return false;
|
343
|
+
}
|
348
344
|
}
|
349
345
|
str++;
|
350
346
|
for (i = 0; i < 12; i++, str++) {
|
351
|
-
|
352
|
-
|
353
|
-
|
347
|
+
if ('x' != hex_chars[*(uint8_t *)str]) {
|
348
|
+
return false;
|
349
|
+
}
|
354
350
|
}
|
355
351
|
return true;
|
356
352
|
}
|
357
353
|
|
358
|
-
static const char*
|
359
|
-
|
360
|
-
uint32_t v = 0;
|
354
|
+
static const char *read_num(const char *s, int len, int *vp) {
|
355
|
+
uint32_t v = 0;
|
361
356
|
|
362
357
|
for (; 0 < len; len--, s++) {
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
358
|
+
if ('0' <= *s && *s <= '9') {
|
359
|
+
v = v * 10 + *s - '0';
|
360
|
+
} else {
|
361
|
+
return NULL;
|
362
|
+
}
|
368
363
|
}
|
369
364
|
*vp = (int)v;
|
370
365
|
|
371
366
|
return s;
|
372
367
|
}
|
373
368
|
|
374
|
-
static VALUE
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
time_t secs;
|
369
|
+
static VALUE time_parse(const char *s, int len) {
|
370
|
+
struct tm tm;
|
371
|
+
bool neg = false;
|
372
|
+
long nsecs = 0;
|
373
|
+
int i;
|
374
|
+
time_t secs;
|
381
375
|
|
382
376
|
memset(&tm, 0, sizeof(tm));
|
383
377
|
if ('-' == *s) {
|
384
|
-
|
385
|
-
|
378
|
+
s++;
|
379
|
+
neg = true;
|
386
380
|
}
|
387
381
|
if (NULL == (s = read_num(s, 4, &tm.tm_year))) {
|
388
|
-
|
382
|
+
return Qnil;
|
389
383
|
}
|
390
384
|
if (neg) {
|
391
|
-
|
392
|
-
|
385
|
+
tm.tm_year = -tm.tm_year;
|
386
|
+
neg = false;
|
393
387
|
}
|
394
388
|
tm.tm_year -= 1900;
|
395
389
|
s++;
|
396
390
|
if (NULL == (s = read_num(s, 2, &tm.tm_mon))) {
|
397
|
-
|
391
|
+
return Qnil;
|
398
392
|
}
|
399
393
|
tm.tm_mon--;
|
400
394
|
s++;
|
401
395
|
if (NULL == (s = read_num(s, 2, &tm.tm_mday))) {
|
402
|
-
|
396
|
+
return Qnil;
|
403
397
|
}
|
404
398
|
s++;
|
405
399
|
if (NULL == (s = read_num(s, 2, &tm.tm_hour))) {
|
406
|
-
|
400
|
+
return Qnil;
|
407
401
|
}
|
408
402
|
s++;
|
409
403
|
if (NULL == (s = read_num(s, 2, &tm.tm_min))) {
|
410
|
-
|
404
|
+
return Qnil;
|
411
405
|
}
|
412
406
|
s++;
|
413
407
|
if (NULL == (s = read_num(s, 2, &tm.tm_sec))) {
|
414
|
-
|
408
|
+
return Qnil;
|
415
409
|
}
|
416
410
|
s++;
|
417
411
|
|
418
412
|
for (i = 9; 0 < i; i--, s++) {
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
413
|
+
if ('0' <= *s && *s <= '9') {
|
414
|
+
nsecs = nsecs * 10 + *s - '0';
|
415
|
+
} else {
|
416
|
+
return Qnil;
|
417
|
+
}
|
424
418
|
}
|
425
419
|
#if IS_WINDOWS
|
426
420
|
secs = (time_t)mktime(&tm);
|
@@ -434,71 +428,67 @@ time_parse(const char *s, int len) {
|
|
434
428
|
return rb_funcall(rb_time_nano_new(secs, nsecs), oj_utc_id, 0);
|
435
429
|
}
|
436
430
|
|
437
|
-
static VALUE
|
438
|
-
protect_uri(VALUE rstr) {
|
431
|
+
static VALUE protect_uri(VALUE rstr) {
|
439
432
|
return rb_funcall(resolve_uri_class(), oj_parse_id, 1, rstr);
|
440
433
|
}
|
441
434
|
|
442
|
-
static VALUE
|
443
|
-
|
444
|
-
volatile VALUE v = Qnil;
|
435
|
+
static VALUE cstr_to_rstr(const char *str, size_t len) {
|
436
|
+
volatile VALUE v = Qnil;
|
445
437
|
|
446
|
-
if (30 == len && '-' == str[4] && '-' == str[7] && 'T' == str[10] && ':' == str[13] &&
|
447
|
-
|
448
|
-
|
449
|
-
|
438
|
+
if (30 == len && '-' == str[4] && '-' == str[7] && 'T' == str[10] && ':' == str[13] &&
|
439
|
+
':' == str[16] && '.' == str[19] && 'Z' == str[29]) {
|
440
|
+
if (Qnil != (v = time_parse(str, (int)len))) {
|
441
|
+
return v;
|
442
|
+
}
|
450
443
|
}
|
451
|
-
if (36 == len && '-' == str[8] && '-' == str[13] && '-' == str[18] && '-' == str[23] &&
|
452
|
-
|
444
|
+
if (36 == len && '-' == str[8] && '-' == str[13] && '-' == str[18] && '-' == str[23] &&
|
445
|
+
uuid_check(str, (int)len) && Qnil != resolve_wab_uuid_class()) {
|
446
|
+
return rb_funcall(wab_uuid_clas, oj_new_id, 1, rb_str_new(str, len));
|
453
447
|
}
|
454
448
|
v = rb_str_new(str, len);
|
455
449
|
if (7 < len && 0 == strncasecmp("http://", str, 7)) {
|
456
|
-
|
457
|
-
|
450
|
+
int err = 0;
|
451
|
+
volatile VALUE uri = rb_protect(protect_uri, v, &err);
|
458
452
|
|
459
|
-
|
460
|
-
|
461
|
-
|
453
|
+
if (0 == err) {
|
454
|
+
return uri;
|
455
|
+
}
|
462
456
|
}
|
463
457
|
return oj_encode(v);
|
464
458
|
}
|
465
459
|
|
466
|
-
static void
|
467
|
-
add_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
|
460
|
+
static void add_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
|
468
461
|
pi->stack.head->val = cstr_to_rstr(str, len);
|
469
462
|
if (Yes == pi->options.trace) {
|
470
|
-
|
463
|
+
oj_trace_parse_call("add_string", pi, __FILE__, __LINE__, pi->stack.head->val);
|
471
464
|
}
|
472
465
|
}
|
473
466
|
|
474
|
-
static void
|
475
|
-
add_num(ParseInfo pi, NumInfo ni) {
|
467
|
+
static void add_num(ParseInfo pi, NumInfo ni) {
|
476
468
|
if (ni->infinity || ni->nan) {
|
477
|
-
|
469
|
+
oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "not a number or other value");
|
478
470
|
}
|
479
471
|
pi->stack.head->val = oj_num_as_value(ni);
|
480
472
|
if (Yes == pi->options.trace) {
|
481
|
-
|
473
|
+
oj_trace_parse_call("add_number", pi, __FILE__, __LINE__, pi->stack.head->val);
|
482
474
|
}
|
483
475
|
}
|
484
476
|
|
485
|
-
static VALUE
|
486
|
-
start_hash(ParseInfo pi) {
|
477
|
+
static VALUE start_hash(ParseInfo pi) {
|
487
478
|
if (Yes == pi->options.trace) {
|
488
|
-
|
479
|
+
oj_trace_parse_in("start_hash", pi, __FILE__, __LINE__);
|
489
480
|
}
|
490
481
|
if (Qnil != pi->options.hash_class) {
|
491
|
-
|
482
|
+
return rb_class_new_instance(0, NULL, pi->options.hash_class);
|
492
483
|
}
|
493
484
|
return rb_hash_new();
|
494
485
|
}
|
495
486
|
|
496
|
-
static VALUE
|
497
|
-
|
498
|
-
volatile VALUE rkey = parent->key_val;
|
487
|
+
static VALUE calc_hash_key(ParseInfo pi, Val parent) {
|
488
|
+
volatile VALUE rkey = parent->key_val;
|
499
489
|
|
500
490
|
if (Qundef == rkey) {
|
501
|
-
|
491
|
+
rkey = rb_str_new(parent->key, parent->klen);
|
502
492
|
}
|
503
493
|
rkey = oj_encode(rkey);
|
504
494
|
rkey = rb_str_intern(rkey);
|
@@ -506,121 +496,113 @@ calc_hash_key(ParseInfo pi, Val parent) {
|
|
506
496
|
return rkey;
|
507
497
|
}
|
508
498
|
|
509
|
-
static void
|
510
|
-
|
511
|
-
volatile VALUE rval = cstr_to_rstr(str, len);
|
499
|
+
static void hash_set_cstr(ParseInfo pi, Val parent, const char *str, size_t len, const char *orig) {
|
500
|
+
volatile VALUE rval = cstr_to_rstr(str, len);
|
512
501
|
|
513
502
|
rb_hash_aset(stack_peek(&pi->stack)->val, calc_hash_key(pi, parent), rval);
|
514
503
|
if (Yes == pi->options.trace) {
|
515
|
-
|
504
|
+
oj_trace_parse_call("set_string", pi, __FILE__, __LINE__, rval);
|
516
505
|
}
|
517
506
|
}
|
518
507
|
|
519
|
-
static void
|
520
|
-
|
521
|
-
volatile VALUE rval = Qnil;
|
508
|
+
static void hash_set_num(ParseInfo pi, Val parent, NumInfo ni) {
|
509
|
+
volatile VALUE rval = Qnil;
|
522
510
|
|
523
511
|
if (ni->infinity || ni->nan) {
|
524
|
-
|
512
|
+
oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "not a number or other value");
|
525
513
|
}
|
526
514
|
rval = oj_num_as_value(ni);
|
527
515
|
rb_hash_aset(stack_peek(&pi->stack)->val, calc_hash_key(pi, parent), rval);
|
528
516
|
if (Yes == pi->options.trace) {
|
529
|
-
|
517
|
+
oj_trace_parse_call("set_number", pi, __FILE__, __LINE__, rval);
|
530
518
|
}
|
531
519
|
}
|
532
520
|
|
533
|
-
static void
|
534
|
-
hash_set_value(ParseInfo pi, Val parent, VALUE value) {
|
521
|
+
static void hash_set_value(ParseInfo pi, Val parent, VALUE value) {
|
535
522
|
rb_hash_aset(stack_peek(&pi->stack)->val, calc_hash_key(pi, parent), value);
|
536
523
|
if (Yes == pi->options.trace) {
|
537
|
-
|
524
|
+
oj_trace_parse_call("set_value", pi, __FILE__, __LINE__, value);
|
538
525
|
}
|
539
526
|
}
|
540
527
|
|
541
|
-
static VALUE
|
542
|
-
start_array(ParseInfo pi) {
|
528
|
+
static VALUE start_array(ParseInfo pi) {
|
543
529
|
if (Yes == pi->options.trace) {
|
544
|
-
|
530
|
+
oj_trace_parse_in("start_array", pi, __FILE__, __LINE__);
|
545
531
|
}
|
546
532
|
return rb_ary_new();
|
547
533
|
}
|
548
534
|
|
549
|
-
static void
|
550
|
-
|
551
|
-
volatile VALUE rval = cstr_to_rstr(str, len);
|
535
|
+
static void array_append_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
|
536
|
+
volatile VALUE rval = cstr_to_rstr(str, len);
|
552
537
|
|
553
538
|
rb_ary_push(stack_peek(&pi->stack)->val, rval);
|
554
539
|
if (Yes == pi->options.trace) {
|
555
|
-
|
540
|
+
oj_trace_parse_call("set_value", pi, __FILE__, __LINE__, rval);
|
556
541
|
}
|
557
542
|
}
|
558
543
|
|
559
|
-
static void
|
560
|
-
|
561
|
-
volatile VALUE rval = Qnil;
|
544
|
+
static void array_append_num(ParseInfo pi, NumInfo ni) {
|
545
|
+
volatile VALUE rval = Qnil;
|
562
546
|
|
563
547
|
if (ni->infinity || ni->nan) {
|
564
|
-
|
548
|
+
oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "not a number or other value");
|
565
549
|
}
|
566
550
|
rval = oj_num_as_value(ni);
|
567
551
|
rb_ary_push(stack_peek(&pi->stack)->val, rval);
|
568
552
|
if (Yes == pi->options.trace) {
|
569
|
-
|
553
|
+
oj_trace_parse_call("append_number", pi, __FILE__, __LINE__, rval);
|
570
554
|
}
|
571
555
|
}
|
572
556
|
|
573
|
-
static void
|
574
|
-
array_append_value(ParseInfo pi, VALUE value) {
|
557
|
+
static void array_append_value(ParseInfo pi, VALUE value) {
|
575
558
|
rb_ary_push(stack_peek(&pi->stack)->val, value);
|
576
559
|
if (Yes == pi->options.trace) {
|
577
|
-
|
578
|
-
}
|
579
|
-
}
|
580
|
-
|
581
|
-
void
|
582
|
-
|
583
|
-
pi->
|
584
|
-
pi->
|
585
|
-
pi->
|
586
|
-
pi->
|
587
|
-
pi->
|
588
|
-
pi->
|
589
|
-
pi->
|
590
|
-
pi->
|
591
|
-
pi->
|
592
|
-
pi->array_append_num = array_append_num;
|
560
|
+
oj_trace_parse_call("append_value", pi, __FILE__, __LINE__, value);
|
561
|
+
}
|
562
|
+
}
|
563
|
+
|
564
|
+
void oj_set_wab_callbacks(ParseInfo pi) {
|
565
|
+
pi->start_hash = start_hash;
|
566
|
+
pi->end_hash = hash_end;
|
567
|
+
pi->hash_key = noop_hash_key;
|
568
|
+
pi->hash_set_cstr = hash_set_cstr;
|
569
|
+
pi->hash_set_num = hash_set_num;
|
570
|
+
pi->hash_set_value = hash_set_value;
|
571
|
+
pi->start_array = start_array;
|
572
|
+
pi->end_array = array_end;
|
573
|
+
pi->array_append_cstr = array_append_cstr;
|
574
|
+
pi->array_append_num = array_append_num;
|
593
575
|
pi->array_append_value = array_append_value;
|
594
|
-
pi->add_cstr
|
595
|
-
pi->add_num
|
596
|
-
pi->add_value
|
597
|
-
pi->expect_value
|
576
|
+
pi->add_cstr = add_cstr;
|
577
|
+
pi->add_num = add_num;
|
578
|
+
pi->add_value = add_value;
|
579
|
+
pi->expect_value = 1;
|
598
580
|
}
|
599
581
|
|
600
582
|
VALUE
|
601
583
|
oj_wab_parse(int argc, VALUE *argv, VALUE self) {
|
602
|
-
struct _parseInfo
|
584
|
+
struct _parseInfo pi;
|
603
585
|
|
604
586
|
parse_info_init(&pi);
|
605
|
-
pi.options
|
606
|
-
pi.handler
|
587
|
+
pi.options = oj_default_options;
|
588
|
+
pi.handler = Qnil;
|
607
589
|
pi.err_class = Qnil;
|
608
590
|
oj_set_wab_callbacks(&pi);
|
609
591
|
|
610
592
|
if (T_STRING == rb_type(*argv)) {
|
611
|
-
|
593
|
+
return oj_pi_parse(argc, argv, &pi, 0, 0, true);
|
612
594
|
} else {
|
613
|
-
|
595
|
+
return oj_pi_sparse(argc, argv, &pi, 0);
|
614
596
|
}
|
615
597
|
}
|
616
598
|
|
617
599
|
VALUE
|
618
600
|
oj_wab_parse_cstr(int argc, VALUE *argv, char *json, size_t len) {
|
619
|
-
struct _parseInfo
|
601
|
+
struct _parseInfo pi;
|
620
602
|
|
621
603
|
parse_info_init(&pi);
|
622
|
-
pi.options
|
623
|
-
pi.handler
|
604
|
+
pi.options = oj_default_options;
|
605
|
+
pi.handler = Qnil;
|
624
606
|
pi.err_class = Qnil;
|
625
607
|
oj_set_wab_callbacks(&pi);
|
626
608
|
|