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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  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. if( cmArrayIsValid(h) == false )
  75. return 0;
  76. cmAr_t* p = _cmArHandleToPtr(h);
  77. return p->cur_cnt;
  78. }
  79. cmArRC_t cmArrayClear( cmArrayH_t h, bool releaseFl )
  80. {
  81. cmAr_t* p = _cmArHandleToPtr(h);
  82. if( releaseFl )
  83. {
  84. cmMemPtrFree(&p->base);
  85. p->alloc_cnt = 0;
  86. }
  87. p->cur_cnt = 0;
  88. return kOkArRC;
  89. }
  90. void* _cmArraySet( cmAr_t* p, unsigned idx, const void* data, unsigned dataEleCnt )
  91. {
  92. if( idx+dataEleCnt > p->alloc_cnt )
  93. {
  94. unsigned add_cnt = (idx + dataEleCnt) - p->alloc_cnt;
  95. if( add_cnt < p->expand_cnt )
  96. add_cnt = p->expand_cnt;
  97. else
  98. add_cnt = ((add_cnt / p->expand_cnt) + 1) * p->expand_cnt;
  99. p->alloc_cnt += add_cnt;
  100. p->base = cmMemResizePZ(char,p->base,p->alloc_cnt*p->ele_byte_cnt);
  101. }
  102. char* bp = p->base + (idx*p->ele_byte_cnt);
  103. if( data == NULL )
  104. memset(bp, 0, p->ele_byte_cnt * dataEleCnt );
  105. else
  106. memcpy(bp, data, p->ele_byte_cnt * dataEleCnt );
  107. if( idx+dataEleCnt > p->cur_cnt )
  108. p->cur_cnt = idx + dataEleCnt;
  109. return bp;
  110. }
  111. void* cmArrayPush( cmArrayH_t h, const void* data, unsigned dataEleCnt )
  112. {
  113. cmAr_t* p = _cmArHandleToPtr(h);
  114. return _cmArraySet(p,p->cur_cnt,data,dataEleCnt);
  115. }
  116. cmArRC_t cmArrayPop( cmArrayH_t h, unsigned eleCnt )
  117. {
  118. cmAr_t* p = _cmArHandleToPtr(h);
  119. if( eleCnt > p->cur_cnt )
  120. return cmErrMsg(&p->err,kUnderflowArRC,"Cannot pop %i element(s). Array contains %i element(s).",eleCnt,p->cur_cnt);
  121. p->cur_cnt -= eleCnt;
  122. return kOkArRC;
  123. }
  124. void* cmArraySet( cmArrayH_t h, unsigned index, const void* data, unsigned dataEleCnt )
  125. {
  126. cmAr_t* p = _cmArHandleToPtr(h);
  127. return _cmArraySet(p,index,data,dataEleCnt );
  128. }
  129. const void* cmArrayGet( cmArrayH_t h, unsigned index )
  130. {
  131. cmAr_t* p = _cmArHandleToPtr(h);
  132. return p->base + (index * p->ele_byte_cnt);
  133. }