Java Code Examples for io.netty.buffer.CompositeByteBuf#writerIndex()

The following examples show how to use io.netty.buffer.CompositeByteBuf#writerIndex() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: BufUnwrapperTest.java    From grpc-nebula-java with Apache License 2.0 6 votes vote down vote up
@Test
public void writableNioBuffers_worksWithComposite() {
  CompositeByteBuf buf = alloc.compositeBuffer();
  buf.addComponent(alloc.buffer(1));
  buf.capacity(1);
  try (BufUnwrapper unwrapper = new BufUnwrapper()) {
    ByteBuffer[] internalBufs = unwrapper.writableNioBuffers(buf);
    Truth.assertThat(internalBufs).hasLength(1);

    internalBufs[0].put((byte) 'a');

    buf.writerIndex(1);
    assertEquals('a', buf.readByte());
  } finally {
    buf.release();
  }
}
 
Example 2
Source File: PacketEncoder.java    From socketio with Apache License 2.0 6 votes vote down vote up
public static ByteBuf encodePacket(final Packet packet) throws IOException {
  ByteBuf dataBytes = packet.getData();
  boolean hasData = dataBytes != null;

  CompositeByteBuf compositeByteBuf = PooledByteBufAllocator.DEFAULT.compositeBuffer(hasData ? 1 : 2);

  byte[] typeBytes = packet.getType().getValueAsBytes();
  int headerCapacity = typeBytes.length + DELIMITER_LENGTH + DELIMITER_LENGTH + (hasData ? DELIMITER_LENGTH : 0);
  ByteBuf headerByteBuf = PooledByteBufAllocator.DEFAULT.buffer(headerCapacity, headerCapacity);
  headerByteBuf.writeBytes(typeBytes);
  headerByteBuf.writeBytes(DELIMITER_BYTES);
  headerByteBuf.writeBytes(DELIMITER_BYTES);
  if (hasData) {
    headerByteBuf.writeBytes(DELIMITER_BYTES);
  }
  compositeByteBuf.addComponent(headerByteBuf);
  int compositeReadableBytes = headerByteBuf.readableBytes();

  if (hasData) {
    compositeByteBuf.addComponent(dataBytes);
    compositeReadableBytes += dataBytes.readableBytes();
  }

  compositeByteBuf.writerIndex(compositeReadableBytes);
  return compositeByteBuf;
}
 
Example 3
Source File: BufUnwrapperTest.java    From grpc-java with Apache License 2.0 6 votes vote down vote up
@Test
public void writableNioBuffers_worksWithComposite() {
  CompositeByteBuf buf = alloc.compositeBuffer();
  buf.addComponent(alloc.buffer(1));
  buf.capacity(1);
  try (BufUnwrapper unwrapper = new BufUnwrapper()) {
    ByteBuffer[] internalBufs = unwrapper.writableNioBuffers(buf);
    Truth.assertThat(internalBufs).hasLength(1);

    internalBufs[0].put((byte) 'a');

    buf.writerIndex(1);
    assertEquals('a', buf.readByte());
  } finally {
    buf.release();
  }
}
 
Example 4
Source File: SubMultiLookupRequest.java    From couchbase-jvm-core with Apache License 2.0 6 votes vote down vote up
private static ByteBuf encode(List<LookupCommand> commands) {
    CompositeByteBuf compositeBuf = Unpooled.compositeBuffer(commands.size()); //FIXME pooled allocator?
    for (LookupCommand command : commands) {
        byte[] pathBytes = command.path().getBytes(CharsetUtil.UTF_8);
        short pathLength = (short) pathBytes.length;

        ByteBuf commandBuf = Unpooled.buffer(4 + pathLength); //FIXME a way of using the pooled allocator?
        commandBuf.writeByte(command.opCode());
        //flags
        if (command.xattr()) {
            commandBuf.writeByte(SUBDOC_FLAG_XATTR_PATH);
        } else {
            commandBuf.writeByte(0);
        }
        commandBuf.writeShort(pathLength);
        //no value length
        commandBuf.writeBytes(pathBytes);

        compositeBuf.addComponent(commandBuf);
        compositeBuf.writerIndex(compositeBuf.writerIndex() + commandBuf.readableBytes());
    }
    return compositeBuf;
}
 
