483 lines
14 KiB
C
483 lines
14 KiB
C
/*
|
|
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
* SCR_DyAr.h
|
|
* Scripts, Beaudet Christophe
|
|
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
*
|
|
*/
|
|
|
|
#ifndef __SCR_DyAr_h__Types
|
|
#define __SCR_DyAr_h__Types
|
|
|
|
#ifndef __Only_Types__
|
|
#define __SCR_DyAr_h__Undef
|
|
#define __Only_Types__
|
|
#endif /* !__Only_Types__ */
|
|
|
|
/*
|
|
*=================================================================================================
|
|
* Includes.
|
|
*=================================================================================================
|
|
*/
|
|
|
|
#ifdef __SCR_DyAr_h__Undef
|
|
#undef __Only_Types__
|
|
#undef __SCR_DyAr_h__Undef
|
|
#endif /* __SCR_DyAr_h__Undef */
|
|
|
|
/*
|
|
*=================================================================================================
|
|
* Constants.
|
|
*=================================================================================================
|
|
*/
|
|
|
|
/*
|
|
* To export code.
|
|
*/
|
|
#undef CPA_EXPORT
|
|
#if defined(CPA_WANTS_IMPORT)
|
|
#define CPA_EXPORT __declspec(dllimport)
|
|
#elif defined(CPA_WANTS_EXPORT)
|
|
#define CPA_EXPORT __declspec(dllexport)
|
|
#else /* CPA_WANTS_IMPORT */
|
|
#define CPA_EXPORT
|
|
#endif /* CPA_WANTS_IMPORT */
|
|
|
|
/*
|
|
* Base allocation (and reallocation) of a dynamic array
|
|
*/
|
|
#define SCR_C_ui_DyAr_BaseForAllocation 100
|
|
|
|
/*
|
|
*=================================================================================================
|
|
* Types.
|
|
*=================================================================================================
|
|
*/
|
|
|
|
/*
|
|
* Header of a dynamic element.
|
|
*/
|
|
typedef struct SCR_tdst_DyAr_Header_
|
|
{
|
|
#ifdef SCR_DM_ProtectedVersion
|
|
unsigned int uiSizeOf; /* Size of this structure for test in debug mod */
|
|
#endif /* SCR_DM_ProtectedVersion */
|
|
unsigned int uiIndexInArray; /* Index in dynamic array */
|
|
unsigned char ucMemLevel; /* Memory level */
|
|
} SCR_tdst_DyAr_Header;
|
|
|
|
/*
|
|
* State of an element.
|
|
*/
|
|
typedef enum SCR_tde_DyAr_State
|
|
{
|
|
SCR_EDAS_DyAr_Invalid = 0, /* Invalid entry : Error */
|
|
SCR_EDAS_DyAr_Free, /* Entry free */
|
|
SCR_EDAS_DyAr_Occupy, /* Entry occupy */
|
|
} SCR_tde_DyAr_State;
|
|
|
|
/*
|
|
* Structure that describes an element of a dynamic array.
|
|
*/
|
|
typedef struct SCR_tdst_DyAr_Element_
|
|
{
|
|
void *d_vElement; /* Real element */
|
|
SCR_tde_DyAr_State eState; /* State of the element */
|
|
} SCR_tdst_DyAr_Element;
|
|
|
|
/*
|
|
* Structure that describes the dynamic array
|
|
*/
|
|
typedef struct SCR_tdst_DyAr_Description_
|
|
{
|
|
SCR_tdst_DyAr_Element *d_stDynArray; /* Address of dynamic array */
|
|
unsigned int uiNumValues; /* Number of values in array */
|
|
unsigned int uiMaxValues; /* Max number of values in array */
|
|
} SCR_tdst_DyAr_Description;
|
|
|
|
#endif /* !__SCR_DyAr_h__Types */
|
|
|
|
/*
|
|
*=================================================================================================
|
|
* Macros.
|
|
*=================================================================================================
|
|
*/
|
|
|
|
#if !defined(__SCR_DyAr_h__Macros) && !defined(__Only_Types__)
|
|
#define __SCR_DyAr_h__Macros
|
|
|
|
/*
|
|
* To add a new element of a specific type in a dynamic array.
|
|
* _Cast : Cast of structure to add.
|
|
* _Pos : To receive position of new allocated structure in dynamic array.
|
|
* _Pointer : To receive address of new allocated structure.
|
|
* _Array : Array concerned.
|
|
* _InitMem : Must reset memory allocation ?
|
|
*
|
|
* ALLOCATION IS IN BLOCK 0 FOR STATIC ELEMENTS.
|
|
*/
|
|
#define SCR_M_DyAr_AddElementStatic(_Cast, _Pos, _Pointer, _Array)\
|
|
{\
|
|
/*
|
|
* Allocate a place in dynamic array.
|
|
*/\
|
|
fn_v_Mem_SetMode(0);\
|
|
_Pos = fn_ui_DyAr_AllocateElement(&_Array, 1);\
|
|
/*
|
|
* Allocate a new structure if it's not already here.
|
|
*/\
|
|
/* Init current memory level of element */\
|
|
if((_Array).d_stDynArray[_Pos].d_vElement == NULL)\
|
|
{\
|
|
fn_v_Mem_SetMode(0);\
|
|
SCR_M_Mem_AllocAndSet(_Cast, _Pointer, 1);\
|
|
/*
|
|
* Initialize context in array.
|
|
*/\
|
|
(_Array).d_stDynArray[_Pos].d_vElement = _Pointer;\
|
|
SCR_M_Dbg_UpdateSizeOf_P(_Cast, _Pointer);\
|
|
}\
|
|
/*
|
|
* We initialize _Pointer with already allocated structure.
|
|
*/\
|
|
else\
|
|
{\
|
|
_Pointer = (_Cast *) (_Array).d_stDynArray[_Pos].d_vElement;\
|
|
SCR_M_Dbg_AssertStruct_P(_Cast, _Pointer);\
|
|
}\
|
|
/*
|
|
* It is now occupy...
|
|
*/\
|
|
(_Pointer)->stHeader.uiIndexInArray = _Pos;\
|
|
(_Pointer)->stHeader.ucMemLevel = 0;\
|
|
(_Array).d_stDynArray[_Pos].eState = SCR_EDAS_DyAr_Occupy;\
|
|
}
|
|
|
|
#define SCR_M_DyAr_AddElement(_Cast, _Pos, _Pointer, _Array)\
|
|
{\
|
|
/*
|
|
* Allocate a place in dynamic array.
|
|
*/\
|
|
fn_v_Mem_SetMode(0);\
|
|
_Pos = fn_ui_DyAr_AllocateElement(&_Array, 0);\
|
|
/*
|
|
* Allocate a new structure.
|
|
* Allocation depend on current memory level.
|
|
*/\
|
|
fn_v_Mem_SetMode(g_uc_Mem_CurrentMemLevel);\
|
|
SCR_M_Mem_Alloc(_Cast, _Pointer, 1);\
|
|
/*
|
|
* Initialize context in array.
|
|
*/\
|
|
(_Array).d_stDynArray[_Pos].d_vElement = (_Pointer);\
|
|
SCR_M_Dbg_UpdateSizeOf_P(_Cast, _Pointer);\
|
|
/*
|
|
* It is now occupy...
|
|
*/\
|
|
(_Pointer)->stHeader.uiIndexInArray = _Pos;\
|
|
(_Pointer)->stHeader.ucMemLevel = g_uc_Mem_CurrentMemLevel;\
|
|
(_Array).d_stDynArray[_Pos].eState = SCR_EDAS_DyAr_Occupy;\
|
|
}
|
|
|
|
#define SCR_M_DyAr_AddElementNoAlloc(_Pos, _Pointer, _Array)\
|
|
{\
|
|
/*
|
|
* Allocate a place in dynamic array.
|
|
*/\
|
|
fn_v_Mem_SetMode(0);\
|
|
_Pos = fn_ui_DyAr_AllocateElement(&_Array, 0);\
|
|
/*
|
|
* Initialize context in array.
|
|
*/\
|
|
(_Array).d_stDynArray[_Pos].d_vElement = (_Pointer);\
|
|
/*
|
|
* It is now occupy...
|
|
*/\
|
|
(_Pointer)->stHeader.uiIndexInArray = _Pos;\
|
|
(_Array).d_stDynArray[_Pos].eState = SCR_EDAS_DyAr_Occupy;\
|
|
}
|
|
|
|
/*
|
|
* To delete an element.
|
|
* _Cast : Cast of an element in array.
|
|
* _Pos : Position of element to delete.
|
|
* _Array : Array to delete the element.
|
|
* _Code : Code to free inside the element.
|
|
*/
|
|
#define SCR_M_DyAr_DeleteElement(_Cast, _Pos, _Array, _Code)\
|
|
{\
|
|
SCR_tdst_DyAr_Element *_p_stElement_;\
|
|
_Cast *_p_stPointer_;\
|
|
unsigned int _uiDPos_ = _Pos;\
|
|
/*
|
|
* Mark the element to be free.
|
|
*/\
|
|
_p_stElement_ = &(_Array)->d_stDynArray[_uiDPos_];\
|
|
_p_stElement_->eState = SCR_EDAS_DyAr_Free;\
|
|
_p_stPointer_ = (_Cast *) _p_stElement_->d_vElement;\
|
|
/*
|
|
* Really delete element if we can.
|
|
*/\
|
|
{_Code}\
|
|
fn_v_Mem_SetMode(_p_stPointer_->stHeader.ucMemLevel);\
|
|
SCR_M_Mem_Free(_p_stElement_->d_vElement);\
|
|
/*
|
|
* Reduce num of values if we delete last one.
|
|
*/\
|
|
if(_uiDPos_ == (_Array)->uiNumValues - 1)\
|
|
(_Array)->uiNumValues--;\
|
|
}
|
|
|
|
#define SCR_M_DyAr_DeleteElementNoAlloc(_Pos, _Array, _Code)\
|
|
{\
|
|
SCR_tdst_DyAr_Element *_p_stElement_;\
|
|
unsigned int _uiDPos_ = _Pos;\
|
|
/*
|
|
* Mark the element to be free.
|
|
*/\
|
|
_p_stElement_ = &(_Array)->d_stDynArray[_uiDPos_];\
|
|
_p_stElement_->eState = SCR_EDAS_DyAr_Free;\
|
|
{_Code}\
|
|
_p_stElement_->d_vElement = NULL;\
|
|
/*
|
|
* Reduce num of values if we delete last one.
|
|
*/\
|
|
if(_uiDPos_ == (_Array)->uiNumValues - 1)\
|
|
(_Array)->uiNumValues--;\
|
|
}
|
|
|
|
/*
|
|
* To delete all elements of a dynamic array.
|
|
* _Cast : Cast of element to delete.
|
|
* _Array : Array to delete the element.
|
|
* _Code : Code to free inside the element.
|
|
* _Borne : Borne to stop deletion.
|
|
*
|
|
* _Code MUST SET ALLOCATION MODE FOR ELEMENT !!!
|
|
*/
|
|
#define _SCR_M_DyAr_DeleteAllElements(_Cast, _Array, _Code, _Borne)\
|
|
{\
|
|
unsigned int _uiIndex_;\
|
|
/*
|
|
* Delete all elements.
|
|
*/\
|
|
for(_uiIndex_ = 0; _uiIndex_ < (_Array)->##_Borne; _uiIndex_++)\
|
|
if((_Array)->d_stDynArray[_uiIndex_].d_vElement != NULL)\
|
|
SCR_M_DyAr_DeleteElement(_Cast, _uiIndex_, _Array, _Code);\
|
|
/*
|
|
* Free array.
|
|
*/\
|
|
if((_Array)->d_stDynArray)\
|
|
{\
|
|
fn_v_Mem_SetMode(0);\
|
|
SCR_M_Mem_Free((_Array)->d_stDynArray);\
|
|
}\
|
|
(_Array)->uiNumValues = (_Array)->uiMaxValues = 0;\
|
|
}
|
|
|
|
#define SCR_M_DyAr_DeleteAllElements(_Cast, _Array, _Code)\
|
|
_SCR_M_DyAr_DeleteAllElements(_Cast, _Array, _Code, uiNumValues);
|
|
#define SCR_M_DyAr_DeleteAllElementsStatic(_Cast, _Array, _Code)\
|
|
_SCR_M_DyAr_DeleteAllElements(_Cast, _Array, _Code, uiMaxValues);
|
|
|
|
/*
|
|
* A macro to delete an element depending on its priority.
|
|
* For a static allocation, element is not deleted but is erased from the dynamic array.
|
|
* So we assume that static block will be destroyed later.
|
|
*/
|
|
#define SCR_M_DyAr_DeleteElementWithMemLevel(_Cast, _Array, _Code, _PrioMin, _PrioMax)\
|
|
{\
|
|
_Cast *_p_stPointer_;\
|
|
unsigned int _uiPos_;\
|
|
char _cMode_;\
|
|
_uiPos_ = 0;\
|
|
SCR_M_DyAr_GetNextElement(_Cast, _uiPos_, _p_stPointer_, _Array);\
|
|
while(_p_stPointer_)\
|
|
{\
|
|
if\
|
|
(\
|
|
((_p_stPointer_)->stHeader.ucMemLevel >= (_PrioMin))\
|
|
&& ((_p_stPointer_)->stHeader.ucMemLevel <= (_PrioMax))\
|
|
)\
|
|
{\
|
|
if\
|
|
(\
|
|
((_p_stPointer_)->stHeader.ucMemLevel >= E_ucScrMaxBlocksNb)\
|
|
|| (g_a_ul_Mem_BlocAllocationSize[(_p_stPointer_)->stHeader.ucMemLevel] == 0)\
|
|
)\
|
|
{\
|
|
_cMode_ = 0;\
|
|
SCR_M_DyAr_DeleteElement(_Cast, _uiPos_, &(_Array), _Code);\
|
|
}\
|
|
else\
|
|
{\
|
|
_cMode_ = 1;\
|
|
SCR_M_DyAr_DeleteElementNoAlloc(_uiPos_, &(_Array), _Code);\
|
|
}\
|
|
}\
|
|
_uiPos_++;\
|
|
SCR_M_DyAr_GetNextElement(_Cast, _uiPos_, _p_stPointer_, _Array);\
|
|
}\
|
|
}
|
|
|
|
/*
|
|
* A macro to get an element.
|
|
* _Cast : Cast of structure to get.
|
|
* _Pos : Position of element to get.
|
|
* _Pointer : To receive address of element.
|
|
* _Array : Array concerned.
|
|
*/
|
|
#define SCR_M_DyAr_GetElement(_Cast, _Pos, _Pointer, _Array)\
|
|
{\
|
|
_Pointer = ((_Cast *) (_Array.d_stDynArray[_Pos].d_vElement));\
|
|
SCR_M_Dbg_AssertStruct_P(_Cast, _Pointer);\
|
|
}
|
|
|
|
/*
|
|
* A macro to search the first valid element of a dynamic array.
|
|
* _Cast : Cast of element to return.
|
|
* _Pos : Pos of found element and current position to search.
|
|
* _Pointer : To receive address of element (NULL if not).
|
|
* _Array : Array to search.
|
|
*/
|
|
#define SCR_M_DyAr_GetNextElement(_Cast, _Pos, _Pointer, _Array)\
|
|
{\
|
|
while((_Pos) < (_Array).uiNumValues)\
|
|
{\
|
|
if((_Array).d_stDynArray[_Pos].eState != SCR_EDAS_DyAr_Free)\
|
|
{\
|
|
SCR_M_DyAr_GetElement(_Cast, _Pos, _Pointer, _Array);\
|
|
break;\
|
|
}\
|
|
(_Pos)++;\
|
|
}\
|
|
if((_Pos) >= (_Array).uiNumValues)\
|
|
_Pointer = NULL;\
|
|
}
|
|
|
|
/*
|
|
* A macro to search an element in an array.
|
|
* _Cast : Cast of structure to get.
|
|
* _Pos : Position of element to get.
|
|
* _Pointer : To receive address of element.
|
|
* _Array : Array concerned.
|
|
* _Test : Lines to test if this is the good element.
|
|
*/
|
|
#define SCR_M_DyAr_SearchElement(_Cast, _Pos, _Pointer, _Array, _Test)\
|
|
{\
|
|
_Pos = 0;\
|
|
SCR_M_DyAr_GetNextElement(_Cast, _Pos, _Pointer, _Array);\
|
|
while((_Pointer) != NULL)\
|
|
{\
|
|
if(_Test)\
|
|
break;\
|
|
(_Pos)++;\
|
|
SCR_M_DyAr_GetNextElement(_Cast, _Pos, _Pointer, _Array);\
|
|
}\
|
|
}
|
|
|
|
/*
|
|
* Simply pack an array by just adjusting its size.
|
|
* _Cast : Cast of an element in array.
|
|
* _Array : Array to realloc.
|
|
*/
|
|
#define SCR_M_DyAr_SimplePackArray(_Cast, _Array)\
|
|
{\
|
|
/* Realloc array */\
|
|
if((_Array).uiNumValues != (_Array).uiMaxValues)\
|
|
{\
|
|
if((_Array).uiNumValues == 0)\
|
|
{\
|
|
fn_v_Mem_SetMode(0);\
|
|
SCR_M_Mem_Free((_Array).d_stDynArray);\
|
|
}\
|
|
else\
|
|
{\
|
|
fn_v_Mem_SetMode(0);\
|
|
SCR_M_Mem_Realloc(SCR_tdst_DyAr_Element, (_Array).d_stDynArray, (_Array).d_stDynArray, (_Array).uiNumValues, 0);\
|
|
}\
|
|
(_Array).uiMaxValues = (_Array).uiNumValues;\
|
|
}\
|
|
}
|
|
|
|
/*
|
|
* To reduce the size of a dynamic array by filliing the free places.
|
|
* _Cast : Cast of an element.
|
|
* _Array : Dynamic array to reduce.
|
|
* _Code : Eventual code to execute.
|
|
*/
|
|
#define SCR_M_DyAr_PackArray(_Cast, _Array, _Code)\
|
|
{\
|
|
_Cast *_p_stPointer_;\
|
|
int _DyAr_iEndPos_;\
|
|
int _DyAr_iBegPos_ = (_Array).uiNumValues - 1;\
|
|
if(_Array.uiNumValues)\
|
|
{\
|
|
/* Search the last non free place of array */\
|
|
while\
|
|
(\
|
|
(_DyAr_iBegPos_ >= 0)\
|
|
&& ((_Array).d_stDynArray[_DyAr_iBegPos_].eState == SCR_EDAS_DyAr_Free)\
|
|
)\
|
|
{\
|
|
_DyAr_iBegPos_--;\
|
|
(_Array).uiNumValues--;\
|
|
}\
|
|
_DyAr_iEndPos_ = _DyAr_iBegPos_;\
|
|
while(_DyAr_iBegPos_ >= 0)\
|
|
{\
|
|
/* Search the last free place in array */\
|
|
while\
|
|
(\
|
|
(_DyAr_iBegPos_ >= 0)\
|
|
&& ((_Array).d_stDynArray[_DyAr_iBegPos_].eState != SCR_EDAS_DyAr_Free)\
|
|
)\
|
|
{\
|
|
_DyAr_iBegPos_--;\
|
|
}\
|
|
/* We find a home and must fill it with the last non free of array */\
|
|
if(_DyAr_iBegPos_ >= 0)\
|
|
{\
|
|
memcpy\
|
|
(\
|
|
&((_Array).d_stDynArray[_DyAr_iBegPos_]),\
|
|
&((_Array).d_stDynArray[_DyAr_iEndPos_]),\
|
|
sizeof(SCR_tdst_DyAr_Element)\
|
|
);\
|
|
(_Array).uiNumValues--;\
|
|
{_Code;}\
|
|
_DyAr_iBegPos_--;\
|
|
_DyAr_iEndPos_--;\
|
|
}\
|
|
}\
|
|
}\
|
|
if(_Array.uiMaxValues)\
|
|
{\
|
|
/* Simple pack array */\
|
|
SCR_M_DyAr_SimplePackArray(_Cast, _Array);\
|
|
/* Recompute "uiIndexInArray" field */\
|
|
for(_DyAr_iBegPos_ = 0; (unsigned int) _DyAr_iBegPos_ < (_Array).uiNumValues; _DyAr_iBegPos_++)\
|
|
{\
|
|
SCR_M_DyAr_GetElement(_Cast, _DyAr_iBegPos_, _p_stPointer_, _Array);\
|
|
_p_stPointer_->stHeader.uiIndexInArray = _DyAr_iBegPos_;\
|
|
}\
|
|
}\
|
|
}
|
|
|
|
#endif /* !__SCR_DyAr_h__Macros && !__Only_Types__ */
|
|
|
|
/*
|
|
*=================================================================================================
|
|
* Protos.
|
|
*=================================================================================================
|
|
*/
|
|
|
|
#if !defined(__SCR_DyAr_h__Protos) && !defined(__Only_Types__)
|
|
#define __SCR_DyAr_h__Protos
|
|
|
|
extern void fn_v_DyAr_InitArray(SCR_tdst_DyAr_Description *);
|
|
|
|
extern unsigned int fn_ui_DyAr_AllocateElement(SCR_tdst_DyAr_Description *, char);
|
|
|
|
#endif /* !__SCR_DyAr_h__Protos && !__Only_Types__ */
|