diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index bcd1f98eb..a12e14d47 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -38,25 +38,6 @@ jobs: run: | ninja -C /tmp/build test - plain-build: - runs-on: ubuntu-latest - container: gottox/sqsh-build:${{ matrix.arch }} - strategy: - matrix: - cc: - - gcc - - clang - arch: - #- i386 - - x86_64 - steps: - - uses: actions/checkout@v3 - - name: build - run: | - CC=${{ matrix.cc }} - apk add zlib-dev - $CC -o sqsh-ls tools/common.c tools/ls.c $(find lib -name '*.c') -DCONFIG_ZLIB -L/lib -lz - build: runs-on: ubuntu-latest container: gottox/sqsh-build:${{ matrix.arch }} @@ -127,7 +108,6 @@ jobs: needs: - build - build-openbsd - - plain-build - test runs-on: ubuntu-latest container: gottox/sqsh-build:latest diff --git a/include/meson.build b/include/meson.build index bc50efd34..c35321e40 100644 --- a/include/meson.build +++ b/include/meson.build @@ -15,7 +15,6 @@ headers = files( 'sqsh_mapper_private.h', 'sqsh_metablock_private.h', 'sqsh_posix.h', - 'sqsh_primitive_private.h', 'sqsh_reader_private.h', 'sqsh_table.h', 'sqsh_table_private.h', diff --git a/include/sqsh_extract_private.h b/include/sqsh_extract_private.h index c4ead60c3..d69b9b4cf 100644 --- a/include/sqsh_extract_private.h +++ b/include/sqsh_extract_private.h @@ -34,7 +34,7 @@ #ifndef SQSH_EXTRACT_PRIVATE_H #define SQSH_EXTRACT_PRIVATE_H -#include "sqsh_primitive_private.h" +#include #include "sqsh_thread_private.h" @@ -91,7 +91,7 @@ struct SqshExtractor { /** * @privatesection */ - struct SqshBuffer *buffer; + struct CxBuffer *buffer; const struct SqshExtractorImpl *impl; size_t block_size; }; @@ -122,7 +122,7 @@ sqsh__extractor_impl_from_id(int id); * @return 0 on success, a negative value on error. */ SQSH_NO_EXPORT SQSH_NO_UNUSED int sqsh__extractor_init( - struct SqshExtractor *extractor, struct SqshBuffer *buffer, + struct SqshExtractor *extractor, struct CxBuffer *buffer, int algorithm_id, size_t block_size); /** @@ -162,11 +162,11 @@ struct SqshExtractManager { /** * @privatesection */ - struct SqshRcHashMap hash_map; + struct CxRcHashMap hash_map; unsigned int compression_id; uint32_t block_size; struct SqshMapManager *map_manager; - struct SqshLru lru; + struct CxLru lru; sqsh__mutex_t lock; }; @@ -199,7 +199,7 @@ SQSH_NO_EXPORT SQSH_NO_UNUSED int sqsh__extract_manager_init( */ SQSH_NO_EXPORT int sqsh__extract_manager_uncompress( struct SqshExtractManager *manager, const struct SqshMapReader *reader, - const struct SqshBuffer **target); + const struct CxBuffer **target); /** * @internal @@ -212,7 +212,7 @@ SQSH_NO_EXPORT int sqsh__extract_manager_uncompress( * @return 0 on success, a negative value on error. */ SQSH_NO_EXPORT int sqsh__extract_manager_release( - struct SqshExtractManager *manager, const struct SqshBuffer *buffer); + struct SqshExtractManager *manager, const struct CxBuffer *buffer); /** * @internal @@ -238,7 +238,7 @@ struct SqshExtractView { * @privatesection */ struct SqshExtractManager *manager; - const struct SqshBuffer *buffer; + const struct CxBuffer *buffer; size_t offset; size_t size; }; diff --git a/include/sqsh_mapper_private.h b/include/sqsh_mapper_private.h index 6ba872861..ad61f47fa 100644 --- a/include/sqsh_mapper_private.h +++ b/include/sqsh_mapper_private.h @@ -36,9 +36,9 @@ #include "sqsh_mapper.h" -#include "sqsh_primitive_private.h" #include "sqsh_reader_private.h" #include "sqsh_thread_private.h" +#include #include #ifdef __cplusplus @@ -259,8 +259,8 @@ struct SqshMapManager { * @privatesection */ struct SqshMapper mapper; - struct SqshLru lru; - struct SqshRcMap maps; + struct CxLru lru; + struct CxRcMap maps; uint64_t archive_offset; sqsh__mutex_t lock; }; diff --git a/include/sqsh_primitive_private.h b/include/sqsh_primitive_private.h deleted file mode 100644 index a592af21c..000000000 --- a/include/sqsh_primitive_private.h +++ /dev/null @@ -1,528 +0,0 @@ -/****************************************************************************** - * * - * Copyright (c) 2023, Enno Boland * - * * - * Redistribution and use in source and binary forms, with or without * - * modification, are permitted provided that the following conditions are * - * met: * - * * - * * Redistributions of source code must retain the above copyright notice, * - * this list of conditions and the following disclaimer. * - * * Redistributions in binary form must reproduce the above copyright * - * notice, this list of conditions and the following disclaimer in the * - * documentation and/or other materials provided with the distribution. * - * * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR * - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * * - ******************************************************************************/ - -/** - * @author Enno Boland (mail@eboland.de) - * @file sqsh_primitive_private.h - */ - -#ifndef SQSH_PRIMITIVE_PRIVATE_H -#define SQSH_PRIMITIVE_PRIVATE_H - -#include "sqsh_common.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/*************************************** - * primitive/buffer.c - */ - -/** - * @brief The SqshBuffer struct is a buffer for arbitrary data. - * - * The buffer takes care about resizing and freeing the memory managed by The - * buffer. - */ -struct SqshBuffer { - /** - * @privatesection - */ - uint8_t *data; - size_t size; - size_t capacity; -}; - -/** - * @internal - * @memberof SqshBuffer - * @brief sqsh__buffer_init initializes a SqshBuffer. - * - * @param[out] buffer The SqshBuffer to initialize. - * - * @return 0 on success, less than 0 on error. - */ -SQSH_NO_EXPORT SQSH_NO_UNUSED int sqsh__buffer_init(struct SqshBuffer *buffer); - -/** - * @internal - * @memberof SqshBuffer - * @brief sqsh__buffer_add_size tells SqshBuffer to increase the buffer by - * additional_size - * - * Please be aware, that the buffer needs to be allocated by - * sqsh__buffer_add_capacity before. Otherwise the function behavior is - * undefined. - * - * @param[in,out] buffer The SqshBuffer to increase. - * @param[in] additional_size The additional size to increase the buffer. - * - * @return 0 on success, less than 0 on error. - */ -SQSH_NO_EXPORT SQSH_NO_UNUSED int -sqsh__buffer_add_size(struct SqshBuffer *buffer, size_t additional_size); - -/** - * @internal - * @memberof SqshBuffer - * @brief sqsh__buffer_add_size allocates additional memory for the SqshBuffer - * and sets additional_buffer to the beginning of the additional memory. - * - * After sqsh__buffer_add_capacity has been called, the buffer will behave - * undefined if you query data or size. In order to use the buffer again, you - * need to call sqsh__buffer_add_size again. - * - * @param[in,out] buffer The SqshBuffer to free. - * @param[in] additional_buffer The pointer to the additional memory. - * @param[in] additional_size The size of the additional memory. - * - * @return 0 on success, less than 0 on error. - */ -SQSH_NO_EXPORT SQSH_NO_UNUSED int sqsh__buffer_add_capacity( - struct SqshBuffer *buffer, uint8_t **additional_buffer, - size_t additional_size); - -/** - * @internal - * @memberof SqshBuffer - * @brief sqsh__buffer_append - * - * @param[in,out] buffer The SqshBuffer to append to. - * @param[in] source The data to append. - * @param[in] source_size The size of the data to append. - * - * @return 0 on success, less than 0 on error. - */ -SQSH_NO_EXPORT SQSH_NO_UNUSED int sqsh__buffer_append( - struct SqshBuffer *buffer, const uint8_t *source, - const size_t source_size); - -/** - * @internal - * @memberof SqshBuffer - * @brief moves the data from buffer source to buffer. The source buffer will be - * invalid after this operation. - * - * @param[in,out] buffer The SqshBuffer to move to. - * @param[in] source The SqshBuffer to move from. - * - * @return 0 on success, less than 0 on error. - */ -SQSH_NO_EXPORT SQSH_NO_UNUSED int -sqsh__buffer_move(struct SqshBuffer *buffer, struct SqshBuffer *source); - -/** - * @internal - * @memberof SqshBuffer - * @brief resets the buffer size to 0. - * - * This does not free the memory allocated by the buffer so that - * the buffer can be reused. - * - * @param[in,out] buffer The SqshBuffer to drain. - */ - -void sqsh__buffer_drain(struct SqshBuffer *buffer); - -/** - * @internal - * @memberof SqshBuffer - * @brief sqsh__buffer_data returns the data of the SqshBuffer. - * @param[in] buffer The SqshBuffer to get the data from. - * @return a pointer to the data of the SqshBuffer. - */ -SQSH_NO_EXPORT const uint8_t * -sqsh__buffer_data(const struct SqshBuffer *buffer); - -/** - * @internal - * @memberof SqshBuffer - * @brief sqsh__buffer_size returns the size of the SqshBuffer. - * - * @param[in] buffer The SqshBuffer to get the size from. - * - * @return the size of the SqshBuffer. - */ -SQSH_NO_EXPORT size_t sqsh__buffer_size(const struct SqshBuffer *buffer); - -/** - * @internal - * @memberof SqshBuffer - * @brief cleans up the buffer and returns the data. - * @param[in,out] buffer The SqshBuffer to unwrap. - * - * @return 0 on success, less than 0 on error. - */ -SQSH_NO_EXPORT uint8_t *sqsh__buffer_unwrap(struct SqshBuffer *buffer); -/** - * @internal - * @memberof SqshBuffer - * @brief sqsh__buffer_cleanup frees the memory managed by the SqshBuffer. - * @param[in,out] buffer The SqshBuffer to cleanup. - * - * @return 0 on success, less than 0 on error. - */ -SQSH_NO_EXPORT int sqsh__buffer_cleanup(struct SqshBuffer *buffer); - -/*************************************** - * primitive/rc_map.c - */ - -/** - * @brief The type of the cleanup callback function. - */ -typedef void (*sqsh_rc_map_cleanup_t)(void *data); - -/** - * @internal - * @brief The SqshRcMap struct is a reference-counted array. - */ -struct SqshRcMap { - /** - * @privatesection - */ - uint8_t *data; - size_t size; - size_t element_size; - int *ref_count; - sqsh_rc_map_cleanup_t cleanup; -}; - -/** - * @internal - * @memberof SqshRcMap - * @brief Initializes a reference-counted array. - * - * @param array The array to initialize. - * @param size The size of the array. - * @param element_size The size of each element. - * @param cleanup The cleanup function. - * @return 0 on success, a negative value on error. - */ -SQSH_NO_EXPORT SQSH_NO_UNUSED int sqsh__rc_map_init( - struct SqshRcMap *array, size_t size, size_t element_size, - sqsh_rc_map_cleanup_t cleanup); - -/** - * @internal - * @memberof SqshRcMap - * @brief Tests if a reference-counted array is empty. - * @param array The array to test. - * @param index The index to test. - * @return True if the array is empty, false otherwise. - */ -SQSH_NO_EXPORT bool -sqsh__rc_map_is_empty(struct SqshRcMap *array, sqsh_index_t index); - -/** - * @internal - * @memberof SqshRcMap - * @brief Sets a value in a reference-counted array. - * - * @param array The array to set the value in. - * @param index The index to set the value at. - * @param data The data to set. - * @return 0 on success, a negative value on error. - */ -SQSH_NO_EXPORT const void * -sqsh__rc_map_set(struct SqshRcMap *array, sqsh_index_t index, void *data); - -/** - * @internal - * @memberof SqshRcMap - * @brief Gets the size of a reference-counted array. - * - * @param array The array to get the size of. - * @return The size of the array. - */ -SQSH_NO_EXPORT size_t sqsh__rc_map_size(const struct SqshRcMap *array); - -/** - * @internal - * @memberof SqshRcMap - * @brief Retains the data at a specified index in a reference-counted array. - * - * @param array The array containing the data. - * @param index The index of the data. - * @return A pointer to the retained data. - */ -SQSH_NO_EXPORT const void * -sqsh__rc_map_retain(struct SqshRcMap *array, sqsh_index_t index); - -/** - * @internal - * @memberof SqshRcMap - * @brief Releases the reference to the data at a specified index in a - * reference-counted array. - * - * @param array The array containing the data. - * @param element The element to release. - * @return 0 on success, a negative value on error. - */ -SQSH_NO_EXPORT int -sqsh__rc_map_release(struct SqshRcMap *array, const void *element); - -/** - * @internal - * @memberof SqshRcMap - * @brief Releases the reference to the data at a specified index in a - * reference-counted array. - * - * @param array The array containing the data. - * @param index The index of the data to release. - * @return 0 on success, a negative value on error. - */ -SQSH_NO_EXPORT int -sqsh__rc_map_release_index(struct SqshRcMap *array, sqsh_index_t index); - -/** - * @internal - * @memberof SqshRcMap - * @brief Checks if the element is contained in the array. - * - * @param array The array containing the data. - * @param element The element to check. - * @return True if the element is contained in the array, false otherwise. - */ -SQSH_NO_EXPORT bool -sqsh__rc_map_contains(struct SqshRcMap *array, const void *element); - -/** - * @internal - * @memberof SqshRcMap - * @brief Cleans up a reference-counted array. - * - * @param array The array to cleanup. - * @return 0 on success, a negative value on error. - */ -SQSH_NO_EXPORT int sqsh__rc_map_cleanup(struct SqshRcMap *array); - -/** - * @internal - * @memberof SqshRcMap - * - * @brief An implementation table to use SqshRcMap as a SqshLruBackend. - */ -SQSH_NO_EXPORT extern const struct SqshLruBackendImpl sqsh__lru_rc_map; - -/*************************************** - * primitive/rc_hash_map.c - */ - -/** - * @brief The type of the key for the hash map. - */ -typedef uint64_t sqsh_rc_map_key_t; - -struct SqshRcHashMapInner; - -/** - * @brief A reference-counted hash map. - */ -struct SqshRcHashMap { - /** - * @privatesection - */ - struct SqshRcHashMapInner *hash_maps; - size_t hash_map_count; - size_t map_size; - size_t element_size; - sqsh_rc_map_cleanup_t cleanup; -}; - -/** - * @internal - * @memberof SqshRcHashMap - * @brief Initializes a reference-counted array. - * - * @param hash_map The array to initialize. - * @param size The size of the array. - * @param element_size The size of each element. - * @param cleanup The cleanup function. - * @return 0 on success, a negative value on error. - */ -SQSH_NO_EXPORT SQSH_NO_UNUSED int sqsh__rc_hash_map_init( - struct SqshRcHashMap *hash_map, size_t size, size_t element_size, - sqsh_rc_map_cleanup_t cleanup); - -/** - * @internal - * @memberof SqshRcHashMap - * @brief Sets a value in a reference-counted array. - * - * @param hash_map The hash map to set the value in. - * @param key The key to set the value at. - * @param data The data to set. - * @return 0 on success, a negative value on error. - */ -SQSH_NO_EXPORT SQSH_NO_EXPORT const void *sqsh__rc_hash_map_put( - struct SqshRcHashMap *hash_map, sqsh_rc_map_key_t key, void *data); - -/** - * @internal - * @memberof SqshRcHashMap - * @brief Gets the size of a reference-counted hash map. - * - * @param hash_map The hash map to get the size of. - * @return The size of the hash map. - */ -SQSH_NO_EXPORT size_t -sqsh__rc_hash_map_size(const struct SqshRcHashMap *hash_map); - -/** - * @internal - * @memberof SqshRcHashMap - * @brief Retains the data at a specified key in a reference-counted hash map. - * - * @param hash_map The hash map containing the data. - * @param key The key of the data. - * @return A pointer to the retained data. - */ -SQSH_NO_EXPORT const void * -sqsh__rc_hash_map_retain(struct SqshRcHashMap *hash_map, sqsh_rc_map_key_t key); - -/** - * @internal - * @memberof SqshRcHashMap - * @brief Releases the reference to the data at a specified index in a - * reference-counted hash map. - * - * @param hash_map The hash map containing the data. - * @param element The element to release. - * @return 0 on success, a negative value on error. - */ -SQSH_NO_EXPORT int -sqsh__rc_hash_map_release(struct SqshRcHashMap *hash_map, const void *element); - -/** - * @internal - * @memberof SqshRcHashMap - * @brief Releases the reference to the data at a specified index in a - * reference-counted hash map. - * - * @param hash_map The hash map containing the data. - * @param key The key of the data to release. - * @return 0 on success, a negative value on error. - */ -SQSH_NO_EXPORT int sqsh__rc_hash_map_release_key( - struct SqshRcHashMap *hash_map, sqsh_rc_map_key_t key); - -/** - * @internal - * @memberof SqshRcHashMap - * @brief Cleans up a reference-counted hash map. - * - * @param hash_map The hash map to cleanup. - * @return 0 on success, a negative value on error. - */ -SQSH_NO_EXPORT int sqsh__rc_hash_map_cleanup(struct SqshRcHashMap *hash_map); - -/** - * @internal - * @memberof SqshRcHashMap - * - * @brief An implementation table to use SqshRcHashap as a SqshLruBackend. - */ -SQSH_NO_EXPORT extern const struct SqshLruBackendImpl sqsh__lru_rc_hash_map; - -/*************************************** - * primitive/lru.c - */ - -/** - * @internal - * @brief The connection to the backend data structure. used by the LRU cache. - */ -struct SqshLruBackendImpl { - /** - * @brief Function that is called to retain an element. - */ - const void *(*retain)(void *backend, sqsh_index_t id); - /** - * @brief Function that is called to release an element. - */ - int (*release)(void *backend, sqsh_index_t id); -}; - -/** - * @internal - * @brief Adds LRU functionality to a backend data structure. - */ -struct SqshLru { - /** - * @privatesection - */ - void *backend; - const struct SqshLruBackendImpl *impl; - sqsh_index_t *items; - sqsh_index_t ring_index; - size_t size; -}; - -/** - * @internal - * @memberof SqshLru - * @brief Initializes an LRU cache. - * - * @param lru The LRU cache to initialize. - * @param size The size of the LRU cache. - * @param impl The implementation of the backend data structure. - * @param backend The backend to use for the LRU cache. - * @return 0 on success, a negative value on error. - */ -SQSH_NO_EXPORT SQSH_NO_UNUSED int sqsh__lru_init( - struct SqshLru *lru, size_t size, const struct SqshLruBackendImpl *impl, - void *backend); - -/** - * @internal - * @memberof SqshLru - * @brief marks an item as recently used. - * @param lru The LRU cache to mark the item in. - * @param id The id of the item to touch - * @return 0 on success, a negative value on error. - */ -SQSH_NO_EXPORT SQSH_NO_UNUSED int -sqsh__lru_touch(struct SqshLru *lru, sqsh_index_t id); - -/** - * @internal - * @memberof SqshLru - * @brief Cleans up an LRU cache. - * - * @param lru The LRU cache to cleanup. - * - * @return 0 on success, a negative value on error. - */ -SQSH_NO_EXPORT int sqsh__lru_cleanup(struct SqshLru *lru); - -#ifdef __cplusplus -} -#endif -#endif /* SQSH_PRIMITIVE_PRIVATE_H */ diff --git a/include/sqsh_reader_private.h b/include/sqsh_reader_private.h index c3111fa78..c353e359a 100644 --- a/include/sqsh_reader_private.h +++ b/include/sqsh_reader_private.h @@ -35,7 +35,7 @@ #define SQSH_READER_PRIVATE_H #include "sqsh_common.h" -#include "sqsh_primitive_private.h" +#include #include #ifdef __cplusplus @@ -106,7 +106,7 @@ struct SqshReader { /** * @brief The buffer to store data in if they cannot be directly mapped. */ - struct SqshBuffer buffer; + struct CxBuffer buffer; /** * @brief The data that is presented to the user. diff --git a/include/sqsh_xattr.h b/include/sqsh_xattr.h index 031fe3bd1..3aca35766 100644 --- a/include/sqsh_xattr.h +++ b/include/sqsh_xattr.h @@ -78,7 +78,8 @@ sqsh_xattr_iterator_new(const struct SqshFile *file, int *err); * stored. * * @retval true When the iterator was advanced. - * @retval false When the end of the xattrs list was reached or an error occured. + * @retval false When the end of the xattrs list was reached or an error + * occured. */ SQSH_NO_UNUSED bool sqsh_xattr_iterator_next(struct SqshXattrIterator *iterator, int *err); diff --git a/lib/easy/directory.c b/lib/easy/directory.c index 5fd74666d..7c35438e2 100644 --- a/lib/easy/directory.c +++ b/lib/easy/directory.c @@ -51,8 +51,8 @@ sqsh_easy_directory_list( struct SqshArchive *archive, const char *path, int *err) { int rv = 0; static const uintptr_t nullptr = 0; - struct SqshBuffer dir_list = {0}; - struct SqshBuffer dir_list_names = {0}; + struct CxBuffer dir_list = {0}; + struct CxBuffer dir_list_names = {0}; size_t elements = 0; struct SqshFile *file = NULL; struct SqshDirectoryIterator *iterator = NULL; @@ -68,11 +68,11 @@ sqsh_easy_directory_list( goto out; } - rv = sqsh__buffer_init(&dir_list); + rv = cx_buffer_init(&dir_list); if (rv < 0) { goto out; } - rv = sqsh__buffer_init(&dir_list_names); + rv = cx_buffer_init(&dir_list_names); if (rv < 0) { goto out; } @@ -85,36 +85,35 @@ sqsh_easy_directory_list( while (sqsh_directory_iterator_next(iterator, &rv)) { const char *name = sqsh_directory_iterator_name(iterator); size_t name_len = sqsh_directory_iterator_name_size(iterator); - size_t index = sqsh__buffer_size(&dir_list_names); + size_t index = cx_buffer_size(&dir_list_names); char *index_ptr = (void *)index; elements++; - rv = sqsh__buffer_append( - &dir_list, (uint8_t *)&index_ptr, sizeof(char *)); + rv = cx_buffer_append(&dir_list, (uint8_t *)&index_ptr, sizeof(char *)); if (rv < 0) { goto out; } - rv = sqsh__buffer_append(&dir_list_names, (uint8_t *)name, name_len); + rv = cx_buffer_append(&dir_list_names, (uint8_t *)name, name_len); if (rv < 0) { goto out; } - rv = sqsh__buffer_append( + rv = cx_buffer_append( &dir_list_names, (uint8_t *)&nullptr, sizeof(char)); if (rv < 0) { goto out; } } - rv = sqsh__buffer_append(&dir_list, (uint8_t *)&nullptr, sizeof(char *)); - size_t base_size = sqsh__buffer_size(&dir_list); + rv = cx_buffer_append(&dir_list, (uint8_t *)&nullptr, sizeof(char *)); + size_t base_size = cx_buffer_size(&dir_list); - const uint8_t *names_data = sqsh__buffer_data(&dir_list_names); - size_t names_size = sqsh__buffer_size(&dir_list_names); - rv = sqsh__buffer_append(&dir_list, names_data, names_size); + const uint8_t *names_data = cx_buffer_data(&dir_list_names); + size_t names_size = cx_buffer_size(&dir_list_names); + rv = cx_buffer_append(&dir_list, names_data, names_size); if (rv < 0) { goto out; } - dir_list_data = (char **)sqsh__buffer_unwrap(&dir_list); + dir_list_data = (char **)cx_buffer_unwrap(&dir_list); for (sqsh_index_t i = 0; i < elements; i++) { dir_list_data[i] += base_size + (uintptr_t)dir_list_data; @@ -122,8 +121,8 @@ sqsh_easy_directory_list( out: sqsh_directory_iterator_free(iterator); - sqsh__buffer_cleanup(&dir_list); - sqsh__buffer_cleanup(&dir_list_names); + cx_buffer_cleanup(&dir_list); + cx_buffer_cleanup(&dir_list_names); sqsh_close(file); if (err) { *err = rv; diff --git a/lib/extract/extract_manager.c b/lib/extract/extract_manager.c index aa8b80529..a4d5ed06d 100644 --- a/lib/extract/extract_manager.c +++ b/lib/extract/extract_manager.c @@ -39,7 +39,7 @@ #include "../../include/sqsh_mapper.h" #include "../../include/sqsh_mapper_private.h" -#include "../../include/sqsh_primitive_private.h" +#include /** * Calculates pow(x,y) % mod @@ -76,7 +76,7 @@ find_next_maybe_prime(size_t n) { static void buffer_cleanup(void *buffer) { - sqsh__buffer_cleanup(buffer); + cx_buffer_cleanup(buffer); } SQSH_NO_UNUSED int @@ -105,15 +105,13 @@ sqsh__extract_manager_init( if (rv < 0) { goto out; } - rv = sqsh__rc_hash_map_init( - &manager->hash_map, size, sizeof(struct SqshBuffer), - buffer_cleanup); + rv = cx_rc_hash_map_init( + &manager->hash_map, size, sizeof(struct CxBuffer), buffer_cleanup); if (rv < 0) { goto out; } - rv = sqsh__lru_init( - &manager->lru, lru_size, &sqsh__lru_rc_hash_map, - &manager->hash_map); + rv = cx_lru_init( + &manager->lru, lru_size, &cx_lru_rc_hash_map, &manager->hash_map); if (rv < 0) { goto out; } @@ -135,7 +133,7 @@ sqsh__extract_manager_init( int sqsh__extract_manager_uncompress( struct SqshExtractManager *manager, const struct SqshMapReader *reader, - const struct SqshBuffer **target) { + const struct CxBuffer **target) { int rv = 0; struct SqshExtractor extractor = {0}; const enum SqshSuperblockCompressionId compression_id = @@ -150,11 +148,11 @@ sqsh__extract_manager_uncompress( const uint64_t address = sqsh__map_reader_address(reader); const size_t size = sqsh__map_reader_size(reader); - *target = sqsh__rc_hash_map_retain(&manager->hash_map, address); + *target = cx_rc_hash_map_retain(&manager->hash_map, address); if (*target == NULL) { - struct SqshBuffer buffer = {0}; - rv = sqsh__buffer_init(&buffer); + struct CxBuffer buffer = {0}; + rv = cx_buffer_init(&buffer); if (rv < 0) { goto out; } @@ -168,13 +166,13 @@ sqsh__extract_manager_uncompress( rv = sqsh__extractor_to_buffer(&extractor, data, size); if (rv < 0) { - sqsh__buffer_cleanup(&buffer); + cx_buffer_cleanup(&buffer); goto out; } - *target = sqsh__rc_hash_map_put(&manager->hash_map, address, &buffer); + *target = cx_rc_hash_map_put(&manager->hash_map, address, &buffer); } - rv = sqsh__lru_touch(&manager->lru, address); + rv = cx_lru_touch(&manager->lru, address); out: sqsh__extractor_cleanup(&extractor); @@ -184,13 +182,13 @@ sqsh__extract_manager_uncompress( int sqsh__extract_manager_release( - struct SqshExtractManager *manager, const struct SqshBuffer *buffer) { + struct SqshExtractManager *manager, const struct CxBuffer *buffer) { int rv = sqsh__mutex_lock(&manager->lock); if (rv < 0) { goto out; } - rv = sqsh__rc_hash_map_release(&manager->hash_map, buffer); + rv = cx_rc_hash_map_release(&manager->hash_map, buffer); sqsh__mutex_unlock(&manager->lock); out: @@ -199,8 +197,8 @@ sqsh__extract_manager_release( int sqsh__extract_manager_cleanup(struct SqshExtractManager *manager) { - sqsh__lru_cleanup(&manager->lru); - sqsh__rc_hash_map_cleanup(&manager->hash_map); + cx_lru_cleanup(&manager->lru); + cx_rc_hash_map_cleanup(&manager->hash_map); sqsh__mutex_destroy(&manager->lock); return 0; diff --git a/lib/extract/extract_view.c b/lib/extract/extract_view.c index 0533df389..78964ab6d 100644 --- a/lib/extract/extract_view.c +++ b/lib/extract/extract_view.c @@ -50,7 +50,7 @@ sqsh__extract_view_init( goto out; } - view->size = sqsh__buffer_size(view->buffer); + view->size = cx_buffer_size(view->buffer); out: if (rv < 0) { @@ -61,7 +61,7 @@ sqsh__extract_view_init( const uint8_t * sqsh__extract_view_data(const struct SqshExtractView *view) { - const uint8_t *data = sqsh__buffer_data(view->buffer); + const uint8_t *data = cx_buffer_data(view->buffer); return &data[view->offset]; } diff --git a/lib/extract/extractor.c b/lib/extract/extractor.c index d584ef935..37fc37636 100644 --- a/lib/extract/extractor.c +++ b/lib/extract/extractor.c @@ -35,7 +35,7 @@ #include "../../include/sqsh_archive.h" #include "../../include/sqsh_error.h" -#include "../../include/sqsh_primitive_private.h" +#include const struct SqshExtractorImpl *const __attribute__((weak)) sqsh__impl_lzo = NULL; @@ -62,7 +62,7 @@ sqsh__extractor_impl_from_id(int id) { int sqsh__extractor_init( - struct SqshExtractor *extractor, struct SqshBuffer *buffer, + struct SqshExtractor *extractor, struct CxBuffer *buffer, int algorithm_id, size_t block_size) { const struct SqshExtractorImpl *impl = sqsh__extractor_impl_from_id(algorithm_id); @@ -85,9 +85,9 @@ sqsh__extractor_to_buffer( uint8_t *decompressed = NULL; const struct SqshExtractorImpl *impl = extractor->impl; sqsh__extractor_context_t extractor_context = {0}; - struct SqshBuffer *buffer = extractor->buffer; + struct CxBuffer *buffer = extractor->buffer; - rv = sqsh__buffer_add_capacity(buffer, &decompressed, max_size); + rv = cx_buffer_add_capacity(buffer, &decompressed, max_size); if (rv < 0) { goto out; } @@ -114,7 +114,7 @@ sqsh__extractor_to_buffer( rv = -SQSH_ERROR_COMPRESSION_DECOMPRESS; goto out; } - rv = sqsh__buffer_add_size(buffer, size); + rv = cx_buffer_add_size(buffer, size); out: return rv; diff --git a/lib/file/file_iterator.c b/lib/file/file_iterator.c index e4783a7e3..d55eafcad 100644 --- a/lib/file/file_iterator.c +++ b/lib/file/file_iterator.c @@ -35,7 +35,7 @@ #include "../../include/sqsh_archive_private.h" #include "../../include/sqsh_error.h" -#include "../../include/sqsh_primitive_private.h" +#include #include "../../include/sqsh_file_private.h" #include "../utils/utils.h" diff --git a/lib/mapper/map_manager.c b/lib/mapper/map_manager.c index bffedf5f4..236ec8c70 100644 --- a/lib/mapper/map_manager.c +++ b/lib/mapper/map_manager.c @@ -109,15 +109,14 @@ sqsh__map_manager_init( sqsh__mapper_block_size(&manager->mapper)); manager->archive_offset = archive_offset; - rv = sqsh__rc_map_init( + rv = cx_rc_map_init( &manager->maps, map_size, sizeof(struct SqshMapSlice), map_cleanup_cb); if (rv < 0) { goto out; } - rv = sqsh__lru_init( - &manager->lru, lru_size, &sqsh__lru_rc_map, &manager->maps); + rv = cx_lru_init(&manager->lru, lru_size, &cx_lru_rc_map, &manager->maps); out: if (rv < 0) { sqsh__map_manager_cleanup(manager); @@ -137,7 +136,7 @@ sqsh__map_manager_block_size(const struct SqshMapManager *manager) { size_t sqsh__map_manager_block_count(const struct SqshMapManager *manager) { - return sqsh__rc_map_size(&manager->maps); + return cx_rc_map_size(&manager->maps); } int @@ -151,7 +150,7 @@ sqsh__map_manager_get( goto out; } - *target = sqsh__rc_map_retain(&manager->maps, index); + *target = cx_rc_map_retain(&manager->maps, index); if (*target == NULL) { struct SqshMapSlice mapping = {0}; @@ -166,9 +165,9 @@ sqsh__map_manager_get( goto out; } - *target = sqsh__rc_map_set(&manager->maps, index, &mapping); + *target = cx_rc_map_set(&manager->maps, index, &mapping); } - rv = sqsh__lru_touch(&manager->lru, index); + rv = cx_lru_touch(&manager->lru, index); out: sqsh__mutex_unlock(&manager->lock); @@ -186,7 +185,7 @@ sqsh__map_manager_release( goto out; } - rv = sqsh__rc_map_release(&manager->maps, mapping); + rv = cx_rc_map_release(&manager->maps, mapping); sqsh__mutex_unlock(&manager->lock); out: @@ -195,8 +194,8 @@ sqsh__map_manager_release( int sqsh__map_manager_cleanup(struct SqshMapManager *manager) { - sqsh__lru_cleanup(&manager->lru); - sqsh__rc_map_cleanup(&manager->maps); + cx_lru_cleanup(&manager->lru); + cx_rc_map_cleanup(&manager->maps); sqsh__mapper_cleanup(&manager->mapper); sqsh__mutex_destroy(&manager->lock); diff --git a/lib/meson.build b/lib/meson.build index c515b64a8..f9b232d65 100644 --- a/lib/meson.build +++ b/lib/meson.build @@ -37,10 +37,6 @@ libsqsh_sources = files( 'mapper/static_mapper.c', 'metablock/metablock_iterator.c', 'metablock/metablock_reader.c', - 'primitive/buffer.c', - 'primitive/lru.c', - 'primitive/rc_hash_map.c', - 'primitive/rc_map.c', 'table/export_table.c', 'table/fragment_table.c', 'table/id_table.c', @@ -55,7 +51,9 @@ libsqsh_sources = files( libsqsh_headers_private = ['utils/utils.h'] -libsqsh_dependencies = [] +libsqsh_dependencies = [ + cextras_dep, +] c_args = [] if threads_dep.found() diff --git a/lib/primitive/buffer.c b/lib/primitive/buffer.c deleted file mode 100644 index c7cc11c03..000000000 --- a/lib/primitive/buffer.c +++ /dev/null @@ -1,146 +0,0 @@ -/****************************************************************************** - * * - * Copyright (c) 2023, Enno Boland * - * * - * Redistribution and use in source and binary forms, with or without * - * modification, are permitted provided that the following conditions are * - * met: * - * * - * * Redistributions of source code must retain the above copyright notice, * - * this list of conditions and the following disclaimer. * - * * Redistributions in binary form must reproduce the above copyright * - * notice, this list of conditions and the following disclaimer in the * - * documentation and/or other materials provided with the distribution. * - * * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR * - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * * - ******************************************************************************/ - -/** - * @author Enno Boland (mail@eboland.de) - * @file buffer.c - */ - -#include "../../include/sqsh_primitive_private.h" - -#include "../../include/sqsh_error.h" -#include "../utils/utils.h" - -int -sqsh__buffer_init(struct SqshBuffer *buffer) { - int rv = 0; - - buffer->data = NULL; - buffer->capacity = buffer->size = 0; - - return rv; -} - -int -sqsh__buffer_add_capacity( - struct SqshBuffer *buffer, uint8_t **additional_buffer, - size_t additional_size) { - const size_t buffer_size = buffer->size; - uint8_t *new_data; - size_t new_capacity; - - if (SQSH_ADD_OVERFLOW(buffer_size, additional_size, &new_capacity)) { - return -SQSH_ERROR_INTEGER_OVERFLOW; - } - - if (new_capacity > buffer->capacity) { - new_data = realloc(buffer->data, new_capacity); - if (new_data == NULL) { - return -SQSH_ERROR_MALLOC_FAILED; - } - buffer->data = new_data; - buffer->capacity = new_capacity; - } - if (additional_buffer != NULL) { - *additional_buffer = &buffer->data[buffer_size]; - } - return new_capacity; -} - -int -sqsh__buffer_add_size(struct SqshBuffer *buffer, size_t additional_size) { - const size_t buffer_size = buffer->size; - size_t new_size; - if (SQSH_ADD_OVERFLOW(buffer_size, additional_size, &new_size)) { - return -SQSH_ERROR_INTEGER_OVERFLOW; - } - - buffer->size = new_size; - return 0; -} - -int -sqsh__buffer_append( - struct SqshBuffer *buffer, const uint8_t *source, const size_t size) { - int rv = 0; - uint8_t *additional_buffer; - - if (size <= 0) { - return 0; - } - - rv = sqsh__buffer_add_capacity(buffer, &additional_buffer, size); - if (rv < 0) { - return rv; - } - - memcpy(additional_buffer, source, size); - rv = sqsh__buffer_add_size(buffer, size); - return rv; -} - -int -sqsh__buffer_move(struct SqshBuffer *buffer, struct SqshBuffer *source) { - sqsh__buffer_cleanup(buffer); - - memcpy(buffer, source, sizeof(struct SqshBuffer)); - memset(source, 0, sizeof(struct SqshBuffer)); - - return 0; -} - -void -sqsh__buffer_drain(struct SqshBuffer *buffer) { - buffer->size = 0; -} - -const uint8_t * -sqsh__buffer_data(const struct SqshBuffer *buffer) { - return buffer->data; -} -size_t -sqsh__buffer_size(const struct SqshBuffer *buffer) { - return buffer->size; -} - -uint8_t * -sqsh__buffer_unwrap(struct SqshBuffer *buffer) { - uint8_t *data = buffer->data; - buffer->data = NULL; - sqsh__buffer_cleanup(buffer); - - return data; -} - -int -sqsh__buffer_cleanup(struct SqshBuffer *buffer) { - free(buffer->data); - buffer->data = NULL; - buffer->size = buffer->capacity = 0; - return 0; -} diff --git a/lib/primitive/lru.c b/lib/primitive/lru.c deleted file mode 100644 index 17c34dff9..000000000 --- a/lib/primitive/lru.c +++ /dev/null @@ -1,137 +0,0 @@ -/****************************************************************************** - * * - * Copyright (c) 2023, Enno Boland * - * * - * Redistribution and use in source and binary forms, with or without * - * modification, are permitted provided that the following conditions are * - * met: * - * * - * * Redistributions of source code must retain the above copyright notice, * - * this list of conditions and the following disclaimer. * - * * Redistributions in binary form must reproduce the above copyright * - * notice, this list of conditions and the following disclaimer in the * - * documentation and/or other materials provided with the distribution. * - * * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR * - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * * - ******************************************************************************/ - -/** - * @author Enno Boland (mail@eboland.de) - * @file lru.c - */ - -#include "../../include/sqsh_primitive_private.h" - -#include "../../include/sqsh_error.h" -#include "../utils/utils.h" - -#include - -#define EMPTY_MARKER SIZE_MAX - -#if 0 -# include - -static void -debug_print(const struct SqshLru *lru, const char msg, sqsh_index_t ring_index) { - sqsh_index_t backend_index = lru->items[ring_index]; - - fprintf(stderr, "%clru %lu: ", msg, ring_index); - size_t sum = 0; - for (size_t i = 0; i < lru->size; i++) { - sqsh_index_t cur_index = lru->items[i]; - if (cur_index == backend_index) { - sum++; - } - } - fprintf(stderr, "idx: %lu refs: %lu\n", backend_index, sum); - fflush(stderr); -} -#else -# define debug_print(...) -#endif - -int -sqsh__lru_init( - struct SqshLru *lru, size_t size, const struct SqshLruBackendImpl *impl, - void *backend) { - memset(lru, 0, sizeof(*lru)); - lru->impl = impl; - lru->backend = backend; - lru->size = size; - if (size == 0) { - return 0; - } - - lru->items = calloc(size, sizeof(sqsh_index_t)); - if (lru->items == NULL) { - return -SQSH_ERROR_MALLOC_FAILED; - } - for (size_t i = 0; i < lru->size; i++) { - lru->items[i] = EMPTY_MARKER; - } - lru->ring_index = 0; - - return 0; -} - -int -sqsh__lru_touch(struct SqshLru *lru, sqsh_index_t index) { - if (lru->size == 0) { - return 0; - } - - sqsh_index_t ring_index = lru->ring_index; - size_t size = lru->size; - void *backend = lru->backend; - const struct SqshLruBackendImpl *impl = lru->impl; - sqsh_index_t last_index = lru->items[ring_index]; - - ring_index = (ring_index + 1) % size; - - sqsh_index_t old_index = lru->items[ring_index]; - - if (old_index == index || last_index == index) { - return 0; - } - - debug_print(lru, '-', ring_index); - if (old_index != EMPTY_MARKER) { - impl->release(backend, old_index); - } - - lru->items[ring_index] = index; - debug_print(lru, '+', ring_index); - impl->retain(backend, index); - - lru->ring_index = ring_index; - - return 0; -} - -int -sqsh__lru_cleanup(struct SqshLru *lru) { - const struct SqshLruBackendImpl *impl = lru->impl; - - for (size_t i = 0; i < lru->size; i++) { - sqsh_index_t index = lru->items[i]; - if (index != EMPTY_MARKER) { - impl->release(lru->backend, index); - } - } - free(lru->items); - lru->size = 0; - lru->items = NULL; - return 0; -} diff --git a/lib/primitive/rc_hash_map.c b/lib/primitive/rc_hash_map.c deleted file mode 100644 index 5e9bf099f..000000000 --- a/lib/primitive/rc_hash_map.c +++ /dev/null @@ -1,228 +0,0 @@ -/****************************************************************************** - * * - * Copyright (c) 2023, Enno Boland * - * * - * Redistribution and use in source and binary forms, with or without * - * modification, are permitted provided that the following conditions are * - * met: * - * * - * * Redistributions of source code must retain the above copyright notice, * - * this list of conditions and the following disclaimer. * - * * Redistributions in binary form must reproduce the above copyright * - * notice, this list of conditions and the following disclaimer in the * - * documentation and/or other materials provided with the distribution. * - * * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR * - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * * - ******************************************************************************/ - -/** - * @author Enno Boland (mail@eboland.de) - * @file rc_map.c - */ - -#include "../../include/sqsh_primitive_private.h" - -#include "../../include/sqsh_error.h" -#include "../utils/utils.h" -#include - -#define COLLISION_RESERVE_BITS 2 -#define MAX_COLLISIONS 5 - -struct SqshRcHashMapInner { - sqsh_rc_map_key_t *keys; - struct SqshRcMap values; - size_t count; -}; - -static uint64_t -djb2_hash(const void *data, const size_t size) { - uint64_t hash = 5381; - const uint8_t *p = data; - for (size_t i = 0; i < size; i++) { - hash = ((hash << 5) + hash) + p[i]; - } - return hash; -} - -static sqsh_index_t -key_to_index(const sqsh_rc_map_key_t key, const size_t size) { - sqsh_index_t hash = djb2_hash(&key, sizeof(uint64_t)); - - /* reserve the lower COLLISION_RESERVE_BITS bits for collisions. */ - hash <<= COLLISION_RESERVE_BITS; - return hash % size; -} - -static int -extend_hash_map(struct SqshRcHashMap *hash_map) { - size_t new_size; - const sqsh_index_t last_index = hash_map->hash_map_count; - struct SqshRcHashMapInner *hash_maps; - - if (SQSH_ADD_OVERFLOW(hash_map->hash_map_count, 1, &new_size)) { - return -SQSH_ERROR_INTEGER_OVERFLOW; - } - hash_map->hash_map_count = new_size; - if (SQSH_MULT_OVERFLOW( - new_size, sizeof(struct SqshRcHashMapInner), &new_size)) { - return -SQSH_ERROR_INTEGER_OVERFLOW; - } - - hash_map->hash_maps = realloc(hash_map->hash_maps, new_size); - hash_maps = &hash_map->hash_maps[last_index]; - - hash_maps->keys = calloc(hash_map->map_size, sizeof(sqsh_rc_map_key_t)); - if (hash_maps->keys == NULL) { - return -SQSH_ERROR_MALLOC_FAILED; - } - - return sqsh__rc_map_init( - &hash_maps->values, hash_map->map_size, hash_map->element_size, - hash_map->cleanup); -} - -int -sqsh__rc_hash_map_init( - struct SqshRcHashMap *hash_map, size_t size, size_t element_size, - sqsh_rc_map_cleanup_t cleanup) { - memset(hash_map, 0, sizeof(*hash_map)); - hash_map->hash_maps = NULL; - hash_map->hash_map_count = 0; - hash_map->map_size = size; - hash_map->element_size = element_size; - hash_map->cleanup = cleanup; - return extend_hash_map(hash_map); -} - -const void * -sqsh__rc_hash_map_put( - struct SqshRcHashMap *hash_map, sqsh_rc_map_key_t key, void *data) { - int rv = 0; - const size_t size = sqsh__rc_map_size(&hash_map->hash_maps[0].values); - const sqsh_index_t orig_index = key_to_index(key, size); - sqsh_index_t index = orig_index; - struct SqshRcMap *values = NULL; - sqsh_rc_map_key_t *keys = NULL; - - for (sqsh_index_t i = 0; i < size && i < MAX_COLLISIONS; i++, index++) { - index = index % size; - - for (sqsh_index_t j = 0; j < hash_map->hash_map_count; j++) { - values = &hash_map->hash_maps[j].values; - keys = hash_map->hash_maps[j].keys; - if (sqsh__rc_map_is_empty(values, index) || keys[index] == key) { - goto found; - } - } - } - - index = orig_index; - rv = extend_hash_map(hash_map); - if (rv < 0) { - return NULL; - } - values = &hash_map->hash_maps[hash_map->hash_map_count - 1].values; - keys = hash_map->hash_maps[hash_map->hash_map_count - 1].keys; - -found: - keys[index] = key; - return sqsh__rc_map_set(values, index, data); -} - -size_t -sqsh__rc_hash_map_size(const struct SqshRcHashMap *hash_map) { - return sqsh__rc_map_size(&hash_map->hash_maps[0].values) * - hash_map->hash_map_count; -} - -const void * -sqsh__rc_hash_map_retain( - struct SqshRcHashMap *hash_map, sqsh_rc_map_key_t key) { - const size_t size = sqsh__rc_map_size(&hash_map->hash_maps[0].values); - sqsh_index_t index = key_to_index(key, size); - - for (sqsh_index_t i = 0; i < size && i < MAX_COLLISIONS; i++, index++) { - index = index % size; - - for (sqsh_index_t j = 0; j < hash_map->hash_map_count; j++) { - struct SqshRcMap *values = &hash_map->hash_maps[j].values; - sqsh_rc_map_key_t *keys = hash_map->hash_maps[j].keys; - if (keys[index] == key) { - return sqsh__rc_map_retain(values, index); - } - } - } - - return NULL; -} - -int -sqsh__rc_hash_map_release(struct SqshRcHashMap *hash_map, const void *element) { - for (sqsh_index_t i = 0; i < hash_map->hash_map_count; i++) { - struct SqshRcMap *values = &hash_map->hash_maps[i].values; - - if (sqsh__rc_map_contains(values, element)) { - return sqsh__rc_map_release(values, element); - } - } - return -SQSL_ERROR_ELEMENT_NOT_FOUND; -} - -int -sqsh__rc_hash_map_release_key( - struct SqshRcHashMap *hash_map, sqsh_rc_map_key_t key) { - const size_t size = sqsh__rc_map_size(&hash_map->hash_maps[0].values); - sqsh_index_t index = key_to_index(key, size); - - for (sqsh_index_t i = 0; i < size; i++, index++) { - index = index % size; - - for (sqsh_index_t j = 0; j < hash_map->hash_map_count; j++) { - struct SqshRcMap *values = &hash_map->hash_maps[j].values; - sqsh_rc_map_key_t *keys = hash_map->hash_maps[j].keys; - if (keys[index] == key) { - return sqsh__rc_map_release_index(values, index); - } - } - } - - return 0; -} - -int -sqsh__rc_hash_map_cleanup(struct SqshRcHashMap *hash_map) { - for (sqsh_index_t i = 0; i < hash_map->hash_map_count; i++) { - free(hash_map->hash_maps[i].keys); - sqsh__rc_map_cleanup(&hash_map->hash_maps[i].values); - } - free(hash_map->hash_maps); - - return 0; -} - -static const void * -lru_rc_hash_map_retain(void *backend, sqsh_index_t index) { - return sqsh__rc_hash_map_retain(backend, index); -} - -static int -lru_rc_hash_map_release(void *backend, sqsh_index_t index) { - return sqsh__rc_hash_map_release_key(backend, index); -} - -const struct SqshLruBackendImpl sqsh__lru_rc_hash_map = { - .retain = lru_rc_hash_map_retain, - .release = lru_rc_hash_map_release, -}; diff --git a/lib/primitive/rc_map.c b/lib/primitive/rc_map.c deleted file mode 100644 index b5219a248..000000000 --- a/lib/primitive/rc_map.c +++ /dev/null @@ -1,246 +0,0 @@ -/****************************************************************************** - * * - * Copyright (c) 2023, Enno Boland * - * * - * Redistribution and use in source and binary forms, with or without * - * modification, are permitted provided that the following conditions are * - * met: * - * * - * * Redistributions of source code must retain the above copyright notice, * - * this list of conditions and the following disclaimer. * - * * Redistributions in binary form must reproduce the above copyright * - * notice, this list of conditions and the following disclaimer in the * - * documentation and/or other materials provided with the distribution. * - * * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR * - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * * - ******************************************************************************/ - -/** - * @author Enno Boland (mail@eboland.de) - * @file rc_map.c - */ - -#include "../../include/sqsh_primitive_private.h" - -#include "../../include/sqsh_error.h" -#include "../utils/utils.h" -#include - -#if 0 -# include - -static void -debug_print(struct SqshRcMap *array, int index, char msg) { - fprintf(stderr, "ref_count_array: %i\n", index); - putc('[', stderr); - for (sqsh_index_t i = 0; i < array->size; ++i) { - if (array->ref_count[i] == 0) - putc('_', stderr); - else if (array->ref_count[i] >= 10) - putc('+', stderr); - else if (array->ref_count[i] < 0) - putc('<', stderr); - else - putc('0' + array->ref_count[i], stderr); - } - fputs("]\n", stderr); - putc(msg, stderr); - - for (sqsh_index_t i = 0; i < (size_t)index; ++i) { - putc(' ', stderr); - } - fputs("^\n", stderr); -} -#else -# define debug_print(...) -#endif - -int -sqsh__rc_map_init( - struct SqshRcMap *array, size_t size, size_t element_size, - sqsh_rc_map_cleanup_t cleanup) { - int rv = 0; - array->data = calloc(size, element_size); - if (array->data == NULL) { - rv = -SQSH_ERROR_MALLOC_FAILED; - goto out; - } - array->ref_count = calloc(size, sizeof(*array->ref_count)); - if (array->ref_count == NULL) { - rv = -SQSH_ERROR_MALLOC_FAILED; - goto out; - } - - array->size = size; - array->cleanup = cleanup; - array->element_size = element_size; -out: - if (rv < 0) { - sqsh__rc_map_cleanup(array); - } - return rv; -} - -static void * -get_element(struct SqshRcMap *array, sqsh_index_t index) { - sqsh_index_t offset; - - if (SQSH_MULT_OVERFLOW(index, array->element_size, &offset)) { - return NULL; - } - - return (void *)&array->data[offset]; -} - -int -retain_rc(struct SqshRcMap *array, sqsh_index_t index) { - int ref_count = ++array->ref_count[index]; - - assert(ref_count >= 1); - debug_print(array, index, '+'); - - return ref_count; -} - -int -release_rc(struct SqshRcMap *array, sqsh_index_t index) { - int ref_count = --array->ref_count[index]; - - debug_print(array, index, '-'); - - assert(ref_count >= 0); - - return ref_count; -} - -bool -sqsh__rc_map_is_empty(struct SqshRcMap *array, sqsh_index_t index) { - return array->ref_count[index] == 0; -} - -const void * -sqsh__rc_map_set(struct SqshRcMap *array, sqsh_index_t index, void *data) { - void *target; - - target = get_element(array, index); - - /* If the element is already in the array, cleanup the new data and retain - * the old. */ - if (sqsh__rc_map_is_empty(array, index) == false) { - array->cleanup(data); - return sqsh__rc_map_retain(array, index); - } - - memcpy(target, data, array->element_size); - - retain_rc(array, index); - - return target; -} - -const void * -sqsh__rc_map_retain(struct SqshRcMap *array, sqsh_index_t index) { - void *data = NULL; - - if (sqsh__rc_map_is_empty(array, index) == false) { - retain_rc(array, index); - debug_print(array, index, '+'); - data = get_element(array, index); - } - - return data; -} - -int -sqsh__rc_map_release(struct SqshRcMap *array, const void *element) { - if (element == NULL) { - return 0; - } - - const sqsh_index_t index = - ((uint8_t *)element - array->data) / array->element_size; - - return sqsh__rc_map_release_index(array, index); -} - -int -sqsh__rc_map_release_index(struct SqshRcMap *array, sqsh_index_t index) { - int ref_count = release_rc(array, index); - - if (ref_count == 0) { - void *data = get_element(array, index); - array->cleanup(data); - } - - return 0; -} - -bool -sqsh__rc_map_contains(struct SqshRcMap *array, const void *element) { - const uint8_t *needle = (uint8_t *)element; - - if (needle == NULL) { - return false; - } - - if (needle < array->data) { - return false; - } - - if (needle >= &array->data[array->size * array->element_size]) { - return false; - } - - return true; -} - -size_t -sqsh__rc_map_size(const struct SqshRcMap *array) { - return array->size; -} - -int -sqsh__rc_map_cleanup(struct SqshRcMap *array) { -#ifndef NDEBUG - if (array->ref_count != NULL) { - int acc = 0; - for (size_t i = 0; i < array->size; ++i) { - acc |= array->ref_count[i]; - } - assert(acc == 0); - } -#endif - free(array->data); - array->data = NULL; - free(array->ref_count); - array->ref_count = NULL; - array->size = 0; - - return 0; -} - -static const void * -lru_rc_map_retain(void *backend, sqsh_index_t index) { - return sqsh__rc_map_retain(backend, index); -} - -static int -lru_rc_map_release(void *backend, sqsh_index_t index) { - return sqsh__rc_map_release_index(backend, index); -} - -const struct SqshLruBackendImpl sqsh__lru_rc_map = { - .retain = lru_rc_map_retain, - .release = lru_rc_map_release, -}; diff --git a/lib/reader/reader.c b/lib/reader/reader.c index da5102fc6..7fed47aea 100644 --- a/lib/reader/reader.c +++ b/lib/reader/reader.c @@ -97,7 +97,7 @@ sqsh__reader_init( reader->iterator_offset = 0; reader->iterator_impl = iterator_impl; reader->iterator = iterator; - return sqsh__buffer_init(&reader->buffer); + return cx_buffer_init(&reader->buffer); } /** @@ -115,16 +115,16 @@ reader_fill_buffer(struct SqshReader *reader, size_t size) { int rv = 0; void *iterator = reader->iterator; const struct SqshReaderIteratorImpl *impl = reader->iterator_impl; - struct SqshBuffer *buffer = &reader->buffer; + struct CxBuffer *buffer = &reader->buffer; sqsh_index_t offset = reader->offset; sqsh_index_t iterator_offset = reader->iterator_offset; - size_t remaining_size = size - sqsh__buffer_size(buffer); + size_t remaining_size = size - cx_buffer_size(buffer); for (;;) { const uint8_t *data = impl->data(iterator); const size_t data_size = impl->size(iterator); const size_t copy_size = SQSH_MIN(data_size - offset, remaining_size); - rv = sqsh__buffer_append(buffer, &data[offset], copy_size); + rv = cx_buffer_append(buffer, &data[offset], copy_size); if (rv < 0) { goto out; } @@ -142,12 +142,12 @@ reader_fill_buffer(struct SqshReader *reader, size_t size) { } } - assert(size == sqsh__buffer_size(buffer)); + assert(size == cx_buffer_size(buffer)); assert(iterator_offset != 0); reader->iterator_offset = iterator_offset; reader->offset = 0; - reader->data = sqsh__buffer_data(buffer); + reader->data = cx_buffer_data(buffer); reader->size = size; out: return rv; @@ -156,24 +156,24 @@ reader_fill_buffer(struct SqshReader *reader, size_t size) { static int handle_buffered(struct SqshReader *reader, sqsh_index_t offset, size_t size) { int rv = 0; - struct SqshBuffer new_buffer = {0}; + struct CxBuffer new_buffer = {0}; sqsh_index_t iterator_offset = reader->iterator_offset; - struct SqshBuffer *buffer = &reader->buffer; - const uint8_t *buffer_data = sqsh__buffer_data(buffer); - size_t buffer_size = sqsh__buffer_size(buffer); + struct CxBuffer *buffer = &reader->buffer; + const uint8_t *buffer_data = cx_buffer_data(buffer); + size_t buffer_size = cx_buffer_size(buffer); const size_t copy_size = buffer_size - offset; if (offset != 0) { - rv = sqsh__buffer_init(&new_buffer); + rv = cx_buffer_init(&new_buffer); if (rv < 0) { goto out; } - rv = sqsh__buffer_append(&new_buffer, &buffer_data[offset], copy_size); + rv = cx_buffer_append(&new_buffer, &buffer_data[offset], copy_size); if (rv < 0) { goto out; } - rv = sqsh__buffer_move(buffer, &new_buffer); + rv = cx_buffer_move(buffer, &new_buffer); if (rv < 0) { goto out; } @@ -213,8 +213,8 @@ handle_mapped(struct SqshReader *reader, sqsh_index_t offset, size_t size) { reader->data = &data[offset]; reader->size = size; } else { - struct SqshBuffer *buffer = &reader->buffer; - sqsh__buffer_drain(buffer); + struct CxBuffer *buffer = &reader->buffer; + cx_buffer_drain(buffer); rv = reader_fill_buffer(reader, size); } @@ -246,5 +246,5 @@ sqsh__reader_size(const struct SqshReader *reader) { int sqsh__reader_cleanup(struct SqshReader *reader) { - return sqsh__buffer_cleanup(&reader->buffer); + return cx_buffer_cleanup(&reader->buffer); } diff --git a/meson.build b/meson.build index 075c85a78..dc3a1b341 100644 --- a/meson.build +++ b/meson.build @@ -27,6 +27,7 @@ lz4_dep = dependency('liblz4', required: get_option('lz4')) lzma_dep = dependency('liblzma', required: get_option('lzma')) zlib_dep = dependency('zlib', required: get_option('zlib')) zstd_dep = dependency('libzstd', required: get_option('zstd')) +cextras_dep = subproject('cextras').get_variable('cextras_dep') subdir('include') diff --git a/subprojects/cextras.wrap b/subprojects/cextras.wrap index 4e833fb83..63a0e304f 100644 --- a/subprojects/cextras.wrap +++ b/subprojects/cextras.wrap @@ -1,6 +1,6 @@ [wrap-git] url=https://github.com/Gottox/cextras.git -revision=main +revision=9a39123923ccefd5939a30fb163c3df0e823db97 depth=1 [provide] diff --git a/test/extract/extract_manager.c b/test/extract/extract_manager.c index a45a03dc3..a5f524cc7 100644 --- a/test/extract/extract_manager.c +++ b/test/extract/extract_manager.c @@ -45,7 +45,7 @@ decompress(void) { int rv; struct SqshArchive archive = {0}; struct SqshExtractManager manager = {0}; - const struct SqshBuffer *buffer = NULL; + const struct CxBuffer *buffer = NULL; uint8_t payload[8192] = {SQSH_HEADER, ZLIB_ABCD}; mk_stub(&archive, payload, sizeof(payload)); @@ -65,8 +65,8 @@ decompress(void) { rv = sqsh__extract_manager_uncompress(&manager, &reader, &buffer); assert(rv == 0); assert(buffer != NULL); - assert(sqsh__buffer_size(buffer) == 4); - assert(memcmp(sqsh__buffer_data(buffer), "abcd", 4) == 0); + assert(cx_buffer_size(buffer) == 4); + assert(memcmp(cx_buffer_data(buffer), "abcd", 4) == 0); sqsh__map_reader_cleanup(&reader); sqsh__extract_manager_release(&manager, buffer); @@ -79,8 +79,8 @@ decompress_and_cached(void) { int rv; struct SqshArchive archive = {0}; struct SqshExtractManager manager = {0}; - const struct SqshBuffer *buffer = NULL; - const struct SqshBuffer *cached_buffer = NULL; + const struct CxBuffer *buffer = NULL; + const struct CxBuffer *cached_buffer = NULL; uint8_t payload[8192] = {SQSH_HEADER, ZLIB_ABCD}; mk_stub(&archive, payload, sizeof(payload)); @@ -100,8 +100,8 @@ decompress_and_cached(void) { rv = sqsh__extract_manager_uncompress(&manager, &reader, &buffer); assert(rv == 0); assert(buffer != NULL); - assert(sqsh__buffer_size(buffer) == 4); - assert(memcmp(sqsh__buffer_data(buffer), "abcd", 4) == 0); + assert(cx_buffer_size(buffer) == 4); + assert(memcmp(cx_buffer_data(buffer), "abcd", 4) == 0); rv = sqsh__extract_manager_uncompress(&manager, &reader, &cached_buffer); assert(rv == 0); diff --git a/test/meson.build b/test/meson.build index a7829c4cf..5cd48e04f 100644 --- a/test/meson.build +++ b/test/meson.build @@ -29,10 +29,6 @@ sqsh_test = [ 'metablock/metablock_reader.c', 'nasty.c', 'reader/reader.c', - 'primitive/buffer.c', - 'primitive/lru.c', - 'primitive/rc_hash_map.c', - 'primitive/rc_map.c', 'tree/walker.c', 'xattr/xattr_iterator.c', ] @@ -107,7 +103,7 @@ foreach p : sqsh_test install: false, c_args: this_c_args, link_with: libsqsh.get_static_lib(), - dependencies: [threads_dep, testlib_dep], + dependencies: [threads_dep, testlib_dep, cextras_dep], ) test(p, t) endforeach diff --git a/test/metablock/metablock_iterator.c b/test/metablock/metablock_iterator.c index 3b625b15f..ef924e0b2 100644 --- a/test/metablock/metablock_iterator.c +++ b/test/metablock/metablock_iterator.c @@ -59,7 +59,6 @@ next_once(void) { assert(rv == 0); assert(has_next); - assert(sqsh__metablock_iterator_size(&iter) == 4); p = sqsh__metablock_iterator_data(&iter); diff --git a/test/primitive/buffer.c b/test/primitive/buffer.c deleted file mode 100644 index 7ac9d1e26..000000000 --- a/test/primitive/buffer.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * BSD 2-Clause License - * - * Copyright (c) 2023, Enno Boland - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * @author Enno Boland (mail@eboland.de) - * @file buffer.c - */ - -#include "../common.h" -#include - -#include "../../include/sqsh_primitive_private.h" - -static void -init_buffer(void) { - int rv; - struct SqshBuffer buffer = {0}; - - rv = sqsh__buffer_init(&buffer); - assert(rv == 0); - rv = sqsh__buffer_cleanup(&buffer); - assert(rv == 0); -} - -static void -append_to_buffer(void) { - int rv; - struct SqshBuffer buffer = {0}; - - rv = sqsh__buffer_init(&buffer); - assert(rv == 0); - - const uint8_t hello_world[] = "Hello World"; - rv = sqsh__buffer_append(&buffer, hello_world, sizeof(hello_world)); - assert(rv == 0); - rv = sqsh__buffer_append(&buffer, hello_world, sizeof(hello_world)); - assert(rv == 0); - - const uint8_t *data = sqsh__buffer_data(&buffer); - rv = memcmp(data, "Hello World\0Hello World\0", sizeof(hello_world) * 2); - assert(rv == 0); - - rv = sqsh__buffer_cleanup(&buffer); - assert(rv == 0); -} - -DECLARE_TESTS -TEST(init_buffer) -TEST(append_to_buffer) -END_TESTS diff --git a/test/primitive/lru.c b/test/primitive/lru.c deleted file mode 100644 index f8cdd4ba2..000000000 --- a/test/primitive/lru.c +++ /dev/null @@ -1,223 +0,0 @@ -/* - * BSD 2-Clause License - * - * Copyright (c) 2023, Enno Boland - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * @author Enno Boland (mail@eboland.de) - * @file rc_map.c - */ - -#include "../common.h" -#include - -#include "../../include/sqsh_primitive_private.h" - -#include -#include -#include - -static atomic_uint rc_map_deinit_calls = 0; - -static void -deinit(void *data) { - uint8_t *data_ptr = data; - *data_ptr = UINT8_MAX; - rc_map_deinit_calls++; -} - -static void -lru_map(void) { - int rv; - struct SqshLru lru = {0}; - struct SqshRcMap map = {0}; - - rv = sqsh__rc_map_init(&map, 128, sizeof(uint8_t), deinit); - assert(rv == 0); - - rv = sqsh__lru_init(&lru, 10, &sqsh__lru_rc_map, &map); - assert(rv == 0); - - rv = sqsh__lru_cleanup(&lru); - assert(rv == 0); - - rv = sqsh__rc_map_cleanup(&map); - assert(rv == 0); -} - -static void -lru_hash_map(void) { - int rv; - struct SqshLru lru = {0}; - struct SqshRcHashMap map = {0}; - - rv = sqsh__rc_hash_map_init(&map, 128, sizeof(uint8_t), deinit); - assert(rv == 0); - - rv = sqsh__lru_init(&lru, 10, &sqsh__lru_rc_hash_map, &map); - assert(rv == 0); - - rv = sqsh__lru_cleanup(&lru); - assert(rv == 0); - - rv = sqsh__rc_hash_map_cleanup(&map); - assert(rv == 0); -} - -static void -lru_hash_map_insert_and_retain(void) { - int rv; - struct SqshLru lru = {0}; - struct SqshRcHashMap map = {0}; - uint8_t data = 23; - const uint8_t *ptr; - - rv = sqsh__rc_hash_map_init(&map, 128, sizeof(uint8_t), deinit); - assert(rv == 0); - - rv = sqsh__lru_init(&lru, 10, &sqsh__lru_rc_hash_map, &map); - assert(rv == 0); - - ptr = sqsh__rc_hash_map_put(&map, 42, &data); - rv = sqsh__lru_touch(&lru, 42); - assert(rv == 0); - - sqsh__rc_hash_map_release(&map, ptr); - - rv = sqsh__lru_cleanup(&lru); - assert(rv == 0); - - rv = sqsh__rc_hash_map_cleanup(&map); - assert(rv == 0); -} - -static void -lru_hash_map_insert_and_retain_twice(void) { - int rv; - struct SqshLru lru = {0}; - struct SqshRcHashMap map = {0}; - uint8_t data = 23; - const uint8_t *ptr; - - rv = sqsh__rc_hash_map_init(&map, 128, sizeof(uint8_t), deinit); - assert(rv == 0); - - rv = sqsh__lru_init(&lru, 10, &sqsh__lru_rc_hash_map, &map); - assert(rv == 0); - - ptr = sqsh__rc_hash_map_put(&map, 42, &data); - rv = sqsh__lru_touch(&lru, 42); - assert(rv == 0); - sqsh__rc_hash_map_release(&map, ptr); - - ptr = sqsh__rc_hash_map_put(&map, 36, &data); - rv = sqsh__lru_touch(&lru, 36); - assert(rv == 0); - - rv = sqsh__lru_touch(&lru, 42); - assert(rv == 0); - - sqsh__rc_hash_map_release(&map, ptr); - - rv = sqsh__lru_cleanup(&lru); - assert(rv == 0); - - rv = sqsh__rc_hash_map_cleanup(&map); - assert(rv == 0); -} - -static void -lru_hash_map_insert_and_retain_overflow(void) { - int rv; - struct SqshLru lru = {0}; - struct SqshRcHashMap map = {0}; - uint8_t data = 232; - const uint8_t *ptr; - - rv = sqsh__rc_hash_map_init(&map, 10, sizeof(uint8_t), deinit); - assert(rv == 0); - - rv = sqsh__lru_init(&lru, 10, &sqsh__lru_rc_hash_map, &map); - assert(rv == 0); - - ptr = sqsh__rc_hash_map_put(&map, 0, &data); - rv = sqsh__lru_touch(&lru, 0); - assert(rv == 0); - sqsh__rc_hash_map_release(&map, ptr); - - ptr = sqsh__rc_hash_map_put(&map, 1, &data); - rv = sqsh__lru_touch(&lru, 1); - assert(rv == 0); - sqsh__rc_hash_map_release(&map, ptr); - - ptr = sqsh__rc_hash_map_put(&map, 2, &data); - rv = sqsh__lru_touch(&lru, 2); - assert(rv == 0); - sqsh__rc_hash_map_release(&map, ptr); - - rv = sqsh__lru_touch(&lru, 0); - assert(rv == 0); - rv = sqsh__lru_touch(&lru, 1); - assert(rv == 0); - - rv = sqsh__lru_touch(&lru, 0); - assert(rv == 0); - rv = sqsh__lru_touch(&lru, 1); - assert(rv == 0); - - rv = sqsh__lru_touch(&lru, 0); - assert(rv == 0); - rv = sqsh__lru_touch(&lru, 1); - assert(rv == 0); - - rv = sqsh__lru_touch(&lru, 0); - assert(rv == 0); - rv = sqsh__lru_touch(&lru, 1); - assert(rv == 0); - - rv = sqsh__lru_touch(&lru, 0); - assert(rv == 0); - rv = sqsh__lru_touch(&lru, 1); - assert(rv == 0); - - ptr = sqsh__rc_hash_map_retain(&map, 2); - assert(ptr == NULL); - - rv = sqsh__lru_cleanup(&lru); - assert(rv == 0); - - rv = sqsh__rc_hash_map_cleanup(&map); - assert(rv == 0); -} - -DECLARE_TESTS -TEST(lru_map) -TEST(lru_hash_map) -TEST(lru_hash_map_insert_and_retain) -TEST(lru_hash_map_insert_and_retain_twice) -TEST(lru_hash_map_insert_and_retain_overflow) -END_TESTS diff --git a/test/primitive/rc_hash_map.c b/test/primitive/rc_hash_map.c deleted file mode 100644 index 445490bca..000000000 --- a/test/primitive/rc_hash_map.c +++ /dev/null @@ -1,132 +0,0 @@ -/* - * BSD 2-Clause License - * - * Copyright (c) 2023, Enno Boland - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * @author Enno Boland (mail@eboland.de) - * @file rc_map.c - */ - -#include "../common.h" -#include - -#include "../../include/sqsh_primitive_private.h" - -#include -#include -#include - -static atomic_uint rc_hash_map_deinit_calls = 0; - -static void -rc_hash_map_deinit(void *data) { - uint8_t *data_ptr = data; - *data_ptr = UINT8_MAX; - rc_hash_map_deinit_calls++; -} - -static void -init_rc_hash_map(void) { - int rv; - struct SqshRcHashMap map; - - rv = sqsh__rc_hash_map_init(&map, 128, sizeof(uint8_t), rc_hash_map_deinit); - assert(rv == 0); - - rv = sqsh__rc_hash_map_cleanup(&map); - assert(rv == 0); -} - -static void -set_and_get_element(void) { - int rv; - struct SqshRcHashMap map; - uint8_t data = 23; - - rv = sqsh__rc_hash_map_init(&map, 128, sizeof(uint8_t), rc_hash_map_deinit); - assert(rv == 0); - - uint64_t key = 4242424; - const uint8_t *set_ptr = sqsh__rc_hash_map_put(&map, key, &data); - assert(rv == 0); - assert(set_ptr != &data); - - const uint8_t *get_ptr = sqsh__rc_hash_map_retain(&map, key); - assert(rv == 0); - assert(get_ptr != &data); - assert(*get_ptr == data); - - sqsh__rc_hash_map_release(&map, set_ptr); - sqsh__rc_hash_map_release(&map, get_ptr); - - rv = sqsh__rc_hash_map_cleanup(&map); - assert(rv == 0); -} - -static void -check_overflow(void) { - int rv; - struct SqshRcHashMap map; - uint8_t data = 1; - const uint8_t *ptr; - - rv = sqsh__rc_hash_map_init(&map, 4, sizeof(uint8_t), rc_hash_map_deinit); - assert(rv == 0); - - ptr = sqsh__rc_hash_map_put(&map, 1, &data); - assert(*ptr == data); - ptr = sqsh__rc_hash_map_put(&map, 2, &data); - assert(*ptr == data); - ptr = sqsh__rc_hash_map_put(&map, 3, &data); - assert(*ptr == data); - ptr = sqsh__rc_hash_map_put(&map, 4, &data); - assert(*ptr == data); - data = 42; - ptr = sqsh__rc_hash_map_put(&map, 5, &data); - assert(*ptr == data); - - const uint8_t *get_ptr = sqsh__rc_hash_map_retain(&map, 5); - assert(rv == 0); - assert(*get_ptr == 42); - sqsh__rc_hash_map_release(&map, get_ptr); - - sqsh__rc_hash_map_release_key(&map, 1); - sqsh__rc_hash_map_release_key(&map, 2); - sqsh__rc_hash_map_release_key(&map, 3); - sqsh__rc_hash_map_release_key(&map, 4); - sqsh__rc_hash_map_release_key(&map, 5); - - rv = sqsh__rc_hash_map_cleanup(&map); - assert(rv == 0); -} - -DECLARE_TESTS -TEST(init_rc_hash_map) -TEST(set_and_get_element) -TEST(check_overflow) -END_TESTS diff --git a/test/primitive/rc_map.c b/test/primitive/rc_map.c deleted file mode 100644 index ffeedca5f..000000000 --- a/test/primitive/rc_map.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * BSD 2-Clause License - * - * Copyright (c) 2023, Enno Boland - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * @author Enno Boland (mail@eboland.de) - * @file rc_map.c - */ - -#include "../common.h" -#include - -#include "../../include/sqsh_primitive_private.h" - -#include -#include -#include - -static atomic_uint rc_map_deinit_calls = 0; - -static void -rc_map_deinit(void *data) { - uint8_t *data_ptr = data; - *data_ptr = UINT8_MAX; - rc_map_deinit_calls++; -} - -static void -init_rc_map(void) { - int rv; - struct SqshRcMap map; - - rv = sqsh__rc_map_init(&map, 128, sizeof(uint8_t), rc_map_deinit); - assert(rv == 0); - - rv = sqsh__rc_map_cleanup(&map); - assert(rv == 0); -} - -static void -set_and_get_element(void) { - int rv; - struct SqshRcMap map; - uint8_t data = 23; - - rv = sqsh__rc_map_init(&map, 128, sizeof(uint8_t), rc_map_deinit); - assert(rv == 0); - - sqsh_index_t index = 42; - const uint8_t *set_ptr = sqsh__rc_map_set(&map, index, &data); - assert(rv == 0); - assert(set_ptr != &data); - - const uint8_t *get_ptr = sqsh__rc_map_retain(&map, index); - assert(rv == 0); - assert(get_ptr != &data); - assert(get_ptr == get_ptr); - sqsh__rc_map_release(&map, get_ptr); - - sqsh__rc_map_release(&map, set_ptr); - - rv = sqsh__rc_map_cleanup(&map); - assert(rv == 0); -} - -DECLARE_TESTS -TEST(init_rc_map) -TEST(set_and_get_element) -END_TESTS diff --git a/test/read-chunk.c b/test/read-chunk.c index 1c35ae65c..d9ab2cb5c 100644 --- a/test/read-chunk.c +++ b/test/read-chunk.c @@ -8,7 +8,6 @@ #include "../include/sqsh_easy.h" #include "../include/sqsh_error.h" #include "../include/sqsh_file.h" -#include "sqsh_archive_private.h" #include #include