diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2015-12-18 06:40:00 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2015-12-18 06:40:00 +0000 |
commit | 21973c01ab5da205aa261cc41d0639642b8aaf15 (patch) | |
tree | 1703f5a940c8c82d294cdad05f1bdade6a4bc4b9 | |
parent | a6e055f4a151a6f6dbbba0cd7231c699ec022ad7 (diff) | |
download | ruby-21973c01ab5da205aa261cc41d0639642b8aaf15.tar.gz |
stringio.c: strio_unget_bytes
* ext/stringio/stringio.c (strio_unget_bytes): extract from
strio_ungetbyte to share with strio_ungetc.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@53185 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | ext/stringio/stringio.c | 52 |
2 files changed, 26 insertions, 31 deletions
@@ -1,3 +1,8 @@ +Fri Dec 18 15:40:06 2015 Nobuyoshi Nakada <nobu@ruby-lang.org> + + * ext/stringio/stringio.c (strio_unget_bytes): extract from + strio_ungetbyte to share with strio_ungetc. + Fri Dec 18 12:39:42 2015 SHIBATA Hiroshi <hsbt@ruby-lang.org> * doc/syntax/*.rdoc: separated modifier at sentence. diff --git a/ext/stringio/stringio.c b/ext/stringio/stringio.c index 23d7deba02..28e629599f 100644 --- a/ext/stringio/stringio.c +++ b/ext/stringio/stringio.c @@ -29,6 +29,7 @@ struct StringIO { }; static void strio_init(int, VALUE *, struct StringIO *, VALUE); +static VALUE strio_unget_bytes(struct StringIO *, const char *, long); #define IS_STRIO(obj) (rb_typeddata_is_kind_of((obj), &strio_data_type)) #define error_inval(msg) (errno = EINVAL, rb_sys_fail(msg)) @@ -723,19 +724,17 @@ static VALUE strio_ungetc(VALUE self, VALUE c) { struct StringIO *ptr = readable(self); - long lpos, clen; - char *p, *pend; rb_encoding *enc, *enc2; - if (NIL_P(c)) return Qnil; check_modifiable(ptr); + if (NIL_P(c)) return Qnil; if (FIXNUM_P(c)) { int cc = FIX2INT(c); char buf[16]; enc = rb_enc_get(ptr->string); rb_enc_mbcput(cc, buf, enc); - c = rb_enc_str_new(buf, rb_enc_codelen(cc, enc), enc); + return strio_unget_bytes(ptr, buf, rb_enc_codelen(cc, enc)); } else { SafeStringValue(c); @@ -744,29 +743,10 @@ strio_ungetc(VALUE self, VALUE c) if (enc != enc2 && enc != rb_ascii8bit_encoding()) { c = rb_str_conv_enc(c, enc2, enc); } + strio_unget_bytes(ptr, RSTRING_PTR(c), RSTRING_LEN(c)); + RB_GC_GUARD(c); + return Qnil; } - if (RSTRING_LEN(ptr->string) < ptr->pos) { - long len = RSTRING_LEN(ptr->string); - rb_str_resize(ptr->string, ptr->pos - 1); - memset(RSTRING_PTR(ptr->string) + len, 0, ptr->pos - len - 1); - rb_str_concat(ptr->string, c); - ptr->pos--; - } - else { - /* get logical position */ - lpos = 0; p = RSTRING_PTR(ptr->string); pend = p + ptr->pos; - for (;;) { - clen = rb_enc_mbclen(p, pend, enc); - if (p+clen >= pend) break; - p += clen; - lpos++; - } - clen = p - RSTRING_PTR(ptr->string); - rb_str_update(ptr->string, lpos, ptr->pos ? 1 : 0, c); - ptr->pos = clen; - } - - return Qnil; } /* @@ -780,21 +760,32 @@ strio_ungetbyte(VALUE self, VALUE c) { struct StringIO *ptr = readable(self); char buf[1], *cp = buf; - long pos = ptr->pos, cl = 1, len, rest; - VALUE str = ptr->string; - char *s; + long cl = 1; + check_modifiable(ptr); if (NIL_P(c)) return Qnil; if (FIXNUM_P(c)) { buf[0] = (char)FIX2INT(c); + return strio_unget_bytes(ptr, buf, 1); } else { SafeStringValue(c); cp = RSTRING_PTR(c); cl = RSTRING_LEN(c); if (cl == 0) return Qnil; + strio_unget_bytes(ptr, cp, cl); + RB_GC_GUARD(c); + return Qnil; } - check_modifiable(ptr); +} + +static VALUE +strio_unget_bytes(struct StringIO *ptr, const char *cp, long cl) +{ + long pos = ptr->pos, len, rest; + VALUE str = ptr->string; + char *s; + len = RSTRING_LEN(str); rest = pos - len; if (cl > pos) { @@ -816,7 +807,6 @@ strio_ungetbyte(VALUE self, VALUE c) } memcpy(s + pos, cp, cl); ptr->pos = pos; - RB_GC_GUARD(c); return Qnil; } |