1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.asn1.ber ;
18
19
20 import junit.framework.TestCase;
21 import org.apache.asn1.codec.DecoderException;
22 import org.apache.asn1.codec.binary.BinaryCodec;
23 import org.apache.asn1.codec.stateful.DecoderCallback;
24 import org.apache.asn1.codec.stateful.DecoderMonitor;
25 import org.apache.asn1.codec.stateful.StatefulDecoder;
26 import org.apache.commons.lang.exception.ExceptionUtils;
27
28 import java.nio.ByteBuffer;
29 import java.util.ArrayList;
30 import java.util.Stack;
31
32
33 /***
34 * Tests the BER decoder.
35 *
36 * @author <a href="mailto:dev@directory.apache.org">
37 * Apache Directory Project</a>
38 * @version $Rev: 158144 $
39 */
40 public abstract class AbstractDecoderTestCase extends TestCase
41 implements BERDecoderCallback, DecoderMonitor
42 {
43 /*** list of encountered TLV's as we recieve completed decode callbacks */
44 protected ArrayList tlvList = new ArrayList() ;
45 /*** the decoder that is constructed every time */
46 protected BERDecoder decoder = null ;
47 /*** value accumulator */
48 ByteBuffer buf = ByteBuffer.allocate(11111) ;
49
50
51
52
53
54 protected void setUp() throws Exception
55 {
56 super.setUp() ;
57 decoder = new BERDecoder() ;
58 decoder.setCallback( this ) ;
59 decoder.setDecoderMonitor( this ) ;
60 }
61
62
63
64
65
66 protected void tearDown() throws Exception
67 {
68 super.tearDown() ;
69 tlvList.clear() ;
70 decoder = null ;
71 }
72
73
74 /***
75 * Constructor for BERDecoderTest.
76 * @param arg0
77 */
78 public AbstractDecoderTestCase( String arg0 )
79 {
80 super( arg0 ) ;
81 }
82
83
84 /***
85 * Fragments an array of bytes into multiple arrays 'attempting' to keep
86 * them the same size however the last fragment will be an array
87 * bites.length%size which may or may not be of the requested fragment size.
88 * However it will never be greater. Use this method to break appart TLV
89 * byte arrays to feed them into the decoder for testing.
90 *
91 * @param bites the bites to fragment
92 * @param size the maximum size of a fragment
93 * @return the array of byte[] fragments
94 */
95 public byte[][] fragment( byte[] bites, int size )
96 {
97 byte[][] fragments = null ;
98
99 if ( size <= 0 )
100 {
101 throw new IllegalArgumentException(
102 "fragment size should be 1 or more but was " + size ) ;
103 }
104
105 int wholeFrags = bites.length/size ;
106 int partialFragSize = bites.length % size ;
107
108
109
110
111 if ( partialFragSize == 0 )
112 {
113 fragments = new byte[wholeFrags][] ;
114 }
115 else
116 {
117 fragments = new byte[wholeFrags+1][] ;
118 fragments[wholeFrags] = new byte[partialFragSize] ;
119 }
120
121 for ( int ii = 0; ii < wholeFrags; ii++ )
122 {
123 fragments[ii] = new byte[size] ;
124 System.arraycopy( bites, ii * size, fragments[ii], 0, size ) ;
125 }
126
127 if ( partialFragSize != 0 )
128 {
129 int srcPos = wholeFrags * size ;
130 byte[] src = fragments[wholeFrags] ;
131 System.arraycopy( bites, srcPos, src, 0, partialFragSize ) ;
132 }
133
134 return fragments ;
135 }
136
137
138 /***
139 * Fragments a byte buffer into multiple buffer 'attempting' to keep
140 * them the same size however the last fragment will be an array
141 * bites.length%size which may or may not be of the requested fragment size.
142 * However it will never be greater. Use this method to break appart TLV
143 * bytes to feed them into the decoder for testing.
144 *
145 * @param bites the bites to fragment
146 * @param size the maximum size of a fragment
147 * @return the buffer fragment
148 */
149 public ByteBuffer[] fragment( ByteBuffer bites, int size )
150 {
151 bites = bites.duplicate() ;
152 ByteBuffer[] fragments = null ;
153
154 if ( size <= 0 )
155 {
156 throw new IllegalArgumentException(
157 "fragment size should be 1 or more but was " + size ) ;
158 }
159
160 int wholeFrags = bites.remaining()/size ;
161 int partialFragSize = bites.remaining() % size ;
162
163
164
165
166 if ( partialFragSize == 0 )
167 {
168 fragments = new ByteBuffer[wholeFrags] ;
169 }
170 else
171 {
172 fragments = new ByteBuffer[wholeFrags+1] ;
173 fragments[wholeFrags] = ByteBuffer.allocate( partialFragSize ) ;
174 }
175
176 for ( int ii = 0; ii < wholeFrags; ii++ )
177 {
178 fragments[ii] = ( ByteBuffer ) bites.slice().limit( size ) ;
179 bites.position( bites.position() + size ) ;
180 }
181
182 if ( partialFragSize != 0 )
183 {
184 fragments[wholeFrags].put( bites ) ;
185 fragments[wholeFrags].flip() ;
186 }
187
188 return fragments ;
189 }
190
191
192 /***
193 * BER decodes a string of 0's and 1's.
194 *
195 * @param bitString a string of ascii 0's and 1's
196 * @return a copy of the decoded tuple or the partially decoded current tlv
197 * @throws DecoderException if there are errors while decoding.
198 */
199 public Tuple decode( String bitString ) throws DecoderException
200 {
201 byte [] bites = BinaryCodec.fromAscii( bitString.getBytes() ) ;
202 ByteBuffer buf = ByteBuffer.wrap( bites ) ;
203 int lastSize = tlvList.size() ;
204 decoder.decode( buf ) ;
205
206 if ( tlvList.isEmpty() || tlvList.size() == lastSize )
207 {
208 return decoder.getCurrentTuple() ;
209 }
210
211 return ( Tuple ) tlvList.get( tlvList.size() - 1 ) ;
212 }
213
214
215 /***
216 * BER decodes a single byte.
217 *
218 * @param bite a single byte to decode
219 * @return a copy of the decoded tuple or the partially decoded current tlv
220 * @throws DecoderException if there are errors while decoding.
221 */
222 public Tuple decode( byte bite ) throws DecoderException
223 {
224 byte [] bites = { bite } ;
225 ByteBuffer buf = ByteBuffer.wrap( bites ) ;
226 int lastSize = tlvList.size() ;
227 decoder.decode( buf ) ;
228
229 if ( tlvList.isEmpty() || tlvList.size() == lastSize )
230 {
231 return decoder.getCurrentTuple() ;
232 }
233
234 return ( Tuple ) tlvList.get( tlvList.size() - 1 ) ;
235 }
236
237
238 /***
239 * BER decodes a byte buffer.
240 *
241 * @param bites a byte buffer to decode
242 * @return a copy of the decoded tuple or the partially decoded current tlv
243 * @throws DecoderException if there are errors while decoding.
244 */
245 public Tuple decode( ByteBuffer bites ) throws DecoderException
246 {
247 int lastSize = tlvList.size() ;
248 decoder.decode( bites ) ;
249
250 if ( tlvList.isEmpty() || tlvList.size() == lastSize )
251 {
252 return decoder.getCurrentTuple() ;
253 }
254
255 return ( Tuple ) tlvList.get( tlvList.size() - 1 ) ;
256 }
257
258
259 /***
260 * First BER encodes then BER decodes a Tuple.
261 *
262 * @param tlv a tuple to encode then decode
263 * @return a copy of the decoded tuple or the partially decoded current tlv
264 * @throws DecoderException if there are errors while decoding
265 */
266 public Tuple decode( Tuple tlv, ByteBuffer value ) throws DecoderException
267 {
268 ArrayList list = new ArrayList() ;
269 list.add( value ) ;
270 ByteBuffer buf = tlv.toEncodedBuffer( list ) ;
271 int lastSize = tlvList.size() ;
272 decoder.decode( buf ) ;
273
274 if ( tlvList.isEmpty() || tlvList.size() == lastSize )
275 {
276 Stack stack = decoder.getTupleStack() ;
277
278 if ( stack.isEmpty() )
279 {
280 return decoder.getCurrentTuple() ;
281 }
282 else
283 {
284 return ( Tuple ) stack.peek() ;
285 }
286 }
287
288 return ( Tuple ) tlvList.get( tlvList.size() - 1 ) ;
289 }
290
291
292 /***
293 * First BER encodes then BER decodes a train of Tuples.
294 *
295 * @param tlvs a tuple array to encode then decode
296 * @return a copy of the decoded tuple or the partially decoded current tlv
297 * @throws DecoderException if there are errors while decoding
298 */
299 public Tuple decode( Tuple[] tlvs, ByteBuffer[] values )
300 throws DecoderException
301 {
302 int lastSize = tlvList.size() ;
303
304 for ( int ii = 0; ii < tlvs.length; ii++ )
305 {
306 decode( tlvs[ii], values[ii] ) ;
307 }
308
309 if ( tlvList.isEmpty() || tlvList.size() == lastSize )
310 {
311 return decoder.getCurrentTuple() ;
312 }
313
314 return ( Tuple ) tlvList.get( tlvList.size() - 1 ) ;
315 }
316
317 public Tuple decode( byte[] pdu ) throws DecoderException
318 {
319 decode( ByteBuffer.wrap( pdu ) ) ;
320 return ( Tuple ) tlvList.get( tlvList.size() - 1 ) ;
321 }
322
323
324
325
326
327 public void tagDecoded( Tuple tlv )
328 {
329 assertTrue( decoder.getCurrentTuple().equals( tlv ) ) ;
330 assertEquals( BERDecoderState.TAG, decoder.getState() ) ;
331 }
332
333
334
335
336
337
338 public void lengthDecoded( Tuple tlv )
339 {
340 assertTrue( decoder.getCurrentTuple().equals( tlv ) ) ;
341 assertEquals( BERDecoderState.LENGTH, decoder.getState() ) ;
342 buf.clear() ;
343 }
344
345
346
347
348
349
350 public void partialValueDecoded( Tuple tlv )
351 {
352 buf.put( tlv.valueChunk ) ;
353 }
354
355
356
357
358
359
360 public void decodeOccurred( StatefulDecoder decoder, Object decoded )
361 {
362 Tuple t = ( Tuple ) decoded ;
363 tlvList.add( t.clone() ) ;
364 assertEquals( BERDecoderState.VALUE, this.decoder.getState() ) ;
365 buf.flip() ;
366 }
367
368
369
370
371
372
373
374 public void callbackOccured( StatefulDecoder decoder, DecoderCallback cb,
375 Object decoded )
376 {
377 assertEquals( this, cb ) ;
378 assertEquals( this.decoder, decoder ) ;
379 Tuple t = ( Tuple ) decoded ;
380 assertNotNull( t ) ;
381 if ( t.isPrimitive )
382 {
383 assertTrue( this.decoder.getCurrentTuple().equals( decoded ) ) ;
384 }
385 }
386
387
388
389
390
391
392
393
394 public void callbackSet( StatefulDecoder decoder, DecoderCallback oldcb,
395 DecoderCallback newcb )
396 {
397 assertEquals( this, newcb ) ;
398 }
399
400
401
402
403
404
405 public void error( StatefulDecoder decoder, Exception exception )
406 {
407 fail( ExceptionUtils.getFullStackTrace( exception ) ) ;
408 }
409
410
411
412
413
414
415 public void fatalError( StatefulDecoder decoder, Exception exception )
416 {
417 fail( ExceptionUtils.getFullStackTrace( exception ) ) ;
418 }
419
420
421
422
423
424
425
426 public void monitorSet( StatefulDecoder decoder, DecoderMonitor oldmon )
427 {
428 assertEquals( this, oldmon ) ;
429 }
430
431
432
433
434
435
436 public void warning( StatefulDecoder decoder, Exception exception )
437 {
438 assertNotNull( exception ) ;
439 }
440 }