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