return delta;
}
-/* This function realigns input data in a possibly wrapping buffer so that it
- * becomes contiguous and starts at the beginning of the buffer area. The
- * function may only be used when the buffer's output is empty.
+/* This function realigns a possibly wrapping buffer so that the input part is
+ * contiguous and starts at the beginning of the buffer and the output part
+ * ends at the end of the buffer. This provides the best conditions since it
+ * allows the largest inputs to be processed at once and ensures that once the
+ * output data leaves, the whole buffer is available at once.
*/
void buffer_slow_realign(struct buffer *buf)
{
- /* two possible cases :
- * - the buffer is in one contiguous block, we move it in-place
- * - the buffer is in two blocks, we move it via the swap_buffer
- */
- if (buf->i) {
- int block1 = buf->i;
- int block2 = 0;
- if (buf->p + buf->i > buf->data + buf->size) {
- /* non-contiguous block */
- block1 = buf->data + buf->size - buf->p;
- block2 = buf->p + buf->i - (buf->data + buf->size);
- }
- if (block2)
- memcpy(swap_buffer, buf->data, block2);
- memmove(buf->data, buf->p, block1);
- if (block2)
- memcpy(buf->data + block1, swap_buffer, block2);
+ int block1 = buf->o;
+ int block2 = 0;
+
+ /* process output data in two steps to cover wrapping */
+ if (block1 > buf->p - buf->data) {
+ block2 = buf->p - buf->data;
+ block1 -= block2;
}
+ memcpy(swap_buffer + buf->size - buf->o, bo_ptr(buf), block1);
+ memcpy(swap_buffer + buf->size - block2, buf->data, block2);
+
+ /* process input data in two steps to cover wrapping */
+ block1 = buf->i;
+ block2 = 0;
+
+ if (block1 > buf->data + buf->size - buf->p) {
+ block1 = buf->data + buf->size - buf->p;
+ block2 = buf->i - block1;
+ }
+ memcpy(swap_buffer, bi_ptr(buf), block1);
+ memcpy(swap_buffer + block1, buf->data, block2);
+
+ /* reinject changes into the buffer */
+ memcpy(buf->data, swap_buffer, buf->i);
+ memcpy(buf->data + buf->size - buf->o, swap_buffer + buf->size - buf->o, buf->o);
buf->p = buf->data;
}