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 SlicedChannelBuffer extends AbstractChannelBuffer implements WrappedChannelBuffer {
037
038 private final ChannelBuffer buffer;
039 private final int adjustment;
040 private final int length;
041
042 public SlicedChannelBuffer(ChannelBuffer buffer, int index, int length) {
043 if (index < 0 || index > buffer.capacity()) {
044 throw new IndexOutOfBoundsException();
045 }
046
047 if (index + length > buffer.capacity()) {
048 throw new IndexOutOfBoundsException();
049 }
050
051 this.buffer = buffer;
052 adjustment = index;
053 this.length = length;
054 writerIndex(length);
055 }
056
057 public ChannelBuffer unwrap() {
058 return buffer;
059 }
060
061 public ByteOrder order() {
062 return buffer.order();
063 }
064
065 public int capacity() {
066 return length;
067 }
068
069 public byte getByte(int index) {
070 checkIndex(index);
071 return buffer.getByte(index + adjustment);
072 }
073
074 public short getShort(int index) {
075 checkIndex(index, 2);
076 return buffer.getShort(index + adjustment);
077 }
078
079 public int getMedium(int index) {
080 checkIndex(index, 3);
081 return buffer.getMedium(index + adjustment);
082 }
083
084 public int getInt(int index) {
085 checkIndex(index, 4);
086 return buffer.getInt(index + adjustment);
087 }
088
089 public long getLong(int index) {
090 checkIndex(index, 8);
091 return buffer.getLong(index + adjustment);
092 }
093
094 public ChannelBuffer duplicate() {
095 return new SlicedChannelBuffer(buffer, adjustment, length);
096 }
097
098 public ChannelBuffer copy(int index, int length) {
099 return buffer.copy(index + adjustment, length);
100 }
101
102 public ChannelBuffer slice(int index, int length) {
103 checkIndex(index, length);
104 return new SlicedChannelBuffer(buffer, index + adjustment, length);
105 }
106
107 public void getBytes(int index, ChannelBuffer dst, int dstIndex, int length) {
108 checkIndex(index, length);
109 buffer.getBytes(index + adjustment, dst, dstIndex, length);
110 }
111
112 public void getBytes(int index, byte[] dst, int dstIndex, int length) {
113 checkIndex(index, length);
114 buffer.getBytes(index + adjustment, dst, dstIndex, length);
115 }
116
117 public void getBytes(int index, ByteBuffer dst) {
118 checkIndex(index, dst.remaining());
119 buffer.getBytes(index + adjustment, dst);
120 }
121
122 public void setByte(int index, byte value) {
123 checkIndex(index);
124 buffer.setByte(index + adjustment, value);
125 }
126
127 public void setShort(int index, short value) {
128 checkIndex(index, 2);
129 buffer.setShort(index + adjustment, value);
130 }
131
132 public void setMedium(int index, int value) {
133 checkIndex(index, 3);
134 buffer.setMedium(index + adjustment, value);
135 }
136
137 public void setInt(int index, int value) {
138 checkIndex(index, 4);
139 buffer.setInt(index + adjustment, value);
140 }
141
142 public void setLong(int index, long value) {
143 checkIndex(index, 8);
144 buffer.setLong(index + adjustment, value);
145 }
146
147 public void setBytes(int index, byte[] src, int srcIndex, int length) {
148 checkIndex(index, length);
149 buffer.setBytes(index + adjustment, src, srcIndex, length);
150 }
151
152 public void setBytes(int index, ChannelBuffer src, int srcIndex, int length) {
153 checkIndex(index, length);
154 buffer.setBytes(index + adjustment, src, srcIndex, length);
155 }
156
157 public void setBytes(int index, ByteBuffer src) {
158 checkIndex(index, src.remaining());
159 buffer.setBytes(index + adjustment, src);
160 }
161
162 public void getBytes(int index, OutputStream out, int length)
163 throws IOException {
164 checkIndex(index, length);
165 buffer.getBytes(index + adjustment, out, length);
166 }
167
168 public int getBytes(int index, GatheringByteChannel out, int length)
169 throws IOException {
170 checkIndex(index, length);
171 return buffer.getBytes(index + adjustment, out, length);
172 }
173
174 public void setBytes(int index, InputStream in, int length)
175 throws IOException {
176 checkIndex(index, length);
177 buffer.setBytes(index + adjustment, in, length);
178 }
179
180 public int setBytes(int index, ScatteringByteChannel in, int length)
181 throws IOException {
182 checkIndex(index, length);
183 return buffer.setBytes(index + adjustment, in, length);
184 }
185
186 public ByteBuffer toByteBuffer(int index, int length) {
187 checkIndex(index, length);
188 return buffer.toByteBuffer(index + adjustment, length);
189 }
190
191 private void checkIndex(int index) {
192 if (index < 0 || index >= capacity()) {
193 throw new IndexOutOfBoundsException();
194 }
195 }
196
197 private void checkIndex(int startIndex, int length) {
198 if (length < 0) {
199 throw new IllegalArgumentException(
200 "length is negative: " + length);
201 }
202 if (startIndex < 0) {
203 throw new IndexOutOfBoundsException();
204 }
205 if (startIndex + length > capacity()) {
206 throw new IndexOutOfBoundsException();
207 }
208 }
209 }