1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty5.handler.codec;
17
18 import io.netty5.buffer.api.Buffer;
19 import io.netty5.channel.ChannelHandler;
20 import io.netty5.channel.ChannelHandlerAdapter;
21 import io.netty5.channel.ChannelHandlerContext;
22 import io.netty5.channel.ChannelPipeline;
23 import io.netty5.util.concurrent.Future;
24 import io.netty5.util.internal.TypeParameterMatcher;
25
26 import static io.netty5.util.internal.SilentDispose.autoClosing;
27 import static java.util.Objects.requireNonNull;
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44 public abstract class MessageToByteEncoder<I> extends ChannelHandlerAdapter {
45
46 private final TypeParameterMatcher matcher;
47
48
49
50
51 protected MessageToByteEncoder() {
52 matcher = TypeParameterMatcher.find(this, MessageToByteEncoder.class, "I");
53 }
54
55
56
57
58
59
60 protected MessageToByteEncoder(Class<? extends I> outboundMessageType) {
61 matcher = TypeParameterMatcher.get(requireNonNull(outboundMessageType, "outboundMessageType"));
62 }
63
64
65
66
67
68 public boolean acceptOutboundMessage(Object msg) throws Exception {
69 return matcher.match(msg);
70 }
71
72 @Override
73 public Future<Void> write(ChannelHandlerContext ctx, Object msg) {
74 Buffer buf = null;
75 try {
76 if (acceptOutboundMessage(msg)) {
77 @SuppressWarnings("unchecked")
78 I cast = (I) msg;
79 buf = allocateBuffer(ctx, cast);
80 try (AutoCloseable ignore = autoClosing(cast)) {
81 encode(ctx, cast, buf);
82 }
83
84 if (buf.readableBytes() > 0) {
85 Future<Void> f = ctx.write(buf);
86 buf = null;
87 return f;
88 }
89 return ctx.write(ctx.bufferAllocator().allocate(0));
90 }
91 return ctx.write(msg);
92 } catch (EncoderException e) {
93 return ctx.newFailedFuture(e);
94 } catch (Throwable e) {
95 return ctx.newFailedFuture(new EncoderException(e));
96 } finally {
97 if (buf != null) {
98 buf.close();
99 }
100 }
101 }
102
103
104
105
106
107
108
109 protected abstract Buffer allocateBuffer(ChannelHandlerContext ctx, I msg) throws Exception;
110
111
112
113
114
115
116
117
118
119
120 protected abstract void encode(ChannelHandlerContext ctx, I msg, Buffer out) throws Exception;
121 }