1 /*
2  * Copyright 2012 The Netty Project
3  *
4  * The Netty Project licenses this file to the License at:
5  *
6  *   http://www.apache.org/licenses/LICENSE-2.0
7  *
8  * Unless required by applicable law or agreed to in writing, software
9  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11  * License for the specific language governing permissions and limitations
12  * under the License.
13  */

14
15 package io.netty.buffer;
16
17 import io.netty.util.internal.ObjectPool;
18 import io.netty.util.internal.ObjectPool.Handle;
19 import io.netty.util.internal.ObjectPool.ObjectCreator;
20 import io.netty.util.internal.PlatformDependent;
21
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.io.OutputStream;
25 import java.nio.ByteBuffer;
26
27 class PooledHeapByteBuf extends PooledByteBuf<byte[]> {
28
29     private static final ObjectPool<PooledHeapByteBuf> RECYCLER = ObjectPool.newPool(
30             new ObjectCreator<PooledHeapByteBuf>() {
31         @Override
32         public PooledHeapByteBuf newObject(Handle<PooledHeapByteBuf> handle) {
33             return new PooledHeapByteBuf(handle, 0);
34         }
35     });
36
37     static PooledHeapByteBuf newInstance(int maxCapacity) {
38         PooledHeapByteBuf buf = RECYCLER.get();
39         buf.reuse(maxCapacity);
40         return buf;
41     }
42
43     PooledHeapByteBuf(Handle<? extends PooledHeapByteBuf> recyclerHandle, int maxCapacity) {
44         super(recyclerHandle, maxCapacity);
45     }
46
47     @Override
48     public final boolean isDirect() {
49         return false;
50     }
51
52     @Override
53     protected byte _getByte(int index) {
54         return HeapByteBufUtil.getByte(memory, idx(index));
55     }
56
57     @Override
58     protected short _getShort(int index) {
59         return HeapByteBufUtil.getShort(memory, idx(index));
60     }
61
62     @Override
63     protected short _getShortLE(int index) {
64         return HeapByteBufUtil.getShortLE(memory, idx(index));
65     }
66
67     @Override
68     protected int _getUnsignedMedium(int index) {
69         return HeapByteBufUtil.getUnsignedMedium(memory, idx(index));
70     }
71
72     @Override
73     protected int _getUnsignedMediumLE(int index) {
74         return HeapByteBufUtil.getUnsignedMediumLE(memory, idx(index));
75     }
76
77     @Override
78     protected int _getInt(int index) {
79         return HeapByteBufUtil.getInt(memory, idx(index));
80     }
81
82     @Override
83     protected int _getIntLE(int index) {
84         return HeapByteBufUtil.getIntLE(memory, idx(index));
85     }
86
87     @Override
88     protected long _getLong(int index) {
89         return HeapByteBufUtil.getLong(memory, idx(index));
90     }
91
92     @Override
93     protected long _getLongLE(int index) {
94         return HeapByteBufUtil.getLongLE(memory, idx(index));
95     }
96
97     @Override
98     public final ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) {
99         checkDstIndex(index, length, dstIndex, dst.capacity());
100         if (dst.hasMemoryAddress()) {
101             PlatformDependent.copyMemory(memory, idx(index), dst.memoryAddress() + dstIndex, length);
102         } else if (dst.hasArray()) {
103             getBytes(index, dst.array(), dst.arrayOffset() + dstIndex, length);
104         } else {
105             dst.setBytes(dstIndex, memory, idx(index), length);
106         }
107         return this;
108     }
109
110     @Override
111     public final ByteBuf getBytes(int index, byte[] dst, int dstIndex, int length) {
112         checkDstIndex(index, length, dstIndex, dst.length);
113         System.arraycopy(memory, idx(index), dst, dstIndex, length);
114         return this;
115     }
116
117     @Override
118     public final ByteBuf getBytes(int index, ByteBuffer dst) {
119         int length = dst.remaining();
120         checkIndex(index, length);
121         dst.put(memory, idx(index), length);
122         return this;
123     }
124
125     @Override
126     public final ByteBuf getBytes(int index, OutputStream out, int length) throws IOException {
127         checkIndex(index, length);
128         out.write(memory, idx(index), length);
129         return this;
130     }
131
132     @Override
133     protected void _setByte(int index, int value) {
134         HeapByteBufUtil.setByte(memory, idx(index), value);
135     }
136
137     @Override
138     protected void _setShort(int index, int value) {
139         HeapByteBufUtil.setShort(memory, idx(index), value);
140     }
141
142     @Override
143     protected void _setShortLE(int index, int value) {
144         HeapByteBufUtil.setShortLE(memory, idx(index), value);
145     }
146
147     @Override
148     protected void _setMedium(int index, int   value) {
149         HeapByteBufUtil.setMedium(memory, idx(index), value);
150     }
151
152     @Override
153     protected void _setMediumLE(int index, int value) {
154         HeapByteBufUtil.setMediumLE(memory, idx(index), value);
155     }
156
157     @Override
158     protected void _setInt(int index, int   value) {
159         HeapByteBufUtil.setInt(memory, idx(index), value);
160     }
161
162     @Override
163     protected void _setIntLE(int index, int value) {
164         HeapByteBufUtil.setIntLE(memory, idx(index), value);
165     }
166
167     @Override
168     protected void _setLong(int index, long  value) {
169         HeapByteBufUtil.setLong(memory, idx(index), value);
170     }
171
172     @Override
173     protected void _setLongLE(int index, long value) {
174         HeapByteBufUtil.setLongLE(memory, idx(index), value);
175     }
176
177     @Override
178     public final ByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length) {
179         checkSrcIndex(index, length, srcIndex, src.capacity());
180         if (src.hasMemoryAddress()) {
181             PlatformDependent.copyMemory(src.memoryAddress() + srcIndex, memory, idx(index), length);
182         } else if (src.hasArray()) {
183             setBytes(index, src.array(), src.arrayOffset() + srcIndex, length);
184         } else {
185             src.getBytes(srcIndex, memory, idx(index), length);
186         }
187         return this;
188     }
189
190     @Override
191     public final ByteBuf setBytes(int index, byte[] src, int srcIndex, int length) {
192         checkSrcIndex(index, length, srcIndex, src.length);
193         System.arraycopy(src, srcIndex, memory, idx(index), length);
194         return this;
195     }
196
197     @Override
198     public final ByteBuf setBytes(int index, ByteBuffer src) {
199         int length = src.remaining();
200         checkIndex(index, length);
201         src.get(memory, idx(index), length);
202         return this;
203     }
204
205     @Override
206     public final int setBytes(int index, InputStream in, int length) throws IOException {
207         checkIndex(index, length);
208         return in.read(memory, idx(index), length);
209     }
210
211     @Override
212     public final ByteBuf copy(int index, int length) {
213         checkIndex(index, length);
214         ByteBuf copy = alloc().heapBuffer(length, maxCapacity());
215         return copy.writeBytes(memory, idx(index), length);
216     }
217
218     @Override
219     final ByteBuffer duplicateInternalNioBuffer(int index, int length) {
220         checkIndex(index, length);
221         return ByteBuffer.wrap(memory, idx(index), length).slice();
222     }
223
224     @Override
225     public final boolean hasArray() {
226         return true;
227     }
228
229     @Override
230     public final byte[] array() {
231         ensureAccessible();
232         return memory;
233     }
234
235     @Override
236     public final int arrayOffset() {
237         return offset;
238     }
239
240     @Override
241     public final boolean hasMemoryAddress() {
242         return false;
243     }
244
245     @Override
246     public final long memoryAddress() {
247         throw new UnsupportedOperationException();
248     }
249
250     @Override
251     protected final ByteBuffer newInternalNioBuffer(byte[] memory) {
252         return ByteBuffer.wrap(memory);
253     }
254 }
255