libcm is a C development framework with an emphasis on audio signal processing applications.
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

cmStrStream.c 4.6KB

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