#include "cmGlobal.h" #include "cmRpt.h" #include "cmErr.h" #include "cmCtx.h" #include "cmMem.h" #include "cmMallocDebug.h" #include "cmArray.h" typedef struct { cmErr_t err; char* base; unsigned expand_cnt; unsigned alloc_cnt; unsigned cur_cnt; unsigned ele_byte_cnt; } cmAr_t; cmArrayH_t cmArrayNullHandle = cmSTATIC_NULL_HANDLE; cmAr_t* _cmArHandleToPtr( cmArrayH_t h ) { cmAr_t* p = (cmAr_t*)h.h; assert(p!=NULL); return p; } cmArRC_t _cmArFree( cmAr_t* p ) { cmArRC_t rc = kOkArRC; cmMemFree(p->base); cmMemFree(p); return rc; } cmArRC_t cmArrayAlloc0( cmCtx_t* ctx, cmArrayH_t* hp, unsigned eleByteCnt, unsigned initCnt, unsigned expandCnt ) { cmArRC_t rc; if((rc = cmArrayRelease(hp)) != kOkArRC ) return rc; cmAr_t* p = cmMemAllocZ(cmAr_t,1); cmErrSetup(&p->err,&ctx->rpt,"Array"); p->alloc_cnt = initCnt; p->expand_cnt = expandCnt; p->cur_cnt = 0; p->ele_byte_cnt = eleByteCnt; if( p->alloc_cnt > 0 ) p->base = cmMemAllocZ(char,p->alloc_cnt*eleByteCnt); hp->h = p; return rc; } cmArRC_t cmArrayAlloc( cmCtx_t* ctx, cmArrayH_t* hp, unsigned eleByteCnt ) { return cmArrayAlloc0(ctx,hp,eleByteCnt,10,10); } cmArRC_t cmArrayRelease( cmArrayH_t* hp ) { cmArRC_t rc = kOkArRC; if(hp==NULL || cmArrayIsValid(*hp)==false ) return rc; cmAr_t* p = _cmArHandleToPtr(*hp); if((rc = _cmArFree(p)) != kOkArRC ) return rc; hp->h = NULL; return rc; } cmArRC_t cmArrayIsValid(cmArrayH_t h ) { return h.h != NULL; } void cmArraySetExpandCount( cmArrayH_t h, unsigned expandCnt ) { cmAr_t* p = _cmArHandleToPtr(h); p->expand_cnt = expandCnt; } unsigned cmArrayExpandCount( cmArrayH_t h ) { cmAr_t* p = _cmArHandleToPtr(h); return p->expand_cnt; } unsigned cmArrayCount( cmArrayH_t h ) { if( cmArrayIsValid(h) == false ) return 0; cmAr_t* p = _cmArHandleToPtr(h); return p->cur_cnt; } cmArRC_t cmArrayClear( cmArrayH_t h, bool releaseFl ) { cmAr_t* p = _cmArHandleToPtr(h); if( releaseFl ) { cmMemPtrFree(&p->base); p->alloc_cnt = 0; } p->cur_cnt = 0; return kOkArRC; } void* _cmArraySet( cmAr_t* p, unsigned idx, const void* data, unsigned dataEleCnt ) { if( idx+dataEleCnt > p->alloc_cnt ) { unsigned add_cnt = (idx + dataEleCnt) - p->alloc_cnt; if( add_cnt < p->expand_cnt ) add_cnt = p->expand_cnt; else add_cnt = ((add_cnt / p->expand_cnt) + 1) * p->expand_cnt; p->alloc_cnt += add_cnt; p->base = cmMemResizePZ(char,p->base,p->alloc_cnt*p->ele_byte_cnt); } char* bp = p->base + (idx*p->ele_byte_cnt); if( data == NULL ) memset(bp, 0, p->ele_byte_cnt * dataEleCnt ); else memcpy(bp, data, p->ele_byte_cnt * dataEleCnt ); if( idx+dataEleCnt > p->cur_cnt ) p->cur_cnt = idx + dataEleCnt; return bp; } void* cmArrayPush( cmArrayH_t h, const void* data, unsigned dataEleCnt ) { cmAr_t* p = _cmArHandleToPtr(h); return _cmArraySet(p,p->cur_cnt,data,dataEleCnt); } cmArRC_t cmArrayPop( cmArrayH_t h, unsigned eleCnt ) { cmAr_t* p = _cmArHandleToPtr(h); if( eleCnt > p->cur_cnt ) return cmErrMsg(&p->err,kUnderflowArRC,"Cannot pop %i element(s). Array contains %i element(s).",eleCnt,p->cur_cnt); p->cur_cnt -= eleCnt; return kOkArRC; } void* cmArraySet( cmArrayH_t h, unsigned index, const void* data, unsigned dataEleCnt ) { cmAr_t* p = _cmArHandleToPtr(h); return _cmArraySet(p,index,data,dataEleCnt ); } const void* cmArrayGet( cmArrayH_t h, unsigned index ) { cmAr_t* p = _cmArHandleToPtr(h); return p->base + (index * p->ele_byte_cnt); }