json 2.7.2 → 2.8.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/BSDL +22 -0
- data/CHANGES.md +73 -17
- data/LEGAL +60 -0
- data/README.md +15 -236
- data/ext/json/ext/fbuffer/fbuffer.h +76 -79
- data/ext/json/ext/generator/extconf.rb +8 -2
- data/ext/json/ext/generator/generator.c +776 -816
- data/ext/json/ext/parser/extconf.rb +7 -27
- data/ext/json/ext/parser/parser.c +1697 -670
- data/ext/json/ext/parser/parser.rl +832 -338
- 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 +273 -95
- data/lib/json/ext/generator/state.rb +105 -0
- data/lib/json/ext.rb +13 -5
- data/lib/json/generic_object.rb +1 -1
- data/lib/json/{pure → truffle_ruby}/generator.rb +228 -120
- 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,101 +1,103 @@
|
|
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;
|
51
49
|
} FBuffer;
|
52
50
|
|
51
|
+
#define FBUFFER_STACK_SIZE 512
|
53
52
|
#define FBUFFER_INITIAL_LENGTH_DEFAULT 1024
|
54
53
|
|
55
|
-
#define FBUFFER_PTR(fb) (fb->ptr)
|
56
|
-
#define FBUFFER_LEN(fb) (fb->len)
|
57
|
-
#define FBUFFER_CAPA(fb) (fb->capa)
|
54
|
+
#define FBUFFER_PTR(fb) ((fb)->ptr)
|
55
|
+
#define FBUFFER_LEN(fb) ((fb)->len)
|
56
|
+
#define FBUFFER_CAPA(fb) ((fb)->capa)
|
58
57
|
#define FBUFFER_PAIR(fb) FBUFFER_PTR(fb), FBUFFER_LEN(fb)
|
59
58
|
|
60
|
-
static FBuffer *fbuffer_alloc(unsigned long initial_length);
|
61
59
|
static void fbuffer_free(FBuffer *fb);
|
60
|
+
#ifndef JSON_GENERATOR
|
62
61
|
static void fbuffer_clear(FBuffer *fb);
|
62
|
+
#endif
|
63
63
|
static void fbuffer_append(FBuffer *fb, const char *newstr, unsigned long len);
|
64
64
|
#ifdef JSON_GENERATOR
|
65
65
|
static void fbuffer_append_long(FBuffer *fb, long number);
|
66
66
|
#endif
|
67
|
-
static void fbuffer_append_char(FBuffer *fb, char newchr);
|
67
|
+
static inline void fbuffer_append_char(FBuffer *fb, char newchr);
|
68
68
|
#ifdef JSON_GENERATOR
|
69
|
-
static FBuffer *fbuffer_dup(FBuffer *fb);
|
70
69
|
static VALUE fbuffer_to_s(FBuffer *fb);
|
71
70
|
#endif
|
72
71
|
|
73
|
-
static FBuffer *
|
72
|
+
static void fbuffer_stack_init(FBuffer *fb, unsigned long initial_length, char *stack_buffer, long stack_buffer_size)
|
74
73
|
{
|
75
|
-
|
76
|
-
if (
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
74
|
+
fb->initial_length = (initial_length > 0) ? initial_length : FBUFFER_INITIAL_LENGTH_DEFAULT;
|
75
|
+
if (stack_buffer) {
|
76
|
+
fb->type = FBUFFER_STACK_ALLOCATED;
|
77
|
+
fb->ptr = stack_buffer;
|
78
|
+
fb->capa = stack_buffer_size;
|
79
|
+
}
|
81
80
|
}
|
82
81
|
|
83
82
|
static void fbuffer_free(FBuffer *fb)
|
84
83
|
{
|
85
|
-
if (fb->ptr
|
86
|
-
|
84
|
+
if (fb->ptr && fb->type == FBUFFER_HEAP_ALLOCATED) {
|
85
|
+
ruby_xfree(fb->ptr);
|
86
|
+
}
|
87
87
|
}
|
88
88
|
|
89
|
+
#ifndef JSON_GENERATOR
|
89
90
|
static void fbuffer_clear(FBuffer *fb)
|
90
91
|
{
|
91
92
|
fb->len = 0;
|
92
93
|
}
|
94
|
+
#endif
|
93
95
|
|
94
|
-
static void
|
96
|
+
static void fbuffer_do_inc_capa(FBuffer *fb, unsigned long requested)
|
95
97
|
{
|
96
98
|
unsigned long required;
|
97
99
|
|
98
|
-
if (!fb->ptr) {
|
100
|
+
if (RB_UNLIKELY(!fb->ptr)) {
|
99
101
|
fb->ptr = ALLOC_N(char, fb->initial_length);
|
100
102
|
fb->capa = fb->initial_length;
|
101
103
|
}
|
@@ -103,11 +105,25 @@ static void fbuffer_inc_capa(FBuffer *fb, unsigned long requested)
|
|
103
105
|
for (required = fb->capa; requested > required - fb->len; required <<= 1);
|
104
106
|
|
105
107
|
if (required > fb->capa) {
|
106
|
-
|
108
|
+
if (fb->type == FBUFFER_STACK_ALLOCATED) {
|
109
|
+
const char *old_buffer = fb->ptr;
|
110
|
+
fb->ptr = ALLOC_N(char, required);
|
111
|
+
fb->type = FBUFFER_HEAP_ALLOCATED;
|
112
|
+
MEMCPY(fb->ptr, old_buffer, char, fb->len);
|
113
|
+
} else {
|
114
|
+
REALLOC_N(fb->ptr, char, required);
|
115
|
+
}
|
107
116
|
fb->capa = required;
|
108
117
|
}
|
109
118
|
}
|
110
119
|
|
120
|
+
static inline void fbuffer_inc_capa(FBuffer *fb, unsigned long requested)
|
121
|
+
{
|
122
|
+
if (RB_UNLIKELY(requested > fb->capa - fb->len)) {
|
123
|
+
fbuffer_do_inc_capa(fb, requested);
|
124
|
+
}
|
125
|
+
}
|
126
|
+
|
111
127
|
static void fbuffer_append(FBuffer *fb, const char *newstr, unsigned long len)
|
112
128
|
{
|
113
129
|
if (len > 0) {
|
@@ -129,7 +145,7 @@ static void fbuffer_append_str(FBuffer *fb, VALUE str)
|
|
129
145
|
}
|
130
146
|
#endif
|
131
147
|
|
132
|
-
static void fbuffer_append_char(FBuffer *fb, char newchr)
|
148
|
+
static inline void fbuffer_append_char(FBuffer *fb, char newchr)
|
133
149
|
{
|
134
150
|
fbuffer_inc_capa(fb, 1);
|
135
151
|
*(fb->ptr + fb->len) = newchr;
|
@@ -137,50 +153,31 @@ static void fbuffer_append_char(FBuffer *fb, char newchr)
|
|
137
153
|
}
|
138
154
|
|
139
155
|
#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
156
|
static long fltoa(long number, char *buf)
|
150
157
|
{
|
151
|
-
static char digits[] = "0123456789";
|
158
|
+
static const char digits[] = "0123456789";
|
152
159
|
long sign = number;
|
153
160
|
char* tmp = buf;
|
154
161
|
|
155
162
|
if (sign < 0) number = -number;
|
156
|
-
do *tmp
|
157
|
-
if (sign < 0) *tmp
|
158
|
-
|
159
|
-
return tmp - buf;
|
163
|
+
do *tmp-- = digits[number % 10]; while (number /= 10);
|
164
|
+
if (sign < 0) *tmp-- = '-';
|
165
|
+
return buf - tmp;
|
160
166
|
}
|
161
167
|
|
168
|
+
#define LONG_BUFFER_SIZE 20
|
162
169
|
static void fbuffer_append_long(FBuffer *fb, long number)
|
163
170
|
{
|
164
|
-
char buf[
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
static FBuffer *fbuffer_dup(FBuffer *fb)
|
170
|
-
{
|
171
|
-
unsigned long len = fb->len;
|
172
|
-
FBuffer *result;
|
173
|
-
|
174
|
-
result = fbuffer_alloc(len);
|
175
|
-
fbuffer_append(result, FBUFFER_PAIR(fb));
|
176
|
-
return result;
|
171
|
+
char buf[LONG_BUFFER_SIZE];
|
172
|
+
char *buffer_end = buf + LONG_BUFFER_SIZE;
|
173
|
+
long len = fltoa(number, buffer_end - 1);
|
174
|
+
fbuffer_append(fb, buffer_end - len, len);
|
177
175
|
}
|
178
176
|
|
179
177
|
static VALUE fbuffer_to_s(FBuffer *fb)
|
180
178
|
{
|
181
|
-
VALUE result =
|
179
|
+
VALUE result = rb_utf8_str_new(FBUFFER_PTR(fb), FBUFFER_LEN(fb));
|
182
180
|
fbuffer_free(fb);
|
183
|
-
FORCE_UTF8(result);
|
184
181
|
return result;
|
185
182
|
}
|
186
183
|
#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
|