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