1/**********************************************************************
2
3  stringio.c -
4
5  $Author: glass $
6  $RoughId: stringio.c,v 1.13 2002/03/14 03:24:18 nobu Exp $
7  created at: Tue Feb 19 04:10:38 JST 2002
8
9  All the files in this distribution are covered under the Ruby's
10  license (see the file COPYING).
11
12**********************************************************************/
13
14#include "ruby.h"
15#include "ruby/io.h"
16#include "ruby/encoding.h"
17#if defined(HAVE_FCNTL_H) || defined(_WIN32)
18#include <fcntl.h>
19#elif defined(HAVE_SYS_FCNTL_H)
20#include <sys/fcntl.h>
21#endif
22
23struct StringIO {
24    VALUE string;
25    long pos;
26    long lineno;
27    int flags;
28    int count;
29};
30
31static void strio_init(int, VALUE *, struct StringIO *, VALUE);
32
33#define IS_STRIO(obj) (rb_typeddata_is_kind_of((obj), &strio_data_type))
34#define error_inval(msg) (errno = EINVAL, rb_sys_fail(msg))
35
36static struct StringIO *
37strio_alloc(void)
38{
39    struct StringIO *ptr = ALLOC(struct StringIO);
40    ptr->string = Qnil;
41    ptr->pos = 0;
42    ptr->lineno = 0;
43    ptr->flags = 0;
44    ptr->count = 1;
45    return ptr;
46}
47
48static void
49strio_mark(void *p)
50{
51    struct StringIO *ptr = p;
52    if (ptr) {
53	rb_gc_mark(ptr->string);
54    }
55}
56
57static void
58strio_free(void *p)
59{
60    struct StringIO *ptr = p;
61    if (--ptr->count <= 0) {
62	xfree(ptr);
63    }
64}
65
66static size_t
67strio_memsize(const void *p)
68{
69    const struct StringIO *ptr = p;
70    if (!ptr) return 0;
71    return sizeof(struct StringIO);
72}
73
74static const rb_data_type_t strio_data_type = {
75    "strio",
76    {
77	strio_mark,
78	strio_free,
79	strio_memsize,
80    },
81};
82
83#define check_strio(self) ((struct StringIO*)rb_check_typeddata((self), &strio_data_type))
84
85static struct StringIO*
86get_strio(VALUE self)
87{
88    struct StringIO *ptr = check_strio(rb_io_taint_check(self));
89
90    if (!ptr) {
91	rb_raise(rb_eIOError, "uninitialized stream");
92    }
93    return ptr;
94}
95
96static VALUE
97strio_substr(struct StringIO *ptr, long pos, long len)
98{
99    VALUE str = ptr->string;
100    rb_encoding *enc = rb_enc_get(str);
101    long rlen = RSTRING_LEN(str) - pos;
102
103    if (len > rlen) len = rlen;
104    if (len < 0) len = 0;
105    return rb_enc_str_new(RSTRING_PTR(str)+pos, len, enc);
106}
107
108#define StringIO(obj) get_strio(obj)
109
110#define STRIO_READABLE FL_USER4
111#define STRIO_WRITABLE FL_USER5
112#define STRIO_READWRITE (STRIO_READABLE|STRIO_WRITABLE)
113typedef char strio_flags_check[(STRIO_READABLE/FMODE_READABLE == STRIO_WRITABLE/FMODE_WRITABLE) * 2 - 1];
114#define STRIO_MODE_SET_P(strio, mode) \
115    ((RBASIC(strio)->flags & STRIO_##mode) && \
116     ((struct StringIO*)DATA_PTR(strio))->flags & FMODE_##mode)
117#define CLOSED(strio) (!STRIO_MODE_SET_P(strio, READWRITE))
118#define READABLE(strio) STRIO_MODE_SET_P(strio, READABLE)
119#define WRITABLE(strio) STRIO_MODE_SET_P(strio, WRITABLE)
120
121static struct StringIO*
122readable(VALUE strio)
123{
124    struct StringIO *ptr = StringIO(strio);
125    if (!READABLE(strio)) {
126	rb_raise(rb_eIOError, "not opened for reading");
127    }
128    return ptr;
129}
130
131static struct StringIO*
132writable(VALUE strio)
133{
134    struct StringIO *ptr = StringIO(strio);
135    if (!WRITABLE(strio)) {
136	rb_raise(rb_eIOError, "not opened for writing");
137    }
138    if (!OBJ_TAINTED(ptr->string)) {
139	rb_secure(4);
140    }
141    return ptr;
142}
143
144static void
145check_modifiable(struct StringIO *ptr)
146{
147    if (OBJ_FROZEN(ptr->string)) {
148	rb_raise(rb_eIOError, "not modifiable string");
149    }
150}
151
152static VALUE
153strio_s_allocate(VALUE klass)
154{
155    return TypedData_Wrap_Struct(klass, &strio_data_type, 0);
156}
157
158/*
159 * call-seq: StringIO.new(string=""[, mode])
160 *
161 * Creates new StringIO instance from with _string_ and _mode_.
162 */
163static VALUE
164strio_initialize(int argc, VALUE *argv, VALUE self)
165{
166    struct StringIO *ptr = check_strio(self);
167
168    if (!ptr) {
169	DATA_PTR(self) = ptr = strio_alloc();
170    }
171    rb_call_super(0, 0);
172    strio_init(argc, argv, ptr, self);
173    return self;
174}
175
176static void
177strio_init(int argc, VALUE *argv, struct StringIO *ptr, VALUE self)
178{
179    VALUE string, mode;
180    int trunc = 0;
181
182    switch (rb_scan_args(argc, argv, "02", &string, &mode)) {
183      case 2:
184	if (FIXNUM_P(mode)) {
185	    int flags = FIX2INT(mode);
186	    ptr->flags = rb_io_modenum_flags(flags);
187	    trunc = flags & O_TRUNC;
188	}
189	else {
190	    const char *m = StringValueCStr(mode);
191	    ptr->flags = rb_io_mode_flags(m);
192	    trunc = *m == 'w';
193	}
194	StringValue(string);
195	if ((ptr->flags & FMODE_WRITABLE) && OBJ_FROZEN(string)) {
196	    errno = EACCES;
197	    rb_sys_fail(0);
198	}
199	if (trunc) {
200	    rb_str_resize(string, 0);
201	}
202	break;
203      case 1:
204	StringValue(string);
205	ptr->flags = OBJ_FROZEN(string) ? FMODE_READABLE : FMODE_READWRITE;
206	break;
207      case 0:
208	string = rb_enc_str_new("", 0, rb_default_external_encoding());
209	ptr->flags = FMODE_READWRITE;
210	break;
211    }
212    ptr->string = string;
213    ptr->pos = 0;
214    ptr->lineno = 0;
215    RBASIC(self)->flags |= (ptr->flags & FMODE_READWRITE) * (STRIO_READABLE / FMODE_READABLE);
216}
217
218static VALUE
219strio_finalize(VALUE self)
220{
221    struct StringIO *ptr = StringIO(self);
222    ptr->string = Qnil;
223    ptr->flags &= ~FMODE_READWRITE;
224    return self;
225}
226
227/*
228 * call-seq: StringIO.open(string=""[, mode]) {|strio| ...}
229 *
230 * Equivalent to StringIO.new except that when it is called with a block, it
231 * yields with the new instance and closes it, and returns the result which
232 * returned from the block.
233 */
234static VALUE
235strio_s_open(int argc, VALUE *argv, VALUE klass)
236{
237    VALUE obj = rb_class_new_instance(argc, argv, klass);
238    if (!rb_block_given_p()) return obj;
239    return rb_ensure(rb_yield, obj, strio_finalize, obj);
240}
241
242/*
243 * Returns +false+.  Just for compatibility to IO.
244 */
245static VALUE
246strio_false(VALUE self)
247{
248    StringIO(self);
249    return Qfalse;
250}
251
252/*
253 * Returns +nil+.  Just for compatibility to IO.
254 */
255static VALUE
256strio_nil(VALUE self)
257{
258    StringIO(self);
259    return Qnil;
260}
261
262/*
263 * Returns *strio* itself.  Just for compatibility to IO.
264 */
265static VALUE
266strio_self(VALUE self)
267{
268    StringIO(self);
269    return self;
270}
271
272/*
273 * Returns 0.  Just for compatibility to IO.
274 */
275static VALUE
276strio_0(VALUE self)
277{
278    StringIO(self);
279    return INT2FIX(0);
280}
281
282/*
283 * Returns the argument unchanged.  Just for compatibility to IO.
284 */
285static VALUE
286strio_first(VALUE self, VALUE arg)
287{
288    StringIO(self);
289    return arg;
290}
291
292/*
293 * Raises NotImplementedError.
294 */
295static VALUE
296strio_unimpl(int argc, VALUE *argv, VALUE self)
297{
298    StringIO(self);
299    rb_notimplement();
300
301    UNREACHABLE;
302}
303
304/*
305 * call-seq: strio.string     -> string
306 *
307 * Returns underlying String object, the subject of IO.
308 */
309static VALUE
310strio_get_string(VALUE self)
311{
312    return StringIO(self)->string;
313}
314
315/*
316 * call-seq:
317 *   strio.string = string  -> string
318 *
319 * Changes underlying String object, the subject of IO.
320 */
321static VALUE
322strio_set_string(VALUE self, VALUE string)
323{
324    struct StringIO *ptr = StringIO(self);
325
326    rb_io_taint_check(self);
327    ptr->flags &= ~FMODE_READWRITE;
328    StringValue(string);
329    ptr->flags = OBJ_FROZEN(string) ? FMODE_READABLE : FMODE_READWRITE;
330    ptr->pos = 0;
331    ptr->lineno = 0;
332    return ptr->string = string;
333}
334
335/*
336 * call-seq:
337 *   strio.close  -> nil
338 *
339 * Closes strio.  The *strio* is unavailable for any further data
340 * operations; an +IOError+ is raised if such an attempt is made.
341 */
342static VALUE
343strio_close(VALUE self)
344{
345    StringIO(self);
346    if (CLOSED(self)) {
347	rb_raise(rb_eIOError, "closed stream");
348    }
349    RBASIC(self)->flags &= ~STRIO_READWRITE;
350    return Qnil;
351}
352
353/*
354 * call-seq:
355 *   strio.close_read    -> nil
356 *
357 * Closes the read end of a StringIO.  Will raise an +IOError+ if the
358 * *strio* is not readable.
359 */
360static VALUE
361strio_close_read(VALUE self)
362{
363    StringIO(self);
364    if (!READABLE(self)) {
365	rb_raise(rb_eIOError, "closing non-duplex IO for reading");
366    }
367    RBASIC(self)->flags &= ~STRIO_READABLE;
368    return Qnil;
369}
370
371/*
372 * call-seq:
373 *   strio.close_write    -> nil
374 *
375 * Closes the write end of a StringIO.  Will raise an  +IOError+ if the
376 * *strio* is not writeable.
377 */
378static VALUE
379strio_close_write(VALUE self)
380{
381    StringIO(self);
382    if (!WRITABLE(self)) {
383	rb_raise(rb_eIOError, "closing non-duplex IO for writing");
384    }
385    RBASIC(self)->flags &= ~STRIO_WRITABLE;
386    return Qnil;
387}
388
389/*
390 * call-seq:
391 *   strio.closed?    -> true or false
392 *
393 * Returns +true+ if *strio* is completely closed, +false+ otherwise.
394 */
395static VALUE
396strio_closed(VALUE self)
397{
398    StringIO(self);
399    if (!CLOSED(self)) return Qfalse;
400    return Qtrue;
401}
402
403/*
404 * call-seq:
405 *   strio.closed_read?    -> true or false
406 *
407 * Returns +true+ if *strio* is not readable, +false+ otherwise.
408 */
409static VALUE
410strio_closed_read(VALUE self)
411{
412    StringIO(self);
413    if (READABLE(self)) return Qfalse;
414    return Qtrue;
415}
416
417/*
418 * call-seq:
419 *   strio.closed_write?    -> true or false
420 *
421 * Returns +true+ if *strio* is not writable, +false+ otherwise.
422 */
423static VALUE
424strio_closed_write(VALUE self)
425{
426    StringIO(self);
427    if (WRITABLE(self)) return Qfalse;
428    return Qtrue;
429}
430
431/*
432 * call-seq:
433 *   strio.eof     -> true or false
434 *   strio.eof?    -> true or false
435 *
436 * Returns true if *strio* is at end of file. The stringio must be
437 * opened for reading or an +IOError+ will be raised.
438 */
439static VALUE
440strio_eof(VALUE self)
441{
442    struct StringIO *ptr = readable(self);
443    if (ptr->pos < RSTRING_LEN(ptr->string)) return Qfalse;
444    return Qtrue;
445}
446
447/* :nodoc: */
448static VALUE
449strio_copy(VALUE copy, VALUE orig)
450{
451    struct StringIO *ptr;
452
453    orig = rb_convert_type(orig, T_DATA, "StringIO", "to_strio");
454    if (copy == orig) return copy;
455    ptr = StringIO(orig);
456    if (check_strio(copy)) {
457	strio_free(DATA_PTR(copy));
458    }
459    DATA_PTR(copy) = ptr;
460    OBJ_INFECT(copy, orig);
461    RBASIC(copy)->flags &= ~STRIO_READWRITE;
462    RBASIC(copy)->flags |= RBASIC(orig)->flags & STRIO_READWRITE;
463    ++ptr->count;
464    return copy;
465}
466
467/*
468 * call-seq:
469 *   strio.lineno    -> integer
470 *
471 * Returns the current line number in *strio*. The stringio must be
472 * opened for reading. +lineno+ counts the number of times  +gets+ is
473 * called, rather than the number of newlines  encountered. The two
474 * values will differ if +gets+ is  called with a separator other than
475 * newline.  See also the  <code>$.</code> variable.
476 */
477static VALUE
478strio_get_lineno(VALUE self)
479{
480    return LONG2NUM(StringIO(self)->lineno);
481}
482
483/*
484 * call-seq:
485 *   strio.lineno = integer    -> integer
486 *
487 * Manually sets the current line number to the given value.
488 * <code>$.</code> is updated only on the next read.
489 */
490static VALUE
491strio_set_lineno(VALUE self, VALUE lineno)
492{
493    StringIO(self)->lineno = NUM2LONG(lineno);
494    return lineno;
495}
496
497/* call-seq: strio.binmode -> true */
498#define strio_binmode strio_self
499
500/* call-seq: strio.fcntl */
501#define strio_fcntl strio_unimpl
502
503/* call-seq: strio.flush -> strio */
504#define strio_flush strio_self
505
506/* call-seq: strio.fsync -> 0 */
507#define strio_fsync strio_0
508
509/*
510 * call-seq:
511 *   strio.reopen(other_StrIO)     -> strio
512 *   strio.reopen(string, mode)    -> strio
513 *
514 * Reinitializes *strio* with the given <i>other_StrIO</i> or _string_
515 * and _mode_ (see StringIO#new).
516 */
517static VALUE
518strio_reopen(int argc, VALUE *argv, VALUE self)
519{
520    rb_io_taint_check(self);
521    if (argc == 1 && !RB_TYPE_P(*argv, T_STRING)) {
522	return strio_copy(self, *argv);
523    }
524    strio_init(argc, argv, StringIO(self), self);
525    return self;
526}
527
528/*
529 * call-seq:
530 *   strio.pos     -> integer
531 *   strio.tell    -> integer
532 *
533 * Returns the current offset (in bytes) of *strio*.
534 */
535static VALUE
536strio_get_pos(VALUE self)
537{
538    return LONG2NUM(StringIO(self)->pos);
539}
540
541/*
542 * call-seq:
543 *   strio.pos = integer    -> integer
544 *
545 * Seeks to the given position (in bytes) in *strio*.
546 */
547static VALUE
548strio_set_pos(VALUE self, VALUE pos)
549{
550    struct StringIO *ptr = StringIO(self);
551    long p = NUM2LONG(pos);
552    if (p < 0) {
553	error_inval(0);
554    }
555    ptr->pos = p;
556    return pos;
557}
558
559/*
560 * call-seq:
561 *   strio.rewind    -> 0
562 *
563 * Positions *strio* to the beginning of input, resetting
564 * +lineno+ to zero.
565 */
566static VALUE
567strio_rewind(VALUE self)
568{
569    struct StringIO *ptr = StringIO(self);
570    ptr->pos = 0;
571    ptr->lineno = 0;
572    return INT2FIX(0);
573}
574
575/*
576 * call-seq:
577 *   strio.seek(amount, whence=SEEK_SET) -> 0
578 *
579 * Seeks to a given offset _amount_ in the stream according to
580 * the value of _whence_ (see IO#seek).
581 */
582static VALUE
583strio_seek(int argc, VALUE *argv, VALUE self)
584{
585    VALUE whence;
586    struct StringIO *ptr = StringIO(self);
587    long offset;
588
589    rb_scan_args(argc, argv, "11", NULL, &whence);
590    offset = NUM2LONG(argv[0]);
591    if (CLOSED(self)) {
592	rb_raise(rb_eIOError, "closed stream");
593    }
594    switch (NIL_P(whence) ? 0 : NUM2LONG(whence)) {
595      case 0:
596	break;
597      case 1:
598	offset += ptr->pos;
599	break;
600      case 2:
601	offset += RSTRING_LEN(ptr->string);
602	break;
603      default:
604	error_inval("invalid whence");
605    }
606    if (offset < 0) {
607	error_inval(0);
608    }
609    ptr->pos = offset;
610    return INT2FIX(0);
611}
612
613/*
614 * call-seq:
615 *   strio.sync    -> true
616 *
617 * Returns +true+ always.
618 */
619static VALUE
620strio_get_sync(VALUE self)
621{
622    StringIO(self);
623    return Qtrue;
624}
625
626/* call-seq: strio.sync = boolean -> boolean */
627#define strio_set_sync strio_first
628
629#define strio_tell strio_get_pos
630
631/*
632 * call-seq:
633 *   strio.each_byte {|byte| block }  -> strio
634 *   strio.each_byte                  -> anEnumerator
635 *
636 * See IO#each_byte.
637 */
638static VALUE
639strio_each_byte(VALUE self)
640{
641    struct StringIO *ptr = readable(self);
642
643    RETURN_ENUMERATOR(self, 0, 0);
644
645    while (ptr->pos < RSTRING_LEN(ptr->string)) {
646	char c = RSTRING_PTR(ptr->string)[ptr->pos++];
647	rb_yield(CHR2FIX(c));
648    }
649    return self;
650}
651
652/*
653 *  This is a deprecated alias for <code>each_byte</code>.
654 */
655static VALUE
656strio_bytes(VALUE self)
657{
658    rb_warn("StringIO#bytes is deprecated; use #each_byte instead");
659    if (!rb_block_given_p())
660	return rb_enumeratorize(self, ID2SYM(rb_intern("each_byte")), 0, 0);
661    return strio_each_byte(self);
662}
663
664/*
665 * call-seq:
666 *   strio.getc   -> string or nil
667 *
668 * See IO#getc.
669 */
670static VALUE
671strio_getc(VALUE self)
672{
673    struct StringIO *ptr = readable(self);
674    rb_encoding *enc = rb_enc_get(ptr->string);
675    int len;
676    char *p;
677
678    if (ptr->pos >= RSTRING_LEN(ptr->string)) {
679	return Qnil;
680    }
681    p = RSTRING_PTR(ptr->string)+ptr->pos;
682    len = rb_enc_mbclen(p, RSTRING_END(ptr->string), enc);
683    ptr->pos += len;
684    return rb_enc_str_new(p, len, rb_enc_get(ptr->string));
685}
686
687/*
688 * call-seq:
689 *   strio.getbyte   -> fixnum or nil
690 *
691 * See IO#getbyte.
692 */
693static VALUE
694strio_getbyte(VALUE self)
695{
696    struct StringIO *ptr = readable(self);
697    int c;
698    if (ptr->pos >= RSTRING_LEN(ptr->string)) {
699	return Qnil;
700    }
701    c = RSTRING_PTR(ptr->string)[ptr->pos++];
702    return CHR2FIX(c);
703}
704
705static void
706strio_extend(struct StringIO *ptr, long pos, long len)
707{
708    long olen;
709
710    check_modifiable(ptr);
711    olen = RSTRING_LEN(ptr->string);
712    if (pos + len > olen) {
713	rb_str_resize(ptr->string, pos + len);
714	if (pos > olen)
715	    MEMZERO(RSTRING_PTR(ptr->string) + olen, char, pos - olen);
716    }
717    else {
718	rb_str_modify(ptr->string);
719    }
720}
721
722/*
723 * call-seq:
724 *   strio.ungetc(string)   -> nil
725 *
726 * Pushes back one character (passed as a parameter) onto *strio*
727 * such that a subsequent buffered read will return it.  There is no
728 * limitation for multiple pushbacks including pushing back behind the
729 * beginning of the buffer string.
730 */
731static VALUE
732strio_ungetc(VALUE self, VALUE c)
733{
734    struct StringIO *ptr = readable(self);
735    long lpos, clen;
736    char *p, *pend;
737    rb_encoding *enc, *enc2;
738
739    if (NIL_P(c)) return Qnil;
740    check_modifiable(ptr);
741    if (FIXNUM_P(c)) {
742	int cc = FIX2INT(c);
743	char buf[16];
744
745	enc = rb_enc_get(ptr->string);
746	rb_enc_mbcput(cc, buf, enc);
747	c = rb_enc_str_new(buf, rb_enc_codelen(cc, enc), enc);
748    }
749    else {
750	SafeStringValue(c);
751	enc = rb_enc_get(ptr->string);
752	enc2 = rb_enc_get(c);
753	if (enc != enc2 && enc != rb_ascii8bit_encoding()) {
754	    c = rb_str_conv_enc(c, enc2, enc);
755	}
756    }
757    if (RSTRING_LEN(ptr->string) < ptr->pos) {
758	long len = RSTRING_LEN(ptr->string);
759	rb_str_resize(ptr->string, ptr->pos - 1);
760	memset(RSTRING_PTR(ptr->string) + len, 0, ptr->pos - len - 1);
761	rb_str_concat(ptr->string, c);
762	ptr->pos--;
763    }
764    else {
765	/* get logical position */
766	lpos = 0; p = RSTRING_PTR(ptr->string); pend = p + ptr->pos;
767	for (;;) {
768	    clen = rb_enc_mbclen(p, pend, enc);
769	    if (p+clen >= pend) break;
770	    p += clen;
771	    lpos++;
772	}
773	clen = p - RSTRING_PTR(ptr->string);
774	rb_str_update(ptr->string, lpos, ptr->pos ? 1 : 0, c);
775	ptr->pos = clen;
776    }
777
778    return Qnil;
779}
780
781/*
782 * call-seq:
783 *   strio.ungetbyte(fixnum)   -> nil
784 *
785 * See IO#ungetbyte
786 */
787static VALUE
788strio_ungetbyte(VALUE self, VALUE c)
789{
790    struct StringIO *ptr = readable(self);
791    char buf[1], *cp = buf;
792    long pos = ptr->pos, cl = 1;
793    VALUE str = ptr->string;
794
795    if (NIL_P(c)) return Qnil;
796    if (FIXNUM_P(c)) {
797	buf[0] = (char)FIX2INT(c);
798    }
799    else {
800	SafeStringValue(c);
801	cp = RSTRING_PTR(c);
802	cl = RSTRING_LEN(c);
803	if (cl == 0) return Qnil;
804    }
805    check_modifiable(ptr);
806    rb_str_modify(str);
807    if (cl > pos) {
808	char *s;
809	long rest = RSTRING_LEN(str) - pos;
810	rb_str_resize(str, rest + cl);
811	s = RSTRING_PTR(str);
812	memmove(s + cl, s + pos, rest);
813	pos = 0;
814    }
815    else {
816	pos -= cl;
817    }
818    memcpy(RSTRING_PTR(str) + pos, cp, cl);
819    ptr->pos = pos;
820    RB_GC_GUARD(c);
821    return Qnil;
822}
823
824/*
825 * call-seq:
826 *   strio.readchar   -> string
827 *
828 * See IO#readchar.
829 */
830static VALUE
831strio_readchar(VALUE self)
832{
833    VALUE c = rb_funcall2(self, rb_intern("getc"), 0, 0);
834    if (NIL_P(c)) rb_eof_error();
835    return c;
836}
837
838/*
839 * call-seq:
840 *   strio.readbyte   -> fixnum
841 *
842 * See IO#readbyte.
843 */
844static VALUE
845strio_readbyte(VALUE self)
846{
847    VALUE c = rb_funcall2(self, rb_intern("getbyte"), 0, 0);
848    if (NIL_P(c)) rb_eof_error();
849    return c;
850}
851
852/*
853 * call-seq:
854 *   strio.each_char {|char| block }  -> strio
855 *   strio.each_char                  -> anEnumerator
856 *
857 * See IO#each_char.
858 */
859static VALUE
860strio_each_char(VALUE self)
861{
862    VALUE c;
863
864    RETURN_ENUMERATOR(self, 0, 0);
865
866    while (!NIL_P(c = strio_getc(self))) {
867	rb_yield(c);
868    }
869    return self;
870}
871
872/*
873 *  This is a deprecated alias for <code>each_char</code>.
874 */
875static VALUE
876strio_chars(VALUE self)
877{
878    rb_warn("StringIO#chars is deprecated; use #each_char instead");
879    if (!rb_block_given_p())
880	return rb_enumeratorize(self, ID2SYM(rb_intern("each_char")), 0, 0);
881    return strio_each_char(self);
882}
883
884/*
885 * call-seq:
886 *   strio.each_codepoint {|c| block }  -> strio
887 *   strio.each_codepoint               -> anEnumerator
888 *
889 * See IO#each_codepoint.
890 */
891static VALUE
892strio_each_codepoint(VALUE self)
893{
894    struct StringIO *ptr;
895    rb_encoding *enc;
896    unsigned int c;
897    int n;
898
899    RETURN_ENUMERATOR(self, 0, 0);
900
901    ptr = readable(self);
902    enc = rb_enc_get(ptr->string);
903    for (;;) {
904	if (ptr->pos >= RSTRING_LEN(ptr->string)) {
905	    return self;
906	}
907
908	c = rb_enc_codepoint_len(RSTRING_PTR(ptr->string)+ptr->pos,
909				 RSTRING_END(ptr->string), &n, enc);
910	rb_yield(UINT2NUM(c));
911	ptr->pos += n;
912    }
913    return self;
914}
915
916/*
917 *  This is a deprecated alias for <code>each_codepoint</code>.
918 */
919static VALUE
920strio_codepoints(VALUE self)
921{
922    rb_warn("StringIO#codepoints is deprecated; use #each_codepoint instead");
923    if (!rb_block_given_p())
924	return rb_enumeratorize(self, ID2SYM(rb_intern("each_codepoint")), 0, 0);
925    return strio_each_codepoint(self);
926}
927
928/* Boyer-Moore search: copied from regex.c */
929static void
930bm_init_skip(long *skip, const char *pat, long m)
931{
932    int c;
933
934    for (c = 0; c < (1 << CHAR_BIT); c++) {
935	skip[c] = m;
936    }
937    while (--m) {
938	skip[(unsigned char)*pat++] = m;
939    }
940}
941
942static long
943bm_search(const char *little, long llen, const char *big, long blen, const long *skip)
944{
945    long i, j, k;
946
947    i = llen - 1;
948    while (i < blen) {
949	k = i;
950	j = llen - 1;
951	while (j >= 0 && big[k] == little[j]) {
952	    k--;
953	    j--;
954	}
955	if (j < 0) return k + 1;
956	i += skip[(unsigned char)big[i]];
957    }
958    return -1;
959}
960
961static VALUE
962strio_getline(int argc, VALUE *argv, struct StringIO *ptr)
963{
964    const char *s, *e, *p;
965    long n, limit = 0;
966    VALUE str, lim;
967
968    rb_scan_args(argc, argv, "02", &str, &lim);
969    switch (argc) {
970      case 0:
971	str = rb_rs;
972	break;
973
974      case 1:
975	if (!NIL_P(str) && !RB_TYPE_P(str, T_STRING)) {
976	    VALUE tmp = rb_check_string_type(str);
977	    if (NIL_P(tmp)) {
978		limit = NUM2LONG(str);
979		if (limit == 0) return rb_str_new(0,0);
980		str = rb_rs;
981	    }
982	    else {
983		str = tmp;
984	    }
985	}
986	break;
987
988      case 2:
989	if (!NIL_P(str)) StringValue(str);
990	if (!NIL_P(lim)) limit = NUM2LONG(lim);
991	break;
992    }
993
994    if (ptr->pos >= (n = RSTRING_LEN(ptr->string))) {
995	return Qnil;
996    }
997    s = RSTRING_PTR(ptr->string);
998    e = s + RSTRING_LEN(ptr->string);
999    s += ptr->pos;
1000    if (limit > 0 && s + limit < e) {
1001	e = rb_enc_right_char_head(s, s + limit, e, rb_enc_get(ptr->string));
1002    }
1003    if (NIL_P(str)) {
1004	str = strio_substr(ptr, ptr->pos, e - s);
1005    }
1006    else if ((n = RSTRING_LEN(str)) == 0) {
1007	p = s;
1008	while (*p == '\n') {
1009	    if (++p == e) {
1010		return Qnil;
1011	    }
1012	}
1013	s = p;
1014	while ((p = memchr(p, '\n', e - p)) && (p != e)) {
1015	    if (*++p == '\n') {
1016		e = p + 1;
1017		break;
1018	    }
1019	}
1020	str = strio_substr(ptr, s - RSTRING_PTR(ptr->string), e - s);
1021    }
1022    else if (n == 1) {
1023	if ((p = memchr(s, RSTRING_PTR(str)[0], e - s)) != 0) {
1024	    e = p + 1;
1025	}
1026	str = strio_substr(ptr, ptr->pos, e - s);
1027    }
1028    else {
1029	if (n < e - s) {
1030	    if (e - s < 1024) {
1031		for (p = s; p + n <= e; ++p) {
1032		    if (MEMCMP(p, RSTRING_PTR(str), char, n) == 0) {
1033			e = p + n;
1034			break;
1035		    }
1036		}
1037	    }
1038	    else {
1039		long skip[1 << CHAR_BIT], pos;
1040		p = RSTRING_PTR(str);
1041		bm_init_skip(skip, p, n);
1042		if ((pos = bm_search(p, n, s, e - s, skip)) >= 0) {
1043		    e = s + pos + n;
1044		}
1045	    }
1046	}
1047	str = strio_substr(ptr, ptr->pos, e - s);
1048    }
1049    ptr->pos = e - RSTRING_PTR(ptr->string);
1050    ptr->lineno++;
1051    return str;
1052}
1053
1054/*
1055 * call-seq:
1056 *   strio.gets(sep=$/)     -> string or nil
1057 *   strio.gets(limit)      -> string or nil
1058 *   strio.gets(sep, limit) -> string or nil
1059 *
1060 * See IO#gets.
1061 */
1062static VALUE
1063strio_gets(int argc, VALUE *argv, VALUE self)
1064{
1065    VALUE str = strio_getline(argc, argv, readable(self));
1066
1067    rb_lastline_set(str);
1068    return str;
1069}
1070
1071/*
1072 * call-seq:
1073 *   strio.readline(sep=$/)     -> string
1074 *   strio.readline(limit)      -> string or nil
1075 *   strio.readline(sep, limit) -> string or nil
1076 *
1077 * See IO#readline.
1078 */
1079static VALUE
1080strio_readline(int argc, VALUE *argv, VALUE self)
1081{
1082    VALUE line = rb_funcall2(self, rb_intern("gets"), argc, argv);
1083    if (NIL_P(line)) rb_eof_error();
1084    return line;
1085}
1086
1087/*
1088 * call-seq:
1089 *   strio.each(sep=$/) {|line| block }         -> strio
1090 *   strio.each(limit) {|line| block }          -> strio
1091 *   strio.each(sep, limit) {|line| block }     -> strio
1092 *   strio.each(...)                            -> anEnumerator
1093 *
1094 *   strio.each_line(sep=$/) {|line| block }    -> strio
1095 *   strio.each_line(limit) {|line| block }     -> strio
1096 *   strio.each_line(sep,limit) {|line| block } -> strio
1097 *   strio.each_line(...)                       -> anEnumerator
1098 *
1099 * See IO#each.
1100 */
1101static VALUE
1102strio_each(int argc, VALUE *argv, VALUE self)
1103{
1104    VALUE line;
1105
1106    StringIO(self);
1107    RETURN_ENUMERATOR(self, argc, argv);
1108
1109    if (argc > 0 && !NIL_P(argv[argc-1]) && NIL_P(rb_check_string_type(argv[argc-1])) &&
1110	NUM2LONG(argv[argc-1]) == 0) {
1111	rb_raise(rb_eArgError, "invalid limit: 0 for each_line");
1112    }
1113
1114    while (!NIL_P(line = strio_getline(argc, argv, readable(self)))) {
1115	rb_yield(line);
1116    }
1117    return self;
1118}
1119
1120/*
1121 *  This is a deprecated alias for <code>each_line</code>.
1122 */
1123static VALUE
1124strio_lines(int argc, VALUE *argv, VALUE self)
1125{
1126    rb_warn("StringIO#lines is deprecated; use #each_line instead");
1127    if (!rb_block_given_p())
1128	return rb_enumeratorize(self, ID2SYM(rb_intern("each_line")), argc, argv);
1129    return strio_each(argc, argv, self);
1130}
1131
1132/*
1133 * call-seq:
1134 *   strio.readlines(sep=$/)    ->   array
1135 *   strio.readlines(limit)     ->   array
1136 *   strio.readlines(sep,limit) ->   array
1137 *
1138 * See IO#readlines.
1139 */
1140static VALUE
1141strio_readlines(int argc, VALUE *argv, VALUE self)
1142{
1143    VALUE ary, line;
1144
1145    StringIO(self);
1146    ary = rb_ary_new();
1147    if (argc > 0 && !NIL_P(argv[argc-1]) && NIL_P(rb_check_string_type(argv[argc-1])) &&
1148	NUM2LONG(argv[argc-1]) == 0) {
1149	rb_raise(rb_eArgError, "invalid limit: 0 for readlines");
1150    }
1151
1152    while (!NIL_P(line = strio_getline(argc, argv, readable(self)))) {
1153	rb_ary_push(ary, line);
1154    }
1155    return ary;
1156}
1157
1158/*
1159 * call-seq:
1160 *   strio.write(string)    -> integer
1161 *   strio.syswrite(string) -> integer
1162 *
1163 * Appends the given string to the underlying buffer string of *strio*.
1164 * The stream must be opened for writing.  If the argument is not a
1165 * string, it will be converted to a string using <code>to_s</code>.
1166 * Returns the number of bytes written.  See IO#write.
1167 */
1168static VALUE
1169strio_write(VALUE self, VALUE str)
1170{
1171    struct StringIO *ptr = writable(self);
1172    long len, olen;
1173    rb_encoding *enc, *enc2;
1174
1175    RB_GC_GUARD(str);
1176    if (!RB_TYPE_P(str, T_STRING))
1177	str = rb_obj_as_string(str);
1178    enc = rb_enc_get(ptr->string);
1179    enc2 = rb_enc_get(str);
1180    if (enc != enc2 && enc != rb_ascii8bit_encoding()) {
1181	str = rb_str_conv_enc(str, enc2, enc);
1182    }
1183    len = RSTRING_LEN(str);
1184    if (len == 0) return INT2FIX(0);
1185    check_modifiable(ptr);
1186    olen = RSTRING_LEN(ptr->string);
1187    if (ptr->flags & FMODE_APPEND) {
1188	ptr->pos = olen;
1189    }
1190    if (ptr->pos == olen) {
1191	rb_str_cat(ptr->string, RSTRING_PTR(str), len);
1192    }
1193    else {
1194	strio_extend(ptr, ptr->pos, len);
1195	memmove(RSTRING_PTR(ptr->string)+ptr->pos, RSTRING_PTR(str), len);
1196	OBJ_INFECT(ptr->string, str);
1197    }
1198    OBJ_INFECT(ptr->string, self);
1199    ptr->pos += len;
1200    return LONG2NUM(len);
1201}
1202
1203/*
1204 * call-seq:
1205 *   strio << obj     -> strio
1206 *
1207 * See IO#<<.
1208 */
1209#define strio_addstr rb_io_addstr
1210
1211/*
1212 * call-seq:
1213 *   strio.print()             -> nil
1214 *   strio.print(obj, ...)     -> nil
1215 *
1216 * See IO#print.
1217 */
1218#define strio_print rb_io_print
1219
1220/*
1221 * call-seq:
1222 *   strio.printf(format_string [, obj, ...] )   -> nil
1223 *
1224 * See IO#printf.
1225 */
1226#define strio_printf rb_io_printf
1227
1228/*
1229 * call-seq:
1230 *   strio.putc(obj)    -> obj
1231 *
1232 * See IO#putc.
1233 */
1234static VALUE
1235strio_putc(VALUE self, VALUE ch)
1236{
1237    struct StringIO *ptr = writable(self);
1238    int c = NUM2CHR(ch);
1239    long olen;
1240
1241    check_modifiable(ptr);
1242    olen = RSTRING_LEN(ptr->string);
1243    if (ptr->flags & FMODE_APPEND) {
1244	ptr->pos = olen;
1245    }
1246    strio_extend(ptr, ptr->pos, 1);
1247    RSTRING_PTR(ptr->string)[ptr->pos++] = c;
1248    OBJ_INFECT(ptr->string, self);
1249    return ch;
1250}
1251
1252/*
1253 * call-seq:
1254 *   strio.puts(obj, ...)    -> nil
1255 *
1256 * See IO#puts.
1257 */
1258#define strio_puts rb_io_puts
1259
1260/*
1261 * call-seq:
1262 *   strio.read([length [, outbuf]])    -> string, outbuf, or nil
1263 *
1264 * See IO#read.
1265 */
1266static VALUE
1267strio_read(int argc, VALUE *argv, VALUE self)
1268{
1269    struct StringIO *ptr = readable(self);
1270    VALUE str = Qnil;
1271    long len;
1272    int binary = 0;
1273
1274    switch (argc) {
1275      case 2:
1276	str = argv[1];
1277	if (!NIL_P(str)) {
1278	    StringValue(str);
1279	    rb_str_modify(str);
1280	}
1281      case 1:
1282	if (!NIL_P(argv[0])) {
1283	    len = NUM2LONG(argv[0]);
1284	    if (len < 0) {
1285		rb_raise(rb_eArgError, "negative length %ld given", len);
1286	    }
1287	    if (len > 0 && ptr->pos >= RSTRING_LEN(ptr->string)) {
1288		if (!NIL_P(str)) rb_str_resize(str, 0);
1289		return Qnil;
1290	    }
1291	    binary = 1;
1292	    break;
1293	}
1294	/* fall through */
1295      case 0:
1296	len = RSTRING_LEN(ptr->string);
1297	if (len <= ptr->pos) {
1298	    if (NIL_P(str)) {
1299		str = rb_str_new(0, 0);
1300	    }
1301	    else {
1302		rb_str_resize(str, 0);
1303	    }
1304	    return str;
1305	}
1306	else {
1307	    len -= ptr->pos;
1308	}
1309	break;
1310      default:
1311	rb_raise(rb_eArgError, "wrong number of arguments (%d for 0)", argc);
1312    }
1313    if (NIL_P(str)) {
1314	str = strio_substr(ptr, ptr->pos, len);
1315	if (binary) rb_enc_associate(str, rb_ascii8bit_encoding());
1316    }
1317    else {
1318	long rest = RSTRING_LEN(ptr->string) - ptr->pos;
1319	if (len > rest) len = rest;
1320	rb_str_resize(str, len);
1321	MEMCPY(RSTRING_PTR(str), RSTRING_PTR(ptr->string) + ptr->pos, char, len);
1322	if (binary)
1323	    rb_enc_associate(str, rb_ascii8bit_encoding());
1324	else
1325	    rb_enc_copy(str, ptr->string);
1326    }
1327    ptr->pos += RSTRING_LEN(str);
1328    return str;
1329}
1330
1331/*
1332 * call-seq:
1333 *   strio.sysread(integer[, outbuf])    -> string
1334 *
1335 * Similar to #read, but raises +EOFError+ at end of string instead of
1336 * returning +nil+, as well as IO#sysread does.
1337 */
1338static VALUE
1339strio_sysread(int argc, VALUE *argv, VALUE self)
1340{
1341    VALUE val = rb_funcall2(self, rb_intern("read"), argc, argv);
1342    if (NIL_P(val)) {
1343	rb_eof_error();
1344    }
1345    return val;
1346}
1347
1348#define strio_syswrite rb_io_write
1349
1350/*
1351 * call-seq:
1352 *   strio.isatty -> nil
1353 *   strio.tty? -> nil
1354 *
1355 */
1356#define strio_isatty strio_false
1357
1358/* call-seq: strio.pid -> nil */
1359#define strio_pid strio_nil
1360
1361/* call-seq: strio.fileno -> nil */
1362#define strio_fileno strio_nil
1363
1364/*
1365 * call-seq:
1366 *   strio.size   -> integer
1367 *
1368 * Returns the size of the buffer string.
1369 */
1370static VALUE
1371strio_size(VALUE self)
1372{
1373    VALUE string = StringIO(self)->string;
1374    if (NIL_P(string)) {
1375	rb_raise(rb_eIOError, "not opened");
1376    }
1377    return ULONG2NUM(RSTRING_LEN(string));
1378}
1379
1380/*
1381 * call-seq:
1382 *   strio.truncate(integer)    -> 0
1383 *
1384 * Truncates the buffer string to at most _integer_ bytes. The *strio*
1385 * must be opened for writing.
1386 */
1387static VALUE
1388strio_truncate(VALUE self, VALUE len)
1389{
1390    VALUE string = writable(self)->string;
1391    long l = NUM2LONG(len);
1392    long plen = RSTRING_LEN(string);
1393    if (l < 0) {
1394	error_inval("negative length");
1395    }
1396    rb_str_resize(string, l);
1397    if (plen < l) {
1398	MEMZERO(RSTRING_PTR(string) + plen, char, l - plen);
1399    }
1400    return len;
1401}
1402
1403/*
1404 *  call-seq:
1405 *     strio.external_encoding   => encoding
1406 *
1407 *  Returns the Encoding object that represents the encoding of the file.
1408 *  If strio is write mode and no encoding is specified, returns <code>nil</code>.
1409 */
1410
1411static VALUE
1412strio_external_encoding(VALUE self)
1413{
1414    return rb_enc_from_encoding(rb_enc_get(StringIO(self)->string));
1415}
1416
1417/*
1418 *  call-seq:
1419 *     strio.internal_encoding   => encoding
1420 *
1421 *  Returns the Encoding of the internal string if conversion is
1422 *  specified.  Otherwise returns nil.
1423 */
1424
1425static VALUE
1426strio_internal_encoding(VALUE self)
1427{
1428     return Qnil;
1429}
1430
1431/*
1432 *  call-seq:
1433 *     strio.set_encoding(ext_enc, [int_enc[, opt]])  => strio
1434 *
1435 *  Specify the encoding of the StringIO as <i>ext_enc</i>.
1436 *  Use the default external encoding if <i>ext_enc</i> is nil.
1437 *  2nd argument <i>int_enc</i> and optional hash <i>opt</i> argument
1438 *  are ignored; they are for API compatibility to IO.
1439 */
1440
1441static VALUE
1442strio_set_encoding(int argc, VALUE *argv, VALUE self)
1443{
1444    rb_encoding* enc;
1445    VALUE str = StringIO(self)->string;
1446    VALUE ext_enc, int_enc, opt;
1447
1448    argc = rb_scan_args(argc, argv, "11:", &ext_enc, &int_enc, &opt);
1449
1450    if (NIL_P(ext_enc)) {
1451	enc = rb_default_external_encoding();
1452    }
1453    else {
1454	enc = rb_to_encoding(ext_enc);
1455    }
1456    rb_enc_associate(str, enc);
1457    return self;
1458}
1459
1460/*
1461 * Pseudo I/O on String object.
1462 */
1463void
1464Init_stringio()
1465{
1466    VALUE StringIO = rb_define_class("StringIO", rb_cData);
1467
1468    rb_include_module(StringIO, rb_mEnumerable);
1469    rb_define_alloc_func(StringIO, strio_s_allocate);
1470    rb_define_singleton_method(StringIO, "open", strio_s_open, -1);
1471    rb_define_method(StringIO, "initialize", strio_initialize, -1);
1472    rb_define_method(StringIO, "initialize_copy", strio_copy, 1);
1473    rb_define_method(StringIO, "reopen", strio_reopen, -1);
1474
1475    rb_define_method(StringIO, "string", strio_get_string, 0);
1476    rb_define_method(StringIO, "string=", strio_set_string, 1);
1477    rb_define_method(StringIO, "lineno", strio_get_lineno, 0);
1478    rb_define_method(StringIO, "lineno=", strio_set_lineno, 1);
1479
1480    rb_define_method(StringIO, "binmode", strio_binmode, 0);
1481    rb_define_method(StringIO, "close", strio_close, 0);
1482    rb_define_method(StringIO, "close_read", strio_close_read, 0);
1483    rb_define_method(StringIO, "close_write", strio_close_write, 0);
1484    rb_define_method(StringIO, "closed?", strio_closed, 0);
1485    rb_define_method(StringIO, "closed_read?", strio_closed_read, 0);
1486    rb_define_method(StringIO, "closed_write?", strio_closed_write, 0);
1487    rb_define_method(StringIO, "eof", strio_eof, 0);
1488    rb_define_method(StringIO, "eof?", strio_eof, 0);
1489    rb_define_method(StringIO, "fcntl", strio_fcntl, -1);
1490    rb_define_method(StringIO, "flush", strio_flush, 0);
1491    rb_define_method(StringIO, "fsync", strio_fsync, 0);
1492    rb_define_method(StringIO, "pos", strio_get_pos, 0);
1493    rb_define_method(StringIO, "pos=", strio_set_pos, 1);
1494    rb_define_method(StringIO, "rewind", strio_rewind, 0);
1495    rb_define_method(StringIO, "seek", strio_seek, -1);
1496    rb_define_method(StringIO, "sync", strio_get_sync, 0);
1497    rb_define_method(StringIO, "sync=", strio_set_sync, 1);
1498    rb_define_method(StringIO, "tell", strio_tell, 0);
1499
1500    rb_define_method(StringIO, "each", strio_each, -1);
1501    rb_define_method(StringIO, "each_line", strio_each, -1);
1502    rb_define_method(StringIO, "lines", strio_lines, -1);
1503    rb_define_method(StringIO, "each_byte", strio_each_byte, 0);
1504    rb_define_method(StringIO, "bytes", strio_bytes, 0);
1505    rb_define_method(StringIO, "each_char", strio_each_char, 0);
1506    rb_define_method(StringIO, "chars", strio_chars, 0);
1507    rb_define_method(StringIO, "each_codepoint", strio_each_codepoint, 0);
1508    rb_define_method(StringIO, "codepoints", strio_codepoints, 0);
1509    rb_define_method(StringIO, "getc", strio_getc, 0);
1510    rb_define_method(StringIO, "ungetc", strio_ungetc, 1);
1511    rb_define_method(StringIO, "ungetbyte", strio_ungetbyte, 1);
1512    rb_define_method(StringIO, "getbyte", strio_getbyte, 0);
1513    rb_define_method(StringIO, "gets", strio_gets, -1);
1514    rb_define_method(StringIO, "readlines", strio_readlines, -1);
1515    rb_define_method(StringIO, "read", strio_read, -1);
1516
1517    rb_define_method(StringIO, "write", strio_write, 1);
1518    rb_define_method(StringIO, "putc", strio_putc, 1);
1519
1520    rb_define_method(StringIO, "isatty", strio_isatty, 0);
1521    rb_define_method(StringIO, "tty?", strio_isatty, 0);
1522    rb_define_method(StringIO, "pid", strio_pid, 0);
1523    rb_define_method(StringIO, "fileno", strio_fileno, 0);
1524    rb_define_method(StringIO, "size", strio_size, 0);
1525    rb_define_method(StringIO, "length", strio_size, 0);
1526    rb_define_method(StringIO, "truncate", strio_truncate, 1);
1527
1528    rb_define_method(StringIO, "external_encoding", strio_external_encoding, 0);
1529    rb_define_method(StringIO, "internal_encoding", strio_internal_encoding, 0);
1530    rb_define_method(StringIO, "set_encoding", strio_set_encoding, -1);
1531
1532    {
1533	VALUE mReadable = rb_define_module_under(rb_cIO, "readable");
1534	rb_define_method(mReadable, "readchar", strio_readchar, 0);
1535	rb_define_method(mReadable, "readbyte", strio_readbyte, 0);
1536	rb_define_method(mReadable, "readline", strio_readline, -1);
1537	rb_define_method(mReadable, "sysread", strio_sysread, -1);
1538	rb_define_method(mReadable, "readpartial", strio_sysread, -1);
1539	rb_define_method(mReadable, "read_nonblock", strio_sysread, -1);
1540	rb_include_module(StringIO, mReadable);
1541    }
1542    {
1543	VALUE mWritable = rb_define_module_under(rb_cIO, "writable");
1544	rb_define_method(mWritable, "<<", strio_addstr, 1);
1545	rb_define_method(mWritable, "print", strio_print, -1);
1546	rb_define_method(mWritable, "printf", strio_printf, -1);
1547	rb_define_method(mWritable, "puts", strio_puts, -1);
1548	rb_define_method(mWritable, "syswrite", strio_syswrite, 1);
1549	rb_define_method(mWritable, "write_nonblock", strio_syswrite, 1);
1550	rb_include_module(StringIO, mWritable);
1551    }
1552}
1553