blob: 8547c8db4f223d1e8b4f92db155791f6875a5b3e [file] [log] [blame]
/***************************************************************************/
/* */
/* ftmemory.h */
/* */
/* The FreeType memory management macros (specification). */
/* */
/* Copyright 1996-2001, 2002, 2004, 2005, 2006 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg */
/* */
/* This file is part of the FreeType project, and may only be used, */
/* modified, and distributed under the terms of the FreeType project */
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
/* this file you indicate that you have read the license and */
/* understand and accept it fully. */
/* */
/***************************************************************************/
#ifndef __FTMEMORY_H__
#define __FTMEMORY_H__
#include <ft2build.h>
#include FT_CONFIG_CONFIG_H
#include FT_TYPES_H
FT_BEGIN_HEADER
/*************************************************************************/
/* */
/* <Macro> */
/* FT_SET_ERROR */
/* */
/* <Description> */
/* This macro is used to set an implicit `error' variable to a given */
/* expression's value (usually a function call), and convert it to a */
/* boolean which is set whenever the value is != 0. */
/* */
#undef FT_SET_ERROR
#define FT_SET_ERROR( expression ) \
( ( error = (expression) ) != 0 )
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
/**** ****/
/**** ****/
/**** M E M O R Y ****/
/**** ****/
/**** ****/
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
#ifdef FT_STRICT_ALIASING
/*
* The allocation functions return a pointer, and the error code
* is written to through the `p_error' parameter. See below for
* for documentation.
*/
FT_BASE( FT_Pointer )
ft_mem_alloc( FT_Memory memory,
FT_Long size,
FT_Error *p_error );
FT_BASE( FT_Pointer )
ft_mem_qalloc( FT_Memory memory,
FT_Long size,
FT_Error *p_error );
FT_BASE( FT_Pointer )
ft_mem_realloc( FT_Memory memory,
FT_Long current,
FT_Long size,
void* block,
FT_Error *p_error );
FT_BASE( FT_Pointer )
ft_mem_qrealloc( FT_Memory memory,
FT_Long current,
FT_Long size,
void* block,
FT_Error *p_error );
FT_BASE( void )
ft_mem_free( FT_Memory memory,
const void* P );
#ifdef FT_DEBUG_MEMORY
FT_BASE( FT_Pointer )
ft_mem_alloc_debug( FT_Memory memory,
FT_Long size,
FT_Error *p_error,
const char* file_name,
FT_Long line_no );
FT_BASE( FT_Pointer )
ft_mem_qalloc_debug( FT_Memory memory,
FT_Long size,
FT_Error *p_error,
const char* file_name,
FT_Long line_no );
FT_BASE( FT_Pointer )
ft_mem_realloc_debug( FT_Memory memory,
FT_Long current,
FT_Long size,
void* P,
FT_Error *p_error,
const char* file_name,
FT_Long line_no );
FT_BASE( FT_Pointer )
ft_mem_qrealloc_debug( FT_Memory memory,
FT_Long current,
FT_Long size,
void* P,
FT_Error *p_error,
const char* file_name,
FT_Long line_no );
FT_BASE( void )
ft_mem_free_debug( FT_Memory memory,
const void *P,
const char* file_name,
FT_Long line_no );
#define FT_MEM_ALLOC( _pointer_, _size_ ) \
(_pointer_) = ft_mem_alloc_debug( memory, _size_, &error, \
__FILE__, __LINE__ )
#define FT_MEM_REALLOC( _pointer_, _current_, _size_ ) \
(_pointer_) = ft_mem_realloc_debug( memory, _current_, _size_, \
(_pointer_), &error, \
__FILE__, __LINE__ )
#define FT_MEM_QALLOC( _pointer_, _size_ ) \
(_pointer_) = ft_mem_qalloc_debug( memory, _size_, &error, \
__FILE__, __LINE__ )
#define FT_MEM_QREALLOC( _pointer_, _current_, _size_ ) \
(_pointer_) = ft_mem_qrealloc_debug( memory, _current_, _size_, \
(_pointer_), &error, \
__FILE__, __LINE__ )
#define FT_MEM_FREE( _pointer_ ) \
FT_BEGIN_STMNT \
if ( _pointer_ ) \
{ \
ft_mem_free_debug( memory, (_pointer_), __FILE__, __LINE__ ); \
(_pointer_) = NULL; \
} \
FT_END_STMNT
#else /* !FT_DEBUG_MEMORY */
#define FT_MEM_ALLOC( _pointer_, _size_ ) \
(_pointer_) = ft_mem_alloc( memory, _size_, &error )
#define FT_MEM_FREE( _pointer_ ) \
FT_BEGIN_STMNT \
if ( (_pointer_) ) \
{ \
ft_mem_free( memory, (_pointer_) ); \
(_pointer_) = NULL; \
} \
FT_END_STMNT
#define FT_MEM_REALLOC( _pointer_, _current_, _size_ ) \
(_pointer_) = ft_mem_realloc( memory, _current_, _size_, \
(_pointer_), &error )
#define FT_MEM_QALLOC( _pointer_, _size_ ) \
(_pointer_) = ft_mem_qalloc( memory, _size_, &error )
#define FT_MEM_QREALLOC( _pointer_, _current_, _size_ ) \
(_pointer_) = ft_mem_qrealloc( memory, _current_, _size_, \
(_pointer_), &error )
#endif /* !FT_DEBUG_MEMORY */
#define FT_MEM_SET_ERROR( cond ) ( (cond), error != 0 )
#else /* !FT_STRICT_ALIASING */
#ifdef FT_DEBUG_MEMORY
FT_BASE( FT_Error )
ft_mem_alloc_debug( FT_Memory memory,
FT_Long size,
void* *P,
const char* file_name,
FT_Long line_no );
FT_BASE( FT_Error )
ft_mem_qalloc_debug( FT_Memory memory,
FT_Long size,
void* *P,
const char* file_name,
FT_Long line_no );
FT_BASE( FT_Error )
ft_mem_realloc_debug( FT_Memory memory,
FT_Long current,
FT_Long size,
void* *P,
const char* file_name,
FT_Long line_no );
FT_BASE( FT_Error )
ft_mem_qrealloc_debug( FT_Memory memory,
FT_Long current,
FT_Long size,
void* *P,
const char* file_name,
FT_Long line_no );
FT_BASE( void )
ft_mem_free_debug( FT_Memory memory,
FT_Pointer block,
const char* file_name,
FT_Long line_no );
#endif /* FT_DEBUG_MEMORY */
/*************************************************************************/
/* */
/* <Function> */
/* ft_mem_alloc */
/* */
/* <Description> */
/* Allocates a new block of memory. The returned area is always */
/* zero-filled; this is a strong convention in many FreeType parts. */
/* */
/* <Input> */
/* memory :: A handle to a given `memory object' which handles */
/* allocation. */
/* */
/* size :: The size in bytes of the block to allocate. */
/* */
/* <Output> */
/* P :: A pointer to the fresh new block. It should be set to */
/* NULL if `size' is 0, or in case of error. */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
FT_BASE( FT_Error )
ft_mem_alloc( FT_Memory memory,
FT_Long size,
void* *P );
/*************************************************************************/
/* */
/* <Function> */
/* ft_mem_qalloc */
/* */
/* <Description> */
/* Allocates a new block of memory. The returned area is *not* */
/* zero-filled, making allocation quicker. */
/* */
/* <Input> */
/* memory :: A handle to a given `memory object' which handles */
/* allocation. */
/* */
/* size :: The size in bytes of the block to allocate. */
/* */
/* <Output> */
/* P :: A pointer to the fresh new block. It should be set to */
/* NULL if `size' is 0, or in case of error. */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
FT_BASE( FT_Error )
ft_mem_qalloc( FT_Memory memory,
FT_Long size,
void* *p );
/*************************************************************************/
/* */
/* <Function> */
/* ft_mem_realloc */
/* */
/* <Description> */
/* Reallocates a block of memory pointed to by `*P' to `Size' bytes */
/* from the heap, possibly changing `*P'. The returned area is */
/* zero-filled. */
/* */
/* <Input> */
/* memory :: A handle to a given `memory object' which handles */
/* reallocation. */
/* */
/* current :: The current block size in bytes. */
/* */
/* size :: The new block size in bytes. */
/* */
/* <InOut> */
/* P :: A pointer to the fresh new block. It should be set to */
/* NULL if `size' is 0, or in case of error. */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
/* <Note> */
/* All callers of ft_mem_realloc() _must_ provide the current block */
/* size as well as the new one. */
/* */
FT_BASE( FT_Error )
ft_mem_realloc( FT_Memory memory,
FT_Long current,
FT_Long size,
void* *P );
/*************************************************************************/
/* */
/* <Function> */
/* ft_mem_qrealloc */
/* */
/* <Description> */
/* Reallocates a block of memory pointed to by `*P' to `Size' bytes */
/* from the heap, possibly changing `*P'. The returned area is *not* */
/* zero-filled, making reallocation quicker. */
/* */
/* <Input> */
/* memory :: A handle to a given `memory object' which handles */
/* reallocation. */
/* */
/* current :: The current block size in bytes. */
/* */
/* size :: The new block size in bytes. */
/* */
/* <InOut> */
/* P :: A pointer to the fresh new block. It should be set to */
/* NULL if `size' is 0, or in case of error. */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
/* <Note> */
/* All callers of ft_mem_realloc() _must_ provide the current block */
/* size as well as the new one. */
/* */
FT_BASE( FT_Error )
ft_mem_qrealloc( FT_Memory memory,
FT_Long current,
FT_Long size,
void* *p );
/*************************************************************************/
/* */
/* <Function> */
/* ft_mem_free */
/* */
/* <Description> */
/* Releases a given block of memory allocated through ft_mem_alloc(). */
/* */
/* <Input> */
/* memory :: A handle to a given `memory object' which handles */
/* memory deallocation */
/* */
/* P :: This is the _address_ of a _pointer_ which points to the */
/* allocated block. It is always set to NULL on exit. */
/* */
/* <Note> */
/* If P or *P is NULL, this function should return successfully. */
/* This is a strong convention within all of FreeType and its */
/* drivers. */
/* */
FT_BASE( void )
ft_mem_free( FT_Memory memory,
void* *P );
#ifdef FT_DEBUG_MEMORY
#define FT_MEM_ALLOC( _pointer_, _size_ ) \
ft_mem_alloc_debug( memory, _size_, \
(void**)(void*)&(_pointer_), \
__FILE__, __LINE__ )
#define FT_MEM_REALLOC( _pointer_, _current_, _size_ ) \
ft_mem_realloc_debug( memory, _current_, _size_, \
(void**)(void*)&(_pointer_), \
__FILE__, __LINE__ )
#define FT_MEM_QALLOC( _pointer_, _size_ ) \
ft_mem_qalloc_debug( memory, _size_, \
(void**)(void*)&(_pointer_), \
__FILE__, __LINE__ )
#define FT_MEM_QREALLOC( _pointer_, _current_, _size_ ) \
ft_mem_qrealloc_debug( memory, _current_, _size_, \
(void**)(void*)&(_pointer_), \
__FILE__, __LINE__ )
#define FT_MEM_FREE( _pointer_ ) \
ft_mem_free_debug( memory, (void**)(void*)&(_pointer_), \
__FILE__, __LINE__ )
#else /* !FT_DEBUG_MEMORY */
#define FT_MEM_ALLOC( _pointer_, _size_ ) \
ft_mem_alloc( memory, _size_, \
(void**)(void*)&(_pointer_) )
#define FT_MEM_FREE( _pointer_ ) \
ft_mem_free( memory, \
(void**)(void*)&(_pointer_) )
#define FT_MEM_REALLOC( _pointer_, _current_, _size_ ) \
ft_mem_realloc( memory, _current_, _size_, \
(void**)(void*)&(_pointer_) )
#define FT_MEM_QALLOC( _pointer_, _size_ ) \
ft_mem_qalloc( memory, _size_, \
(void**)(void*)&(_pointer_) )
#define FT_MEM_QREALLOC( _pointer_, _current_, _size_ ) \
ft_mem_qrealloc( memory, _current_, _size_, \
(void**)(void*)&(_pointer_) )
#endif /* !FT_DEBUG_MEMORY */
#define FT_MEM_SET_ERROR( cond ) ( ( error = (cond) ) != 0 )
#endif /* !FT_STRICT_ALIASING */
#define FT_MEM_SET( dest, byte, count ) ft_memset( dest, byte, count )
#define FT_MEM_COPY( dest, source, count ) ft_memcpy( dest, source, count )
#define FT_MEM_MOVE( dest, source, count ) ft_memmove( dest, source, count )
#define FT_MEM_ZERO( dest, count ) FT_MEM_SET( dest, 0, count )
#define FT_ZERO( p ) FT_MEM_ZERO( p, sizeof ( *(p) ) )
#define FT_ARRAY_ZERO( dest, count ) \
FT_MEM_ZERO( dest, (count) * sizeof ( *(dest) ) )
#define FT_ARRAY_COPY( dest, source, count ) \
FT_MEM_COPY( dest, source, (count) * sizeof ( *(dest) ) )
#define FT_ARRAY_MOVE( dest, source, count ) \
FT_MEM_MOVE( dest, source, (count) * sizeof ( *(dest) ) )
/*
* Return the maximum number of adressable elements in an array.
* We limit ourselves to INT_MAX, rather than UINT_MAX, to avoid
* any problems.
*/
#define FT_ARRAY_MAX( ptr ) ( FT_INT_MAX / sizeof ( *(ptr) ) )
#define FT_ARRAY_CHECK( ptr, count ) ( (count) <= FT_ARRAY_MAX( ptr ) )
/*************************************************************************/
/* */
/* The following functions macros expect that their pointer argument is */
/* _typed_ in order to automatically compute array element sizes. */
/* */
#define FT_MEM_NEW( _pointer_ ) \
FT_MEM_ALLOC( _pointer_, sizeof ( *(_pointer_) ) )
#define FT_MEM_NEW_ARRAY( _pointer_, _count_ ) \
FT_MEM_ALLOC( _pointer_, (_count_) * sizeof ( *(_pointer_) ) )
#define FT_MEM_RENEW_ARRAY( _pointer_, _old_, _new_ ) \
FT_MEM_REALLOC( _pointer_, (_old_) * sizeof ( *(_pointer_) ), \
(_new_) * sizeof ( *(_pointer_) ) )
#define FT_MEM_QNEW( _pointer_ ) \
FT_MEM_QALLOC( _pointer_, sizeof ( *(_pointer_) ) )
#define FT_MEM_QNEW_ARRAY( _pointer_, _count_ ) \
FT_MEM_QALLOC( _pointer_, (_count_) * sizeof ( *(_pointer_) ) )
#define FT_MEM_QRENEW_ARRAY( _pointer_, _old_, _new_ ) \
FT_MEM_QREALLOC( _pointer_, (_old_) * sizeof ( *(_pointer_) ), \
(_new_) * sizeof ( *(_pointer_) ) )
/*************************************************************************/
/* */
/* the following macros are obsolete but kept for compatibility reasons */
/* */
#define FT_MEM_ALLOC_ARRAY( _pointer_, _count_, _type_ ) \
FT_MEM_ALLOC( _pointer_, (_count_) * sizeof ( _type_ ) )
#define FT_MEM_REALLOC_ARRAY( _pointer_, _old_, _new_, _type_ ) \
FT_MEM_REALLOC( _pointer_, (_old_) * sizeof ( _type ), \
(_new_) * sizeof ( _type_ ) )
/*************************************************************************/
/* */
/* The following macros are variants of their FT_MEM_XXXX equivalents; */
/* they are used to set an _implicit_ `error' variable and return TRUE */
/* if an error occured (i.e., if 'error != 0'). */
/* */
#define FT_ALLOC( _pointer_, _size_ ) \
FT_MEM_SET_ERROR( FT_MEM_ALLOC( _pointer_, _size_ ) )
#define FT_REALLOC( _pointer_, _current_, _size_ ) \
FT_MEM_SET_ERROR( FT_MEM_REALLOC( _pointer_, _current_, _size_ ) )
#define FT_QALLOC( _pointer_, _size_ ) \
FT_MEM_SET_ERROR( FT_MEM_QALLOC( _pointer_, _size_ ) )
#define FT_QREALLOC( _pointer_, _current_, _size_ ) \
FT_MEM_SET_ERROR( FT_MEM_QREALLOC( _pointer_, _current_, _size_ ) )
#define FT_FREE( _pointer_ ) \
FT_MEM_FREE( _pointer_ )
#define FT_NEW( _pointer_ ) \
FT_ALLOC( _pointer_, sizeof ( *(_pointer_) ) )
#define FT_NEW_ARRAY( _pointer_, _count_ ) \
FT_ALLOC( _pointer_, sizeof ( *(_pointer_) ) * (_count_) )
#define FT_RENEW_ARRAY( _pointer_, _old_, _new_ ) \
FT_REALLOC( _pointer_, sizeof ( *(_pointer_) ) * (_old_), \
sizeof ( *(_pointer_) ) * (_new_) )
#define FT_QNEW( _pointer_ ) \
FT_QALLOC( _pointer_, sizeof ( *(_pointer_) ) )
#define FT_QNEW_ARRAY( _pointer_, _count_ ) \
FT_QALLOC( _pointer_, sizeof ( *(_pointer_) ) * (_count_) )
#define FT_QRENEW_ARRAY( _pointer_, _old_, _new_ ) \
FT_QREALLOC( _pointer_, sizeof ( *(_pointer_) ) * (_old_), \
sizeof ( *(_pointer_) ) * (_new_) )
#define FT_ALLOC_ARRAY( _pointer_, _count_, _type_ ) \
FT_ALLOC( _pointer_, (_count_) * sizeof ( _type_ ) )
#define FT_REALLOC_ARRAY( _pointer_, _old_, _new_, _type_ ) \
FT_REALLOC( _pointer_, (_old_) * sizeof ( _type_ ), \
(_new_) * sizeof ( _type_ ) )
#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
FT_BASE( FT_Error )
FT_Alloc( FT_Memory memory,
FT_Long size,
void* *P );
FT_BASE( FT_Error )
FT_QAlloc( FT_Memory memory,
FT_Long size,
void* *p );
FT_BASE( FT_Error )
FT_Realloc( FT_Memory memory,
FT_Long current,
FT_Long size,
void* *P );
FT_BASE( FT_Error )
FT_QRealloc( FT_Memory memory,
FT_Long current,
FT_Long size,
void* *p );
FT_BASE( void )
FT_Free( FT_Memory memory,
void* *P );
#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
/* */
FT_END_HEADER
#endif /* __FTMEMORY_H__ */
/* END */