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