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.ByteArrayOutputStream;
23  import java.io.IOException;
24  
25  import org.apache.commons.compress.harmony.pack200.BHSDCodec;
26  import org.apache.commons.compress.harmony.pack200.Codec;
27  import org.apache.commons.compress.harmony.pack200.Pack200Exception;
28  import org.junit.jupiter.api.Test;
29  
30  /**
31   */
32  public class ClassBandsTest extends AbstractBandsTest {
33  
34      public class MockCpBands extends CpBands {
35  
36          public MockCpBands(final Segment segment) {
37              super(segment);
38          }
39  
40          @Override
41          public String[] getCpClass() {
42              return cpClasses;
43          }
44  
45          @Override
46          public String[] getCpDescriptor() {
47              return cpDescriptor;
48          }
49  
50          public double[] getCpDouble() {
51              return new double[0];
52          }
53  
54          public float[] getCpFloat() {
55              return new float[0];
56          }
57  
58          @Override
59          public int[] getCpInt() {
60              return new int[0];
61          }
62  
63          @Override
64          public long[] getCpLong() {
65              return new long[0];
66          }
67  
68          @Override
69          public String[] getCpSignature() {
70              return new String[0];
71          }
72  
73          @Override
74          public String[] getCpUTF8() {
75              return cpUTF8;
76          }
77      }
78  
79      public class MockSegment extends AbstractBandsTest.MockSegment {
80  
81          @Override
82          protected CpBands getCpBands() {
83              return new MockCpBands(this);
84          }
85      }
86  
87      private String[] cpClasses;
88  
89      private String[] cpDescriptor;
90  
91      private String[] cpUTF8;
92  
93      ClassBands classBands = new ClassBands(new MockSegment());
94  
95      private byte[] encodeBandInt(final int[] data, final BHSDCodec codec) throws IOException, Pack200Exception {
96          final ByteArrayOutputStream baos = new ByteArrayOutputStream();
97          for (int i = 0; i < data.length; i++) {
98              baos.write(codec.encode(data[i], i == 0 ? 0 : data[i - 1]));
99          }
100         return baos.toByteArray();
101     }
102 
103     @Test
104     public void testSimple() throws IOException, Pack200Exception {
105         cpClasses = new String[] { "Class1", "Class2", "Class3", "Interface1", "Interface2" };
106         cpDescriptor = new String[0];
107         cpUTF8 = new String[0];
108         final byte[] classThis = Codec.DELTA5.encode(1, 0);
109         final byte[] classSuper = Codec.DELTA5.encode(2, 0);
110         final byte[] classInterfaceCount = Codec.DELTA5.encode(2, 0);
111         final byte[] classInterfaceRef1 = encodeBandInt(new int[] { 3, 4 }, Codec.DELTA5);
112         final byte[] classFieldCount = Codec.DELTA5.encode(0, 0);
113         final byte[] classMethodCount = Codec.DELTA5.encode(0, 0);
114         final byte[] classFlags = Codec.UNSIGNED5.encode(0, 0);
115         final byte[][] allArrays = { classThis, classSuper, classInterfaceCount, classInterfaceRef1, classFieldCount, classMethodCount, classFlags };
116         final int total = classThis.length + classSuper.length + classInterfaceCount.length + classInterfaceRef1.length + classFieldCount.length
117                 + classMethodCount.length + classFlags.length;
118         final byte[] bytes = new byte[total];
119         int index = 0;
120         for (final byte[] array : allArrays) {
121             for (final byte element : array) {
122                 bytes[index] = element;
123                 index++;
124             }
125         }
126         final ByteArrayInputStream in = new ByteArrayInputStream(bytes);
127         classBands.unpack(in);
128         assertEquals(1, classBands.getClassThisInts()[0]);
129         assertEquals(2, classBands.getClassSuperInts()[0]);
130         assertEquals(1, classBands.getClassInterfacesInts().length);
131         assertEquals(2, classBands.getClassInterfacesInts()[0].length);
132         assertEquals(3, classBands.getClassInterfacesInts()[0][0]);
133         assertEquals(4, classBands.getClassInterfacesInts()[0][1]);
134         cpClasses = null;
135     }
136 
137     @Test
138     public void testWithMethods() throws Pack200Exception, IOException {
139         cpClasses = new String[] { "Class1", "Class2", "Class3" };
140         cpDescriptor = new String[] { "method1", "method2", "method3" };
141         cpUTF8 = new String[0];
142         final byte[] classThis = Codec.DELTA5.encode(1, 0);
143         final byte[] classSuper = Codec.DELTA5.encode(2, 0);
144         final byte[] classInterfaceCount = Codec.DELTA5.encode(0, 0);
145         final byte[] classFieldCount = Codec.DELTA5.encode(0, 0);
146         final byte[] classMethodCount = Codec.DELTA5.encode(3, 0);
147         final byte[] methodDescr = encodeBandInt(new int[] { 0, 1, 2 }, Codec.MDELTA5);
148         final byte[] methodFlagsLo = encodeBandInt(new int[] { 0, 0, 0 }, Codec.UNSIGNED5);
149         final byte[] classFlags = Codec.UNSIGNED5.encode(0, 0);
150         final byte[][] allArrays = { classThis, classSuper, classInterfaceCount, classFieldCount, classMethodCount, methodDescr, methodFlagsLo, classFlags, };
151         int total = 0;
152         for (final byte[] array : allArrays) {
153             total += array.length;
154         }
155         final byte[] bytes = new byte[total];
156         int index = 0;
157         for (final byte[] array : allArrays) {
158             for (final byte element : array) {
159                 bytes[index] = element;
160                 index++;
161             }
162         }
163         final ByteArrayInputStream in = new ByteArrayInputStream(bytes);
164         classBands.unpack(in);
165         assertEquals(1, classBands.getClassThisInts()[0]);
166         assertEquals(2, classBands.getClassSuperInts()[0]);
167         assertEquals(1, classBands.getMethodDescr().length);
168         assertEquals(3, classBands.getMethodDescr()[0].length);
169         assertEquals(cpDescriptor[0], classBands.getMethodDescr()[0][0]);
170         assertEquals(cpDescriptor[1], classBands.getMethodDescr()[0][1]);
171         assertEquals(cpDescriptor[2], classBands.getMethodDescr()[0][2]);
172 
173         cpClasses = null;
174         cpDescriptor = null;
175     }
176 
177 }