1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.commons.compress.harmony.pack200;
20
21 import static org.junit.jupiter.api.Assertions.assertEquals;
22 import static org.junit.jupiter.api.Assertions.assertFalse;
23 import static org.junit.jupiter.api.Assertions.assertTrue;
24
25 import java.io.ByteArrayInputStream;
26 import java.io.ByteArrayOutputStream;
27 import java.io.IOException;
28 import java.util.List;
29
30 import org.apache.commons.compress.harmony.pack200.AttributeDefinitionBands.AttributeDefinition;
31 import org.apache.commons.compress.harmony.pack200.NewAttributeBands.AttributeLayoutElement;
32 import org.apache.commons.compress.harmony.pack200.NewAttributeBands.Call;
33 import org.apache.commons.compress.harmony.pack200.NewAttributeBands.Callable;
34 import org.apache.commons.compress.harmony.pack200.NewAttributeBands.Integral;
35 import org.apache.commons.compress.harmony.pack200.NewAttributeBands.LayoutElement;
36 import org.apache.commons.compress.harmony.pack200.NewAttributeBands.Reference;
37 import org.apache.commons.compress.harmony.pack200.NewAttributeBands.Replication;
38 import org.apache.commons.compress.harmony.pack200.NewAttributeBands.Union;
39 import org.apache.commons.compress.harmony.pack200.NewAttributeBands.UnionCase;
40 import org.junit.jupiter.api.Test;
41 import org.junit.jupiter.params.ParameterizedTest;
42 import org.junit.jupiter.params.provider.ValueSource;
43
44
45
46
47 class NewAttributeBandsTest {
48
49 private final class MockNewAttributeBands extends NewAttributeBands {
50
51 MockNewAttributeBands(final int effort, final CpBands cpBands, final SegmentHeader header, final AttributeDefinition def) throws IOException {
52 super(effort, cpBands, header, def);
53 }
54
55 public List<AttributeLayoutElement> getLayoutElements() {
56 return attributeLayoutElements;
57 }
58 }
59
60 @Test
61 void testAddAttributes() throws IOException, Pack200Exception {
62 final CPUTF8 name = new CPUTF8("TestAttribute");
63 final CPUTF8 layout = new CPUTF8("B");
64 final MockNewAttributeBands newAttributeBands = new MockNewAttributeBands(1, null, null,
65 new AttributeDefinition(35, AttributeDefinitionBands.CONTEXT_CLASS, name, layout));
66 newAttributeBands.addAttribute(new NewAttribute(null, "TestAttribute", "B", new byte[] { 27 }, null, 0, null));
67 newAttributeBands.addAttribute(new NewAttribute(null, "TestAttribute", "B", new byte[] { 56 }, null, 0, null));
68 newAttributeBands.addAttribute(new NewAttribute(null, "TestAttribute", "B", new byte[] { 3 }, null, 0, null));
69 final ByteArrayOutputStream out = new ByteArrayOutputStream();
70 newAttributeBands.pack(out);
71
72
73 final byte[] bytes = out.toByteArray();
74 assertEquals(3, bytes.length);
75 assertEquals(27, bytes[0]);
76 assertEquals(56, bytes[1]);
77 assertEquals(3, bytes[2]);
78 }
79
80 @Test
81 void testAddAttributesWithReplicationLayout() throws IOException, Pack200Exception {
82 final CPUTF8 name = new CPUTF8("TestAttribute");
83 final CPUTF8 layout = new CPUTF8("NB[SH]");
84 final MockNewAttributeBands newAttributeBands = new MockNewAttributeBands(1, null, null,
85 new AttributeDefinition(35, AttributeDefinitionBands.CONTEXT_CLASS, name, layout));
86 newAttributeBands.addAttribute(new NewAttribute(null, "TestAttribute", "B", new byte[] { 1, 0, 100 }, null, 0, null));
87 final short s = -50;
88 final byte b1 = (byte) (s >>> 8);
89 final byte b2 = (byte) s;
90 newAttributeBands.addAttribute(new NewAttribute(null, "TestAttribute", "B", new byte[] { 3, 0, 5, 0, 25, b1, b2 }, null, 0, null));
91 final ByteArrayOutputStream out = new ByteArrayOutputStream();
92 newAttributeBands.pack(out);
93 final byte[] bytes = out.toByteArray();
94 assertEquals(1, bytes[0]);
95 assertEquals(3, bytes[1]);
96 final byte[] band = new byte[bytes.length - 2];
97 System.arraycopy(bytes, 2, band, 0, band.length);
98 final int[] decoded = Codec.SIGNED5.decodeInts(4, new ByteArrayInputStream(band));
99 assertEquals(4, decoded.length);
100 assertEquals(100, decoded[0]);
101 assertEquals(5, decoded[1]);
102 assertEquals(25, decoded[2]);
103 assertEquals(-50, decoded[3]);
104 }
105
106 @Test
107 void testEmptyLayout() throws IOException {
108 final CPUTF8 name = new CPUTF8("TestAttribute");
109 final CPUTF8 layout = new CPUTF8("");
110 final MockNewAttributeBands newAttributeBands = new MockNewAttributeBands(1, null, null,
111 new AttributeDefinition(35, AttributeDefinitionBands.CONTEXT_CLASS, name, layout));
112 final List<AttributeLayoutElement> layoutElements = newAttributeBands.getLayoutElements();
113 assertEquals(0, layoutElements.size());
114 }
115
116 @ParameterizedTest
117 @ValueSource(strings = { "B", "FB", "SB", "H", "FH", "SH", "I", "FI", "SI", "PB", "OB", "OSB", "POB", "PH", "OH", "OSH", "POH", "PI", "OI", "OSI", "POI" })
118 void testIntegralLayouts(final String layoutStr) throws IOException {
119 final CPUTF8 name = new CPUTF8("TestAttribute");
120 final CPUTF8 layout = new CPUTF8(layoutStr);
121 final MockNewAttributeBands newAttributeBands = new MockNewAttributeBands(1, null, null,
122 new AttributeDefinition(35, AttributeDefinitionBands.CONTEXT_CLASS, name, layout));
123 final List<AttributeLayoutElement> layoutElements = newAttributeBands.getLayoutElements();
124 assertEquals(1, layoutElements.size());
125 final Integral element = (Integral) layoutElements.get(0);
126 assertEquals(layoutStr, element.getTag());
127 }
128
129 @Test
130 void testLayoutWithBackwardsCalls() throws Exception {
131 CPUTF8 name = new CPUTF8("TestAttribute");
132 CPUTF8 layout = new CPUTF8("[NH[(1)]][KIH][(-1)]");
133 MockNewAttributeBands newAttributeBands = new MockNewAttributeBands(1, null, null,
134 new AttributeDefinition(35, AttributeDefinitionBands.CONTEXT_CLASS, name, layout));
135 List<AttributeLayoutElement> layoutElements = newAttributeBands.getLayoutElements();
136 assertEquals(3, layoutElements.size());
137 Callable firstCallable = (Callable) layoutElements.get(0);
138 Callable secondCallable = (Callable) layoutElements.get(1);
139 Callable thirdCallable = (Callable) layoutElements.get(2);
140 List<LayoutElement> thirdBody = thirdCallable.getBody();
141 assertEquals(1, thirdBody.size());
142 Call call = (Call) thirdBody.get(0);
143 assertEquals(secondCallable, call.getCallable());
144 assertTrue(secondCallable.isBackwardsCallable());
145 assertFalse(firstCallable.isBackwardsCallable());
146 assertFalse(thirdCallable.isBackwardsCallable());
147
148 name = new CPUTF8("TestAttribute");
149 layout = new CPUTF8("[NH[(1)]][KIH][(-2)]");
150 newAttributeBands = new MockNewAttributeBands(1, null, null, new AttributeDefinition(35, AttributeDefinitionBands.CONTEXT_CLASS, name, layout));
151 layoutElements = newAttributeBands.getLayoutElements();
152 assertEquals(3, layoutElements.size());
153 firstCallable = (Callable) layoutElements.get(0);
154 secondCallable = (Callable) layoutElements.get(1);
155 thirdCallable = (Callable) layoutElements.get(2);
156 thirdBody = thirdCallable.getBody();
157 assertEquals(1, thirdBody.size());
158 call = (Call) thirdBody.get(0);
159 assertEquals(firstCallable, call.getCallable());
160 assertTrue(firstCallable.isBackwardsCallable());
161 assertFalse(secondCallable.isBackwardsCallable());
162 assertFalse(thirdCallable.isBackwardsCallable());
163
164 name = new CPUTF8("TestAttribute");
165 layout = new CPUTF8("[NH[(1)]][KIH][(0)]");
166 newAttributeBands = new MockNewAttributeBands(1, null, null, new AttributeDefinition(35, AttributeDefinitionBands.CONTEXT_CLASS, name, layout));
167 layoutElements = newAttributeBands.getLayoutElements();
168 assertEquals(3, layoutElements.size());
169 firstCallable = (Callable) layoutElements.get(0);
170 secondCallable = (Callable) layoutElements.get(1);
171 thirdCallable = (Callable) layoutElements.get(2);
172 thirdBody = thirdCallable.getBody();
173 assertEquals(1, thirdBody.size());
174 call = (Call) thirdBody.get(0);
175 assertEquals(thirdCallable, call.getCallable());
176 assertTrue(thirdCallable.isBackwardsCallable());
177 assertFalse(firstCallable.isBackwardsCallable());
178 assertFalse(secondCallable.isBackwardsCallable());
179 }
180
181 @Test
182 void testLayoutWithCalls() throws IOException {
183 final CPUTF8 name = new CPUTF8("TestAttribute");
184
185 final CPUTF8 layout = new CPUTF8(
186 "[NH[(1)]][RSH NH[RUH(1)]][TB(66,67,73,83,90)[KIH](68)[KDH](70)[KFH](74)[KJH](99)[RSH](101)[RSH RUH](115)[RUH](91)[NH[(0)]](64)[RSH[RUH(0)]]()[]]"
187 );
188
189 final MockNewAttributeBands newAttributeBands = new MockNewAttributeBands(1, null, null,
190 new AttributeDefinition(35, AttributeDefinitionBands.CONTEXT_CLASS, name, layout));
191 final List<AttributeLayoutElement> layoutElements = newAttributeBands.getLayoutElements();
192 assertEquals(3, layoutElements.size());
193 final Callable firstCallable = (Callable) layoutElements.get(0);
194 final Callable secondCallable = (Callable) layoutElements.get(1);
195 final Callable thirdCallable = (Callable) layoutElements.get(2);
196 final List<LayoutElement> firstBody = firstCallable.getBody();
197 assertEquals(1, firstBody.size());
198 final Replication rep = (Replication) firstBody.get(0);
199 final List<LayoutElement> repBody = rep.getLayoutElements();
200 assertEquals(1, repBody.size());
201 final Call call = (Call) repBody.get(0);
202 assertEquals(1, call.getCallableIndex());
203 assertEquals(secondCallable, call.getCallable());
204 assertFalse(firstCallable.isBackwardsCallable());
205 assertFalse(secondCallable.isBackwardsCallable());
206 assertFalse(thirdCallable.isBackwardsCallable());
207 }
208
209 @ParameterizedTest
210 @ValueSource(strings = { "KIB", "KIH", "KII", "KINH", "KJH", "KDH", "KSH", "KQH", "RCH", "RSH", "RDH", "RFH", "RMH", "RIH", "RUH", "RQH", "RQNH", "RQNI" })
211 void testReferenceLayouts(final String layoutStr) throws IOException {
212 final CPUTF8 name = new CPUTF8("TestAttribute");
213 final CPUTF8 layout = new CPUTF8(layoutStr);
214 final MockNewAttributeBands newAttributeBands = new MockNewAttributeBands(1, null, null,
215 new AttributeDefinition(35, AttributeDefinitionBands.CONTEXT_CLASS, name, layout));
216 final List<AttributeLayoutElement> layoutElements = newAttributeBands.getLayoutElements();
217 assertEquals(1, layoutElements.size());
218 final Reference element = (Reference) layoutElements.get(0);
219 assertEquals(layoutStr, element.getTag());
220 }
221
222 @Test
223 void testReplicationLayouts() throws IOException {
224 final CPUTF8 name = new CPUTF8("TestAttribute");
225 final CPUTF8 layout = new CPUTF8("NH[PHOHRUHRSHH]");
226 final MockNewAttributeBands newAttributeBands = new MockNewAttributeBands(1, null, null,
227 new AttributeDefinition(35, AttributeDefinitionBands.CONTEXT_CLASS, name, layout));
228 final List<AttributeLayoutElement> layoutElements = newAttributeBands.getLayoutElements();
229 assertEquals(1, layoutElements.size());
230 final Replication element = (Replication) layoutElements.get(0);
231 final Integral countElement = element.getCountElement();
232 assertEquals("H", countElement.getTag());
233 final List<LayoutElement> replicatedElements = element.getLayoutElements();
234 assertEquals(5, replicatedElements.size());
235 final Integral firstElement = (Integral) replicatedElements.get(0);
236 assertEquals("PH", firstElement.getTag());
237 final Integral secondElement = (Integral) replicatedElements.get(1);
238 assertEquals("OH", secondElement.getTag());
239 final Reference thirdElement = (Reference) replicatedElements.get(2);
240 assertEquals("RUH", thirdElement.getTag());
241 final Reference fourthElement = (Reference) replicatedElements.get(3);
242 assertEquals("RSH", fourthElement.getTag());
243 final Integral fifthElement = (Integral) replicatedElements.get(4);
244 assertEquals("H", fifthElement.getTag());
245 }
246
247 @Test
248 void testUnionLayout() throws IOException {
249 final CPUTF8 name = new CPUTF8("TestAttribute");
250 final CPUTF8 layout = new CPUTF8("TB(55)[FH](23)[]()[RSH]");
251 final MockNewAttributeBands newAttributeBands = new MockNewAttributeBands(1, null, null,
252 new AttributeDefinition(35, AttributeDefinitionBands.CONTEXT_CLASS, name, layout));
253 final List<AttributeLayoutElement> layoutElements = newAttributeBands.getLayoutElements();
254 assertEquals(1, layoutElements.size());
255 final Union element = (Union) layoutElements.get(0);
256 final Integral tag = element.getUnionTag();
257 assertEquals("B", tag.getTag());
258 final List<UnionCase> unionCases = element.getUnionCases();
259 assertEquals(2, unionCases.size());
260 final UnionCase firstCase = unionCases.get(0);
261 assertTrue(firstCase.hasTag(55));
262 assertFalse(firstCase.hasTag(23));
263 List<LayoutElement> body = firstCase.getBody();
264 assertEquals(1, body.size());
265 final Integral bodyElement = (Integral) body.get(0);
266 assertEquals("FH", bodyElement.getTag());
267 final UnionCase secondCase = unionCases.get(1);
268 assertTrue(secondCase.hasTag(23));
269 assertFalse(secondCase.hasTag(55));
270 body = secondCase.getBody();
271 assertEquals(0, body.size());
272 final List<LayoutElement> defaultBody = element.getDefaultCaseBody();
273 assertEquals(1, defaultBody.size());
274 final Reference ref = (Reference) defaultBody.get(0);
275 assertEquals("RSH", ref.getTag());
276 }
277
278 }