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.GatheringByteChannel;
26  import java.nio.channels.ScatteringByteChannel;
27  
28  class PooledHeapByteBuf extends PooledByteBuf<byte[]> {
29  
30      private static final Recycler<PooledHeapByteBuf> RECYCLER = new Recycler<PooledHeapByteBuf>() {
31          @Override
32          protected PooledHeapByteBuf newObject(Handle 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(Recycler.Handle 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 int _getUnsignedMedium(int index) {
64          return HeapByteBufUtil.getUnsignedMedium(memory, idx(index));
65      }
66  
67      @Override
68      protected int _getInt(int index) {
69          return HeapByteBufUtil.getInt(memory, idx(index));
70      }
71  
72      @Override
73      protected long _getLong(int index) {
74          return HeapByteBufUtil.getLong(memory, idx(index));
75      }
76  
77      @Override
78      public final ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) {
79          checkDstIndex(index, length, dstIndex, dst.capacity());
80          if (dst.hasMemoryAddress()) {
81              PlatformDependent.copyMemory(memory, idx(index), dst.memoryAddress() + dstIndex, length);
82          } else if (dst.hasArray()) {
83              getBytes(index, dst.array(), dst.arrayOffset() + dstIndex, length);
84          } else {
85              dst.setBytes(dstIndex, memory, idx(index), length);
86          }
87          return this;
88      }
89  
90      @Override
91      public final ByteBuf getBytes(int index, byte[] dst, int dstIndex, int length) {
92          checkDstIndex(index, length, dstIndex, dst.length);
93          System.arraycopy(memory, idx(index), dst, dstIndex, length);
94          return this;
95      }
96  
97      @Override
98      public final ByteBuf getBytes(int index, ByteBuffer dst) {
99          checkIndex(index, dst.remaining());
100         dst.put(memory, idx(index), dst.remaining());
101         return this;
102     }
103 
104     @Override
105     public final ByteBuf getBytes(int index, OutputStream out, int length) throws IOException {
106         checkIndex(index, length);
107         out.write(memory, idx(index), length);
108         return this;
109     }
110 
111     @Override
112     public final int getBytes(int index, GatheringByteChannel out, int length) throws IOException {
113         return getBytes(index, out, length, false);
114     }
115 
116     private int getBytes(int index, GatheringByteChannel out, int length, boolean internal) throws IOException {
117         checkIndex(index, length);
118         index = idx(index);
119         ByteBuffer tmpBuf;
120         if (internal) {
121             tmpBuf = internalNioBuffer();
122         } else {
123             tmpBuf = ByteBuffer.wrap(memory);
124         }
125         return out.write((ByteBuffer) tmpBuf.clear().position(index).limit(index + length));
126     }
127 
128     @Override
129     public final int readBytes(GatheringByteChannel out, int length) throws IOException {
130         checkReadableBytes(length);
131         int readBytes = getBytes(readerIndex, out, length, true);
132         readerIndex += readBytes;
133         return readBytes;
134     }
135 
136     @Override
137     protected void _setByte(int index, int value) {
138         HeapByteBufUtil.setByte(memory, idx(index), value);
139     }
140 
141     @Override
142     protected void _setShort(int index, int value) {
143         HeapByteBufUtil.setShort(memory, idx(index), value);
144     }
145 
146     @Override
147     protected void _setMedium(int index, int   value) {
148         HeapByteBufUtil.setMedium(memory, idx(index), value);
149     }
150 
151     @Override
152     protected void _setInt(int index, int   value) {
153         HeapByteBufUtil.setInt(memory, idx(index), value);
154     }
155 
156     @Override
157     protected void _setLong(int index, long  value) {
158         HeapByteBufUtil.setLong(memory, idx(index), value);
159     }
160 
161     @Override
162     public final ByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length) {
163         checkSrcIndex(index, length, srcIndex, src.capacity());
164         if (src.hasMemoryAddress()) {
165             PlatformDependent.copyMemory(src.memoryAddress() + srcIndex, memory, idx(index), length);
166         } else if (src.hasArray()) {
167             setBytes(index, src.array(), src.arrayOffset() + srcIndex, length);
168         } else {
169             src.getBytes(srcIndex, memory, idx(index), length);
170         }
171         return this;
172     }
173 
174     @Override
175     public final ByteBuf setBytes(int index, byte[] src, int srcIndex, int length) {
176         checkSrcIndex(index, length, srcIndex, src.length);
177         System.arraycopy(src, srcIndex, memory, idx(index), length);
178         return this;
179     }
180 
181     @Override
182     public final ByteBuf setBytes(int index, ByteBuffer src) {
183         int length = src.remaining();
184         checkIndex(index, length);
185         src.get(memory, idx(index), length);
186         return this;
187     }
188 
189     @Override
190     public final int setBytes(int index, InputStream in, int length) throws IOException {
191         checkIndex(index, length);
192         return in.read(memory, idx(index), length);
193     }
194 
195     @Override
196     public final int setBytes(int index, ScatteringByteChannel in, int length) throws IOException {
197         checkIndex(index, length);
198         index = idx(index);
199         try {
200             return in.read((ByteBuffer) internalNioBuffer().clear().position(index).limit(index + length));
201         } catch (ClosedChannelException ignored) {
202             return -1;
203         }
204     }
205 
206     @Override
207     public final ByteBuf copy(int index, int length) {
208         checkIndex(index, length);
209         ByteBuf copy = alloc().heapBuffer(length, maxCapacity());
210         copy.writeBytes(memory, idx(index), length);
211         return copy;
212     }
213 
214     @Override
215     public final int nioBufferCount() {
216         return 1;
217     }
218 
219     @Override
220     public final ByteBuffer[] nioBuffers(int index, int length) {
221         return new ByteBuffer[] { nioBuffer(index, length) };
222     }
223 
224     @Override
225     public final ByteBuffer nioBuffer(int index, int length) {
226         checkIndex(index, length);
227         index = idx(index);
228         ByteBuffer buf =  ByteBuffer.wrap(memory, index, length);
229         return buf.slice();
230     }
231 
232     @Override
233     public final ByteBuffer internalNioBuffer(int index, int length) {
234         checkIndex(index, length);
235         index = idx(index);
236         return (ByteBuffer) internalNioBuffer().clear().position(index).limit(index + length);
237     }
238 
239     @Override
240     public final boolean hasArray() {
241         return true;
242     }
243 
244     @Override
245     public final byte[] array() {
246         ensureAccessible();
247         return memory;
248     }
249 
250     @Override
251     public final int arrayOffset() {
252         return offset;
253     }
254 
255     @Override
256     public final boolean hasMemoryAddress() {
257         return false;
258     }
259 
260     @Override
261     public final long memoryAddress() {
262         throw new UnsupportedOperationException();
263     }
264 
265     @Override
266     protected final ByteBuffer newInternalNioBuffer(byte[] memory) {
267         return ByteBuffer.wrap(memory);
268     }
269 
270     @Override
271     protected Recycler<?> recycler() {
272         return RECYCLER;
273     }
274 }