diff options
| author | KOBAYASHI Shuji <[email protected]> | 2019-11-18 19:01:50 +0900 |
|---|---|---|
| committer | KOBAYASHI Shuji <[email protected]> | 2019-11-19 01:07:58 +0900 |
| commit | 3241a7e5a8c2fa6e7a161cb22e011a87ca3bc3c4 (patch) | |
| tree | d6322998ae3ed5fa849dbb3d94c3742f836ea993 /src/string.c | |
| parent | bd87799673de665eefe62f362d6310f51ffcc17c (diff) | |
| download | mruby-3241a7e5a8c2fa6e7a161cb22e011a87ca3bc3c4.tar.gz mruby-3241a7e5a8c2fa6e7a161cb22e011a87ca3bc3c4.zip | |
Refactor `mrb_string_value_cstr`
- Keep `MRB_STR_ASCII` flag.
- Avoid a string object creation.
Diffstat (limited to 'src/string.c')
| -rw-r--r-- | src/string.c | 55 |
1 files changed, 29 insertions, 26 deletions
diff --git a/src/string.c b/src/string.c index bf0d696d7..724aad745 100644 --- a/src/string.c +++ b/src/string.c @@ -246,6 +246,28 @@ str_decref(mrb_state *mrb, mrb_shared_string *shared) } static void +str_modify_keep_ascii(mrb_state *mrb, struct RString *s) +{ + if (RSTR_SHARED_P(s)) { + mrb_shared_string *shared = s->as.heap.aux.shared; + + if (shared->refcnt == 1 && s->as.heap.ptr == shared->ptr) { + s->as.heap.aux.capa = shared->capa; + s->as.heap.ptr[s->as.heap.len] = '\0'; + RSTR_UNSET_SHARED_FLAG(s); + mrb_free(mrb, shared); + } + else { + str_init_modifiable(mrb, s, s->as.heap.ptr, (size_t)s->as.heap.len); + str_decref(mrb, shared); + } + } + else if (RSTR_NOFREE_P(s) || RSTR_FSHARED_P(s)) { + str_init_modifiable(mrb, s, s->as.heap.ptr, (size_t)s->as.heap.len); + } +} + +static void check_null_byte(mrb_state *mrb, mrb_value str) { mrb_to_str(mrb, str); @@ -814,23 +836,7 @@ MRB_API void mrb_str_modify_keep_ascii(mrb_state *mrb, struct RString *s) { mrb_check_frozen(mrb, s); - if (RSTR_SHARED_P(s)) { - mrb_shared_string *shared = s->as.heap.aux.shared; - - if (shared->refcnt == 1 && s->as.heap.ptr == shared->ptr) { - s->as.heap.aux.capa = shared->capa; - s->as.heap.ptr[s->as.heap.len] = '\0'; - RSTR_UNSET_SHARED_FLAG(s); - mrb_free(mrb, shared); - } - else { - str_init_modifiable(mrb, s, s->as.heap.ptr, (size_t)s->as.heap.len); - str_decref(mrb, shared); - } - } - else if (RSTR_NOFREE_P(s) || RSTR_FSHARED_P(s)) { - str_init_modifiable(mrb, s, s->as.heap.ptr, (size_t)s->as.heap.len); - } + str_modify_keep_ascii(mrb, s); } MRB_API void @@ -2423,15 +2429,12 @@ mrb_string_value_cstr(mrb_state *mrb, mrb_value *ptr) if (p[len] == '\0') { return p; } - if (mrb_frozen_p(ps) || RSTR_CAPA(ps) == len) { - ps = str_new(mrb, NULL, len+1); - memcpy(RSTR_PTR(ps), p, len); - RSTR_SET_LEN(ps, len); - *ptr = mrb_obj_value(ps); - } - else { - mrb_str_modify(mrb, ps); - } + + /* + * Even after str_modify_keep_ascii(), NULL termination is not ensured if + * RSTR_SET_LEN() is used explicitly (e.g. String#delete_suffix!). + */ + str_modify_keep_ascii(mrb, ps); RSTR_PTR(ps)[len] = '\0'; return RSTR_PTR(ps); } |