Example 5
Source File: AbstractSubdocRequest.java    From couchbase-jvm-core with Apache License 2.0 6 votes vote down vote up
protected ByteBuf createContent(ByteBuf pathByteBuf, ByteBuf... restOfContent) {
    if (restOfContent == null || restOfContent.length == 0) {
        return pathByteBuf;
    } else {
        CompositeByteBuf composite = Unpooled.compositeBuffer(1 + restOfContent.length);
        composite.addComponent(pathByteBuf);
        composite.writerIndex(composite.writerIndex() + pathByteBuf.readableBytes());

        for (ByteBuf component : restOfContent) {
            composite.addComponent(component);
            composite.writerIndex(composite.writerIndex() + component.readableBytes());
        }

        return composite;
    }
}
 
Example 6
Source File: FileOperationEncoder.java    From fastdfs-client with Apache License 2.0 6 votes vote down vote up
@Override
public List<Object> encode(ByteBufAllocator alloc) {
    ByteBuf meta = metadata(alloc);

    ByteBuf head = alloc.buffer(FDFS_HEAD_LEN);
    head.writeLong(meta.readableBytes() + size);
    head.writeByte(cmd());
    head.writeByte(ERRNO_OK);

    CompositeByteBuf cbb = alloc.compositeBuffer();
    cbb.addComponents(head, meta);
    cbb.writerIndex(head.readableBytes() + meta.readableBytes());

    List<Object> requests = new LinkedList<>();
    requests.add(cbb);
    requests.add(content);
    return requests;
}
 
Example 7
Source File: FileOperationEncoder.java    From azeroth with Apache License 2.0 6 votes vote down vote up
@Override
public List<Object> encode(ByteBufAllocator alloc) {
    ByteBuf meta = metadata(alloc);

    ByteBuf head = alloc.buffer(FDFS_HEAD_LEN);
    head.writeLong(meta.readableBytes() + size);
    head.writeByte(cmd());
    head.writeByte(ERRNO_OK);

    CompositeByteBuf cbb = alloc.compositeBuffer();
    cbb.addComponents(head, meta);
    cbb.writerIndex(head.readableBytes() + meta.readableBytes());

    List<Object> requests = new LinkedList<>();
    requests.add(cbb);
    requests.add(content);
    return requests;
}
 
Example 8
Source File: DatagramUnicastTest.java    From netty4.0.27Learn with Apache License 2.0 5 votes vote down vote up
public void testSimpleSendCompositeDirectByteBuf(Bootstrap sb, Bootstrap cb) throws Throwable {
    CompositeByteBuf buf = Unpooled.compositeBuffer();
    buf.addComponent(Unpooled.directBuffer().writeBytes(BYTES, 0, 2));
    buf.addComponent(Unpooled.directBuffer().writeBytes(BYTES, 2, 2));
    buf.writerIndex(4);
    testSimpleSend0(sb, cb, buf, true, BYTES, 1);

    CompositeByteBuf buf2 = Unpooled.compositeBuffer();
    buf2.addComponent(Unpooled.directBuffer().writeBytes(BYTES, 0, 2));
    buf2.addComponent(Unpooled.directBuffer().writeBytes(BYTES, 2, 2));
    buf2.writerIndex(4);
    testSimpleSend0(sb, cb, buf2, true, BYTES, 4);
}
 
