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