@@ -1583,6 +1583,48 @@ strio_read(int argc, VALUE *argv, VALUE self)
15831583 return str ;
15841584}
15851585
1586+ /*
1587+ * call-seq:
1588+ * pread(maxlen, offset) -> string
1589+ * pread(maxlen, offset, out_string) -> string
1590+ *
1591+ * See IO#pread.
1592+ */
1593+ static VALUE
1594+ strio_pread (int argc , VALUE * argv , VALUE self )
1595+ {
1596+ VALUE rb_len , rb_offset , rb_buf ;
1597+ rb_scan_args (argc , argv , "21" , & rb_len , & rb_offset , & rb_buf );
1598+ long len = NUM2LONG (rb_len );
1599+ long offset = NUM2LONG (rb_offset );
1600+
1601+ if (len < 0 ) {
1602+ rb_raise (rb_eArgError , "negative string size (or size too big): %ld" , len );
1603+ }
1604+
1605+ if (offset < 0 ) {
1606+ rb_exc_raise (rb_syserr_new_str (EINVAL , rb_sprintf ("pread: Invalid offset argument: %ld" , offset )));
1607+ }
1608+
1609+ struct StringIO * ptr = readable (self );
1610+
1611+ if (offset >= RSTRING_LEN (ptr -> string )) {
1612+ rb_eof_error ();
1613+ }
1614+
1615+ if (NIL_P (rb_buf )) {
1616+ return strio_substr (ptr , offset , len , rb_ascii8bit_encoding ());
1617+ }
1618+
1619+ long rest = RSTRING_LEN (ptr -> string ) - offset ;
1620+ if (len > rest ) len = rest ;
1621+ rb_str_resize (rb_buf , len );
1622+ rb_enc_associate (rb_buf , rb_ascii8bit_encoding ());
1623+ MEMCPY (RSTRING_PTR (rb_buf ), RSTRING_PTR (ptr -> string ) + offset , char , len );
1624+ return rb_buf ;
1625+ }
1626+
1627+
15861628/*
15871629 * call-seq:
15881630 * strio.sysread(integer[, outbuf]) -> string
@@ -1843,6 +1885,7 @@ Init_stringio(void)
18431885 rb_define_method (StringIO , "gets" , strio_gets , -1 );
18441886 rb_define_method (StringIO , "readlines" , strio_readlines , -1 );
18451887 rb_define_method (StringIO , "read" , strio_read , -1 );
1888+ rb_define_method (StringIO , "pread" , strio_pread , -1 );
18461889
18471890 rb_define_method (StringIO , "write" , strio_write_m , -1 );
18481891 rb_define_method (StringIO , "putc" , strio_putc , 1 );
0 commit comments