1   /*
2    *   Copyright 2004 The Apache Software Foundation
3    *
4    *   Licensed under the Apache License, Version 2.0 (the "License");
5    *   you may not use this file except in compliance with the License.
6    *   You may obtain a copy of the License at
7    *
8    *       http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *   Unless required by applicable law or agreed to in writing, software
11   *   distributed under the License is distributed on an "AS IS" BASIS,
12   *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *   See the License for the specific language governing permissions and
14   *   limitations under the License.
15   *
16   */
17  package org.apache.asn1.ber.digester ;
18  
19  
20  import junit.framework.TestCase;
21  import org.apache.asn1.ber.TypeClass;
22  
23  import java.net.URL;
24  import java.net.URLClassLoader;
25  import java.nio.ByteBuffer;
26  import java.util.EmptyStackException;
27  
28  
29  /***
30   * A test case for the BERDigester.
31   *
32   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
33   * @version $Rev: 158144 $
34   */
35  public class BERDigesterTest extends TestCase
36  {
37      BERDigester digester ;
38  
39  
40      /***
41       * Sets up the decoder rulesBase system.
42       *
43       * @throws Exception
44       */
45      public void setUp() throws Exception
46      {
47          super.setUp();
48  
49          digester = new BERDigester() ;
50      }
51  
52  
53      /***
54       * Clears and nulls out the rulesBase.
55       *
56       * @throws Exception
57       */
58      public void tearDown() throws Exception
59      {
60          super.tearDown();
61  
62          digester.clear() ;
63          digester = null ;
64      }
65  
66  
67      /***
68       * Tests the BERDigester.addRule(int[],Rule) method.
69       */
70      public void testAddRule() throws Exception
71      {
72          int[] pat0 = { 1, 2, 3 } ;
73          MockRule rule0 = new MockRule() ;
74  
75          digester.addRule( pat0, rule0 ) ;
76      }
77  
78  
79      /***
80       * Tests the BERDigester.setRules(Rules) method.
81       */
82      public void testSetRules() throws Exception
83      {
84          RulesBase rules = new RulesBase() ;
85          digester.setRules( rules ) ;
86          assertSame( rules.getDigester(), digester ) ;
87      }
88  
89  
90      /***
91       * Tests the BERDigester.getRules() method.
92       */
93      public void testGetRules() throws Exception
94      {
95          Rules rules = digester.getRules() ;
96          assertNotNull( rules ) ;
97          assertTrue( rules.rules().isEmpty() ) ;
98      }
99  
100 
101     /***
102      * Tests the BERDigester.getCount() method.
103      */
104     public void testGetCount() throws Exception
105     {
106         assertEquals( 0, digester.getCount() ) ;
107     }
108 
109 
110     /***
111      * Tests the BERDigester.peek() method.
112      */
113     public void testPeek() throws Exception
114     {
115         try
116         {
117             digester.peek() ;
118         }
119         catch( EmptyStackException e )
120         {
121             assertNotNull( e ) ;
122             return ;
123         }
124 
125         fail( "should never reach this line" ) ;
126     }
127 
128 
129     /***
130      * Tests the BERDigester.peek(int) method.
131      */
132     public void testPeekint() throws Exception
133     {
134         try
135         {
136             digester.peek() ;
137         }
138         catch( EmptyStackException e )
139         {
140             assertNotNull( e ) ;
141         }
142 
143         try
144         {
145             digester.peek( -1 ) ;
146         }
147         catch( IndexOutOfBoundsException e )
148         {
149             assertNotNull( e ) ;
150         }
151 
152         try
153         {
154             digester.peek( Integer.MAX_VALUE ) ;
155         }
156         catch( EmptyStackException e )
157         {
158             assertNotNull( e ) ;
159         }
160 
161         try
162         {
163             digester.peek( Integer.MIN_VALUE ) ;
164         }
165         catch( IndexOutOfBoundsException e )
166         {
167             assertNotNull( e ) ;
168         }
169     }
170 
171 
172     /***
173      * Tests the BERDigester.pop() method.
174      */
175     public void testPop() throws Exception
176     {
177         try
178         {
179             digester.pop() ;
180         }
181         catch( EmptyStackException e )
182         {
183             assertNotNull( e ) ;
184             return ;
185         }
186 
187         fail( "should never reach this line" ) ;
188     }
189 
190 
191     /***
192      * Tests the BERDigester.push(Object) method.
193      */
194     public void testPush() throws Exception
195     {
196         Object o0 = new Object() ;
197         Object o1 = new Object() ;
198         Object o2 = new Object() ;
199 
200         try
201         {
202             digester.pop() ;
203             fail( "should not get here" ) ;
204         }
205         catch( EmptyStackException e )
206         {
207             assertNotNull( e ) ;
208         }
209 
210         digester.push( o0 ) ;
211         assertSame( o0, digester.peek() ) ;
212         assertSame( o0, digester.peek( 0 ) ) ;
213 
214         digester.push( o1 ) ;
215         assertSame( o1, digester.peek() ) ;
216         assertSame( o1, digester.peek( 0 ) ) ;
217         assertSame( o0, digester.peek( 1 ) ) ;
218 
219         digester.push( o2 ) ;
220         assertSame( o2, digester.peek() ) ;
221         assertSame( o2, digester.peek( 0 ) ) ;
222         assertSame( o1, digester.peek( 1 ) ) ;
223         assertSame( o0, digester.peek( 2 ) ) ;
224 
225         assertSame( o2, digester.pop() ) ;
226         assertSame( o1, digester.pop() ) ;
227         assertSame( o0, digester.pop() ) ;
228 
229         try
230         {
231             digester.pop() ;
232             fail( "should not get here" ) ;
233         }
234         catch( EmptyStackException e )
235         {
236             assertNotNull( e ) ;
237         }
238     }
239 
240 
241     /***
242      * Tests the BERDigester.GetRoot() method.
243      */
244     public void testGetRoot() throws Exception
245     {
246         Object o0 = new Object() ;
247         Object o1 = new Object() ;
248         Object o2 = new Object() ;
249 
250         try
251         {
252             digester.pop() ;
253             fail( "should not get here" ) ;
254         }
255         catch( EmptyStackException e )
256         {
257             assertNotNull( e ) ;
258         }
259 
260         digester.push( o0 ) ;
261         assertSame( o0, digester.getRoot() ) ;
262 
263         digester.push( o1 ) ;
264         assertSame( o0, digester.getRoot() ) ;
265 
266         digester.push( o2 ) ;
267 
268         assertSame( o2, digester.pop() ) ;
269         assertSame( o1, digester.pop() ) ;
270         assertSame( o0, digester.pop() ) ;
271 
272         try
273         {
274             digester.pop() ;
275             fail( "should not get here" ) ;
276         }
277         catch( EmptyStackException e )
278         {
279             assertNotNull( e ) ;
280         }
281 
282         assertSame( o0, digester.getRoot() ) ;
283     }
284 
285 
286     /***
287      * Tests the BERDigester.getTopTag() method.
288      */
289     public void testGetTopTag() throws Exception
290     {
291         assertEquals( BERDigester.NO_TOP_TAG, digester.getTopTag() ) ;
292         digester.decode( ByteBuffer.wrap( new byte[] { (byte) 3} ) ) ;
293         assertFalse( BERDigester.NO_TOP_TAG == digester.getTopTag() ); ;
294     }
295 
296 
297     /***
298      * Tests the BERDigester.getClassLoader() method.
299      */
300     public void testGetClassLoader() throws Exception
301     {
302         assertSame( BERDigester.class.getClassLoader(), digester.getClassLoader() ) ;
303     }
304 
305 
306     /***
307      * Tests the BERDigester.setClassLoader() method.
308      */
309     public void testSetClassLoader() throws Exception
310     {
311         assertSame( BERDigester.class.getClassLoader(), digester.getClassLoader() ) ;
312         URL[] urls = { new URL( "file:///." ) } ;
313         ClassLoader cl = new URLClassLoader( urls ) ;
314         digester.setClassLoader( cl ) ;
315         assertSame( cl, digester.getClassLoader() ) ;
316     }
317 
318 
319     /***
320      * Tests the BERDigester.getUseContextClassLoader() method.
321      */
322     public void testGetUseContextClassLoader() throws Exception
323     {
324         assertSame( BERDigester.class.getClassLoader(), digester.getClassLoader() ) ;
325         assertFalse( digester.getUseContextClassLoader() ) ;
326     }
327 
328 
329     /***
330      * Tests the BERDigester.setUseContextClassLoader() method.
331      */
332     public void testSetUseContextClassLoader() throws Exception
333     {
334         digester.setUseContextClassLoader( true ) ;
335         assertTrue( digester.getUseContextClassLoader() ) ;
336         assertSame( Thread.currentThread().getContextClassLoader(),
337                 digester.getClassLoader() ) ;
338         Thread.currentThread().setContextClassLoader( null ) ;
339         assertSame( BERDigester.class.getClassLoader(), digester.getClassLoader() ) ;
340     }
341 
342 
343     // ------------------------------------------------------------------------
344     // test the event fireing routines that trigger rules
345     // ------------------------------------------------------------------------
346 
347 
348     /***
349      * Tests the BERDigester.fireTagEvent(int,boolean,TypeClass) method.
350      */
351     public void testFireTagEvent() throws Exception
352     {
353         digester.fireTagEvent( 0, true, TypeClass.UNIVERSAL ) ;
354 
355         int[] pat0 = { 0x10000000 } ;
356         CollectorRule rule0 = new CollectorRule() ;
357         digester.addRule( pat0, rule0 ) ;
358         ByteBuffer buf = ByteBuffer.allocate( 1 ) ;
359         buf.put( ( byte ) 0x10 ) ;
360         buf.flip() ;
361 
362         // Nothing should have fired yet
363         assertFalse( rule0.tagFired ) ;
364         assertFalse( rule0.lengthFired ) ;
365         assertFalse( rule0.valueFired ) ;
366         assertFalse( rule0.hasFinished ) ;
367 
368         digester.decode( buf ) ;
369         assertTrue( rule0.tagFired ) ;
370         assertEquals( 16, rule0.id ) ;
371         assertEquals( TypeClass.UNIVERSAL, rule0.typeClass ) ;
372         assertEquals( true, rule0.isPrimitive ) ;
373         assertFalse( rule0.lengthFired ) ;
374         assertFalse( rule0.valueFired ) ;
375         assertFalse( rule0.hasFinished ) ;
376         assertEquals( 0x10000000, digester.getTopTag() ) ;
377     }
378 
379 
380     /***
381      * Tests the BERDigester.fireLengthEvent(int) method.
382      */
383     public void testFireLengthEvent() throws Exception
384     {
385         digester.fireLengthEvent( 0 ) ;
386 
387         int[] pat0 = { 0x10000000 } ;
388         CollectorRule rule0 = new CollectorRule() ;
389         digester.addRule( pat0, rule0 ) ;
390         ByteBuffer buf = ByteBuffer.allocate( 1 ) ;
391         buf.put( ( byte ) 0x10 ) ;
392         buf.flip() ;
393 
394         // Nothing should have fired yet
395         assertFalse( rule0.tagFired ) ;
396         assertFalse( rule0.lengthFired ) ;
397         assertFalse( rule0.valueFired ) ;
398         assertFalse( rule0.hasFinished ) ;
399 
400         digester.decode( buf ) ;
401         assertTrue( rule0.tagFired ) ;
402         assertEquals( 16, rule0.id ) ;
403         assertEquals( TypeClass.UNIVERSAL, rule0.typeClass ) ;
404         assertEquals( true, rule0.isPrimitive ) ;
405         assertFalse( rule0.lengthFired ) ;
406         assertFalse( rule0.valueFired ) ;
407         assertFalse( rule0.hasFinished ) ;
408         assertEquals( 0x10000000, digester.getTopTag() ) ;
409     }
410 
411 
412     /***
413      * Tests the BERDigester.fireValueEvent(ByteBuffer) method.
414      */
415     public void testFireValueEvent() throws Exception
416     {
417         digester.fireValueEvent( ByteBuffer.allocate( 0 ) ) ;
418 
419         int[] pat0 = { 0x10000000 } ;
420         CollectorRule rule0 = new CollectorRule() ;
421         digester.addRule( pat0, rule0 ) ;
422         ByteBuffer buf = ByteBuffer.allocate( 1 ) ;
423         buf.put( ( byte ) 0x10 ) ;
424         buf.flip() ;
425 
426         // Nothing should have fired yet
427         assertFalse( rule0.tagFired ) ;
428         assertFalse( rule0.lengthFired ) ;
429         assertFalse( rule0.valueFired ) ;
430         assertFalse( rule0.hasFinished ) ;
431 
432         digester.decode( buf ) ;
433         assertTrue( rule0.tagFired ) ;
434         assertEquals( 16, rule0.id ) ;
435         assertEquals( TypeClass.UNIVERSAL, rule0.typeClass ) ;
436         assertEquals( true, rule0.isPrimitive ) ;
437         assertFalse( rule0.lengthFired ) ;
438         assertFalse( rule0.valueFired ) ;
439         assertFalse( rule0.hasFinished ) ;
440         assertEquals( 0x10000000, digester.getTopTag() ) ;
441 
442         buf.rewind() ;
443         buf.put( ( byte ) 0x02 ) ;
444         buf.flip() ;
445         digester.decode( buf ) ;
446         assertTrue( rule0.tagFired ) ;
447         assertEquals( 2, rule0.length ) ;
448         assertTrue( rule0.lengthFired ) ;
449         assertFalse( rule0.valueFired ) ;
450         assertFalse( rule0.hasFinished ) ;
451         assertEquals( 0x10000000, digester.getTopTag() ) ;
452 
453         buf.rewind() ;
454         buf.put( ( byte ) 0x07 ) ;
455         buf.flip() ;
456         digester.decode( buf ) ;
457         assertTrue( rule0.tagFired ) ;
458         assertEquals( 2, rule0.length ) ;
459         assertTrue( rule0.lengthFired ) ;
460         assertTrue( rule0.valueFired ) ;
461         assertFalse( rule0.hasFinished ) ;
462         assertEquals( 0x10000000, digester.getTopTag() ) ;
463         assertEquals( buf.get(0), rule0.buf.get(0) ) ;
464     }
465 
466 
467     /***
468      * Tests the BERDecoder.fireFinishEvent() methods.
469      */
470     public void testFireFinishEvent() throws Exception
471     {
472         int[] pat0 = { 0x10000000 } ;
473         CollectorRule rule0 = new CollectorRule() ;
474         digester.addRule( pat0, rule0 ) ;
475         ByteBuffer buf = ByteBuffer.allocate( 1 ) ;
476         buf.put( ( byte ) 0x10 ) ;
477         buf.flip() ;
478 
479         // Nothing should have fired yet
480         assertFalse( rule0.tagFired ) ;
481         assertFalse( rule0.lengthFired ) ;
482         assertFalse( rule0.valueFired ) ;
483         assertFalse( rule0.hasFinished ) ;
484 
485         digester.decode( buf ) ;
486         assertTrue( rule0.tagFired ) ;
487         assertEquals( 16, rule0.id ) ;
488         assertEquals( TypeClass.UNIVERSAL, rule0.typeClass ) ;
489         assertEquals( true, rule0.isPrimitive ) ;
490         assertFalse( rule0.lengthFired ) ;
491         assertFalse( rule0.valueFired ) ;
492         assertFalse( rule0.hasFinished ) ;
493         assertEquals( 0x10000000, digester.getTopTag() ) ;
494 
495         buf.rewind() ;
496         buf.put( ( byte ) 0x02 ) ;
497         buf.flip() ;
498         digester.decode( buf ) ;
499         assertTrue( rule0.tagFired ) ;
500         assertEquals( 2, rule0.length ) ;
501         assertTrue( rule0.lengthFired ) ;
502         assertFalse( rule0.valueFired ) ;
503         assertFalse( rule0.hasFinished ) ;
504         assertEquals( 0x10000000, digester.getTopTag() ) ;
505 
506         buf.rewind() ;
507         buf.put( ( byte ) 0x07 ) ;
508         buf.flip() ;
509         digester.decode( buf ) ;
510         assertTrue( rule0.tagFired ) ;
511         assertEquals( 2, rule0.length ) ;
512         assertTrue( rule0.lengthFired ) ;
513         assertTrue( rule0.valueFired ) ;
514         assertFalse( rule0.hasFinished ) ;
515         assertEquals( 0x10000000, digester.getTopTag() ) ;
516         assertEquals( buf.get(0), rule0.buf.get(0) ) ;
517 
518         buf.rewind() ;
519         buf.put( ( byte ) 0x09 ) ;
520         buf.flip() ;
521         digester.decode( buf ) ;
522         assertTrue( rule0.tagFired ) ;
523         assertEquals( 2, rule0.length ) ;
524         assertTrue( rule0.lengthFired ) ;
525         assertTrue( rule0.valueFired ) ;
526         assertTrue( rule0.hasFinished ) ;
527         assertEquals( BERDigester.NO_TOP_TAG, digester.getTopTag() ) ;
528         assertEquals( buf.get(0), rule0.buf.get(0) ) ;
529     }
530 
531 
532     /***
533      * Tests the when rules throw errors.
534      */
535     public void testErrorOnTag() throws Exception
536     {
537         int[] pat0 = { 0x10000000 } ;
538         ErrorRule rule0 = new ErrorRule() ;
539         digester.addRule( pat0, rule0 ) ;
540         rule0.throwErrors() ;
541 
542         ByteBuffer buf = ByteBuffer.allocate( 1 ) ;
543         buf.put( ( byte ) 0x10 ) ;
544         buf.flip() ;
545 
546         try
547         {
548             digester.decode( buf ) ;
549         }
550         catch( Error e )
551         {
552             assertNotNull( e ) ;
553             return ;
554         }
555 
556         fail( "should never get here" ) ;
557     }
558 
559 
560     public void testErrorOnLength() throws Exception
561     {
562         int[] pat0 = { 0x10000000 } ;
563         ErrorRule rule0 = new ErrorRule() ;
564         digester.addRule( pat0, rule0 ) ;
565 
566         ByteBuffer buf = ByteBuffer.allocate( 1 ) ;
567         buf.put( ( byte ) 0x10 ) ;
568         buf.flip() ;
569 
570         digester.decode( buf ) ;
571 
572         buf.rewind() ;
573         buf.put( ( byte ) 0x02 ) ;
574         buf.flip() ;
575 
576         rule0.throwErrors() ;
577         try
578         {
579             digester.decode( buf ) ;
580         }
581         catch( Error e )
582         {
583             assertNotNull( e ) ;
584             return ;
585         }
586 
587         fail( "should never get here" ) ;
588     }
589 
590 
591     public void testErrorOnValue() throws Exception
592     {
593         int[] pat0 = { 0x10000000 } ;
594         ErrorRule rule0 = new ErrorRule() ;
595         digester.addRule( pat0, rule0 ) ;
596 
597         ByteBuffer buf = ByteBuffer.allocate( 1 ) ;
598         buf.put( ( byte ) 0x10 ) ;
599         buf.flip() ;
600 
601         digester.decode( buf ) ;
602 
603         buf.rewind() ;
604         buf.put( ( byte ) 0x02 ) ;
605         buf.flip() ;
606 
607         digester.decode( buf ) ;
608 
609         buf.rewind() ;
610         buf.put( ( byte ) 0x02 ) ;
611         buf.flip() ;
612 
613         rule0.throwErrors() ;
614         try
615         {
616             digester.decode( buf ) ;
617         }
618         catch( Error e )
619         {
620             assertNotNull( e ) ;
621             return ;
622         }
623 
624         fail( "should never get here" ) ;
625     }
626 
627 
628     public void testErrorOnFinish() throws Exception
629     {
630         int[] pat0 = { 0x10000000 } ;
631         ErrorRule rule0 = new ErrorRule() ;
632         digester.addRule( pat0, rule0 ) ;
633 
634         ByteBuffer buf = ByteBuffer.allocate( 1 ) ;
635         buf.put( ( byte ) 0x10 ) ;
636         buf.flip() ;
637 
638         digester.decode( buf ) ;
639 
640         buf.rewind() ;
641         buf.put( ( byte ) 0x02 ) ;
642         buf.flip() ;
643 
644         digester.decode( buf ) ;
645 
646         buf.rewind() ;
647         buf.put( ( byte ) 0x07 ) ;
648         buf.flip() ;
649 
650         digester.decode( buf ) ;
651 
652         buf.rewind() ;
653         buf.put( ( byte ) 0x09 ) ;
654         buf.flip() ;
655 
656         rule0.throwErrorOnFinish() ;
657         try
658         {
659             digester.decode( buf ) ;
660         }
661         catch( Error e )
662         {
663             assertNotNull( e ) ;
664             return ;
665         }
666 
667         fail( "should never get here" ) ;
668     }
669 
670 
671     /***
672      * Tests the when rules throw errors.
673      */
674     public void testExceptionOnTag() throws Exception
675     {
676         int[] pat0 = { 0x10000000 } ;
677         ExceptionRule rule0 = new ExceptionRule() ;
678         digester.addRule( pat0, rule0 ) ;
679         rule0.throwErrors() ;
680 
681         ByteBuffer buf = ByteBuffer.allocate( 1 ) ;
682         buf.put( ( byte ) 0x10 ) ;
683         buf.flip() ;
684 
685         try
686         {
687             digester.decode( buf ) ;
688         }
689         catch( RuntimeException e )
690         {
691             assertNotNull( e ) ;
692             return ;
693         }
694 
695         fail( "should never get here" ) ;
696     }
697 
698 
699     public void testExceptionOnLength() throws Exception
700     {
701         int[] pat0 = { 0x10000000 } ;
702         ExceptionRule rule0 = new ExceptionRule() ;
703         digester.addRule( pat0, rule0 ) ;
704 
705         ByteBuffer buf = ByteBuffer.allocate( 1 ) ;
706         buf.put( ( byte ) 0x10 ) ;
707         buf.flip() ;
708 
709         digester.decode( buf ) ;
710 
711         buf.rewind() ;
712         buf.put( ( byte ) 0x02 ) ;
713         buf.flip() ;
714 
715         rule0.throwErrors() ;
716         try
717         {
718             digester.decode( buf ) ;
719         }
720         catch( RuntimeException e )
721         {
722             assertNotNull( e ) ;
723             return ;
724         }
725 
726         fail( "should never get here" ) ;
727     }
728 
729 
730     public void testExceptionOnValue() throws Exception
731     {
732         int[] pat0 = { 0x10000000 } ;
733         ExceptionRule rule0 = new ExceptionRule() ;
734         digester.addRule( pat0, rule0 ) ;
735 
736         ByteBuffer buf = ByteBuffer.allocate( 1 ) ;
737         buf.put( ( byte ) 0x10 ) ;
738         buf.flip() ;
739 
740         digester.decode( buf ) ;
741 
742         buf.rewind() ;
743         buf.put( ( byte ) 0x02 ) ;
744         buf.flip() ;
745 
746         digester.decode( buf ) ;
747 
748         buf.rewind() ;
749         buf.put( ( byte ) 0x02 ) ;
750         buf.flip() ;
751 
752         rule0.throwErrors() ;
753         try
754         {
755             digester.decode( buf ) ;
756         }
757         catch( RuntimeException e )
758         {
759             assertNotNull( e ) ;
760             return ;
761         }
762 
763         fail( "should never get here" ) ;
764     }
765 
766 
767     public void testExceptionOnFinish() throws Exception
768     {
769         int[] pat0 = { 0x10000000 } ;
770         ExceptionRule rule0 = new ExceptionRule() ;
771         digester.addRule( pat0, rule0 ) ;
772 
773         ByteBuffer buf = ByteBuffer.allocate( 1 ) ;
774         buf.put( ( byte ) 0x10 ) ;
775         buf.flip() ;
776 
777         digester.decode( buf ) ;
778 
779         buf.rewind() ;
780         buf.put( ( byte ) 0x02 ) ;
781         buf.flip() ;
782 
783         digester.decode( buf ) ;
784 
785         buf.rewind() ;
786         buf.put( ( byte ) 0x07 ) ;
787         buf.flip() ;
788 
789         digester.decode( buf ) ;
790 
791         buf.rewind() ;
792         buf.put( ( byte ) 0x09 ) ;
793         buf.flip() ;
794 
795         rule0.throwErrorOnFinish() ;
796         try
797         {
798             digester.decode( buf ) ;
799         }
800         catch( RuntimeException e )
801         {
802             assertNotNull( e ) ;
803             return ;
804         }
805 
806         fail( "should never get here" ) ;
807     }
808 
809 
810     public void testFullTlv() throws Exception
811     {
812         int[] pat0 = { 0x10000000 } ;
813         int[] pat1 = { 0x11000000 } ;
814         CollectorRule rule0 = new CollectorRule() ;
815         CollectorRule rule1 = new CollectorRule() ;
816         digester.addRule( pat0, rule0 ) ;
817         digester.addRule( pat1, rule1 ) ;
818         byte[] bites = { 0x10, 0x02, 0x07, 0x09 } ;
819         ByteBuffer buf = ByteBuffer.wrap( bites ) ;
820         digester.decode( buf ) ;
821     }
822 
823 
824     public void testNestedTlvs() throws Exception
825     {
826         int[] pat0 = { 0x14000000, 0x10000000 } ;
827         int[] pat1 = { 0x11000000 } ;
828         CollectorRule rule0 = new CollectorRule() ;
829         CollectorRule rule1 = new CollectorRule() ;
830         digester.addRule( pat0, rule0 ) ;
831         digester.addRule( pat1, rule1 ) ;
832         byte[] bites = {
833             0x34, 0x04,                 // constructed id = 20 w/ 4 byte value
834             0x10, 0x02, 0x07, 0x09      // primitive id = 16 w/ 2 byte value
835         } ;
836         ByteBuffer buf = ByteBuffer.wrap( bites ) ;
837         digester.decode( buf ) ;
838     }
839 
840 
841     public void testNestedTlvsWithErrors() throws Exception
842     {
843         int[] pat0 = { 0x14000000, 0x10000000 } ;
844         int[] pat1 = { 0x14000000 } ;
845         ErrorRule rule0 = new ErrorRule() ;
846         ErrorRule rule1 = new ErrorRule() ;
847         digester.addRule( pat0, rule0 ) ;
848         digester.addRule( pat1, rule1 ) ;
849         byte[] bites = {
850             0x34, 0x04,                 // constructed id = 20 w/ 4 byte value
851             0x10, 0x02, 0x07            // primitive id = 16 w/ 2 byte value
852             // last byte missing
853         } ;
854         ByteBuffer buf = ByteBuffer.wrap( bites ) ;
855         digester.decode( buf ) ;
856 
857         rule1.throwErrorOnFinish() ;
858         buf = ByteBuffer.allocate( 1 ) ;
859         buf.put( 0, ( byte ) 0x09 ) ;
860 
861         try
862         {
863             digester.decode( buf ) ;
864         }
865         catch( Error e )
866         {
867             return ;
868         }
869 
870         fail( "should never get here" ) ;
871     }
872 
873 
874     class MockRule extends AbstractRule {}
875 
876 
877     class CollectorRule extends AbstractRule
878     {
879         boolean tagFired = false ;
880         boolean lengthFired = false ;
881         boolean valueFired = false ;
882         int id = -1 ;
883         boolean isPrimitive = false ;
884         TypeClass typeClass = null ;
885         int length = -1 ;
886         ByteBuffer buf = null ;
887         boolean hasFinished = false ;
888 
889         public void tag( int id, boolean isPrimitive, TypeClass typeClass )
890         {
891             this.id = id ;
892             this.typeClass = typeClass ;
893             this.isPrimitive = isPrimitive ;
894             this.tagFired = true ;
895         }
896 
897         public void length( int length )
898         {
899             this.length = length ;
900             this.lengthFired = true ;
901         }
902 
903         public void value( ByteBuffer buf )
904         {
905             this.buf = buf ;
906             this.valueFired = true ;
907         }
908 
909         public void finish()
910         {
911             this.hasFinished = true ;
912         }
913     }
914 
915 
916     class ErrorRule extends AbstractRule
917     {
918         private boolean doThrow = false ;
919         private boolean doThrowOnFinish = false ;
920 
921         public void throwErrors()
922         {
923             doThrow = true ;
924         }
925 
926         public void throwErrorOnFinish()
927         {
928             doThrowOnFinish = true ;
929         }
930 
931         public void tag( int id, boolean isPrimitive, TypeClass typeClass )
932         {
933             if ( doThrow )
934             {
935                 throw new Error() ;
936             }
937         }
938 
939         public void length( int length )
940         {
941             if ( doThrow )
942             {
943                 throw new Error() ;
944             }
945         }
946 
947         public void value( ByteBuffer buf )
948         {
949             if ( doThrow )
950             {
951                 throw new Error() ;
952             }
953         }
954 
955         public void finish()
956         {
957             if ( doThrowOnFinish )
958             {
959                 throw new Error() ;
960             }
961         }
962     }
963 
964 
965     class ExceptionRule extends AbstractRule
966     {
967         private boolean doThrow = false ;
968         private boolean doThrowOnFinish = false ;
969 
970         public void throwErrors()
971         {
972             doThrow = true ;
973         }
974 
975         public void throwErrorOnFinish()
976         {
977             doThrowOnFinish = true ;
978         }
979 
980         public void tag( int id, boolean isPrimitive, TypeClass typeClass )
981         {
982             if ( doThrow )
983             {
984                 throw new RuntimeException() ;
985             }
986         }
987 
988         public void length( int length )
989         {
990             if ( doThrow )
991             {
992                 throw new RuntimeException() ;
993             }
994         }
995 
996         public void value( ByteBuffer buf )
997         {
998             if ( doThrow )
999             {
1000                 throw new RuntimeException() ;
1001             }
1002         }
1003 
1004         public void finish()
1005         {
1006             if ( doThrowOnFinish )
1007             {
1008                 throw new RuntimeException() ;
1009             }
1010         }
1011     }
1012 }