/**
* \file lzma/memlimit.h
* \brief Memory usage limitter
*
* \author Copyright (C) 1999-2006 Igor Pavlov
* \author Copyright (C) 2007 Lasse Collin
*
* This library 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 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*/
#ifndef LZMA_H_INTERNAL
# error Never include this file directly. Use <lzma.h> instead.
#endif
/**
* \brief Opaque data type used with the memory usage limitting functions
*/
typedef struct lzma_memlimit_s lzma_memlimit;
/**
* \brief Allocates and initializes a new lzma_memlimit structure
*
* It is easy to make liblzma to use huge amounts of memory. This can
* be a problem especially with the decoder, since it a file requiring
* huge amounts of memory to uncompress could allow even a denial of
* service attack if the memory usage wasn't limited.
*
* liblzma provides a set of functions to control memory usage. Pointers
* to these functions can be used in lzma_allocator structure, which makes
* it easy to limit memory usage with liblzma.
*
* The memory limitter functions are not tied to limitting memory usage
* with liblzma itself. You can use them with anything you like.
*
* In multi-threaded applications, only one thread at once may use the same
* lzma_memlimit structure. If there is a need, this limitation may
* be removed in future versions without breaking the libary API/ABI.
*
* \param limit Initial memory usage limit in bytes
*
* \return Pointer to allocated and initialized lzma_memlimit
* structure. On error, NULL is returned. The reason behind
* an error is either that malloc() failed or that the given
* limit was so small that it didn't allow allocating even
* the lzma_memlimit structure itself.
*
* \note Excluding lzma_memlimit_usage(), the functions whose name begin
* lzma_memlimit_ can be used even if lzma_init() hasn't been
* called.
*/
extern lzma_memlimit *lzma_memlimit_create(size_t limit);
/**
* \brief Sets a new memory usage limit
*
* \param mem Pointer to a lzma_memlimit structure returned
* earlier by lzma_memry_limit_create().
* \param limit New memory usage limit
*
* The new usage limit may be smaller than the amount of memory currently
* allocated via *mem: New allocations will fail until enough memory has
* been freed or a new limit is set, but the existing allocatations will
* stay untouched.
*/
extern void lzma_memlimit_set(lzma_memlimit *mem, size_t limit);
/**
* \brief Gets the current memory usage limit
*/
extern size_t lzma_memlimit_get(const lzma_memlimit *mem);
/**
* \brief Gets the amount of currently allocated memory
*
* \note This value includes the sizes of some helper structures,
* thus it will always be larger than the total number of
* bytes allocated via lzma_memlimit_alloc().
*/
extern size_t lzma_memlimit_used(const lzma_memlimit *mem);
/**
* \brief Allocates memory with malloc() if memory limit allows
*
* \param mem Pointer to a lzma_memlimit structure returned
* earlier by lzma_memry_limit_create().
* \param nmemb Number of elements to allocate. While liblzma always
* sets this to one, this function still takes the
* value of nmemb into account to keep the function
* usable with zlib and libbzip2.
* \param size Size of an element.
*
* \return Pointer to memory allocated with malloc(nmemb * size),
* except if nmemb * size == 0 which returns malloc(1).
* On error, NULL is returned.
*
* \note This function assumes that nmemb * size is at maximum of
* SIZE_MAX. If it isn't, an overflow will occur resulting
* invalid amount of memory being allocated.
*/
extern void *lzma_memlimit_alloc(
lzma_memlimit *mem, size_t nmemb, size_t size);
/**
* \brief Removes the pointer from memory limitting list
*
* \param mem Pointer to a lzma_memlimit structure returned
* earlier by lzma_memry_limit_create().
* \param ptr Pointer returned earlier by lzma_memlimit_alloc().
*
* This function removes ptr from the internal list and decreases the
* counter of used memory accordingly. The ptr itself isn't freed. This is
* useful when Extra Records allocated by liblzma using lzma_memlimit
* are needed by the application and must not be freed when the
* lzma_memlimit structure is destroyed.
*
* It is OK to call this function with ptr that hasn't been allocated with
* lzma_memlimit_alloc(). In that case, this has no effect other than wasting
* a few CPU cycles.
*/
extern void lzma_memlimit_detach(lzma_memlimit *mem, void *ptr);
/**
* \brief Frees memory and updates the memory limit list
*
* This is like lzma_memlimit_detach() but also frees the given pointer.
*/
extern void lzma_memlimit_free(lzma_memlimit *mem, void *ptr);
/**
* \brief Frees the memory allocated for and by the memory usage limitter
*
* \param mem Pointer to memory limitter
* \param free_allocated If this is non-zero, all the memory allocated
* by lzma_memlimit_alloc() using *mem is also
* freed if it hasn't already been freed with
* lzma_memlimit_free(). Usually this should be
* set to true.
*/
extern void lzma_memlimit_end(
lzma_memlimit *mem, lzma_bool free_allocated);