summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-12-18 07:54:33 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-12-18 07:54:33 +0000
commit3e1c01ae463a8c9d8bbe9050251a2538ddb0292f (patch)
tree6b976948575d7ca6042198ecb76889bf50173823 /ext
parentdd5fd65eef79637a951a766f5488724c87937c41 (diff)
stringio.c: separate encoding from buffer
* ext/stringio/stringio.c (strio_set_encoding): add StringIO's own encoding and separate it from the buffer string to override the encoding of string when reading. [ruby-core:72189] [Bug #11827] note that setting the encoding of its buffer string may cause unpredictable behavior. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@53188 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext')
-rw-r--r--ext/stringio/stringio.c26
1 files changed, 17 insertions, 9 deletions
diff --git a/ext/stringio/stringio.c b/ext/stringio/stringio.c
index 28e629599f..3a14716fef 100644
--- a/ext/stringio/stringio.c
+++ b/ext/stringio/stringio.c
@@ -22,6 +22,7 @@
struct StringIO {
VALUE string;
+ rb_encoding *enc;
long pos;
long lineno;
int flags;
@@ -33,6 +34,7 @@ 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))
+#define get_enc(ptr) ((ptr)->enc ? (ptr)->enc : rb_enc_get((ptr)->string))
static struct StringIO *
strio_alloc(void)
@@ -97,7 +99,7 @@ static VALUE
strio_substr(struct StringIO *ptr, long pos, long len)
{
VALUE str = ptr->string;
- rb_encoding *enc = rb_enc_get(str);
+ rb_encoding *enc = get_enc(ptr);
long rlen = RSTRING_LEN(str) - pos;
if (len > rlen) len = rlen;
@@ -210,6 +212,7 @@ strio_init(int argc, VALUE *argv, struct StringIO *ptr, VALUE self)
break;
}
ptr->string = string;
+ ptr->enc = 0;
ptr->pos = 0;
ptr->lineno = 0;
RBASIC(self)->flags |= (ptr->flags & FMODE_READWRITE) * (STRIO_READABLE / FMODE_READABLE);
@@ -663,7 +666,7 @@ static VALUE
strio_getc(VALUE self)
{
struct StringIO *ptr = readable(self);
- rb_encoding *enc = rb_enc_get(ptr->string);
+ rb_encoding *enc = get_enc(ptr);
int len;
char *p;
@@ -673,7 +676,7 @@ strio_getc(VALUE self)
p = RSTRING_PTR(ptr->string)+ptr->pos;
len = rb_enc_mbclen(p, RSTRING_END(ptr->string), enc);
ptr->pos += len;
- return rb_enc_str_new(p, len, rb_enc_get(ptr->string));
+ return rb_enc_str_new(p, len, enc);
}
/*
@@ -888,7 +891,7 @@ strio_each_codepoint(VALUE self)
RETURN_ENUMERATOR(self, 0, 0);
ptr = readable(self);
- enc = rb_enc_get(ptr->string);
+ enc = get_enc(ptr);
for (;;) {
if (ptr->pos >= RSTRING_LEN(ptr->string)) {
return self;
@@ -987,7 +990,7 @@ strio_getline(int argc, VALUE *argv, struct StringIO *ptr)
e = s + RSTRING_LEN(ptr->string);
s += ptr->pos;
if (limit > 0 && s + limit < e) {
- e = rb_enc_right_char_head(s, s + limit, e, rb_enc_get(ptr->string));
+ e = rb_enc_right_char_head(s, s + limit, e, get_enc(ptr));
}
if (NIL_P(str)) {
str = strio_substr(ptr, ptr->pos, e - s);
@@ -1164,7 +1167,7 @@ strio_write(VALUE self, VALUE str)
if (!RB_TYPE_P(str, T_STRING))
str = rb_obj_as_string(str);
- enc = rb_enc_get(ptr->string);
+ enc = get_enc(ptr);
enc2 = rb_enc_get(str);
if (enc != enc2 && enc != ascii8bit) {
str = rb_str_conv_enc(str, enc2, enc);
@@ -1439,7 +1442,8 @@ strio_truncate(VALUE self, VALUE len)
static VALUE
strio_external_encoding(VALUE self)
{
- return rb_enc_from_encoding(rb_enc_get(StringIO(self)->string));
+ struct StringIO *ptr = StringIO(self);
+ return rb_enc_from_encoding(get_enc(ptr));
}
/*
@@ -1470,7 +1474,7 @@ static VALUE
strio_set_encoding(int argc, VALUE *argv, VALUE self)
{
rb_encoding* enc;
- VALUE str = StringIO(self)->string;
+ struct StringIO *ptr = StringIO(self);
VALUE ext_enc, int_enc, opt;
argc = rb_scan_args(argc, argv, "11:", &ext_enc, &int_enc, &opt);
@@ -1481,7 +1485,11 @@ strio_set_encoding(int argc, VALUE *argv, VALUE self)
else {
enc = rb_to_encoding(ext_enc);
}
- rb_enc_associate(str, enc);
+ ptr->enc = enc;
+ if (WRITABLE(self)) {
+ rb_enc_associate(ptr->string, enc);
+ }
+
return self;
}