@@ -48,7 +48,7 @@ static long strio_write(VALUE self, VALUE str);
4848
4949#define IS_STRIO (obj ) (rb_typeddata_is_kind_of((obj), &strio_data_type))
5050#define error_inval (msg ) (rb_syserr_fail(EINVAL, msg))
51- #define get_enc (ptr ) ((ptr)->enc ? (ptr)->enc : rb_enc_get((ptr)->string))
51+ #define get_enc (ptr ) ((ptr)->enc ? (ptr)->enc : !NIL_P((ptr)->string) ? rb_enc_get((ptr)->string) : NULL )
5252
5353static struct StringIO *
5454strio_alloc (void )
@@ -281,13 +281,13 @@ strio_init(int argc, VALUE *argv, struct StringIO *ptr, VALUE self)
281281
282282 argc = rb_scan_args (argc , argv , "02:" , & string , & vmode , & opt );
283283 rb_io_extract_modeenc (& vmode , 0 , opt , & oflags , & ptr -> flags , & convconfig );
284- if (argc ) {
284+ if (! NIL_P ( string ) ) {
285285 StringValue (string );
286286 }
287- else {
287+ else if (! argc ) {
288288 string = rb_enc_str_new ("" , 0 , rb_default_external_encoding ());
289289 }
290- if (OBJ_FROZEN_RAW (string )) {
290+ if (! NIL_P ( string ) && OBJ_FROZEN_RAW (string )) {
291291 if (ptr -> flags & FMODE_WRITABLE ) {
292292 rb_syserr_fail (EACCES , 0 );
293293 }
@@ -297,11 +297,11 @@ strio_init(int argc, VALUE *argv, struct StringIO *ptr, VALUE self)
297297 ptr -> flags |= FMODE_WRITABLE ;
298298 }
299299 }
300- if (ptr -> flags & FMODE_TRUNC ) {
300+ if (! NIL_P ( string ) && ( ptr -> flags & FMODE_TRUNC ) ) {
301301 rb_str_resize (string , 0 );
302302 }
303303 RB_OBJ_WRITE (self , & ptr -> string , string );
304- if (argc == 1 ) {
304+ if (argc == 1 && ! NIL_P ( string ) ) {
305305 ptr -> enc = rb_enc_get (string );
306306 }
307307 else {
@@ -595,6 +595,7 @@ static struct StringIO *
595595strio_to_read (VALUE self )
596596{
597597 struct StringIO * ptr = readable (self );
598+ if (NIL_P (ptr -> string )) return NULL ;
598599 if (ptr -> pos < RSTRING_LEN (ptr -> string )) return ptr ;
599600 return NULL ;
600601}
@@ -872,7 +873,7 @@ strio_getc(VALUE self)
872873 int len ;
873874 char * p ;
874875
875- if (pos >= RSTRING_LEN (str )) {
876+ if (NIL_P ( str ) || pos >= RSTRING_LEN (str )) {
876877 return Qnil ;
877878 }
878879 p = RSTRING_PTR (str )+ pos ;
@@ -893,7 +894,7 @@ strio_getbyte(VALUE self)
893894{
894895 struct StringIO * ptr = readable (self );
895896 int c ;
896- if (ptr -> pos >= RSTRING_LEN (ptr -> string )) {
897+ if (NIL_P ( ptr -> string ) || ptr -> pos >= RSTRING_LEN (ptr -> string )) {
897898 return Qnil ;
898899 }
899900 c = RSTRING_PTR (ptr -> string )[ptr -> pos ++ ];
@@ -931,6 +932,7 @@ strio_ungetc(VALUE self, VALUE c)
931932 rb_encoding * enc , * enc2 ;
932933
933934 check_modifiable (ptr );
935+ if (NIL_P (ptr -> string )) return Qnil ;
934936 if (NIL_P (c )) return Qnil ;
935937 if (RB_INTEGER_TYPE_P (c )) {
936938 int len , cc = NUM2INT (c );
@@ -968,6 +970,7 @@ strio_ungetbyte(VALUE self, VALUE c)
968970 struct StringIO * ptr = readable (self );
969971
970972 check_modifiable (ptr );
973+ if (NIL_P (ptr -> string )) return Qnil ;
971974 if (NIL_P (c )) return Qnil ;
972975 if (RB_INTEGER_TYPE_P (c )) {
973976 /* rb_int_and() not visible from exts */
@@ -1171,7 +1174,7 @@ prepare_getline_args(struct StringIO *ptr, struct getline_arg *arg, int argc, VA
11711174 if (!NIL_P (lim )) limit = NUM2LONG (lim );
11721175 break ;
11731176 }
1174- if (!NIL_P (rs )) {
1177+ if (!NIL_P (ptr -> string ) && ! NIL_P ( rs )) {
11751178 rb_encoding * enc_rs , * enc_io ;
11761179 enc_rs = rb_enc_get (rs );
11771180 enc_io = get_enc (ptr );
@@ -1226,7 +1229,7 @@ strio_getline(struct getline_arg *arg, struct StringIO *ptr)
12261229 long w = 0 ;
12271230 rb_encoding * enc = get_enc (ptr );
12281231
1229- if (ptr -> pos >= (n = RSTRING_LEN (ptr -> string ))) {
1232+ if (NIL_P ( ptr -> string ) || ptr -> pos >= (n = RSTRING_LEN (ptr -> string ))) {
12301233 return Qnil ;
12311234 }
12321235 s = RSTRING_PTR (ptr -> string );
@@ -1323,6 +1326,7 @@ strio_gets(int argc, VALUE *argv, VALUE self)
13231326 VALUE str ;
13241327
13251328 if (prepare_getline_args (ptr , & arg , argc , argv )-> limit == 0 ) {
1329+ if (NIL_P (ptr -> string )) return Qnil ;
13261330 return rb_enc_str_new (0 , 0 , get_enc (ptr ));
13271331 }
13281332
@@ -1437,6 +1441,7 @@ strio_write(VALUE self, VALUE str)
14371441 if (!RB_TYPE_P (str , T_STRING ))
14381442 str = rb_obj_as_string (str );
14391443 enc = get_enc (ptr );
1444+ if (!enc ) return 0 ;
14401445 enc2 = rb_enc_get (str );
14411446 if (enc != enc2 && enc != ascii8bit && enc != (usascii = rb_usascii_encoding ())) {
14421447 VALUE converted = rb_str_conv_enc (str , enc2 , enc );
@@ -1509,10 +1514,12 @@ strio_putc(VALUE self, VALUE ch)
15091514
15101515 check_modifiable (ptr );
15111516 if (RB_TYPE_P (ch , T_STRING )) {
1517+ if (NIL_P (ptr -> string )) return ch ;
15121518 str = rb_str_substr (ch , 0 , 1 );
15131519 }
15141520 else {
15151521 char c = NUM2CHR (ch );
1522+ if (NIL_P (ptr -> string )) return ch ;
15161523 str = rb_str_new (& c , 1 );
15171524 }
15181525 strio_write (self , str );
@@ -1555,7 +1562,8 @@ strio_read(int argc, VALUE *argv, VALUE self)
15551562 if (len < 0 ) {
15561563 rb_raise (rb_eArgError , "negative length %ld given" , len );
15571564 }
1558- if (len > 0 && ptr -> pos >= RSTRING_LEN (ptr -> string )) {
1565+ if (len > 0 &&
1566+ (NIL_P (ptr -> string ) || ptr -> pos >= RSTRING_LEN (ptr -> string ))) {
15591567 if (!NIL_P (str )) rb_str_resize (str , 0 );
15601568 return Qnil ;
15611569 }
@@ -1564,6 +1572,7 @@ strio_read(int argc, VALUE *argv, VALUE self)
15641572 }
15651573 /* fall through */
15661574 case 0 :
1575+ if (NIL_P (ptr -> string )) return Qnil ;
15671576 len = RSTRING_LEN (ptr -> string );
15681577 if (len <= ptr -> pos ) {
15691578 rb_encoding * enc = get_enc (ptr );
@@ -1733,7 +1742,7 @@ strio_size(VALUE self)
17331742{
17341743 VALUE string = StringIO (self )-> string ;
17351744 if (NIL_P (string )) {
1736- rb_raise ( rb_eIOError , "not opened" );
1745+ return INT2FIX ( 0 );
17371746 }
17381747 return ULONG2NUM (RSTRING_LEN (string ));
17391748}
@@ -1750,10 +1759,12 @@ strio_truncate(VALUE self, VALUE len)
17501759{
17511760 VALUE string = writable (self )-> string ;
17521761 long l = NUM2LONG (len );
1753- long plen = RSTRING_LEN ( string ) ;
1762+ long plen ;
17541763 if (l < 0 ) {
17551764 error_inval ("negative length" );
17561765 }
1766+ if (NIL_P (string )) return 0 ;
1767+ plen = RSTRING_LEN (string );
17571768 rb_str_resize (string , l );
17581769 if (plen < l ) {
17591770 MEMZERO (RSTRING_PTR (string ) + plen , char , l - plen );
@@ -1824,7 +1835,7 @@ strio_set_encoding(int argc, VALUE *argv, VALUE self)
18241835 }
18251836 }
18261837 ptr -> enc = enc ;
1827- if (WRITABLE (self )) {
1838+ if (! NIL_P ( ptr -> string ) && WRITABLE (self )) {
18281839 rb_enc_associate (ptr -> string , enc );
18291840 }
18301841
0 commit comments