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