json 2.7.2 → 2.8.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|