TransformationResult<Buffer, Buffer> transformationResult = null;
Buffer targetBuffer = null;
Buffer currentTargetBuffer = null;
final ByteBufferArray originalByteBufferArray =
originalMessage.toByteBufferArray();
boolean restore = false;
for (int i = 0; i < originalByteBufferArray.size(); i++) {
final int pos = originalMessage.position();
final ByteBuffer originalByteBuffer = originalByteBufferArray.getArray()[i];
currentTargetBuffer = allowDispose(memoryManager.allocate(
sslEngine.getSession().getPacketBufferSize()));
final ByteBuffer currentTargetByteBuffer =
currentTargetBuffer.toByteBuffer();
try {
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.log(Level.FINE, "SSLEncoder engine: {0} input: {1} output: {2}",
new Object[]{sslEngine, originalByteBuffer, currentTargetByteBuffer});
}
final SSLEngineResult sslEngineResult =
sslEngine.wrap(originalByteBuffer,
currentTargetByteBuffer);
// If the position of the original message hasn't changed,
// update the position now.
if (pos == originalMessage.position()) {
restore = true;
originalMessage.position(pos + sslEngineResult.bytesConsumed());
}
final SSLEngineResult.Status status = sslEngineResult.getStatus();
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.log(Level.FINE, "SSLEncoder done engine: {0} result: {1} input: {2} output: {3}",
new Object[]{sslEngine, sslEngineResult, originalByteBuffer, currentTargetByteBuffer});
}
if (status == SSLEngineResult.Status.OK) {
currentTargetBuffer.position(sslEngineResult.bytesProduced());
currentTargetBuffer.trim();
targetBuffer = Buffers.appendBuffers(memoryManager,
targetBuffer, currentTargetBuffer);
} else if (status == SSLEngineResult.Status.CLOSED) {
transformationResult =
TransformationResult.createCompletedResult(
Buffers.EMPTY_BUFFER, originalMessage);
break;
} else {
if (status == SSLEngineResult.Status.BUFFER_UNDERFLOW) {
transformationResult =
TransformationResult.createErrorResult(
BUFFER_UNDERFLOW_ERROR,
"Buffer underflow during wrap operation");
} else if (status == SSLEngineResult.Status.BUFFER_OVERFLOW) {
transformationResult =
TransformationResult.createErrorResult(
BUFFER_OVERFLOW_ERROR,
"Buffer overflow during wrap operation");
}
break;
}
} catch (SSLException e) {
disposeBuffers(currentTargetBuffer, targetBuffer);
originalByteBufferArray.restore();
throw new TransformationException(e);
}
if (originalByteBuffer.hasRemaining()) { // Keep working with the current source ByteBuffer
i--;
}
}
assert !originalMessage.hasRemaining();
if (restore) {
originalByteBufferArray.restore();
}
originalByteBufferArray.recycle();
if (transformationResult != null) { // transformation error case
disposeBuffers(currentTargetBuffer, targetBuffer);
return transformationResult;