17 #if defined(HAVE_FCNTL_H) || defined(_WIN32) 19 #elif defined(HAVE_SYS_FCNTL_H) 20 #include <sys/fcntl.h> 23 #ifndef RB_INTEGER_TYPE_P 24 # define RB_INTEGER_TYPE_P(c) (FIXNUM_P(c) || RB_TYPE_P(c, T_BIGNUM)) 37 static VALUE strio_unget_bytes(
struct StringIO *,
const char *,
long);
39 #define IS_STRIO(obj) (rb_typeddata_is_kind_of((obj), &strio_data_type)) 40 #define error_inval(msg) (rb_syserr_fail(EINVAL, msg)) 41 #define get_enc(ptr) ((ptr)->enc ? (ptr)->enc : rb_enc_get((ptr)->string)) 67 if (--ptr->
count <= 0) {
73 strio_memsize(
const void *p)
88 #define check_strio(self) ((struct StringIO*)rb_check_typeddata((self), &strio_data_type)) 115 if (
len > rlen)
len = rlen;
118 return enc_subseq(str,
pos,
len, enc);
121 #define StringIO(obj) get_strio(obj) 123 #define STRIO_READABLE FL_USER4 124 #define STRIO_WRITABLE FL_USER5 125 #define STRIO_READWRITE (STRIO_READABLE|STRIO_WRITABLE) 127 #define STRIO_MODE_SET_P(strio, mode) \ 128 ((RBASIC(strio)->flags & STRIO_##mode) && \ 129 ((struct StringIO*)DATA_PTR(strio))->flags & FMODE_##mode) 130 #define CLOSED(strio) (!STRIO_MODE_SET_P(strio, READWRITE)) 131 #define READABLE(strio) STRIO_MODE_SET_P(strio, READABLE) 132 #define WRITABLE(strio) STRIO_MODE_SET_P(strio, WRITABLE) 134 static VALUE sym_exception;
137 readable(
VALUE strio)
147 writable(
VALUE strio)
157 check_modifiable(
struct StringIO *ptr)
165 strio_s_allocate(
VALUE klass)
181 DATA_PTR(
self) = ptr = strio_alloc();
184 return strio_init(
argc,
argv, ptr,
self);
198 trunc = flags & O_TRUNC;
231 strio_finalize(
VALUE self)
271 strio_false(
VALUE self)
281 strio_nil(
VALUE self)
291 strio_self(
VALUE self)
335 strio_get_string(
VALUE self)
368 strio_close(
VALUE self)
383 strio_close_read(
VALUE self)
401 strio_close_write(
VALUE self)
418 strio_closed(
VALUE self)
432 strio_closed_read(
VALUE self)
446 strio_closed_write(
VALUE self)
462 strio_eof(
VALUE self)
464 struct StringIO *ptr = readable(
self);
476 if (copy == orig)
return copy;
500 strio_get_lineno(
VALUE self)
520 strio_binmode(
VALUE self)
532 #define strio_fcntl strio_unimpl 534 #define strio_flush strio_self 536 #define strio_fsync strio_0 551 return strio_copy(
self, *argv);
553 return strio_init(argc, argv,
StringIO(
self),
self);
564 strio_get_pos(
VALUE self)
595 strio_rewind(
VALUE self)
635 if (amount >
LONG_MAX - offset || amount + offset < 0) {
638 ptr->
pos = amount + offset;
649 strio_get_sync(
VALUE self)
655 #define strio_set_sync strio_first 657 #define strio_tell strio_get_pos 667 strio_each_byte(
VALUE self)
669 struct StringIO *ptr = readable(
self);
684 strio_bytes(
VALUE self)
686 rb_warn(
"StringIO#bytes is deprecated; use #each_byte instead");
689 return strio_each_byte(
self);
699 strio_getc(
VALUE self)
701 struct StringIO *ptr = readable(
self);
714 return enc_subseq(str, pos, len, enc);
724 strio_getbyte(
VALUE self)
726 struct StringIO *ptr = readable(
self);
743 check_modifiable(ptr);
745 if (
pos + len > olen) {
767 struct StringIO *ptr = readable(
self);
770 check_modifiable(ptr);
780 return strio_unget_bytes(ptr, buf, len);
804 struct StringIO *ptr = readable(
self);
808 check_modifiable(ptr);
812 return strio_unget_bytes(ptr, buf, 1);
818 if (cl == 0)
return Qnil;
819 strio_unget_bytes(ptr, cp, cl);
826 strio_unget_bytes(
struct StringIO *ptr,
const char *cp,
long cl)
835 long ex = (rest < 0 ? cl-
pos : cl+rest);
839 if (rest < 0)
memmove(s + cl, s + pos, -rest);
848 if (rest > cl) memset(s + len, 0, rest - cl);
851 memcpy(s + pos, cp, cl);
863 strio_readchar(
VALUE self)
877 strio_readbyte(
VALUE self)
892 strio_each_char(
VALUE self)
898 while (!
NIL_P(c = strio_getc(
self))) {
908 strio_chars(
VALUE self)
910 rb_warn(
"StringIO#chars is deprecated; use #each_char instead");
913 return strio_each_char(
self);
924 strio_each_codepoint(
VALUE self)
933 ptr = readable(
self);
952 strio_codepoints(
VALUE self)
954 rb_warn(
"StringIO#codepoints is deprecated; use #each_codepoint instead");
957 return strio_each_codepoint(
self);
962 bm_init_skip(
long *skip,
const char *pat,
long m)
966 for (c = 0; c < (1 <<
CHAR_BIT); c++) {
970 skip[(
unsigned char)*pat++] = m;
975 bm_search(
const char *little,
long llen,
const char *big,
long blen,
const long *skip)
983 while (j >= 0 && big[k] == little[j]) {
987 if (j < 0)
return k + 1;
988 i += skip[(
unsigned char)big[i]];
1002 VALUE str, lim, opts;
1005 argc =
rb_scan_args(argc, argv,
"02:", &str, &lim, &opts);
1033 static ID keywords[1];
1045 chomp_newline_width(
const char *s,
const char *e)
1047 if (e > s && *--e ==
'\n') {
1048 if (e > s && *--e ==
'\r')
return 2;
1057 const char *s, *e, *p;
1069 if (limit > 0 && (
size_t)limit < (
size_t)(e - s)) {
1074 w = chomp_newline_width(s, e);
1076 str = strio_substr(ptr, ptr->
pos, e - s - w, enc);
1080 while (p[(p + 1 < e) && (*p ==
'\r') && 0] ==
'\n') {
1087 while ((p = memchr(p,
'\n', e - p)) && (p != e)) {
1090 w = (arg->
chomp ? 1 : 0);
1093 else if (*p ==
'\r' && p < e && p[1] ==
'\n') {
1095 w = (arg->
chomp ? 2 : 0);
1099 if (!w && arg->
chomp) {
1100 w = chomp_newline_width(s, e);
1105 if ((p = memchr(s,
RSTRING_PTR(str)[0], e - s)) != 0) {
1107 w = (arg->
chomp ? (p > s && *(p-1) ==
'\r') + 1 : 0);
1109 str = strio_substr(ptr, ptr->
pos, e - s - w, enc);
1114 for (p = s; p + n <= e; ++p) {
1116 e = p + (arg->
chomp ? 0 : n);
1124 bm_init_skip(skip, p, n);
1125 if ((pos = bm_search(p, n, s, e - s, skip)) >= 0) {
1126 e = s + pos + (arg->
chomp ? 0 : n);
1130 str = strio_substr(ptr, ptr->
pos, e - s - w, enc);
1152 struct StringIO *ptr = readable(
self);
1156 str = strio_getline(&arg, readable(
self));
1204 while (!
NIL_P(line = strio_getline(&arg, readable(
self)))) {
1216 rb_warn(
"StringIO#lines is deprecated; use #each_line instead");
1219 return strio_each(
argc,
argv,
self);
1242 while (!
NIL_P(line = strio_getline(&arg, readable(
self)))) {
1261 struct StringIO *ptr = writable(
self);
1270 if (enc != enc2 && enc != ascii8bit) {
1274 if (len == 0)
return INT2FIX(0);
1275 check_modifiable(ptr);
1280 if (ptr->
pos == olen) {
1281 if (enc == ascii8bit || enc2 == ascii8bit) {
1290 strio_extend(ptr, ptr->
pos, len);
1306 #define strio_addstr rb_io_addstr 1315 #define strio_print rb_io_print 1323 #define strio_printf rb_io_printf 1334 struct StringIO *ptr = writable(
self);
1337 check_modifiable(ptr);
1345 strio_write(
self, str);
1355 #define strio_puts rb_io_puts 1366 struct StringIO *ptr = readable(
self);
1381 if (!
NIL_P(argv[0])) {
1396 if (len <= ptr->
pos) {
1414 str = strio_substr(ptr, ptr->
pos, len, enc);
1418 if (len > rest) len = rest;
1466 val = strio_read(
argc,
argv,
self);
1478 #define strio_syswrite rb_io_write 1489 #define strio_isatty strio_false 1491 #define strio_pid strio_nil 1493 #define strio_fileno strio_nil 1503 strio_size(
VALUE self)
1506 if (
NIL_P(
string)) {
1544 strio_external_encoding(
VALUE self)
1559 strio_internal_encoding(
VALUE self)
1579 VALUE ext_enc, int_enc, opt;
1583 if (
NIL_P(ext_enc)) {
1692 rb_define_method(StringIO,
"external_encoding", strio_external_encoding, 0);
1693 rb_define_method(StringIO,
"internal_encoding", strio_internal_encoding, 0);
1713 rb_define_method(mWritable,
"write_nonblock", strio_syswrite_nonblock, -1);
#define MEMCMP(p1, p2, type, n)
int rb_enc_codelen(int c, rb_encoding *enc)
RUBY_EXTERN VALUE rb_cData
void rb_warn(const char *fmt,...)
void rb_syserr_fail(int e, const char *mesg)
void rb_enc_copy(VALUE obj1, VALUE obj2)
#define RUBY_TYPED_FREE_IMMEDIATELY
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj.
int rb_block_given_p(void)
Determines if the current method is given a block.
void rb_raise(VALUE exc, const char *fmt,...)
int rb_get_kwargs(VALUE keyword_hash, const ID *table, int required, int optional, VALUE *values)
#define TypedData_Wrap_Struct(klass, data_type, sval)
rb_encoding * rb_to_encoding(VALUE enc)
VALUE rb_enc_from_encoding(rb_encoding *encoding)
VALUE rb_ary_push(VALUE ary, VALUE item)
void rb_str_set_len(VALUE, long)
int rb_io_modestr_fmode(const char *modestr)
unsigned int rb_enc_codepoint_len(const char *p, const char *e, int *len_p, rb_encoding *enc)
char strio_flags_check[(STRIO_READABLE/FMODE_READABLE==STRIO_WRITABLE/FMODE_WRITABLE) *2 - 1]
VALUE rb_enc_associate(VALUE obj, rb_encoding *enc)
VALUE rb_io_taint_check(VALUE)
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
int rb_enc_mbclen(const char *p, const char *e, rb_encoding *enc)
void rb_include_module(VALUE klass, VALUE module)
void rb_gc_mark(VALUE ptr)
VALUE rb_ensure(VALUE(*b_proc)(ANYARGS), VALUE data1, VALUE(*e_proc)(ANYARGS), VALUE data2)
An equivalent to ensure clause.
VALUE rb_str_buf_append(VALUE, VALUE)
RUBY_EXTERN void * memmove(void *, const void *, size_t)
#define RB_TYPE_P(obj, type)
#define MEMZERO(p, type, n)
rb_encoding * rb_default_external_encoding(void)
VALUE rb_str_substr(VALUE, long, long)
int rb_io_oflags_fmode(int oflags)
VALUE rb_obj_as_string(VALUE)
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
void rb_lastline_set(VALUE)
void rb_notimplement(void)
VALUE rb_str_conv_enc(VALUE str, rb_encoding *from, rb_encoding *to)
#define MEMCPY(p1, p2, type, n)
VALUE rb_str_resize(VALUE, long)
VALUE rb_str_subseq(VALUE, long, long)
#define check_strio(self)
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
void rb_str_modify_expand(VALUE, long)
unsigned char buf[MIME_BUF_SIZE]
VALUE rb_enc_uint_chr(unsigned int code, rb_encoding *enc)
VALUE rb_call_super(int, const VALUE *)
register unsigned int len
VALUE rb_define_module_under(VALUE outer, const char *name)
#define StringValueCStr(v)
#define rb_enc_right_char_head(s, p, e, enc)
void rb_str_modify(VALUE)
rb_encoding * rb_enc_get(VALUE obj)
VALUE rb_hash_lookup2(VALUE hash, VALUE key, VALUE def)
VALUE rb_convert_type(VALUE, int, const char *, const char *)
Converts an object into another type.
VALUE rb_enumeratorize(VALUE obj, VALUE meth, int argc, const VALUE *argv)
VALUE rb_check_string_type(VALUE)
VALUE rb_class_new_instance(int, const VALUE *, VALUE)
Allocates and initializes an instance of klass.
#define RETURN_ENUMERATOR(obj, argc, argv)
#define SafeStringValue(v)
VALUE rb_enc_str_new(const char *, long, rb_encoding *)
RUBY_EXTERN VALUE rb_eIOError
rb_encoding * rb_ascii8bit_encoding(void)
#define rb_intern_const(str)
#define rb_enc_mbcput(c, buf, enc)
#define RB_INTEGER_TYPE_P(obj)
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
VALUE rb_enc_str_buf_cat(VALUE str, const char *ptr, long len, rb_encoding *enc)
VALUE rb_str_new(const char *, long)