Example 9
Source File: DatagramUnicastTest.java    From netty4.0.27Learn with Apache License 2.0 5 votes vote down vote up
public void testSimpleSendCompositeHeapByteBuf(Bootstrap sb, Bootstrap cb) throws Throwable {
    CompositeByteBuf buf = Unpooled.compositeBuffer();
    buf.addComponent(Unpooled.buffer().writeBytes(BYTES, 0, 2));
    buf.addComponent(Unpooled.buffer().writeBytes(BYTES, 2, 2));
    buf.writerIndex(4);
    testSimpleSend0(sb, cb, buf, true, BYTES, 1);

    CompositeByteBuf buf2 = Unpooled.compositeBuffer();
    buf2.addComponent(Unpooled.buffer().writeBytes(BYTES, 0, 2));
    buf2.addComponent(Unpooled.buffer().writeBytes(BYTES, 2, 2));
    buf2.writerIndex(4);
    testSimpleSend0(sb, cb, buf2, true, BYTES, 4);
}
 
Example 10
Source File: DatagramUnicastTest.java    From netty4.0.27Learn with Apache License 2.0 5 votes vote down vote up
public void testSimpleSendCompositeMixedByteBuf(Bootstrap sb, Bootstrap cb) throws Throwable {
    CompositeByteBuf buf = Unpooled.compositeBuffer();
    buf.addComponent(Unpooled.directBuffer().writeBytes(BYTES, 0, 2));
    buf.addComponent(Unpooled.buffer().writeBytes(BYTES, 2, 2));
    buf.writerIndex(4);
    testSimpleSend0(sb, cb, buf, true, BYTES, 1);

    CompositeByteBuf buf2 = Unpooled.compositeBuffer();
    buf2.addComponent(Unpooled.directBuffer().writeBytes(BYTES, 0, 2));
    buf2.addComponent(Unpooled.buffer().writeBytes(BYTES, 2, 2));
    buf2.writerIndex(4);
    testSimpleSend0(sb, cb, buf2, true, BYTES, 4);
}
 
Example 11
Source File: SnappyFramedEncoderTest.java    From netty4.0.27Learn with Apache License 2.0 5 votes vote down vote up
@Test
public void testStreamStartIsOnlyWrittenOnce() throws Exception {
    ByteBuf in = Unpooled.wrappedBuffer(new byte[] {
        'n', 'e', 't', 't', 'y'
    });

    channel.writeOutbound(in.copy());
    in.readerIndex(0); // rewind the buffer to write the same data
    channel.writeOutbound(in.copy());
    assertTrue(channel.finish());

    ByteBuf expected = Unpooled.wrappedBuffer(new byte[] {
        (byte) 0xff, 0x06, 0x00, 0x00, 0x73, 0x4e, 0x61, 0x50, 0x70, 0x59,
         0x01, 0x09, 0x00, 0x00, 0x6f, -0x68, -0x7e, -0x5e, 'n', 'e', 't', 't', 'y',
         0x01, 0x09, 0x00, 0x00, 0x6f, -0x68, -0x7e, -0x5e, 'n', 'e', 't', 't', 'y',
    });

    CompositeByteBuf actual = Unpooled.compositeBuffer();
    for (;;) {
        ByteBuf m = (ByteBuf) channel.readOutbound();
        if (m == null) {
            break;
        }
        actual.addComponent(m);
        actual.writerIndex(actual.writerIndex() + m.readableBytes());
    }
    assertEquals(releaseLater(expected), releaseLater(actual));
    in.release();
}
 
Example 12
Source File: TFrameCodec.java    From tchannel-java with MIT License 5 votes vote down vote up
public static ByteBuf encode(ByteBufAllocator allocator, TFrame frame) {
    ByteBuf buffer = allocator.buffer(TFrame.FRAME_HEADER_LENGTH, TFrame.FRAME_HEADER_LENGTH);

    final ByteBuf result;
    boolean release = true;
    try {
        // size:2
        buffer.writeShort(frame.size + TFrame.FRAME_HEADER_LENGTH);

        // type:1
        buffer.writeByte(frame.type);

        // reserved:1
        buffer.writeZero(1);

        // id:4
        buffer.writeInt((int) frame.id);

        // reserved:8
        buffer.writeZero(8);

        // TODO: refactor
        if (frame.payload instanceof CompositeByteBuf) {
            CompositeByteBuf cbf = (CompositeByteBuf) frame.payload;
            cbf.addComponent(0, buffer);
            cbf.writerIndex(cbf.writerIndex() + TFrame.FRAME_HEADER_LENGTH);
            result = cbf;
        } else {
            result = Unpooled.wrappedBuffer(buffer, frame.payload);
        }
        release = false;
    } finally {
        if (release) {
            buffer.release();
        }
    }
    return result;
}
 
