View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   https://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.commons.compress.harmony.unpack200;
20  
21  import static org.junit.jupiter.api.Assertions.assertEquals;
22  
23  import java.io.ByteArrayInputStream;
24  import java.io.ByteArrayOutputStream;
25  import java.io.IOException;
26  
27  import org.apache.commons.compress.harmony.pack200.BHSDCodec;
28  import org.apache.commons.compress.harmony.pack200.Codec;
29  import org.apache.commons.compress.harmony.pack200.Pack200Exception;
30  import org.junit.jupiter.api.Test;
31  
32  /**
33   */
34  class ClassBandsTest extends AbstractBandsTest {
35  
36      public class MockCpBands extends CpBands {
37  
38          MockCpBands(final Segment segment) {
39              super(segment);
40          }
41  
42          @Override
43          public String[] getCpClass() {
44              return cpClasses;
45          }
46  
47          @Override
48          public String[] getCpDescriptor() {
49              return cpDescriptor;
50          }
51  
52          public double[] getCpDouble() {
53              return new double[0];
54          }
55  
56          public float[] getCpFloat() {
57              return new float[0];
58          }
59  
60          @Override
61          public int[] getCpInt() {
62              return new int[0];
63          }
64  
65          @Override
66          public long[] getCpLong() {
67              return new long[0];
68          }
69  
70          @Override
71          public String[] getCpSignature() {
72              return new String[0];
73          }
74  
75          @Override
76          public String[] getCpUTF8() {
77              return cpUTF8;
78          }
79      }
80  
81      public class MockSegment extends AbstractBandsTest.MockSegment {
82  
83          @Override
84          protected CpBands getCpBands() {
85              return new MockCpBands(this);
86          }
87      }
88  
89      private String[] cpClasses;
90  
91      private String[] cpDescriptor;
92  
93      private String[] cpUTF8;
94  
95      ClassBands classBands = new ClassBands(new MockSegment());
96  
97      private byte[] encodeBandInt(final int[] data, final BHSDCodec codec) throws IOException, Pack200Exception {
98          final ByteArrayOutputStream baos = new ByteArrayOutputStream();
99          for (int i = 0; i < data.length; i++) {
100             baos.write(codec.encode(data[i], i == 0 ? 0 : data[i - 1]));
101         }
102         return baos.toByteArray();
103     }
104 
105     @Test
106     void testSimple() throws IOException, Pack200Exception {
107         cpClasses = new String[] { "Class1", "Class2", "Class3", "Interface1", "Interface2" };
108         cpDescriptor = new String[0];
109         cpUTF8 = new String[0];
110         final byte[] classThis = Codec.DELTA5.encode(1, 0);
111         final byte[] classSuper = Codec.DELTA5.encode(2, 0);
112         final byte[] classInterfaceCount = Codec.DELTA5.encode(2, 0);
113         final byte[] classInterfaceRef1 = encodeBandInt(new int[] { 3, 4 }, Codec.DELTA5);
114         final byte[] classFieldCount = Codec.DELTA5.encode(0, 0);
115         final byte[] classMethodCount = Codec.DELTA5.encode(0, 0);
116         final byte[] classFlags = Codec.UNSIGNED5.encode(0, 0);
117         final byte[][] allArrays = { classThis, classSuper, classInterfaceCount, classInterfaceRef1, classFieldCount, classMethodCount, classFlags };
118         final int total = classThis.length + classSuper.length + classInterfaceCount.length + classInterfaceRef1.length + classFieldCount.length
119                 + classMethodCount.length + classFlags.length;
120         final byte[] bytes = new byte[total];
121         int index = 0;
122         for (final byte[] array : allArrays) {
123             for (final byte element : array) {
124                 bytes[index] = element;
125                 index++;
126             }
127         }
128         final ByteArrayInputStream in = new ByteArrayInputStream(bytes);
129         classBands.unpack(in);
130         assertEquals(1, classBands.getClassThisInts()[0]);
131         assertEquals(2, classBands.getClassSuperInts()[0]);
132         assertEquals(1, classBands.getClassInterfacesInts().length);
133         assertEquals(2, classBands.getClassInterfacesInts()[0].length);
134         assertEquals(3, classBands.getClassInterfacesInts()[0][0]);
135         assertEquals(4, classBands.getClassInterfacesInts()[0][1]);
136         cpClasses = null;
137     }
138 
139     @Test
140     void testWithMethods() throws Pack200Exception, IOException {
141         cpClasses = new String[] { "Class1", "Class2", "Class3" };
142         cpDescriptor = new String[] { "method1", "method2", "method3" };
143         cpUTF8 = new String[0];
144         final byte[] classThis = Codec.DELTA5.encode(1, 0);
145         final byte[] classSuper = Codec.DELTA5.encode(2, 0);
146         final byte[] classInterfaceCount = Codec.DELTA5.encode(0, 0);
147         final byte[] classFieldCount = Codec.DELTA5.encode(0, 0);
148         final byte[] classMethodCount = Codec.DELTA5.encode(3, 0);
149         final byte[] methodDescr = encodeBandInt(new int[] { 0, 1, 2 }, Codec.MDELTA5);
150         final byte[] methodFlagsLo = encodeBandInt(new int[] { 0, 0, 0 }, Codec.UNSIGNED5);
151         final byte[] classFlags = Codec.UNSIGNED5.encode(0, 0);
152         final byte[][] allArrays = { classThis, classSuper, classInterfaceCount, classFieldCount, classMethodCount, methodDescr, methodFlagsLo, classFlags, };
153         int total = 0;
154         for (final byte[] array : allArrays) {
155             total += array.length;
156         }
157         final byte[] bytes = new byte[total];
158         int index = 0;
159         for (final byte[] array : allArrays) {
160             for (final byte element : array) {
161                 bytes[index] = element;
162                 index++;
163             }
164         }
165         final ByteArrayInputStream in = new ByteArrayInputStream(bytes);
166         classBands.unpack(in);
167         assertEquals(1, classBands.getClassThisInts()[0]);
168         assertEquals(2, classBands.getClassSuperInts()[0]);
169         assertEquals(1, classBands.getMethodDescr().length);
170         assertEquals(3, classBands.getMethodDescr()[0].length);
171         assertEquals(cpDescriptor[0], classBands.getMethodDescr()[0][0]);
172         assertEquals(cpDescriptor[1], classBands.getMethodDescr()[0][1]);
173         assertEquals(cpDescriptor[2], classBands.getMethodDescr()[0][2]);
174 
175         cpClasses = null;
176         cpDescriptor = null;
177     }
178 
179 }