1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.commons.compress.archivers.zip;
20
21 import static org.junit.Assert.assertEquals;
22 import static org.junit.Assert.assertTrue;
23
24 import java.io.ByteArrayInputStream;
25 import java.io.File;
26 import java.io.FileInputStream;
27 import java.io.IOException;
28 import java.io.InputStream;
29 import java.io.OutputStream;
30 import java.nio.file.Files;
31 import java.nio.file.Path;
32
33 import org.apache.commons.compress.AbstractTest;
34 import org.apache.commons.compress.compressors.zstandard.ZstdCompressorInputStream;
35 import org.apache.commons.compress.compressors.zstandard.ZstdCompressorOutputStream;
36 import org.apache.commons.compress.compressors.zstandard.ZstdUtils;
37 import org.apache.commons.io.IOUtils;
38 import org.junit.jupiter.api.Test;
39 import org.junit.jupiter.params.ParameterizedTest;
40 import org.junit.jupiter.params.provider.EnumSource;
41
42 class ZipCompressMethodZstdTest extends AbstractTest {
43
44 private static final int DEFAULT_LEVEL = 3;
45
46
47
48
49
50
51
52
53 private static void compress(final InputStream input, final OutputStream output) throws IOException {
54 @SuppressWarnings("resource")
55 final ZstdCompressorOutputStream outputStream = new ZstdCompressorOutputStream(output, DEFAULT_LEVEL, true);
56 IOUtils.copyLarge(input, outputStream);
57 outputStream.flush();
58 }
59
60 @Test
61 void testZstdInputStream() throws IOException {
62 final Path file = getPath("COMPRESS-692/compress-692.zip");
63 try (ZipFile zip = ZipFile.builder().setFile(file.toFile()).get()) {
64 final ZipArchiveEntry entry = zip.getEntries().nextElement();
65 assertEquals("Unexpected first entry", "dolor.txt", entry.getName());
66 assertTrue("entry can't be read", zip.canReadEntryData(entry));
67 assertEquals("Unexpected method", ZipMethod.ZSTD.getCode(), entry.getMethod());
68 try (InputStream inputStream = zip.getInputStream(entry)) {
69 final long uncompSize = entry.getSize();
70 final byte[] buf = new byte[(int) uncompSize];
71 inputStream.read(buf);
72 final String uncompData = new String(buf);
73 assertTrue(uncompData.startsWith("dolor sit amet"));
74 assertTrue(uncompData.endsWith("ex ea commodo"));
75 assertEquals(6066, uncompData.length());
76 }
77 }
78 }
79
80 @ParameterizedTest
81 @EnumSource(names = { "ZSTD", "ZSTD_DEPRECATED" })
82 void testZstdMethod(final ZipMethod zipMethod) throws IOException {
83 final String zipContentFile = "Name.txt";
84 final byte[] simpleText = "This is a Simple Test File.".getBytes();
85 final File file = Files.createTempFile("", ".zip").toFile();
86
87 try (ZipArchiveOutputStream zipOutputStream = new ZipArchiveOutputStream(file)) {
88 final ZipArchiveEntry archiveEntry = new ZipArchiveEntry(zipContentFile);
89 archiveEntry.setMethod(zipMethod.getCode());
90 archiveEntry.setSize(simpleText.length);
91 zipOutputStream.putArchiveEntry(archiveEntry);
92 ZipCompressMethodZstdTest.compress(new ByteArrayInputStream(simpleText), zipOutputStream);
93 zipOutputStream.closeArchiveEntry();
94 }
95
96 try (ZipFile zipFile = ZipFile.builder().setFile(file).get()) {
97
98 final ZipArchiveEntry entry = zipFile.getEntry(zipContentFile);
99
100 assertEquals(entry.getMethod(), zipMethod.getCode());
101 final InputStream inputStream = zipFile.getInputStream(entry);
102 assertTrue("Input stream must be a ZstdInputStream", inputStream instanceof ZstdCompressorInputStream);
103 }
104 }
105
106 @ParameterizedTest
107 @EnumSource(names = { "ZSTD", "ZSTD_DEPRECATED" })
108 void testZstdMethodInZipFile(final ZipMethod zipMethod) throws IOException {
109 final String zipContentFile = "Name.txt";
110 final byte[] simpleText = "This is a Simple Test File.".getBytes();
111 final File file = Files.createTempFile("", ".zip").toFile();
112
113 try (ZipArchiveOutputStream zipOutputStream = new ZipArchiveOutputStream(file)) {
114 final ZipArchiveEntry archiveEntry = new ZipArchiveEntry(zipContentFile);
115 archiveEntry.setMethod(zipMethod.getCode());
116 archiveEntry.setSize(simpleText.length);
117 zipOutputStream.putArchiveEntry(archiveEntry);
118 ZipCompressMethodZstdTest.compress(new ByteArrayInputStream(simpleText), zipOutputStream);
119 zipOutputStream.closeArchiveEntry();
120 }
121
122 try (ZipFile zipFile = ZipFile.builder().setFile(file).get()) {
123
124 final ZipArchiveEntry entry = zipFile.getEntry(zipContentFile);
125
126 assertEquals(entry.getMethod(), zipMethod.getCode());
127 final InputStream inputStream = zipFile.getInputStream(entry);
128 assertTrue(inputStream instanceof ZstdCompressorInputStream);
129 final long dataOffset = entry.getDataOffset();
130 final int uncompressedSize = (int) entry.getSize();
131 assertEquals(simpleText.length, uncompressedSize);
132 final byte[] uncompressedData = new byte[uncompressedSize];
133 inputStream.read(uncompressedData, 0, uncompressedSize);
134
135 assertEquals(new String(simpleText), new String(uncompressedData));
136 try (FileInputStream fileInputStream = new FileInputStream(file)) {
137 fileInputStream.skip(dataOffset);
138 final byte[] compressedData = new byte[4];
139 fileInputStream.read(compressedData);
140 assertTrue("Compressed data must begin with the magic bytes of Zstd", ZstdUtils.matches(compressedData, 4));
141 }
142 }
143 }
144 }