1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty.handler.ssl;
17
18 import io.netty.buffer.ByteBuf;
19 import io.netty.buffer.ByteBufAllocator;
20 import io.netty.buffer.CompositeByteBuf;
21 import io.netty.channel.AbstractCoalescingBufferQueue;
22 import io.netty.channel.Channel;
23 import io.netty.util.internal.PlatformDependent;
24
25 import static io.netty.buffer.ByteBufUtil.ensureWritableSuccess;
26
27
28
29
30
31
32 abstract class SslHandlerCoalescingBufferQueue extends AbstractCoalescingBufferQueue {
33
34 private final boolean wantsDirectBuffer;
35
36 SslHandlerCoalescingBufferQueue(Channel channel, int initSize, boolean wantsDirectBuffer) {
37 super(channel, initSize);
38 this.wantsDirectBuffer = wantsDirectBuffer;
39 }
40
41 protected abstract int wrapDataSize();
42
43 @Override
44 protected ByteBuf compose(ByteBufAllocator alloc, ByteBuf cumulation, ByteBuf next) {
45 return attemptCopyToCumulation(cumulation, next, wrapDataSize()) ? cumulation :
46 copyAndCompose(alloc, cumulation, next);
47 }
48
49 @Override
50 protected ByteBuf composeFirst(ByteBufAllocator allocator, ByteBuf first, int bufferSize) {
51 final ByteBuf newFirst;
52 if (wantsDirectBuffer) {
53 newFirst = allocator.directBuffer(bufferSize);
54 } else {
55 newFirst = allocator.heapBuffer(bufferSize);
56 }
57 try {
58 newFirst.writeBytes(first);
59 } catch (Throwable cause) {
60 newFirst.release();
61 PlatformDependent.throwException(cause);
62 }
63 assert !first.isReadable();
64 first.release();
65 return newFirst;
66 }
67
68 @Override
69 protected ByteBuf removeEmptyValue() {
70 return null;
71 }
72
73 private static boolean attemptCopyToCumulation(ByteBuf cumulation, ByteBuf next, int wrapDataSize) {
74 final int inReadableBytes = next.readableBytes();
75
76 if (inReadableBytes == 0) {
77 next.release();
78 return true;
79 }
80 final int cumulationCapacity = cumulation.capacity();
81 if (wrapDataSize - cumulation.readableBytes() >= inReadableBytes &&
82
83
84
85 (cumulation.isWritable(inReadableBytes) && cumulationCapacity >= wrapDataSize ||
86 cumulationCapacity < wrapDataSize &&
87 ensureWritableSuccess(cumulation.ensureWritable(inReadableBytes, false)))) {
88 cumulation.writeBytes(next);
89 next.release();
90 return true;
91 }
92 return false;
93 }
94 }