// Deflate no more than stride bytes at a time. This avoids
// excess copying in deflateBytes (see Deflater.c)
int stride = bufferSize;
Buffer resultBuffer = null;
final ByteBufferArray byteBufferArray = buffer.toByteBufferArray();
final ByteBuffer[] buffers = byteBufferArray.getArray();
final int size = byteBufferArray.size();
for (int i = 0; i < size; i++) {
final ByteBuffer byteBuffer = buffers[i];
final int len = byteBuffer.remaining();
if (len > 0) {
final byte[] buf;
final int off;
if (byteBuffer.hasArray()) {
buf = byteBuffer.array();
off = byteBuffer.arrayOffset() + byteBuffer.position();
} else {
// @TODO allocate byte array via MemoryUtils
buf = new byte[len];
off = 0;
byteBuffer.get(buf);
byteBuffer.position(byteBuffer.position() - len);
}
for (int j = 0; j < len; j += stride) {
deflater.setInput(buf, off + j, Math.min(stride, len - j));
while (!deflater.needsInput()) {
final Buffer deflated = deflate(deflater, memoryManager);
if (deflated != null) {
resultBuffer = Buffers.appendBuffers(
memoryManager, resultBuffer, deflated);
}
}
}
crc32.update(buf, off, len);
}
}
byteBufferArray.restore();
byteBufferArray.recycle();
buffer.position(buffer.limit());
return resultBuffer;
}