203 } |
203 } |
204 } |
204 } |
205 |
205 |
206 static size_t cx_buffer_flush_helper( |
206 static size_t cx_buffer_flush_helper( |
207 const CxBuffer *buffer, |
207 const CxBuffer *buffer, |
|
208 const unsigned char *src, |
208 size_t size, |
209 size_t size, |
209 const unsigned char *src, |
|
210 size_t nitems |
210 size_t nitems |
211 ) { |
211 ) { |
212 // flush data from an arbitrary source |
212 // flush data from an arbitrary source |
213 // does not need to be the buffer's contents |
213 // does not need to be the buffer's contents |
214 size_t max_items = buffer->flush->blksize / size; |
214 size_t max_items = buffer->flush->blksize / size; |
234 static size_t cx_buffer_flush_impl(CxBuffer *buffer, size_t size) { |
234 static size_t cx_buffer_flush_impl(CxBuffer *buffer, size_t size) { |
235 // flush the current contents of the buffer |
235 // flush the current contents of the buffer |
236 unsigned char *space = buffer->bytes; |
236 unsigned char *space = buffer->bytes; |
237 size_t remaining = buffer->pos / size; |
237 size_t remaining = buffer->pos / size; |
238 size_t flushed_total = cx_buffer_flush_helper( |
238 size_t flushed_total = cx_buffer_flush_helper( |
239 buffer, size, space, remaining); |
239 buffer, space, size, remaining); |
240 |
240 |
241 // shift the buffer left after flushing |
241 // shift the buffer left after flushing |
242 // IMPORTANT: up to this point, copy on write must have been |
242 // IMPORTANT: up to this point, copy on write must have been |
243 // performed already, because we can't do error handling here |
243 // performed already, because we can't do error handling here |
244 cxBufferShiftLeft(buffer, flushed_total*size); |
244 cxBufferShiftLeft(buffer, flushed_total*size); |
315 if (perform_flush) { |
315 if (perform_flush) { |
316 size_t items_flush; |
316 size_t items_flush; |
317 if (buffer->pos == 0) { |
317 if (buffer->pos == 0) { |
318 // if we don't have data in the buffer, but are instructed |
318 // if we don't have data in the buffer, but are instructed |
319 // to flush, it means that we are supposed to relay the data |
319 // to flush, it means that we are supposed to relay the data |
320 items_flush = cx_buffer_flush_helper(buffer, size, ptr, nitems); |
320 items_flush = cx_buffer_flush_helper(buffer, ptr, size, nitems); |
321 if (items_flush == 0) { |
321 if (items_flush == 0) { |
322 // we needed to flush, but could not flush anything |
322 // we needed to flush, but could not flush anything |
323 // give up and avoid endless trying |
323 // give up and avoid endless trying |
324 return 0; |
324 return 0; |
325 } |
325 } |
326 size_t ritems = nitems - items_flush; |
326 size_t ritems = nitems - items_flush; |
327 const unsigned char *rest = ptr; |
327 if (ritems > 0) { |
328 rest += items_flush * size; |
328 const unsigned char *rest = ptr; |
329 return items_flush + cxBufferWrite(rest, size, ritems, buffer); |
329 rest += items_flush * size; |
|
330 return items_flush + cxBufferWrite(rest, size, ritems, buffer); |
|
331 } else { |
|
332 return items_flush; |
|
333 } |
330 } else { |
334 } else { |
331 items_flush = cx_buffer_flush_impl(buffer, size); |
335 items_flush = cx_buffer_flush_impl(buffer, size); |
332 if (items_flush == 0) { |
336 if (items_flush == 0) { |
333 return 0; |
337 return 0; |
334 } |
338 } |