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.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  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->base);
  28. cmMemFree(p);
  29. return rc;
  30. }
  31. cmArRC_t cmArrayAlloc0( cmCtx_t* ctx, cmArrayH_t* hp, unsigned eleByteCnt, unsigned initCnt, unsigned expandCnt )
  32. {
  33. cmArRC_t rc;
  34. if((rc = cmArrayRelease(hp)) != kOkArRC )
  35. return rc;
  36. cmAr_t* p = cmMemAllocZ(cmAr_t,1);
  37. cmErrSetup(&p->err,&ctx->rpt,"Array");
  38. p->alloc_cnt = initCnt;
  39. p->expand_cnt = expandCnt;
  40. p->cur_cnt = 0;
  41. p->ele_byte_cnt = eleByteCnt;
  42. if( p->alloc_cnt > 0 )
  43. p->base = cmMemAllocZ(char,p->alloc_cnt*eleByteCnt);
  44. hp->h = p;
  45. return rc;
  46. }
  47. cmArRC_t cmArrayAlloc( cmCtx_t* ctx, cmArrayH_t* hp, unsigned eleByteCnt )
  48. { return cmArrayAlloc0(ctx,hp,eleByteCnt,10,10); }
  49. cmArRC_t cmArrayRelease( cmArrayH_t* hp )
  50. {
  51. cmArRC_t rc = kOkArRC;
  52. if(hp==NULL || cmArrayIsValid(*hp)==false )
  53. return rc;
  54. cmAr_t* p = _cmArHandleToPtr(*hp);
  55. if((rc = _cmArFree(p)) != kOkArRC )
  56. return rc;
  57. hp->h = NULL;
  58. return rc;
  59. }
  60. cmArRC_t cmArrayIsValid(cmArrayH_t h )
  61. { return h.h != NULL; }
  62. void cmArraySetExpandCount( cmArrayH_t h, unsigned expandCnt )
  63. {
  64. cmAr_t* p = _cmArHandleToPtr(h);
  65. p->expand_cnt = expandCnt;
  66. }
  67. unsigned cmArrayExpandCount( cmArrayH_t h )
  68. {
  69. cmAr_t* p = _cmArHandleToPtr(h);
  70. return p->expand_cnt;
  71. }
  72. unsigned cmArrayCount( cmArrayH_t h )
  73. {
  74. cmAr_t* p = _cmArHandleToPtr(h);
  75. return p->cur_cnt;
  76. }
  77. cmArRC_t cmArrayClear( cmArrayH_t h, bool releaseFl )
  78. {
  79. cmAr_t* p = _cmArHandleToPtr(h);
  80. if( releaseFl )
  81. {
  82. cmMemPtrFree(&p->base);
  83. p->alloc_cnt = 0;
  84. }
  85. p->cur_cnt = 0;
  86. return kOkArRC;
  87. }
  88. void* _cmArraySet( cmAr_t* p, unsigned idx, const void* data, unsigned dataEleCnt )
  89. {
  90. if( idx+dataEleCnt > p->alloc_cnt )
  91. {
  92. unsigned add_cnt = (idx + dataEleCnt) - p->alloc_cnt;
  93. if( add_cnt < p->expand_cnt )
  94. add_cnt = p->expand_cnt;
  95. else
  96. add_cnt = ((add_cnt / p->expand_cnt) + 1) * p->expand_cnt;
  97. p->alloc_cnt += add_cnt;
  98. p->base = cmMemResizePZ(char,p->base,p->alloc_cnt*p->ele_byte_cnt);
  99. }
  100. char* bp = p->base + (idx*p->ele_byte_cnt);
  101. if( data == NULL )
  102. memset(bp, 0, p->ele_byte_cnt * dataEleCnt );
  103. else
  104. memcpy(bp, data, p->ele_byte_cnt * dataEleCnt );
  105. if( idx+dataEleCnt > p->cur_cnt )
  106. p->cur_cnt = idx + dataEleCnt;
  107. return bp;
  108. }
  109. void* cmArrayPush( cmArrayH_t h, const void* data, unsigned dataEleCnt )
  110. {
  111. cmAr_t* p = _cmArHandleToPtr(h);
  112. return _cmArraySet(p,p->cur_cnt,data,dataEleCnt);
  113. }
  114. cmArRC_t cmArrayPop( cmArrayH_t h, unsigned eleCnt )
  115. {
  116. cmAr_t* p = _cmArHandleToPtr(h);
  117. if( eleCnt > p->cur_cnt )
  118. return cmErrMsg(&p->err,kUnderflowArRC,"Cannot pop %i element(s). Array contains %i element(s).",eleCnt,p->cur_cnt);
  119. p->cur_cnt -= eleCnt;
  120. return kOkArRC;
  121. }
  122. void* cmArraySet( cmArrayH_t h, unsigned index, const void* data, unsigned dataEleCnt )
  123. {
  124. cmAr_t* p = _cmArHandleToPtr(h);
  125. return _cmArraySet(p,index,data,dataEleCnt );
  126. }
  127. const void* cmArrayGet( cmArrayH_t h, unsigned index )
  128. {
  129. cmAr_t* p = _cmArHandleToPtr(h);
  130. return p->base + (index * p->ele_byte_cnt);
  131. }