1 /*
2 * Copyright 2013 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 * https://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.buffer;
17
18 import io.netty.util.internal.ObjectUtil;
19
20 import java.nio.ByteOrder;
21
22 /**
23 * A {@link ByteBuf} implementation that wraps another buffer to prevent a user from increasing or decreasing the
24 * wrapped buffer's reference count.
25 */
26 final class UnreleasableByteBuf extends WrappedByteBuf {
27
28 private SwappedByteBuf swappedBuf;
29
30 UnreleasableByteBuf(ByteBuf buf) {
31 super(buf instanceof UnreleasableByteBuf ? buf.unwrap() : buf);
32 }
33
34 @Override
35 public ByteBuf order(ByteOrder endianness) {
36 if (ObjectUtil.checkNotNull(endianness, "endianness") == order()) {
37 return this;
38 }
39
40 SwappedByteBuf swappedBuf = this.swappedBuf;
41 if (swappedBuf == null) {
42 this.swappedBuf = swappedBuf = new SwappedByteBuf(this);
43 }
44 return swappedBuf;
45 }
46
47 @Override
48 public ByteBuf asReadOnly() {
49 return buf.isReadOnly() ? this : new UnreleasableByteBuf(buf.asReadOnly());
50 }
51
52 @Override
53 public ByteBuf readSlice(int length) {
54 return new UnreleasableByteBuf(buf.readSlice(length));
55 }
56
57 @Override
58 public ByteBuf readRetainedSlice(int length) {
59 // We could call buf.readSlice(..), and then call buf.release(). However this creates a leak in unit tests
60 // because the release method on UnreleasableByteBuf will never allow the leak record to be cleaned up.
61 // So we just use readSlice(..) because the end result should be logically equivalent.
62 return readSlice(length);
63 }
64
65 @Override
66 public ByteBuf slice() {
67 return new UnreleasableByteBuf(buf.slice());
68 }
69
70 @Override
71 public ByteBuf retainedSlice() {
72 // We could call buf.retainedSlice(), and then call buf.release(). However this creates a leak in unit tests
73 // because the release method on UnreleasableByteBuf will never allow the leak record to be cleaned up.
74 // So we just use slice() because the end result should be logically equivalent.
75 return slice();
76 }
77
78 @Override
79 public ByteBuf slice(int index, int length) {
80 return new UnreleasableByteBuf(buf.slice(index, length));
81 }
82
83 @Override
84 public ByteBuf retainedSlice(int index, int length) {
85 // We could call buf.retainedSlice(..), and then call buf.release(). However this creates a leak in unit tests
86 // because the release method on UnreleasableByteBuf will never allow the leak record to be cleaned up.
87 // So we just use slice(..) because the end result should be logically equivalent.
88 return slice(index, length);
89 }
90
91 @Override
92 public ByteBuf duplicate() {
93 return new UnreleasableByteBuf(buf.duplicate());
94 }
95
96 @Override
97 public ByteBuf retainedDuplicate() {
98 // We could call buf.retainedDuplicate(), and then call buf.release(). However this creates a leak in unit tests
99 // because the release method on UnreleasableByteBuf will never allow the leak record to be cleaned up.
100 // So we just use duplicate() because the end result should be logically equivalent.
101 return duplicate();
102 }
103
104 @Override
105 public ByteBuf retain(int increment) {
106 return this;
107 }
108
109 @Override
110 public ByteBuf retain() {
111 return this;
112 }
113
114 @Override
115 public ByteBuf touch() {
116 return this;
117 }
118
119 @Override
120 public ByteBuf touch(Object hint) {
121 return this;
122 }
123
124 @Override
125 public boolean release() {
126 return false;
127 }
128
129 @Override
130 public boolean release(int decrement) {
131 return false;
132 }
133 }