/* SPDX-License-Identifier: LGPL-3.0-or-later */ /* * meta_writer.h - This file is part of libsquashfs * * Copyright (C) 2019 David Oberhollenzer * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program 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 Lesser General Public License * along with this program. If not, see . */ #ifndef SQFS_META_WRITER_H #define SQFS_META_WRITER_H #include "sqfs/predef.h" /** * @file meta_writer.h * * @brief Contains declarations for the @ref sqfs_meta_writer_t. */ /** * @struct sqfs_meta_writer_t * * @implements sqfs_object_t * * @brief Abstracts generating of meta data blocks, either in memory or * directly on disk. * * SquashFS stores meta data by dividing it into fixed size (8k) chunks * that are written to disk with a small header indicating the on-disk * size and whether it is compressed or not. * * Data written to meta data blocks doesn't have to be aligned, i.e. * SquashFS doesn't care if an object is written across two blocks. * * The main task of the meta data writer is to provide a simple append * function that transparently takes care of chopping data up into blocks, * compressing the blocks and pre-pending a header. * * This object is not copyable, i.e. @ref sqfs_copy will always return NULL. */ /** * @enum E_SQFS_META_WRITER_FLAGS * * @brief Possible flags for @ref sqfs_meta_writer_create. */ typedef enum { /** * @brief If set, keep finished blocks in memory. * * To write them to disk, explicitly call * @ref sqfs_meta_write_write_to_file. */ SQFS_META_WRITER_KEEP_IN_MEMORY = 0x01, SQFS_META_WRITER_ALL_FLAGS = 0x01, } E_SQFS_META_WRITER_FLAGS; #ifdef __cplusplus extern "C" { #endif /** * @brief Create a meta data writer. * * @memberof sqfs_meta_writer_t * * @note The meta writer internally keeps references to the pointers passed * to this function, so don't destroy them before destroying the * meta writer. * * @param file An output file to write the data to. * @param cmp A compressor to use. * @param flags A combination of @ref E_SQFS_META_WRITER_FLAGS. * * @return A pointer to a meta writer on success, NULL on allocation failure * or if an unknown flag was set. */ SQFS_API sqfs_meta_writer_t *sqfs_meta_writer_create(sqfs_file_t *file, sqfs_compressor_t *cmp, sqfs_u32 flags); /** * @brief Finish the current block, even if it isn't full yet. * * @memberof sqfs_meta_writer_t * * This function forces the meta writer to compress and store the block it * is currently writing to, even if it isn't full yet, and either write it * out to disk (or append it to the in memory chain if told to keep blocks * in memory). * * @param m A pointer to a meta data writer. * * @return Zero on success, an @ref E_SQFS_ERROR value on failure. */ SQFS_API int sqfs_meta_writer_flush(sqfs_meta_writer_t *m); /** * @brief Finish the current block, even if it isn't full yet. * * @memberof sqfs_meta_writer_t * * This function forces reads a speicifed number of bytes from a given data * block and appends it to the meta data block that the writer is currently * working on. If the block becomes full, it is compressed, written to disk * and a new block is started that the remaining data is written to. * * @param m A pointer to a meta data writer. * @param data A pointer to a chunk of data to append to the writer. * @param size The number of data bytes to append. * * @return Zero on success, an @ref E_SQFS_ERROR value on failure. */ SQFS_API int sqfs_meta_writer_append(sqfs_meta_writer_t *m, const void *data, size_t size); /** * @brief Query the current block start position and offset within the block * * @memberof sqfs_meta_writer_t * * Get the byte offset relative to the first block that the current block will * start at once it is written to disk and get the byte offset within this * block that the next call to @ref sqfs_meta_writer_append will start writing * data at. * * @param m A pointer to a meta data writer. * @param block_start Returns the offset of the current block from the first. * @param offset Returns an offset into the current block where the next write * starts. */ SQFS_API void sqfs_meta_writer_get_position(const sqfs_meta_writer_t *m, sqfs_u64 *block_start, sqfs_u32 *offset); /** * @brief Reset all internal state, including the current block start position. * * @memberof sqfs_meta_writer_t * * This functions forces the meta data writer to forget everything that * happened since it was created, so it can be recycled. * * The data written is not lost, unless it was kept in memory and never written * out to disk. */ SQFS_API void sqfs_meta_writer_reset(sqfs_meta_writer_t *m); /** * @brief Write all blocks collected in memory to disk * * @memberof sqfs_meta_writer_t * * If the meta writer was created with the flag set to store blocks in * memory instead of writing them to disk, calling this function forces * the meta writer to write out all blocks it collected so far. * * @return Zero on success, an @ref E_SQFS_ERROR value on failure. */ SQFS_API int sqfs_meta_write_write_to_file(sqfs_meta_writer_t *m); /** * @brief A convenience function for encoding and writing an inode * * @memberof sqfs_meta_writer_t * * The SquashFS inode table is essentially a series of meta data blocks * containing variable sized inodes. This function takes a generic inode * structure, encodes it and writes the result to a meta data writer * using @ref sqfs_meta_writer_append internally. * * @param iw A pointer to a meta data writer. * @param n A pointer to an inode. * * @return Zero on success, an @ref E_SQFS_ERROR value on failure. */ SQFS_API int sqfs_meta_writer_write_inode(sqfs_meta_writer_t *iw, const sqfs_inode_generic_t *n); #ifdef __cplusplus } #endif #endif /* SQFS_META_WRITER_H */