libcm is a C development framework with an emphasis on audio signal processing applications.
Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

cmStrStream.c 4.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  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 "cmLinkedHeap.h"
  8. #include "cmStrStream.h"
  9. #include "cmText.h"
  10. typedef struct cmSsBlk_str
  11. {
  12. char* blk;
  13. unsigned i;
  14. struct cmSsBlk_str* link;
  15. } cmSsBlk_t;
  16. typedef struct
  17. {
  18. cmErr_t err;
  19. cmLHeapH_t lhH;
  20. unsigned blkByteCnt;
  21. cmSsBlk_t* blp;
  22. cmSsBlk_t* elp;
  23. } cmOss_t;
  24. cmOss_t* _cmOssHandleToPtr( cmStrStreamH_t h )
  25. {
  26. cmOss_t* p = (cmOss_t*)h.h;
  27. assert(p != NULL );
  28. return p;
  29. }
  30. cmSsRC_t _cmOssDestroy( cmOss_t* p )
  31. {
  32. cmSsRC_t rc = kOkSsRC;
  33. cmLHeapDestroy(&p->lhH);
  34. cmMemFree(p);
  35. return rc;
  36. }
  37. cmSsRC_t cmOStrStreamCreate( cmCtx_t* ctx, cmStrStreamH_t* hp, unsigned dfltBlkByteCnt )
  38. {
  39. cmSsRC_t rc;
  40. if((rc = cmOStrStreamDestroy(hp)) != kOkSsRC )
  41. return rc;
  42. cmOss_t* p = cmMemAllocZ(cmOss_t,1);
  43. p->blkByteCnt = dfltBlkByteCnt==0 ? 4096 : dfltBlkByteCnt;
  44. cmErrSetup(&p->err,&ctx->rpt,"OStrStream");
  45. if( cmLHeapIsValid(p->lhH = cmLHeapCreate(p->blkByteCnt+sizeof(cmSsBlk_t),ctx)) == false )
  46. {
  47. rc = cmErrMsg(&p->err,kLHeapMemFailSsRC,"Linked heap allocation failed.");
  48. goto errLabel;
  49. }
  50. hp->h = p;
  51. errLabel:
  52. if(rc != kOkSsRC )
  53. _cmOssDestroy(p);
  54. return rc;
  55. }
  56. cmSsRC_t cmOStrStreamDestroy(cmStrStreamH_t* hp )
  57. {
  58. cmSsRC_t rc = kOkSsRC;
  59. if( hp==NULL || cmOStrStreamIsValid(*hp)==false )
  60. return rc;
  61. cmOss_t* p = _cmOssHandleToPtr(*hp);
  62. if((rc = _cmOssDestroy(p)) != kOkSsRC )
  63. return rc;
  64. hp->h = NULL;
  65. return rc;
  66. }
  67. bool cmOStrStreamIsValid( cmStrStreamH_t h )
  68. { return h.h != NULL; }
  69. cmSsRC_t cmOStrStreamWrite( cmStrStreamH_t h, const void* vp, unsigned byteCnt )
  70. {
  71. cmSsRC_t rc = kOkSsRC;
  72. cmOss_t* p = _cmOssHandleToPtr(h);
  73. char* cp = (char*)vp;
  74. do
  75. {
  76. // if a blk exists
  77. if( p->elp != NULL )
  78. {
  79. // copy as much of vp[] as possible into the current end block
  80. unsigned n = cmMin(byteCnt, p->blkByteCnt - p->elp->i);
  81. memcpy(p->elp->blk,cp,n);
  82. byteCnt -= n;
  83. p->elp->i += n;
  84. }
  85. // if all of vp[] has been copied then we are done
  86. if( byteCnt == 0 )
  87. break;
  88. assert( p->elp==NULL || p->elp->i == p->blkByteCnt );
  89. // allocate a new block
  90. cmSsBlk_t* nbp = (cmSsBlk_t*)cmLHeapAlloc(p->lhH,p->blkByteCnt+sizeof(cmSsBlk_t));
  91. nbp->blk = (char*)(nbp + 1);
  92. nbp->i = 0;
  93. nbp->link = NULL;
  94. // end the new blk onto the end of the list
  95. if( p->elp == NULL )
  96. p->blp = nbp;
  97. else
  98. p->elp->link = nbp;
  99. p->elp = nbp;
  100. }while(1);
  101. return rc;
  102. }
  103. cmSsRC_t cmOStrStreamWriteStr( cmStrStreamH_t h, const cmChar_t* str )
  104. {
  105. if( str == NULL )
  106. return kOkSsRC;
  107. return cmOStrStreamWrite(h,str,strlen(str));
  108. }
  109. cmSsRC_t cmOStrStreamVPrintf( cmStrStreamH_t h, const cmChar_t* fmt, va_list vl )
  110. {
  111. cmChar_t* s = cmTsVPrintfP(NULL,fmt,vl);
  112. cmSsRC_t rc = cmOStrStreamWriteStr(h,s);
  113. cmMemFree(s);
  114. return rc;
  115. }
  116. cmSsRC_t cmOStrStreamPrintf( cmStrStreamH_t h, const cmChar_t* fmt, ... )
  117. {
  118. va_list vl;
  119. va_start(vl,fmt);
  120. cmSsRC_t rc = cmOStrStreamVPrintf(h,fmt,vl);
  121. va_end(vl);
  122. return rc;
  123. }
  124. unsigned cmOStrStreamByteCount( cmStrStreamH_t h )
  125. {
  126. unsigned n = 0;
  127. cmOss_t* p = _cmOssHandleToPtr(h);
  128. cmSsBlk_t* bp = p->blp;
  129. for(; bp!=NULL; bp=bp->link)
  130. n += bp->i;
  131. return n;
  132. }
  133. unsigned _cmOssCopyBuf( cmOss_t* p, char* buf, unsigned n )
  134. {
  135. unsigned i = 0;
  136. cmSsBlk_t* bp = p->blp;
  137. for(; bp!=NULL; bp=bp->link)
  138. {
  139. assert( i + bp->i <= n );
  140. memcpy(buf+i,bp->blk,bp->i);
  141. i += bp->i;
  142. }
  143. return i;
  144. }
  145. void* cmOStrStreamAllocBuf( cmStrStreamH_t h )
  146. {
  147. unsigned n = cmOStrStreamByteCount(h);
  148. cmOss_t* p = _cmOssHandleToPtr(h);
  149. if( n == 0 )
  150. return NULL;
  151. char* buf = cmMemAlloc(char,n);
  152. unsigned i = _cmOssCopyBuf(p,buf,n);
  153. assert(i==n);
  154. return buf;
  155. }
  156. cmChar_t* cmOStrStreamAllocText( cmStrStreamH_t h )
  157. {
  158. unsigned n = cmOStrStreamByteCount(h);
  159. cmOss_t* p = _cmOssHandleToPtr(h);
  160. if( n == 0 )
  161. return NULL;
  162. char* buf = cmMemAlloc(char,n+1);
  163. unsigned i = _cmOssCopyBuf(p,buf,n);
  164. assert(i==n);
  165. buf[n] = 0;
  166. return buf;
  167. }