libcm is a C development framework with an emphasis on audio signal processing applications.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

cmArray.c 3.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. #include "cmGlobal.h"
  2. #include "cmRpt.h"
  3. #include "cmErr.h"
  4. #include "cmCtx.h"
  5. #include "cmMem.h"
  6. #include "cmMallocDebug.h"
  7. #include "cmArray.h"
  8. typedef struct
  9. {
  10. cmErr_t err;
  11. char* base;
  12. unsigned expand_cnt;
  13. unsigned alloc_cnt;
  14. unsigned cur_cnt;
  15. unsigned ele_byte_cnt;
  16. } cmAr_t;
  17. cmArrayH_t cmArrayNullHandle = cmSTATIC_NULL_HANDLE;
  18. cmAr_t* _cmArHandleToPtr( cmArrayH_t h )
  19. {
  20. cmAr_t* p = (cmAr_t*)h.h;
  21. assert(p!=NULL);
  22. return p;
  23. }
  24. cmArRC_t _cmArFree( cmAr_t* p )
  25. {
  26. cmArRC_t rc = kOkArRC;
  27. cmMemFree(p);
  28. return rc;
  29. }
  30. cmArRC_t cmArrayAlloc( cmCtx_t* ctx, cmArrayH_t* hp, unsigned initCnt, unsigned expandCnt, unsigned eleByteCnt )
  31. {
  32. cmArRC_t rc;
  33. if((rc = cmArrayRelease(hp)) != kOkArRC )
  34. return rc;
  35. cmAr_t* p = cmMemAllocZ(cmAr_t,1);
  36. cmErrSetup(&p->err,&ctx->rpt,"Array");
  37. p->alloc_cnt = initCnt * eleByteCnt;
  38. p->expand_cnt = expandCnt;
  39. p->cur_cnt = 0;
  40. p->ele_byte_cnt = eleByteCnt;
  41. if( p->alloc_cnt > 0 )
  42. p->base = cmMemAllocZ(char,p->alloc_cnt);
  43. hp->h = p;
  44. return rc;
  45. }
  46. cmArRC_t cmArrayRelease( cmArrayH_t* hp )
  47. {
  48. cmArRC_t rc = kOkArRC;
  49. if(hp==NULL || cmArrayIsValid(*hp)==false )
  50. return rc;
  51. cmAr_t* p = _cmArHandleToPtr(*hp);
  52. if((rc = _cmArFree(p)) != kOkArRC )
  53. return rc;
  54. hp->h = NULL;
  55. return rc;
  56. }
  57. cmArRC_t cmArrayIsValid(cmArrayH_t h )
  58. { return h.h != NULL; }
  59. unsigned cmArrayCount( cmArrayH_t h )
  60. {
  61. cmAr_t* p = _cmArHandleToPtr(h);
  62. return p->cur_cnt;
  63. }
  64. cmArRC_t cmArrayClear( cmArrayH_t h, bool releaseFl )
  65. {
  66. cmAr_t* p = _cmArHandleToPtr(h);
  67. if( releaseFl )
  68. {
  69. cmMemPtrFree(&p->base);
  70. p->alloc_cnt = 0;
  71. }
  72. p->cur_cnt = 0;
  73. return kOkArRC;
  74. }
  75. void* _cmArraySet( cmAr_t* p, unsigned idx, const void* data, unsigned dataEleCnt )
  76. {
  77. if( idx+dataEleCnt > p->alloc_cnt )
  78. {
  79. unsigned add_cnt = (idx + dataEleCnt) - p->alloc_cnt;
  80. p->alloc_cnt += ((add_cnt / p->expand_cnt) + 1) * p->expand_cnt;
  81. p->base = cmMemResizePZ(char,p->base,p->alloc_cnt);
  82. }
  83. char* bp = p->base + (idx*p->ele_byte_cnt);
  84. if( data == NULL )
  85. memset(bp, 0, p->ele_byte_cnt * dataEleCnt );
  86. else
  87. memcpy(bp, data, p->ele_byte_cnt * dataEleCnt );
  88. if( idx+dataEleCnt > p->cur_cnt )
  89. p->cur_cnt = idx + dataEleCnt;
  90. return bp;
  91. }
  92. void* cmArrayPush( cmArrayH_t h, const void* data, unsigned dataEleCnt )
  93. {
  94. cmAr_t* p = _cmArHandleToPtr(h);
  95. return _cmArraySet(p,p->cur_cnt,data,dataEleCnt);
  96. }
  97. cmArRC_t cmArrayPop( cmArrayH_t h, unsigned eleCnt )
  98. {
  99. cmAr_t* p = _cmArHandleToPtr(h);
  100. if( eleCnt > p->cur_cnt )
  101. return cmErrMsg(&p->err,kUnderflowArRC,"Cannot pop %i element(s). Array contains %i element(s).",eleCnt,p->cur_cnt);
  102. p->cur_cnt -= eleCnt;
  103. return kOkArRC;
  104. }
  105. void* cmArraySet( cmArrayH_t h, unsigned index, const void* data, unsigned dataEleCnt )
  106. {
  107. cmAr_t* p = _cmArHandleToPtr(h);
  108. return _cmArraySet(p,index,data,dataEleCnt );
  109. }
  110. const void* cmArrayGet( cmArrayH_t h, unsigned index )
  111. {
  112. cmAr_t* p = _cmArHandleToPtr(h);
  113. return p->base + (index * p->ele_byte_cnt);
  114. }