public PartialDecodedMessage DecodePartial(IoBuffer buf)
        {
            HermesPrimitiveCodec codec = new HermesPrimitiveCodec(buf);

            // skip whole length
            codec.ReadInt();
            // skip header length
            int headerLen = codec.ReadInt();
            // skip body length
            int bodyLen = codec.ReadInt();
            verifyChecksum(buf, headerLen + bodyLen);
            PartialDecodedMessage msg = new PartialDecodedMessage();
            msg.Key = codec.ReadString();
            msg.BornTime = codec.ReadLong();
            msg.RemainingRetries = codec.ReadInt();
            msg.BodyCodecType = codec.ReadString();

            int len = codec.ReadInt();
            msg.DurableProperties = buf.GetSlice(len);

            len = codec.ReadInt();
            msg.VolatileProperties = buf.GetSlice(len);

            msg.Body = buf.GetSlice(bodyLen);

            // skip crc
            codec.ReadLong();

            return msg;
        }
        private void readBatchDatas(IoBuffer buf, HermesPrimitiveCodec codec, List<TppConsumerMessageBatch> batches)
        {
            foreach (TppConsumerMessageBatch batch in batches)
            {
                int len = codec.ReadInt();
                batch.Data = buf.GetSlice(len);
            }

        }
        private void Encode(ProducerMessage message, IoBuffer buf, byte[] body, string codecType)
        {
            var codec = new HermesPrimitiveCodec(buf);
            var indexBeginning = buf.Position;
            codec.WriteInt(-1); // placeholder for whole length
            var indexAfterWholeLen = buf.Position;
            codec.WriteInt(-1); // placeholder for header length
            codec.WriteInt(-1); // placeholder for body length
            var indexBeforeHeader = buf.Position;

            // header begin
            codec.WriteString(message.Key);
            codec.WriteLong(message.BornTime);
            codec.WriteInt(0); //remaining retries
            codec.WriteString(codecType);

            var propertiesHolder = message.PropertiesHolder;
            WriteProperties(propertiesHolder.DurableProperties, buf, codec);
            WriteProperties(propertiesHolder.VolatileProperties, buf, codec);
            // header end

            var headerLen = buf.Position - indexBeforeHeader;

            //body begin
            var indexBeforeBody = buf.Position;
            buf.Put(body);
            var bodyLen = buf.Position - indexBeforeBody;
            //body end

            //crc
            codec.WriteLong(ChecksumUtil.Crc32(buf.GetSlice(indexBeforeHeader, headerLen + bodyLen)));
            var indexEnd = buf.Position;

            var wholeLen = indexEnd - indexAfterWholeLen;

            // refill whole length
            buf.Position = indexBeginning;
            codec.WriteInt(wholeLen);

            // refill header length
            codec.WriteInt(headerLen);

            // refill body length
            codec.WriteInt(bodyLen);

            buf.Position = indexEnd;
        }