/* *%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% * 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__ */