1   /*
2    *   Copyright 2004-2005 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;
18  
19  
20  import junit.framework.TestCase;
21  import org.apache.asn1.ber.primitives.UniversalTag;
22  import org.apache.asn1.codec.stateful.EncoderCallback;
23  import org.apache.asn1.codec.stateful.StatefulEncoder;
24  import org.apache.asn1.codec.stateful.StatefulEncoder;
25  import org.apache.asn1.ber.primitives.UniversalTag;
26  import org.apache.asn1.ber.BEREncoder;
27  import org.apache.commons.lang.ArrayUtils;
28  
29  import java.nio.ByteBuffer;
30  import java.util.ArrayList;
31  
32  
33  /***
34   * Tests the BEREncoder for correct operation.
35   *
36   * @author <a href="mailto:dev@directory.apache.org"> Apache Directory
37   *         Project</a> $Rev: 157644 $
38   */
39  public class BEREncoderTest extends TestCase implements EncoderCallback
40  {
41      private BEREncoder encoder = null;
42      private ByteBuffer collector = null;
43  
44  
45      protected void setUp() throws Exception
46      {
47          super.setUp();
48          encoder = new BEREncoder();
49          encoder.setCallback( this );
50          collector = ByteBuffer.wrap( new byte[32] );
51      }
52  
53  
54      protected void tearDown() throws Exception
55      {
56          super.tearDown();
57          encoder.setCallback( null );
58          encoder = null;
59          collector = null;
60      }
61  
62  
63      public void encodeOccurred( StatefulEncoder encoder, Object encoded )
64      {
65          ByteBuffer buf = ( ByteBuffer ) encoded;
66          collector.put( buf );
67      }
68  
69  
70  
71      /***
72       * Produces a primitive tuple and pumps it through the encoder while
73       * listening to the output of the encoder collecting the output bytes into
74       * one buffer.  Then the collected data is compared with the expected
75       * encoded data.
76       */
77      public void testPrimitives()
78      {
79          // prepare tlv and generate an integer tag event
80          Tuple tlv = new Tuple();
81          tlv.setTag( UniversalTag.INTEGER );
82          encoder.tag( tlv );
83  
84          // generate a length event
85          tlv.setLength( 1 );
86          encoder.length( tlv );
87  
88          // generate a value event
89          byte[] value = new byte[] { (byte) 10 };
90          ByteBuffer chunk = ByteBuffer.wrap( value );
91          tlv.setLastValueChunk( chunk );
92          encoder.chunkedValue( tlv, chunk );
93  
94          // not really necessary but here for completeness
95          encoder.finish( tlv );
96  
97          // generate the expected encoded bytes
98          ArrayList list = new ArrayList();
99          list.add( ByteBuffer.wrap( value ) );
100         ByteBuffer buf = tlv.toEncodedBuffer( list );
101         byte[] correctBytes = new byte[buf.remaining()];
102         buf.get( correctBytes );
103 
104         // gather the collected encoded bytes
105         collector.flip();
106         byte[] encodedBytes = new byte[collector.remaining()];
107         collector.get( encodedBytes );
108 
109         // compare the two
110         assertTrue( ArrayUtils.isEquals( correctBytes, encodedBytes ) );
111     }
112 
113 
114     /***
115      * Produces the tlv events for constructed TLV of definate length.
116      */
117     public void testConstructedDefinateLength1()
118     {
119         // prepare top level TLV of sequence with length of 3
120         Tuple top = new Tuple();
121         top.setTag( UniversalTag.SEQUENCE_SEQUENCE_OF, false );
122         encoder.tag( top );
123         top.setLength( 3 );
124         encoder.length( top );
125 
126         // prepare single nested child tlv
127         Tuple tlv = new Tuple();
128         tlv.setTag( UniversalTag.INTEGER );
129         encoder.tag( tlv );
130         tlv.setLength( 1 );
131         encoder.length( tlv );
132         byte[] value = new byte[] { (byte) 10 };
133         ByteBuffer chunk = ByteBuffer.wrap( value );
134         tlv.setLastValueChunk( chunk );
135         encoder.chunkedValue( tlv, chunk );
136         encoder.finish( tlv );
137         encoder.finish( top );
138 
139         // prepare the expected correct sequence of encoded bytes
140         ArrayList list = new ArrayList();
141         ByteBuffer all = ByteBuffer.wrap( new byte[64] ) ;
142         all.put( top.toEncodedBuffer( list ) );
143         list.add( ByteBuffer.wrap( value ) );
144         all.put( tlv.toEncodedBuffer( list ) );
145         all.flip();
146         byte[] correctBytes = new byte[all.remaining()];
147         all.get( correctBytes );
148 
149         // gather the collected encoded bytes
150         collector.flip();
151         byte[] encodedBytes = new byte[collector.remaining()];
152         collector.get( encodedBytes );
153 
154         // compare correct with encoded
155         assertTrue( ArrayUtils.isEquals( correctBytes, encodedBytes ) );
156     }
157 
158 
159     /***
160      * Produces the tlv events for constructed TLV of definate length.
161      */
162     public void testConstructedDefinateLength2()
163     {
164         // prepare top level TLV of sequence with length of 3
165         Tuple top = new Tuple();
166         top.setTag( UniversalTag.SEQUENCE_SEQUENCE_OF, false );
167         encoder.tag( top );
168         top.setLength( 8 );
169         encoder.length( top );
170 
171         // prepare the expected correct sequence of encoded bytes
172         ArrayList list = new ArrayList();
173         ByteBuffer all = ByteBuffer.wrap( new byte[64] ) ;
174         all.put( top.toEncodedBuffer( list ) );
175 
176         // prepare single nested child tlv
177         Tuple tlv = new Tuple();
178         tlv.setTag( UniversalTag.INTEGER );
179         encoder.tag( tlv );
180         tlv.setLength( 1 );
181         encoder.length( tlv );
182         byte[] value = new byte[] { (byte) 10 };
183         ByteBuffer chunk = ByteBuffer.wrap( value );
184         tlv.setLastValueChunk( chunk );
185         encoder.chunkedValue( tlv, chunk );
186         encoder.finish( tlv );
187         list.add( ByteBuffer.wrap( value ) );
188         all.put( tlv.toEncodedBuffer( list ) );
189 
190         tlv.setTag( UniversalTag.INTEGER );
191         encoder.tag( tlv );
192         tlv.setLength( 3 );
193         encoder.length( tlv );
194         value = new byte[] { (byte) 2, 7, 12 };
195         chunk = ByteBuffer.wrap( value );
196         tlv.setLastValueChunk( chunk );
197         encoder.chunkedValue( tlv, chunk );
198         encoder.finish( tlv );
199         encoder.finish( top );
200         list.add( ByteBuffer.wrap( value ) );
201         all.put( tlv.toEncodedBuffer( list ) );
202 
203         // prepare the correct buffers
204         all.flip();
205         byte[] correctBytes = new byte[all.remaining()];
206         all.get( correctBytes );
207 
208         // gather the collected encoded bytes
209         collector.flip();
210         byte[] encodedBytes = new byte[collector.remaining()];
211         collector.get( encodedBytes );
212 
213         // compare correct with encoded
214         assertTrue( ArrayUtils.isEquals( correctBytes, encodedBytes ) );
215     }
216 
217 
218     /***
219      * Produces the tlv events for constructed TLV of definate length.
220      */
221     public void testConstructedIndefiniteLength()
222     {
223         // prepare top level TLV of sequence with length of 3
224         Tuple top = new Tuple();
225         top.setTag( UniversalTag.SEQUENCE_SEQUENCE_OF, false );
226         encoder.tag( top );
227         top.setLength( Length.INDEFINITE );
228         encoder.length( top );
229 
230         // prepare the expected correct sequence of encoded bytes
231         ArrayList list = new ArrayList();
232         ByteBuffer all = ByteBuffer.wrap( new byte[64] ) ;
233         all.put( top.toEncodedBuffer( list ) );
234 
235         // prepare single nested child tlv
236         Tuple tlv = new Tuple();
237         tlv.setTag( UniversalTag.INTEGER );
238         encoder.tag( tlv );
239         tlv.setLength( 1 );
240         encoder.length( tlv );
241         byte[] value = new byte[] { (byte) 10 };
242         ByteBuffer chunk = ByteBuffer.wrap( value );
243         tlv.setLastValueChunk( chunk );
244         encoder.chunkedValue( tlv, chunk );
245         encoder.finish( tlv );
246         list.add( ByteBuffer.wrap( value ) );
247         all.put( tlv.toEncodedBuffer( list ) );
248 
249         tlv.setTag( UniversalTag.INTEGER );
250         encoder.tag( tlv );
251         tlv.setLength( 3 );
252         encoder.length( tlv );
253         value = new byte[] { (byte) 2, 7, 12 };
254         chunk = ByteBuffer.wrap( value );
255         tlv.setLastValueChunk( chunk );
256         encoder.chunkedValue( tlv, chunk );
257         encoder.finish( tlv );
258         encoder.finish( top );
259         list.add( ByteBuffer.wrap( value ) );
260         all.put( tlv.toEncodedBuffer( list ) );
261         all.put( (byte) 0 ).put( (byte) 0 );
262 
263         // prepare the correct buffers
264         all.flip();
265         byte[] correctBytes = new byte[all.remaining()];
266         all.get( correctBytes );
267 
268         // gather the collected encoded bytes
269         collector.flip();
270         byte[] encodedBytes = new byte[collector.remaining()];
271         collector.get( encodedBytes );
272 
273         // compare correct with encoded
274         assertTrue( ArrayUtils.isEquals( correctBytes, encodedBytes ) );
275     }
276 }