зеркало из https://github.com/github/ruby.git
stringio.c: close separatedly
* ext/stringio/stringio.c (strio_close): close separatedly per each instances, as well as IO. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37382 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
897a3fce91
Коммит
56f9574de8
|
@ -1,3 +1,8 @@
|
||||||
|
Mon Oct 29 18:22:58 2012 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* ext/stringio/stringio.c (strio_close): close separatedly per each
|
||||||
|
instances, as well as IO.
|
||||||
|
|
||||||
Mon Oct 29 10:22:00 2012 Aaron Patterson <aaron@tenderlovemaking.com>
|
Mon Oct 29 10:22:00 2012 Aaron Patterson <aaron@tenderlovemaking.com>
|
||||||
|
|
||||||
* ext/psych/lib/psych/handlers/recorder.rb: added a class for
|
* ext/psych/lib/psych/handlers/recorder.rb: added a class for
|
||||||
|
|
|
@ -28,7 +28,7 @@ struct StringIO {
|
||||||
int count;
|
int count;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void strio_init(int, VALUE *, struct StringIO *);
|
static void strio_init(int, VALUE *, struct StringIO *, VALUE);
|
||||||
|
|
||||||
#define IS_STRIO(obj) (rb_typeddata_is_kind_of((obj), &strio_data_type))
|
#define IS_STRIO(obj) (rb_typeddata_is_kind_of((obj), &strio_data_type))
|
||||||
#define error_inval(msg) (errno = EINVAL, rb_sys_fail(msg))
|
#define error_inval(msg) (errno = EINVAL, rb_sys_fail(msg))
|
||||||
|
@ -107,23 +107,32 @@ strio_substr(struct StringIO *ptr, long pos, long len)
|
||||||
|
|
||||||
#define StringIO(obj) get_strio(obj)
|
#define StringIO(obj) get_strio(obj)
|
||||||
|
|
||||||
#define CLOSED(ptr) (!((ptr)->flags & FMODE_READWRITE))
|
#define STRIO_READABLE FL_USER4
|
||||||
#define READABLE(ptr) ((ptr)->flags & FMODE_READABLE)
|
#define STRIO_WRITABLE FL_USER5
|
||||||
#define WRITABLE(ptr) ((ptr)->flags & FMODE_WRITABLE)
|
#define STRIO_READWRITE (STRIO_READABLE|STRIO_WRITABLE)
|
||||||
|
typedef char strio_flags_check[(STRIO_READABLE/FMODE_READABLE == STRIO_WRITABLE/FMODE_WRITABLE) * 2 - 1];
|
||||||
|
#define STRIO_MODE_SET_P(strio, mode) \
|
||||||
|
((RBASIC(strio)->flags & STRIO_##mode) && \
|
||||||
|
((struct StringIO*)DATA_PTR(strio))->flags & FMODE_##mode)
|
||||||
|
#define CLOSED(strio) (!STRIO_MODE_SET_P(strio, READWRITE))
|
||||||
|
#define READABLE(strio) STRIO_MODE_SET_P(strio, READABLE)
|
||||||
|
#define WRITABLE(strio) STRIO_MODE_SET_P(strio, WRITABLE)
|
||||||
|
|
||||||
static struct StringIO*
|
static struct StringIO*
|
||||||
readable(struct StringIO *ptr)
|
readable(VALUE strio)
|
||||||
{
|
{
|
||||||
if (!READABLE(ptr)) {
|
struct StringIO *ptr = StringIO(strio);
|
||||||
|
if (!READABLE(strio)) {
|
||||||
rb_raise(rb_eIOError, "not opened for reading");
|
rb_raise(rb_eIOError, "not opened for reading");
|
||||||
}
|
}
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct StringIO*
|
static struct StringIO*
|
||||||
writable(struct StringIO *ptr)
|
writable(VALUE strio)
|
||||||
{
|
{
|
||||||
if (!WRITABLE(ptr)) {
|
struct StringIO *ptr = StringIO(strio);
|
||||||
|
if (!WRITABLE(strio)) {
|
||||||
rb_raise(rb_eIOError, "not opened for writing");
|
rb_raise(rb_eIOError, "not opened for writing");
|
||||||
}
|
}
|
||||||
if (!OBJ_TAINTED(ptr->string)) {
|
if (!OBJ_TAINTED(ptr->string)) {
|
||||||
|
@ -160,12 +169,12 @@ strio_initialize(int argc, VALUE *argv, VALUE self)
|
||||||
DATA_PTR(self) = ptr = strio_alloc();
|
DATA_PTR(self) = ptr = strio_alloc();
|
||||||
}
|
}
|
||||||
rb_call_super(0, 0);
|
rb_call_super(0, 0);
|
||||||
strio_init(argc, argv, ptr);
|
strio_init(argc, argv, ptr, self);
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
strio_init(int argc, VALUE *argv, struct StringIO *ptr)
|
strio_init(int argc, VALUE *argv, struct StringIO *ptr, VALUE self)
|
||||||
{
|
{
|
||||||
VALUE string, mode;
|
VALUE string, mode;
|
||||||
int trunc = 0;
|
int trunc = 0;
|
||||||
|
@ -203,6 +212,7 @@ strio_init(int argc, VALUE *argv, struct StringIO *ptr)
|
||||||
ptr->string = string;
|
ptr->string = string;
|
||||||
ptr->pos = 0;
|
ptr->pos = 0;
|
||||||
ptr->lineno = 0;
|
ptr->lineno = 0;
|
||||||
|
RBASIC(self)->flags |= (ptr->flags & FMODE_READWRITE) * (STRIO_READABLE / FMODE_READABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
|
@ -332,11 +342,11 @@ strio_set_string(VALUE self, VALUE string)
|
||||||
static VALUE
|
static VALUE
|
||||||
strio_close(VALUE self)
|
strio_close(VALUE self)
|
||||||
{
|
{
|
||||||
struct StringIO *ptr = StringIO(self);
|
StringIO(self);
|
||||||
if (CLOSED(ptr)) {
|
if (CLOSED(self)) {
|
||||||
rb_raise(rb_eIOError, "closed stream");
|
rb_raise(rb_eIOError, "closed stream");
|
||||||
}
|
}
|
||||||
ptr->flags &= ~FMODE_READWRITE;
|
RBASIC(self)->flags &= ~STRIO_READWRITE;
|
||||||
return Qnil;
|
return Qnil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -350,11 +360,11 @@ strio_close(VALUE self)
|
||||||
static VALUE
|
static VALUE
|
||||||
strio_close_read(VALUE self)
|
strio_close_read(VALUE self)
|
||||||
{
|
{
|
||||||
struct StringIO *ptr = StringIO(self);
|
StringIO(self);
|
||||||
if (!READABLE(ptr)) {
|
if (!READABLE(self)) {
|
||||||
rb_raise(rb_eIOError, "closing non-duplex IO for reading");
|
rb_raise(rb_eIOError, "closing non-duplex IO for reading");
|
||||||
}
|
}
|
||||||
ptr->flags &= ~FMODE_READABLE;
|
RBASIC(self)->flags &= ~STRIO_READABLE;
|
||||||
return Qnil;
|
return Qnil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -368,11 +378,11 @@ strio_close_read(VALUE self)
|
||||||
static VALUE
|
static VALUE
|
||||||
strio_close_write(VALUE self)
|
strio_close_write(VALUE self)
|
||||||
{
|
{
|
||||||
struct StringIO *ptr = StringIO(self);
|
StringIO(self);
|
||||||
if (!WRITABLE(ptr)) {
|
if (!WRITABLE(self)) {
|
||||||
rb_raise(rb_eIOError, "closing non-duplex IO for writing");
|
rb_raise(rb_eIOError, "closing non-duplex IO for writing");
|
||||||
}
|
}
|
||||||
ptr->flags &= ~FMODE_WRITABLE;
|
RBASIC(self)->flags &= ~STRIO_WRITABLE;
|
||||||
return Qnil;
|
return Qnil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -385,8 +395,8 @@ strio_close_write(VALUE self)
|
||||||
static VALUE
|
static VALUE
|
||||||
strio_closed(VALUE self)
|
strio_closed(VALUE self)
|
||||||
{
|
{
|
||||||
struct StringIO *ptr = StringIO(self);
|
StringIO(self);
|
||||||
if (!CLOSED(ptr)) return Qfalse;
|
if (!CLOSED(self)) return Qfalse;
|
||||||
return Qtrue;
|
return Qtrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -399,8 +409,8 @@ strio_closed(VALUE self)
|
||||||
static VALUE
|
static VALUE
|
||||||
strio_closed_read(VALUE self)
|
strio_closed_read(VALUE self)
|
||||||
{
|
{
|
||||||
struct StringIO *ptr = StringIO(self);
|
StringIO(self);
|
||||||
if (READABLE(ptr)) return Qfalse;
|
if (READABLE(self)) return Qfalse;
|
||||||
return Qtrue;
|
return Qtrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -413,8 +423,8 @@ strio_closed_read(VALUE self)
|
||||||
static VALUE
|
static VALUE
|
||||||
strio_closed_write(VALUE self)
|
strio_closed_write(VALUE self)
|
||||||
{
|
{
|
||||||
struct StringIO *ptr = StringIO(self);
|
StringIO(self);
|
||||||
if (WRITABLE(ptr)) return Qfalse;
|
if (WRITABLE(self)) return Qfalse;
|
||||||
return Qtrue;
|
return Qtrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -429,7 +439,7 @@ strio_closed_write(VALUE self)
|
||||||
static VALUE
|
static VALUE
|
||||||
strio_eof(VALUE self)
|
strio_eof(VALUE self)
|
||||||
{
|
{
|
||||||
struct StringIO *ptr = readable(StringIO(self));
|
struct StringIO *ptr = readable(self);
|
||||||
if (ptr->pos < RSTRING_LEN(ptr->string)) return Qfalse;
|
if (ptr->pos < RSTRING_LEN(ptr->string)) return Qfalse;
|
||||||
return Qtrue;
|
return Qtrue;
|
||||||
}
|
}
|
||||||
|
@ -448,6 +458,8 @@ strio_copy(VALUE copy, VALUE orig)
|
||||||
}
|
}
|
||||||
DATA_PTR(copy) = ptr;
|
DATA_PTR(copy) = ptr;
|
||||||
OBJ_INFECT(copy, orig);
|
OBJ_INFECT(copy, orig);
|
||||||
|
RBASIC(copy)->flags &= ~STRIO_READWRITE;
|
||||||
|
RBASIC(copy)->flags |= RBASIC(orig)->flags & STRIO_READWRITE;
|
||||||
++ptr->count;
|
++ptr->count;
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
@ -509,7 +521,7 @@ strio_reopen(int argc, VALUE *argv, VALUE self)
|
||||||
if (argc == 1 && !RB_TYPE_P(*argv, T_STRING)) {
|
if (argc == 1 && !RB_TYPE_P(*argv, T_STRING)) {
|
||||||
return strio_copy(self, *argv);
|
return strio_copy(self, *argv);
|
||||||
}
|
}
|
||||||
strio_init(argc, argv, StringIO(self));
|
strio_init(argc, argv, StringIO(self), self);
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -576,7 +588,7 @@ strio_seek(int argc, VALUE *argv, VALUE self)
|
||||||
|
|
||||||
rb_scan_args(argc, argv, "11", NULL, &whence);
|
rb_scan_args(argc, argv, "11", NULL, &whence);
|
||||||
offset = NUM2LONG(argv[0]);
|
offset = NUM2LONG(argv[0]);
|
||||||
if (CLOSED(ptr)) {
|
if (CLOSED(self)) {
|
||||||
rb_raise(rb_eIOError, "closed stream");
|
rb_raise(rb_eIOError, "closed stream");
|
||||||
}
|
}
|
||||||
switch (NIL_P(whence) ? 0 : NUM2LONG(whence)) {
|
switch (NIL_P(whence) ? 0 : NUM2LONG(whence)) {
|
||||||
|
@ -629,7 +641,7 @@ strio_get_sync(VALUE self)
|
||||||
static VALUE
|
static VALUE
|
||||||
strio_each_byte(VALUE self)
|
strio_each_byte(VALUE self)
|
||||||
{
|
{
|
||||||
struct StringIO *ptr = readable(StringIO(self));
|
struct StringIO *ptr = readable(self);
|
||||||
|
|
||||||
RETURN_ENUMERATOR(self, 0, 0);
|
RETURN_ENUMERATOR(self, 0, 0);
|
||||||
|
|
||||||
|
@ -649,7 +661,7 @@ strio_each_byte(VALUE self)
|
||||||
static VALUE
|
static VALUE
|
||||||
strio_getc(VALUE self)
|
strio_getc(VALUE self)
|
||||||
{
|
{
|
||||||
struct StringIO *ptr = readable(StringIO(self));
|
struct StringIO *ptr = readable(self);
|
||||||
rb_encoding *enc = rb_enc_get(ptr->string);
|
rb_encoding *enc = rb_enc_get(ptr->string);
|
||||||
int len;
|
int len;
|
||||||
char *p;
|
char *p;
|
||||||
|
@ -672,7 +684,7 @@ strio_getc(VALUE self)
|
||||||
static VALUE
|
static VALUE
|
||||||
strio_getbyte(VALUE self)
|
strio_getbyte(VALUE self)
|
||||||
{
|
{
|
||||||
struct StringIO *ptr = readable(StringIO(self));
|
struct StringIO *ptr = readable(self);
|
||||||
int c;
|
int c;
|
||||||
if (ptr->pos >= RSTRING_LEN(ptr->string)) {
|
if (ptr->pos >= RSTRING_LEN(ptr->string)) {
|
||||||
return Qnil;
|
return Qnil;
|
||||||
|
@ -710,7 +722,7 @@ strio_extend(struct StringIO *ptr, long pos, long len)
|
||||||
static VALUE
|
static VALUE
|
||||||
strio_ungetc(VALUE self, VALUE c)
|
strio_ungetc(VALUE self, VALUE c)
|
||||||
{
|
{
|
||||||
struct StringIO *ptr = readable(StringIO(self));
|
struct StringIO *ptr = readable(self);
|
||||||
long lpos, clen;
|
long lpos, clen;
|
||||||
char *p, *pend;
|
char *p, *pend;
|
||||||
rb_encoding *enc, *enc2;
|
rb_encoding *enc, *enc2;
|
||||||
|
@ -765,7 +777,7 @@ strio_ungetc(VALUE self, VALUE c)
|
||||||
static VALUE
|
static VALUE
|
||||||
strio_ungetbyte(VALUE self, VALUE c)
|
strio_ungetbyte(VALUE self, VALUE c)
|
||||||
{
|
{
|
||||||
struct StringIO *ptr = readable(StringIO(self));
|
struct StringIO *ptr = readable(self);
|
||||||
char buf[1], *cp = buf;
|
char buf[1], *cp = buf;
|
||||||
long pos = ptr->pos, cl = 1;
|
long pos = ptr->pos, cl = 1;
|
||||||
VALUE str = ptr->string;
|
VALUE str = ptr->string;
|
||||||
|
@ -869,7 +881,7 @@ strio_each_codepoint(VALUE self)
|
||||||
|
|
||||||
RETURN_ENUMERATOR(self, 0, 0);
|
RETURN_ENUMERATOR(self, 0, 0);
|
||||||
|
|
||||||
ptr = readable(StringIO(self));
|
ptr = readable(self);
|
||||||
enc = rb_enc_get(ptr->string);
|
enc = rb_enc_get(ptr->string);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (ptr->pos >= RSTRING_LEN(ptr->string)) {
|
if (ptr->pos >= RSTRING_LEN(ptr->string)) {
|
||||||
|
@ -1021,7 +1033,7 @@ strio_getline(int argc, VALUE *argv, struct StringIO *ptr)
|
||||||
static VALUE
|
static VALUE
|
||||||
strio_gets(int argc, VALUE *argv, VALUE self)
|
strio_gets(int argc, VALUE *argv, VALUE self)
|
||||||
{
|
{
|
||||||
VALUE str = strio_getline(argc, argv, readable(StringIO(self)));
|
VALUE str = strio_getline(argc, argv, readable(self));
|
||||||
|
|
||||||
rb_lastline_set(str);
|
rb_lastline_set(str);
|
||||||
return str;
|
return str;
|
||||||
|
@ -1065,9 +1077,9 @@ strio_readline(int argc, VALUE *argv, VALUE self)
|
||||||
static VALUE
|
static VALUE
|
||||||
strio_each(int argc, VALUE *argv, VALUE self)
|
strio_each(int argc, VALUE *argv, VALUE self)
|
||||||
{
|
{
|
||||||
struct StringIO *ptr = StringIO(self);
|
|
||||||
VALUE line;
|
VALUE line;
|
||||||
|
|
||||||
|
StringIO(self);
|
||||||
RETURN_ENUMERATOR(self, argc, argv);
|
RETURN_ENUMERATOR(self, argc, argv);
|
||||||
|
|
||||||
if (argc > 0 && !NIL_P(argv[argc-1]) && NIL_P(rb_check_string_type(argv[argc-1])) &&
|
if (argc > 0 && !NIL_P(argv[argc-1]) && NIL_P(rb_check_string_type(argv[argc-1])) &&
|
||||||
|
@ -1075,7 +1087,7 @@ strio_each(int argc, VALUE *argv, VALUE self)
|
||||||
rb_raise(rb_eArgError, "invalid limit: 0 for each_line");
|
rb_raise(rb_eArgError, "invalid limit: 0 for each_line");
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!NIL_P(line = strio_getline(argc, argv, readable(ptr)))) {
|
while (!NIL_P(line = strio_getline(argc, argv, readable(self)))) {
|
||||||
rb_yield(line);
|
rb_yield(line);
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
|
@ -1092,15 +1104,16 @@ strio_each(int argc, VALUE *argv, VALUE self)
|
||||||
static VALUE
|
static VALUE
|
||||||
strio_readlines(int argc, VALUE *argv, VALUE self)
|
strio_readlines(int argc, VALUE *argv, VALUE self)
|
||||||
{
|
{
|
||||||
struct StringIO *ptr = StringIO(self);
|
VALUE ary, line;
|
||||||
VALUE ary = rb_ary_new(), line;
|
|
||||||
|
|
||||||
|
StringIO(self);
|
||||||
|
ary = rb_ary_new();
|
||||||
if (argc > 0 && !NIL_P(argv[argc-1]) && NIL_P(rb_check_string_type(argv[argc-1])) &&
|
if (argc > 0 && !NIL_P(argv[argc-1]) && NIL_P(rb_check_string_type(argv[argc-1])) &&
|
||||||
NUM2LONG(argv[argc-1]) == 0) {
|
NUM2LONG(argv[argc-1]) == 0) {
|
||||||
rb_raise(rb_eArgError, "invalid limit: 0 for readlines");
|
rb_raise(rb_eArgError, "invalid limit: 0 for readlines");
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!NIL_P(line = strio_getline(argc, argv, readable(ptr)))) {
|
while (!NIL_P(line = strio_getline(argc, argv, readable(self)))) {
|
||||||
rb_ary_push(ary, line);
|
rb_ary_push(ary, line);
|
||||||
}
|
}
|
||||||
return ary;
|
return ary;
|
||||||
|
@ -1119,7 +1132,7 @@ strio_readlines(int argc, VALUE *argv, VALUE self)
|
||||||
static VALUE
|
static VALUE
|
||||||
strio_write(VALUE self, VALUE str)
|
strio_write(VALUE self, VALUE str)
|
||||||
{
|
{
|
||||||
struct StringIO *ptr = writable(StringIO(self));
|
struct StringIO *ptr = writable(self);
|
||||||
long len, olen;
|
long len, olen;
|
||||||
rb_encoding *enc, *enc2;
|
rb_encoding *enc, *enc2;
|
||||||
|
|
||||||
|
@ -1185,7 +1198,7 @@ strio_write(VALUE self, VALUE str)
|
||||||
static VALUE
|
static VALUE
|
||||||
strio_putc(VALUE self, VALUE ch)
|
strio_putc(VALUE self, VALUE ch)
|
||||||
{
|
{
|
||||||
struct StringIO *ptr = writable(StringIO(self));
|
struct StringIO *ptr = writable(self);
|
||||||
int c = NUM2CHR(ch);
|
int c = NUM2CHR(ch);
|
||||||
long olen;
|
long olen;
|
||||||
|
|
||||||
|
@ -1217,7 +1230,7 @@ strio_putc(VALUE self, VALUE ch)
|
||||||
static VALUE
|
static VALUE
|
||||||
strio_read(int argc, VALUE *argv, VALUE self)
|
strio_read(int argc, VALUE *argv, VALUE self)
|
||||||
{
|
{
|
||||||
struct StringIO *ptr = readable(StringIO(self));
|
struct StringIO *ptr = readable(self);
|
||||||
VALUE str = Qnil;
|
VALUE str = Qnil;
|
||||||
long len;
|
long len;
|
||||||
int binary = 0;
|
int binary = 0;
|
||||||
|
@ -1338,7 +1351,7 @@ strio_size(VALUE self)
|
||||||
static VALUE
|
static VALUE
|
||||||
strio_truncate(VALUE self, VALUE len)
|
strio_truncate(VALUE self, VALUE len)
|
||||||
{
|
{
|
||||||
VALUE string = writable(StringIO(self))->string;
|
VALUE string = writable(self)->string;
|
||||||
long l = NUM2LONG(len);
|
long l = NUM2LONG(len);
|
||||||
long plen = RSTRING_LEN(string);
|
long plen = RSTRING_LEN(string);
|
||||||
if (l < 0) {
|
if (l < 0) {
|
||||||
|
|
|
@ -234,7 +234,7 @@ class TestStringIO < Test::Unit::TestCase
|
||||||
assert_equal(nil, f1.getc)
|
assert_equal(nil, f1.getc)
|
||||||
assert_equal(true, f2.eof?)
|
assert_equal(true, f2.eof?)
|
||||||
f1.close
|
f1.close
|
||||||
assert_equal(true, f2.closed?)
|
assert_equal(false, f2.closed?, '[ruby-core:48443]')
|
||||||
ensure
|
ensure
|
||||||
f1.close unless f1.closed?
|
f1.close unless f1.closed?
|
||||||
f2.close unless f2.closed?
|
f2.close unless f2.closed?
|
||||||
|
|
Загрузка…
Ссылка в новой задаче