- /* Adjust reserved header if there is enough room */
- if( p_block->p_buffer - i_prebody > p_sys->p_allocated_buffer &&
- p_block->p_buffer - i_prebody < p_sys->p_allocated_buffer +
- p_sys->i_allocated_buffer )
+ uint8_t *p_start = p_sys->p_allocated_buffer;
+ uint8_t *p_end = p_sys->p_allocated_buffer + p_sys->i_allocated_buffer;
+
+ assert( p_block->p_buffer + p_block->i_buffer <= p_end );
+ assert( p_block->p_buffer >= p_start );
+
+ /* Corner case: the current payload is discarded completely */
+ if( i_prebody <= 0 && p_block->i_buffer <= (size_t)-i_prebody )
+ p_block->i_buffer = 0; /* discard current payload */
+ if( p_block->i_buffer == 0 )
+ {
+ size_t available = p_end - p_start;
+
+ if( requested <= available )
+ { /* Enough room: recycle buffer */
+ size_t extra = available - requested;
+
+ p_block->p_buffer = p_start + (extra / 2);
+ p_block->i_buffer = requested;
+ return p_block;
+ }
+ /* Not enough room: allocate a new buffer */
+ block_t *p_rea = block_Alloc( requested );
+ if( p_rea )
+ BlockMetaCopy( p_rea, p_block );
+ block_Release( p_block );
+ return p_rea;
+ }
+
+ /* First, shrink payload */
+
+ /* Pull payload start */
+ if( i_prebody < 0 )