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