static VALUE rb_smbdir_read(VALUE self) { RB_SMBFILE_DATA_FROM_OBJ(self, data); RB_SMBFILE_DATA_CLOSED(data); smbc_readdir_fn fn; struct smbc_dirent *smbcdent; fn = smbc_getFunctionReaddir(data->smbcctx); errno = 0; smbcdent = (*fn)(data->smbcctx, data->smbcfile); if (smbcdent == NULL) { if (errno) { rb_sys_fail(data->url); } return Qnil; } VALUE args[4]; args[0] = rb_external_str_new_with_enc(smbcdent->name, strlen(smbcdent->name), data->enc); args[1] = INT2NUM(smbcdent->smbc_type); args[2] = rb_str_new2(data->url); rb_str_cat2(args[2], "/"); /* FIXME: Unless if the last char is not "/" */ rb_str_cat2(args[2], smbcdent->name); /* FIXME: Must be URL encoding */ args[3] = rb_str_new(smbcdent->comment, smbcdent->commentlen); VALUE entry_obj = rb_class_new_instance(4, args, rb_cSMBDirEntry); return entry_obj; }
static VALUE rb_smbfile_seek(int argc, VALUE *argv, VALUE self) { RB_SMBFILE_DATA_FROM_OBJ(self, data); RB_SMBFILE_DATA_CLOSED(data); VALUE whence_num; rb_scan_args(argc, argv, "11", NULL, &whence_num); off_t offset = NUM2OFFT(argv[0]); int whence = NIL_P(whence_num) ? SEEK_SET : NUM2INT(whence_num); switch (whence) { case SEEK_SET: data->pos = offset; break; case SEEK_CUR: if (offset < 0 && offset < -data->pos) { errno = EINVAL; rb_sys_fail(data->url); } data->pos += offset; break; case SEEK_END: /* FIXME */ rb_raise(rb_eNotImpError, "SEEK_END"); break; default: errno = EINVAL; rb_sys_fail(data->url); break; } rb_smbfile_seek_by_data(data); return self; }
static VALUE rb_smbfile_pos(VALUE self) { RB_SMBFILE_DATA_FROM_OBJ(self, data); RB_SMBFILE_DATA_CLOSED(data); return SIZET2NUM(data->pos); }
static VALUE rb_smbdir_close(VALUE self) { RB_SMBFILE_DATA_FROM_OBJ(self, data); RB_SMBFILE_DATA_CLOSED(data); RB_SMB_DEBUG("data=%p smbcctx=%p smbcfile=%p\n", data, data->smbcctx, data->smbcfile); rb_smbdir_close_and_deref_by_data(data); return self; }
static VALUE rb_smbfile_read(int argc, VALUE *argv, VALUE self) { RB_SMBFILE_DATA_FROM_OBJ(self, data); RB_SMBFILE_DATA_CLOSED(data); ssize_t req_read_size; VALUE str = rb_str_new2(""); rb_smbfile_readable_p_by_data(data); if (argc == 0) { req_read_size = -1; } else { req_read_size = NUM2SSIZET(argv[0]); if (req_read_size == 0) { return str; /* Return empty string */ } if (req_read_size < 0) { rb_raise(rb_eArgError, "Negative length given: %zd", req_read_size); } } while (req_read_size) { ssize_t buffer_read_size = data->buffer_used_size - data->buffer_pos; if (buffer_read_size == 0) { /* No remained data in buffer */ rb_smbfile_read_by_data(data); if (data->eof) { /* No remained data in file */ return (req_read_size > 0 && RSTRING_LEN(str) == 0) ? Qnil : str; } buffer_read_size = data->buffer_used_size - data->buffer_pos; } if (req_read_size > 0 && buffer_read_size > req_read_size) { buffer_read_size = req_read_size; } rb_str_cat(str, data->buffer + data->buffer_pos, buffer_read_size); data->pos += buffer_read_size; data->buffer_pos += buffer_read_size; if (req_read_size > 0) { req_read_size -= buffer_read_size; } } return str; }
static VALUE rb_smbdir_seek(VALUE self, VALUE offset_num) { RB_SMBFILE_DATA_FROM_OBJ(self, data); RB_SMBFILE_DATA_CLOSED(data); smbc_lseekdir_fn fn; off_t offset = (off_t)NUM2LONG(offset_num); fn = smbc_getFunctionLseekdir(data->smbcctx); errno = 0; if ((*fn)(data->smbcctx, data->smbcfile, offset) == -1) { rb_sys_fail(data->url); } return self; }
static VALUE rb_smbdir_tell(VALUE self) { RB_SMBFILE_DATA_FROM_OBJ(self, data); RB_SMBFILE_DATA_CLOSED(data); smbc_telldir_fn fn; off_t offset; fn = smbc_getFunctionTelldir(data->smbcctx); errno = 0; offset = (*fn)(data->smbcctx, data->smbcfile); if (offset == (off_t)-1) { if (errno != 0) { rb_sys_fail(data->url); } } return LONG2NUM(offset); }
static VALUE rb_smbfile_eof_p(VALUE self) { RB_SMBFILE_DATA_FROM_OBJ(self, data); RB_SMBFILE_DATA_CLOSED(data); if (data->buffer_used_size - data->buffer_pos > 0) { /* Remained data exist in buffer */ return Qfalse; } /* Try to read from file to buffer */ rb_smbfile_read_by_data(data); if (data->buffer_used_size - data->buffer_pos > 0) { /* Remained data exist in buffer */ return Qfalse; } return Qtrue; }