module IOPositioningReadWrite::StringIO
Public Instance Methods
readat(offset) → nil or string
click to toggle source
readat(offset, length) → nil or string
readat(offset, length, buffer) → nil or buffer
IO#readat
と同じ。
ただし、例外の搬出は挙動が異なります。このあたりは将来的に (200年後くらいには) 改善される見込みです。
処理中は Ruby のすべてのスレッドが停止します (GVL を開放しないため)。
static VALUE strio_readat(int argc, VALUE argv[], VALUE io) { VALUE offset, length = Qnil, buffer = Qnil; rb_scan_args(argc, argv, "12", &offset, &length, &buffer); VALUE str = strio_getread(io); VALUE tmp = Qnil; if (NIL_P(buffer)) { tmp = buffer = rb_str_buf_new(0); } ssize_t lenmax = RSTRING_LEN(str); ssize_t len = NIL_P(length) ? lenmax : NUM2SSIZET(length); ssize_t off = NUM2SSIZET(offset); if (off < 0) { off += lenmax; } if (len == 0) { if (NIL_P(buffer)) { buffer = rb_str_new(0, 0); } else { rb_str_modify(buffer); rb_str_set_len(buffer, 0); } OBJ_INFECT(buffer, io); return buffer; } if (off >= lenmax) { return Qnil; } if (off + len < 0) { rb_raise(rb_eRangeError, "offset and length are too small or too large"); } if (off + len > lenmax) { len = lenmax - off; } StringValue(buffer); rb_str_modify(buffer); rb_str_resize(buffer, len); rb_str_set_len(buffer, len); memcpy(RSTRING_PTR(buffer), RSTRING_PTR(str) + off, len); OBJ_INFECT(buffer, str); return buffer; }
writeat(offset, buffer) → integer
click to toggle source
IO#writeat
と同じ。
ただし、例外の搬出は挙動が異なります。このあたりは将来的に (200年後くらいには) 改善される見込みです。
処理中は Ruby のすべてのスレッドが停止します (GVL を開放しないため)。
static VALUE strio_writeat(VALUE io, VALUE offset, VALUE buffer) { rb_secure(4); VALUE str = strio_getwrite(io); ssize_t off = NUM2SSIZET(offset); if (off < 0) { NUM2SSIZET(SIZET2NUM(off)); } // EXCEPTION! StringValue(buffer); ssize_t len = RSTRING_LEN(buffer); if (len < 0) { NUM2SSIZET(SIZET2NUM(len)); } // EXCEPTION! if (off + len < 0) { rb_raise(rb_eRangeError, "offset and buffer size are too large"); } if (off + len > RSTRING_LEN(str)) { ssize_t p = RSTRING_LEN(str); rb_str_modify(buffer); rb_str_resize(str, off + len); rb_str_set_len(str, off + len); if (off > p) { memset(RSTRING_PTR(str) + p, 0, off - p); } } else { rb_str_modify(str); } memcpy(RSTRING_PTR(str) + off, RSTRING_PTR(buffer), len); return SSIZET2NUM(len); }