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