/* SPDX-License-Identifier: GPL-3.0-or-later */ /* * table.c * * Copyright (C) 2021 David Oberhollenzer */ #include "config.h" #include "compat.h" #include "util/test.h" #include "sqfs/compressor.h" #include "sqfs/error.h" #include "sqfs/table.h" #include "sqfs/io.h" static sqfs_u8 file_data[32768]; static size_t file_used = 0; static int dummy_read_at(sqfs_file_t *file, sqfs_u64 offset, void *buffer, size_t size) { (void)file; if (offset >= sizeof(file_data)) return SQFS_ERROR_OUT_OF_BOUNDS; if (size > (sizeof(file_data) - offset)) return SQFS_ERROR_OUT_OF_BOUNDS; memset(buffer, 0, size); if (offset < file_used) { if (size > (file_used - offset)) size = file_used - offset; memcpy(buffer, file_data + offset, size); } return 0; } static int dummy_write_at(sqfs_file_t *file, sqfs_u64 offset, const void *buffer, size_t size) { (void)file; if (offset >= sizeof(file_data)) return SQFS_ERROR_OUT_OF_BOUNDS; if (size > (sizeof(file_data) - offset)) return SQFS_ERROR_OUT_OF_BOUNDS; if (offset > file_used) memset(file_data + file_used, 0, offset - file_used); if ((offset + size) > file_used) file_used = offset + size; memcpy(file_data + offset, buffer, size); return 0; } static sqfs_u64 dummy_get_size(const sqfs_file_t *file) { (void)file; return file_used; } static sqfs_s32 dummy_compress(sqfs_compressor_t *cmp, const sqfs_u8 *in, sqfs_u32 size, sqfs_u8 *out, sqfs_u32 outsize) { (void)cmp; memcpy(out, in, outsize < size ? outsize : size); return 0; } static sqfs_s32 dummy_uncompress(sqfs_compressor_t *cmp, const sqfs_u8 *in, sqfs_u32 size, sqfs_u8 *out, sqfs_u32 outsize) { (void)cmp; if (outsize < size) return 0; memcpy(out, in, size); return size; } static sqfs_file_t dummy_file = { { 1, NULL, NULL }, dummy_read_at, dummy_write_at, dummy_get_size, NULL, NULL, }; static sqfs_compressor_t dummy_compressor = { { 1, NULL, NULL }, NULL, NULL, NULL, dummy_compress, }; static sqfs_compressor_t dummy_uncompressor = { { 1, NULL, NULL }, NULL, NULL, NULL, dummy_uncompress, }; /*****************************************************************************/ static sqfs_u64 table[4000]; int main(int argc, char **argv) { sqfs_u64 start, value, locations[4], *copy; sqfs_u16 hdr; size_t i; int ret; (void)argc; (void)argv; /* fill the table with data */ for (i = 0; i < sizeof(table) / sizeof(table[0]); ++i) table[i] = i; /* serialize the table */ ret = sqfs_write_table(&dummy_file, &dummy_compressor, table, sizeof(table), &start); TEST_EQUAL_I(ret, 0); TEST_EQUAL_UI(file_used, (3 * (8192 + 2) + (7424 + 2) + 4 * sizeof(sqfs_u64))); TEST_EQUAL_UI(start, (3 * (8192 + 2) + (7424 + 2))); /* check the location list */ memcpy(locations, file_data + start, sizeof(locations)); for (i = 0; i < 4; ++i) locations[i] = le64toh(locations[i]); TEST_EQUAL_UI(locations[0], 0); TEST_EQUAL_UI(locations[1], (1 * (8192 + 2))); TEST_EQUAL_UI(locations[2], (2 * (8192 + 2))); TEST_EQUAL_UI(locations[3], (3 * (8192 + 2))); /* check the individual blocks */ memcpy(&hdr, file_data + locations[0], sizeof(hdr)); hdr = le16toh(hdr); TEST_EQUAL_UI(hdr, (0x8000 | 8192)); for (i = 0; i < 8192; i += sizeof(sqfs_u64)) { memcpy(&value, (file_data + locations[0] + 2) + i, sizeof(value)); TEST_EQUAL_UI(value, i / sizeof(sqfs_u64)); } memcpy(&hdr, file_data + locations[1], sizeof(hdr)); hdr = le16toh(hdr); TEST_EQUAL_UI(hdr, (0x8000 | 8192)); for (i = 0; i < 8192; i += sizeof(sqfs_u64)) { memcpy(&value, (file_data + locations[1] + 2) + i, sizeof(value)); TEST_EQUAL_UI(value, (1024 + i / sizeof(sqfs_u64))); } memcpy(&hdr, file_data + locations[2], sizeof(hdr)); hdr = le16toh(hdr); TEST_EQUAL_UI(hdr, (0x8000 | 8192)); for (i = 0; i < 8192; i += sizeof(sqfs_u64)) { memcpy(&value, (file_data + locations[2] + 2) + i, sizeof(value)); TEST_EQUAL_UI(value, (2048 + i / sizeof(sqfs_u64))); } memcpy(&hdr, file_data + locations[3], sizeof(hdr)); hdr = le16toh(hdr); TEST_EQUAL_UI(hdr, (0x8000 | 7424)); for (i = 0; i < 7424; i += sizeof(sqfs_u64)) { memcpy(&value, (file_data + locations[3] + 2) + i, sizeof(value)); TEST_EQUAL_UI(value, (3072 + i / sizeof(sqfs_u64))); } /* read the table back */ ret = sqfs_read_table(&dummy_file, &dummy_uncompressor, sizeof(table), start, 0, start, (void **)©); TEST_EQUAL_I(ret, 0); ret = memcmp(copy, table, sizeof(table)); TEST_EQUAL_I(ret, 0); free(copy); return EXIT_SUCCESS; }