json 2.7.2 → 2.9.1
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/BSDL +22 -0
- data/CHANGES.md +86 -17
- data/LEGAL +60 -0
- data/README.md +15 -236
- data/ext/json/ext/fbuffer/fbuffer.h +112 -85
- data/ext/json/ext/generator/extconf.rb +8 -2
- data/ext/json/ext/generator/generator.c +818 -830
- data/ext/json/ext/parser/extconf.rb +7 -27
- data/ext/json/ext/parser/parser.c +1698 -671
- data/ext/json/ext/parser/parser.rl +833 -339
- data/json.gemspec +45 -49
- data/lib/json/add/bigdecimal.rb +2 -2
- data/lib/json/add/complex.rb +1 -1
- data/lib/json/add/core.rb +1 -1
- data/lib/json/add/date.rb +1 -1
- data/lib/json/add/date_time.rb +1 -1
- data/lib/json/add/exception.rb +1 -1
- data/lib/json/add/ostruct.rb +1 -1
- data/lib/json/add/range.rb +1 -1
- data/lib/json/add/rational.rb +1 -1
- data/lib/json/add/regexp.rb +1 -1
- data/lib/json/add/struct.rb +1 -1
- data/lib/json/add/symbol.rb +1 -2
- data/lib/json/add/time.rb +3 -10
- data/lib/json/common.rb +299 -101
- data/lib/json/ext/generator/state.rb +116 -0
- data/lib/json/ext.rb +13 -5
- data/lib/json/generic_object.rb +1 -1
- data/lib/json/{pure → truffle_ruby}/generator.rb +242 -126
- data/lib/json/version.rb +3 -7
- data/lib/json.rb +16 -21
- metadata +19 -21
- data/ext/json/ext/generator/depend +0 -1
- data/ext/json/ext/generator/generator.h +0 -177
- data/ext/json/ext/parser/depend +0 -1
- data/ext/json/ext/parser/parser.h +0 -96
- data/ext/json/extconf.rb +0 -3
- data/lib/json/pure/parser.rb +0 -337
- data/lib/json/pure.rb +0 -15
- /data/{LICENSE → COPYING} +0 -0
@@ -1,89 +1,91 @@
|
|
1
|
-
|
2
1
|
#ifndef _FBUFFER_H_
|
3
2
|
#define _FBUFFER_H_
|
4
3
|
|
5
4
|
#include "ruby.h"
|
5
|
+
#include "ruby/encoding.h"
|
6
6
|
|
7
|
-
|
8
|
-
|
7
|
+
/* shims */
|
8
|
+
/* This is the fallback definition from Ruby 3.4 */
|
9
|
+
|
10
|
+
#ifndef RBIMPL_STDBOOL_H
|
11
|
+
#if defined(__cplusplus)
|
12
|
+
# if defined(HAVE_STDBOOL_H) && (__cplusplus >= 201103L)
|
13
|
+
# include <cstdbool>
|
14
|
+
# endif
|
15
|
+
#elif defined(HAVE_STDBOOL_H)
|
16
|
+
# include <stdbool.h>
|
17
|
+
#elif !defined(HAVE__BOOL)
|
18
|
+
typedef unsigned char _Bool;
|
19
|
+
# define bool _Bool
|
20
|
+
# define true ((_Bool)+1)
|
21
|
+
# define false ((_Bool)+0)
|
22
|
+
# define __bool_true_false_are_defined
|
9
23
|
#endif
|
10
|
-
|
11
|
-
#ifndef RFLOAT_VALUE
|
12
|
-
#define RFLOAT_VALUE(val) (RFLOAT(val)->value)
|
13
24
|
#endif
|
14
25
|
|
15
|
-
#ifndef
|
16
|
-
#define
|
17
|
-
#endif
|
18
|
-
#ifndef RSTRING_PTR
|
19
|
-
#define RSTRING_PTR(string) RSTRING(string)->ptr
|
20
|
-
#endif
|
21
|
-
#ifndef RSTRING_LEN
|
22
|
-
#define RSTRING_LEN(string) RSTRING(string)->len
|
26
|
+
#ifndef RB_UNLIKELY
|
27
|
+
#define RB_UNLIKELY(expr) expr
|
23
28
|
#endif
|
24
29
|
|
25
|
-
#
|
26
|
-
#
|
27
|
-
# define RB_OBJ_STRING(obj) (obj)
|
28
|
-
#else
|
29
|
-
# define PRIsVALUE "s"
|
30
|
-
# define RB_OBJ_CLASSNAME(obj) rb_obj_classname(obj)
|
31
|
-
# define RB_OBJ_STRING(obj) StringValueCStr(obj)
|
30
|
+
#ifndef RB_LIKELY
|
31
|
+
#define RB_LIKELY(expr) expr
|
32
32
|
#endif
|
33
33
|
|
34
|
-
#
|
35
|
-
#
|
36
|
-
#define FORCE_UTF8(obj) rb_enc_associate((obj), rb_utf8_encoding())
|
37
|
-
#else
|
38
|
-
#define FORCE_UTF8(obj)
|
34
|
+
#ifndef MAYBE_UNUSED
|
35
|
+
# define MAYBE_UNUSED(x) x
|
39
36
|
#endif
|
40
37
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
38
|
+
enum fbuffer_type {
|
39
|
+
FBUFFER_HEAP_ALLOCATED = 0,
|
40
|
+
FBUFFER_STACK_ALLOCATED = 1,
|
41
|
+
};
|
45
42
|
|
46
43
|
typedef struct FBufferStruct {
|
44
|
+
enum fbuffer_type type;
|
47
45
|
unsigned long initial_length;
|
48
|
-
char *ptr;
|
49
46
|
unsigned long len;
|
50
47
|
unsigned long capa;
|
48
|
+
char *ptr;
|
49
|
+
VALUE io;
|
51
50
|
} FBuffer;
|
52
51
|
|
52
|
+
#define FBUFFER_STACK_SIZE 512
|
53
|
+
#define FBUFFER_IO_BUFFER_SIZE (16384 - 1)
|
53
54
|
#define FBUFFER_INITIAL_LENGTH_DEFAULT 1024
|
54
55
|
|
55
|
-
#define FBUFFER_PTR(fb) (fb->ptr)
|
56
|
-
#define FBUFFER_LEN(fb) (fb->len)
|
57
|
-
#define FBUFFER_CAPA(fb) (fb->capa)
|
56
|
+
#define FBUFFER_PTR(fb) ((fb)->ptr)
|
57
|
+
#define FBUFFER_LEN(fb) ((fb)->len)
|
58
|
+
#define FBUFFER_CAPA(fb) ((fb)->capa)
|
58
59
|
#define FBUFFER_PAIR(fb) FBUFFER_PTR(fb), FBUFFER_LEN(fb)
|
59
60
|
|
60
|
-
static FBuffer *fbuffer_alloc(unsigned long initial_length);
|
61
61
|
static void fbuffer_free(FBuffer *fb);
|
62
|
+
#ifndef JSON_GENERATOR
|
62
63
|
static void fbuffer_clear(FBuffer *fb);
|
64
|
+
#endif
|
63
65
|
static void fbuffer_append(FBuffer *fb, const char *newstr, unsigned long len);
|
64
66
|
#ifdef JSON_GENERATOR
|
65
67
|
static void fbuffer_append_long(FBuffer *fb, long number);
|
66
68
|
#endif
|
67
|
-
static void fbuffer_append_char(FBuffer *fb, char newchr);
|
69
|
+
static inline void fbuffer_append_char(FBuffer *fb, char newchr);
|
68
70
|
#ifdef JSON_GENERATOR
|
69
|
-
static
|
70
|
-
static VALUE fbuffer_to_s(FBuffer *fb);
|
71
|
+
static VALUE fbuffer_finalize(FBuffer *fb);
|
71
72
|
#endif
|
72
73
|
|
73
|
-
static FBuffer *
|
74
|
+
static void fbuffer_stack_init(FBuffer *fb, unsigned long initial_length, char *stack_buffer, long stack_buffer_size)
|
74
75
|
{
|
75
|
-
|
76
|
-
if (
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
76
|
+
fb->initial_length = (initial_length > 0) ? initial_length : FBUFFER_INITIAL_LENGTH_DEFAULT;
|
77
|
+
if (stack_buffer) {
|
78
|
+
fb->type = FBUFFER_STACK_ALLOCATED;
|
79
|
+
fb->ptr = stack_buffer;
|
80
|
+
fb->capa = stack_buffer_size;
|
81
|
+
}
|
81
82
|
}
|
82
83
|
|
83
84
|
static void fbuffer_free(FBuffer *fb)
|
84
85
|
{
|
85
|
-
if (fb->ptr
|
86
|
-
|
86
|
+
if (fb->ptr && fb->type == FBUFFER_HEAP_ALLOCATED) {
|
87
|
+
ruby_xfree(fb->ptr);
|
88
|
+
}
|
87
89
|
}
|
88
90
|
|
89
91
|
static void fbuffer_clear(FBuffer *fb)
|
@@ -91,20 +93,57 @@ static void fbuffer_clear(FBuffer *fb)
|
|
91
93
|
fb->len = 0;
|
92
94
|
}
|
93
95
|
|
94
|
-
static void
|
96
|
+
static void fbuffer_flush(FBuffer *fb)
|
97
|
+
{
|
98
|
+
rb_io_write(fb->io, rb_utf8_str_new(fb->ptr, fb->len));
|
99
|
+
fbuffer_clear(fb);
|
100
|
+
}
|
101
|
+
|
102
|
+
static void fbuffer_realloc(FBuffer *fb, unsigned long required)
|
103
|
+
{
|
104
|
+
if (required > fb->capa) {
|
105
|
+
if (fb->type == FBUFFER_STACK_ALLOCATED) {
|
106
|
+
const char *old_buffer = fb->ptr;
|
107
|
+
fb->ptr = ALLOC_N(char, required);
|
108
|
+
fb->type = FBUFFER_HEAP_ALLOCATED;
|
109
|
+
MEMCPY(fb->ptr, old_buffer, char, fb->len);
|
110
|
+
} else {
|
111
|
+
REALLOC_N(fb->ptr, char, required);
|
112
|
+
}
|
113
|
+
fb->capa = required;
|
114
|
+
}
|
115
|
+
}
|
116
|
+
|
117
|
+
static void fbuffer_do_inc_capa(FBuffer *fb, unsigned long requested)
|
95
118
|
{
|
119
|
+
if (RB_UNLIKELY(fb->io)) {
|
120
|
+
if (fb->capa < FBUFFER_IO_BUFFER_SIZE) {
|
121
|
+
fbuffer_realloc(fb, FBUFFER_IO_BUFFER_SIZE);
|
122
|
+
} else {
|
123
|
+
fbuffer_flush(fb);
|
124
|
+
}
|
125
|
+
|
126
|
+
if (RB_LIKELY(requested < fb->capa)) {
|
127
|
+
return;
|
128
|
+
}
|
129
|
+
}
|
130
|
+
|
96
131
|
unsigned long required;
|
97
132
|
|
98
|
-
if (!fb->ptr) {
|
133
|
+
if (RB_UNLIKELY(!fb->ptr)) {
|
99
134
|
fb->ptr = ALLOC_N(char, fb->initial_length);
|
100
135
|
fb->capa = fb->initial_length;
|
101
136
|
}
|
102
137
|
|
103
138
|
for (required = fb->capa; requested > required - fb->len; required <<= 1);
|
104
139
|
|
105
|
-
|
106
|
-
|
107
|
-
|
140
|
+
fbuffer_realloc(fb, required);
|
141
|
+
}
|
142
|
+
|
143
|
+
static inline void fbuffer_inc_capa(FBuffer *fb, unsigned long requested)
|
144
|
+
{
|
145
|
+
if (RB_UNLIKELY(requested > fb->capa - fb->len)) {
|
146
|
+
fbuffer_do_inc_capa(fb, requested);
|
108
147
|
}
|
109
148
|
}
|
110
149
|
|
@@ -129,7 +168,7 @@ static void fbuffer_append_str(FBuffer *fb, VALUE str)
|
|
129
168
|
}
|
130
169
|
#endif
|
131
170
|
|
132
|
-
static void fbuffer_append_char(FBuffer *fb, char newchr)
|
171
|
+
static inline void fbuffer_append_char(FBuffer *fb, char newchr)
|
133
172
|
{
|
134
173
|
fbuffer_inc_capa(fb, 1);
|
135
174
|
*(fb->ptr + fb->len) = newchr;
|
@@ -137,51 +176,39 @@ static void fbuffer_append_char(FBuffer *fb, char newchr)
|
|
137
176
|
}
|
138
177
|
|
139
178
|
#ifdef JSON_GENERATOR
|
140
|
-
static void freverse(char *start, char *end)
|
141
|
-
{
|
142
|
-
char c;
|
143
|
-
|
144
|
-
while (end > start) {
|
145
|
-
c = *end, *end-- = *start, *start++ = c;
|
146
|
-
}
|
147
|
-
}
|
148
|
-
|
149
179
|
static long fltoa(long number, char *buf)
|
150
180
|
{
|
151
|
-
static char digits[] = "0123456789";
|
181
|
+
static const char digits[] = "0123456789";
|
152
182
|
long sign = number;
|
153
183
|
char* tmp = buf;
|
154
184
|
|
155
185
|
if (sign < 0) number = -number;
|
156
|
-
do *tmp
|
157
|
-
if (sign < 0) *tmp
|
158
|
-
|
159
|
-
return tmp - buf;
|
186
|
+
do *tmp-- = digits[number % 10]; while (number /= 10);
|
187
|
+
if (sign < 0) *tmp-- = '-';
|
188
|
+
return buf - tmp;
|
160
189
|
}
|
161
190
|
|
191
|
+
#define LONG_BUFFER_SIZE 20
|
162
192
|
static void fbuffer_append_long(FBuffer *fb, long number)
|
163
193
|
{
|
164
|
-
char buf[
|
165
|
-
|
166
|
-
|
194
|
+
char buf[LONG_BUFFER_SIZE];
|
195
|
+
char *buffer_end = buf + LONG_BUFFER_SIZE;
|
196
|
+
long len = fltoa(number, buffer_end - 1);
|
197
|
+
fbuffer_append(fb, buffer_end - len, len);
|
167
198
|
}
|
168
199
|
|
169
|
-
static
|
200
|
+
static VALUE fbuffer_finalize(FBuffer *fb)
|
170
201
|
{
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
VALUE result = rb_str_new(FBUFFER_PTR(fb), FBUFFER_LEN(fb));
|
182
|
-
fbuffer_free(fb);
|
183
|
-
FORCE_UTF8(result);
|
184
|
-
return result;
|
202
|
+
if (fb->io) {
|
203
|
+
fbuffer_flush(fb);
|
204
|
+
fbuffer_free(fb);
|
205
|
+
rb_io_flush(fb->io);
|
206
|
+
return fb->io;
|
207
|
+
} else {
|
208
|
+
VALUE result = rb_utf8_str_new(FBUFFER_PTR(fb), FBUFFER_LEN(fb));
|
209
|
+
fbuffer_free(fb);
|
210
|
+
return result;
|
211
|
+
}
|
185
212
|
}
|
186
213
|
#endif
|
187
214
|
#endif
|
@@ -1,4 +1,10 @@
|
|
1
1
|
require 'mkmf'
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
if RUBY_ENGINE == 'truffleruby'
|
4
|
+
# The pure-Ruby generator is faster on TruffleRuby, so skip compiling the generator extension
|
5
|
+
File.write('Makefile', dummy_makefile("").join)
|
6
|
+
else
|
7
|
+
append_cflags("-std=c99")
|
8
|
+
$defs << "-DJSON_GENERATOR"
|
9
|
+
create_makefile 'json/ext/generator'
|
10
|
+
end
|