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.assertThrows;
23
24 import java.io.ByteArrayInputStream;
25 import java.io.IOException;
26 import java.util.stream.Stream;
27
28 import org.junit.jupiter.api.Disabled;
29 import org.junit.jupiter.api.Test;
30 import org.junit.jupiter.params.ParameterizedTest;
31 import org.junit.jupiter.params.provider.Arguments;
32 import org.junit.jupiter.params.provider.MethodSource;
33
34
35
36
37 class RunCodecTest {
38
39 static Stream<Arguments> runCodec() {
40 return Stream.of(Arguments.of(0, Codec.SIGNED5, Codec.UDELTA5, "Should not allow a k value of 0"),
41 Arguments.of(10, null, Codec.UDELTA5, "Should not allow a null codec"), Arguments.of(10, Codec.UDELTA5, null, "Should not allow a null codec"),
42 Arguments.of(10, null, null, "Should not allow a null codec"));
43 }
44
45 @Test
46 void testDecode() throws Exception {
47 RunCodec runCodec = new RunCodec(1, Codec.UNSIGNED5, Codec.BYTE1);
48 ByteArrayInputStream bais = new ByteArrayInputStream(new byte[] { (byte) 192, 0, (byte) 192, 0 });
49 assertEquals(192, runCodec.decode(bais));
50 assertEquals(192, runCodec.decode(bais));
51 assertEquals(0, runCodec.decode(bais));
52 assertEquals(0, bais.available());
53 runCodec = new RunCodec(1, Codec.BYTE1, Codec.UNSIGNED5);
54 bais = new ByteArrayInputStream(new byte[] { (byte) 192, 0, (byte) 192, 0 });
55 assertEquals(192, runCodec.decode(bais));
56 assertEquals(0, runCodec.decode(bais));
57 assertEquals(192, runCodec.decode(bais));
58 assertEquals(0, bais.available());
59 }
60
61 @Test
62 void testDecodeInts() throws Exception {
63 final int[] band = { 1, -2, -3, 1000, 55, 5, 10, 20 };
64
65 final byte[] bytes1 = Codec.DELTA5.encode(new int[] { 1, -2, -3, 1000, 55 });
66
67 final byte[] bytes2 = Codec.UNSIGNED5.encode(new int[] { 5, 10, 20 });
68 final byte[] bandEncoded = new byte[bytes1.length + bytes2.length];
69 System.arraycopy(bytes1, 0, bandEncoded, 0, bytes1.length);
70 System.arraycopy(bytes2, 0, bandEncoded, bytes1.length, bytes2.length);
71 final RunCodec runCodec = new RunCodec(5, Codec.DELTA5, Codec.UNSIGNED5);
72 final int[] bandDecoded = runCodec.decodeInts(8, new ByteArrayInputStream(bandEncoded));
73 assertEquals(band.length, bandDecoded.length);
74 for (int i = 0; i < band.length; i++) {
75 assertEquals(band[i], bandDecoded[i]);
76 }
77 }
78
79 @Test
80 void testEncodeSingleValue() {
81 assertThrows(Pack200Exception.class, () -> new RunCodec(10, Codec.SIGNED5, Codec.UDELTA5).encode(5),
82 "Should not allow a single value to be encoded as we don't know which codec to use");
83 assertThrows(Pack200Exception.class, () -> new RunCodec(10, Codec.SIGNED5, Codec.UDELTA5).encode(5, 8),
84 "Should not allow a single value to be encoded as we don't know which codec to use");
85 }
86
87 @Test
88 void testNestedPopulationCodec() throws Exception {
89 final int[] band = { 11, 12, 33, 4000, -555, 5, 10, 20, 10, 3, 20, 20, 20, 10, 10, 999, 20, 789, 10, 10, 355, 12345 };
90
91 final byte[] bytes1 = Codec.DELTA5.encode(new int[] { 11, 12, 33, 4000, -555 });
92
93 final PopulationCodec popCodec = new PopulationCodec(Codec.UNSIGNED5, Codec.BYTE1, Codec.UNSIGNED5);
94 final byte[] bytes2 = popCodec.encode(new int[] { 10, 20 }, new int[] { 0, 1, 2, 1, 0, 2, 2, 2, 1, 1, 0, 2, 0, 1, 1, 0, 0 },
95 new int[] { 5, 3, 999, 789, 355, 12345 });
96 final byte[] bandEncoded = new byte[bytes1.length + bytes2.length];
97 System.arraycopy(bytes1, 0, bandEncoded, 0, bytes1.length);
98 System.arraycopy(bytes2, 0, bandEncoded, bytes1.length, bytes2.length);
99 final RunCodec runCodec = new RunCodec(5, Codec.DELTA5, new PopulationCodec(Codec.UNSIGNED5, Codec.BYTE1, Codec.UNSIGNED5));
100 final int[] bandDecoded = runCodec.decodeInts(band.length, new ByteArrayInputStream(bandEncoded));
101 assertEquals(band.length, bandDecoded.length);
102 for (int i = 0; i < band.length; i++) {
103 assertEquals(band[i], bandDecoded[i]);
104 }
105 }
106
107 @Test
108 void testNestedRunCodec() throws Exception {
109 final int[] band = { 1, 2, 3, 10, 20, 30, 100, 200, 300 };
110
111 final byte[] bytes1 = Codec.UDELTA5.encode(new int[] { 1, 2, 3 });
112
113 final byte[] bytes2 = Codec.BYTE1.encode(new int[] { 10, 20, 30 });
114 final byte[] bytes3 = Codec.UNSIGNED5.encode(new int[] { 100, 200, 300 });
115 final byte[] bandEncoded = new byte[bytes1.length + bytes2.length + bytes3.length];
116 System.arraycopy(bytes1, 0, bandEncoded, 0, bytes1.length);
117 System.arraycopy(bytes2, 0, bandEncoded, bytes1.length, bytes2.length);
118 System.arraycopy(bytes3, 0, bandEncoded, bytes1.length + bytes2.length, bytes3.length);
119 final RunCodec runCodec = new RunCodec(3, Codec.UDELTA5, new RunCodec(3, Codec.BYTE1, Codec.UNSIGNED5));
120 final int[] bandDecoded = runCodec.decodeInts(9, new ByteArrayInputStream(bandEncoded));
121 assertEquals(band.length, bandDecoded.length);
122 for (int i = 0; i < band.length; i++) {
123 assertEquals(band[i], bandDecoded[i]);
124 }
125 }
126
127 @Disabled
128 @Test
129 void testPopulationCodecDecodeIntsOverflow() throws Exception {
130 final byte[] bytes1 = Codec.DELTA5.encode(new int[] { 11, 12, 33, 4000, -555 });
131 final PopulationCodec popCodec = new PopulationCodec(Codec.UNSIGNED5, Codec.BYTE1, Codec.UNSIGNED5);
132 final byte[] bytes2 = popCodec.encode(new int[] { 10, 20 }, new int[] { 0, 1, 2, 1, 0, 2, 2, 2, 1, 1, 0, 2, 0, 1, 1, 0, 0 },
133 new int[] { 5, 3, 999, 789, 355, 12345 });
134 final byte[] bandEncoded = new byte[bytes1.length + bytes2.length];
135
136
137 assertThrows(IOException.class, () -> popCodec.decodeInts(Integer.MAX_VALUE - 1, new ByteArrayInputStream(bandEncoded)));
138 }
139
140 @ParameterizedTest
141 @MethodSource("runCodec")
142 void testRunCodec(final int k, final Codec aCodec, final Codec bCodec, final String failureMessage) {
143 assertThrows(Pack200Exception.class, () -> new RunCodec(k, aCodec, bCodec), failureMessage);
144 }
145
146 @Disabled
147 @Test
148 void testRunCodecDecodeIntsOverflow() throws Exception {
149 final byte[] bytes1 = Codec.DELTA5.encode(new int[] { 1, -2, -3, 1000, 55 });
150 final byte[] bytes2 = Codec.UNSIGNED5.encode(new int[] { 5, 10, 20 });
151 final byte[] bandEncoded = new byte[bytes1.length + bytes2.length];
152 System.arraycopy(bytes1, 0, bandEncoded, 0, bytes1.length);
153 System.arraycopy(bytes2, 0, bandEncoded, bytes1.length, bytes2.length);
154 final RunCodec runCodec = new RunCodec(5, Codec.DELTA5, Codec.UNSIGNED5);
155
156
157 assertThrows(IOException.class, () -> runCodec.decodeInts(Integer.MAX_VALUE - 1, new ByteArrayInputStream(bandEncoded)));
158 assertThrows(IOException.class, () -> runCodec.decodeInts(Integer.MAX_VALUE - 1, new ByteArrayInputStream(bandEncoded), 1));
159 }
160
161 @Test
162 void testToString() throws Pack200Exception {
163 final RunCodec runCodec = new RunCodec(3, Codec.UNSIGNED5, Codec.BYTE1);
164 assertEquals("RunCodec[k=" + 3 + ";aCodec=" + Codec.UNSIGNED5 + "bCodec=" + Codec.BYTE1 + "]", runCodec.toString());
165 }
166 }