View Javadoc
1   /*
2    * Copyright 2016 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.ByteProcessor;
20  import io.netty.util.Recycler;
21  import io.netty.util.internal.ObjectPool.Handle;
22  
23  import java.io.IOException;
24  import java.io.InputStream;
25  import java.io.OutputStream;
26  import java.nio.ByteBuffer;
27  import java.nio.channels.FileChannel;
28  import java.nio.channels.GatheringByteChannel;
29  import java.nio.channels.ScatteringByteChannel;
30  
31  import static io.netty.buffer.AbstractUnpooledSlicedByteBuf.checkSliceOutOfBounds;
32  
33  final class PooledSlicedByteBuf extends AbstractPooledDerivedByteBuf {
34  
35      private static final Recycler<PooledSlicedByteBuf> RECYCLER =
36              new Recycler<PooledSlicedByteBuf>() {
37                  @Override
38                  protected PooledSlicedByteBuf newObject(Handle<PooledSlicedByteBuf> handle) {
39                      return new PooledSlicedByteBuf(handle);
40                  }
41              };
42  
43      static PooledSlicedByteBuf newInstance(AbstractByteBuf unwrapped, ByteBuf wrapped,
44                                             int index, int length) {
45          checkSliceOutOfBounds(index, length, unwrapped);
46          return newInstance0(unwrapped, wrapped, index, length);
47      }
48  
49      private static PooledSlicedByteBuf newInstance0(AbstractByteBuf unwrapped, ByteBuf wrapped,
50                                                      int adjustment, int length) {
51          final PooledSlicedByteBuf slice = RECYCLER.get();
52          slice.init(unwrapped, wrapped, 0, length, length);
53          slice.discardMarks();
54          slice.adjustment = adjustment;
55  
56          return slice;
57      }
58  
59      int adjustment;
60  
61      private PooledSlicedByteBuf(Handle<PooledSlicedByteBuf> handle) {
62          super(handle);
63      }
64  
65      @Override
66      public int capacity() {
67          return maxCapacity();
68      }
69  
70      @Override
71      public ByteBuf capacity(int newCapacity) {
72          throw new UnsupportedOperationException("sliced buffer");
73      }
74  
75      @Override
76      public int arrayOffset() {
77          return idx(unwrap().arrayOffset());
78      }
79  
80      @Override
81      public long memoryAddress() {
82          return unwrap().memoryAddress() + adjustment;
83      }
84  
85      @Override
86      public ByteBuffer nioBuffer(int index, int length) {
87          checkIndex0(index, length);
88          return unwrap().nioBuffer(idx(index), length);
89      }
90  
91      @Override
92      public ByteBuffer[] nioBuffers(int index, int length) {
93          checkIndex0(index, length);
94          return unwrap().nioBuffers(idx(index), length);
95      }
96  
97      @Override
98      public ByteBuf copy(int index, int length) {
99          checkIndex0(index, length);
100         return unwrap().copy(idx(index), length);
101     }
102 
103     @Override
104     public ByteBuf slice(int index, int length) {
105         checkIndex0(index, length);
106         return super.slice(idx(index), length);
107     }
108 
109     @Override
110     public ByteBuf retainedSlice(int index, int length) {
111         checkIndex0(index, length);
112         return PooledSlicedByteBuf.newInstance0(unwrap(), this, idx(index), length);
113     }
114 
115     @Override
116     public ByteBuf duplicate() {
117         return slice(0, capacity()).setIndex(readerIndex(), writerIndex());
118     }
119 
120     @Override
121     public ByteBuf retainedDuplicate() {
122         return retainedSlice(0, capacity()).setIndex(readerIndex(), writerIndex());
123     }
124 
125     @Override
126     public byte getByte(int index) {
127         checkIndex(index, 1);
128         return _getByte(index);
129     }
130 
131     @Override
132     protected byte _getByte(int index) {
133         return unwrap()._getByte(idx(index));
134     }
135 
136     @Override
137     public short getShort(int index) {
138         checkIndex(index, 2);
139         return _getShort(index);
140     }
141 
142     @Override
143     protected short _getShort(int index) {
144         return unwrap()._getShort(idx(index));
145     }
146 
147     @Override
148     public short getShortLE(int index) {
149         checkIndex(index, 2);
150         return _getShortLE(index);
151     }
152 
153     @Override
154     protected short _getShortLE(int index) {
155         return unwrap()._getShortLE(idx(index));
156     }
157 
158     @Override
159     public int getUnsignedMedium(int index) {
160         checkIndex(index, 3);
161         return _getUnsignedMedium(index);
162     }
163 
164     @Override
165     protected int _getUnsignedMedium(int index) {
166         return unwrap()._getUnsignedMedium(idx(index));
167     }
168 
169     @Override
170     public int getUnsignedMediumLE(int index) {
171         checkIndex(index, 3);
172         return _getUnsignedMediumLE(index);
173     }
174 
175     @Override
176     protected int _getUnsignedMediumLE(int index) {
177         return unwrap()._getUnsignedMediumLE(idx(index));
178     }
179 
180     @Override
181     public int getInt(int index) {
182         checkIndex(index, 4);
183         return _getInt(index);
184     }
185 
186     @Override
187     protected int _getInt(int index) {
188         return unwrap()._getInt(idx(index));
189     }
190 
191     @Override
192     public int getIntLE(int index) {
193         checkIndex(index, 4);
194         return _getIntLE(index);
195     }
196 
197     @Override
198     protected int _getIntLE(int index) {
199         return unwrap()._getIntLE(idx(index));
200     }
201 
202     @Override
203     public long getLong(int index) {
204         checkIndex(index, 8);
205         return _getLong(index);
206     }
207 
208     @Override
209     protected long _getLong(int index) {
210         return unwrap()._getLong(idx(index));
211     }
212 
213     @Override
214     public long getLongLE(int index) {
215         checkIndex(index, 8);
216         return _getLongLE(index);
217     }
218 
219     @Override
220     protected long _getLongLE(int index) {
221         return unwrap()._getLongLE(idx(index));
222     }
223 
224     @Override
225     public ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) {
226         checkIndex0(index, length);
227         unwrap().getBytes(idx(index), dst, dstIndex, length);
228         return this;
229     }
230 
231     @Override
232     public ByteBuf getBytes(int index, byte[] dst, int dstIndex, int length) {
233         checkIndex0(index, length);
234         unwrap().getBytes(idx(index), dst, dstIndex, length);
235         return this;
236     }
237 
238     @Override
239     public ByteBuf getBytes(int index, ByteBuffer dst) {
240         checkIndex0(index, dst.remaining());
241         unwrap().getBytes(idx(index), dst);
242         return this;
243     }
244 
245     @Override
246     public ByteBuf setByte(int index, int value) {
247         checkIndex(index, 1);
248         _setByte(index, value);
249         return this;
250     }
251 
252     @Override
253     protected void _setByte(int index, int value) {
254         unwrap()._setByte(idx(index), value);
255     }
256 
257     @Override
258     public ByteBuf setShort(int index, int value) {
259         checkIndex(index, 2);
260         _setShort(index, value);
261         return this;
262     }
263 
264     @Override
265     protected void _setShort(int index, int value) {
266         unwrap()._setShort(idx(index), value);
267     }
268 
269     @Override
270     public ByteBuf setShortLE(int index, int value) {
271         checkIndex(index, 2);
272         _setShortLE(index, value);
273         return this;
274     }
275 
276     @Override
277     protected void _setShortLE(int index, int value) {
278         unwrap()._setShortLE(idx(index), value);
279     }
280 
281     @Override
282     public ByteBuf setMedium(int index, int value) {
283         checkIndex(index, 3);
284         _setMedium(index, value);
285         return this;
286     }
287 
288     @Override
289     protected void _setMedium(int index, int value) {
290         unwrap()._setMedium(idx(index), value);
291     }
292 
293     @Override
294     public ByteBuf setMediumLE(int index, int value) {
295         checkIndex(index, 3);
296         _setMediumLE(index, value);
297         return this;
298     }
299 
300     @Override
301     protected void _setMediumLE(int index, int value) {
302         unwrap()._setMediumLE(idx(index), value);
303     }
304 
305     @Override
306     public ByteBuf setInt(int index, int value) {
307         checkIndex(index, 4);
308         _setInt(index, value);
309         return this;
310     }
311 
312     @Override
313     protected void _setInt(int index, int value) {
314         unwrap()._setInt(idx(index), value);
315     }
316 
317     @Override
318     public ByteBuf setIntLE(int index, int value) {
319         checkIndex(index, 4);
320         _setIntLE(index, value);
321         return this;
322     }
323 
324     @Override
325     protected void _setIntLE(int index, int value) {
326         unwrap()._setIntLE(idx(index), value);
327     }
328 
329     @Override
330     public ByteBuf setLong(int index, long value) {
331         checkIndex(index, 8);
332         _setLong(index, value);
333         return this;
334     }
335 
336     @Override
337     protected void _setLong(int index, long value) {
338         unwrap()._setLong(idx(index), value);
339     }
340 
341     @Override
342     public ByteBuf setLongLE(int index, long value) {
343         checkIndex(index, 8);
344         _setLongLE(index, value);
345         return this;
346     }
347 
348     @Override
349     protected void _setLongLE(int index, long value) {
350         unwrap()._setLongLE(idx(index), value);
351     }
352 
353     @Override
354     public ByteBuf setBytes(int index, byte[] src, int srcIndex, int length) {
355         checkIndex0(index, length);
356         unwrap().setBytes(idx(index), src, srcIndex, length);
357         return this;
358     }
359 
360     @Override
361     public ByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length) {
362         checkIndex0(index, length);
363         unwrap().setBytes(idx(index), src, srcIndex, length);
364         return this;
365     }
366 
367     @Override
368     public ByteBuf setBytes(int index, ByteBuffer src) {
369         checkIndex0(index, src.remaining());
370         unwrap().setBytes(idx(index), src);
371         return this;
372     }
373 
374     @Override
375     public ByteBuf getBytes(int index, OutputStream out, int length)
376             throws IOException {
377         checkIndex0(index, length);
378         unwrap().getBytes(idx(index), out, length);
379         return this;
380     }
381 
382     @Override
383     public int getBytes(int index, GatheringByteChannel out, int length)
384             throws IOException {
385         checkIndex0(index, length);
386         return unwrap().getBytes(idx(index), out, length);
387     }
388 
389     @Override
390     public int getBytes(int index, FileChannel out, long position, int length)
391             throws IOException {
392         checkIndex0(index, length);
393         return unwrap().getBytes(idx(index), out, position, length);
394     }
395 
396     @Override
397     public int setBytes(int index, InputStream in, int length)
398             throws IOException {
399         checkIndex0(index, length);
400         return unwrap().setBytes(idx(index), in, length);
401     }
402 
403     @Override
404     public int setBytes(int index, ScatteringByteChannel in, int length)
405             throws IOException {
406         checkIndex0(index, length);
407         return unwrap().setBytes(idx(index), in, length);
408     }
409 
410     @Override
411     public int setBytes(int index, FileChannel in, long position, int length)
412             throws IOException {
413         checkIndex0(index, length);
414         return unwrap().setBytes(idx(index), in, position, length);
415     }
416 
417     @Override
418     public int forEachByte(int index, int length, ByteProcessor processor) {
419         checkIndex0(index, length);
420         int ret = unwrap().forEachByte(idx(index), length, processor);
421         if (ret < adjustment) {
422             return -1;
423         }
424         return ret - adjustment;
425     }
426 
427     @Override
428     public int forEachByteDesc(int index, int length, ByteProcessor processor) {
429         checkIndex0(index, length);
430         int ret = unwrap().forEachByteDesc(idx(index), length, processor);
431         if (ret < adjustment) {
432             return -1;
433         }
434         return ret - adjustment;
435     }
436 
437     private int idx(int index) {
438         return index + adjustment;
439     }
440 }