Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * Cumulates content of <tt>in</tt> into internal buffer and forwards
- * decoding request to
- * {@link #doDecode(IoSession, IoBuffer, ProtocolDecoderOutput)}.
- * <tt>doDecode()</tt> is invoked repeatedly until it returns <tt>false</tt>
- * and the cumulative buffer is compacted after decoding ends.
- *
- * @throws IllegalStateException
- * if your <tt>doDecode()</tt> returned <tt>true</tt> not
- * consuming the cumulative buffer.
- */
- public void decode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception {
- // if (!session.getTransportMetadata().hasFragmentation()) {
- while (in.hasRemaining()) {
- if (!doDecode(session, in, out)) {
- break;
- }
- }
- // return;
- // }
- boolean usingSessionBuffer = true;
- IoBuffer buf = (IoBuffer) session.getAttribute(BUFFER);
- // If we have a session buffer, append data to that; otherwise
- // use the buffer read from the network directly.
- if (buf != null) {
- boolean appended = false;
- // Make sure that the buffer is auto-expanded.
- if (buf.isAutoExpand()) {
- try {
- buf.put(in);
- appended = true;
- } catch (IllegalStateException e) {
- // A user called derivation method (e.g. slice()),
- // which disables auto-expansion of the parent buffer.
- } catch (IndexOutOfBoundsException e) {
- // A user disabled auto-expansion.
- }
- }
- if (appended) {
- buf.flip();
- } else {
- // Reallocate the buffer if append operation failed due to
- // derivation or disabled auto-expansion.
- buf.flip();
- IoBuffer newBuf = IoBuffer.allocate(buf.remaining() + in.remaining()).setAutoExpand(true);
- newBuf.order(buf.order());
- newBuf.put(buf);
- newBuf.put(in);
- newBuf.flip();
- buf = newBuf;
- // Update the session attribute.
- session.setAttribute(BUFFER, buf);
- }
- } else {
- buf = in;
- usingSessionBuffer = false;
- }
- for (;;) {
- int oldPos = buf.position();
- boolean decoded = doDecode(session, buf, out);
- if (decoded) {
- if (buf.position() == oldPos) {
- throw new IllegalStateException("doDecode() can't return true when buffer is not consumed.");
- }
- if (!buf.hasRemaining()) {
- break;
- }
- } else {
- break;
- }
- }
- // if there is any data left that cannot be decoded, we store
- // it in a buffer in the session and next time this decoder is
- // invoked the session buffer gets appended to
- if (buf.hasRemaining()) {
- if (usingSessionBuffer && buf.isAutoExpand()) {
- buf.compact();
- } else {
- storeRemainingInSession(buf, session);
- }
- } else {
- if (usingSessionBuffer) {
- removeSessionBuffer(session);
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment