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 void expand(CompositeByteArray cba, int minSize);
48 }
49
50
51
52
53
54 public static class NopExpander implements Expander {
55 public void expand(CompositeByteArray cba, int minSize) {
56
57 }
58 }
59
60
61
62
63
64
65 public static class ChunkedExpander implements Expander {
66
67 private final ByteArrayFactory baf;
68
69 private final int newComponentSize;
70
71 public ChunkedExpander(ByteArrayFactory baf, int newComponentSize) {
72 this.baf = baf;
73 this.newComponentSize = newComponentSize;
74 }
75
76 public void expand(CompositeByteArray cba, int minSize) {
77 int remaining = minSize;
78 while (remaining > 0) {
79 ByteArray component = baf.create(newComponentSize);
80 cba.addLast(component);
81 remaining -= newComponentSize;
82 }
83 }
84
85 }
86
87
88
89
90 public interface Flusher {
91
92 void flush(ByteArray ba);
93 }
94
95
96
97
98 private final Expander expander;
99
100
101
102
103 private final Flusher flusher;
104
105
106
107
108
109 private final boolean autoFlush;
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124 public CompositeByteArrayRelativeWriter(CompositeByteArray cba, Expander expander, Flusher flusher,
125 boolean autoFlush) {
126 super(cba);
127 this.expander = expander;
128 this.flusher = flusher;
129 this.autoFlush = autoFlush;
130 }
131
132 private void prepareForAccess(int size) {
133 int underflow = cursor.getIndex() + size - last();
134 if (underflow > 0) {
135 expander.expand(cba, underflow);
136 }
137 }
138
139
140
141
142 public void flush() {
143 flushTo(cursor.getIndex());
144 }
145
146
147
148
149
150
151 public void flushTo(int index) {
152 ByteArray removed = cba.removeTo(index);
153 flusher.flush(removed);
154 }
155
156
157
158
159 public void skip(int length) {
160 cursor.skip(length);
161 }
162
163 @Override
164 protected void cursorPassedFirstComponent() {
165 if (autoFlush) {
166 flushTo(cba.first() + cba.getFirst().length());
167 }
168 }
169
170
171
172
173 public void put(byte b) {
174 prepareForAccess(1);
175 cursor.put(b);
176 }
177
178
179
180
181 public void put(IoBuffer bb) {
182 prepareForAccess(bb.remaining());
183 cursor.put(bb);
184 }
185
186
187
188
189 public void putShort(short s) {
190 prepareForAccess(2);
191 cursor.putShort(s);
192 }
193
194
195
196
197 public void putInt(int i) {
198 prepareForAccess(4);
199 cursor.putInt(i);
200 }
201
202
203
204
205 public void putLong(long l) {
206 prepareForAccess(8);
207 cursor.putLong(l);
208 }
209
210
211
212
213 public void putFloat(float f) {
214 prepareForAccess(4);
215 cursor.putFloat(f);
216 }
217
218
219
220
221 public void putDouble(double d) {
222 prepareForAccess(8);
223 cursor.putDouble(d);
224 }
225
226
227
228
229 public void putChar(char c) {
230 prepareForAccess(2);
231 cursor.putChar(c);
232 }
233 }