Example 13
Source File: SubMultiMutationRequest.java    From couchbase-jvm-core with Apache License 2.0 5 votes vote down vote up
private static ByteBuf encode(List<MutationCommand> commands) {
    //FIXME a way of using the pooled allocator?
    CompositeByteBuf compositeBuf = Unpooled.compositeBuffer(commands.size());
    for (MutationCommand command : commands) {
        byte[] pathBytes = command.path().getBytes(CharsetUtil.UTF_8);
        short pathLength = (short) pathBytes.length;

        ByteBuf commandBuf = Unpooled.buffer(4 + pathLength + command.fragment().readableBytes());
        commandBuf.writeByte(command.opCode());
        byte subdocFlags = 0;
        if (command.createIntermediaryPath()) {
            subdocFlags |= KeyValueHandler.SUBDOC_BITMASK_MKDIR_P;
        }
        if (command.xattr()) {
            subdocFlags |= KeyValueHandler.SUBDOC_FLAG_XATTR_PATH;
        }
        if (command.expandMacros()) {
            subdocFlags |= KeyValueHandler.SUBDOC_FLAG_EXPAND_MACROS;
        }
        commandBuf.writeByte(subdocFlags);
        commandBuf.writeShort(pathLength);
        commandBuf.writeInt(command.fragment().readableBytes());
        commandBuf.writeBytes(pathBytes);

        //copy the fragment but don't move indexes (in case it is retained and reused)
        commandBuf.writeBytes(command.fragment(), command.fragment().readerIndex(), command.fragment().readableBytes());
        //eagerly release the fragment once it's been copied
        command.fragment().release();

        //add the command to the composite buffer
        compositeBuf.addComponent(commandBuf);
        compositeBuf.writerIndex(compositeBuf.writerIndex() + commandBuf.readableBytes());
    }
    return compositeBuf;
}
 
Example 14
Source File: NettyHandlerTestBase.java    From grpc-java with Apache License 2.0 5 votes vote down vote up
protected final ByteBuf captureWrite(ChannelHandlerContext ctx) {
  ArgumentCaptor<ByteBuf> captor = ArgumentCaptor.forClass(ByteBuf.class);
  verify(ctx, atLeastOnce()).write(captor.capture(), any(ChannelPromise.class));
  CompositeByteBuf composite = Unpooled.compositeBuffer();
  for (ByteBuf buf : captor.getAllValues()) {
    composite.addComponent(buf);
    composite.writerIndex(composite.writerIndex() + buf.readableBytes());
  }
  return composite;
}
 
Example 15
Source File: ChunkCreationHandler.java    From Bats with Apache License 2.0 5 votes vote down vote up
@Override
protected void encode(ChannelHandlerContext ctx, ByteBuf msg, List<Object> out) throws Exception {

  if (RpcConstants.EXTRA_DEBUGGING) {
    logger.debug("ChunkCreationHandler called with msg {} of size {} with chunkSize {}",
        msg, msg.readableBytes(), chunkSize);
  }

  if (!ctx.channel().isOpen()) {
    logger.debug("Channel closed, skipping encode inside {}.", RpcConstants.CHUNK_CREATION_HANDLER);
    msg.release();
    return;
  }

  // Calculate the number of chunks based on configured chunk size and input msg size
  int numChunks = (int) Math.ceil((double) msg.readableBytes() / chunkSize);

  // Initialize a composite buffer to hold numChunks chunk.
  final CompositeByteBuf cbb = ctx.alloc().compositeBuffer(numChunks);

  int cbbWriteIndex = 0;
  int currentChunkLen = min(msg.readableBytes(), chunkSize);

  // Create slices of chunkSize from input msg and add it to the composite buffer.
  while (numChunks > 0) {
    final ByteBuf chunkBuf = msg.slice(msg.readerIndex(), currentChunkLen);
    chunkBuf.retain();
    cbb.addComponent(chunkBuf);
    cbbWriteIndex += currentChunkLen;
    msg.skipBytes(currentChunkLen);
    --numChunks;
    currentChunkLen = min(msg.readableBytes(), chunkSize);
  }

  // Update the writerIndex of composite byte buffer. Netty doesn't do it automatically.
  cbb.writerIndex(cbbWriteIndex);

  // Add the final composite bytebuf into output buffer.
  out.add(cbb);
}
 
