@@ -48,7 +48,7 @@ static long strio_write(VALUE self, VALUE str);
48
48
49
49
#define IS_STRIO (obj ) (rb_typeddata_is_kind_of((obj), &strio_data_type))
50
50
#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 )
52
52
53
53
static struct StringIO *
54
54
strio_alloc (void )
@@ -281,13 +281,13 @@ strio_init(int argc, VALUE *argv, struct StringIO *ptr, VALUE self)
281
281
282
282
argc = rb_scan_args (argc , argv , "02:" , & string , & vmode , & opt );
283
283
rb_io_extract_modeenc (& vmode , 0 , opt , & oflags , & ptr -> flags , & convconfig );
284
- if (argc ) {
284
+ if (! NIL_P ( string ) ) {
285
285
StringValue (string );
286
286
}
287
- else {
287
+ else if (! argc ) {
288
288
string = rb_enc_str_new ("" , 0 , rb_default_external_encoding ());
289
289
}
290
- if (OBJ_FROZEN_RAW (string )) {
290
+ if (! NIL_P ( string ) && OBJ_FROZEN_RAW (string )) {
291
291
if (ptr -> flags & FMODE_WRITABLE ) {
292
292
rb_syserr_fail (EACCES , 0 );
293
293
}
@@ -297,11 +297,11 @@ strio_init(int argc, VALUE *argv, struct StringIO *ptr, VALUE self)
297
297
ptr -> flags |= FMODE_WRITABLE ;
298
298
}
299
299
}
300
- if (ptr -> flags & FMODE_TRUNC ) {
300
+ if (! NIL_P ( string ) && ( ptr -> flags & FMODE_TRUNC ) ) {
301
301
rb_str_resize (string , 0 );
302
302
}
303
303
RB_OBJ_WRITE (self , & ptr -> string , string );
304
- if (argc == 1 ) {
304
+ if (argc == 1 && ! NIL_P ( string ) ) {
305
305
ptr -> enc = rb_enc_get (string );
306
306
}
307
307
else {
@@ -595,6 +595,7 @@ static struct StringIO *
595
595
strio_to_read (VALUE self )
596
596
{
597
597
struct StringIO * ptr = readable (self );
598
+ if (NIL_P (ptr -> string )) return NULL ;
598
599
if (ptr -> pos < RSTRING_LEN (ptr -> string )) return ptr ;
599
600
return NULL ;
600
601
}
@@ -872,7 +873,7 @@ strio_getc(VALUE self)
872
873
int len ;
873
874
char * p ;
874
875
875
- if (pos >= RSTRING_LEN (str )) {
876
+ if (NIL_P ( str ) || pos >= RSTRING_LEN (str )) {
876
877
return Qnil ;
877
878
}
878
879
p = RSTRING_PTR (str )+ pos ;
@@ -893,7 +894,7 @@ strio_getbyte(VALUE self)
893
894
{
894
895
struct StringIO * ptr = readable (self );
895
896
int c ;
896
- if (ptr -> pos >= RSTRING_LEN (ptr -> string )) {
897
+ if (NIL_P ( ptr -> string ) || ptr -> pos >= RSTRING_LEN (ptr -> string )) {
897
898
return Qnil ;
898
899
}
899
900
c = RSTRING_PTR (ptr -> string )[ptr -> pos ++ ];
@@ -931,6 +932,7 @@ strio_ungetc(VALUE self, VALUE c)
931
932
rb_encoding * enc , * enc2 ;
932
933
933
934
check_modifiable (ptr );
935
+ if (NIL_P (ptr -> string )) return Qnil ;
934
936
if (NIL_P (c )) return Qnil ;
935
937
if (RB_INTEGER_TYPE_P (c )) {
936
938
int len , cc = NUM2INT (c );
@@ -968,6 +970,7 @@ strio_ungetbyte(VALUE self, VALUE c)
968
970
struct StringIO * ptr = readable (self );
969
971
970
972
check_modifiable (ptr );
973
+ if (NIL_P (ptr -> string )) return Qnil ;
971
974
if (NIL_P (c )) return Qnil ;
972
975
if (RB_INTEGER_TYPE_P (c )) {
973
976
/* rb_int_and() not visible from exts */
@@ -1171,7 +1174,7 @@ prepare_getline_args(struct StringIO *ptr, struct getline_arg *arg, int argc, VA
1171
1174
if (!NIL_P (lim )) limit = NUM2LONG (lim );
1172
1175
break ;
1173
1176
}
1174
- if (!NIL_P (rs )) {
1177
+ if (!NIL_P (ptr -> string ) && ! NIL_P ( rs )) {
1175
1178
rb_encoding * enc_rs , * enc_io ;
1176
1179
enc_rs = rb_enc_get (rs );
1177
1180
enc_io = get_enc (ptr );
@@ -1226,7 +1229,7 @@ strio_getline(struct getline_arg *arg, struct StringIO *ptr)
1226
1229
long w = 0 ;
1227
1230
rb_encoding * enc = get_enc (ptr );
1228
1231
1229
- if (ptr -> pos >= (n = RSTRING_LEN (ptr -> string ))) {
1232
+ if (NIL_P ( ptr -> string ) || ptr -> pos >= (n = RSTRING_LEN (ptr -> string ))) {
1230
1233
return Qnil ;
1231
1234
}
1232
1235
s = RSTRING_PTR (ptr -> string );
@@ -1323,6 +1326,7 @@ strio_gets(int argc, VALUE *argv, VALUE self)
1323
1326
VALUE str ;
1324
1327
1325
1328
if (prepare_getline_args (ptr , & arg , argc , argv )-> limit == 0 ) {
1329
+ if (NIL_P (ptr -> string )) return Qnil ;
1326
1330
return rb_enc_str_new (0 , 0 , get_enc (ptr ));
1327
1331
}
1328
1332
@@ -1437,6 +1441,7 @@ strio_write(VALUE self, VALUE str)
1437
1441
if (!RB_TYPE_P (str , T_STRING ))
1438
1442
str = rb_obj_as_string (str );
1439
1443
enc = get_enc (ptr );
1444
+ if (!enc ) return 0 ;
1440
1445
enc2 = rb_enc_get (str );
1441
1446
if (enc != enc2 && enc != ascii8bit && enc != (usascii = rb_usascii_encoding ())) {
1442
1447
VALUE converted = rb_str_conv_enc (str , enc2 , enc );
@@ -1509,10 +1514,12 @@ strio_putc(VALUE self, VALUE ch)
1509
1514
1510
1515
check_modifiable (ptr );
1511
1516
if (RB_TYPE_P (ch , T_STRING )) {
1517
+ if (NIL_P (ptr -> string )) return ch ;
1512
1518
str = rb_str_substr (ch , 0 , 1 );
1513
1519
}
1514
1520
else {
1515
1521
char c = NUM2CHR (ch );
1522
+ if (NIL_P (ptr -> string )) return ch ;
1516
1523
str = rb_str_new (& c , 1 );
1517
1524
}
1518
1525
strio_write (self , str );
@@ -1555,7 +1562,8 @@ strio_read(int argc, VALUE *argv, VALUE self)
1555
1562
if (len < 0 ) {
1556
1563
rb_raise (rb_eArgError , "negative length %ld given" , len );
1557
1564
}
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 ))) {
1559
1567
if (!NIL_P (str )) rb_str_resize (str , 0 );
1560
1568
return Qnil ;
1561
1569
}
@@ -1564,6 +1572,7 @@ strio_read(int argc, VALUE *argv, VALUE self)
1564
1572
}
1565
1573
/* fall through */
1566
1574
case 0 :
1575
+ if (NIL_P (ptr -> string )) return Qnil ;
1567
1576
len = RSTRING_LEN (ptr -> string );
1568
1577
if (len <= ptr -> pos ) {
1569
1578
rb_encoding * enc = get_enc (ptr );
@@ -1733,7 +1742,7 @@ strio_size(VALUE self)
1733
1742
{
1734
1743
VALUE string = StringIO (self )-> string ;
1735
1744
if (NIL_P (string )) {
1736
- rb_raise ( rb_eIOError , "not opened" );
1745
+ return INT2FIX ( 0 );
1737
1746
}
1738
1747
return ULONG2NUM (RSTRING_LEN (string ));
1739
1748
}
@@ -1750,10 +1759,12 @@ strio_truncate(VALUE self, VALUE len)
1750
1759
{
1751
1760
VALUE string = writable (self )-> string ;
1752
1761
long l = NUM2LONG (len );
1753
- long plen = RSTRING_LEN ( string ) ;
1762
+ long plen ;
1754
1763
if (l < 0 ) {
1755
1764
error_inval ("negative length" );
1756
1765
}
1766
+ if (NIL_P (string )) return 0 ;
1767
+ plen = RSTRING_LEN (string );
1757
1768
rb_str_resize (string , l );
1758
1769
if (plen < l ) {
1759
1770
MEMZERO (RSTRING_PTR (string ) + plen , char , l - plen );
@@ -1824,7 +1835,7 @@ strio_set_encoding(int argc, VALUE *argv, VALUE self)
1824
1835
}
1825
1836
}
1826
1837
ptr -> enc = enc ;
1827
- if (WRITABLE (self )) {
1838
+ if (! NIL_P ( ptr -> string ) && WRITABLE (self )) {
1828
1839
rb_enc_associate (ptr -> string , enc );
1829
1840
}
1830
1841
0 commit comments