json 2.7.2 → 2.10.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 +98 -17
- data/LEGAL +8 -0
- data/README.md +68 -216
- data/ext/json/ext/fbuffer/fbuffer.h +110 -92
- data/ext/json/ext/generator/extconf.rb +8 -2
- data/ext/json/ext/generator/generator.c +952 -833
- data/ext/json/ext/parser/extconf.rb +7 -27
- data/ext/json/ext/parser/parser.c +1207 -1940
- data/json.gemspec +44 -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 +8 -4
- data/lib/json/add/time.rb +3 -10
- data/lib/json/common.rb +401 -106
- data/lib/json/ext/generator/state.rb +106 -0
- data/lib/json/ext.rb +34 -4
- data/lib/json/generic_object.rb +1 -1
- data/lib/json/{pure → truffle_ruby}/generator.rb +322 -145
- data/lib/json/version.rb +3 -7
- data/lib/json.rb +16 -21
- metadata +15 -22
- 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/ext/parser/parser.rl +0 -971
- 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,85 @@
|
|
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
62
|
static void fbuffer_clear(FBuffer *fb);
|
63
63
|
static void fbuffer_append(FBuffer *fb, const char *newstr, unsigned long len);
|
64
|
-
#ifdef JSON_GENERATOR
|
65
64
|
static void fbuffer_append_long(FBuffer *fb, long number);
|
66
|
-
|
67
|
-
static
|
68
|
-
#ifdef JSON_GENERATOR
|
69
|
-
static FBuffer *fbuffer_dup(FBuffer *fb);
|
70
|
-
static VALUE fbuffer_to_s(FBuffer *fb);
|
71
|
-
#endif
|
65
|
+
static inline void fbuffer_append_char(FBuffer *fb, char newchr);
|
66
|
+
static VALUE fbuffer_finalize(FBuffer *fb);
|
72
67
|
|
73
|
-
static FBuffer *
|
68
|
+
static void fbuffer_stack_init(FBuffer *fb, unsigned long initial_length, char *stack_buffer, long stack_buffer_size)
|
74
69
|
{
|
75
|
-
|
76
|
-
if (
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
70
|
+
fb->initial_length = (initial_length > 0) ? initial_length : FBUFFER_INITIAL_LENGTH_DEFAULT;
|
71
|
+
if (stack_buffer) {
|
72
|
+
fb->type = FBUFFER_STACK_ALLOCATED;
|
73
|
+
fb->ptr = stack_buffer;
|
74
|
+
fb->capa = stack_buffer_size;
|
75
|
+
}
|
81
76
|
}
|
82
77
|
|
83
78
|
static void fbuffer_free(FBuffer *fb)
|
84
79
|
{
|
85
|
-
if (fb->ptr
|
86
|
-
|
80
|
+
if (fb->ptr && fb->type == FBUFFER_HEAP_ALLOCATED) {
|
81
|
+
ruby_xfree(fb->ptr);
|
82
|
+
}
|
87
83
|
}
|
88
84
|
|
89
85
|
static void fbuffer_clear(FBuffer *fb)
|
@@ -91,20 +87,57 @@ static void fbuffer_clear(FBuffer *fb)
|
|
91
87
|
fb->len = 0;
|
92
88
|
}
|
93
89
|
|
94
|
-
static void
|
90
|
+
static void fbuffer_flush(FBuffer *fb)
|
91
|
+
{
|
92
|
+
rb_io_write(fb->io, rb_utf8_str_new(fb->ptr, fb->len));
|
93
|
+
fbuffer_clear(fb);
|
94
|
+
}
|
95
|
+
|
96
|
+
static void fbuffer_realloc(FBuffer *fb, unsigned long required)
|
97
|
+
{
|
98
|
+
if (required > fb->capa) {
|
99
|
+
if (fb->type == FBUFFER_STACK_ALLOCATED) {
|
100
|
+
const char *old_buffer = fb->ptr;
|
101
|
+
fb->ptr = ALLOC_N(char, required);
|
102
|
+
fb->type = FBUFFER_HEAP_ALLOCATED;
|
103
|
+
MEMCPY(fb->ptr, old_buffer, char, fb->len);
|
104
|
+
} else {
|
105
|
+
REALLOC_N(fb->ptr, char, required);
|
106
|
+
}
|
107
|
+
fb->capa = required;
|
108
|
+
}
|
109
|
+
}
|
110
|
+
|
111
|
+
static void fbuffer_do_inc_capa(FBuffer *fb, unsigned long requested)
|
95
112
|
{
|
113
|
+
if (RB_UNLIKELY(fb->io)) {
|
114
|
+
if (fb->capa < FBUFFER_IO_BUFFER_SIZE) {
|
115
|
+
fbuffer_realloc(fb, FBUFFER_IO_BUFFER_SIZE);
|
116
|
+
} else {
|
117
|
+
fbuffer_flush(fb);
|
118
|
+
}
|
119
|
+
|
120
|
+
if (RB_LIKELY(requested < fb->capa)) {
|
121
|
+
return;
|
122
|
+
}
|
123
|
+
}
|
124
|
+
|
96
125
|
unsigned long required;
|
97
126
|
|
98
|
-
if (!fb->ptr) {
|
127
|
+
if (RB_UNLIKELY(!fb->ptr)) {
|
99
128
|
fb->ptr = ALLOC_N(char, fb->initial_length);
|
100
129
|
fb->capa = fb->initial_length;
|
101
130
|
}
|
102
131
|
|
103
132
|
for (required = fb->capa; requested > required - fb->len; required <<= 1);
|
104
133
|
|
105
|
-
|
106
|
-
|
107
|
-
|
134
|
+
fbuffer_realloc(fb, required);
|
135
|
+
}
|
136
|
+
|
137
|
+
static inline void fbuffer_inc_capa(FBuffer *fb, unsigned long requested)
|
138
|
+
{
|
139
|
+
if (RB_UNLIKELY(requested > fb->capa - fb->len)) {
|
140
|
+
fbuffer_do_inc_capa(fb, requested);
|
108
141
|
}
|
109
142
|
}
|
110
143
|
|
@@ -117,7 +150,6 @@ static void fbuffer_append(FBuffer *fb, const char *newstr, unsigned long len)
|
|
117
150
|
}
|
118
151
|
}
|
119
152
|
|
120
|
-
#ifdef JSON_GENERATOR
|
121
153
|
static void fbuffer_append_str(FBuffer *fb, VALUE str)
|
122
154
|
{
|
123
155
|
const char *newstr = StringValuePtr(str);
|
@@ -127,61 +159,47 @@ static void fbuffer_append_str(FBuffer *fb, VALUE str)
|
|
127
159
|
|
128
160
|
fbuffer_append(fb, newstr, len);
|
129
161
|
}
|
130
|
-
#endif
|
131
162
|
|
132
|
-
static void fbuffer_append_char(FBuffer *fb, char newchr)
|
163
|
+
static inline void fbuffer_append_char(FBuffer *fb, char newchr)
|
133
164
|
{
|
134
165
|
fbuffer_inc_capa(fb, 1);
|
135
166
|
*(fb->ptr + fb->len) = newchr;
|
136
167
|
fb->len++;
|
137
168
|
}
|
138
169
|
|
139
|
-
#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
170
|
static long fltoa(long number, char *buf)
|
150
171
|
{
|
151
|
-
static char digits[] = "0123456789";
|
172
|
+
static const char digits[] = "0123456789";
|
152
173
|
long sign = number;
|
153
174
|
char* tmp = buf;
|
154
175
|
|
155
176
|
if (sign < 0) number = -number;
|
156
|
-
do *tmp
|
157
|
-
if (sign < 0) *tmp
|
158
|
-
|
159
|
-
return tmp - buf;
|
177
|
+
do *tmp-- = digits[number % 10]; while (number /= 10);
|
178
|
+
if (sign < 0) *tmp-- = '-';
|
179
|
+
return buf - tmp;
|
160
180
|
}
|
161
181
|
|
182
|
+
#define LONG_BUFFER_SIZE 20
|
162
183
|
static void fbuffer_append_long(FBuffer *fb, long number)
|
163
184
|
{
|
164
|
-
char buf[
|
165
|
-
|
166
|
-
|
185
|
+
char buf[LONG_BUFFER_SIZE];
|
186
|
+
char *buffer_end = buf + LONG_BUFFER_SIZE;
|
187
|
+
long len = fltoa(number, buffer_end - 1);
|
188
|
+
fbuffer_append(fb, buffer_end - len, len);
|
167
189
|
}
|
168
190
|
|
169
|
-
static
|
191
|
+
static VALUE fbuffer_finalize(FBuffer *fb)
|
170
192
|
{
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
193
|
+
if (fb->io) {
|
194
|
+
fbuffer_flush(fb);
|
195
|
+
fbuffer_free(fb);
|
196
|
+
rb_io_flush(fb->io);
|
197
|
+
return fb->io;
|
198
|
+
} else {
|
199
|
+
VALUE result = rb_utf8_str_new(FBUFFER_PTR(fb), FBUFFER_LEN(fb));
|
200
|
+
fbuffer_free(fb);
|
201
|
+
return result;
|
202
|
+
}
|
177
203
|
}
|
178
204
|
|
179
|
-
static VALUE fbuffer_to_s(FBuffer *fb)
|
180
|
-
{
|
181
|
-
VALUE result = rb_str_new(FBUFFER_PTR(fb), FBUFFER_LEN(fb));
|
182
|
-
fbuffer_free(fb);
|
183
|
-
FORCE_UTF8(result);
|
184
|
-
return result;
|
185
|
-
}
|
186
|
-
#endif
|
187
205
|
#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
|