Example 16
Source File: NettyHandlerTestBase.java    From grpc-nebula-java with Apache License 2.0 5 votes vote down vote up
protected final ByteBuf captureWrite(ChannelHandlerContext ctx) {
  ArgumentCaptor<ByteBuf> captor = ArgumentCaptor.forClass(ByteBuf.class);
  verify(ctx, atLeastOnce()).write(captor.capture(), any(ChannelPromise.class));
  CompositeByteBuf composite = Unpooled.compositeBuffer();
  for (ByteBuf buf : captor.getAllValues()) {
    composite.addComponent(buf);
    composite.writerIndex(composite.writerIndex() + buf.readableBytes());
  }
  return composite;
}
 
Example 17
Source File: CodecUtils.java    From tchannel-java with MIT License 4 votes vote down vote up
public static @NotNull ByteBuf writeArgs(
    @NotNull ByteBufAllocator allocator,
    @NotNull ByteBuf header,
    @NotNull List<ByteBuf> args
) {
    int writableBytes = TFrame.MAX_FRAME_PAYLOAD_LENGTH - header.readableBytes();
    List<ByteBuf> allocatedBufs = new ArrayList<>(7);
    List<ByteBuf> bufs = new ArrayList<>(7);
    bufs.add(header);

    boolean release = true;
    try {
        while (!args.isEmpty()) {
            ByteBuf arg = args.get(0);
            int len = writeArg(allocator, arg, writableBytes, bufs, allocatedBufs);
            writableBytes -= len;
            if (writableBytes <= TFrame.FRAME_SIZE_LENGTH) {
                break;
            }

            if (arg.readableBytes() == 0) {
                args.remove(0);
            }
        }

        CompositeByteBuf comp = allocator.compositeBuffer();
        comp.addComponents(bufs);
        comp.writerIndex(TFrame.MAX_FRAME_PAYLOAD_LENGTH - writableBytes);
        release = false;
        return comp;
    } finally {
        if (release) {
            for (ByteBuf buf : allocatedBufs) {
                if (buf != null) {
                    try {
                        buf.release();
                    } catch (Exception e) {
                        logger.warn("Failed to release", e);
                    }
                }
            }
        }
    }

}
 
