mirror of
https://github.com/ruby/ruby.git
synced 2026-08-03 13:08:59 +08:00
[ruby/json] generator.c: don't start with a stack buffer in IO case
It was never intended to be initialized with a stack buffer in that case, as when dumping into an IO we want larger chunks. https://github.com/ruby/json/commit/996bac686d
This commit is contained in:
parent
f7047b300f
commit
9ac37cd626
@ -37,13 +37,17 @@ static void fbuffer_append_long(FBuffer *fb, long number);
|
||||
static inline void fbuffer_append_char(FBuffer *fb, char newchr);
|
||||
static VALUE fbuffer_finalize(FBuffer *fb);
|
||||
|
||||
static void fbuffer_stack_init(FBuffer *fb, size_t initial_length, char *stack_buffer, size_t stack_buffer_size)
|
||||
static void fbuffer_init(FBuffer *fb, size_t initial_length, VALUE io, char *stack_buffer, size_t stack_buffer_size)
|
||||
{
|
||||
fb->initial_length = (initial_length > 0) ? initial_length : FBUFFER_INITIAL_LENGTH_DEFAULT;
|
||||
if (stack_buffer) {
|
||||
if (RTEST(io)) {
|
||||
JSON_ASSERT(fb->type == FBUFFER_HEAP_ALLOCATED);
|
||||
fb->io = io;
|
||||
fb->initial_length = (initial_length > 0) ? initial_length : FBUFFER_IO_BUFFER_SIZE;
|
||||
} else {
|
||||
fb->type = FBUFFER_STACK_ALLOCATED;
|
||||
fb->ptr = stack_buffer;
|
||||
fb->capa = stack_buffer_size;
|
||||
fb->initial_length = (initial_length > 0) ? initial_length : FBUFFER_INITIAL_LENGTH_DEFAULT;
|
||||
}
|
||||
#if JSON_DEBUG
|
||||
fb->requested = 0;
|
||||
@ -79,45 +83,40 @@ static void fbuffer_flush(FBuffer *fb)
|
||||
fbuffer_clear(fb);
|
||||
}
|
||||
|
||||
static void fbuffer_realloc(FBuffer *fb, size_t required)
|
||||
static void fbuffer_realloc(FBuffer *fb, size_t new_capa)
|
||||
{
|
||||
if (required > fb->capa) {
|
||||
if (new_capa > fb->capa) {
|
||||
if (fb->type == FBUFFER_STACK_ALLOCATED) {
|
||||
const char *old_buffer = fb->ptr;
|
||||
fb->ptr = ALLOC_N(char, required);
|
||||
fb->ptr = ALLOC_N(char, new_capa);
|
||||
fb->type = FBUFFER_HEAP_ALLOCATED;
|
||||
MEMCPY(fb->ptr, old_buffer, char, fb->len);
|
||||
} else {
|
||||
JSON_SIZED_REALLOC_N(fb->ptr, char, required, fb->capa);
|
||||
JSON_SIZED_REALLOC_N(fb->ptr, char, new_capa, fb->capa);
|
||||
}
|
||||
fb->capa = required;
|
||||
fb->capa = new_capa;
|
||||
}
|
||||
}
|
||||
|
||||
static void fbuffer_do_inc_capa(FBuffer *fb, size_t requested)
|
||||
{
|
||||
if (RB_UNLIKELY(fb->io)) {
|
||||
if (fb->capa < FBUFFER_IO_BUFFER_SIZE) {
|
||||
fbuffer_realloc(fb, FBUFFER_IO_BUFFER_SIZE);
|
||||
} else {
|
||||
if (fb->capa != 0) {
|
||||
fbuffer_flush(fb);
|
||||
}
|
||||
|
||||
if (RB_LIKELY(requested < fb->capa)) {
|
||||
return;
|
||||
if (RB_LIKELY(requested < fb->capa)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t required;
|
||||
size_t new_capa = fb->capa ? fb->capa : fb->initial_length;
|
||||
size_t needed_capa = requested + fb->len;
|
||||
|
||||
if (RB_UNLIKELY(!fb->ptr)) {
|
||||
fb->ptr = ALLOC_N(char, fb->initial_length);
|
||||
fb->capa = fb->initial_length;
|
||||
while (new_capa < needed_capa) {
|
||||
new_capa *= 2;
|
||||
}
|
||||
|
||||
for (required = fb->capa; requested > required - fb->len; required <<= 1);
|
||||
|
||||
fbuffer_realloc(fb, required);
|
||||
fbuffer_realloc(fb, new_capa);
|
||||
}
|
||||
|
||||
static inline void fbuffer_inc_capa(FBuffer *fb, size_t requested)
|
||||
|
||||
@ -1308,10 +1308,8 @@ static inline VALUE cState_partial_generate(VALUE self, VALUE obj, generator_fun
|
||||
GET_STATE(self);
|
||||
|
||||
char stack_buffer[FBUFFER_STACK_SIZE];
|
||||
FBuffer buffer = {
|
||||
.io = RTEST(io) ? io : Qfalse,
|
||||
};
|
||||
fbuffer_stack_init(&buffer, state->buffer_initial_length, stack_buffer, FBUFFER_STACK_SIZE);
|
||||
FBuffer buffer = { 0 };
|
||||
fbuffer_init(&buffer, state->buffer_initial_length, io, stack_buffer, FBUFFER_STACK_SIZE);
|
||||
|
||||
struct generate_json_data data = {
|
||||
.buffer = &buffer,
|
||||
@ -1870,10 +1868,8 @@ static VALUE cState_m_do_generate(VALUE klass, VALUE obj, VALUE opts, VALUE io,
|
||||
configure_state(&state, Qfalse, opts);
|
||||
|
||||
char stack_buffer[FBUFFER_STACK_SIZE];
|
||||
FBuffer buffer = {
|
||||
.io = RTEST(io) ? io : Qfalse,
|
||||
};
|
||||
fbuffer_stack_init(&buffer, state.buffer_initial_length, stack_buffer, FBUFFER_STACK_SIZE);
|
||||
FBuffer buffer = { 0 };
|
||||
fbuffer_init(&buffer, state.buffer_initial_length, io, stack_buffer, FBUFFER_STACK_SIZE);
|
||||
|
||||
struct generate_json_data data = {
|
||||
.buffer = &buffer,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user