View Javadoc
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.Recycler;
18  import io.netty.util.internal.PlatformDependent;
19  
20  import java.io.IOException;
21  import java.io.InputStream;
22  import java.io.OutputStream;
23  import java.nio.ByteBuffer;
24  import java.nio.channels.ClosedChannelException;
25  import java.nio.channels.FileChannel;
26  import java.nio.channels.GatheringByteChannel;
27  import java.nio.channels.ScatteringByteChannel;
28  
29  class PooledHeapByteBuf extends PooledByteBuf<byte[]> {
30  
31      private static final Recycler<PooledHeapByteBuf> RECYCLER = new Recycler<PooledHeapByteBuf>() {
32          @Override
33          protected PooledHeapByteBuf newObject(Handle<PooledHeapByteBuf> handle) {
34              return new PooledHeapByteBuf(handle, 0);
35          }
36      };
37  
38      static PooledHeapByteBuf newInstance(int maxCapacity) {
39          PooledHeapByteBuf buf = RECYCLER.get();
40          buf.reuse(maxCapacity);
41          return buf;
42      }
43  
44      PooledHeapByteBuf(Recycler.Handle<? extends PooledHeapByteBuf> recyclerHandle, int maxCapacity) {
45          super(recyclerHandle, maxCapacity);
46      }
47  
48      @Override
49      public final boolean isDirect() {
50          return false;
51      }
52  
53      @Override
54      protected byte _getByte(int index) {
55          return HeapByteBufUtil.getByte(memory, idx(index));
56      }
57  
58      @Override
59      protected short _getShort(int index) {
60          return HeapByteBufUtil.getShort(memory, idx(index));
61      }
62  
63      @Override
64      protected short _getShortLE(int index) {
65          return HeapByteBufUtil.getShortLE(memory, idx(index));
66      }
67  
68      @Override
69      protected int _getUnsignedMedium(int index) {
70          return HeapByteBufUtil.getUnsignedMedium(memory, idx(index));
71      }
72  
73      @Override
74      protected int _getUnsignedMediumLE(int index) {
75          return HeapByteBufUtil.getUnsignedMediumLE(memory, idx(index));
76      }
77  
78      @Override
79      protected int _getInt(int index) {
80          return HeapByteBufUtil.getInt(memory, idx(index));
81      }
82  
83      @Override
84      protected int _getIntLE(int index) {
85          return HeapByteBufUtil.getIntLE(memory, idx(index));
86      }
87  
88      @Override
89      protected long _getLong(int index) {
90          return HeapByteBufUtil.getLong(memory, idx(index));
91      }
92  
93      @Override
94      protected long _getLongLE(int index) {
95          return HeapByteBufUtil.getLongLE(memory, idx(index));
96      }
97  
98      @Override
99      public final ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) {
100         checkDstIndex(index, length, dstIndex, dst.capacity());
101         if (dst.hasMemoryAddress()) {
102             PlatformDependent.copyMemory(memory, idx(index), dst.memoryAddress() + dstIndex, length);
103         } else if (dst.hasArray()) {
104             getBytes(index, dst.array(), dst.arrayOffset() + dstIndex, length);
105         } else {
106             dst.setBytes(dstIndex, memory, idx(index), length);
107         }
108         return this;
109     }
110 
111     @Override
112     public final ByteBuf getBytes(int index, byte[] dst, int dstIndex, int length) {
113         checkDstIndex(index, length, dstIndex, dst.length);
114         System.arraycopy(memory, idx(index), dst, dstIndex, length);
115         return this;
116     }
117 
118     @Override
119     public final ByteBuf getBytes(int index, ByteBuffer dst) {
120         checkIndex(index, dst.remaining());
121         dst.put(memory, idx(index), dst.remaining());
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     public final int getBytes(int index, GatheringByteChannel out, int length) throws IOException {
134         return getBytes(index, out, length, false);
135     }
136 
137     private int getBytes(int index, GatheringByteChannel out, int length, boolean internal) throws IOException {
138         checkIndex(index, length);
139         index = idx(index);
140         ByteBuffer tmpBuf;
141         if (internal) {
142             tmpBuf = internalNioBuffer();
143         } else {
144             tmpBuf = ByteBuffer.wrap(memory);
145         }
146         return out.write((ByteBuffer) tmpBuf.clear().position(index).limit(index + length));
147     }
148 
149     @Override
150     public final int getBytes(int index, FileChannel out, long position, int length) throws IOException {
151         return getBytes(index, out, position, length, false);
152     }
153 
154     private int getBytes(int index, FileChannel out, long position, int length, boolean internal) throws IOException {
155         checkIndex(index, length);
156         index = idx(index);
157         ByteBuffer tmpBuf = internal ? internalNioBuffer() : ByteBuffer.wrap(memory);
158         return out.write((ByteBuffer) tmpBuf.clear().position(index).limit(index + length), position);
159     }
160 
161     @Override
162     public final int readBytes(GatheringByteChannel out, int length) throws IOException {
163         checkReadableBytes(length);
164         int readBytes = getBytes(readerIndex, out, length, true);
165         readerIndex += readBytes;
166         return readBytes;
167     }
168 
169     @Override
170     public final int readBytes(FileChannel out, long position, int length) throws IOException {
171         checkReadableBytes(length);
172         int readBytes = getBytes(readerIndex, out, position, length, true);
173         readerIndex += readBytes;
174         return readBytes;
175     }
176 
177     @Override
178     protected void _setByte(int index, int value) {
179         HeapByteBufUtil.setByte(memory, idx(index), value);
180     }
181 
182     @Override
183     protected void _setShort(int index, int value) {
184         HeapByteBufUtil.setShort(memory, idx(index), value);
185     }
186 
187     @Override
188     protected void _setShortLE(int index, int value) {
189         HeapByteBufUtil.setShortLE(memory, idx(index), value);
190     }
191 
192     @Override
193     protected void _setMedium(int index, int   value) {
194         HeapByteBufUtil.setMedium(memory, idx(index), value);
195     }
196 
197     @Override
198     protected void _setMediumLE(int index, int value) {
199         HeapByteBufUtil.setMediumLE(memory, idx(index), value);
200     }
201 
202     @Override
203     protected void _setInt(int index, int   value) {
204         HeapByteBufUtil.setInt(memory, idx(index), value);
205     }
206 
207     @Override
208     protected void _setIntLE(int index, int value) {
209         HeapByteBufUtil.setIntLE(memory, idx(index), value);
210     }
211 
212     @Override
213     protected void _setLong(int index, long  value) {
214         HeapByteBufUtil.setLong(memory, idx(index), value);
215     }
216 
217     @Override
218     protected void _setLongLE(int index, long value) {
219         HeapByteBufUtil.setLongLE(memory, idx(index), value);
220     }
221 
222     @Override
223     public final ByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length) {
224         checkSrcIndex(index, length, srcIndex, src.capacity());
225         if (src.hasMemoryAddress()) {
226             PlatformDependent.copyMemory(src.memoryAddress() + srcIndex, memory, idx(index), length);
227         } else if (src.hasArray()) {
228             setBytes(index, src.array(), src.arrayOffset() + srcIndex, length);
229         } else {
230             src.getBytes(srcIndex, memory, idx(index), length);
231         }
232         return this;
233     }
234 
235     @Override
236     public final ByteBuf setBytes(int index, byte[] src, int srcIndex, int length) {
237         checkSrcIndex(index, length, srcIndex, src.length);
238         System.arraycopy(src, srcIndex, memory, idx(index), length);
239         return this;
240     }
241 
242     @Override
243     public final ByteBuf setBytes(int index, ByteBuffer src) {
244         int length = src.remaining();
245         checkIndex(index, length);
246         src.get(memory, idx(index), length);
247         return this;
248     }
249 
250     @Override
251     public final int setBytes(int index, InputStream in, int length) throws IOException {
252         checkIndex(index, length);
253         return in.read(memory, idx(index), length);
254     }
255 
256     @Override
257     public final int setBytes(int index, ScatteringByteChannel in, int length) throws IOException {
258         checkIndex(index, length);
259         index = idx(index);
260         try {
261             return in.read((ByteBuffer) internalNioBuffer().clear().position(index).limit(index + length));
262         } catch (ClosedChannelException ignored) {
263             return -1;
264         }
265     }
266 
267     @Override
268     public final int setBytes(int index, FileChannel in, long position, int length) throws IOException {
269         checkIndex(index, length);
270         index = idx(index);
271         try {
272             return in.read((ByteBuffer) internalNioBuffer().clear().position(index).limit(index + length), position);
273         } catch (ClosedChannelException ignored) {
274             return -1;
275         }
276     }
277 
278     @Override
279     public final ByteBuf copy(int index, int length) {
280         checkIndex(index, length);
281         ByteBuf copy = alloc().heapBuffer(length, maxCapacity());
282         copy.writeBytes(memory, idx(index), length);
283         return copy;
284     }
285 
286     @Override
287     public final int nioBufferCount() {
288         return 1;
289     }
290 
291     @Override
292     public final ByteBuffer[] nioBuffers(int index, int length) {
293         return new ByteBuffer[] { nioBuffer(index, length) };
294     }
295 
296     @Override
297     public final ByteBuffer nioBuffer(int index, int length) {
298         checkIndex(index, length);
299         index = idx(index);
300         ByteBuffer buf =  ByteBuffer.wrap(memory, index, length);
301         return buf.slice();
302     }
303 
304     @Override
305     public final ByteBuffer internalNioBuffer(int index, int length) {
306         checkIndex(index, length);
307         index = idx(index);
308         return (ByteBuffer) internalNioBuffer().clear().position(index).limit(index + length);
309     }
310 
311     @Override
312     public final boolean hasArray() {
313         return true;
314     }
315 
316     @Override
317     public final byte[] array() {
318         ensureAccessible();
319         return memory;
320     }
321 
322     @Override
323     public final int arrayOffset() {
324         return offset;
325     }
326 
327     @Override
328     public final boolean hasMemoryAddress() {
329         return false;
330     }
331 
332     @Override
333     public final long memoryAddress() {
334         throw new UnsupportedOperationException();
335     }
336 
337     @Override
338     protected final ByteBuffer newInternalNioBuffer(byte[] memory) {
339         return ByteBuffer.wrap(memory);
340     }
341 }