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