Example 18
Source File: ChunkDecoder.java    From opc-ua-stack with Apache License 2.0 4 votes vote down vote up
private ByteBuf decode(Delegate delegate, SecureChannel channel, List<ByteBuf> chunkBuffers) throws UaException {
    CompositeByteBuf composite = BufferUtil.compositeBuffer();

    int signatureSize = delegate.getSignatureSize(channel);
    int cipherTextBlockSize = delegate.getCipherTextBlockSize(channel);

    boolean encrypted = delegate.isEncryptionEnabled(channel);
    boolean signed = delegate.isSigningEnabled(channel);

    for (ByteBuf chunkBuffer : chunkBuffers) {
        char chunkType = (char) chunkBuffer.getByte(3);

        chunkBuffer.skipBytes(SecureMessageHeader.SECURE_MESSAGE_HEADER_SIZE);

        delegate.readSecurityHeader(channel, chunkBuffer);

        if (encrypted) {
            decryptChunk(delegate, channel, chunkBuffer);
        }

        int encryptedStart = chunkBuffer.readerIndex();
        chunkBuffer.readerIndex(0);

        if (signed) {
            delegate.verifyChunk(channel, chunkBuffer);
        }

        int paddingSize = encrypted ? getPaddingSize(cipherTextBlockSize, signatureSize, chunkBuffer) : 0;
        int bodyEnd = chunkBuffer.readableBytes() - signatureSize - paddingSize;

        chunkBuffer.readerIndex(encryptedStart);

        SequenceHeader sequenceHeader = SequenceHeader.decode(chunkBuffer);
        long sequenceNumber = sequenceHeader.getSequenceNumber();
        lastRequestId = sequenceHeader.getRequestId();

        if (lastSequenceNumber == -1) {
            lastSequenceNumber = sequenceNumber;
        } else {
            if (lastSequenceNumber + 1 != sequenceNumber) {
                String message = String.format("expected sequence number %s but received %s",
                        lastSequenceNumber + 1, sequenceNumber);

                logger.error(message);
                logger.error(ByteBufUtil.hexDump(chunkBuffer, 0, chunkBuffer.writerIndex()));

                throw new UaException(StatusCodes.Bad_SecurityChecksFailed, message);
            }

            lastSequenceNumber = sequenceNumber;
        }

        ByteBuf bodyBuffer = chunkBuffer.readSlice(bodyEnd - chunkBuffer.readerIndex());

        if (chunkType == 'A') {
            ErrorMessage errorMessage = ErrorMessage.decode(bodyBuffer);

            throw new MessageAbortedException(errorMessage.getError(), errorMessage.getReason());
        }

        composite.addComponent(bodyBuffer);
        composite.writerIndex(composite.writerIndex() + bodyBuffer.readableBytes());
    }

    return composite.order(ByteOrder.LITTLE_ENDIAN);
}
 
Example 19
Source File: BinaryMemcacheObjectAggregator.java    From couchbase-jvm-core with Apache License 2.0 4 votes vote down vote up
@Override
protected void decode(ChannelHandlerContext ctx, MemcacheObject msg, List<Object> out) throws Exception {
    FullMemcacheMessage currentMessage = this.currentMessage;

    if (msg instanceof MemcacheMessage) {
        tooLongFrameFound = false;
        MemcacheMessage m = (MemcacheMessage) msg;

        if (!m.getDecoderResult().isSuccess()) {
            out.add(toFullMessage(m));
            this.currentMessage = null;
            return;
        }

        if (msg instanceof BinaryMemcacheRequest) {
            this.currentMessage = toFullRequest((BinaryMemcacheRequest) msg,
                Unpooled.compositeBuffer(getMaxCumulationBufferComponents()));
        } else if (msg instanceof BinaryMemcacheResponse) {
            this.currentMessage = toFullResponse((BinaryMemcacheResponse) msg,
                Unpooled.compositeBuffer(getMaxCumulationBufferComponents()));
        } else {
            throw new Error();
        }
    } else if (msg instanceof MemcacheContent) {
        if (tooLongFrameFound) {
            if (msg instanceof LastMemcacheContent) {
                this.currentMessage = null;
            }
            return;
        }

        MemcacheContent chunk = (MemcacheContent) msg;
        CompositeByteBuf content = (CompositeByteBuf) currentMessage.content();

        if (content.readableBytes() > getMaxContentLength() - chunk.content().readableBytes()) {
            tooLongFrameFound = true;

            currentMessage.release();
            this.currentMessage = null;

            throw new TooLongFrameException("Memcache content length exceeded " + getMaxContentLength()
                + " bytes.");
        }

        if (chunk.content().isReadable()) {
            chunk.retain();
            content.addComponent(chunk.content());
            content.writerIndex(content.writerIndex() + chunk.content().readableBytes());
        }

        final boolean last;
        if (!chunk.getDecoderResult().isSuccess()) {
            currentMessage.setDecoderResult(
                DecoderResult.failure(chunk.getDecoderResult().cause()));
            last = true;
        } else {
            last = chunk instanceof LastMemcacheContent;
        }

        if (last) {
            this.currentMessage = null;
            out.add(currentMessage);
        }
    } else {
        throw new Error();
    }
}
 
