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