Skip to content

Commit 7b20075

Browse files
committed
stringio: encoding support
1 parent aff05d9 commit 7b20075

File tree

2 files changed

+31
-28
lines changed

2 files changed

+31
-28
lines changed

ext/stringio/stringio.c

Lines changed: 20 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -190,40 +190,33 @@ strio_initialize(int argc, VALUE *argv, VALUE self)
190190
static VALUE
191191
strio_init(int argc, VALUE *argv, struct StringIO *ptr, VALUE self)
192192
{
193-
VALUE string, mode;
194-
int trunc = 0;
193+
VALUE string, vmode, opt;
194+
int oflags;
195+
struct rb_io_enc_t convconfig;
195196

196-
switch (rb_scan_args(argc, argv, "02", &string, &mode)) {
197-
case 2:
198-
if (FIXNUM_P(mode)) {
199-
int flags = FIX2INT(mode);
200-
ptr->flags = rb_io_oflags_fmode(flags);
201-
trunc = flags & O_TRUNC;
202-
}
203-
else {
204-
const char *m = StringValueCStr(mode);
205-
ptr->flags = rb_io_modestr_fmode(m);
206-
trunc = *m == 'w';
207-
}
197+
argc = rb_scan_args(argc, argv, "02:", &string, &vmode, &opt);
198+
rb_io_extract_modeenc(&vmode, 0, opt, &oflags, &ptr->flags, &convconfig);
199+
if (argc) {
208200
StringValue(string);
209-
if ((ptr->flags & FMODE_WRITABLE) && OBJ_FROZEN(string)) {
201+
}
202+
else {
203+
string = rb_enc_str_new("", 0, rb_default_external_encoding());
204+
}
205+
if (OBJ_FROZEN_RAW(string)) {
206+
if (ptr->flags & FMODE_WRITABLE) {
210207
rb_syserr_fail(EACCES, 0);
211208
}
212-
if (trunc) {
213-
rb_str_resize(string, 0);
209+
}
210+
else {
211+
if (NIL_P(vmode)) {
212+
ptr->flags |= FMODE_WRITABLE;
214213
}
215-
break;
216-
case 1:
217-
StringValue(string);
218-
ptr->flags = OBJ_FROZEN(string) ? FMODE_READABLE : FMODE_READWRITE;
219-
break;
220-
case 0:
221-
string = rb_enc_str_new("", 0, rb_default_external_encoding());
222-
ptr->flags = FMODE_READWRITE;
223-
break;
214+
}
215+
if (ptr->flags & FMODE_TRUNC) {
216+
rb_str_resize(string, 0);
224217
}
225218
ptr->string = string;
226-
ptr->enc = 0;
219+
ptr->enc = convconfig.enc;
227220
ptr->pos = 0;
228221
ptr->lineno = 0;
229222
RBASIC(self)->flags |= (ptr->flags & FMODE_READWRITE) * (STRIO_READABLE / FMODE_READABLE);

test/stringio/test_stringio.rb

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ def test_initialize
2222
assert_raise(ArgumentError) { StringIO.new('', 'rx') }
2323
assert_raise(ArgumentError) { StringIO.new('', 'rbt') }
2424
assert_raise(TypeError) { StringIO.new(nil) }
25-
assert_raise(TypeError) { StringIO.new('str', nil) }
2625

2726
o = Object.new
2827
def o.to_str
@@ -785,6 +784,17 @@ def test_overflow
785784
end;
786785
end
787786

787+
def test_encoding_write
788+
s = StringIO.new("", "w:utf-32be")
789+
s.print "abc"
790+
assert_equal("abc".encode("utf-32be"), s.string)
791+
end
792+
793+
def test_encoding_read
794+
s = StringIO.new("abc".encode("utf-32be"), "r:utf-8")
795+
assert_equal("\0\0\0a\0\0\0b\0\0\0c", s.read)
796+
end
797+
788798
def assert_string(content, encoding, str, mesg = nil)
789799
assert_equal([content, encoding], [str, str.encoding], mesg)
790800
end

0 commit comments

Comments
 (0)