ext/stringio/stringio.c

Go to the documentation of this file.
00001 /**********************************************************************
00002 
00003   stringio.c -
00004 
00005   $Author: nagachika $
00006   $RoughId: stringio.c,v 1.13 2002/03/14 03:24:18 nobu Exp $
00007   created at: Tue Feb 19 04:10:38 JST 2002
00008 
00009   All the files in this distribution are covered under the Ruby's
00010   license (see the file COPYING).
00011 
00012 **********************************************************************/
00013 
00014 #include "ruby.h"
00015 #include "ruby/io.h"
00016 #include "ruby/encoding.h"
00017 #if defined(HAVE_FCNTL_H) || defined(_WIN32)
00018 #include <fcntl.h>
00019 #elif defined(HAVE_SYS_FCNTL_H)
00020 #include <sys/fcntl.h>
00021 #endif
00022 
00023 struct StringIO {
00024     VALUE string;
00025     long pos;
00026     long lineno;
00027     int flags;
00028     int count;
00029 };
00030 
00031 static void strio_init(int, VALUE *, struct StringIO *, VALUE);
00032 
00033 #define IS_STRIO(obj) (rb_typeddata_is_kind_of((obj), &strio_data_type))
00034 #define error_inval(msg) (errno = EINVAL, rb_sys_fail(msg))
00035 
00036 static struct StringIO *
00037 strio_alloc(void)
00038 {
00039     struct StringIO *ptr = ALLOC(struct StringIO);
00040     ptr->string = Qnil;
00041     ptr->pos = 0;
00042     ptr->lineno = 0;
00043     ptr->flags = 0;
00044     ptr->count = 1;
00045     return ptr;
00046 }
00047 
00048 static void
00049 strio_mark(void *p)
00050 {
00051     struct StringIO *ptr = p;
00052     if (ptr) {
00053         rb_gc_mark(ptr->string);
00054     }
00055 }
00056 
00057 static void
00058 strio_free(void *p)
00059 {
00060     struct StringIO *ptr = p;
00061     if (--ptr->count <= 0) {
00062         xfree(ptr);
00063     }
00064 }
00065 
00066 static size_t
00067 strio_memsize(const void *p)
00068 {
00069     const struct StringIO *ptr = p;
00070     if (!ptr) return 0;
00071     return sizeof(struct StringIO);
00072 }
00073 
00074 static const rb_data_type_t strio_data_type = {
00075     "strio",
00076     {
00077         strio_mark,
00078         strio_free,
00079         strio_memsize,
00080     },
00081     NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
00082 };
00083 
00084 #define check_strio(self) ((struct StringIO*)rb_check_typeddata((self), &strio_data_type))
00085 
00086 static struct StringIO*
00087 get_strio(VALUE self)
00088 {
00089     struct StringIO *ptr = check_strio(rb_io_taint_check(self));
00090 
00091     if (!ptr) {
00092         rb_raise(rb_eIOError, "uninitialized stream");
00093     }
00094     return ptr;
00095 }
00096 
00097 static VALUE
00098 strio_substr(struct StringIO *ptr, long pos, long len)
00099 {
00100     VALUE str = ptr->string;
00101     rb_encoding *enc = rb_enc_get(str);
00102     long rlen = RSTRING_LEN(str) - pos;
00103 
00104     if (len > rlen) len = rlen;
00105     if (len < 0) len = 0;
00106     if (len == 0) return rb_str_new(0,0);
00107     return rb_enc_str_new(RSTRING_PTR(str)+pos, len, enc);
00108 }
00109 
00110 #define StringIO(obj) get_strio(obj)
00111 
00112 #define STRIO_READABLE FL_USER4
00113 #define STRIO_WRITABLE FL_USER5
00114 #define STRIO_READWRITE (STRIO_READABLE|STRIO_WRITABLE)
00115 typedef char strio_flags_check[(STRIO_READABLE/FMODE_READABLE == STRIO_WRITABLE/FMODE_WRITABLE) * 2 - 1];
00116 #define STRIO_MODE_SET_P(strio, mode) \
00117     ((RBASIC(strio)->flags & STRIO_##mode) && \
00118      ((struct StringIO*)DATA_PTR(strio))->flags & FMODE_##mode)
00119 #define CLOSED(strio) (!STRIO_MODE_SET_P(strio, READWRITE))
00120 #define READABLE(strio) STRIO_MODE_SET_P(strio, READABLE)
00121 #define WRITABLE(strio) STRIO_MODE_SET_P(strio, WRITABLE)
00122 
00123 static VALUE sym_exception;
00124 
00125 static struct StringIO*
00126 readable(VALUE strio)
00127 {
00128     struct StringIO *ptr = StringIO(strio);
00129     if (!READABLE(strio)) {
00130         rb_raise(rb_eIOError, "not opened for reading");
00131     }
00132     return ptr;
00133 }
00134 
00135 static struct StringIO*
00136 writable(VALUE strio)
00137 {
00138     struct StringIO *ptr = StringIO(strio);
00139     if (!WRITABLE(strio)) {
00140         rb_raise(rb_eIOError, "not opened for writing");
00141     }
00142     if (!OBJ_TAINTED(ptr->string)) {
00143     }
00144     return ptr;
00145 }
00146 
00147 static void
00148 check_modifiable(struct StringIO *ptr)
00149 {
00150     if (OBJ_FROZEN(ptr->string)) {
00151         rb_raise(rb_eIOError, "not modifiable string");
00152     }
00153 }
00154 
00155 static VALUE
00156 strio_s_allocate(VALUE klass)
00157 {
00158     return TypedData_Wrap_Struct(klass, &strio_data_type, 0);
00159 }
00160 
00161 /*
00162  * call-seq: StringIO.new(string=""[, mode])
00163  *
00164  * Creates new StringIO instance from with _string_ and _mode_.
00165  */
00166 static VALUE
00167 strio_initialize(int argc, VALUE *argv, VALUE self)
00168 {
00169     struct StringIO *ptr = check_strio(self);
00170 
00171     if (!ptr) {
00172         DATA_PTR(self) = ptr = strio_alloc();
00173     }
00174     rb_call_super(0, 0);
00175     strio_init(argc, argv, ptr, self);
00176     return self;
00177 }
00178 
00179 static void
00180 strio_init(int argc, VALUE *argv, struct StringIO *ptr, VALUE self)
00181 {
00182     VALUE string, mode;
00183     int trunc = 0;
00184 
00185     switch (rb_scan_args(argc, argv, "02", &string, &mode)) {
00186       case 2:
00187         if (FIXNUM_P(mode)) {
00188             int flags = FIX2INT(mode);
00189             ptr->flags = rb_io_modenum_flags(flags);
00190             trunc = flags & O_TRUNC;
00191         }
00192         else {
00193             const char *m = StringValueCStr(mode);
00194             ptr->flags = rb_io_mode_flags(m);
00195             trunc = *m == 'w';
00196         }
00197         StringValue(string);
00198         if ((ptr->flags & FMODE_WRITABLE) && OBJ_FROZEN(string)) {
00199             errno = EACCES;
00200             rb_sys_fail(0);
00201         }
00202         if (trunc) {
00203             rb_str_resize(string, 0);
00204         }
00205         break;
00206       case 1:
00207         StringValue(string);
00208         ptr->flags = OBJ_FROZEN(string) ? FMODE_READABLE : FMODE_READWRITE;
00209         break;
00210       case 0:
00211         string = rb_enc_str_new("", 0, rb_default_external_encoding());
00212         ptr->flags = FMODE_READWRITE;
00213         break;
00214     }
00215     ptr->string = string;
00216     ptr->pos = 0;
00217     ptr->lineno = 0;
00218     RBASIC(self)->flags |= (ptr->flags & FMODE_READWRITE) * (STRIO_READABLE / FMODE_READABLE);
00219 }
00220 
00221 static VALUE
00222 strio_finalize(VALUE self)
00223 {
00224     struct StringIO *ptr = StringIO(self);
00225     ptr->string = Qnil;
00226     ptr->flags &= ~FMODE_READWRITE;
00227     return self;
00228 }
00229 
00230 /*
00231  * call-seq: StringIO.open(string=""[, mode]) {|strio| ...}
00232  *
00233  * Equivalent to StringIO.new except that when it is called with a block, it
00234  * yields with the new instance and closes it, and returns the result which
00235  * returned from the block.
00236  */
00237 static VALUE
00238 strio_s_open(int argc, VALUE *argv, VALUE klass)
00239 {
00240     VALUE obj = rb_class_new_instance(argc, argv, klass);
00241     if (!rb_block_given_p()) return obj;
00242     return rb_ensure(rb_yield, obj, strio_finalize, obj);
00243 }
00244 
00245 /*
00246  * Returns +false+.  Just for compatibility to IO.
00247  */
00248 static VALUE
00249 strio_false(VALUE self)
00250 {
00251     StringIO(self);
00252     return Qfalse;
00253 }
00254 
00255 /*
00256  * Returns +nil+.  Just for compatibility to IO.
00257  */
00258 static VALUE
00259 strio_nil(VALUE self)
00260 {
00261     StringIO(self);
00262     return Qnil;
00263 }
00264 
00265 /*
00266  * Returns *strio* itself.  Just for compatibility to IO.
00267  */
00268 static VALUE
00269 strio_self(VALUE self)
00270 {
00271     StringIO(self);
00272     return self;
00273 }
00274 
00275 /*
00276  * Returns 0.  Just for compatibility to IO.
00277  */
00278 static VALUE
00279 strio_0(VALUE self)
00280 {
00281     StringIO(self);
00282     return INT2FIX(0);
00283 }
00284 
00285 /*
00286  * Returns the argument unchanged.  Just for compatibility to IO.
00287  */
00288 static VALUE
00289 strio_first(VALUE self, VALUE arg)
00290 {
00291     StringIO(self);
00292     return arg;
00293 }
00294 
00295 /*
00296  * Raises NotImplementedError.
00297  */
00298 static VALUE
00299 strio_unimpl(int argc, VALUE *argv, VALUE self)
00300 {
00301     StringIO(self);
00302     rb_notimplement();
00303 
00304     UNREACHABLE;
00305 }
00306 
00307 /*
00308  * call-seq: strio.string     -> string
00309  *
00310  * Returns underlying String object, the subject of IO.
00311  */
00312 static VALUE
00313 strio_get_string(VALUE self)
00314 {
00315     return StringIO(self)->string;
00316 }
00317 
00318 /*
00319  * call-seq:
00320  *   strio.string = string  -> string
00321  *
00322  * Changes underlying String object, the subject of IO.
00323  */
00324 static VALUE
00325 strio_set_string(VALUE self, VALUE string)
00326 {
00327     struct StringIO *ptr = StringIO(self);
00328 
00329     rb_io_taint_check(self);
00330     ptr->flags &= ~FMODE_READWRITE;
00331     StringValue(string);
00332     ptr->flags = OBJ_FROZEN(string) ? FMODE_READABLE : FMODE_READWRITE;
00333     ptr->pos = 0;
00334     ptr->lineno = 0;
00335     return ptr->string = string;
00336 }
00337 
00338 /*
00339  * call-seq:
00340  *   strio.close  -> nil
00341  *
00342  * Closes strio.  The *strio* is unavailable for any further data
00343  * operations; an +IOError+ is raised if such an attempt is made.
00344  */
00345 static VALUE
00346 strio_close(VALUE self)
00347 {
00348     StringIO(self);
00349     if (CLOSED(self)) {
00350         rb_raise(rb_eIOError, "closed stream");
00351     }
00352     RBASIC(self)->flags &= ~STRIO_READWRITE;
00353     return Qnil;
00354 }
00355 
00356 /*
00357  * call-seq:
00358  *   strio.close_read    -> nil
00359  *
00360  * Closes the read end of a StringIO.  Will raise an +IOError+ if the
00361  * *strio* is not readable.
00362  */
00363 static VALUE
00364 strio_close_read(VALUE self)
00365 {
00366     StringIO(self);
00367     if (!READABLE(self)) {
00368         rb_raise(rb_eIOError, "closing non-duplex IO for reading");
00369     }
00370     RBASIC(self)->flags &= ~STRIO_READABLE;
00371     return Qnil;
00372 }
00373 
00374 /*
00375  * call-seq:
00376  *   strio.close_write    -> nil
00377  *
00378  * Closes the write end of a StringIO.  Will raise an  +IOError+ if the
00379  * *strio* is not writeable.
00380  */
00381 static VALUE
00382 strio_close_write(VALUE self)
00383 {
00384     StringIO(self);
00385     if (!WRITABLE(self)) {
00386         rb_raise(rb_eIOError, "closing non-duplex IO for writing");
00387     }
00388     RBASIC(self)->flags &= ~STRIO_WRITABLE;
00389     return Qnil;
00390 }
00391 
00392 /*
00393  * call-seq:
00394  *   strio.closed?    -> true or false
00395  *
00396  * Returns +true+ if *strio* is completely closed, +false+ otherwise.
00397  */
00398 static VALUE
00399 strio_closed(VALUE self)
00400 {
00401     StringIO(self);
00402     if (!CLOSED(self)) return Qfalse;
00403     return Qtrue;
00404 }
00405 
00406 /*
00407  * call-seq:
00408  *   strio.closed_read?    -> true or false
00409  *
00410  * Returns +true+ if *strio* is not readable, +false+ otherwise.
00411  */
00412 static VALUE
00413 strio_closed_read(VALUE self)
00414 {
00415     StringIO(self);
00416     if (READABLE(self)) return Qfalse;
00417     return Qtrue;
00418 }
00419 
00420 /*
00421  * call-seq:
00422  *   strio.closed_write?    -> true or false
00423  *
00424  * Returns +true+ if *strio* is not writable, +false+ otherwise.
00425  */
00426 static VALUE
00427 strio_closed_write(VALUE self)
00428 {
00429     StringIO(self);
00430     if (WRITABLE(self)) return Qfalse;
00431     return Qtrue;
00432 }
00433 
00434 /*
00435  * call-seq:
00436  *   strio.eof     -> true or false
00437  *   strio.eof?    -> true or false
00438  *
00439  * Returns true if *strio* is at end of file. The stringio must be
00440  * opened for reading or an +IOError+ will be raised.
00441  */
00442 static VALUE
00443 strio_eof(VALUE self)
00444 {
00445     struct StringIO *ptr = readable(self);
00446     if (ptr->pos < RSTRING_LEN(ptr->string)) return Qfalse;
00447     return Qtrue;
00448 }
00449 
00450 /* :nodoc: */
00451 static VALUE
00452 strio_copy(VALUE copy, VALUE orig)
00453 {
00454     struct StringIO *ptr;
00455 
00456     orig = rb_convert_type(orig, T_DATA, "StringIO", "to_strio");
00457     if (copy == orig) return copy;
00458     ptr = StringIO(orig);
00459     if (check_strio(copy)) {
00460         strio_free(DATA_PTR(copy));
00461     }
00462     DATA_PTR(copy) = ptr;
00463     OBJ_INFECT(copy, orig);
00464     RBASIC(copy)->flags &= ~STRIO_READWRITE;
00465     RBASIC(copy)->flags |= RBASIC(orig)->flags & STRIO_READWRITE;
00466     ++ptr->count;
00467     return copy;
00468 }
00469 
00470 /*
00471  * call-seq:
00472  *   strio.lineno    -> integer
00473  *
00474  * Returns the current line number in *strio*. The stringio must be
00475  * opened for reading. +lineno+ counts the number of times  +gets+ is
00476  * called, rather than the number of newlines  encountered. The two
00477  * values will differ if +gets+ is  called with a separator other than
00478  * newline.  See also the  <code>$.</code> variable.
00479  */
00480 static VALUE
00481 strio_get_lineno(VALUE self)
00482 {
00483     return LONG2NUM(StringIO(self)->lineno);
00484 }
00485 
00486 /*
00487  * call-seq:
00488  *   strio.lineno = integer    -> integer
00489  *
00490  * Manually sets the current line number to the given value.
00491  * <code>$.</code> is updated only on the next read.
00492  */
00493 static VALUE
00494 strio_set_lineno(VALUE self, VALUE lineno)
00495 {
00496     StringIO(self)->lineno = NUM2LONG(lineno);
00497     return lineno;
00498 }
00499 
00500 #define strio_binmode strio_self
00501 
00502 #define strio_fcntl strio_unimpl
00503 
00504 #define strio_flush strio_self
00505 
00506 #define strio_fsync strio_0
00507 
00508 /*
00509  * call-seq:
00510  *   strio.reopen(other_StrIO)     -> strio
00511  *   strio.reopen(string, mode)    -> strio
00512  *
00513  * Reinitializes *strio* with the given <i>other_StrIO</i> or _string_
00514  * and _mode_ (see StringIO#new).
00515  */
00516 static VALUE
00517 strio_reopen(int argc, VALUE *argv, VALUE self)
00518 {
00519     rb_io_taint_check(self);
00520     if (argc == 1 && !RB_TYPE_P(*argv, T_STRING)) {
00521         return strio_copy(self, *argv);
00522     }
00523     strio_init(argc, argv, StringIO(self), self);
00524     return self;
00525 }
00526 
00527 /*
00528  * call-seq:
00529  *   strio.pos     -> integer
00530  *   strio.tell    -> integer
00531  *
00532  * Returns the current offset (in bytes) of *strio*.
00533  */
00534 static VALUE
00535 strio_get_pos(VALUE self)
00536 {
00537     return LONG2NUM(StringIO(self)->pos);
00538 }
00539 
00540 /*
00541  * call-seq:
00542  *   strio.pos = integer    -> integer
00543  *
00544  * Seeks to the given position (in bytes) in *strio*.
00545  */
00546 static VALUE
00547 strio_set_pos(VALUE self, VALUE pos)
00548 {
00549     struct StringIO *ptr = StringIO(self);
00550     long p = NUM2LONG(pos);
00551     if (p < 0) {
00552         error_inval(0);
00553     }
00554     ptr->pos = p;
00555     return pos;
00556 }
00557 
00558 /*
00559  * call-seq:
00560  *   strio.rewind    -> 0
00561  *
00562  * Positions *strio* to the beginning of input, resetting
00563  * +lineno+ to zero.
00564  */
00565 static VALUE
00566 strio_rewind(VALUE self)
00567 {
00568     struct StringIO *ptr = StringIO(self);
00569     ptr->pos = 0;
00570     ptr->lineno = 0;
00571     return INT2FIX(0);
00572 }
00573 
00574 /*
00575  * call-seq:
00576  *   strio.seek(amount, whence=SEEK_SET) -> 0
00577  *
00578  * Seeks to a given offset _amount_ in the stream according to
00579  * the value of _whence_ (see IO#seek).
00580  */
00581 static VALUE
00582 strio_seek(int argc, VALUE *argv, VALUE self)
00583 {
00584     VALUE whence;
00585     struct StringIO *ptr = StringIO(self);
00586     long offset;
00587 
00588     rb_scan_args(argc, argv, "11", NULL, &whence);
00589     offset = NUM2LONG(argv[0]);
00590     if (CLOSED(self)) {
00591         rb_raise(rb_eIOError, "closed stream");
00592     }
00593     switch (NIL_P(whence) ? 0 : NUM2LONG(whence)) {
00594       case 0:
00595         break;
00596       case 1:
00597         offset += ptr->pos;
00598         break;
00599       case 2:
00600         offset += RSTRING_LEN(ptr->string);
00601         break;
00602       default:
00603         error_inval("invalid whence");
00604     }
00605     if (offset < 0) {
00606         error_inval(0);
00607     }
00608     ptr->pos = offset;
00609     return INT2FIX(0);
00610 }
00611 
00612 /*
00613  * call-seq:
00614  *   strio.sync    -> true
00615  *
00616  * Returns +true+ always.
00617  */
00618 static VALUE
00619 strio_get_sync(VALUE self)
00620 {
00621     StringIO(self);
00622     return Qtrue;
00623 }
00624 
00625 #define strio_set_sync strio_first
00626 
00627 #define strio_tell strio_get_pos
00628 
00629 /*
00630  * call-seq:
00631  *   strio.each_byte {|byte| block }  -> strio
00632  *   strio.each_byte                  -> anEnumerator
00633  *
00634  * See IO#each_byte.
00635  */
00636 static VALUE
00637 strio_each_byte(VALUE self)
00638 {
00639     struct StringIO *ptr = readable(self);
00640 
00641     RETURN_ENUMERATOR(self, 0, 0);
00642 
00643     while (ptr->pos < RSTRING_LEN(ptr->string)) {
00644         char c = RSTRING_PTR(ptr->string)[ptr->pos++];
00645         rb_yield(CHR2FIX(c));
00646     }
00647     return self;
00648 }
00649 
00650 /*
00651  *  This is a deprecated alias for #each_byte.
00652  */
00653 static VALUE
00654 strio_bytes(VALUE self)
00655 {
00656     rb_warn("StringIO#bytes is deprecated; use #each_byte instead");
00657     if (!rb_block_given_p())
00658         return rb_enumeratorize(self, ID2SYM(rb_intern("each_byte")), 0, 0);
00659     return strio_each_byte(self);
00660 }
00661 
00662 /*
00663  * call-seq:
00664  *   strio.getc   -> string or nil
00665  *
00666  * See IO#getc.
00667  */
00668 static VALUE
00669 strio_getc(VALUE self)
00670 {
00671     struct StringIO *ptr = readable(self);
00672     rb_encoding *enc = rb_enc_get(ptr->string);
00673     int len;
00674     char *p;
00675 
00676     if (ptr->pos >= RSTRING_LEN(ptr->string)) {
00677         return Qnil;
00678     }
00679     p = RSTRING_PTR(ptr->string)+ptr->pos;
00680     len = rb_enc_mbclen(p, RSTRING_END(ptr->string), enc);
00681     ptr->pos += len;
00682     return rb_enc_str_new(p, len, rb_enc_get(ptr->string));
00683 }
00684 
00685 /*
00686  * call-seq:
00687  *   strio.getbyte   -> fixnum or nil
00688  *
00689  * See IO#getbyte.
00690  */
00691 static VALUE
00692 strio_getbyte(VALUE self)
00693 {
00694     struct StringIO *ptr = readable(self);
00695     int c;
00696     if (ptr->pos >= RSTRING_LEN(ptr->string)) {
00697         return Qnil;
00698     }
00699     c = RSTRING_PTR(ptr->string)[ptr->pos++];
00700     return CHR2FIX(c);
00701 }
00702 
00703 static void
00704 strio_extend(struct StringIO *ptr, long pos, long len)
00705 {
00706     long olen;
00707 
00708     check_modifiable(ptr);
00709     olen = RSTRING_LEN(ptr->string);
00710     if (pos + len > olen) {
00711         rb_str_resize(ptr->string, pos + len);
00712         if (pos > olen)
00713             MEMZERO(RSTRING_PTR(ptr->string) + olen, char, pos - olen);
00714     }
00715     else {
00716         rb_str_modify(ptr->string);
00717     }
00718 }
00719 
00720 /*
00721  * call-seq:
00722  *   strio.ungetc(string)   -> nil
00723  *
00724  * Pushes back one character (passed as a parameter) onto *strio*
00725  * such that a subsequent buffered read will return it.  There is no
00726  * limitation for multiple pushbacks including pushing back behind the
00727  * beginning of the buffer string.
00728  */
00729 static VALUE
00730 strio_ungetc(VALUE self, VALUE c)
00731 {
00732     struct StringIO *ptr = readable(self);
00733     long lpos, clen;
00734     char *p, *pend;
00735     rb_encoding *enc, *enc2;
00736 
00737     if (NIL_P(c)) return Qnil;
00738     check_modifiable(ptr);
00739     if (FIXNUM_P(c)) {
00740         int cc = FIX2INT(c);
00741         char buf[16];
00742 
00743         enc = rb_enc_get(ptr->string);
00744         rb_enc_mbcput(cc, buf, enc);
00745         c = rb_enc_str_new(buf, rb_enc_codelen(cc, enc), enc);
00746     }
00747     else {
00748         SafeStringValue(c);
00749         enc = rb_enc_get(ptr->string);
00750         enc2 = rb_enc_get(c);
00751         if (enc != enc2 && enc != rb_ascii8bit_encoding()) {
00752             c = rb_str_conv_enc(c, enc2, enc);
00753         }
00754     }
00755     if (RSTRING_LEN(ptr->string) < ptr->pos) {
00756         long len = RSTRING_LEN(ptr->string);
00757         rb_str_resize(ptr->string, ptr->pos - 1);
00758         memset(RSTRING_PTR(ptr->string) + len, 0, ptr->pos - len - 1);
00759         rb_str_concat(ptr->string, c);
00760         ptr->pos--;
00761     }
00762     else {
00763         /* get logical position */
00764         lpos = 0; p = RSTRING_PTR(ptr->string); pend = p + ptr->pos;
00765         for (;;) {
00766             clen = rb_enc_mbclen(p, pend, enc);
00767             if (p+clen >= pend) break;
00768             p += clen;
00769             lpos++;
00770         }
00771         clen = p - RSTRING_PTR(ptr->string);
00772         rb_str_update(ptr->string, lpos, ptr->pos ? 1 : 0, c);
00773         ptr->pos = clen;
00774     }
00775 
00776     return Qnil;
00777 }
00778 
00779 /*
00780  * call-seq:
00781  *   strio.ungetbyte(fixnum)   -> nil
00782  *
00783  * See IO#ungetbyte
00784  */
00785 static VALUE
00786 strio_ungetbyte(VALUE self, VALUE c)
00787 {
00788     struct StringIO *ptr = readable(self);
00789     char buf[1], *cp = buf;
00790     long pos = ptr->pos, cl = 1;
00791     VALUE str = ptr->string;
00792 
00793     if (NIL_P(c)) return Qnil;
00794     if (FIXNUM_P(c)) {
00795         buf[0] = (char)FIX2INT(c);
00796     }
00797     else {
00798         SafeStringValue(c);
00799         cp = RSTRING_PTR(c);
00800         cl = RSTRING_LEN(c);
00801         if (cl == 0) return Qnil;
00802     }
00803     check_modifiable(ptr);
00804     rb_str_modify(str);
00805     if (cl > pos) {
00806         char *s;
00807         long rest = RSTRING_LEN(str) - pos;
00808         rb_str_resize(str, rest + cl);
00809         s = RSTRING_PTR(str);
00810         memmove(s + cl, s + pos, rest);
00811         pos = 0;
00812     }
00813     else {
00814         pos -= cl;
00815     }
00816     memcpy(RSTRING_PTR(str) + pos, cp, cl);
00817     ptr->pos = pos;
00818     RB_GC_GUARD(c);
00819     return Qnil;
00820 }
00821 
00822 /*
00823  * call-seq:
00824  *   strio.readchar   -> string
00825  *
00826  * See IO#readchar.
00827  */
00828 static VALUE
00829 strio_readchar(VALUE self)
00830 {
00831     VALUE c = rb_funcall2(self, rb_intern("getc"), 0, 0);
00832     if (NIL_P(c)) rb_eof_error();
00833     return c;
00834 }
00835 
00836 /*
00837  * call-seq:
00838  *   strio.readbyte   -> fixnum
00839  *
00840  * See IO#readbyte.
00841  */
00842 static VALUE
00843 strio_readbyte(VALUE self)
00844 {
00845     VALUE c = rb_funcall2(self, rb_intern("getbyte"), 0, 0);
00846     if (NIL_P(c)) rb_eof_error();
00847     return c;
00848 }
00849 
00850 /*
00851  * call-seq:
00852  *   strio.each_char {|char| block }  -> strio
00853  *   strio.each_char                  -> anEnumerator
00854  *
00855  * See IO#each_char.
00856  */
00857 static VALUE
00858 strio_each_char(VALUE self)
00859 {
00860     VALUE c;
00861 
00862     RETURN_ENUMERATOR(self, 0, 0);
00863 
00864     while (!NIL_P(c = strio_getc(self))) {
00865         rb_yield(c);
00866     }
00867     return self;
00868 }
00869 
00870 /*
00871  *  This is a deprecated alias for <code>each_char</code>.
00872  */
00873 static VALUE
00874 strio_chars(VALUE self)
00875 {
00876     rb_warn("StringIO#chars is deprecated; use #each_char instead");
00877     if (!rb_block_given_p())
00878         return rb_enumeratorize(self, ID2SYM(rb_intern("each_char")), 0, 0);
00879     return strio_each_char(self);
00880 }
00881 
00882 /*
00883  * call-seq:
00884  *   strio.each_codepoint {|c| block }  -> strio
00885  *   strio.each_codepoint               -> anEnumerator
00886  *
00887  * See IO#each_codepoint.
00888  */
00889 static VALUE
00890 strio_each_codepoint(VALUE self)
00891 {
00892     struct StringIO *ptr;
00893     rb_encoding *enc;
00894     unsigned int c;
00895     int n;
00896 
00897     RETURN_ENUMERATOR(self, 0, 0);
00898 
00899     ptr = readable(self);
00900     enc = rb_enc_get(ptr->string);
00901     for (;;) {
00902         if (ptr->pos >= RSTRING_LEN(ptr->string)) {
00903             return self;
00904         }
00905 
00906         c = rb_enc_codepoint_len(RSTRING_PTR(ptr->string)+ptr->pos,
00907                                  RSTRING_END(ptr->string), &n, enc);
00908         rb_yield(UINT2NUM(c));
00909         ptr->pos += n;
00910     }
00911     return self;
00912 }
00913 
00914 /*
00915  *  This is a deprecated alias for <code>each_codepoint</code>.
00916  */
00917 static VALUE
00918 strio_codepoints(VALUE self)
00919 {
00920     rb_warn("StringIO#codepoints is deprecated; use #each_codepoint instead");
00921     if (!rb_block_given_p())
00922         return rb_enumeratorize(self, ID2SYM(rb_intern("each_codepoint")), 0, 0);
00923     return strio_each_codepoint(self);
00924 }
00925 
00926 /* Boyer-Moore search: copied from regex.c */
00927 static void
00928 bm_init_skip(long *skip, const char *pat, long m)
00929 {
00930     int c;
00931 
00932     for (c = 0; c < (1 << CHAR_BIT); c++) {
00933         skip[c] = m;
00934     }
00935     while (--m) {
00936         skip[(unsigned char)*pat++] = m;
00937     }
00938 }
00939 
00940 static long
00941 bm_search(const char *little, long llen, const char *big, long blen, const long *skip)
00942 {
00943     long i, j, k;
00944 
00945     i = llen - 1;
00946     while (i < blen) {
00947         k = i;
00948         j = llen - 1;
00949         while (j >= 0 && big[k] == little[j]) {
00950             k--;
00951             j--;
00952         }
00953         if (j < 0) return k + 1;
00954         i += skip[(unsigned char)big[i]];
00955     }
00956     return -1;
00957 }
00958 
00959 static VALUE
00960 strio_getline(int argc, VALUE *argv, struct StringIO *ptr)
00961 {
00962     const char *s, *e, *p;
00963     long n, limit = 0;
00964     VALUE str, lim;
00965 
00966     rb_scan_args(argc, argv, "02", &str, &lim);
00967     switch (argc) {
00968       case 0:
00969         str = rb_rs;
00970         break;
00971 
00972       case 1:
00973         if (!NIL_P(str) && !RB_TYPE_P(str, T_STRING)) {
00974             VALUE tmp = rb_check_string_type(str);
00975             if (NIL_P(tmp)) {
00976                 limit = NUM2LONG(str);
00977                 if (limit == 0) return rb_str_new(0,0);
00978                 str = rb_rs;
00979             }
00980             else {
00981                 str = tmp;
00982             }
00983         }
00984         break;
00985 
00986       case 2:
00987         if (!NIL_P(str)) StringValue(str);
00988         if (!NIL_P(lim)) limit = NUM2LONG(lim);
00989         break;
00990     }
00991 
00992     if (ptr->pos >= (n = RSTRING_LEN(ptr->string))) {
00993         return Qnil;
00994     }
00995     s = RSTRING_PTR(ptr->string);
00996     e = s + RSTRING_LEN(ptr->string);
00997     s += ptr->pos;
00998     if (limit > 0 && s + limit < e) {
00999         e = rb_enc_right_char_head(s, s + limit, e, rb_enc_get(ptr->string));
01000     }
01001     if (NIL_P(str)) {
01002         str = strio_substr(ptr, ptr->pos, e - s);
01003     }
01004     else if ((n = RSTRING_LEN(str)) == 0) {
01005         p = s;
01006         while (*p == '\n') {
01007             if (++p == e) {
01008                 return Qnil;
01009             }
01010         }
01011         s = p;
01012         while ((p = memchr(p, '\n', e - p)) && (p != e)) {
01013             if (*++p == '\n') {
01014                 e = p + 1;
01015                 break;
01016             }
01017         }
01018         str = strio_substr(ptr, s - RSTRING_PTR(ptr->string), e - s);
01019     }
01020     else if (n == 1) {
01021         if ((p = memchr(s, RSTRING_PTR(str)[0], e - s)) != 0) {
01022             e = p + 1;
01023         }
01024         str = strio_substr(ptr, ptr->pos, e - s);
01025     }
01026     else {
01027         if (n < e - s) {
01028             if (e - s < 1024) {
01029                 for (p = s; p + n <= e; ++p) {
01030                     if (MEMCMP(p, RSTRING_PTR(str), char, n) == 0) {
01031                         e = p + n;
01032                         break;
01033                     }
01034                 }
01035             }
01036             else {
01037                 long skip[1 << CHAR_BIT], pos;
01038                 p = RSTRING_PTR(str);
01039                 bm_init_skip(skip, p, n);
01040                 if ((pos = bm_search(p, n, s, e - s, skip)) >= 0) {
01041                     e = s + pos + n;
01042                 }
01043             }
01044         }
01045         str = strio_substr(ptr, ptr->pos, e - s);
01046     }
01047     ptr->pos = e - RSTRING_PTR(ptr->string);
01048     ptr->lineno++;
01049     return str;
01050 }
01051 
01052 /*
01053  * call-seq:
01054  *   strio.gets(sep=$/)     -> string or nil
01055  *   strio.gets(limit)      -> string or nil
01056  *   strio.gets(sep, limit) -> string or nil
01057  *
01058  * See IO#gets.
01059  */
01060 static VALUE
01061 strio_gets(int argc, VALUE *argv, VALUE self)
01062 {
01063     VALUE str = strio_getline(argc, argv, readable(self));
01064 
01065     rb_lastline_set(str);
01066     return str;
01067 }
01068 
01069 /*
01070  * call-seq:
01071  *   strio.readline(sep=$/)     -> string
01072  *   strio.readline(limit)      -> string or nil
01073  *   strio.readline(sep, limit) -> string or nil
01074  *
01075  * See IO#readline.
01076  */
01077 static VALUE
01078 strio_readline(int argc, VALUE *argv, VALUE self)
01079 {
01080     VALUE line = rb_funcall2(self, rb_intern("gets"), argc, argv);
01081     if (NIL_P(line)) rb_eof_error();
01082     return line;
01083 }
01084 
01085 /*
01086  * call-seq:
01087  *   strio.each(sep=$/) {|line| block }         -> strio
01088  *   strio.each(limit) {|line| block }          -> strio
01089  *   strio.each(sep, limit) {|line| block }     -> strio
01090  *   strio.each(...)                            -> anEnumerator
01091  *
01092  *   strio.each_line(sep=$/) {|line| block }    -> strio
01093  *   strio.each_line(limit) {|line| block }     -> strio
01094  *   strio.each_line(sep,limit) {|line| block } -> strio
01095  *   strio.each_line(...)                       -> anEnumerator
01096  *
01097  * See IO#each.
01098  */
01099 static VALUE
01100 strio_each(int argc, VALUE *argv, VALUE self)
01101 {
01102     VALUE line;
01103 
01104     StringIO(self);
01105     RETURN_ENUMERATOR(self, argc, argv);
01106 
01107     if (argc > 0 && !NIL_P(argv[argc-1]) && NIL_P(rb_check_string_type(argv[argc-1])) &&
01108         NUM2LONG(argv[argc-1]) == 0) {
01109         rb_raise(rb_eArgError, "invalid limit: 0 for each_line");
01110     }
01111 
01112     while (!NIL_P(line = strio_getline(argc, argv, readable(self)))) {
01113         rb_yield(line);
01114     }
01115     return self;
01116 }
01117 
01118 /*
01119  *  This is a deprecated alias for <code>each_line</code>.
01120  */
01121 static VALUE
01122 strio_lines(int argc, VALUE *argv, VALUE self)
01123 {
01124     rb_warn("StringIO#lines is deprecated; use #each_line instead");
01125     if (!rb_block_given_p())
01126         return rb_enumeratorize(self, ID2SYM(rb_intern("each_line")), argc, argv);
01127     return strio_each(argc, argv, self);
01128 }
01129 
01130 /*
01131  * call-seq:
01132  *   strio.readlines(sep=$/)    ->   array
01133  *   strio.readlines(limit)     ->   array
01134  *   strio.readlines(sep,limit) ->   array
01135  *
01136  * See IO#readlines.
01137  */
01138 static VALUE
01139 strio_readlines(int argc, VALUE *argv, VALUE self)
01140 {
01141     VALUE ary, line;
01142 
01143     StringIO(self);
01144     ary = rb_ary_new();
01145     if (argc > 0 && !NIL_P(argv[argc-1]) && NIL_P(rb_check_string_type(argv[argc-1])) &&
01146         NUM2LONG(argv[argc-1]) == 0) {
01147         rb_raise(rb_eArgError, "invalid limit: 0 for readlines");
01148     }
01149 
01150     while (!NIL_P(line = strio_getline(argc, argv, readable(self)))) {
01151         rb_ary_push(ary, line);
01152     }
01153     return ary;
01154 }
01155 
01156 /*
01157  * call-seq:
01158  *   strio.write(string)    -> integer
01159  *   strio.syswrite(string) -> integer
01160  *
01161  * Appends the given string to the underlying buffer string of *strio*.
01162  * The stream must be opened for writing.  If the argument is not a
01163  * string, it will be converted to a string using <code>to_s</code>.
01164  * Returns the number of bytes written.  See IO#write.
01165  */
01166 static VALUE
01167 strio_write(VALUE self, VALUE str)
01168 {
01169     struct StringIO *ptr = writable(self);
01170     long len, olen;
01171     rb_encoding *enc, *enc2;
01172     rb_encoding *const ascii8bit = rb_ascii8bit_encoding();
01173 
01174     if (!RB_TYPE_P(str, T_STRING))
01175         str = rb_obj_as_string(str);
01176     enc = rb_enc_get(ptr->string);
01177     enc2 = rb_enc_get(str);
01178     if (enc != enc2 && enc != ascii8bit) {
01179         str = rb_str_conv_enc(str, enc2, enc);
01180     }
01181     len = RSTRING_LEN(str);
01182     if (len == 0) return INT2FIX(0);
01183     check_modifiable(ptr);
01184     olen = RSTRING_LEN(ptr->string);
01185     if (ptr->flags & FMODE_APPEND) {
01186         ptr->pos = olen;
01187     }
01188     if (ptr->pos == olen) {
01189         if (enc == ascii8bit || enc2 == ascii8bit) {
01190             rb_enc_str_buf_cat(ptr->string, RSTRING_PTR(str), len, enc);
01191             OBJ_INFECT(ptr->string, str);
01192         }
01193         else {
01194             rb_str_buf_append(ptr->string, str);
01195         }
01196     }
01197     else {
01198         strio_extend(ptr, ptr->pos, len);
01199         memmove(RSTRING_PTR(ptr->string)+ptr->pos, RSTRING_PTR(str), len);
01200         OBJ_INFECT(ptr->string, str);
01201     }
01202     OBJ_INFECT(ptr->string, self);
01203     RB_GC_GUARD(str);
01204     ptr->pos += len;
01205     return LONG2NUM(len);
01206 }
01207 
01208 /*
01209  * call-seq:
01210  *   strio << obj     -> strio
01211  *
01212  * See IO#<<.
01213  */
01214 #define strio_addstr rb_io_addstr
01215 
01216 /*
01217  * call-seq:
01218  *   strio.print()             -> nil
01219  *   strio.print(obj, ...)     -> nil
01220  *
01221  * See IO#print.
01222  */
01223 #define strio_print rb_io_print
01224 
01225 /*
01226  * call-seq:
01227  *   strio.printf(format_string [, obj, ...] )   -> nil
01228  *
01229  * See IO#printf.
01230  */
01231 #define strio_printf rb_io_printf
01232 
01233 /*
01234  * call-seq:
01235  *   strio.putc(obj)    -> obj
01236  *
01237  * See IO#putc.
01238  */
01239 static VALUE
01240 strio_putc(VALUE self, VALUE ch)
01241 {
01242     struct StringIO *ptr = writable(self);
01243     VALUE str;
01244 
01245     check_modifiable(ptr);
01246     if (RB_TYPE_P(ch, T_STRING)) {
01247         str = rb_str_substr(ch, 0, 1);
01248     }
01249     else {
01250         char c = NUM2CHR(ch);
01251         str = rb_str_new(&c, 1);
01252     }
01253     strio_write(self, str);
01254     return ch;
01255 }
01256 
01257 /*
01258  * call-seq:
01259  *   strio.puts(obj, ...)    -> nil
01260  *
01261  * See IO#puts.
01262  */
01263 #define strio_puts rb_io_puts
01264 
01265 /*
01266  * call-seq:
01267  *   strio.read([length [, outbuf]])    -> string, outbuf, or nil
01268  *
01269  * See IO#read.
01270  */
01271 static VALUE
01272 strio_read(int argc, VALUE *argv, VALUE self)
01273 {
01274     struct StringIO *ptr = readable(self);
01275     VALUE str = Qnil;
01276     long len;
01277     int binary = 0;
01278 
01279     switch (argc) {
01280       case 2:
01281         str = argv[1];
01282         if (!NIL_P(str)) {
01283             StringValue(str);
01284             rb_str_modify(str);
01285         }
01286       case 1:
01287         if (!NIL_P(argv[0])) {
01288             len = NUM2LONG(argv[0]);
01289             if (len < 0) {
01290                 rb_raise(rb_eArgError, "negative length %ld given", len);
01291             }
01292             if (len > 0 && ptr->pos >= RSTRING_LEN(ptr->string)) {
01293                 if (!NIL_P(str)) rb_str_resize(str, 0);
01294                 return Qnil;
01295             }
01296             binary = 1;
01297             break;
01298         }
01299         /* fall through */
01300       case 0:
01301         len = RSTRING_LEN(ptr->string);
01302         if (len <= ptr->pos) {
01303             if (NIL_P(str)) {
01304                 str = rb_str_new(0, 0);
01305             }
01306             else {
01307                 rb_str_resize(str, 0);
01308             }
01309             return str;
01310         }
01311         else {
01312             len -= ptr->pos;
01313         }
01314         break;
01315       default:
01316         rb_raise(rb_eArgError, "wrong number of arguments (%d for 0)", argc);
01317     }
01318     if (NIL_P(str)) {
01319         str = strio_substr(ptr, ptr->pos, len);
01320         if (binary) rb_enc_associate(str, rb_ascii8bit_encoding());
01321     }
01322     else {
01323         long rest = RSTRING_LEN(ptr->string) - ptr->pos;
01324         if (len > rest) len = rest;
01325         rb_str_resize(str, len);
01326         MEMCPY(RSTRING_PTR(str), RSTRING_PTR(ptr->string) + ptr->pos, char, len);
01327         if (binary)
01328             rb_enc_associate(str, rb_ascii8bit_encoding());
01329         else
01330             rb_enc_copy(str, ptr->string);
01331     }
01332     ptr->pos += RSTRING_LEN(str);
01333     return str;
01334 }
01335 
01336 /*
01337  * call-seq:
01338  *   strio.sysread(integer[, outbuf])    -> string
01339  *   strio.readpartial(integer[, outbuf])    -> string
01340  *
01341  * Similar to #read, but raises +EOFError+ at end of string instead of
01342  * returning +nil+, as well as IO#sysread does.
01343  */
01344 static VALUE
01345 strio_sysread(int argc, VALUE *argv, VALUE self)
01346 {
01347     VALUE val = rb_funcall2(self, rb_intern("read"), argc, argv);
01348     if (NIL_P(val)) {
01349         rb_eof_error();
01350     }
01351     return val;
01352 }
01353 
01354 /*
01355  * call-seq:
01356  *   strio.read_nonblock(integer[, outbuf [, opts]])    -> string
01357  *
01358  * Similar to #read, but raises +EOFError+ at end of string unless the
01359  * +exception: false+ option is passed in.
01360  */
01361 static VALUE
01362 strio_read_nonblock(int argc, VALUE *argv, VALUE self)
01363 {
01364     VALUE opts = Qnil, val;
01365     int no_exception = 0;
01366 
01367     rb_scan_args(argc, argv, "11:", NULL, NULL, &opts);
01368 
01369     if (!NIL_P(opts)) {
01370         argc--;
01371 
01372         if (Qfalse == rb_hash_aref(opts, sym_exception))
01373             no_exception = 1;
01374     }
01375 
01376     val = strio_read(argc, argv, self);
01377     if (NIL_P(val)) {
01378         if (no_exception)
01379             return Qnil;
01380         else
01381             rb_eof_error();
01382     }
01383 
01384     return val;
01385 }
01386 
01387 #define strio_syswrite rb_io_write
01388 
01389 static VALUE
01390 strio_syswrite_nonblock(int argc, VALUE *argv, VALUE self)
01391 {
01392     VALUE str;
01393 
01394     rb_scan_args(argc, argv, "10:", &str, NULL);
01395     return strio_syswrite(self, str);
01396 }
01397 
01398 #define strio_isatty strio_false
01399 
01400 #define strio_pid strio_nil
01401 
01402 #define strio_fileno strio_nil
01403 
01404 /*
01405  * call-seq:
01406  *   strio.length -> integer
01407  *   strio.size   -> integer
01408  *
01409  * Returns the size of the buffer string.
01410  */
01411 static VALUE
01412 strio_size(VALUE self)
01413 {
01414     VALUE string = StringIO(self)->string;
01415     if (NIL_P(string)) {
01416         rb_raise(rb_eIOError, "not opened");
01417     }
01418     return ULONG2NUM(RSTRING_LEN(string));
01419 }
01420 
01421 /*
01422  * call-seq:
01423  *   strio.truncate(integer)    -> 0
01424  *
01425  * Truncates the buffer string to at most _integer_ bytes. The *strio*
01426  * must be opened for writing.
01427  */
01428 static VALUE
01429 strio_truncate(VALUE self, VALUE len)
01430 {
01431     VALUE string = writable(self)->string;
01432     long l = NUM2LONG(len);
01433     long plen = RSTRING_LEN(string);
01434     if (l < 0) {
01435         error_inval("negative length");
01436     }
01437     rb_str_resize(string, l);
01438     if (plen < l) {
01439         MEMZERO(RSTRING_PTR(string) + plen, char, l - plen);
01440     }
01441     return len;
01442 }
01443 
01444 /*
01445  *  call-seq:
01446  *     strio.external_encoding   => encoding
01447  *
01448  *  Returns the Encoding object that represents the encoding of the file.
01449  *  If strio is write mode and no encoding is specified, returns <code>nil</code>.
01450  */
01451 
01452 static VALUE
01453 strio_external_encoding(VALUE self)
01454 {
01455     return rb_enc_from_encoding(rb_enc_get(StringIO(self)->string));
01456 }
01457 
01458 /*
01459  *  call-seq:
01460  *     strio.internal_encoding   => encoding
01461  *
01462  *  Returns the Encoding of the internal string if conversion is
01463  *  specified.  Otherwise returns nil.
01464  */
01465 
01466 static VALUE
01467 strio_internal_encoding(VALUE self)
01468 {
01469      return Qnil;
01470 }
01471 
01472 /*
01473  *  call-seq:
01474  *     strio.set_encoding(ext_enc, [int_enc[, opt]])  => strio
01475  *
01476  *  Specify the encoding of the StringIO as <i>ext_enc</i>.
01477  *  Use the default external encoding if <i>ext_enc</i> is nil.
01478  *  2nd argument <i>int_enc</i> and optional hash <i>opt</i> argument
01479  *  are ignored; they are for API compatibility to IO.
01480  */
01481 
01482 static VALUE
01483 strio_set_encoding(int argc, VALUE *argv, VALUE self)
01484 {
01485     rb_encoding* enc;
01486     VALUE str = StringIO(self)->string;
01487     VALUE ext_enc, int_enc, opt;
01488 
01489     argc = rb_scan_args(argc, argv, "11:", &ext_enc, &int_enc, &opt);
01490 
01491     if (NIL_P(ext_enc)) {
01492         enc = rb_default_external_encoding();
01493     }
01494     else {
01495         enc = rb_to_encoding(ext_enc);
01496     }
01497     rb_enc_associate(str, enc);
01498     return self;
01499 }
01500 
01501 /*
01502  * Pseudo I/O on String object.
01503  */
01504 void
01505 Init_stringio()
01506 {
01507     VALUE StringIO = rb_define_class("StringIO", rb_cData);
01508 
01509     rb_include_module(StringIO, rb_mEnumerable);
01510     rb_define_alloc_func(StringIO, strio_s_allocate);
01511     rb_define_singleton_method(StringIO, "open", strio_s_open, -1);
01512     rb_define_method(StringIO, "initialize", strio_initialize, -1);
01513     rb_define_method(StringIO, "initialize_copy", strio_copy, 1);
01514     rb_define_method(StringIO, "reopen", strio_reopen, -1);
01515 
01516     rb_define_method(StringIO, "string", strio_get_string, 0);
01517     rb_define_method(StringIO, "string=", strio_set_string, 1);
01518     rb_define_method(StringIO, "lineno", strio_get_lineno, 0);
01519     rb_define_method(StringIO, "lineno=", strio_set_lineno, 1);
01520 
01521 
01522     /* call-seq: strio.binmode -> true */
01523     rb_define_method(StringIO, "binmode", strio_binmode, 0);
01524     rb_define_method(StringIO, "close", strio_close, 0);
01525     rb_define_method(StringIO, "close_read", strio_close_read, 0);
01526     rb_define_method(StringIO, "close_write", strio_close_write, 0);
01527     rb_define_method(StringIO, "closed?", strio_closed, 0);
01528     rb_define_method(StringIO, "closed_read?", strio_closed_read, 0);
01529     rb_define_method(StringIO, "closed_write?", strio_closed_write, 0);
01530     rb_define_method(StringIO, "eof", strio_eof, 0);
01531     rb_define_method(StringIO, "eof?", strio_eof, 0);
01532     /* call-seq: strio.fcntl */
01533     rb_define_method(StringIO, "fcntl", strio_fcntl, -1);
01534     /* call-seq: strio.flush -> strio */
01535     rb_define_method(StringIO, "flush", strio_flush, 0);
01536     /* call-seq: strio.fsync -> 0 */
01537     rb_define_method(StringIO, "fsync", strio_fsync, 0);
01538     rb_define_method(StringIO, "pos", strio_get_pos, 0);
01539     rb_define_method(StringIO, "pos=", strio_set_pos, 1);
01540     rb_define_method(StringIO, "rewind", strio_rewind, 0);
01541     rb_define_method(StringIO, "seek", strio_seek, -1);
01542     rb_define_method(StringIO, "sync", strio_get_sync, 0);
01543     /* call-seq: strio.sync = boolean -> boolean */
01544     rb_define_method(StringIO, "sync=", strio_set_sync, 1);
01545     rb_define_method(StringIO, "tell", strio_tell, 0);
01546 
01547     rb_define_method(StringIO, "each", strio_each, -1);
01548     rb_define_method(StringIO, "each_line", strio_each, -1);
01549     rb_define_method(StringIO, "lines", strio_lines, -1);
01550     rb_define_method(StringIO, "each_byte", strio_each_byte, 0);
01551     rb_define_method(StringIO, "bytes", strio_bytes, 0);
01552     rb_define_method(StringIO, "each_char", strio_each_char, 0);
01553     rb_define_method(StringIO, "chars", strio_chars, 0);
01554     rb_define_method(StringIO, "each_codepoint", strio_each_codepoint, 0);
01555     rb_define_method(StringIO, "codepoints", strio_codepoints, 0);
01556     rb_define_method(StringIO, "getc", strio_getc, 0);
01557     rb_define_method(StringIO, "ungetc", strio_ungetc, 1);
01558     rb_define_method(StringIO, "ungetbyte", strio_ungetbyte, 1);
01559     rb_define_method(StringIO, "getbyte", strio_getbyte, 0);
01560     rb_define_method(StringIO, "gets", strio_gets, -1);
01561     rb_define_method(StringIO, "readlines", strio_readlines, -1);
01562     rb_define_method(StringIO, "read", strio_read, -1);
01563 
01564     rb_define_method(StringIO, "write", strio_write, 1);
01565     rb_define_method(StringIO, "putc", strio_putc, 1);
01566 
01567     /*
01568      * call-seq:
01569      *   strio.isatty -> nil
01570      *   strio.tty? -> nil
01571      *
01572      */
01573     rb_define_method(StringIO, "isatty", strio_isatty, 0);
01574     rb_define_method(StringIO, "tty?", strio_isatty, 0);
01575 
01576     /* call-seq: strio.pid -> nil */
01577     rb_define_method(StringIO, "pid", strio_pid, 0);
01578 
01579     /* call-seq: strio.fileno -> nil */
01580     rb_define_method(StringIO, "fileno", strio_fileno, 0);
01581     rb_define_method(StringIO, "size", strio_size, 0);
01582     rb_define_method(StringIO, "length", strio_size, 0);
01583     rb_define_method(StringIO, "truncate", strio_truncate, 1);
01584 
01585     rb_define_method(StringIO, "external_encoding", strio_external_encoding, 0);
01586     rb_define_method(StringIO, "internal_encoding", strio_internal_encoding, 0);
01587     rb_define_method(StringIO, "set_encoding", strio_set_encoding, -1);
01588 
01589     {
01590         VALUE mReadable = rb_define_module_under(rb_cIO, "generic_readable");
01591         rb_define_method(mReadable, "readchar", strio_readchar, 0);
01592         rb_define_method(mReadable, "readbyte", strio_readbyte, 0);
01593         rb_define_method(mReadable, "readline", strio_readline, -1);
01594         rb_define_method(mReadable, "sysread", strio_sysread, -1);
01595         rb_define_method(mReadable, "readpartial", strio_sysread, -1);
01596         rb_define_method(mReadable, "read_nonblock", strio_read_nonblock, -1);
01597         rb_include_module(StringIO, mReadable);
01598     }
01599     {
01600         VALUE mWritable = rb_define_module_under(rb_cIO, "generic_writable");
01601         rb_define_method(mWritable, "<<", strio_addstr, 1);
01602         rb_define_method(mWritable, "print", strio_print, -1);
01603         rb_define_method(mWritable, "printf", strio_printf, -1);
01604         rb_define_method(mWritable, "puts", strio_puts, -1);
01605         rb_define_method(mWritable, "syswrite", strio_syswrite, 1);
01606         rb_define_method(mWritable, "write_nonblock", strio_syswrite_nonblock, -1);
01607         rb_include_module(StringIO, mWritable);
01608     }
01609 
01610     sym_exception = ID2SYM(rb_intern("exception"));
01611 }
01612 

Generated on 19 Jul 2016 for Ruby by  doxygen 1.4.7