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  *   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.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 }
134