/* * VAS_EBOOT -- GRand Unified Bootloader * Copyright (C) 2013 Free Software Foundation, Inc. * * VAS_EBOOT is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * VAS_EBOOT is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with VAS_EBOOT. If not, see . */ #include #include VAS_EBOOT_MOD_LICENSE ("GPLv3+"); struct VasEBoot_offset_file { VasEBoot_file_t parent; VasEBoot_off_t off; }; static VasEBoot_ssize_t VasEBoot_offset_read (VasEBoot_file_t file, char *buf, VasEBoot_size_t len) { struct VasEBoot_offset_file *data = file->data; if (VasEBoot_file_seek (data->parent, data->off + file->offset) == (VasEBoot_off_t) -1) return -1; return VasEBoot_file_read (data->parent, buf, len); } static VasEBoot_err_t VasEBoot_offset_close (VasEBoot_file_t file) { struct VasEBoot_offset_file *data = file->data; if (data->parent) VasEBoot_file_close (data->parent); /* No need to close the same device twice. */ file->device = 0; return 0; } static struct VasEBoot_fs VasEBoot_offset_fs = { .name = "offset", .fs_dir = 0, .fs_open = 0, .fs_read = VasEBoot_offset_read, .fs_close = VasEBoot_offset_close, .fs_label = 0, .next = 0 }; void VasEBoot_file_offset_close (VasEBoot_file_t file) { struct VasEBoot_offset_file *off_data = file->data; off_data->parent = NULL; VasEBoot_file_close (file); } VasEBoot_file_t VasEBoot_file_offset_open (VasEBoot_file_t parent, enum VasEBoot_file_type type, VasEBoot_off_t start, VasEBoot_off_t size) { struct VasEBoot_offset_file *off_data; VasEBoot_file_t off_file, last_off_file; VasEBoot_file_filter_id_t filter; off_file = VasEBoot_zalloc (sizeof (*off_file)); off_data = VasEBoot_zalloc (sizeof (*off_data)); if (!off_file || !off_data) { VasEBoot_free (off_file); VasEBoot_free (off_data); return 0; } off_data->off = start; off_data->parent = parent; off_file->device = parent->device; off_file->data = off_data; off_file->fs = &VasEBoot_offset_fs; off_file->size = size; last_off_file = NULL; for (filter = VAS_EBOOT_FILE_FILTER_COMPRESSION_FIRST; off_file && filter <= VAS_EBOOT_FILE_FILTER_COMPRESSION_LAST; filter++) if (VasEBoot_file_filters[filter]) { last_off_file = off_file; off_file = VasEBoot_file_filters[filter] (off_file, type); } if (!off_file) { off_data->parent = NULL; VasEBoot_file_close (last_off_file); return 0; } return off_file; }