Ruby 2.0.0p353(2013-11-22revision43784)

- 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: 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
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 };
82
83 #define check_strio(self) ((struct StringIO*)rb_check_typeddata((self), &strio_data_type))
84
85 static struct StringIO*
86 get_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
96 static VALUE
97 strio_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)
113 typedef 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
121 static struct StringIO*
122 readable(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
131 static struct StringIO*
132 writable(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
144 static void
145 check_modifiable(struct StringIO *ptr)
146 {
147 if (OBJ_FROZEN(ptr->string)) {
148 rb_raise(rb_eIOError, "not modifiable string");
149 }
150 }
151
152 static VALUE
153 strio_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 */
163 static VALUE
164 strio_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
176 static void
177 strio_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
218 static VALUE
219 strio_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 */
234 static VALUE
235 strio_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 */
245 static VALUE
246 strio_false(VALUE self)
247 {
248 StringIO(self);
249 return Qfalse;
250 }
251
252 /*
253 * Returns +nil+. Just for compatibility to IO.
254 */
255 static VALUE
256 strio_nil(VALUE self)
257 {
258 StringIO(self);
259 return Qnil;
260 }
261
262 /*
263 * Returns *strio* itself. Just for compatibility to IO.
264 */
265 static VALUE
266 strio_self(VALUE self)
267 {
268 StringIO(self);
269 return self;
270 }
271
272 /*
273 * Returns 0. Just for compatibility to IO.
274 */
275 static VALUE
276 strio_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 */
285 static VALUE
286 strio_first(VALUE self, VALUE arg)
287 {
288 StringIO(self);
289 return arg;
290 }
291
292 /*
293 * Raises NotImplementedError.
294 */
295 static VALUE
296 strio_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 */
309 static VALUE
310 strio_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 */
321 static VALUE
322 strio_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 */
342 static VALUE
343 strio_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 */
360 static VALUE
361 strio_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 */
378 static VALUE
379 strio_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 */
395 static VALUE
396 strio_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 */
409 static VALUE
410 strio_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 */
423 static VALUE
424 strio_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 */
439 static VALUE
440 strio_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: */
448 static VALUE
449 strio_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 */
477 static VALUE
478 strio_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 */
490 static VALUE
491 strio_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 */
517 static VALUE
518 strio_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 */
535 static VALUE
536 strio_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 */
547 static VALUE
548 strio_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 */
566 static VALUE
567 strio_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 */
582 static VALUE
583 strio_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 */
619 static VALUE
620 strio_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 */
638 static VALUE
639 strio_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 */
655 static VALUE
656 strio_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 */
670 static VALUE
671 strio_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 */
693 static VALUE
694 strio_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
705 static void
706 strio_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 */
731 static VALUE
732 strio_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 */
787 static VALUE
788 strio_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 */
830 static VALUE
831 strio_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 */
844 static VALUE
845 strio_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 */
859 static VALUE
860 strio_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 */
875 static VALUE
876 strio_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 */
891 static VALUE
892 strio_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 */
919 static VALUE
920 strio_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 */
929 static void
930 bm_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
942 static long
943 bm_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
961 static VALUE
962 strio_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 */
1062 static VALUE
1063 strio_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 */
1079 static VALUE
1080 strio_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 */
1101 static VALUE
1102 strio_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 */
1123 static VALUE
1124 strio_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 */
1140 static VALUE
1141 strio_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 */
1168 static VALUE
1169 strio_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 */
1234 static VALUE
1235 strio_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 */
1266 static VALUE
1267 strio_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 */
1338 static VALUE
1339 strio_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 */
1370 static VALUE
1371 strio_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 */
1387 static VALUE
1388 strio_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
1411 static VALUE
1412 strio_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
1425 static VALUE
1426 strio_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
1441 static VALUE
1442 strio_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 */
1463 void
1464 Init_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 }
strio_closed_read
static VALUE strio_closed_read(VALUE self)
Definition: stringio.c:410
check_modifiable
static void check_modifiable(struct StringIO *ptr)
Definition: stringio.c:145
strio_getbyte
static VALUE strio_getbyte(VALUE self)
Definition: stringio.c:694
RB_TYPE_P
#define RB_TYPE_P(obj, type)
StringIO
Definition: stringio.c:23
ALLOC
#define ALLOC(type)
tmp
volatile VALUE tmp
Definition: tcltklib.c:10209
rb_enc_codelen
int rb_enc_codelen(int c, rb_encoding *enc)
Definition: encoding.c:954
StringIO::pos
long pos
Definition: stringio.c:25
n
ssize_t n
Definition: bigdecimal.c:5655
ary
volatile VALUE ary
Definition: tcltklib.c:9713
pat
UChar * pat
Definition: regerror.c:390
strio_get_string
static VALUE strio_get_string(VALUE self)
Definition: stringio.c:310
rb_enc_copy
void rb_enc_copy(VALUE obj1, VALUE obj2)
Definition: encoding.c:856
FMODE_READWRITE
#define FMODE_READWRITE
Definition: io.h:105
enc2
gz enc2
Definition: zlib.c:2274
OBJ_INFECT
#define OBJ_INFECT(x, s)
rb_class_new_instance
VALUE rb_class_new_instance(int, VALUE *, VALUE)
Definition: object.c:1775
CLOSED
#define CLOSED(strio)
Definition: stringio.c:117
p
Win32OLEIDispatch * p
Definition: win32ole.c:786
RSTRING_END
#define RSTRING_END(str)
strio_print
#define strio_print
Definition: stringio.c:1218
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:1497
error_inval
#define error_inval(msg)
Definition: stringio.c:34
strio_closed
static VALUE strio_closed(VALUE self)
Definition: stringio.c:396
rb_secure
void rb_secure(int)
Definition: safe.c:79
i
ssize_t i
Definition: bigdecimal.c:5655
strio_set_sync
#define strio_set_sync
Definition: stringio.c:627
memmove
RUBY_EXTERN void * memmove(void *, const void *, size_t)
Definition: memmove.c:7
strio_free
static void strio_free(void *p)
Definition: stringio.c:58
rb_enc_right_char_head
#define rb_enc_right_char_head(s, p, e, enc)
STRIO_WRITABLE
#define STRIO_WRITABLE
Definition: stringio.c:111
FMODE_WRITABLE
#define FMODE_WRITABLE
Definition: io.h:104
rb_to_encoding
rb_encoding * rb_to_encoding(VALUE enc)
Definition: encoding.c:194
ruby.h
FMODE_READABLE
#define FMODE_READABLE
Definition: io.h:103
rb_enc_from_encoding
VALUE rb_enc_from_encoding(rb_encoding *encoding)
Definition: encoding.c:103
strio_write
static VALUE strio_write(VALUE self, VALUE str)
Definition: stringio.c:1169
rb_define_alloc_func
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
strio_codepoints
static VALUE strio_codepoints(VALUE self)
Definition: stringio.c:920
OBJ_TAINTED
#define OBJ_TAINTED(x)
UNREACHABLE
#define UNREACHABLE
Definition: ruby.h:40
enc
VALUE enc
Definition: tcltklib.c:10311
rb_ary_push
VALUE rb_ary_push(VALUE ary, VALUE item)
Definition: array.c:822
strio_readlines
static VALUE strio_readlines(int argc, VALUE *argv, VALUE self)
Definition: stringio.c:1141
strio_flags_check
char strio_flags_check[(STRIO_READABLE/FMODE_READABLE==STRIO_WRITABLE/FMODE_WRITABLE)*2-1]
Definition: stringio.c:113
RSTRING_PTR
#define RSTRING_PTR(str)
NIL_P
NIL_P(eventloop_thread)
Definition: tcltklib.c:4068
rb_lastline_set
void rb_lastline_set(VALUE)
Definition: vm.c:780
rb_enc_str_new
VALUE rb_enc_str_new(const char *, long, rb_encoding *)
Definition: string.c:439
strio_readline
static VALUE strio_readline(int argc, VALUE *argv, VALUE self)
Definition: stringio.c:1080
xfree
#define xfree
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:933
rb_raise
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:1780
StringIO::flags
int flags
Definition: stringio.c:27
MEMCMP
#define MEMCMP(p1, p2, type, n)
Qtrue
return Qtrue
Definition: tcltklib.c:9610
rb_enc_associate
VALUE rb_enc_associate(VALUE obj, rb_encoding *enc)
Definition: encoding.c:766
strio_copy
static VALUE strio_copy(VALUE copy, VALUE orig)
Definition: stringio.c:449
RETURN_ENUMERATOR
#define RETURN_ENUMERATOR(obj, argc, argv)
rb_io_taint_check
VALUE rb_io_taint_check(VALUE)
Definition: io.c:587
strio_close_write
static VALUE strio_close_write(VALUE self)
Definition: stringio.c:379
SafeStringValue
#define SafeStringValue(v)
rb_eIOError
RUBY_EXTERN VALUE rb_eIOError
Definition: ripper.y:1476
rb_enc_mbclen
int rb_enc_mbclen(const char *p, const char *e, rb_encoding *enc)
Definition: encoding.c:886
strio_getline
static VALUE strio_getline(int argc, VALUE *argv, struct StringIO *ptr)
Definition: stringio.c:962
FMODE_APPEND
#define FMODE_APPEND
Definition: io.h:110
rb_include_module
void rb_include_module(VALUE klass, VALUE module)
Definition: class.c:695
strio_set_encoding
static VALUE strio_set_encoding(int argc, VALUE *argv, VALUE self)
Definition: stringio.c:1442
strio_truncate
static VALUE strio_truncate(VALUE self, VALUE len)
Definition: stringio.c:1388
READABLE
#define READABLE(strio)
Definition: stringio.c:118
strio_pid
#define strio_pid
Definition: stringio.c:1359
strio_readbyte
static VALUE strio_readbyte(VALUE self)
Definition: stringio.c:845
ID2SYM
#define ID2SYM(x)
LONG2NUM
#define LONG2NUM(x)
strio_isatty
#define strio_isatty
Definition: stringio.c:1356
io.h
rb_str_concat
VALUE rb_str_concat(VALUE, VALUE)
Definition: string.c:2162
StringIO
#define StringIO(obj)
Definition: stringio.c:108
strio_fsync
#define strio_fsync
Definition: stringio.c:507
lineno
gz lineno
Definition: zlib.c:2270
strio_closed_write
static VALUE strio_closed_write(VALUE self)
Definition: stringio.c:424
strio_flush
#define strio_flush
Definition: stringio.c:504
strio_get_pos
static VALUE strio_get_pos(VALUE self)
Definition: stringio.c:536
MEMZERO
#define MEMZERO(p, type, n)
rb_enumeratorize
VALUE rb_enumeratorize(VALUE obj, VALUE meth, int argc, VALUE *argv)
Definition: enumerator.c:398
WRITABLE
#define WRITABLE(strio)
Definition: stringio.c:119
strio_puts
#define strio_puts
Definition: stringio.c:1258
rb_str_update
void rb_str_update(VALUE, long, long, VALUE)
Definition: string.c:3451
strio_close_read
static VALUE strio_close_read(VALUE self)
Definition: stringio.c:361
rb_default_external_encoding
rb_encoding * rb_default_external_encoding(void)
Definition: encoding.c:1288
memset
memset(y->frac+ix+1, 0,(y->Prec-(ix+1))*sizeof(BDIGIT))
m
BDIGIT m
Definition: bigdecimal.c:5085
strio_gets
static VALUE strio_gets(int argc, VALUE *argv, VALUE self)
Definition: stringio.c:1063
Qfalse
return Qfalse
Definition: tcltklib.c:6779
FIXNUM_P
#define FIXNUM_P(f)
strio_s_allocate
static VALUE strio_s_allocate(VALUE klass)
Definition: stringio.c:153
rb_block_given_p
int rb_block_given_p(void)
Definition: eval.c:672
rb_io_modenum_flags
#define rb_io_modenum_flags(oflags)
Definition: io.h:193
Qnil
#define Qnil
Definition: tcltklib.c:1896
strio_close
static VALUE strio_close(VALUE self)
Definition: stringio.c:343
val
#define val
Definition: tcltklib.c:1949
StringIO::string
VALUE string
Definition: stringio.c:24
strio_tell
#define strio_tell
Definition: stringio.c:629
str
static VALUE char * str
Definition: tcltklib.c:3547
writable
static struct StringIO * writable(VALUE strio)
Definition: stringio.c:132
rb_ary_new
VALUE rb_ary_new(void)
Definition: array.c:424
StringValueCStr
#define StringValueCStr(v)
strio_internal_encoding
static VALUE strio_internal_encoding(VALUE self)
Definition: stringio.c:1426
flags
int flags
Definition: tcltklib.c:3023
rb_gc_mark
void rb_gc_mark(VALUE)
Definition: gc.c:2598
rb_define_class
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
Definition: class.c:499
obj
static VALUE VALUE obj
Definition: tcltklib.c:3158
RSTRING_LEN
#define RSTRING_LEN(str)
strio_get_lineno
static VALUE strio_get_lineno(VALUE self)
Definition: stringio.c:478
FIX2INT
#define FIX2INT(x)
INT2FIX
#define INT2FIX(i)
strio_0
static VALUE strio_0(VALUE self)
Definition: stringio.c:276
strio_binmode
#define strio_binmode
Definition: stringio.c:498
strio_set_lineno
static VALUE strio_set_lineno(VALUE self, VALUE lineno)
Definition: stringio.c:491
T_STRING
#define T_STRING
strio_self
static VALUE strio_self(VALUE self)
Definition: stringio.c:266
strio_mark
static void strio_mark(void *p)
Definition: stringio.c:49
rb_call_super
VALUE rb_call_super(int, const VALUE *)
Definition: vm_eval.c:273
TypedData_Wrap_Struct
#define TypedData_Wrap_Struct(klass, data_type, sval)
STRIO_READWRITE
#define STRIO_READWRITE
Definition: stringio.c:112
buf
unsigned char buf[MIME_BUF_SIZE]
Definition: nkf.c:4308
strio_read
static VALUE strio_read(int argc, VALUE *argv, VALUE self)
Definition: stringio.c:1267
strio_each
static VALUE strio_each(int argc, VALUE *argv, VALUE self)
Definition: stringio.c:1102
encoding.h
CHR2FIX
#define CHR2FIX(x)
strio_getc
static VALUE strio_getc(VALUE self)
Definition: stringio.c:671
strio_readchar
static VALUE strio_readchar(VALUE self)
Definition: stringio.c:831
rb_obj_as_string
VALUE rb_obj_as_string(VALUE)
Definition: string.c:895
argv
VALUE * argv
Definition: tcltklib.c:1971
rb_yield
VALUE rb_yield(VALUE)
Definition: vm_eval.c:934
rb_str_resize
VALUE rb_str_resize(VALUE, long)
Definition: string.c:1853
strio_each_char
static VALUE strio_each_char(VALUE self)
Definition: stringio.c:860
memcpy
memcpy(buf+1, str, len)
strio_init
static void strio_init(int, VALUE *, struct StringIO *, VALUE)
Definition: stringio.c:177
errno
int errno
rb_mEnumerable
VALUE rb_mEnumerable
Definition: enum.c:20
StringValue
#define StringValue(v)
rb_enc_mbcput
#define rb_enc_mbcput(c, buf, enc)
s
register char * s
Definition: os2.c:56
check_strio
#define check_strio(self)
Definition: stringio.c:83
mode
VALUE mode
Definition: tcltklib.c:1664
strio_addstr
#define strio_addstr
Definition: stringio.c:1209
rb_scan_args
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1570
strio_each_codepoint
static VALUE strio_each_codepoint(VALUE self)
Definition: stringio.c:892
strio_first
static VALUE strio_first(VALUE self, VALUE arg)
Definition: stringio.c:286
strio_unimpl
static VALUE strio_unimpl(int argc, VALUE *argv, VALUE self)
Definition: stringio.c:296
OBJ_FROZEN
#define OBJ_FROZEN(x)
RB_GC_GUARD
#define RB_GC_GUARD(v)
argc
int argc
Definition: tcltklib.c:1970
strio_putc
static VALUE strio_putc(VALUE self, VALUE ch)
Definition: stringio.c:1235
Init_stringio
void Init_stringio()
Definition: stringio.c:1464
rb_ensure
VALUE rb_ensure(VALUE(*b_proc)(ANYARGS), VALUE data1, VALUE(*e_proc)(ANYARGS), VALUE data2)
Definition: eval.c:804
rb_io_mode_flags
#define rb_io_mode_flags(modestr)
Definition: io.h:192
rb_sys_fail
void rb_sys_fail(const char *mesg)
Definition: error.c:1899
strio_set_pos
static VALUE strio_set_pos(VALUE self, VALUE pos)
Definition: stringio.c:548
ptr
return ptr
Definition: tcltklib.c:784
c
VpDivd * c
Definition: bigdecimal.c:1205
CHAR_BIT
#define CHAR_BIT
Definition: ruby.h:208
rb_cIO
RUBY_EXTERN VALUE rb_cIO
Definition: ripper.y:1442
strio_seek
static VALUE strio_seek(int argc, VALUE *argv, VALUE self)
Definition: stringio.c:583
strio_bytes
static VALUE strio_bytes(VALUE self)
Definition: stringio.c:656
MEMCPY
#define MEMCPY(p1, p2, type, n)
rb_define_module_under
VALUE rb_define_module_under(VALUE outer, const char *name)
Definition: class.c:637
strio_memsize
static size_t strio_memsize(const void *p)
Definition: stringio.c:67
strio_sysread
static VALUE strio_sysread(int argc, VALUE *argv, VALUE self)
Definition: stringio.c:1339
arg
arg
Definition: ripper.y:1315
rb_str_modify
void rb_str_modify(VALUE)
Definition: string.c:1369
strio_chars
static VALUE strio_chars(VALUE self)
Definition: stringio.c:876
rb_str_cat
VALUE rb_str_cat(VALUE, const char *, long)
Definition: string.c:1963
strio_rewind
static VALUE strio_rewind(VALUE self)
Definition: stringio.c:567
StringIO::count
int count
Definition: stringio.c:28
rb_enc_get
rb_encoding * rb_enc_get(VALUE obj)
Definition: encoding.c:772
rb_str_conv_enc
VALUE rb_str_conv_enc(VALUE str, rb_encoding *from, rb_encoding *to)
Definition: string.c:563
NUM2LONG
#define NUM2LONG(x)
strio_extend
static void strio_extend(struct StringIO *ptr, long pos, long len)
Definition: stringio.c:706
strio_initialize
static VALUE strio_initialize(int argc, VALUE *argv, VALUE self)
Definition: stringio.c:164
strio_reopen
static VALUE strio_reopen(int argc, VALUE *argv, VALUE self)
Definition: stringio.c:518
rb_data_type_struct
Definition: ripper.y:960
DATA_PTR
DATA_PTR(self)
bm_init_skip
static void bm_init_skip(long *skip, const char *pat, long m)
Definition: stringio.c:930
strio_s_open
static VALUE strio_s_open(int argc, VALUE *argv, VALUE klass)
Definition: stringio.c:235
RBASIC
#define RBASIC(obj)
klass
klass
Definition: tcltklib.c:3504
UINT2NUM
#define UINT2NUM(x)
strio_ungetbyte
static VALUE strio_ungetbyte(VALUE self, VALUE c)
Definition: stringio.c:788
strio_printf
#define strio_printf
Definition: stringio.c:1226
rb_rs
RUBY_EXTERN VALUE rb_rs
Definition: ripper.y:489
get_strio
static struct StringIO * get_strio(VALUE self)
Definition: stringio.c:86
rb_notimplement
void rb_notimplement(void)
Definition: error.c:1826
strio_ungetc
static VALUE strio_ungetc(VALUE self, VALUE c)
Definition: stringio.c:732
strio_each_byte
static VALUE strio_each_byte(VALUE self)
Definition: stringio.c:639
rb_str_new
VALUE rb_str_new(const char *, long)
Definition: string.c:425
strio_size
static VALUE strio_size(VALUE self)
Definition: stringio.c:1371
strio_false
static VALUE strio_false(VALUE self)
Definition: stringio.c:246
readable
static struct StringIO * readable(VALUE strio)
Definition: stringio.c:122
strio_external_encoding
static VALUE strio_external_encoding(VALUE self)
Definition: stringio.c:1412
strio_finalize
static VALUE strio_finalize(VALUE self)
Definition: stringio.c:219
bm_search
static long bm_search(const char *little, long llen, const char *big, long blen, const long *skip)
Definition: stringio.c:943
e
BDIGIT e
Definition: bigdecimal.c:5085
rb_funcall2
VALUE rb_funcall2(VALUE, ID, int, const VALUE *)
Calls a method.
Definition: vm_eval.c:805
NUM2CHR
#define NUM2CHR(x)
VALUE
unsigned long VALUE
Definition: ripper.y:104
rb_ascii8bit_encoding
rb_encoding * rb_ascii8bit_encoding(void)
Definition: encoding.c:1153
strio_fileno
#define strio_fileno
Definition: stringio.c:1362
strio_set_string
static VALUE strio_set_string(VALUE self, VALUE string)
Definition: stringio.c:322
rb_intern
#define rb_intern(str)
strio_get_sync
static VALUE strio_get_sync(VALUE self)
Definition: stringio.c:620
rb_cData
RUBY_EXTERN VALUE rb_cData
Definition: ripper.y:1433
NULL
#define NULL
Definition: _sdbm.c:103
strio_eof
static VALUE strio_eof(VALUE self)
Definition: stringio.c:440
T_DATA
#define T_DATA
rb_check_string_type
VALUE rb_check_string_type(VALUE)
Definition: string.c:1508
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:1344
ULONG2NUM
#define ULONG2NUM(x)
strio_lines
static VALUE strio_lines(int argc, VALUE *argv, VALUE self)
Definition: stringio.c:1124
strio_nil
static VALUE strio_nil(VALUE self)
Definition: stringio.c:256
rb_warn
void rb_warn(const char *fmt,...)
Definition: error.c:216
strio_syswrite
#define strio_syswrite
Definition: stringio.c:1348
rb_eArgError
VALUE rb_eArgError
Definition: error.c:512
rb_convert_type
VALUE rb_convert_type(VALUE, int, const char *, const char *)
Definition: object.c:2368
STRIO_READABLE
#define STRIO_READABLE
Definition: stringio.c:110
cp
STATIC void unsigned char * cp
Definition: crypt.c:307
strio_fcntl
#define strio_fcntl
Definition: stringio.c:501
StringIO::lineno
long lineno
Definition: stringio.c:26
OnigEncodingTypeST
Definition: ripper.y:161
strio_substr
static VALUE strio_substr(struct StringIO *ptr, long pos, long len)
Definition: stringio.c:97
len
size_t len
Definition: tcltklib.c:3568
strio_alloc
static struct StringIO * strio_alloc(void)
Definition: stringio.c:37
rb_eof_error
void rb_eof_error(void)
Definition: io.c:581