diff --git a/cmArray.c b/cmArray.c new file mode 100644 index 0000000..871c707 --- /dev/null +++ b/cmArray.c @@ -0,0 +1,146 @@ +#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); + return rc; +} + +cmArRC_t cmArrayAlloc( cmCtx_t* ctx, cmArrayH_t* hp, unsigned initCnt, unsigned expandCnt, unsigned eleByteCnt ) +{ + 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 * eleByteCnt; + 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); + + hp->h = p; + + return rc; +} + +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; } + +unsigned cmArrayCount( cmArrayH_t h ) +{ + 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; + + p->alloc_cnt += ((add_cnt / p->expand_cnt) + 1) * p->expand_cnt; + + p->base = cmMemResizePZ(char,p->base,p->alloc_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); +} + diff --git a/cmArray.h b/cmArray.h new file mode 100644 index 0000000..17fffe1 --- /dev/null +++ b/cmArray.h @@ -0,0 +1,41 @@ +#ifndef cmArray_h +#define cmArray_h + +#ifdef __cplusplus +extern "C" { +#endif + +enum +{ + kOkArRC = cmOkRC, + kUnderflowArRC +}; + + typedef cmRC_t cmArRC_t; + typedef cmHandle_t cmArrayH_t; + + extern cmArrayH_t cmArrayNullHandle; + + cmArRC_t cmArrayAlloc( cmCtx_t* ctx, cmArrayH_t* hp, unsigned eleByteCnt, unsigned initCnt, unsigned expandCnt ); + cmArRC_t cmArrayRelease(cmArrayH_t* hp ); + cmArRC_t cmArrayIsValid(cmArrayH_t h ); + unsigned cmArrayCount( cmArrayH_t h ); + cmArRC_t cmArrayClear( cmArrayH_t h, bool releaseFl ); + void* cmArrayPush( cmArrayH_t h, const void* data, unsigned dataEleCnt ); + cmArRC_t cmArrayPop( cmArrayH_t h, unsigned eleCnt ); + // If 'data' is NULL then array[idx:idx+dataEleCnt] is zeroed. + void* cmArraySet( cmArrayH_t h, unsigned index, const void* data, unsigned dataEleCnt ); + const void* cmArrayGet( cmArrayH_t h, unsigned index ); + + + +#define cmArrayPtr(t,h,i) ((t*)cmArrayGet(h,i)) +#define cmArrayEle(t,h,i) (*(t*)cmArrayGet(h,i)) +#define cmArrayClr(t,h,i) ((t*)cmArraySet(h,i,NULL,1)) +#define cmArrayClrN(t,h,i,n) ((t*)cmArraySet(h,i,NULL,n)) + +#ifdef __cplusplus +} +#endif + +#endif