1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.mina.util.byteaccess;
21
22 import org.apache.mina.core.buffer.IoBuffer;
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41 public class CompositeByteArrayRelativeWriter extends CompositeByteArrayRelativeBase implements IoRelativeWriter {
42
43
44
45
46 public interface Expander {
47
48
49
50
51
52 void expand(CompositeByteArray cba, int minSize);
53 }
54
55
56
57
58
59 public static class NopExpander implements Expander {
60
61
62
63 @Override
64 public void expand(CompositeByteArray cba, int minSize) {
65
66 }
67 }
68
69
70
71
72
73
74 public static class ChunkedExpander implements Expander {
75
76 private final ByteArrayFactory baf;
77
78 private final int newComponentSize;
79
80
81
82
83
84
85
86 public ChunkedExpander(ByteArrayFactory baf, int newComponentSize) {
87 this.baf = baf;
88 this.newComponentSize = newComponentSize;
89 }
90
91
92
93
94 @Override
95 public void expand(CompositeByteArray cba, int minSize) {
96 int remaining = minSize;
97 while (remaining > 0) {
98 ByteArray component = baf.create(newComponentSize);
99 cba.addLast(component);
100 remaining -= newComponentSize;
101 }
102 }
103
104 }
105
106
107
108
109 public interface Flusher {
110
111
112
113
114
115 void flush(ByteArray ba);
116 }
117
118
119
120
121 private final Expander expander;
122
123
124
125
126 private final Flusher flusher;
127
128
129
130
131
132 private final boolean autoFlush;
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147 public CompositeByteArrayRelativeWriter(CompositeByteArray cba, Expander expander, Flusher flusher,
148 boolean autoFlush) {
149 super(cba);
150 this.expander = expander;
151 this.flusher = flusher;
152 this.autoFlush = autoFlush;
153 }
154
155 private void prepareForAccess(int size) {
156 int underflow = cursor.getIndex() + size - last();
157 if (underflow > 0) {
158 expander.expand(cba, underflow);
159 }
160 }
161
162
163
164
165 public void flush() {
166 flushTo(cursor.getIndex());
167 }
168
169
170
171
172
173
174 public void flushTo(int index) {
175 ByteArray removed = cba.removeTo(index);
176 flusher.flush(removed);
177 }
178
179
180
181
182 @Override
183 public void skip(int length) {
184 cursor.skip(length);
185 }
186
187 @Override
188 protected void cursorPassedFirstComponent() {
189 if (autoFlush) {
190 flushTo(cba.first() + cba.getFirst().length());
191 }
192 }
193
194
195
196
197 @Override
198 public void put(byte b) {
199 prepareForAccess(1);
200 cursor.put(b);
201 }
202
203
204
205
206 @Override
207 public void put(IoBuffer bb) {
208 prepareForAccess(bb.remaining());
209 cursor.put(bb);
210 }
211
212
213
214
215 @Override
216 public void putShort(short s) {
217 prepareForAccess(2);
218 cursor.putShort(s);
219 }
220
221
222
223
224 @Override
225 public void putInt(int i) {
226 prepareForAccess(4);
227 cursor.putInt(i);
228 }
229
230
231
232
233 @Override
234 public void putLong(long l) {
235 prepareForAccess(8);
236 cursor.putLong(l);
237 }
238
239
240
241
242 @Override
243 public void putFloat(float f) {
244 prepareForAccess(4);
245 cursor.putFloat(f);
246 }
247
248
249
250
251 @Override
252 public void putDouble(double d) {
253 prepareForAccess(8);
254 cursor.putDouble(d);
255 }
256
257
258
259
260 @Override
261 public void putChar(char c) {
262 prepareForAccess(2);
263 cursor.putChar(c);
264 }
265 }