Ruby 2.1.5p273(2014-11-13revision48405)

- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

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