static int decompressor_xz_reset(struct microfs_sb_info* sbi, void* data) { struct decompressor_xz_data* xzdat = data; xz_dec_reset(xzdat->xz_state); return 0; }
static int xz_dec_test_open(struct inode *i, struct file *f) { if (device_is_open) return -EBUSY; device_is_open = true; xz_dec_reset(state); ret = XZ_OK; crc = 0xFFFFFFFF; buffers.in_pos = 0; buffers.in_size = 0; buffers.out_pos = 0; printk(KERN_INFO DEVICE_NAME ": opened\n"); return 0; }
static grub_ssize_t grub_xzio_read (grub_file_t file, char *buf, grub_size_t len) { grub_ssize_t ret = 0; grub_ssize_t readret; enum xz_ret xzret; grub_xzio_t xzio = file->data; grub_off_t current_offset; /* If seek backward need to reset decoder and start from beginning of file. TODO Possible improvement by jumping blocks. */ if (file->offset < xzio->saved_offset) { xz_dec_reset (xzio->dec); xzio->saved_offset = 0; xzio->buf.out_pos = 0; xzio->buf.in_pos = 0; xzio->buf.in_size = 0; grub_file_seek (xzio->file, 0); } current_offset = xzio->saved_offset; while (len > 0) { xzio->buf.out_size = grub_min (file->offset + ret + len - current_offset, XZBUFSIZ); /* Feed input. */ if (xzio->buf.in_pos == xzio->buf.in_size) { readret = grub_file_read (xzio->file, xzio->inbuf, XZBUFSIZ); if (readret < 0) return -1; xzio->buf.in_size = readret; xzio->buf.in_pos = 0; } xzret = xz_dec_run (xzio->dec, &xzio->buf); switch (xzret) { case XZ_MEMLIMIT_ERROR: case XZ_FORMAT_ERROR: case XZ_OPTIONS_ERROR: case XZ_DATA_ERROR: case XZ_BUF_ERROR: grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "file corrupted or unsupported block options"); return -1; default: break; } { grub_off_t new_offset = current_offset + xzio->buf.out_pos; if (file->offset <= new_offset) /* Store first chunk of data in buffer. */ { grub_size_t delta = new_offset - (file->offset + ret); grub_memmove (buf, xzio->buf.out + (xzio->buf.out_pos - delta), delta); len -= delta; buf += delta; ret += delta; } current_offset = new_offset; } xzio->buf.out_pos = 0; if (xzret == XZ_STREAM_END) /* Stream end, EOF. */ break; } if (ret >= 0) xzio->saved_offset = file->offset + ret; return ret; }