View Javadoc

    1   /*
    2    * Copyright 2009 Red Hat, Inc.
    3    *
    4    * Red Hat licenses this file to you under the Apache License, version 2.0
    5    * (the "License"); you may not use this file except in compliance with the
    6    * 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   * @author <a href="http://www.jboss.org/netty/">The Netty Project</a>
    34   * @author <a href="http://gleamynode.net/">Trustin Lee</a>
    35   *
    36   * @version $Rev: 2206 $, $Date: 2010-03-03 14:35:01 +0900 (Wed, 03 Mar 2010) $
    37   *
    38   */
    39  public class TruncatedChannelBuffer extends AbstractChannelBuffer implements WrappedChannelBuffer {
    40
    41      private final ChannelBuffer buffer;
    42      private final int length;
    43
    44      public TruncatedChannelBuffer(ChannelBuffer buffer, int length) {
    45          if (length > buffer.capacity()) {
    46              throw new IndexOutOfBoundsException();
    47          }
    48
    49          this.buffer = buffer;
    50          this.length = length;
    51          writerIndex(length);
    52      }
    53
    54      public ChannelBuffer unwrap() {
    55          return buffer;
    56      }
    57
    58      public ChannelBufferFactory factory() {
    59          return buffer.factory();
    60      }
    61
    62      public ByteOrder order() {
    63          return buffer.order();
    64      }
    65
    66      public boolean isDirect() {
    67          return buffer.isDirect();
    68      }
    69
    70      public int capacity() {
    71          return length;
    72      }
    73
    74      public boolean hasArray() {
    75          return buffer.hasArray();
    76      }
    77
    78      public byte[] array() {
    79          return buffer.array();
    80      }
    81
    82      public int arrayOffset() {
    83          return buffer.arrayOffset();
    84      }
    85
    86      public byte getByte(int index) {
    87          checkIndex(index);
    88          return buffer.getByte(index);
    89      }
    90
    91      public short getShort(int index) {
    92          checkIndex(index, 2);
    93          return buffer.getShort(index);
    94      }
    95
    96      public int getUnsignedMedium(int index) {
    97          checkIndex(index, 3);
    98          return buffer.getUnsignedMedium(index);
    99      }
    100
    101     public int getInt(int index) {
    102         checkIndex(index, 4);
    103         return buffer.getInt(index);
    104     }
    105
    106     public long getLong(int index) {
    107         checkIndex(index, 8);
    108         return buffer.getLong(index);
    109     }
    110
    111     public ChannelBuffer duplicate() {
    112         ChannelBuffer duplicate = new TruncatedChannelBuffer(buffer, length);
    113         duplicate.setIndex(readerIndex(), writerIndex());
    114         return duplicate;
    115     }
    116
    117     public ChannelBuffer copy(int index, int length) {
    118         checkIndex(index, length);
    119         return buffer.copy(index, length);
    120     }
    121
    122     public ChannelBuffer slice(int index, int length) {
    123         checkIndex(index, length);
    124         if (length == 0) {
    125             return ChannelBuffers.EMPTY_BUFFER;
    126         }
    127         return buffer.slice(index, length);
    128     }
    129
    130     public void getBytes(int index, ChannelBuffer dst, int dstIndex, int length) {
    131         checkIndex(index, length);
    132         buffer.getBytes(index, dst, dstIndex, length);
    133     }
    134
    135     public void getBytes(int index, byte[] dst, int dstIndex, int length) {
    136         checkIndex(index, length);
    137         buffer.getBytes(index, dst, dstIndex, length);
    138     }
    139
    140     public void getBytes(int index, ByteBuffer dst) {
    141         checkIndex(index, dst.remaining());
    142         buffer.getBytes(index, dst);
    143     }
    144
    145     public void setByte(int index, int value) {
    146         checkIndex(index);
    147         buffer.setByte(index, value);
    148     }
    149
    150     public void setShort(int index, int value) {
    151         checkIndex(index, 2);
    152         buffer.setShort(index, value);
    153     }
    154
    155     public void setMedium(int index, int value) {
    156         checkIndex(index, 3);
    157         buffer.setMedium(index, value);
    158     }
    159
    160     public void setInt(int index, int value) {
    161         checkIndex(index, 4);
    162         buffer.setInt(index, value);
    163     }
    164
    165     public void setLong(int index, long value) {
    166         checkIndex(index, 8);
    167         buffer.setLong(index, value);
    168     }
    169
    170     public void setBytes(int index, byte[] src, int srcIndex, int length) {
    171         checkIndex(index, length);
    172         buffer.setBytes(index, src, srcIndex, length);
    173     }
    174
    175     public void setBytes(int index, ChannelBuffer src, int srcIndex, int length) {
    176         checkIndex(index, length);
    177         buffer.setBytes(index, src, srcIndex, length);
    178     }
    179
    180     public void setBytes(int index, ByteBuffer src) {
    181         checkIndex(index, src.remaining());
    182         buffer.setBytes(index, src);
    183     }
    184
    185     public void getBytes(int index, OutputStream out, int length)
    186             throws IOException {
    187         checkIndex(index, length);
    188         buffer.getBytes(index, out, length);
    189     }
    190
    191     public int getBytes(int index, GatheringByteChannel out, int length)
    192             throws IOException {
    193         checkIndex(index, length);
    194         return buffer.getBytes(index, out, length);
    195     }
    196
    197     public int setBytes(int index, InputStream in, int length)
    198             throws IOException {
    199         checkIndex(index, length);
    200         return buffer.setBytes(index, in, length);
    201     }
    202
    203     public int setBytes(int index, ScatteringByteChannel in, int length)
    204             throws IOException {
    205         checkIndex(index, length);
    206         return buffer.setBytes(index, in, length);
    207     }
    208
    209     public ByteBuffer toByteBuffer(int index, int length) {
    210         checkIndex(index, length);
    211         return buffer.toByteBuffer(index, length);
    212     }
    213
    214     private void checkIndex(int index) {
    215         if (index < 0 || index >= capacity()) {
    216             throw new IndexOutOfBoundsException();
    217         }
    218     }
    219
    220     private void checkIndex(int index, int length) {
    221         if (length < 0) {
    222             throw new IllegalArgumentException(
    223                     "length is negative: " + length);
    224         }
    225         if (index + length > capacity()) {
    226             throw new IndexOutOfBoundsException();
    227         }
    228     }
    229 }