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 }