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