001    /*
002     * Copyright (C) 2008  Trustin Heuiseung Lee
003     *
004     * This library is free software; you can redistribute it and/or
005     * modify it under the terms of the GNU Lesser General Public
006     * License as published by the Free Software Foundation; either
007     * version 2.1 of the License, or (at your option) any later version.
008     *
009     * This library is distributed in the hope that it will be useful,
010     * but WITHOUT ANY WARRANTY; without even the implied warranty of
011     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
012     * Lesser General Public License for more details.
013     *
014     * You should have received a copy of the GNU Lesser General Public
015     * License along with this library; if not, write to the Free Software
016     * Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA
017     */
018    package net.gleamynode.netty.buffer;
019    
020    import java.io.IOException;
021    import java.io.InputStream;
022    import java.io.OutputStream;
023    import java.nio.ByteBuffer;
024    import java.nio.ByteOrder;
025    import java.nio.channels.GatheringByteChannel;
026    import java.nio.channels.ScatteringByteChannel;
027    
028    
029    /**
030     * @author The Netty Project (netty@googlegroups.com)
031     * @author Trustin Lee (trustin@gmail.com)
032     *
033     * @version $Rev$, $Date$
034     *
035     */
036    public class TruncatedChannelBuffer extends AbstractChannelBuffer implements WrappedChannelBuffer {
037    
038        private final ChannelBuffer buffer;
039        private final int length;
040    
041        public TruncatedChannelBuffer(ChannelBuffer buffer, int length) {
042            if (length > buffer.capacity()) {
043                throw new IndexOutOfBoundsException();
044            }
045    
046            this.buffer = buffer;
047            this.length = length;
048            writerIndex(length);
049        }
050    
051        public ChannelBuffer unwrap() {
052            return buffer;
053        }
054    
055        public ByteOrder order() {
056            return buffer.order();
057        }
058    
059        public int capacity() {
060            return length;
061        }
062    
063        public byte getByte(int index) {
064            checkIndex(index);
065            return buffer.getByte(index);
066        }
067    
068        public short getShort(int index) {
069            checkIndex(index, 2);
070            return buffer.getShort(index);
071        }
072    
073        public int getMedium(int index) {
074            checkIndex(index, 3);
075            return buffer.getMedium(index);
076        }
077    
078        public int getInt(int index) {
079            checkIndex(index, 4);
080            return buffer.getInt(index);
081        }
082    
083        public long getLong(int index) {
084            checkIndex(index, 8);
085            return buffer.getLong(index);
086        }
087    
088        public ChannelBuffer duplicate() {
089            return new TruncatedChannelBuffer(buffer, length);
090        }
091    
092        public ChannelBuffer copy(int index, int length) {
093            return buffer.copy(index, length);
094        }
095    
096        public ChannelBuffer slice(int index, int length) {
097            checkIndex(index, length);
098            return buffer.slice(index, length);
099        }
100    
101        public void getBytes(int index, ChannelBuffer dst, int dstIndex, int length) {
102            checkIndex(index, length);
103            buffer.getBytes(index, dst, dstIndex, length);
104        }
105    
106        public void getBytes(int index, byte[] dst, int dstIndex, int length) {
107            checkIndex(index, length);
108            buffer.getBytes(index, dst, dstIndex, length);
109        }
110    
111        public void getBytes(int index, ByteBuffer dst) {
112            checkIndex(index, dst.remaining());
113            buffer.getBytes(index, dst);
114        }
115    
116        public void setByte(int index, byte value) {
117            checkIndex(index);
118            buffer.setByte(index, value);
119        }
120    
121        public void setShort(int index, short value) {
122            checkIndex(index, 2);
123            buffer.setShort(index, value);
124        }
125    
126        public void setMedium(int index, int value) {
127            checkIndex(index, 3);
128            buffer.setMedium(index, value);
129        }
130    
131        public void setInt(int index, int value) {
132            checkIndex(index, 4);
133            buffer.setInt(index, value);
134        }
135    
136        public void setLong(int index, long value) {
137            checkIndex(index, 8);
138            buffer.setLong(index, value);
139        }
140    
141        public void setBytes(int index, byte[] src, int srcIndex, int length) {
142            checkIndex(index, length);
143            buffer.setBytes(index, src, srcIndex, length);
144        }
145    
146        public void setBytes(int index, ChannelBuffer src, int srcIndex, int length) {
147            checkIndex(index, length);
148            buffer.setBytes(index, src, srcIndex, length);
149        }
150    
151        public void setBytes(int index, ByteBuffer src) {
152            checkIndex(index, src.remaining());
153            buffer.setBytes(index, src);
154        }
155    
156        public void getBytes(int index, OutputStream out, int length)
157                throws IOException {
158            checkIndex(index, length);
159            buffer.getBytes(index, out, length);
160        }
161    
162        public int getBytes(int index, GatheringByteChannel out, int length)
163                throws IOException {
164            checkIndex(index, length);
165            return buffer.getBytes(index, out, length);
166        }
167    
168        public void setBytes(int index, InputStream in, int length)
169                throws IOException {
170            checkIndex(index, length);
171            buffer.setBytes(index, in, length);
172        }
173    
174        public int setBytes(int index, ScatteringByteChannel in, int length)
175                throws IOException {
176            checkIndex(index, length);
177            return buffer.setBytes(index, in, length);
178        }
179    
180        public ByteBuffer toByteBuffer(int index, int length) {
181            checkIndex(index, length);
182            return buffer.toByteBuffer(index, length);
183        }
184    
185        private void checkIndex(int index) {
186            if (index < 0 || index >= capacity()) {
187                throw new IndexOutOfBoundsException();
188            }
189        }
190    
191        private void checkIndex(int index, int length) {
192            if (length < 0) {
193                throw new IllegalArgumentException(
194                        "length is negative: " + length);
195            }
196            if (index + length > capacity()) {
197                throw new IndexOutOfBoundsException();
198            }
199        }
200    }