Example 20
Source File: RpcEncoder.java    From Bats with Apache License 2.0 4 votes vote down vote up
@Override
protected void encode(ChannelHandlerContext ctx, OutboundRpcMessage msg, List<Object> out) throws Exception {
  if (RpcConstants.EXTRA_DEBUGGING) {
    logger.debug("Rpc Encoder called with msg {}", msg);
  }

  if (!ctx.channel().isOpen()) {
    //output.add(ctx.alloc().buffer(0));
    logger.debug("Channel closed, skipping encode.");
    msg.release();
    return;
  }

  try{
    if (RpcConstants.EXTRA_DEBUGGING) {
      logger.debug("Encoding outbound message {}", msg);
    }
    // first we build the RpcHeader
    RpcHeader header = RpcHeader.newBuilder() //
        .setMode(msg.mode) //
        .setCoordinationId(msg.coordinationId) //
        .setRpcType(msg.rpcType).build();

    // figure out the full length
    int headerLength = header.getSerializedSize();
    int protoBodyLength = msg.pBody.getSerializedSize();
    int rawBodyLength = msg.getRawBodySize();
    int fullLength = //
        HEADER_TAG_LENGTH + getRawVarintSize(headerLength) + headerLength +   //
        PROTOBUF_BODY_TAG_LENGTH + getRawVarintSize(protoBodyLength) + protoBodyLength; //

    if (rawBodyLength > 0) {
      fullLength += (RAW_BODY_TAG_LENGTH + getRawVarintSize(rawBodyLength) + rawBodyLength);
    }

    ByteBuf buf = ctx.alloc().buffer();
    OutputStream os = new ByteBufOutputStream(buf);
    CodedOutputStream cos = CodedOutputStream.newInstance(os);

    // write full length first (this is length delimited stream).
    cos.writeRawVarint32(fullLength);

    // write header
    cos.writeRawVarint32(HEADER_TAG);
    cos.writeRawVarint32(headerLength);
    header.writeTo(cos);

    // write protobuf body length and body
    cos.writeRawVarint32(PROTOBUF_BODY_TAG);
    cos.writeRawVarint32(protoBodyLength);
    msg.pBody.writeTo(cos);

    // if exists, write data body and tag.
    if (msg.getRawBodySize() > 0) {
      if(RpcConstants.EXTRA_DEBUGGING) {
        logger.debug("Writing raw body of size {}", msg.getRawBodySize());
      }

      cos.writeRawVarint32(RAW_BODY_TAG);
      cos.writeRawVarint32(rawBodyLength);
      cos.flush(); // need to flush so that dbody goes after if cos is caching.

      final CompositeByteBuf cbb = ctx.alloc().compositeBuffer(msg.dBodies.length + 1);
      cbb.addComponent(buf);
      int bufLength = buf.readableBytes();
      for (ByteBuf b : msg.dBodies) {
        cbb.addComponent(b);
        bufLength += b.readableBytes();
      }
      cbb.writerIndex(bufLength);
      out.add(cbb);
    } else {
      cos.flush();
      out.add(buf);
    }

    if (RpcConstants.SOME_DEBUGGING) {
      logger.debug("Wrote message length {}:{} bytes (head:body).  Message: " + msg, getRawVarintSize(fullLength), fullLength);
    }
    if (RpcConstants.EXTRA_DEBUGGING) {
      logger.debug("Sent message.  Ending writer index was {}.", buf.writerIndex());
    }
  } finally {
    // make sure to release Rpc Messages underlying byte buffers.
    //msg.release();
  }
}