buffer.c
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:6k
源码类别:

Windows CE

开发平台:

C/C++

  1. /*****************************************************************************
  2.  *
  3.  * This program is free software ; you can redistribute it and/or modify
  4.  * it under the terms of the GNU General Public License as published by
  5.  * the Free Software Foundation; either version 2 of the License, or
  6.  * (at your option) any later version.
  7.  *
  8.  * This program is distributed in the hope that it will be useful,
  9.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11.  * GNU General Public License for more details.
  12.  *
  13.  * You should have received a copy of the GNU General Public License
  14.  * along with this program; if not, write to the Free Software
  15.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  16.  *
  17.  * $Id: buffer.c 432 2005-12-28 16:39:13Z picard $
  18.  *
  19.  * The Core Pocket Media Player
  20.  * Copyright (c) 2004-2005 Gabor Kovacs
  21.  *
  22.  ****************************************************************************/
  23. #include "common.h"
  24. void BufferClear(buffer* p)
  25. {
  26. free(p->Data);
  27. p->Allocated = 0;
  28. p->ReadPos = 0;
  29. p->WritePos = 0;
  30. p->Data = NULL;
  31. }
  32. bool_t BufferAlloc(buffer* p, size_t Size, size_t Align)
  33. {
  34. uint8_t* Data;
  35. Align--;
  36. Size = (Size + SAFETAIL + Align) & ~Align;
  37. Data = realloc(p->Data,Size);
  38. if (!Data)
  39. return 0;
  40. p->Data = Data;
  41. p->Allocated = Size - SAFETAIL;
  42. return 1;
  43. }
  44. void BufferDrop(buffer* p)
  45. {
  46. //drop previous packets
  47. p->WritePos = 0;
  48. p->ReadPos = 0;
  49. }
  50. bool_t BufferStream(buffer* p,stream* Stream)
  51. {
  52. if (p->WritePos > p->ReadPos+p->Allocated/2)
  53. return 1;
  54. if (p->ReadPos > p->Allocated/2)
  55. BufferPack(p,0);
  56. if (p->Allocated > p->WritePos)
  57. {
  58. int n = Stream->Read(Stream,p->Data+p->WritePos,p->Allocated - p->WritePos);
  59. if (n > 0)
  60. p->WritePos += n;
  61. }
  62. return p->WritePos > p->ReadPos;
  63. }
  64. bool_t BufferWrite(buffer* p, const void* Ptr, size_t Length, size_t Align)
  65. {
  66. //append new data to buffer
  67. int WritePos = p->WritePos + (int)Length; //buffer!
  68. if (WritePos > p->Allocated && !BufferAlloc(p,WritePos,Align))
  69. return 0;
  70. if (Ptr)
  71. memcpy(p->Data+p->WritePos,Ptr,Length);
  72. p->WritePos = WritePos;
  73. return 1;
  74. }
  75. bool_t BufferRead(buffer* p, const uint8_t** Ptr, size_t Length)
  76. {
  77. if (p->WritePos < p->ReadPos + (int)Length) //buffer!
  78. return 0;
  79. *Ptr = p->Data + p->ReadPos;
  80. p->ReadPos += (int)Length; //buffer!
  81. return 1;
  82. }
  83. void BufferPack(buffer* p, size_t Length)
  84. {
  85. int Skip = p->ReadPos + (int)Length; //buffer!
  86. if (p->WritePos > Skip)
  87. {
  88. p->WritePos -= Skip;
  89. if (Skip)
  90. memmove(p->Data,p->Data+Skip,p->WritePos); // move end part to the beginning
  91. }
  92. else
  93. p->WritePos = 0;
  94. p->ReadPos = 0;
  95. }
  96. void ArrayClear(array* p)
  97. {
  98. if (p->_Block.Ptr)
  99. FreeBlock(&p->_Block);
  100. else
  101. free(p->_Begin);
  102. p->_Begin = NULL;
  103. p->_End = NULL;
  104. p->_Allocated = 0;
  105. }
  106. void ArrayDrop(array* p)
  107. {
  108. p->_End = p->_Begin;
  109. }
  110. bool_t ArrayAlloc(array* p,size_t Total,size_t Align)
  111. {
  112. uint8_t* Data;
  113. --Align;
  114. Total = (Total + Align) & ~Align;
  115. Data = realloc(p->_Begin,Total);
  116. if (!Data)
  117. return 0;
  118. p->_End = Data + (p->_End - p->_Begin);
  119. p->_Begin = Data;
  120. p->_Allocated = Total;
  121. return 1;
  122. }
  123. bool_t ArrayAppend(array* p, const void* Ptr, size_t Length, size_t Align)
  124. {
  125. size_t Total = p->_End - p->_Begin + Length;
  126. if (Total > p->_Allocated && !ArrayAlloc(p,Total,Align))
  127. return 0;
  128. if (Ptr)
  129. memcpy(p->_End,Ptr,Length);
  130. p->_End += Length;
  131. return 1;
  132. }
  133. void ArraySort(array* p, int Count, size_t Width, arraycmp Cmp)
  134. {
  135. qsort(p->_Begin,Count,Width,Cmp);
  136. }
  137. int ArrayFind(const array* p, int Count, size_t Width, const void* Data, arraycmp Cmp, bool_t* Found)
  138. {
  139. if (Cmp)
  140. {
  141. int i;
  142. int Mid = 0;
  143. int Lower = 0;
  144. int Upper = Count-1;
  145. while (Upper >= Lower) 
  146. {
  147. Mid = (Upper + Lower) >> 1;
  148. i = Cmp(p->_Begin+Width*Mid,Data);
  149. if (i>0)
  150. Upper = Mid-1;
  151. else if (i<0)  
  152. Lower = Mid+1;
  153. else 
  154. {         
  155. *Found = 1;
  156. return Mid;
  157. }
  158. }
  159. *Found = 0;
  160. if (Upper == Mid - 1)
  161. return Mid;
  162. else                 
  163. return Lower;    
  164. }
  165. else
  166. {
  167. int No = 0;
  168. const uint8_t* i;
  169. for (i=p->_Begin;Count--;i+=Width,++No)
  170. if (memcmp(i,Data,Width)==0)
  171. {
  172. *Found = 1;
  173. return No;
  174. }
  175. *Found = 0;
  176. return No;
  177. }
  178. }
  179. bool_t ArrayAdd(array* p,int Count, size_t Width, const void* Data, arraycmp Cmp,size_t Align)
  180. {
  181. int Pos;
  182. bool_t Found;
  183. Pos = ArrayFind(p,Count,Width,Data,Cmp,&Found);
  184. if (!Found)
  185. {
  186. if (!ArrayAppend(p,NULL,Width,Align))
  187. return 0;
  188. memmove(p->_Begin+Width*(Pos+1),p->_Begin+Width*Pos,(Count-Pos)*Width);
  189. }
  190. memcpy(p->_Begin+Width*Pos,Data,Width);
  191. return 1;
  192. }
  193. bool_t ArrayRemove(array* p, int Count, size_t Width, const void* Data, arraycmp Cmp)
  194. {
  195. bool_t Found;
  196. int Pos = ArrayFind(p,Count,Width,Data,Cmp,&Found);
  197. if (Found)
  198. {
  199. memmove(p->_Begin+Pos*Width,p->_Begin+(Pos+1)*Width,(p->_End-p->_Begin)-(Pos+1)*Width);
  200. p->_End -= Width;
  201. }
  202. return Found;
  203. }
  204. void ArrayLock(array* p)
  205. {
  206. #ifdef TARGET_PALMOS
  207. if (!p->_Block.Ptr && p->_End != p->_Begin)
  208. {
  209. int n = p->_End-p->_Begin;
  210. if (AllocBlock(n,&p->_Block,1,HEAP_STORAGE))
  211. {
  212. WriteBlock(&p->_Block,0,p->_Begin,n);
  213. free(p->_Begin);
  214. p->_Begin = (uint8_t*)p->_Block.Ptr;
  215. p->_End = p->_Begin + n;
  216. p->_Allocated = 0;
  217. }
  218. }
  219. #endif
  220. }
  221. bool_t ArrayUnlock(array* p,size_t Align)
  222. {
  223. #ifdef TARGET_PALMOS
  224. if (p->_Block.Ptr)
  225. {
  226. uint8_t* Mem;
  227. size_t n = p->_End-p->_Begin;
  228. size_t Total;
  229. --Align;
  230. Total = (n + Align) & ~Align;
  231. Mem = (uint8_t*) malloc(Total);
  232. if (!Mem)
  233. return 0;
  234. memcpy(Mem,p->_Begin,n);
  235. FreeBlock(&p->_Block);
  236. p->_Begin = Mem;
  237. p->_End = p->_Begin + n;
  238. p->_Allocated = Total;
  239. }
  240. #endif
  241. return 1;
  242. }