View Javadoc
1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one or more
3    *  contributor license agreements.  See the NOTICE file distributed with
4    *  this work for additional information regarding copyright ownership.
5    *  The ASF licenses this file to You under the Apache License, Version 2.0
6    *  (the "License"); you may not use this file except in compliance with
7    *  the License.  You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   *  Unless required by applicable law or agreed to in writing, software
12   *  distributed under the License is distributed on an "AS IS" BASIS,
13   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   *  See the License for the specific language governing permissions and
15   *  limitations under the License.
16   */
17  package org.apache.commons.compress.harmony.unpack200;
18  
19  import static org.junit.jupiter.api.Assertions.assertEquals;
20  
21  import java.io.ByteArrayInputStream;
22  import java.io.IOException;
23  import java.io.InputStream;
24  import java.util.ArrayList;
25  
26  import org.apache.commons.compress.harmony.pack200.Pack200Exception;
27  import org.apache.commons.compress.harmony.unpack200.bytecode.CPClass;
28  import org.apache.commons.compress.harmony.unpack200.bytecode.CPDouble;
29  import org.apache.commons.compress.harmony.unpack200.bytecode.CPFieldRef;
30  import org.apache.commons.compress.harmony.unpack200.bytecode.CPFloat;
31  import org.apache.commons.compress.harmony.unpack200.bytecode.CPInteger;
32  import org.apache.commons.compress.harmony.unpack200.bytecode.CPInterfaceMethodRef;
33  import org.apache.commons.compress.harmony.unpack200.bytecode.CPLong;
34  import org.apache.commons.compress.harmony.unpack200.bytecode.CPMethodRef;
35  import org.apache.commons.compress.harmony.unpack200.bytecode.CPNameAndType;
36  import org.apache.commons.compress.harmony.unpack200.bytecode.CPString;
37  import org.apache.commons.compress.harmony.unpack200.bytecode.CPUTF8;
38  import org.junit.jupiter.api.Disabled;
39  import org.junit.jupiter.api.Test;
40  
41  /**
42   * Tests for Pack200 bytecode bands.
43   *
44   * TODO: The number 8 is used in most of the tests in this class as a low (non-zero) number that is not likely to indicate a multiple byte number, but should be
45   * replaced with properly encoded byte arrays when encoding is implemented.
46   */
47  public class BcBandsTest extends AbstractBandsTest {
48  
49      public class MockClassBands extends ClassBands {
50  
51          public MockClassBands(final Segment segment) {
52              super(segment);
53          }
54  
55          @Override
56          public int[] getClassSuperInts() {
57              final int[] superClasses = new int[numClasses];
58              for (int index = 0; index < numClasses; index++) {
59                  superClasses[index] = 0;
60              }
61              return superClasses;
62          }
63  
64          @Override
65          public int[] getClassThisInts() {
66              final int[] thisClasses = new int[numClasses];
67              for (int index = 0; index < numClasses; index++) {
68                  thisClasses[index] = 0;
69              }
70              return thisClasses;
71          }
72  
73          @Override
74          public boolean[] getCodeHasAttributes() {
75              int totalMethods = 0;
76              for (int i = 0; i < numClasses; i++) {
77                  totalMethods += numMethods[i];
78              }
79              return new boolean[totalMethods];
80          }
81  
82          @Override
83          public int[] getCodeMaxNALocals() {
84              int totalMethods = 0;
85              for (int i = 0; i < numClasses; i++) {
86                  totalMethods += numMethods[i];
87              }
88              return new int[totalMethods];
89          }
90  
91          @Override
92          public int[] getCodeMaxStack() {
93              int totalMethods = 0;
94              for (int i = 0; i < numClasses; i++) {
95                  totalMethods += numMethods[i];
96              }
97              return new int[totalMethods];
98          }
99  
100         @Override
101         public ArrayList[][] getMethodAttributes() {
102             final ArrayList[][] attributes = new ArrayList[numClasses][];
103             for (int i = 0; i < attributes.length; i++) {
104                 attributes[i] = new ArrayList[numMethods[i]];
105                 for (int j = 0; j < attributes[i].length; j++) {
106                     attributes[i][j] = new ArrayList();
107                 }
108             }
109             return attributes;
110         }
111 
112         @Override
113         public String[][] getMethodDescr() {
114             final String[][] descr = new String[numClasses][];
115             for (int i = 0; i < descr.length; i++) {
116                 descr[i] = new String[numMethods[i]];
117                 for (int j = 0; j < descr[i].length; j++) {
118                     descr[i][j] = "hello()";
119                 }
120             }
121             return descr;
122         }
123 
124         @Override
125         public long[][] getMethodFlags() {
126             final long[][] flags = new long[numClasses][];
127             for (int i = 0; i < flags.length; i++) {
128                 flags[i] = new long[numMethods[i]];
129             }
130             return flags;
131         }
132 
133         @Override
134         public ArrayList getOrderedCodeAttributes() {
135             int totalMethods = 0;
136             for (final int numMethod : numMethods) {
137                 totalMethods += numMethod;
138             }
139             final ArrayList orderedAttributeList = new ArrayList();
140             for (int classIndex = 0; classIndex < totalMethods; classIndex++) {
141                 orderedAttributeList.add(new ArrayList());
142             }
143             return orderedAttributeList;
144         }
145     }
146 
147     public class MockCpBands extends CpBands {
148 
149         private final CPUTF8 cpUTF8 = new CPUTF8("java/lang/String");
150         private final CPClass cpClass = new CPClass(cpUTF8, -1);
151         private final CPNameAndType descriptor = new CPNameAndType(new CPUTF8("Hello"), new CPUTF8("(a, b, c)"), -1);
152 
153         public MockCpBands(final Segment segment) {
154             super(segment);
155         }
156 
157         @Override
158         public CPClass cpClassValue(final int index) {
159             return cpClass;
160         }
161 
162         @Override
163         public CPDouble cpDoubleValue(final int index) {
164             return new CPDouble(Double.valueOf(2.5D), index);
165         }
166 
167         @Override
168         public CPFieldRef cpFieldValue(final int index) {
169             return new CPFieldRef(cpClass, descriptor, index);
170         }
171 
172         @Override
173         public CPFloat cpFloatValue(final int index) {
174             return new CPFloat(Float.valueOf(2.5F), index);
175         }
176 
177         @Override
178         public CPInterfaceMethodRef cpIMethodValue(final int index) {
179             return new CPInterfaceMethodRef(cpClass, descriptor, index);
180         }
181 
182         @Override
183         public CPInteger cpIntegerValue(final int index) {
184             return new CPInteger(Integer.valueOf(21), index);
185         }
186 
187         @Override
188         public CPLong cpLongValue(final int index) {
189             return new CPLong(Long.valueOf(21L), index);
190         }
191 
192         @Override
193         public CPMethodRef cpMethodValue(final int index) {
194             return new CPMethodRef(cpClass, descriptor, index);
195         }
196 
197         @Override
198         public CPString cpStringValue(final int index) {
199             return new CPString(cpUTF8, index);
200         }
201 
202         @Override
203         public String[] getCpClass() {
204             return new String[] { "Hello" };
205         }
206 
207         @Override
208         public String[] getCpFieldClass() {
209             return new String[] {};
210         }
211 
212         @Override
213         public String[] getCpIMethodClass() {
214             return new String[] {};
215         }
216 
217         @Override
218         public String[] getCpMethodClass() {
219             return new String[] {};
220         }
221     }
222 
223     public class MockSegment extends AbstractBandsTest.MockSegment {
224 
225         public CpBands cpBands;
226 
227         @Override
228         protected AttrDefinitionBands getAttrDefinitionBands() {
229             return new MockAttributeDefinitionBands(this);
230         }
231 
232         @Override
233         protected ClassBands getClassBands() {
234             return new MockClassBands(this);
235         }
236 
237         @Override
238         public SegmentConstantPool getConstantPool() {
239             return cpBands.getConstantPool();
240         }
241 
242         @Override
243         protected CpBands getCpBands() {
244             if (null == cpBands) {
245                 cpBands = new MockCpBands(this);
246             }
247             return cpBands;
248         }
249     }
250 
251     BcBands bcBands = new BcBands(new MockSegment());
252 
253     /**
254      * Test with codes that should require entries in the bc_byte band
255      *
256      * @throws Pack200Exception
257      * @throws IOException
258      */
259     @Test
260     public void testBcByteBand() throws IOException, Pack200Exception {
261         final byte[] bytes = { 16, (byte) 132, (byte) 188, (byte) 197, (byte) 255, 8, 8, 8, 8, // bc_byte band
262                 8, // bc_locals band (required by iinc (132))
263                 8 }; // bc_class band (required by multianewarray (197))
264         final InputStream in = new ByteArrayInputStream(bytes);
265         bcBands.unpack(in);
266         assertEquals(4, bcBands.getMethodByteCodePacked()[0][0].length);
267         final int[] bc_byte = bcBands.getBcByte();
268         assertEquals(4, bc_byte.length);
269         for (final int element : bc_byte) {
270             assertEquals(8, element);
271         }
272         assertEquals(1, bcBands.getBcLocal().length);
273         assertEquals(1, bcBands.getBcClassRef().length);
274     }
275 
276     /**
277      * Test with codes that require entries in the bc_case_count and bc_case_value bands
278      *
279      * @throws Pack200Exception
280      * @throws IOException
281      */
282     @Test
283     public void testBcCaseBands() throws IOException, Pack200Exception {
284         final byte[] bytes = { (byte) 170, (byte) 171, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (byte) 255, 2, 5, // bc_case_count
285                 0, 0, 0, 0, 0, 0, 0, // bc_case_value
286                 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // bc_label
287         final InputStream in = new ByteArrayInputStream(bytes);
288         bcBands.unpack(in);
289         assertEquals(18, bcBands.getMethodByteCodePacked()[0][0].length);
290         final int[] bc_case_count = bcBands.getBcCaseCount();
291         assertEquals(2, bc_case_count.length);
292         assertEquals(2, bc_case_count[0]);
293         assertEquals(5, bc_case_count[1]);
294         final int[] bc_case_value = bcBands.getBcCaseValue();
295         assertEquals(0, bc_case_value[0]);
296         assertEquals(0, bc_case_value[1]);
297         assertEquals(9, bcBands.getBcLabel().length);
298     }
299 
300     /**
301      * Test with codes that should require entries in the bc_classref band
302      *
303      * @throws Pack200Exception
304      * @throws IOException
305      */
306     @Test
307     public void testBcClassRefBand() throws IOException, Pack200Exception {
308         final byte[] bytes = { (byte) 233, (byte) 236, (byte) 255, 8, 8 }; // bc_classref
309         // band
310         final InputStream in = new ByteArrayInputStream(bytes);
311         bcBands.unpack(in);
312         assertEquals(2, bcBands.getMethodByteCodePacked()[0][0].length);
313         final int[] bc_classref = bcBands.getBcClassRef();
314         assertEquals(2, bc_classref.length);
315     }
316 
317     /**
318      * Test with codes that should require entries in the bc_doubleref band
319      *
320      * @throws Pack200Exception
321      * @throws IOException
322      */
323     @Test
324     public void testBcDoubleRefBand() throws IOException, Pack200Exception {
325         final byte[] bytes = { (byte) 239, (byte) 255, 8 }; // bc_doubleref
326         // band
327         final InputStream in = new ByteArrayInputStream(bytes);
328         bcBands.unpack(in);
329         assertEquals(1, bcBands.getMethodByteCodePacked()[0][0].length);
330         final int[] bc_doubleref = bcBands.getBcDoubleRef();
331         assertEquals(1, bc_doubleref.length);
332     }
333 
334     @Test
335     @Disabled("TODO: Implement")
336     public void testBcEscBands() {
337         // TODO
338     }
339 
340     @Test
341     @Disabled("TODO: Implement")
342     public void testBcEscRefBands() {
343         // TODO
344     }
345 
346     /**
347      * Test with codes that should require entries in the bc_fieldref band
348      *
349      * @throws Pack200Exception
350      * @throws IOException
351      */
352     @Test
353     public void testBcFieldRefBand() throws IOException, Pack200Exception {
354         final byte[] bytes = { (byte) 178, (byte) 179, (byte) 180, (byte) 181, (byte) 255, 8, 8, 8, 8 }; // bc_fieldref band
355         final InputStream in = new ByteArrayInputStream(bytes);
356         bcBands.unpack(in);
357         assertEquals(4, bcBands.getMethodByteCodePacked()[0][0].length);
358         final int[] bc_fieldref = bcBands.getBcFieldRef();
359         assertEquals(4, bc_fieldref.length);
360     }
361 
362     /**
363      * Test with codes that should require entries in the bc_floatref band
364      *
365      * @throws Pack200Exception
366      * @throws IOException
367      */
368     @Test
369     public void testBcFloatRefBand() throws IOException, Pack200Exception {
370         final byte[] bytes = { (byte) 235, (byte) 238, (byte) 255, 8, 8 }; // bc_floatref
371         // band
372         final InputStream in = new ByteArrayInputStream(bytes);
373         bcBands.unpack(in);
374         assertEquals(2, bcBands.getMethodByteCodePacked()[0][0].length);
375         final int[] bc_floatref = bcBands.getBcFloatRef();
376         assertEquals(2, bc_floatref.length);
377     }
378 
379     /**
380      * Test with codes that should require entries in the bc_imethodref band
381      *
382      * @throws Pack200Exception
383      * @throws IOException
384      */
385     @Test
386     public void testBcIMethodRefBand() throws IOException, Pack200Exception {
387         final byte[] bytes = { (byte) 185, (byte) 255, 8 }; // bc_imethodref
388         // band
389         final InputStream in = new ByteArrayInputStream(bytes);
390         bcBands.unpack(in);
391         assertEquals(1, bcBands.getMethodByteCodePacked()[0][0].length);
392         final int[] bc_imethodref = bcBands.getBcIMethodRef();
393         assertEquals(1, bc_imethodref.length);
394     }
395 
396     /**
397      * Test with codes that should require entries in the bc_initrefref band
398      *
399      * @throws Pack200Exception
400      * @throws IOException
401      */
402     @Test
403     @Disabled("TODO: Need to fix this test so it has enough data to pass.")
404     public void testBcInitRefRefBand() throws IOException, Pack200Exception {
405         final byte[] bytes = { (byte) 230, (byte) 231, (byte) 232, (byte) 255, 8, 8, 8 }; // bc_initrefref band
406         final InputStream in = new ByteArrayInputStream(bytes);
407         bcBands.unpack(in);
408         assertEquals(3, bcBands.getMethodByteCodePacked()[0][0].length);
409         final int[] bc_initrefref = bcBands.getBcInitRef();
410         assertEquals(3, bc_initrefref.length);
411     }
412 
413     /**
414      * Test with codes that should require entries in the bc_intref band
415      *
416      * @throws Pack200Exception
417      * @throws IOException
418      */
419     @Test
420     public void testBcIntRefBand() throws IOException, Pack200Exception {
421         final byte[] bytes = { (byte) 234, (byte) 237, (byte) 255, 8, 8 }; // bc_intref
422         // band
423         final InputStream in = new ByteArrayInputStream(bytes);
424         bcBands.unpack(in);
425         assertEquals(2, bcBands.getMethodByteCodePacked()[0][0].length);
426         final int[] bc_intref = bcBands.getBcIntRef();
427         assertEquals(2, bc_intref.length);
428     }
429 
430     /**
431      * Test with codes that should require entries in the bc_label band
432      *
433      * @throws Pack200Exception
434      * @throws IOException
435      */
436     @Test
437     public void testBcLabelBand() throws IOException, Pack200Exception {
438         final byte[] bytes = { (byte) 159, (byte) 160, (byte) 161, (byte) 162, (byte) 163, (byte) 164, (byte) 165, (byte) 166, (byte) 167, (byte) 168,
439                 (byte) 170, (byte) 171, (byte) 198, (byte) 199, (byte) 200, (byte) 201, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (byte) 255,
440                 2, 2, // bc_case_count
441                 // (required
442                 // by
443                 // tableswitch
444                 // (170) and
445                 // lookupswitch
446                 // (171))
447                 0, 0, 0, 0, // bc_case_value
448                 // Now that we're actually doing real label lookup, need valid
449                 // labels
450                 // 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 }; // bc_label
451                 // band
452                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // bc_label
453         // band
454         final InputStream in = new ByteArrayInputStream(bytes);
455         bcBands.unpack(in);
456         assertEquals(36, bcBands.getMethodByteCodePacked()[0][0].length);
457         assertEquals(20, bcBands.getBcLabel().length);
458     }
459 
460     /**
461      * Test with codes that should require entries in the bc_local band
462      *
463      * @throws Pack200Exception
464      * @throws IOException
465      */
466     @Test
467     public void testBcLocalBand() throws IOException, Pack200Exception {
468         final byte[] bytes = { 21, 22, 23, 24, 25, 54, 55, 56, 57, 58, (byte) 169, (byte) 255, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 }; // bc_local
469         // band
470         final InputStream in = new ByteArrayInputStream(bytes);
471         bcBands.unpack(in);
472         assertEquals(11, bcBands.getMethodByteCodePacked()[0][0].length);
473         assertEquals(11, bcBands.getBcLocal().length);
474     }
475 
476     /**
477      * Test with codes that should require entries in the bc_longref band
478      *
479      * @throws Pack200Exception
480      * @throws IOException
481      */
482     @Test
483     public void testBcLongRefBand() throws IOException, Pack200Exception {
484         final byte[] bytes = { 20, (byte) 255, 8 }; // bc_longref band
485         final InputStream in = new ByteArrayInputStream(bytes);
486         bcBands.unpack(in);
487         assertEquals(1, bcBands.getMethodByteCodePacked()[0][0].length);
488         final int[] bc_longref = bcBands.getBcLongRef();
489         assertEquals(1, bc_longref.length);
490     }
491 
492     /**
493      * Test with codes that should require entries in the bc_methodref band
494      *
495      * @throws Pack200Exception
496      * @throws IOException
497      */
498     @Test
499     public void testBcMethodRefBand() throws IOException, Pack200Exception {
500         final byte[] bytes = { (byte) 182, (byte) 183, (byte) 184, (byte) 255, 8, 8, 8 }; // bc_methodref band
501         final InputStream in = new ByteArrayInputStream(bytes);
502         bcBands.unpack(in);
503         assertEquals(3, bcBands.getMethodByteCodePacked()[0][0].length);
504         final int[] bc_methodref = bcBands.getBcMethodRef();
505         assertEquals(3, bc_methodref.length);
506     }
507 
508     /**
509      * Test with codes that should require entries in the bc_short band
510      *
511      * @throws Pack200Exception
512      * @throws IOException
513      */
514     @Test
515     public void testBcShortBand() throws IOException, Pack200Exception {
516         // TODO: Need to fix this test so it has enough data to pass.
517         final byte[] bytes = { 17, (byte) 196, (byte) 132, (byte) 255, 8, 8, // bc_short band
518                 8 }; // bc_locals band (required by wide iinc (196, 132))
519         final InputStream in = new ByteArrayInputStream(bytes);
520         bcBands.unpack(in);
521         assertEquals(3, bcBands.getMethodByteCodePacked()[0][0].length);
522         assertEquals(2, bcBands.getBcShort().length);
523         assertEquals(1, bcBands.getBcLocal().length);
524     }
525 
526     /**
527      * Test with codes that should require entries in the bc_stringref band
528      *
529      * @throws Pack200Exception
530      * @throws IOException
531      */
532     @Test
533     public void testBcStringRefBand() throws IOException, Pack200Exception {
534         final byte[] bytes = { 18, 19, (byte) 255, 8, 8 }; // bc_stringref
535         // band
536         final InputStream in = new ByteArrayInputStream(bytes);
537         bcBands.unpack(in);
538         assertEquals(2, bcBands.getMethodByteCodePacked()[0][0].length);
539         final int[] bc_stringref = bcBands.getBcStringRef();
540         assertEquals(2, bc_stringref.length);
541     }
542 
543     /**
544      * Test with codes that should require entries in the bc_superfield band
545      *
546      * @throws Pack200Exception
547      * @throws IOException
548      */
549     @Test
550     public void testBcSuperFieldBand() throws IOException, Pack200Exception {
551         final byte[] bytes = { (byte) 216, (byte) 217, (byte) 218, (byte) 219, (byte) 223, (byte) 224, (byte) 225, (byte) 226, (byte) 255, 8, 8, 8, 8, 8, 8, 8,
552                 8 }; // bc_superfield band
553         final InputStream in = new ByteArrayInputStream(bytes);
554         bcBands.unpack(in);
555         assertEquals(8, bcBands.getMethodByteCodePacked()[0][0].length);
556         final int[] bc_superfield = bcBands.getBcSuperField();
557         assertEquals(8, bc_superfield.length);
558     }
559 
560     /**
561      * Test with codes that should require entries in the bc_supermethod band
562      *
563      * @throws Pack200Exception
564      * @throws IOException
565      */
566     @Test
567     @Disabled("TODO: Need to fix this test so it has enough data to pass.")
568     public void testBcSuperMethodBand() throws IOException, Pack200Exception {
569         final byte[] bytes = { (byte) 220, (byte) 221, (byte) 222, (byte) 227, (byte) 228, (byte) 229, (byte) 255, 8, 8, 8, 8, 8, 8 }; // bc_supermethod band
570         final InputStream in = new ByteArrayInputStream(bytes);
571         bcBands.unpack(in);
572         assertEquals(6, bcBands.getMethodByteCodePacked()[0][0].length);
573         final int[] bc_supermethod = bcBands.getBcSuperMethod();
574         assertEquals(6, bc_supermethod.length);
575     }
576 
577     /**
578      * Test with codes that should require entries in the bc_thisfieldref band
579      *
580      * @throws Pack200Exception
581      * @throws IOException
582      */
583     @Test
584     public void testBcThisFieldBand() throws IOException, Pack200Exception {
585         final byte[] bytes = { (byte) 202, (byte) 203, (byte) 204, (byte) 205, (byte) 209, (byte) 210, (byte) 211, (byte) 212, (byte) 255, 8, 8, 8, 8, 8, 8, 8,
586                 8 }; // bc_thisfieldref band
587         final InputStream in = new ByteArrayInputStream(bytes);
588         bcBands.unpack(in);
589         assertEquals(8, bcBands.getMethodByteCodePacked()[0][0].length);
590         final int[] bc_thisfield = bcBands.getBcThisField();
591         assertEquals(8, bc_thisfield.length);
592     }
593 
594     /**
595      * Test with codes that should require entries in the bc_thismethod band
596      *
597      * @throws Pack200Exception
598      * @throws IOException
599      */
600     @Test
601     public void testBcThisMethodBand() throws IOException, Pack200Exception {
602         final byte[] bytes = { (byte) 206, (byte) 207, (byte) 208, (byte) 213, (byte) 214, (byte) 215, (byte) 255, 8, 8, 8, 8, 8, 8 }; // bc_thismethod band
603         final InputStream in = new ByteArrayInputStream(bytes);
604         bcBands.unpack(in);
605         assertEquals(6, bcBands.getMethodByteCodePacked()[0][0].length);
606         final int[] bc_thismethod = bcBands.getBcThisMethod();
607         assertEquals(6, bc_thismethod.length);
608     }
609 
610     /**
611      * Test with multiple classes but single byte instructions
612      *
613      * @throws IOException
614      * @throws Pack200Exception
615      */
616     @Test
617     public void testMultipleClassesSimple() throws IOException, Pack200Exception {
618         numClasses = 2;
619         numMethods = new int[] { 1, 1 };
620         final byte[] bytes = { 50, 50, (byte) 255, 50, 50, (byte) 255 };
621         final InputStream in = new ByteArrayInputStream(bytes);
622         bcBands.unpack(in);
623         assertEquals(2, bcBands.getMethodByteCodePacked()[0][0].length);
624         assertEquals(2, bcBands.getMethodByteCodePacked()[0][0].length);
625 
626         numClasses = 1;
627         numMethods = new int[] { 1 };
628     }
629 
630     /**
631      * Test with multiple classes and multiple methods but single byte instructions
632      *
633      * @throws IOException
634      * @throws Pack200Exception
635      */
636     @Test
637     public void testMultipleMethodsSimple() throws IOException, Pack200Exception {
638         numClasses = 2;
639         numMethods = new int[] { 3, 1 };
640         final byte[] bytes = { 50, 50, (byte) 255, 50, 50, (byte) 255, 50, 50, (byte) 255, 50, 50, (byte) 255 };
641         final InputStream in = new ByteArrayInputStream(bytes);
642         bcBands.unpack(in);
643         assertEquals(2, bcBands.getMethodByteCodePacked()[0][0].length);
644         assertEquals(2, bcBands.getMethodByteCodePacked()[0][0].length);
645 
646         numClasses = 1;
647         numMethods = new int[] { 1 };
648     }
649 
650     /**
651      * Test with single byte instructions that mean all other bands apart from bc_codes will be empty.
652      *
653      * @throws IOException
654      * @throws Pack200Exception
655      */
656     @Test
657     public void testSimple() throws IOException, Pack200Exception {
658         final byte[] bytes = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
659                 45, 46, 47, 48, 49, 50, 51, 52, 53, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85,
660                 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,
661                 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, (byte) 128, (byte) 129, (byte) 130, (byte) 131, (byte) 133, (byte) 134, (byte) 135,
662                 (byte) 136, (byte) 137, (byte) 138, (byte) 139, (byte) 140, (byte) 141, (byte) 142, (byte) 143, (byte) 144, (byte) 145, (byte) 146, (byte) 147,
663                 (byte) 148, (byte) 149, (byte) 150, (byte) 151, (byte) 172, (byte) 173, (byte) 174, (byte) 175, (byte) 176, (byte) 177, (byte) 190, (byte) 191,
664                 (byte) 194, (byte) 195, (byte) 255 };
665         final InputStream in = new ByteArrayInputStream(bytes);
666         bcBands.unpack(in);
667         assertEquals(bytes.length - 1, bcBands.getMethodByteCodePacked()[0][0].length);
668     }
669 
670     @Test
671     public void testWideForms() throws IOException, Pack200Exception {
672         final byte[] bytes = { (byte) 196, (byte) 54, // wide istore
673                 (byte) 196, (byte) 132, // wide iinc
674                 (byte) 255, 0, // bc_short band
675                 0, 1 }; // bc_locals band
676         final InputStream in = new ByteArrayInputStream(bytes);
677         bcBands.unpack(in);
678         assertEquals(4, bcBands.getMethodByteCodePacked()[0][0].length);
679         assertEquals(2, bcBands.getBcLocal().length);
680         assertEquals(1, bcBands.getBcShort().length);
681     }
682 
683 }