json 2.13.1 → 2.19.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/CHANGES.md +98 -8
- data/LEGAL +12 -0
- data/README.md +19 -1
- data/ext/json/ext/fbuffer/fbuffer.h +47 -66
- data/ext/json/ext/generator/extconf.rb +1 -1
- data/ext/json/ext/generator/generator.c +375 -552
- data/ext/json/ext/json.h +105 -0
- data/ext/json/ext/parser/extconf.rb +2 -1
- data/ext/json/ext/parser/parser.c +661 -473
- data/ext/json/ext/simd/simd.h +81 -60
- data/ext/json/ext/vendor/fpconv.c +13 -12
- data/ext/json/ext/vendor/ryu.h +819 -0
- data/lib/json/add/core.rb +1 -0
- data/lib/json/add/string.rb +35 -0
- data/lib/json/common.rb +118 -49
- data/lib/json/ext/generator/state.rb +11 -14
- data/lib/json/generic_object.rb +0 -8
- data/lib/json/truffle_ruby/generator.rb +126 -64
- data/lib/json/version.rb +1 -1
- data/lib/json.rb +56 -1
- metadata +6 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 747237eb2b9348d361e6e93684f81381b4f0dcf0cd36971bc809ac042ce295bc
|
|
4
|
+
data.tar.gz: 1c6243010258fd2077acf63c5b372babce9a32e789630279bc8b129fc2deef5d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b43b4ca3d570a3c4051a319f9eb2d2807a6b2567f43cedf8bc21d8208289a3f3a275dc650353cd6ef4bd3e2022afcf73f17164fda51081134e11ac5172374459
|
|
7
|
+
data.tar.gz: 82a96b04fa36bb5b0ab72868d67e95cfcc8cc8d3f0a045a1caf8045b090e5cf46647b664accf7c657073020847cd8ce6ad28535d14536e214dcaab21b6aa4c17
|
data/CHANGES.md
CHANGED
|
@@ -2,6 +2,95 @@
|
|
|
2
2
|
|
|
3
3
|
### Unreleased
|
|
4
4
|
|
|
5
|
+
### 2026-03-08 (2.19.2)
|
|
6
|
+
|
|
7
|
+
* Fix a format string injection vulnerability in `JSON.parse(doc, allow_duplicate_key: false)`.
|
|
8
|
+
|
|
9
|
+
### 2026-03-08 (2.19.1)
|
|
10
|
+
|
|
11
|
+
* Fix a compiler dependent GC bug introduced in `2.18.0`.
|
|
12
|
+
|
|
13
|
+
### 2026-03-06 (2.19.0)
|
|
14
|
+
|
|
15
|
+
* Fix `allow_blank` parsing option to no longer allow invalid types (e.g. `load([], allow_blank: true)` now raise a type error).
|
|
16
|
+
* Add `allow_invalid_escape` parsing option to ignore backslashes that aren't followed by one of the valid escape characters.
|
|
17
|
+
|
|
18
|
+
### 2026-02-03 (2.18.1)
|
|
19
|
+
|
|
20
|
+
* Fix a potential crash in very specific circumstance if GC triggers during a call to `to_json`
|
|
21
|
+
without first invoking a user defined `#to_json` method.
|
|
22
|
+
|
|
23
|
+
### 2025-12-11 (2.18.0)
|
|
24
|
+
|
|
25
|
+
* Add `:allow_control_characters` parser options, to allow JSON strings containing unescaped ASCII control characters (e.g. newlines).
|
|
26
|
+
|
|
27
|
+
### 2025-12-04 (2.17.1)
|
|
28
|
+
|
|
29
|
+
* Fix a regression in parsing of unicode surogate pairs (`\uXX\uXX`) that could cause an invalid string to be returned.
|
|
30
|
+
|
|
31
|
+
### 2025-12-03 (2.17.0)
|
|
32
|
+
|
|
33
|
+
* Improve `JSON.load` and `JSON.unsafe_load` to allow passing options as second argument.
|
|
34
|
+
* Fix the parser to no longer ignore invalid escapes in strings.
|
|
35
|
+
Only `\"`, `\\`, `\b`, `\f`, `\n`, `\r`, `\t` and `\u` are valid JSON escapes.
|
|
36
|
+
* Fixed `JSON::Coder` to use the depth it was initialized with.
|
|
37
|
+
* On TruffleRuby, fix the generator to not call `to_json` on the return value of `as_json` for `Float::NAN`.
|
|
38
|
+
* Fixed handling of `state.depth`: when `to_json` changes `state.depth` but does not restore it, it is reset
|
|
39
|
+
automatically to its initial value.
|
|
40
|
+
In particular, when a `NestingError` is raised, `depth` is no longer equal to `max_nesting` after the call to
|
|
41
|
+
generate, and is reset to its initial value. Similarly when `to_json` raises an exception.
|
|
42
|
+
|
|
43
|
+
### 2025-11-07 (2.16.0)
|
|
44
|
+
|
|
45
|
+
* Deprecate `JSON::State#[]` and `JSON::State#[]=`. Consider using `JSON::Coder` instead.
|
|
46
|
+
* `JSON::Coder` now also yields to the block when encountering strings with invalid encoding.
|
|
47
|
+
* Fix GeneratorError messages to be UTF-8 encoded.
|
|
48
|
+
* Fix memory leak when `Exception` is raised, or `throw` is used during JSON generation.
|
|
49
|
+
* Optimized floating point number parsing by integrating the ryu algorithm (thanks to Josef Šimánek).
|
|
50
|
+
* Optimized numbers parsing using SWAR (thanks to Scott Myron).
|
|
51
|
+
* Optimized parsing of pretty printed documents using SWAR (thanks to Scott Myron).
|
|
52
|
+
|
|
53
|
+
### 2025-10-25 (2.15.2)
|
|
54
|
+
|
|
55
|
+
* Fix `JSON::Coder` to have one dedicated depth counter per invocation.
|
|
56
|
+
After encountering a circular reference in `JSON::Coder#dump`, any further `#dump` call would raise `JSON::NestingError`.
|
|
57
|
+
|
|
58
|
+
### 2025-10-07 (2.15.1)
|
|
59
|
+
|
|
60
|
+
* Fix incorrect escaping in the JRuby extension when encoding shared strings.
|
|
61
|
+
|
|
62
|
+
### 2025-09-22 (2.15.0)
|
|
63
|
+
|
|
64
|
+
* `JSON::Coder` callback now receive a second argument to convey whether the object is a hash key.
|
|
65
|
+
* Tuned the floating point number generator to not use scientific notation as aggressively.
|
|
66
|
+
|
|
67
|
+
### 2025-09-18 (2.14.1)
|
|
68
|
+
|
|
69
|
+
* Fix `IndexOutOfBoundsException` in the JRuby extension when encoding shared strings.
|
|
70
|
+
|
|
71
|
+
### 2025-09-18 (2.14.0)
|
|
72
|
+
|
|
73
|
+
* Add new `allow_duplicate_key` generator options. By default a warning is now emitted when a duplicated key is encountered.
|
|
74
|
+
In `json 3.0` an error will be raised.
|
|
75
|
+
```ruby
|
|
76
|
+
>> Warning[:deprecated] = true
|
|
77
|
+
>> puts JSON.generate({ foo: 1, "foo" => 2 })
|
|
78
|
+
(irb):2: warning: detected duplicate key "foo" in {foo: 1, "foo" => 2}.
|
|
79
|
+
This will raise an error in json 3.0 unless enabled via `allow_duplicate_key: true`
|
|
80
|
+
{"foo":1,"foo":2}
|
|
81
|
+
>> JSON.generate({ foo: 1, "foo" => 2 }, allow_duplicate_key: false)
|
|
82
|
+
detected duplicate key "foo" in {foo: 1, "foo" => 2} (JSON::GeneratorError)
|
|
83
|
+
```
|
|
84
|
+
* Fix `JSON.generate` `strict: true` mode to also restrict hash keys.
|
|
85
|
+
* Fix `JSON::Coder` to also invoke block for hash keys that aren't strings nor symbols.
|
|
86
|
+
* Fix `JSON.unsafe_load` usage with proc
|
|
87
|
+
* Fix the parser to more consistently reject invalid UTF-16 surogate pairs.
|
|
88
|
+
* Stop defining `String.json_create`, `String#to_json_raw`, `String#to_json_raw_object` when `json/add` isn't loaded.
|
|
89
|
+
|
|
90
|
+
### 2025-07-28 (2.13.2)
|
|
91
|
+
|
|
92
|
+
* Improve duplicate key warning and errors to include the key name and point to the right caller.
|
|
93
|
+
|
|
5
94
|
### 2025-07-24 (2.13.1)
|
|
6
95
|
|
|
7
96
|
* Fix support for older compilers without `__builtin_cpu_supports`.
|
|
@@ -40,7 +129,7 @@
|
|
|
40
129
|
### 2025-04-24 (2.11.1)
|
|
41
130
|
|
|
42
131
|
* Add back `JSON.restore`, `JSON.unparse`, `JSON.fast_unparse` and `JSON.pretty_unparse`.
|
|
43
|
-
These were deprecated 16 years ago, but never
|
|
132
|
+
These were deprecated 16 years ago, but never emitted warnings, only undocumented, so are
|
|
44
133
|
still used by a few gems.
|
|
45
134
|
|
|
46
135
|
### 2025-04-24 (2.11.0)
|
|
@@ -67,7 +156,7 @@
|
|
|
67
156
|
### 2025-03-12 (2.10.2)
|
|
68
157
|
|
|
69
158
|
* Fix a potential crash in the C extension parser.
|
|
70
|
-
* Raise a ParserError on all incomplete unicode escape sequence. This was the behavior until `2.10.0`
|
|
159
|
+
* Raise a ParserError on all incomplete unicode escape sequence. This was the behavior until `2.10.0` inadvertently changed it.
|
|
71
160
|
* Ensure document snippets that are included in parser errors don't include truncated multibyte characters.
|
|
72
161
|
* Ensure parser error snippets are valid UTF-8.
|
|
73
162
|
* Fix `JSON::GeneratorError#detailed_message` on Ruby < 3.2
|
|
@@ -98,7 +187,7 @@
|
|
|
98
187
|
|
|
99
188
|
### 2024-11-14 (2.8.2)
|
|
100
189
|
|
|
101
|
-
* `JSON.load_file`
|
|
190
|
+
* `JSON.load_file` explicitly read the file as UTF-8.
|
|
102
191
|
|
|
103
192
|
### 2024-11-06 (2.8.1)
|
|
104
193
|
|
|
@@ -106,7 +195,7 @@
|
|
|
106
195
|
|
|
107
196
|
### 2024-11-06 (2.8.0)
|
|
108
197
|
|
|
109
|
-
* Emit a deprecation warning when `JSON.load` create custom types without the `create_additions` option being
|
|
198
|
+
* Emit a deprecation warning when `JSON.load` create custom types without the `create_additions` option being explicitly enabled.
|
|
110
199
|
* Prefer to use `JSON.unsafe_load(string)` or `JSON.load(string, create_additions: true)`.
|
|
111
200
|
* Emit a deprecation warning when serializing valid UTF-8 strings encoded in `ASCII_8BIT` aka `BINARY`.
|
|
112
201
|
* Bump required Ruby version to 2.7.
|
|
@@ -114,7 +203,7 @@
|
|
|
114
203
|
pre-existing support for comments, make it suitable to parse `jsonc` documents.
|
|
115
204
|
* Many performance improvements to `JSON.parse` and `JSON.load`, up to `1.7x` faster on real world documents.
|
|
116
205
|
* Some minor performance improvements to `JSON.dump` and `JSON.generate`.
|
|
117
|
-
* `JSON.pretty_generate` no longer
|
|
206
|
+
* `JSON.pretty_generate` no longer includes newlines inside empty object and arrays.
|
|
118
207
|
|
|
119
208
|
### 2024-11-04 (2.7.6)
|
|
120
209
|
|
|
@@ -131,13 +220,13 @@
|
|
|
131
220
|
* Workaround a bug in 3.4.8 and older https://github.com/rubygems/rubygems/pull/6490.
|
|
132
221
|
This bug would cause some gems with native extension to fail during compilation.
|
|
133
222
|
* Workaround different versions of `json` and `json_pure` being loaded (not officially supported).
|
|
134
|
-
* Make `json_pure` Ractor compatible.
|
|
223
|
+
* Make `json_pure` Ractor compatible.
|
|
135
224
|
|
|
136
225
|
### 2024-10-24 (2.7.3)
|
|
137
226
|
|
|
138
227
|
* Numerous performance optimizations in `JSON.generate` and `JSON.dump` (up to 2 times faster).
|
|
139
|
-
* Limit the size of ParserError exception messages, only include up to 32 bytes of the
|
|
140
|
-
* Fix json-pure's `Object#to_json` to accept non
|
|
228
|
+
* Limit the size of ParserError exception messages, only include up to 32 bytes of the unparsable source.
|
|
229
|
+
* Fix json-pure's `Object#to_json` to accept non-state arguments.
|
|
141
230
|
* Fix multiline comment support in `json-pure`.
|
|
142
231
|
* Fix `JSON.parse` to no longer mutate the argument encoding when passed an ASCII-8BIT string.
|
|
143
232
|
* Fix `String#to_json` to raise on invalid encoding in `json-pure`.
|
|
@@ -282,6 +371,7 @@
|
|
|
282
371
|
## 2015-09-11 (2.0.0)
|
|
283
372
|
* Now complies to newest JSON RFC 7159.
|
|
284
373
|
* Implements compatibility to ruby 2.4 integer unification.
|
|
374
|
+
* Removed support for `quirks_mode` option.
|
|
285
375
|
* Drops support for old rubies whose life has ended, that is rubies < 2.0.
|
|
286
376
|
Also see https://www.ruby-lang.org/en/news/2014/07/01/eol-for-1-8-7-and-1-9-2/
|
|
287
377
|
* There were still some mentions of dual GPL licensing in the source, but JSON
|
data/LEGAL
CHANGED
|
@@ -6,3 +6,15 @@
|
|
|
6
6
|
All the files in this distribution are covered under either the Ruby's
|
|
7
7
|
license (see the file COPYING) or public-domain except some files
|
|
8
8
|
mentioned below.
|
|
9
|
+
|
|
10
|
+
ext/json/ext/vendor/fpconv.h::
|
|
11
|
+
This file is adapted from https://github.com/night-shift/fpconv
|
|
12
|
+
It is licensed under Boost Software License 1.0.
|
|
13
|
+
|
|
14
|
+
ext/json/ext/vendor/jeaiii-ltoa.h::
|
|
15
|
+
This file is adapted from https://github.com/jeaiii/itoa
|
|
16
|
+
It is licensed under the MIT License
|
|
17
|
+
|
|
18
|
+
ext/json/ext/vendor/ryu.h::
|
|
19
|
+
This file is adapted from the Ryu algorithm by Ulf Adams https://github.com/ulfjack/ryu.
|
|
20
|
+
It is dual-licensed under Apache License 2.0 OR Boost Software License 1.0.
|
data/README.md
CHANGED
|
@@ -97,7 +97,7 @@ Instead it is recommended to use the newer `JSON::Coder` API:
|
|
|
97
97
|
|
|
98
98
|
```ruby
|
|
99
99
|
module MyApp
|
|
100
|
-
API_JSON_CODER = JSON::Coder.new do |object|
|
|
100
|
+
API_JSON_CODER = JSON::Coder.new do |object, is_object_key|
|
|
101
101
|
case object
|
|
102
102
|
when Time
|
|
103
103
|
object.iso8601(3)
|
|
@@ -113,6 +113,24 @@ puts MyApp::API_JSON_CODER.dump(Time.now.utc) # => "2025-01-21T08:41:44.286Z"
|
|
|
113
113
|
The provided block is called for all objects that don't have a native JSON equivalent, and
|
|
114
114
|
must return a Ruby object that has a native JSON equivalent.
|
|
115
115
|
|
|
116
|
+
It is also called for objects that do have a JSON equivalent, but are used as Hash keys, for instance `{ 1 => 2}`,
|
|
117
|
+
as well as for strings that aren't valid UTF-8:
|
|
118
|
+
|
|
119
|
+
```ruby
|
|
120
|
+
coder = JSON::Combining.new do |object, is_object_key|
|
|
121
|
+
case object
|
|
122
|
+
when String
|
|
123
|
+
if !string.valid_encoding? || string.encoding != Encoding::UTF_8
|
|
124
|
+
Base64.encode64(string)
|
|
125
|
+
else
|
|
126
|
+
string
|
|
127
|
+
end
|
|
128
|
+
else
|
|
129
|
+
object
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
```
|
|
133
|
+
|
|
116
134
|
## Combining JSON fragments
|
|
117
135
|
|
|
118
136
|
To combine JSON fragments into a bigger JSON document, you can use `JSON::Fragment`:
|
|
@@ -1,47 +1,9 @@
|
|
|
1
1
|
#ifndef _FBUFFER_H_
|
|
2
2
|
#define _FBUFFER_H_
|
|
3
3
|
|
|
4
|
-
#include "
|
|
5
|
-
#include "ruby/encoding.h"
|
|
4
|
+
#include "../json.h"
|
|
6
5
|
#include "../vendor/jeaiii-ltoa.h"
|
|
7
6
|
|
|
8
|
-
/* shims */
|
|
9
|
-
/* This is the fallback definition from Ruby 3.4 */
|
|
10
|
-
|
|
11
|
-
#ifndef RBIMPL_STDBOOL_H
|
|
12
|
-
#if defined(__cplusplus)
|
|
13
|
-
# if defined(HAVE_STDBOOL_H) && (__cplusplus >= 201103L)
|
|
14
|
-
# include <cstdbool>
|
|
15
|
-
# endif
|
|
16
|
-
#elif defined(HAVE_STDBOOL_H)
|
|
17
|
-
# include <stdbool.h>
|
|
18
|
-
#elif !defined(HAVE__BOOL)
|
|
19
|
-
typedef unsigned char _Bool;
|
|
20
|
-
# define bool _Bool
|
|
21
|
-
# define true ((_Bool)+1)
|
|
22
|
-
# define false ((_Bool)+0)
|
|
23
|
-
# define __bool_true_false_are_defined
|
|
24
|
-
#endif
|
|
25
|
-
#endif
|
|
26
|
-
|
|
27
|
-
#ifndef RB_UNLIKELY
|
|
28
|
-
#define RB_UNLIKELY(expr) expr
|
|
29
|
-
#endif
|
|
30
|
-
|
|
31
|
-
#ifndef RB_LIKELY
|
|
32
|
-
#define RB_LIKELY(expr) expr
|
|
33
|
-
#endif
|
|
34
|
-
|
|
35
|
-
#ifndef MAYBE_UNUSED
|
|
36
|
-
# define MAYBE_UNUSED(x) x
|
|
37
|
-
#endif
|
|
38
|
-
|
|
39
|
-
#ifdef RUBY_DEBUG
|
|
40
|
-
#ifndef JSON_DEBUG
|
|
41
|
-
#define JSON_DEBUG RUBY_DEBUG
|
|
42
|
-
#endif
|
|
43
|
-
#endif
|
|
44
|
-
|
|
45
7
|
enum fbuffer_type {
|
|
46
8
|
FBUFFER_HEAP_ALLOCATED = 0,
|
|
47
9
|
FBUFFER_STACK_ALLOCATED = 1,
|
|
@@ -49,11 +11,11 @@ enum fbuffer_type {
|
|
|
49
11
|
|
|
50
12
|
typedef struct FBufferStruct {
|
|
51
13
|
enum fbuffer_type type;
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
#
|
|
56
|
-
|
|
14
|
+
size_t initial_length;
|
|
15
|
+
size_t len;
|
|
16
|
+
size_t capa;
|
|
17
|
+
#if JSON_DEBUG
|
|
18
|
+
size_t requested;
|
|
57
19
|
#endif
|
|
58
20
|
char *ptr;
|
|
59
21
|
VALUE io;
|
|
@@ -70,12 +32,12 @@ typedef struct FBufferStruct {
|
|
|
70
32
|
|
|
71
33
|
static void fbuffer_free(FBuffer *fb);
|
|
72
34
|
static void fbuffer_clear(FBuffer *fb);
|
|
73
|
-
static void fbuffer_append(FBuffer *fb, const char *newstr,
|
|
35
|
+
static void fbuffer_append(FBuffer *fb, const char *newstr, size_t len);
|
|
74
36
|
static void fbuffer_append_long(FBuffer *fb, long number);
|
|
75
37
|
static inline void fbuffer_append_char(FBuffer *fb, char newchr);
|
|
76
38
|
static VALUE fbuffer_finalize(FBuffer *fb);
|
|
77
39
|
|
|
78
|
-
static void fbuffer_stack_init(FBuffer *fb,
|
|
40
|
+
static void fbuffer_stack_init(FBuffer *fb, size_t initial_length, char *stack_buffer, size_t stack_buffer_size)
|
|
79
41
|
{
|
|
80
42
|
fb->initial_length = (initial_length > 0) ? initial_length : FBUFFER_INITIAL_LENGTH_DEFAULT;
|
|
81
43
|
if (stack_buffer) {
|
|
@@ -83,14 +45,14 @@ static void fbuffer_stack_init(FBuffer *fb, unsigned long initial_length, char *
|
|
|
83
45
|
fb->ptr = stack_buffer;
|
|
84
46
|
fb->capa = stack_buffer_size;
|
|
85
47
|
}
|
|
86
|
-
#
|
|
48
|
+
#if JSON_DEBUG
|
|
87
49
|
fb->requested = 0;
|
|
88
50
|
#endif
|
|
89
51
|
}
|
|
90
52
|
|
|
91
|
-
static inline void fbuffer_consumed(FBuffer *fb,
|
|
53
|
+
static inline void fbuffer_consumed(FBuffer *fb, size_t consumed)
|
|
92
54
|
{
|
|
93
|
-
#
|
|
55
|
+
#if JSON_DEBUG
|
|
94
56
|
if (consumed > fb->requested) {
|
|
95
57
|
rb_bug("fbuffer: Out of bound write");
|
|
96
58
|
}
|
|
@@ -117,7 +79,7 @@ static void fbuffer_flush(FBuffer *fb)
|
|
|
117
79
|
fbuffer_clear(fb);
|
|
118
80
|
}
|
|
119
81
|
|
|
120
|
-
static void fbuffer_realloc(FBuffer *fb,
|
|
82
|
+
static void fbuffer_realloc(FBuffer *fb, size_t required)
|
|
121
83
|
{
|
|
122
84
|
if (required > fb->capa) {
|
|
123
85
|
if (fb->type == FBUFFER_STACK_ALLOCATED) {
|
|
@@ -132,7 +94,7 @@ static void fbuffer_realloc(FBuffer *fb, unsigned long required)
|
|
|
132
94
|
}
|
|
133
95
|
}
|
|
134
96
|
|
|
135
|
-
static void fbuffer_do_inc_capa(FBuffer *fb,
|
|
97
|
+
static void fbuffer_do_inc_capa(FBuffer *fb, size_t requested)
|
|
136
98
|
{
|
|
137
99
|
if (RB_UNLIKELY(fb->io)) {
|
|
138
100
|
if (fb->capa < FBUFFER_IO_BUFFER_SIZE) {
|
|
@@ -146,7 +108,7 @@ static void fbuffer_do_inc_capa(FBuffer *fb, unsigned long requested)
|
|
|
146
108
|
}
|
|
147
109
|
}
|
|
148
110
|
|
|
149
|
-
|
|
111
|
+
size_t required;
|
|
150
112
|
|
|
151
113
|
if (RB_UNLIKELY(!fb->ptr)) {
|
|
152
114
|
fb->ptr = ALLOC_N(char, fb->initial_length);
|
|
@@ -158,9 +120,9 @@ static void fbuffer_do_inc_capa(FBuffer *fb, unsigned long requested)
|
|
|
158
120
|
fbuffer_realloc(fb, required);
|
|
159
121
|
}
|
|
160
122
|
|
|
161
|
-
static inline void fbuffer_inc_capa(FBuffer *fb,
|
|
123
|
+
static inline void fbuffer_inc_capa(FBuffer *fb, size_t requested)
|
|
162
124
|
{
|
|
163
|
-
#
|
|
125
|
+
#if JSON_DEBUG
|
|
164
126
|
fb->requested = requested;
|
|
165
127
|
#endif
|
|
166
128
|
|
|
@@ -169,19 +131,24 @@ static inline void fbuffer_inc_capa(FBuffer *fb, unsigned long requested)
|
|
|
169
131
|
}
|
|
170
132
|
}
|
|
171
133
|
|
|
172
|
-
static void
|
|
134
|
+
static inline void fbuffer_append_reserved(FBuffer *fb, const char *newstr, size_t len)
|
|
135
|
+
{
|
|
136
|
+
MEMCPY(fb->ptr + fb->len, newstr, char, len);
|
|
137
|
+
fbuffer_consumed(fb, len);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
static inline void fbuffer_append(FBuffer *fb, const char *newstr, size_t len)
|
|
173
141
|
{
|
|
174
142
|
if (len > 0) {
|
|
175
143
|
fbuffer_inc_capa(fb, len);
|
|
176
|
-
|
|
177
|
-
fbuffer_consumed(fb, len);
|
|
144
|
+
fbuffer_append_reserved(fb, newstr, len);
|
|
178
145
|
}
|
|
179
146
|
}
|
|
180
147
|
|
|
181
148
|
/* Appends a character into a buffer. The buffer needs to have sufficient capacity, via fbuffer_inc_capa(...). */
|
|
182
149
|
static inline void fbuffer_append_reserved_char(FBuffer *fb, char chr)
|
|
183
150
|
{
|
|
184
|
-
#
|
|
151
|
+
#if JSON_DEBUG
|
|
185
152
|
if (fb->requested < 1) {
|
|
186
153
|
rb_bug("fbuffer: unreserved write");
|
|
187
154
|
}
|
|
@@ -194,12 +161,29 @@ static inline void fbuffer_append_reserved_char(FBuffer *fb, char chr)
|
|
|
194
161
|
|
|
195
162
|
static void fbuffer_append_str(FBuffer *fb, VALUE str)
|
|
196
163
|
{
|
|
197
|
-
const char *
|
|
198
|
-
|
|
164
|
+
const char *ptr;
|
|
165
|
+
size_t len;
|
|
166
|
+
RSTRING_GETMEM(str, ptr, len);
|
|
199
167
|
|
|
168
|
+
fbuffer_append(fb, ptr, len);
|
|
200
169
|
RB_GC_GUARD(str);
|
|
170
|
+
}
|
|
201
171
|
|
|
202
|
-
|
|
172
|
+
static void fbuffer_append_str_repeat(FBuffer *fb, VALUE str, size_t repeat)
|
|
173
|
+
{
|
|
174
|
+
const char *ptr;
|
|
175
|
+
size_t len;
|
|
176
|
+
RSTRING_GETMEM(str, ptr, len);
|
|
177
|
+
|
|
178
|
+
fbuffer_inc_capa(fb, repeat * len);
|
|
179
|
+
while (repeat) {
|
|
180
|
+
#if JSON_DEBUG
|
|
181
|
+
fb->requested = len;
|
|
182
|
+
#endif
|
|
183
|
+
fbuffer_append_reserved(fb, ptr, len);
|
|
184
|
+
repeat--;
|
|
185
|
+
}
|
|
186
|
+
RB_GC_GUARD(str);
|
|
203
187
|
}
|
|
204
188
|
|
|
205
189
|
static inline void fbuffer_append_char(FBuffer *fb, char newchr)
|
|
@@ -257,14 +241,11 @@ static VALUE fbuffer_finalize(FBuffer *fb)
|
|
|
257
241
|
{
|
|
258
242
|
if (fb->io) {
|
|
259
243
|
fbuffer_flush(fb);
|
|
260
|
-
fbuffer_free(fb);
|
|
261
244
|
rb_io_flush(fb->io);
|
|
262
245
|
return fb->io;
|
|
263
246
|
} else {
|
|
264
|
-
|
|
265
|
-
fbuffer_free(fb);
|
|
266
|
-
return result;
|
|
247
|
+
return rb_utf8_str_new(FBUFFER_PTR(fb), FBUFFER_LEN(fb));
|
|
267
248
|
}
|
|
268
249
|
}
|
|
269
250
|
|
|
270
|
-
#endif
|
|
251
|
+
#endif // _FBUFFER_H_
|
|
@@ -6,7 +6,7 @@ if RUBY_ENGINE == 'truffleruby'
|
|
|
6
6
|
else
|
|
7
7
|
append_cflags("-std=c99")
|
|
8
8
|
$defs << "-DJSON_GENERATOR"
|
|
9
|
-
$defs << "-DJSON_DEBUG" if ENV
|
|
9
|
+
$defs << "-DJSON_DEBUG" if ENV.fetch("JSON_DEBUG", "0") != "0"
|
|
10
10
|
|
|
11
11
|
if enable_config('generator-use-simd', default=!ENV["JSON_DISABLE_SIMD"])
|
|
12
12
|
load __dir__ + "/../simd/conf.rb"
|