Preview Ruby 4.1 is a preview. It can change before the final release. Switch to Ruby 4.0 →
instance method
JSON::ResumableParser#<<
self << string → self
ext/json/parser/parser.c
View on GitHub ↗
static VALUE cResumableParser_feed(VALUE self, VALUE str)
{
rb_check_frozen(self);
JSON_ResumableParser *parser = ResumableParser_acquire(self, false);
str = convert_encoding(str);
if (!RSTRING_LEN(str)) {
return self;
}
size_t offset = parser->state.cursor - parser->state.start;
const size_t remaining = parser->state.end - parser->state.cursor;
if (!remaining) {
if (parser->buffer) {
json_str_clear(parser->buffer);
}
parser->buffer = RB_OBJ_FROZEN_RAW(str) ? str : rb_obj_hide(rb_str_new_shared(str));
offset = 0;
} else {
JSON_ASSERT(parser->buffer);
const size_t size = parser->state.end - parser->state.start;
const size_t consumed = size - remaining;
if (RB_OBJ_FROZEN_RAW(parser->buffer)) {
VALUE new_buffer = rb_obj_hide(rb_str_buf_new(remaining + RSTRING_LEN(str)));
rb_enc_associate_index(new_buffer, utf8_encindex);
char *old_ptr = RSTRING_PTR(parser->buffer);
memcpy(RSTRING_PTR(new_buffer), old_ptr + consumed, remaining);
rb_str_set_len(new_buffer, remaining);
offset = 0;
parser->buffer = new_buffer;
} else if (consumed > (size / 2) && size >= 512) {
rb_str_modify(parser->buffer);
char *old_ptr = RSTRING_PTR(parser->buffer);
memmove(old_ptr, old_ptr + consumed, remaining);
rb_str_set_len(parser->buffer, remaining);
offset = 0;
}
rb_str_append(parser->buffer, str);
}
rb_len_t len;
const char *start;
RSTRING_GETMEM(parser->buffer, start, len);
parser->state.start = start;
parser->state.end = start + len;
parser->state.cursor = parser->state.start + offset;
return self;
}
Appends the given string to the parser’s buffer.