View Javadoc
1   /*
2    * Copyright 2012 The Netty Project
3    *
4    * The Netty Project licenses this file tothe 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  final class PooledHeapByteBuf extends PooledByteBuf<byte[]> {
29  
30      private static final Recycler<PooledHeapByteBuf> RECYCLER = new Recycler<PooledHeapByteBuf>() {
31          @Override
32          protected 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.setRefCnt(1);
40          buf.maxCapacity(maxCapacity);
41          return buf;
42      }
43  
44      private PooledHeapByteBuf(Recycler.Handle<PooledHeapByteBuf> recyclerHandle, int maxCapacity) {
45          super(recyclerHandle, maxCapacity);
46      }
47  
48      @Override
49      public boolean isDirect() {
50          return false;
51      }
52  
53      @Override
54      protected byte _getByte(int index) {
55          return memory[idx(index)];
56      }
57  
58      @Override
59      protected short _getShort(int index) {
60          index = idx(index);
61          return (short) (memory[index] << 8 | memory[index + 1] & 0xFF);
62      }
63  
64      @Override
65      protected int _getUnsignedMedium(int index) {
66          index = idx(index);
67          return (memory[index]     & 0xff) << 16 |
68                 (memory[index + 1] & 0xff) <<  8 |
69                  memory[index + 2] & 0xff;
70      }
71  
72      @Override
73      protected int _getInt(int index) {
74          index = idx(index);
75          return (memory[index]     & 0xff) << 24 |
76                 (memory[index + 1] & 0xff) << 16 |
77                 (memory[index + 2] & 0xff) <<  8 |
78                  memory[index + 3] & 0xff;
79      }
80  
81      @Override
82      protected long _getLong(int index) {
83          index = idx(index);
84          return ((long) memory[index]     & 0xff) << 56 |
85                 ((long) memory[index + 1] & 0xff) << 48 |
86                 ((long) memory[index + 2] & 0xff) << 40 |
87                 ((long) memory[index + 3] & 0xff) << 32 |
88                 ((long) memory[index + 4] & 0xff) << 24 |
89                 ((long) memory[index + 5] & 0xff) << 16 |
90                 ((long) memory[index + 6] & 0xff) <<  8 |
91                  (long) memory[index + 7] & 0xff;
92      }
93  
94      @Override
95      public ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) {
96          checkDstIndex(index, length, dstIndex, dst.capacity());
97          if (dst.hasMemoryAddress()) {
98              PlatformDependent.copyMemory(memory, idx(index), dst.memoryAddress() + dstIndex, length);
99          } else if (dst.hasArray()) {
100             getBytes(index, dst.array(), dst.arrayOffset() + dstIndex, length);
101         } else {
102             dst.setBytes(dstIndex, memory, idx(index), length);
103         }
104         return this;
105     }
106 
107     @Override
108     public ByteBuf getBytes(int index, byte[] dst, int dstIndex, int length) {
109         checkDstIndex(index, length, dstIndex, dst.length);
110         System.arraycopy(memory, idx(index), dst, dstIndex, length);
111         return this;
112     }
113 
114     @Override
115     public ByteBuf getBytes(int index, ByteBuffer dst) {
116         checkIndex(index);
117         dst.put(memory, idx(index), Math.min(capacity() - index, dst.remaining()));
118         return this;
119     }
120 
121     @Override
122     public ByteBuf getBytes(int index, OutputStream out, int length) throws IOException {
123         checkIndex(index, length);
124         out.write(memory, idx(index), length);
125         return this;
126     }
127 
128     @Override
129     public int getBytes(int index, GatheringByteChannel out, int length) throws IOException {
130         return getBytes(index, out, length, false);
131     }
132 
133     private int getBytes(int index, GatheringByteChannel out, int length, boolean internal) throws IOException {
134         checkIndex(index, length);
135         index = idx(index);
136         ByteBuffer tmpBuf;
137         if (internal) {
138             tmpBuf = internalNioBuffer();
139         } else {
140             tmpBuf = ByteBuffer.wrap(memory);
141         }
142         return out.write((ByteBuffer) tmpBuf.clear().position(index).limit(index + length));
143     }
144 
145     @Override
146     public int readBytes(GatheringByteChannel out, int length) throws IOException {
147         checkReadableBytes(length);
148         int readBytes = getBytes(readerIndex, out, length, true);
149         readerIndex += readBytes;
150         return readBytes;
151     }
152 
153     @Override
154     protected void _setByte(int index, int value) {
155         memory[idx(index)] = (byte) value;
156     }
157 
158     @Override
159     protected void _setShort(int index, int value) {
160         index = idx(index);
161         memory[index]     = (byte) (value >>> 8);
162         memory[index + 1] = (byte) value;
163     }
164 
165     @Override
166     protected void _setMedium(int index, int   value) {
167         index = idx(index);
168         memory[index]     = (byte) (value >>> 16);
169         memory[index + 1] = (byte) (value >>> 8);
170         memory[index + 2] = (byte) value;
171     }
172 
173     @Override
174     protected void _setInt(int index, int   value) {
175         index = idx(index);
176         memory[index]     = (byte) (value >>> 24);
177         memory[index + 1] = (byte) (value >>> 16);
178         memory[index + 2] = (byte) (value >>> 8);
179         memory[index + 3] = (byte) value;
180     }
181 
182     @Override
183     protected void _setLong(int index, long  value) {
184         index = idx(index);
185         memory[index]     = (byte) (value >>> 56);
186         memory[index + 1] = (byte) (value >>> 48);
187         memory[index + 2] = (byte) (value >>> 40);
188         memory[index + 3] = (byte) (value >>> 32);
189         memory[index + 4] = (byte) (value >>> 24);
190         memory[index + 5] = (byte) (value >>> 16);
191         memory[index + 6] = (byte) (value >>> 8);
192         memory[index + 7] = (byte) value;
193     }
194 
195     @Override
196     public ByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length) {
197         checkSrcIndex(index, length, srcIndex, src.capacity());
198         if (src.hasMemoryAddress()) {
199             PlatformDependent.copyMemory(src.memoryAddress() + srcIndex, memory, idx(index), length);
200         } else if (src.hasArray()) {
201             setBytes(index, src.array(), src.arrayOffset() + srcIndex, length);
202         } else {
203             src.getBytes(srcIndex, memory, idx(index), length);
204         }
205         return this;
206     }
207 
208     @Override
209     public ByteBuf setBytes(int index, byte[] src, int srcIndex, int length) {
210         checkSrcIndex(index, length, srcIndex, src.length);
211         System.arraycopy(src, srcIndex, memory, idx(index), length);
212         return this;
213     }
214 
215     @Override
216     public ByteBuf setBytes(int index, ByteBuffer src) {
217         int length = src.remaining();
218         checkIndex(index, length);
219         src.get(memory, idx(index), length);
220         return this;
221     }
222 
223     @Override
224     public int setBytes(int index, InputStream in, int length) throws IOException {
225         checkIndex(index, length);
226         return in.read(memory, idx(index), length);
227     }
228 
229     @Override
230     public int setBytes(int index, ScatteringByteChannel in, int length) throws IOException {
231         checkIndex(index, length);
232         index = idx(index);
233         try {
234             return in.read((ByteBuffer) internalNioBuffer().clear().position(index).limit(index + length));
235         } catch (ClosedChannelException ignored) {
236             return -1;
237         }
238     }
239 
240     @Override
241     public ByteBuf copy(int index, int length) {
242         checkIndex(index, length);
243         ByteBuf copy = alloc().heapBuffer(length, maxCapacity());
244         copy.writeBytes(memory, idx(index), length);
245         return copy;
246     }
247 
248     @Override
249     public int nioBufferCount() {
250         return 1;
251     }
252 
253     @Override
254     public ByteBuffer[] nioBuffers(int index, int length) {
255         return new ByteBuffer[] { nioBuffer(index, length) };
256     }
257 
258     @Override
259     public ByteBuffer nioBuffer(int index, int length) {
260         checkIndex(index, length);
261         index = idx(index);
262         ByteBuffer buf =  ByteBuffer.wrap(memory, index, length);
263         return buf.slice();
264     }
265 
266     @Override
267     public ByteBuffer internalNioBuffer(int index, int length) {
268         checkIndex(index, length);
269         index = idx(index);
270         return (ByteBuffer) internalNioBuffer().clear().position(index).limit(index + length);
271     }
272 
273     @Override
274     public boolean hasArray() {
275         return true;
276     }
277 
278     @Override
279     public byte[] array() {
280         ensureAccessible();
281         return memory;
282     }
283 
284     @Override
285     public int arrayOffset() {
286         return offset;
287     }
288 
289     @Override
290     public boolean hasMemoryAddress() {
291         return false;
292     }
293 
294     @Override
295     public long memoryAddress() {
296         throw new UnsupportedOperationException();
297     }
298 
299     @Override
300     protected ByteBuffer newInternalNioBuffer(byte[] memory) {
301         return ByteBuffer.wrap(memory);
302     }
303 }