1 /* 2 * Copyright 2012 The Netty Project 3 * 4 * The Netty Project licenses this file to you under the Apache License, 5 * version 2.0 (the "License"); you may not use this file except in compliance 6 * with the License. You may obtain a copy of the License at: 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 * License for the specific language governing permissions and limitations 14 * under the License. 15 */ 16 package io.netty.handler.codec.protobuf; 17 18 import com.google.protobuf.CodedOutputStream; 19 import io.netty.buffer.ByteBuf; 20 import io.netty.buffer.ByteBufOutputStream; 21 import io.netty.channel.ChannelHandler.Sharable; 22 import io.netty.channel.ChannelHandlerContext; 23 import io.netty.handler.codec.MessageToByteEncoder; 24 25 /** 26 * An encoder that prepends the the Google Protocol Buffers 27 * <a href="https://developers.google.com/protocol-buffers/docs/encoding?csw=1#varints">Base 28 * 128 Varints</a> integer length field. For example: 29 * <pre> 30 * BEFORE DECODE (300 bytes) AFTER DECODE (302 bytes) 31 * +---------------+ +--------+---------------+ 32 * | Protobuf Data |-------------->| Length | Protobuf Data | 33 * | (300 bytes) | | 0xAC02 | (300 bytes) | 34 * +---------------+ +--------+---------------+ 35 * </pre> * 36 * 37 * @see CodedOutputStream 38 */ 39 @Sharable 40 public class ProtobufVarint32LengthFieldPrepender extends MessageToByteEncoder<ByteBuf> { 41 42 @Override 43 protected void encode( 44 ChannelHandlerContext ctx, ByteBuf msg, ByteBuf out) throws Exception { 45 int bodyLen = msg.readableBytes(); 46 int headerLen = CodedOutputStream.computeRawVarint32Size(bodyLen); 47 out.ensureWritable(headerLen + bodyLen); 48 49 CodedOutputStream headerOut = 50 CodedOutputStream.newInstance(new ByteBufOutputStream(out), headerLen); 51 headerOut.writeRawVarint32(bodyLen); 52 headerOut.flush(); 53 54 out.writeBytes(msg, msg.readerIndex(), bodyLen); 55 } 56 }