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.assertDoesNotThrow;
22 import static org.junit.jupiter.api.Assertions.assertEquals;
23 import static org.junit.jupiter.api.Assertions.assertFalse;
24 import static org.junit.jupiter.api.Assertions.assertThrows;
25 import static org.junit.jupiter.api.Assertions.assertThrowsExactly;
26 import static org.junit.jupiter.api.Assertions.assertTrue;
27
28 import java.io.ByteArrayInputStream;
29 import java.io.EOFException;
30 import java.io.IOException;
31 import java.util.stream.IntStream;
32 import java.util.stream.Stream;
33
34 import org.junit.jupiter.api.Test;
35 import org.junit.jupiter.params.ParameterizedTest;
36 import org.junit.jupiter.params.provider.Arguments;
37 import org.junit.jupiter.params.provider.MethodSource;
38
39
40
41 class CodecTest {
42
43 static Stream<Arguments> bCodings() {
44 return IntStream.rangeClosed(1, 5).mapToObj(Arguments::of);
45 }
46
47 static Stream<Arguments> codecFamily() {
48 return Stream.of(Arguments.of((Object) CanonicalCodecFamilies.nonDeltaUnsignedCodecs1),
49 Arguments.of((Object) CanonicalCodecFamilies.nonDeltaUnsignedCodecs2), Arguments.of((Object) CanonicalCodecFamilies.nonDeltaUnsignedCodecs3),
50 Arguments.of((Object) CanonicalCodecFamilies.nonDeltaUnsignedCodecs4), Arguments.of((Object) CanonicalCodecFamilies.nonDeltaUnsignedCodecs5),
51 Arguments.of((Object) CanonicalCodecFamilies.deltaUnsignedCodecs1), Arguments.of((Object) CanonicalCodecFamilies.deltaUnsignedCodecs2),
52 Arguments.of((Object) CanonicalCodecFamilies.deltaUnsignedCodecs3), Arguments.of((Object) CanonicalCodecFamilies.deltaUnsignedCodecs4),
53 Arguments.of((Object) CanonicalCodecFamilies.deltaUnsignedCodecs5), Arguments.of((Object) CanonicalCodecFamilies.nonDeltaSignedCodecs1),
54 Arguments.of((Object) CanonicalCodecFamilies.nonDeltaSignedCodecs2), Arguments.of((Object) CanonicalCodecFamilies.nonDeltaDoubleSignedCodecs1),
55 Arguments.of((Object) CanonicalCodecFamilies.deltaSignedCodecs1), Arguments.of((Object) CanonicalCodecFamilies.deltaSignedCodecs2),
56 Arguments.of((Object) CanonicalCodecFamilies.deltaSignedCodecs3), Arguments.of((Object) CanonicalCodecFamilies.deltaSignedCodecs4),
57 Arguments.of((Object) CanonicalCodecFamilies.deltaSignedCodecs5), Arguments.of((Object) CanonicalCodecFamilies.deltaDoubleSignedCodecs1));
58 }
59
60 static Stream<Arguments> hCodings() {
61 return IntStream.range(0, 256).mapToObj(Arguments::of);
62 }
63
64 private long decode(final Codec codec, final byte[] data, final long value, final long last) throws IOException, Pack200Exception {
65 final ByteArrayInputStream in = new ByteArrayInputStream(data);
66 assertEquals(value, codec.decode(in, last));
67 assertEquals(-1, in.read());
68 return value;
69 }
70
71 private void decodeFail(final Codec codec, final byte[] data) {
72 assertThrowsExactly(EOFException.class, () -> decode(codec, data, 0, 0), "Should have detected an EOFException");
73 }
74
75 @ParameterizedTest
76 @MethodSource("bCodings")
77 void testBCodings(final int i) {
78 if (i == 5) {
79 assertThrows(IllegalArgumentException.class, () -> new BHSDCodec(i, 256));
80 } else {
81 assertDoesNotThrow(() -> new BHSDCodec(i, 256));
82 }
83 }
84
85 @Test
86 void testByte1() throws Exception {
87 for (int i = 0; i < 255; i++) {
88 decode(Codec.BYTE1, new byte[] { (byte) i }, i, 0);
89 }
90 }
91
92 @Test
93 void testByte1Delta() throws Exception {
94 final Codec BYTE1D = new BHSDCodec(1, 256, 0, 1);
95 long last = 0;
96 for (int i = 1; i < 255; i++) {
97 last = decode(BYTE1D, new byte[] { (byte) 1 }, i, last);
98 }
99 }
100
101 @Test
102 void testByte1DeltaException() throws Exception {
103 final Codec BYTE1D = new BHSDCodec(1, 256, 0, 1);
104 assertThrows(Pack200Exception.class, () -> BYTE1D.decode(new ByteArrayInputStream(new byte[] { (byte) 1 })),
105 "Decoding with a delta stream and not passing a last value should throw an exception");
106 }
107
108 @Test
109 void testByte1Signed() throws Exception {
110 final Codec BYTE1S2 = new BHSDCodec(1, 256, 2);
111 decode(BYTE1S2, new byte[] { 0 }, 0, 0);
112 decode(BYTE1S2, new byte[] { 1 }, 1, 0);
113 decode(BYTE1S2, new byte[] { 2 }, 2, 0);
114 decode(BYTE1S2, new byte[] { 3 }, -1, 0);
115 decode(BYTE1S2, new byte[] { 4 }, 3, 0);
116 decode(BYTE1S2, new byte[] { 5 }, 4, 0);
117 decode(BYTE1S2, new byte[] { 6 }, 5, 0);
118 decode(BYTE1S2, new byte[] { 7 }, -2, 0);
119 decode(BYTE1S2, new byte[] { 8 }, 6, 0);
120 decode(BYTE1S2, new byte[] { 9 }, 7, 0);
121 decode(BYTE1S2, new byte[] { 10 }, 8, 0);
122 decode(BYTE1S2, new byte[] { 11 }, -3, 0);
123 }
124
125 @Test
126 void testCardinality() {
127 final BHSDCodec byte1 = Codec.BYTE1;
128 assertEquals(256, byte1.cardinality());
129 assertEquals(0, byte1.smallest());
130 assertEquals(255, byte1.largest());
131 assertFalse(byte1.encodes(-257));
132 assertFalse(byte1.encodes(-256));
133 assertFalse(byte1.encodes(-255));
134 assertFalse(byte1.encodes(-129));
135 assertFalse(byte1.encodes(-128));
136 assertFalse(byte1.encodes(-127));
137 assertFalse(byte1.encodes(-1));
138 assertTrue(byte1.encodes(0));
139 assertTrue(byte1.encodes(1));
140 assertTrue(byte1.encodes(255));
141 assertFalse(byte1.encodes(256));
142 final BHSDCodec byte1s = new BHSDCodec(1, 256, 1);
143 assertEquals(256, byte1s.cardinality());
144 assertEquals(-128, byte1s.smallest());
145 assertEquals(127, byte1s.largest());
146 assertFalse(byte1s.encodes(-257));
147 assertFalse(byte1s.encodes(-256));
148 assertFalse(byte1s.encodes(-255));
149 assertFalse(byte1s.encodes(-129));
150 assertTrue(byte1s.encodes(-128));
151 assertTrue(byte1s.encodes(-127));
152 assertTrue(byte1s.encodes(-1));
153 assertTrue(byte1s.encodes(0));
154 assertTrue(byte1s.encodes(1));
155 assertTrue(byte1s.encodes(127));
156 assertFalse(byte1s.encodes(128));
157 assertFalse(byte1s.encodes(129));
158 assertFalse(byte1s.encodes(255));
159 assertFalse(byte1s.encodes(256));
160 final BHSDCodec byte2s = new BHSDCodec(1, 256, 2);
161 assertEquals(256, byte2s.cardinality());
162 assertEquals(-64, byte2s.smallest());
163 assertEquals(191, byte2s.largest());
164 assertFalse(byte2s.encodes(-257));
165 assertFalse(byte2s.encodes(-256));
166 assertFalse(byte2s.encodes(-255));
167 assertFalse(byte2s.encodes(-129));
168 assertFalse(byte2s.encodes(-128));
169 assertFalse(byte2s.encodes(-127));
170 assertFalse(byte2s.encodes(-65));
171 assertTrue(byte2s.encodes(-64));
172 assertTrue(byte2s.encodes(-64));
173 assertTrue(byte2s.encodes(-1));
174 assertTrue(byte2s.encodes(0));
175 assertTrue(byte2s.encodes(1));
176 assertTrue(byte2s.encodes(127));
177 assertTrue(byte2s.encodes(128));
178 assertTrue(byte2s.encodes(191));
179 assertFalse(byte2s.encodes(192));
180 assertFalse(byte2s.encodes(256));
181 }
182
183 @ParameterizedTest
184 @MethodSource("codecFamily")
185 void testCodecFamilies(final BHSDCodec[] family) {
186 for (int i = 1; i < family.length; i++) {
187 final BHSDCodec previous = family[i - 1];
188 final BHSDCodec codec = family[i];
189 assertTrue(codec.largest() >= previous.largest());
190 assertTrue(codec.smallest() <= previous.smallest());
191 }
192 }
193
194 @Test
195 void testCodecToString() {
196 assertEquals("(1,256)", Codec.BYTE1.toString());
197 assertEquals("(3,128)", Codec.CHAR3.toString());
198 assertEquals("(5,4)", Codec.BCI5.toString());
199 assertEquals("(5,4,2)", Codec.BRANCH5.toString());
200 assertEquals("(5,64)", Codec.UNSIGNED5.toString());
201 assertEquals("(5,64,1)", Codec.SIGNED5.toString());
202 assertEquals("(5,64,0,1)", Codec.UDELTA5.toString());
203 assertEquals("(5,64,1,1)", Codec.DELTA5.toString());
204 assertEquals("(5,64,2,1)", Codec.MDELTA5.toString());
205 assertEquals("(5,64)", Codec.UNSIGNED5.toString());
206 assertEquals("(5,64,1)", Codec.SIGNED5.toString());
207 assertEquals("(5,64,1,1)", Codec.DELTA5.toString());
208 assertEquals("(5,64,2,1)", Codec.MDELTA5.toString());
209 }
210
211 @ParameterizedTest
212 @MethodSource("hCodings")
213 void testInvalidHCodings(final int i) {
214 assertThrows(IllegalArgumentException.class, () -> new BHSDCodec(1, i), "b=1 -> h=256");
215 }
216
217 @Test
218 void testUnsigned5() throws Exception {
219 decode(Codec.UNSIGNED5, new byte[] { 1 }, 1, 0);
220 decode(Codec.UNSIGNED5, new byte[] { (byte) 191 }, 191, 0);
221 decode(Codec.UNSIGNED5, new byte[] { (byte) 192, 0 }, 192, 0);
222 decode(Codec.UNSIGNED5, new byte[] { (byte) 193, 0 }, 193, 0);
223 decode(Codec.UNSIGNED5, new byte[] { (byte) 255, 0 }, 255, 0);
224 decode(Codec.UNSIGNED5, new byte[] { (byte) 192, 1 }, 256, 0);
225 decode(Codec.UNSIGNED5, new byte[] { (byte) 192, 5 }, 512, 0);
226 decode(Codec.UNSIGNED5, new byte[] { (byte) 192, 13 }, 1024, 0);
227 decode(Codec.UNSIGNED5, new byte[] { (byte) 192, 29 }, 2048, 0);
228 decode(Codec.UNSIGNED5, new byte[] { (byte) 255, (byte) 191 }, 12479, 0);
229
230 decode(Codec.UNSIGNED5, new byte[] { (byte) 192, (byte) 192, 0 }, 12480, 0);
231 decode(Codec.UNSIGNED5, new byte[] { (byte) 255, (byte) 255, (byte) 191 }, 798911, 0);
232 decode(Codec.UNSIGNED5, new byte[] { (byte) 192, (byte) 192, (byte) 192, 0 }, 798912, 0);
233 decode(Codec.UNSIGNED5, new byte[] { (byte) 255, (byte) 255, (byte) 255, (byte) 191 }, 51130559, 0);
234 decode(Codec.UNSIGNED5, new byte[] { (byte) 192, (byte) 192, (byte) 192, (byte) 192, 0 }, 51130560, 0);
235 decodeFail(Codec.UNSIGNED5, new byte[] { (byte) 192 });
236 decodeFail(Codec.UNSIGNED5, new byte[] { (byte) 192, (byte) 192 });
237 decodeFail(Codec.UNSIGNED5, new byte[] { (byte) 192, (byte) 192, (byte) 192 });
238 decodeFail(Codec.UNSIGNED5, new byte[] { (byte) 192, (byte) 192, (byte) 192, (byte) 192 });
239 }
240 }