1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 package org.apache.http.nio.util;
29
30 import java.nio.BufferOverflowException;
31 import java.nio.ByteBuffer;
32
33 import org.apache.http.io.BufferInfo;
34 import org.apache.http.util.Args;
35
36
37
38
39
40
41
42
43
44
45 @SuppressWarnings("deprecation")
46 public class ExpandableBuffer implements BufferInfo, org.apache.http.nio.util.BufferInfo {
47
48 public final static int INPUT_MODE = 0;
49 public final static int OUTPUT_MODE = 1;
50
51 private final ByteBufferAllocator allocator;
52
53 private int mode;
54 protected ByteBuffer buffer = null;
55
56
57
58
59
60
61
62 public ExpandableBuffer(final int bufferSize, final ByteBufferAllocator allocator) {
63 super();
64 Args.notNull(allocator, "ByteBuffer allocator");
65 this.allocator = allocator;
66 this.buffer = allocator.allocate(bufferSize);
67 this.mode = INPUT_MODE;
68 }
69
70
71
72
73
74
75
76
77
78
79 protected int getMode() {
80 return this.mode;
81 }
82
83
84
85
86 protected void setOutputMode() {
87 if (this.mode != OUTPUT_MODE) {
88 this.buffer.flip();
89 this.mode = OUTPUT_MODE;
90 }
91 }
92
93
94
95
96 protected void setInputMode() {
97 if (this.mode != INPUT_MODE) {
98 if (this.buffer.hasRemaining()) {
99 this.buffer.compact();
100 } else {
101 this.buffer.clear();
102 }
103 this.mode = INPUT_MODE;
104 }
105 }
106
107 private void expandCapacity(final int capacity) {
108 final ByteBuffer oldbuffer = this.buffer;
109 this.buffer = allocator.allocate(capacity);
110 oldbuffer.flip();
111 this.buffer.put(oldbuffer);
112 }
113
114
115
116
117
118
119 protected void expand() throws BufferOverflowException {
120 int newCapacity = (this.buffer.capacity() + 1) << 1;
121 if (newCapacity < 0) {
122 final int vmBytes = Long.SIZE >> 3;
123 final int javaBytes = 8;
124 @SuppressWarnings("unused")
125 final int headRoom = (vmBytes >= javaBytes) ? vmBytes : javaBytes;
126
127
128
129
130
131
132
133
134 newCapacity = Integer.MAX_VALUE - headRoom;
135
136 if (newCapacity <= this.buffer.capacity()) {
137 throw new BufferOverflowException();
138 }
139 }
140 expandCapacity(newCapacity);
141 }
142
143
144
145
146 protected void ensureCapacity(final int requiredCapacity) {
147 if (requiredCapacity > this.buffer.capacity()) {
148 expandCapacity(requiredCapacity);
149 }
150 }
151
152
153
154
155
156
157 @Override
158 public int capacity() {
159 return this.buffer.capacity();
160 }
161
162
163
164
165
166
167
168 public boolean hasData() {
169 setOutputMode();
170 return this.buffer.hasRemaining();
171 }
172
173
174
175
176
177
178 @Override
179 public int length() {
180 setOutputMode();
181 return this.buffer.remaining();
182 }
183
184
185
186
187
188
189 @Override
190 public int available() {
191 setInputMode();
192 return this.buffer.remaining();
193 }
194
195
196
197
198 protected void clear() {
199 this.buffer.clear();
200 this.mode = INPUT_MODE;
201 }
202
203 @Override
204 public String toString() {
205 final StringBuilder sb = new StringBuilder();
206 sb.append("[mode=");
207 if (getMode() == INPUT_MODE) {
208 sb.append("in");
209 } else {
210 sb.append("out");
211 }
212 sb.append(" pos=");
213 sb.append(this.buffer.position());
214 sb.append(" lim=");
215 sb.append(this.buffer.limit());
216 sb.append(" cap=");
217 sb.append(this.buffer.capacity());
218 sb.append("]");
219 return sb.toString();
220 }
221
222 }