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, ptr, size, 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 relay data, but could not flush anything |
323 // give up and avoid endless trying |
323 // i.e. we have to give up to 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 if (ritems > 0) { |
327 if (ritems > 0) { |
328 const unsigned char *rest = ptr; |
328 const unsigned char *rest = ptr; |
332 return items_flush; |
332 return items_flush; |
333 } |
333 } |
334 } else { |
334 } else { |
335 items_flush = cx_buffer_flush_impl(buffer, size); |
335 items_flush = cx_buffer_flush_impl(buffer, size); |
336 if (items_flush == 0) { |
336 if (items_flush == 0) { |
337 return 0; |
337 // flush target is full, let's try to truncate |
|
338 size_t remaining_space; |
|
339 if (buffer->flags & CX_BUFFER_AUTO_EXTEND) { |
|
340 remaining_space = buffer->flush->threshold > buffer->pos |
|
341 ? buffer->flush->threshold - buffer->pos |
|
342 : 0; |
|
343 } else { |
|
344 remaining_space = buffer->capacity > buffer->pos |
|
345 ? buffer->capacity - buffer->pos |
|
346 : 0; |
|
347 } |
|
348 nitems = remaining_space / size; |
|
349 if (nitems == 0) { |
|
350 return 0; |
|
351 } |
338 } |
352 } |
339 return cxBufferWrite(ptr, size, nitems, buffer); |
353 return cxBufferWrite(ptr, size, nitems, buffer); |
340 } |
354 } |
341 } else { |
355 } else { |
342 memcpy(buffer->bytes + buffer->pos, ptr, len); |
356 memcpy(buffer->bytes + buffer->pos, ptr, len); |