# NIO2 and ByteBuffer use for reading variable length messages

I am reading variable length messages where each message is an int + msg bytes. Messages could be any size.

Right now my strategy is to have a direct buffer that reads from the socket, which then transfers the bytes read into an array-backed nondirect buffer. However my solution has a lot of copying, some loops and just feels a bit "icky".

Is there a better solution?

Here is the read completion handler. I'm hoping it should be pretty obvious what is going on:

class DelimitedReadCompletionHandler implements CompletionHandler<Integer, Object> {

private final AsynchronousByteChannel channel;
private final Consumer<byte[]> onMessageCallback;
private final ByteBuffer channelReadBuffer; // this is a direct buffer.

private volatile ByteBuffer currentMessageBuffer;

Consumer<byte[]> onMessageCallback,

this.channel = channel;
this.onMessageCallback = onMessageCallback;
}

@Override
public void completed(Integer result,
Object attachment) {

do {
if (currentMessageBuffer == null) {
break;
}

}

for (int i = 0; i < copyLength; i++) {
}

if (!currentMessageBuffer.hasRemaining()) {
byte[] msg = currentMessageBuffer.array();
ForkJoinPool.commonPool().execute(() -> onMessageCallback.accept(msg));

currentMessageBuffer = null;
}

continue;
}

break;
} while (true);

}

@Override
public void failed(Throwable exc,
Object attachment) {

exc.printStackTrace();
}
}


As stated above, I was very confused by your code. However, if your methods included JavaDoc, then I wouldn't be so confused by the names.

Here is an example of JavaDoc on a simple method:

/**
Returns the sum of both of the parameters.
*/
public int add(int a, int b) {
return a + b;
}


Note the /**? This is required for it to be valid JavaDoc.

In more complicated functions where the parameters aren't clear or the return value isn't clear, you can include something like this in your JavaDoc:

@param nameOfParameter -- description/purpose of parameter
@return -- description of return
-- description of return
-- description of return


You would have multiple -- description of returns if there were multiple potential return values.

There is no point in having a do/while loop where the condition being checked is true; if it were just a normal while loop, it would run atleast once anyway.

I recommend that you change your do/while to just a while as while loops are much more common.

I can not go into the way you tried to solve the problem because I am having trouble understanding your code. I believe this is just on me, but I think that having more documentation would help anyway.

• I'm not sure whether you realise or not, but CompletionHandler is part of the JDK! I am implementing this interface so have no choice but to use those method names. Also the JavaDoc that is on the interface is sufficient I feel (not sure what other people feel). Agree about the do-while loop, i guess I was just being lazy by writing less code. – Cheetah Jul 6 '15 at 11:01
• You are right; I didn't even notice CompletionHandler was part of the JDK. – SirPython Jul 6 '15 at 17:01