static VALUE rb_libarchive_reader_close(VALUE self) { struct rb_libarchive_archive_container *p; Data_Get_Struct(self, struct rb_libarchive_archive_container, p); Check_Archive(p); rb_libarchive_reader_close0(p); return Qnil; }
static VALUE zipruby_archive_replace_function(int argc, VALUE *argv, VALUE self) { VALUE index, flags, mtime; struct zipruby_archive *p_archive; struct zip_source *zsource; struct read_proc *z; int i_index, i_flags = 0; rb_scan_args(argc, argv, "12", &index, &mtime, &flags); rb_need_block(); if (TYPE(index) != T_STRING && !FIXNUM_P(index)) { rb_raise(rb_eTypeError, "wrong argument type %s (expected Fixnum or String)", rb_class2name(CLASS_OF(index))); } if (NIL_P(mtime)) { mtime = rb_funcall(rb_cTime, rb_intern("now"), 0); } else if (!rb_obj_is_instance_of(mtime, rb_cTime)) { rb_raise(rb_eTypeError, "wrong argument type %s (expected Time)", rb_class2name(CLASS_OF(mtime))); } if (!NIL_P(flags)) { i_flags = NUM2INT(flags); } Data_Get_Struct(self, struct zipruby_archive, p_archive); Check_Archive(p_archive); if (FIXNUM_P(index)) { i_index = NUM2INT(index); } else if ((i_index = zip_name_locate(p_archive->archive, RSTRING_PTR(index), i_flags)) == -1) { rb_raise(Error, "Replace file failed - %s: Archive does not contain a file", RSTRING_PTR(index)); } if ((z = malloc(sizeof(struct read_proc))) == NULL) { zip_unchange_all(p_archive->archive); zip_unchange_archive(p_archive->archive); rb_raise(rb_eRuntimeError, "Replace failed at %d: Cannot allocate memory", i_index); } z->proc = rb_block_proc(); rb_ary_push(p_archive->sources, z->proc); z->mtime = TIME2LONG(mtime); if ((zsource = zip_source_proc(p_archive->archive, z)) == NULL) { free(z); rb_raise(Error, "Replace failed at %d: %s", i_index, zip_strerror(p_archive->archive)); } if (zip_replace(p_archive->archive, i_index, zsource) == -1) { zip_source_free(zsource); zip_unchange_all(p_archive->archive); zip_unchange_archive(p_archive->archive); rb_raise(Error, "Replace failed at %d: %s", i_index, zip_strerror(p_archive->archive)); } return Qnil; }
static VALUE zipruby_archive_add_io(int argc, VALUE *argv, VALUE self) { VALUE name, file, mtime; struct zipruby_archive *p_archive; struct zip_source *zsource; struct read_io *z; rb_scan_args(argc, argv, "11", &name, &file); if (NIL_P(file)) { file = name; name = Qnil; } Check_IO(file); if (NIL_P(name)) { if (rb_obj_is_kind_of(file, rb_cFile)) { name = rb_funcall(rb_cFile, rb_intern("basename"), 1, rb_funcall(file, rb_intern("path"), 0)); } else { rb_raise(rb_eRuntimeError, "Add io failed - %s: Entry name is not given", RSTRING(rb_inspect(file))); } } if (rb_obj_is_kind_of(file, rb_cFile)) { mtime = rb_funcall(file, rb_intern("mtime"), 0); } else { mtime = rb_funcall(rb_cTime, rb_intern("now"), 0); } Data_Get_Struct(self, struct zipruby_archive, p_archive); Check_Archive(p_archive); if ((z = malloc(sizeof(struct read_io))) == NULL) { zip_unchange_all(p_archive->archive); zip_unchange_archive(p_archive->archive); rb_raise(rb_eRuntimeError, "Add io failed - %s: Cannot allocate memory", RSTRING(rb_inspect(file))); } z->io = file; rb_ary_push(p_archive->sources, file); z->mtime = TIME2LONG(mtime); if ((zsource = zip_source_io(p_archive->archive, z)) == NULL) { free(z); rb_raise(Error, "Add io failed - %s: %s", RSTRING(rb_inspect(file)), zip_strerror(p_archive->archive)); } if (zip_add(p_archive->archive, RSTRING_PTR(name), zsource) == -1) { zip_source_free(zsource); zip_unchange_all(p_archive->archive); zip_unchange_archive(p_archive->archive); rb_raise(Error, "Add io failed - %s: %s", RSTRING_PTR(name), zip_strerror(p_archive->archive)); } return Qnil; }
static VALUE zipruby_archive_num_files(VALUE self) { struct zipruby_archive *p_archive; int num_files; Data_Get_Struct(self, struct zipruby_archive, p_archive); Check_Archive(p_archive); num_files = zip_get_num_files(p_archive->archive); return INT2NUM(num_files); }
static VALUE zipruby_archive_unchange(VALUE self) { struct zipruby_archive *p_archive; Data_Get_Struct(self, struct zipruby_archive, p_archive); Check_Archive(p_archive); if (zip_unchange_archive(p_archive->archive) == -1) { rb_raise(Error, "Unchange archive failed: %s", zip_strerror(p_archive->archive)); } return Qnil; }
static VALUE zipruby_archive_funchange(VALUE self, VALUE index) { struct zipruby_archive *p_archive; Data_Get_Struct(self, struct zipruby_archive, p_archive); Check_Archive(p_archive); if (zip_unchange(p_archive->archive, NUM2INT(index)) == -1) { zip_unchange_all(p_archive->archive); zip_unchange_archive(p_archive->archive); rb_raise(Error, "Unchange file failed at %d: %s", NUM2INT(index), zip_strerror(p_archive->archive)); } return Qnil; }
static VALUE zipruby_archive_replace_buffer(int argc, VALUE *argv, VALUE self) { struct zipruby_archive *p_archive; struct zip_source *zsource; VALUE index, source, flags; int i_index, i_flags = 0; char *data; size_t len; rb_scan_args(argc, argv, "21", &index, &source, &flags); if (TYPE(index) != T_STRING && !FIXNUM_P(index)) { rb_raise(rb_eTypeError, "wrong argument type %s (expected Fixnum or String)", rb_class2name(CLASS_OF(index))); } if (!NIL_P(flags)) { i_flags = NUM2INT(flags); } Check_Type(source, T_STRING); Data_Get_Struct(self, struct zipruby_archive, p_archive); Check_Archive(p_archive); if (FIXNUM_P(index)) { i_index = NUM2INT(index); } else if ((i_index = zip_name_locate(p_archive->archive, RSTRING_PTR(index), i_flags)) == -1) { rb_raise(Error, "Replace file failed - %s: Archive does not contain a file", RSTRING_PTR(index)); } len = RSTRING_LEN(source); if ((data = malloc(len)) == NULL) { rb_raise(rb_eRuntimeError, "Replace file failed: Cannot allocate memory"); } memcpy(data, RSTRING_PTR(source), len); if ((zsource = zip_source_buffer(p_archive->archive, data, len, 1)) == NULL) { free(data); rb_raise(Error, "Replace file failed at %d: %s", i_index, zip_strerror(p_archive->archive)); } if (zip_replace(p_archive->archive, i_index, zsource) == -1) { zip_source_free(zsource); zip_unchange_all(p_archive->archive); zip_unchange_archive(p_archive->archive); rb_raise(Error, "Replace file failed at %d: %s", i_index, zip_strerror(p_archive->archive)); } return Qnil; }
static VALUE zipruby_archive_frename(VALUE self, VALUE index, VALUE name) { struct zipruby_archive *p_archive; Check_Type(name, T_STRING); Data_Get_Struct(self, struct zipruby_archive, p_archive); Check_Archive(p_archive); if (zip_rename(p_archive->archive, NUM2INT(index), RSTRING_PTR(name)) == -1) { zip_unchange_all(p_archive->archive); zip_unchange_archive(p_archive->archive); rb_raise(Error, "Rename file failed at %d: %s", NUM2INT(index), zip_strerror(p_archive->archive)); } return Qnil; }
static VALUE rb_libarchive_writer_write_header(VALUE self, VALUE v_entry) { struct rb_libarchive_archive_container *pa; struct rb_libarchive_entry_container *pae; Check_Class(v_entry, rb_cArchiveEntry); Data_Get_Struct(self, struct rb_libarchive_archive_container, pa); Check_Archive(pa); Data_Get_Struct(v_entry, struct rb_libarchive_entry_container, pae); Check_Entry(pae); if (archive_write_header(pa->ar, pae->ae) != ARCHIVE_OK) { rb_raise(rb_eArchiveError, "Write header failed: %s", archive_error_string(pa->ar)); } return Qnil; }
static VALUE zipruby_archive_add_dir(VALUE self, VALUE name) { struct zipruby_archive *p_archive; Check_Type(name, T_STRING); Data_Get_Struct(self, struct zipruby_archive, p_archive); Check_Archive(p_archive); if (zip_add_dir(p_archive->archive, RSTRING_PTR(name)) == -1) { zip_unchange_all(p_archive->archive); zip_unchange_archive(p_archive->archive); rb_raise(Error, "Add dir failed - %s: %s", RSTRING_PTR(name), zip_strerror(p_archive->archive)); } return Qnil; }
static VALUE zipruby_archive_locate_name(int argc, VALUE *argv, VALUE self) { VALUE fname, flags; struct zipruby_archive *p_archive; int i_flags = 0; rb_scan_args(argc, argv, "11", &fname, &flags); Check_Type(fname, T_STRING); if (!NIL_P(flags)) { i_flags = NUM2INT(flags); } Data_Get_Struct(self, struct zipruby_archive, p_archive); Check_Archive(p_archive); return INT2NUM(zip_name_locate(p_archive->archive, RSTRING_PTR(fname), i_flags)); }
static VALUE zipruby_archive_encrypt(VALUE self, VALUE password) { VALUE retval; struct zipruby_archive *p_archive; long pwdlen; int changed; zip_uint64_t survivors; int errorp; Check_Type(password, T_STRING); pwdlen = RSTRING_LEN(password); if (pwdlen < 1) { rb_raise(Error, "Encrypt archive failed: Password is empty"); } else if (pwdlen > 0xff) { rb_raise(Error, "Encrypt archive failed: Password is too long"); } Data_Get_Struct(self, struct zipruby_archive, p_archive); Check_Archive(p_archive); changed = _zip_changed(p_archive->archive, &survivors); if (zip_close(p_archive->archive) == -1) { zip_unchange_all(p_archive->archive); zip_unchange_archive(p_archive->archive); rb_raise(Error, "Encrypt archive failed: %s", zip_strerror(p_archive->archive)); } if (!NIL_P(p_archive->buffer) && changed) { rb_funcall(p_archive->buffer, rb_intern("replace"), 1, rb_funcall(self, rb_intern("read"), 0)); } p_archive->archive = NULL; p_archive->flags = (p_archive->flags & ~(ZIP_CREATE | ZIP_EXCL)); retval = zipruby_archive_s_encrypt(Archive, p_archive->path, password); if ((p_archive->archive = zip_open(RSTRING_PTR(p_archive->path), p_archive->flags, &errorp)) == NULL) { char errstr[ERRSTR_BUFSIZE]; zip_error_to_str(errstr, ERRSTR_BUFSIZE, errorp, errno); rb_raise(Error, "Encrypt archive failed: %s", errstr); } return retval; }
static VALUE zipruby_archive_add_function(int argc, VALUE *argv, VALUE self) { VALUE name, mtime; struct zipruby_archive *p_archive; struct zip_source *zsource; struct read_proc *z; rb_scan_args(argc, argv, "11", &name, &mtime); rb_need_block(); Check_Type(name, T_STRING); if (NIL_P(mtime)) { mtime = rb_funcall(rb_cTime, rb_intern("now"), 0); } else if (!rb_obj_is_instance_of(mtime, rb_cTime)) { rb_raise(rb_eTypeError, "wrong argument type %s (expected Time)", rb_class2name(CLASS_OF(mtime))); } Data_Get_Struct(self, struct zipruby_archive, p_archive); Check_Archive(p_archive); if ((z = malloc(sizeof(struct read_proc))) == NULL) { zip_unchange_all(p_archive->archive); zip_unchange_archive(p_archive->archive); rb_raise(rb_eRuntimeError, "Add failed - %s: Cannot allocate memory", RSTRING_PTR(name)); } z->proc = rb_block_proc(); rb_ary_push(p_archive->sources, z->proc); z->mtime = TIME2LONG(mtime); if ((zsource = zip_source_proc(p_archive->archive, z)) == NULL) { free(z); rb_raise(Error, "Add failed - %s: %s", RSTRING_PTR(name), zip_strerror(p_archive->archive)); } if (zip_add(p_archive->archive, RSTRING_PTR(name), zsource) == -1) { zip_source_free(zsource); zip_unchange_all(p_archive->archive); zip_unchange_archive(p_archive->archive); rb_raise(Error, "Add file failed - %s: %s", RSTRING_PTR(name), zip_strerror(p_archive->archive)); } return Qnil; }
static VALUE zipruby_archive_get_fcomment(int argc, VALUE *argv, VALUE self) { VALUE index, flags; struct zipruby_archive *p_archive; const char *comment; int lenp, i_flags = 0; rb_scan_args(argc, argv, "11", &index, &flags); if (!NIL_P(flags)) { i_flags = NUM2INT(flags); } Data_Get_Struct(self, struct zipruby_archive, p_archive); Check_Archive(p_archive); // XXX: How is the error checked? comment = zip_get_file_comment(p_archive->archive, NUM2INT(index), &lenp, i_flags); return comment ? rb_str_new(comment, lenp) : Qnil; }
static VALUE zipruby_archive_add_or_replace_file(int argc, VALUE *argv, VALUE self) { VALUE name, fname, flags; struct zipruby_archive *p_archive; int index, i_flags = 0; rb_scan_args(argc, argv, "12", &name, &fname, &flags); if (NIL_P(flags) && FIXNUM_P(fname)) { flags = fname; fname = Qnil; } if (NIL_P(fname)) { fname = name; name = Qnil; } Check_Type(fname, T_STRING); if (NIL_P(name)) { name = rb_funcall(rb_cFile, rb_intern("basename"), 1, fname); } if (!NIL_P(flags)) { i_flags = NUM2INT(flags); } Check_Type(name, T_STRING); Data_Get_Struct(self, struct zipruby_archive, p_archive); Check_Archive(p_archive); index = zip_name_locate(p_archive->archive, RSTRING_PTR(name), i_flags); if (index >= 0) { VALUE _args[] = { INT2NUM(index), fname }; return zipruby_archive_replace_file(2, _args, self); } else { VALUE _args[] = { name, fname }; return zipruby_archive_add_file(2, _args, self); } }
static VALUE zipruby_stat_initialize(int argc, VALUE *argv, VALUE self) { VALUE archive, index, flags; struct zipruby_archive *p_archive; struct zipruby_stat *p_stat; char *fname = NULL; int i_index = -1, i_flags = 0; rb_scan_args(argc, argv, "21", &archive, &index, &flags); if (!rb_obj_is_instance_of(archive, Archive)) { rb_raise(rb_eTypeError, "wrong argument type %s (expected ZipRuby::Archive)", rb_class2name(CLASS_OF(archive))); } switch (TYPE(index)) { case T_STRING: fname = RSTRING_PTR(index); break; case T_FIXNUM: i_index = NUM2INT(index); break; default: rb_raise(rb_eTypeError, "wrong argument type %s (expected String or Fixnum)", rb_class2name(CLASS_OF(index))); } if (!NIL_P(flags)) { i_flags = NUM2INT(flags); } Data_Get_Struct(archive, struct zipruby_archive, p_archive); Check_Archive(p_archive); Data_Get_Struct(self, struct zipruby_stat, p_stat); if (fname) { if (zip_stat(p_archive->archive, fname, i_flags, p_stat->sb) != 0) { rb_raise(Error, "Obtain file status failed - %s: %s", fname, zip_strerror(p_archive->archive)); } } else { if (zip_stat_index(p_archive->archive, i_index, i_flags, p_stat->sb) != 0) { rb_raise(Error, "Obtain file status failed at %d: %s", i_index, zip_strerror(p_archive->archive)); } } return Qnil; }
static VALUE zipruby_archive_get_name(int argc, VALUE *argv, VALUE self) { VALUE index, flags; struct zipruby_archive *p_archive; int i_flags = 0; const char *name; rb_scan_args(argc, argv, "11", &index, &flags); Check_Type(index, T_FIXNUM); if (!NIL_P(flags)) { i_flags = NUM2INT(flags); } Data_Get_Struct(self, struct zipruby_archive, p_archive); Check_Archive(p_archive); if ((name = zip_get_name(p_archive->archive, NUM2INT(index), i_flags)) == NULL) { rb_raise(Error, "Get name failed at %d: %s", NUM2INT(index), zip_strerror(p_archive->archive)); } return (name != NULL) ? rb_str_new2(name) : Qnil; }
static VALUE rb_libarchive_reader_next_header(VALUE self) { struct rb_libarchive_archive_container *p; struct archive_entry *ae; int r; Data_Get_Struct(self, struct rb_libarchive_archive_container, p); Check_Archive(p); if (p->eof) { return Qnil; } r = archive_read_next_header(p->ar, &ae); if (r == ARCHIVE_EOF) { p->eof = 1; return Qnil; } else if (r != ARCHIVE_OK) { rb_raise(rb_eArchiveError, "Fetch entry failed: %s", archive_error_string(p->ar)); } return rb_libarchive_entry_new(ae, 0); }
static VALUE zipruby_archive_set_fcomment(VALUE self, VALUE index, VALUE comment) { struct zipruby_archive *p_archive; char *s_comment = NULL; int len = 0; if (!NIL_P(comment)) { Check_Type(comment, T_STRING); s_comment = RSTRING_PTR(comment); len = RSTRING_LEN(comment); } Data_Get_Struct(self, struct zipruby_archive, p_archive); Check_Archive(p_archive); if (zip_set_file_comment(p_archive->archive, NUM2INT(index), s_comment, len) == -1) { zip_unchange_all(p_archive->archive); zip_unchange_archive(p_archive->archive); rb_raise(Error, "Comment file failed at %d: %s", NUM2INT(index), zip_strerror(p_archive->archive)); } return Qnil; }
static VALUE zipruby_archive_each(VALUE self) { struct zipruby_archive *p_archive; int i, num_files; Data_Get_Struct(self, struct zipruby_archive, p_archive); Check_Archive(p_archive); num_files = zip_get_num_files(p_archive->archive); for (i = 0; i < num_files; i++) { VALUE file; int status; file = rb_funcall(File, rb_intern("new"), 2, self, INT2NUM(i)); rb_protect(rb_yield, file, &status); rb_funcall(file, rb_intern("close"), 0); if (status != 0) { rb_jump_tag(status); } } return Qnil; }
static VALUE zipruby_archive_commit(VALUE self) { struct zipruby_archive *p_archive; int changed; zip_uint64_t survivors; int errorp; Data_Get_Struct(self, struct zipruby_archive, p_archive); Check_Archive(p_archive); changed = _zip_changed(p_archive->archive, &survivors); if (zip_close(p_archive->archive) == -1) { zip_unchange_all(p_archive->archive); zip_unchange_archive(p_archive->archive); rb_raise(Error, "Commit archive failed: %s", zip_strerror(p_archive->archive)); } if (!NIL_P(p_archive->sources)){ rb_ary_clear(p_archive->sources); } if (!NIL_P(p_archive->buffer) && changed) { rb_funcall(p_archive->buffer, rb_intern("replace"), 1, rb_funcall(self, rb_intern("read"), 0)); } p_archive->archive = NULL; p_archive->flags = (p_archive->flags & ~(ZIP_CREATE | ZIP_EXCL)); if ((p_archive->archive = zip_open(RSTRING_PTR(p_archive->path), p_archive->flags, &errorp)) == NULL) { char errstr[ERRSTR_BUFSIZE]; zip_error_to_str(errstr, ERRSTR_BUFSIZE, errorp, errno); rb_raise(Error, "Commit archive failed: %s", errstr); } return Qnil; }
static VALUE zipruby_archive_add_or_replace_buffer(int argc, VALUE *argv, VALUE self) { struct zipruby_archive *p_archive; VALUE name, source, flags; int index, i_flags = 0; rb_scan_args(argc, argv, "21", &name, &source, &flags); if (!NIL_P(flags)) { i_flags = NUM2INT(flags); } Check_Type(name, T_STRING); Data_Get_Struct(self, struct zipruby_archive, p_archive); Check_Archive(p_archive); index = zip_name_locate(p_archive->archive, RSTRING_PTR(name), i_flags); if (index >= 0) { VALUE _args[] = { INT2NUM(index), source }; return zipruby_archive_replace_buffer(2, _args, self); } else { return zipruby_archive_add_buffer(self, name, source); } }
static VALUE zipruby_archive_update(int argc, VALUE *argv, VALUE self) { struct zipruby_archive *p_archive, *p_srcarchive; VALUE srcarchive, flags; int i, num_files, i_flags = 0; rb_scan_args(argc, argv, "11", &srcarchive, &flags); if (!rb_obj_is_instance_of(srcarchive, Archive)) { rb_raise(rb_eTypeError, "wrong argument type %s (expected Zip::Archive)", rb_class2name(CLASS_OF(srcarchive))); } if (!NIL_P(flags)) { i_flags = NUM2INT(flags); } Data_Get_Struct(self, struct zipruby_archive, p_archive); Check_Archive(p_archive); Data_Get_Struct(srcarchive, struct zipruby_archive, p_srcarchive); Check_Archive(p_srcarchive); num_files = zip_get_num_files(p_srcarchive->archive); for (i = 0; i < num_files; i++) { struct zip_source *zsource; struct zip_file *fzip; struct zip_stat sb; char *buf; const char *name; int index, error; zip_stat_init(&sb); if (zip_stat_index(p_srcarchive->archive, i, 0, &sb)) { zip_unchange_all(p_archive->archive); zip_unchange_archive(p_archive->archive); rb_raise(Error, "Update archive failed: %s", zip_strerror(p_srcarchive->archive)); } if ((buf = malloc(sb.size)) == NULL) { zip_unchange_all(p_archive->archive); zip_unchange_archive(p_archive->archive); rb_raise(rb_eRuntimeError, "Update archive failed: Cannot allocate memory"); } fzip = zip_fopen_index(p_srcarchive->archive, i, 0); if (fzip == NULL) { free(buf); zip_unchange_all(p_archive->archive); zip_unchange_archive(p_archive->archive); rb_raise(Error, "Update archive failed: %s", zip_strerror(p_srcarchive->archive)); } if (zip_fread(fzip, buf, sb.size) == -1) { free(buf); zip_fclose(fzip); zip_unchange_all(p_archive->archive); zip_unchange_archive(p_archive->archive); rb_raise(Error, "Update archive failed: %s", zip_file_strerror(fzip)); } if ((error = zip_fclose(fzip)) != 0) { char errstr[ERRSTR_BUFSIZE]; free(buf); zip_unchange_all(p_archive->archive); zip_unchange_archive(p_archive->archive); zip_error_to_str(errstr, ERRSTR_BUFSIZE, error, errno); rb_raise(Error, "Update archive failed: %s", errstr); } if ((zsource = zip_source_buffer(p_archive->archive, buf, sb.size, 1)) == NULL) { free(buf); zip_unchange_all(p_archive->archive); zip_unchange_archive(p_archive->archive); rb_raise(Error, "Update archive failed: %s", zip_strerror(p_archive->archive)); } if ((name = zip_get_name(p_srcarchive->archive, i, 0)) == NULL) { zip_source_free(zsource); zip_unchange_all(p_archive->archive); zip_unchange_archive(p_archive->archive); rb_raise(Error, "Update archive failed: %s", zip_strerror(p_srcarchive->archive)); } index = zip_name_locate(p_archive->archive, name, i_flags); if (index >= 0) { if (zip_replace(p_archive->archive, i, zsource) == -1) { zip_source_free(zsource); zip_unchange_all(p_archive->archive); zip_unchange_archive(p_archive->archive); rb_raise(Error, "Update archive failed: %s", zip_strerror(p_archive->archive)); } } else { if (zip_add(p_archive->archive, name, zsource) == -1) { zip_source_free(zsource); zip_unchange_all(p_archive->archive); zip_unchange_archive(p_archive->archive); rb_raise(Error, "Update archive failed: %s", zip_strerror(p_archive->archive)); } } } return Qnil; }
static VALUE rb_libarchive_reader_header_position(VALUE self) { struct rb_libarchive_archive_container *p; Data_Get_Struct(self, struct rb_libarchive_archive_container, p); Check_Archive(p); return LONG2NUM((long) archive_read_header_position(p->ar)); }
static VALUE rb_libarchive_reader_read_data(int argc, VALUE *argv, VALUE self) { VALUE v_size; struct rb_libarchive_archive_container *p; char *buff; size_t size = DATA_BUFFER_SIZE; ssize_t n; rb_scan_args(argc, argv, "01", &v_size); if (!NIL_P(v_size)) { size = NUM2INT(v_size); } Data_Get_Struct(self, struct rb_libarchive_archive_container, p); Check_Archive(p); if (p->eof) { return Qnil; } if (rb_block_given_p()) { ssize_t len = 0; int status = 0; buff = xmalloc(size); while ((n = archive_read_data(p->ar, buff, size)) > 0) { rb_protect(rb_yield, rb_str_new(buff, n), &status); if (status != 0) { break; } len += n; } xfree(buff); if (status != 0) { rb_jump_tag(status); } if (n < 0) { rb_raise(rb_eArchiveError, "Read data failed: %s", archive_error_string(p->ar)); } return LONG2NUM(len); } else { VALUE retval = rb_str_new("", 0); buff = xmalloc(size); while ((n = archive_read_data(p->ar, buff, size)) > 0) { rb_str_cat(retval, buff, n); } xfree(buff); if (n < 0) { rb_raise(rb_eArchiveError, "Read data failed: %s", archive_error_string(p->ar)); } return retval; } }