diff --git a/io.c b/io.c index 6038609..ad91df7 100644 --- a/io.c +++ b/io.c @@ -161,6 +161,12 @@ static ID id_write, id_read, id_getc, id_flush, id_readpartial, id_set_encoding; static VALUE sym_mode, sym_perm, sym_extenc, sym_intenc, sym_encoding, sym_open_args; static VALUE sym_textmode, sym_binmode, sym_autoclose; static VALUE sym_SET, sym_CUR, sym_END; +#ifdef SEEK_DATA +static VALUE sym_DATA; +#endif +#ifdef SEEK_HOLE +static VALUE sym_HOLE; +#endif struct argf { VALUE filename, current_file; @@ -1551,6 +1557,14 @@ interpret_seek_whence(VALUE vwhence) return SEEK_CUR; if (vwhence == sym_END) return SEEK_END; +#ifdef SEEK_DATA + if (vwhence == sym_DATA) + return SEEK_DATA; +#endif +#ifdef SEEK_HOLE + if (vwhence == sym_HOLE) + return SEEK_HOLE; +#endif return NUM2INT(vwhence); } @@ -11820,6 +11834,14 @@ Init_IO(void) rb_define_const(rb_cIO, "SEEK_CUR", INT2FIX(SEEK_CUR)); /* Set I/O position from the end */ rb_define_const(rb_cIO, "SEEK_END", INT2FIX(SEEK_END)); +#ifdef SEEK_DATA + /* Set I/O position to the next location containing data */ + rb_define_const(rb_cIO, "SEEK_DATA", INT2FIX(SEEK_DATA)); +#endif +#ifdef SEEK_HOLE + /* Set I/O position to the next hole */ + rb_define_const(rb_cIO, "SEEK_HOLE", INT2FIX(SEEK_HOLE)); +#endif rb_define_method(rb_cIO, "rewind", rb_io_rewind, 0); rb_define_method(rb_cIO, "pos", rb_io_tell, 0); rb_define_method(rb_cIO, "pos=", rb_io_set_pos, 1); @@ -11989,4 +12011,10 @@ Init_IO(void) sym_SET = ID2SYM(rb_intern("SET")); sym_CUR = ID2SYM(rb_intern("CUR")); sym_END = ID2SYM(rb_intern("END")); +#ifdef SEEK_DATA + sym_DATA = ID2SYM(rb_intern("DATA")); +#endif +#ifdef SEEK_HOLE + sym_HOLE = ID2SYM(rb_intern("HOLE")); +#endif } diff --git a/test/ruby/test_io.rb b/test/ruby/test_io.rb index 999be76..469498c 100644 --- a/test/ruby/test_io.rb +++ b/test/ruby/test_io.rb @@ -1565,6 +1565,22 @@ class TestIO < Test::Unit::TestCase f.seek(2, IO::SEEK_CUR) assert_equal("r\nbaz\n", f.read) } + + if defined?(IO::SEEK_DATA) + open(t.path) { |f| + assert_equal("foo\n", f.gets) + f.seek(0, IO::SEEK_DATA) + assert_equal("foo\nbar\nbaz\n", f.read) + } + end + + if defined?(IO::SEEK_HOLE) + open(t.path) { |f|2 + assert_equal("foo\n", f.gets) + f.seek(0, IO::SEEK_HOLE) + assert_equal("", f.read) + } + end } end @@ -1585,6 +1601,22 @@ class TestIO < Test::Unit::TestCase f.seek(2, :CUR) assert_equal("r\nbaz\n", f.read) } + + if defined?(IO::SEEK_DATA) + open(t.path) { |f| + assert_equal("foo\n", f.gets) + f.seek(0, :DATA) + assert_equal("foo\nbar\nbaz\n", f.read) + } + end + + if defined?(IO::SEEK_HOLE) + open(t.path) { |f| + assert_equal("foo\n", f.gets) + f.seek(0, :HOLE) + assert_equal("", f.read) + } + end } end