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