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 }