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