1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
29
30
31
32 public class DynamicChannelBuffer extends AbstractChannelBuffer {
33
34 private final ChannelBufferFactory factory;
35 private final ByteOrder endianness;
36 private ChannelBuffer buffer;
37
38 public DynamicChannelBuffer(int estimatedLength) {
39 this(ByteOrder.BIG_ENDIAN, estimatedLength);
40 }
41
42 public DynamicChannelBuffer(ByteOrder endianness, int estimatedLength) {
43 this(endianness, estimatedLength, HeapChannelBufferFactory.getInstance(endianness));
44 }
45
46 public DynamicChannelBuffer(ByteOrder endianness, int estimatedLength, ChannelBufferFactory factory) {
47 if (estimatedLength < 0) {
48 throw new IllegalArgumentException("estimatedLength: " + estimatedLength);
49 }
50 if (endianness == null) {
51 throw new NullPointerException("endianness");
52 }
53 if (factory == null) {
54 throw new NullPointerException("factory");
55 }
56 this.factory = factory;
57 this.endianness = endianness;
58 buffer = factory.getBuffer(order(), estimatedLength);
59 }
60
61 @Override
62 public void ensureWritableBytes(int minWritableBytes) {
63 if (minWritableBytes <= writableBytes()) {
64 return;
65 }
66
67 int newCapacity;
68 if (capacity() == 0) {
69 newCapacity = 1;
70 } else {
71 newCapacity = capacity();
72 }
73 int minNewCapacity = writerIndex() + minWritableBytes;
74 while (newCapacity < minNewCapacity) {
75 newCapacity <<= 1;
76
77
78
79
80
81 if (newCapacity == 0) {
82 throw new IllegalStateException("Maximum size of 2gb exceeded");
83 }
84 }
85
86 ChannelBuffer newBuffer = factory().getBuffer(order(), newCapacity);
87 newBuffer.writeBytes(buffer, 0, writerIndex());
88 buffer = newBuffer;
89 }
90
91 public ChannelBufferFactory factory() {
92 return factory;
93 }
94
95 public ByteOrder order() {
96 return endianness;
97 }
98
99 public boolean isDirect() {
100 return buffer.isDirect();
101 }
102
103 public int capacity() {
104 return buffer.capacity();
105 }
106
107 public boolean hasArray() {
108 return buffer.hasArray();
109 }
110
111 public byte[] array() {
112 return buffer.array();
113 }
114
115 public int arrayOffset() {
116 return buffer.arrayOffset();
117 }
118
119 public byte getByte(int index) {
120 return buffer.getByte(index);
121 }
122
123 public short getShort(int index) {
124 return buffer.getShort(index);
125 }
126
127 public int getUnsignedMedium(int index) {
128 return buffer.getUnsignedMedium(index);
129 }
130
131 public int getInt(int index) {
132 return buffer.getInt(index);
133 }
134
135 public long getLong(int index) {
136 return buffer.getLong(index);
137 }
138
139 public void getBytes(int index, byte[] dst, int dstIndex, int length) {
140 buffer.getBytes(index, dst, dstIndex, length);
141 }
142
143 public void getBytes(int index, ChannelBuffer dst, int dstIndex, int length) {
144 buffer.getBytes(index, dst, dstIndex, length);
145 }
146
147 public void getBytes(int index, ByteBuffer dst) {
148 buffer.getBytes(index, dst);
149 }
150
151 public int getBytes(int index, GatheringByteChannel out, int length)
152 throws IOException {
153 return buffer.getBytes(index, out, length);
154 }
155
156 public void getBytes(int index, OutputStream out, int length)
157 throws IOException {
158 buffer.getBytes(index, out, length);
159 }
160
161 public void setByte(int index, int value) {
162 buffer.setByte(index, value);
163 }
164
165 public void setShort(int index, int value) {
166 buffer.setShort(index, value);
167 }
168
169 public void setMedium(int index, int value) {
170 buffer.setMedium(index, value);
171 }
172
173 public void setInt(int index, int value) {
174 buffer.setInt(index, value);
175 }
176
177 public void setLong(int index, long value) {
178 buffer.setLong(index, value);
179 }
180
181 public void setBytes(int index, byte[] src, int srcIndex, int length) {
182 buffer.setBytes(index, src, srcIndex, length);
183 }
184
185 public void setBytes(int index, ChannelBuffer src, int srcIndex, int length) {
186 buffer.setBytes(index, src, srcIndex, length);
187 }
188
189 public void setBytes(int index, ByteBuffer src) {
190 buffer.setBytes(index, src);
191 }
192
193 public int setBytes(int index, InputStream in, int length)
194 throws IOException {
195 return buffer.setBytes(index, in, length);
196 }
197
198 public int setBytes(int index, ScatteringByteChannel in, int length)
199 throws IOException {
200 return buffer.setBytes(index, in, length);
201 }
202
203 @Override
204 public void writeByte(int value) {
205 ensureWritableBytes(1);
206 super.writeByte(value);
207 }
208
209 @Override
210 public void writeShort(int value) {
211 ensureWritableBytes(2);
212 super.writeShort(value);
213 }
214
215 @Override
216 public void writeMedium(int value) {
217 ensureWritableBytes(3);
218 super.writeMedium(value);
219 }
220
221 @Override
222 public void writeInt(int value) {
223 ensureWritableBytes(4);
224 super.writeInt(value);
225 }
226
227 @Override
228 public void writeLong(long value) {
229 ensureWritableBytes(8);
230 super.writeLong(value);
231 }
232
233 @Override
234 public void writeBytes(byte[] src, int srcIndex, int length) {
235 ensureWritableBytes(length);
236 super.writeBytes(src, srcIndex, length);
237 }
238
239 @Override
240 public void writeBytes(ChannelBuffer src, int srcIndex, int length) {
241 ensureWritableBytes(length);
242 super.writeBytes(src, srcIndex, length);
243 }
244
245 @Override
246 public void writeBytes(ByteBuffer src) {
247 ensureWritableBytes(src.remaining());
248 super.writeBytes(src);
249 }
250
251 @Override
252 public int writeBytes(InputStream in, int length) throws IOException {
253 ensureWritableBytes(length);
254 return super.writeBytes(in, length);
255 }
256
257 @Override
258 public int writeBytes(ScatteringByteChannel in, int length)
259 throws IOException {
260 ensureWritableBytes(length);
261 return super.writeBytes(in, length);
262 }
263
264 @Override
265 public void writeZero(int length) {
266 ensureWritableBytes(length);
267 super.writeZero(length);
268 }
269
270 public ChannelBuffer duplicate() {
271 return new DuplicatedChannelBuffer(this);
272 }
273
274 public ChannelBuffer copy(int index, int length) {
275 DynamicChannelBuffer copiedBuffer = new DynamicChannelBuffer(order(), Math.max(length, 64), factory());
276 copiedBuffer.buffer = buffer.copy(index, length);
277 copiedBuffer.setIndex(0, length);
278 return copiedBuffer;
279 }
280
281 public ChannelBuffer slice(int index, int length) {
282 if (index == 0) {
283 if (length == 0) {
284 return ChannelBuffers.EMPTY_BUFFER;
285 }
286 return new TruncatedChannelBuffer(this, length);
287 } else {
288 if (length == 0) {
289 return ChannelBuffers.EMPTY_BUFFER;
290 }
291 return new SlicedChannelBuffer(this, index, length);
292 }
293 }
294
295 public ByteBuffer toByteBuffer(int index, int length) {
296 return buffer.toByteBuffer(index, length);
297 }
298 }