1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty.handler.codec.protobuf;
17
18 import com.google.protobuf.CodedOutputStream;
19 import com.google.protobuf.nano.CodedOutputByteBufferNano;
20 import io.netty.buffer.ByteBuf;
21 import io.netty.channel.ChannelHandler.Sharable;
22 import io.netty.channel.ChannelHandlerContext;
23 import io.netty.handler.codec.MessageToByteEncoder;
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 @Sharable
41 public class ProtobufVarint32LengthFieldPrepender extends MessageToByteEncoder<ByteBuf> {
42
43 public ProtobufVarint32LengthFieldPrepender() {
44 super(ByteBuf.class);
45 }
46
47 @Override
48 protected void encode(
49 ChannelHandlerContext ctx, ByteBuf msg, ByteBuf out) throws Exception {
50 int bodyLen = msg.readableBytes();
51 int headerLen = computeRawVarint32Size(bodyLen);
52 out.ensureWritable(headerLen + bodyLen);
53 writeRawVarint32(out, bodyLen);
54 out.writeBytes(msg, msg.readerIndex(), bodyLen);
55 }
56
57
58
59
60
61
62 static void writeRawVarint32(ByteBuf out, int value) {
63 while (true) {
64 if ((value & ~0x7F) == 0) {
65 out.writeByte(value);
66 return;
67 } else {
68 out.writeByte((value & 0x7F) | 0x80);
69 value >>>= 7;
70 }
71 }
72 }
73
74
75
76
77
78
79 static int computeRawVarint32Size(final int value) {
80 if ((value & (0xffffffff << 7)) == 0) {
81 return 1;
82 }
83 if ((value & (0xffffffff << 14)) == 0) {
84 return 2;
85 }
86 if ((value & (0xffffffff << 21)) == 0) {
87 return 3;
88 }
89 if ((value & (0xffffffff << 28)) == 0) {
90 return 4;
91 }
92 return 5;
93 }
94 }