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

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