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 unwrap().duplicate().setIndex(idx(readerIndex()), idx(writerIndex()));
219     }
220 
221     @Override
222     public ByteBuf copy(int index, int length) {
223         checkIndex0(index, length);
224         return unwrap().copy(idx(index), length);
225     }
226 
227     @Override
228     public ByteBuf slice(int index, int length) {
229         checkIndex0(index, length);
230         return unwrap().slice(idx(index), length);
231     }
232 
233     @Override
234     public ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) {
235         checkIndex0(index, length);
236         unwrap().getBytes(idx(index), dst, dstIndex, length);
237         return this;
238     }
239 
240     @Override
241     public ByteBuf getBytes(int index, byte[] dst, int dstIndex, int length) {
242         checkIndex0(index, length);
243         unwrap().getBytes(idx(index), dst, dstIndex, length);
244         return this;
245     }
246 
247     @Override
248     public ByteBuf getBytes(int index, ByteBuffer dst) {
249         checkIndex0(index, dst.remaining());
250         unwrap().getBytes(idx(index), dst);
251         return this;
252     }
253 
254     @Override
255     public ByteBuf setByte(int index, int value) {
256         checkIndex0(index, 1);
257         unwrap().setByte(idx(index), value);
258         return this;
259     }
260 
261     @Override
262     public CharSequence getCharSequence(int index, int length, Charset charset) {
263         checkIndex0(index, length);
264         return unwrap().getCharSequence(idx(index), length, charset);
265     }
266 
267     @Override
268     protected void _setByte(int index, int value) {
269         unwrap().setByte(idx(index), value);
270     }
271 
272     @Override
273     public ByteBuf setShort(int index, int value) {
274         checkIndex0(index, 2);
275         unwrap().setShort(idx(index), value);
276         return this;
277     }
278 
279     @Override
280     protected void _setShort(int index, int value) {
281         unwrap().setShort(idx(index), value);
282     }
283 
284     @Override
285     public ByteBuf setShortLE(int index, int value) {
286         checkIndex0(index, 2);
287         unwrap().setShortLE(idx(index), value);
288         return this;
289     }
290 
291     @Override
292     protected void _setShortLE(int index, int value) {
293         unwrap().setShortLE(idx(index), value);
294     }
295 
296     @Override
297     public ByteBuf setMedium(int index, int value) {
298         checkIndex0(index, 3);
299         unwrap().setMedium(idx(index), value);
300         return this;
301     }
302 
303     @Override
304     protected void _setMedium(int index, int value) {
305         unwrap().setMedium(idx(index), value);
306     }
307 
308     @Override
309     public ByteBuf setMediumLE(int index, int value) {
310         checkIndex0(index, 3);
311         unwrap().setMediumLE(idx(index), value);
312         return this;
313     }
314 
315     @Override
316     protected void _setMediumLE(int index, int value) {
317         unwrap().setMediumLE(idx(index), value);
318     }
319 
320     @Override
321     public ByteBuf setInt(int index, int value) {
322         checkIndex0(index, 4);
323         unwrap().setInt(idx(index), value);
324         return this;
325     }
326 
327     @Override
328     protected void _setInt(int index, int value) {
329         unwrap().setInt(idx(index), value);
330     }
331 
332     @Override
333     public ByteBuf setIntLE(int index, int value) {
334         checkIndex0(index, 4);
335         unwrap().setIntLE(idx(index), value);
336         return this;
337     }
338 
339     @Override
340     protected void _setIntLE(int index, int value) {
341         unwrap().setIntLE(idx(index), value);
342     }
343 
344     @Override
345     public ByteBuf setLong(int index, long value) {
346         checkIndex0(index, 8);
347         unwrap().setLong(idx(index), value);
348         return this;
349     }
350 
351     @Override
352     protected void _setLong(int index, long value) {
353         unwrap().setLong(idx(index), value);
354     }
355 
356     @Override
357     public ByteBuf setLongLE(int index, long value) {
358         checkIndex0(index, 8);
359         unwrap().setLongLE(idx(index), value);
360         return this;
361     }
362 
363     @Override
364     protected void _setLongLE(int index, long value) {
365         unwrap().setLongLE(idx(index), value);
366     }
367 
368     @Override
369     public ByteBuf setBytes(int index, byte[] src, int srcIndex, int length) {
370         checkIndex0(index, length);
371         unwrap().setBytes(idx(index), src, srcIndex, length);
372         return this;
373     }
374 
375     @Override
376     public ByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length) {
377         checkIndex0(index, length);
378         unwrap().setBytes(idx(index), src, srcIndex, length);
379         return this;
380     }
381 
382     @Override
383     public ByteBuf setBytes(int index, ByteBuffer src) {
384         checkIndex0(index, src.remaining());
385         unwrap().setBytes(idx(index), src);
386         return this;
387     }
388 
389     @Override
390     public ByteBuf getBytes(int index, OutputStream out, int length) throws IOException {
391         checkIndex0(index, length);
392         unwrap().getBytes(idx(index), out, length);
393         return this;
394     }
395 
396     @Override
397     public int getBytes(int index, GatheringByteChannel out, int length) throws IOException {
398         checkIndex0(index, length);
399         return unwrap().getBytes(idx(index), out, length);
400     }
401 
402     @Override
403     public int getBytes(int index, FileChannel out, long position, int length) throws IOException {
404         checkIndex0(index, length);
405         return unwrap().getBytes(idx(index), out, position, length);
406     }
407 
408     @Override
409     public int setBytes(int index, InputStream in, int length) throws IOException {
410         checkIndex0(index, length);
411         return unwrap().setBytes(idx(index), in, length);
412     }
413 
414     @Override
415     public int setBytes(int index, ScatteringByteChannel in, int length) throws IOException {
416         checkIndex0(index, length);
417         return unwrap().setBytes(idx(index), in, length);
418     }
419 
420     @Override
421     public int setBytes(int index, FileChannel in, long position, int length) throws IOException {
422         checkIndex0(index, length);
423         return unwrap().setBytes(idx(index), in, position, length);
424     }
425 
426     @Override
427     public int nioBufferCount() {
428         return unwrap().nioBufferCount();
429     }
430 
431     @Override
432     public ByteBuffer nioBuffer(int index, int length) {
433         checkIndex0(index, length);
434         return unwrap().nioBuffer(idx(index), length);
435     }
436 
437     @Override
438     public ByteBuffer[] nioBuffers(int index, int length) {
439         checkIndex0(index, length);
440         return unwrap().nioBuffers(idx(index), length);
441     }
442 
443     @Override
444     public int forEachByte(int index, int length, ByteProcessor processor) {
445         checkIndex0(index, length);
446         int ret = unwrap().forEachByte(idx(index), length, processor);
447         if (ret >= adjustment) {
448             return ret - adjustment;
449         } else {
450             return -1;
451         }
452     }
453 
454     @Override
455     public int forEachByteDesc(int index, int length, ByteProcessor processor) {
456         checkIndex0(index, length);
457         int ret = unwrap().forEachByteDesc(idx(index), length, processor);
458         if (ret >= adjustment) {
459             return ret - adjustment;
460         } else {
461             return -1;
462         }
463     }
464 
465     /**
466      * Returns the index with the needed adjustment.
467      */
468     final int idx(int index) {
469         return index + adjustment;
470     }
471 
472     static void checkSliceOutOfBounds(int index, int length, ByteBuf buffer) {
473         if (isOutOfBounds(index, length, buffer.capacity())) {
474             throw new IndexOutOfBoundsException(buffer + ".slice(" + index + ", " + length + ')');
475         }
476     }
477 }