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

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