libcm is a C development framework with an emphasis on audio signal processing applications.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

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