View Javadoc

    1   /*
    2    * Copyright 2012 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    *   http://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 org.jboss.netty.buffer;
    17
    18  import java.io.IOException;
    19  import java.io.InputStream;
    20  import java.io.OutputStream;
    21  import java.nio.ByteBuffer;
    22  import java.nio.ByteOrder;
    23  import java.nio.channels.GatheringByteChannel;
    24  import java.nio.channels.ScatteringByteChannel;
    25
    26
    27  /**
    28   * A derived buffer which hides its parent's tail data beyond a certain index.
    29   * It is recommended to use {@link ChannelBuffer#slice()} and
    30   * {@link ChannelBuffer#slice(int, int)} instead of calling the constructor
    31   * explicitly.
    32   */
    33  public class TruncatedChannelBuffer extends AbstractChannelBuffer implements WrappedChannelBuffer {
    34
    35      private final ChannelBuffer buffer;
    36      private final int length;
    37
    38      public TruncatedChannelBuffer(ChannelBuffer buffer, int length) {
    39          if (length > buffer.capacity()) {
    40              throw new IndexOutOfBoundsException("Length is too large, got "
    41                      + length + " but can't go higher than " + buffer.capacity());
    42          }
    43
    44          this.buffer = buffer;
    45          this.length = length;
    46          writerIndex(length);
    47      }
    48
    49      public ChannelBuffer unwrap() {
    50          return buffer;
    51      }
    52
    53      public ChannelBufferFactory factory() {
    54          return buffer.factory();
    55      }
    56
    57      public ByteOrder order() {
    58          return buffer.order();
    59      }
    60
    61      public boolean isDirect() {
    62          return buffer.isDirect();
    63      }
    64
    65      public int capacity() {
    66          return length;
    67      }
    68
    69      public boolean hasArray() {
    70          return buffer.hasArray();
    71      }
    72
    73      public byte[] array() {
    74          return buffer.array();
    75      }
    76
    77      public int arrayOffset() {
    78          return buffer.arrayOffset();
    79      }
    80
    81      public byte getByte(int index) {
    82          checkIndex(index);
    83          return buffer.getByte(index);
    84      }
    85
    86      public short getShort(int index) {
    87          checkIndex(index, 2);
    88          return buffer.getShort(index);
    89      }
    90
    91      public int getUnsignedMedium(int index) {
    92          checkIndex(index, 3);
    93          return buffer.getUnsignedMedium(index);
    94      }
    95
    96      public int getInt(int index) {
    97          checkIndex(index, 4);
    98          return buffer.getInt(index);
    99      }
    100
    101     public long getLong(int index) {
    102         checkIndex(index, 8);
    103         return buffer.getLong(index);
    104     }
    105
    106     public ChannelBuffer duplicate() {
    107         ChannelBuffer duplicate = new TruncatedChannelBuffer(buffer, length);
    108         duplicate.setIndex(readerIndex(), writerIndex());
    109         return duplicate;
    110     }
    111
    112     public ChannelBuffer copy(int index, int length) {
    113         checkIndex(index, length);
    114         return buffer.copy(index, length);
    115     }
    116
    117     public ChannelBuffer slice(int index, int length) {
    118         checkIndex(index, length);
    119         if (length == 0) {
    120             return ChannelBuffers.EMPTY_BUFFER;
    121         }
    122         return buffer.slice(index, length);
    123     }
    124
    125     public void getBytes(int index, ChannelBuffer dst, int dstIndex, int length) {
    126         checkIndex(index, length);
    127         buffer.getBytes(index, dst, dstIndex, length);
    128     }
    129
    130     public void getBytes(int index, byte[] dst, int dstIndex, int length) {
    131         checkIndex(index, length);
    132         buffer.getBytes(index, dst, dstIndex, length);
    133     }
    134
    135     public void getBytes(int index, ByteBuffer dst) {
    136         checkIndex(index, dst.remaining());
    137         buffer.getBytes(index, dst);
    138     }
    139
    140     public void setByte(int index, int value) {
    141         checkIndex(index);
    142         buffer.setByte(index, value);
    143     }
    144
    145     public void setShort(int index, int value) {
    146         checkIndex(index, 2);
    147         buffer.setShort(index, value);
    148     }
    149
    150     public void setMedium(int index, int value) {
    151         checkIndex(index, 3);
    152         buffer.setMedium(index, value);
    153     }
    154
    155     public void setInt(int index, int value) {
    156         checkIndex(index, 4);
    157         buffer.setInt(index, value);
    158     }
    159
    160     public void setLong(int index, long value) {
    161         checkIndex(index, 8);
    162         buffer.setLong(index, value);
    163     }
    164
    165     public void setBytes(int index, byte[] src, int srcIndex, int length) {
    166         checkIndex(index, length);
    167         buffer.setBytes(index, src, srcIndex, length);
    168     }
    169
    170     public void setBytes(int index, ChannelBuffer src, int srcIndex, int length) {
    171         checkIndex(index, length);
    172         buffer.setBytes(index, src, srcIndex, length);
    173     }
    174
    175     public void setBytes(int index, ByteBuffer src) {
    176         checkIndex(index, src.remaining());
    177         buffer.setBytes(index, src);
    178     }
    179
    180     public void getBytes(int index, OutputStream out, int length)
    181             throws IOException {
    182         checkIndex(index, length);
    183         buffer.getBytes(index, out, length);
    184     }
    185
    186     public int getBytes(int index, GatheringByteChannel out, int length)
    187             throws IOException {
    188         checkIndex(index, length);
    189         return buffer.getBytes(index, out, length);
    190     }
    191
    192     public int setBytes(int index, InputStream in, int length)
    193             throws IOException {
    194         checkIndex(index, length);
    195         return buffer.setBytes(index, in, length);
    196     }
    197
    198     public int setBytes(int index, ScatteringByteChannel in, int length)
    199             throws IOException {
    200         checkIndex(index, length);
    201         return buffer.setBytes(index, in, length);
    202     }
    203
    204     public ByteBuffer toByteBuffer(int index, int length) {
    205         checkIndex(index, length);
    206         return buffer.toByteBuffer(index, length);
    207     }
    208
    209     private void checkIndex(int index) {
    210         if (index < 0 || index >= capacity()) {
    211             throw new IndexOutOfBoundsException("Invalid index of " + index
    212                     + ", maximum is " + capacity());
    213         }
    214     }
    215
    216     private void checkIndex(int index, int length) {
    217         if (length < 0) {
    218             throw new IllegalArgumentException(
    219                     "length is negative: " + length);
    220         }
    221         if (index + length > capacity()) {
    222             throw new IndexOutOfBoundsException("Invalid index of "
    223                     + (index + length) + ", maximum is " + capacity());
    224         }
    225     }
    226 }