1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
/* Copyright 2016 Google Inc. All Rights Reserved.
Distributed under MIT license.
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
*/
package org.brotli.integration;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
/**
* Utilities to work test files bundles in zip archive.
*/
public class BundleHelper {
private BundleHelper() { }
public static List<String> listEntries(InputStream input) throws IOException {
List<String> result = new ArrayList<String>();
ZipInputStream zis = new ZipInputStream(input);
ZipEntry entry;
try {
while ((entry = zis.getNextEntry()) != null) {
if (!entry.isDirectory()) {
result.add(entry.getName());
}
zis.closeEntry();
}
} finally {
zis.close();
}
return result;
}
public static byte[] readStream(InputStream input) throws IOException {
ByteArrayOutputStream result = new ByteArrayOutputStream();
byte[] buffer = new byte[65536];
int bytesRead;
while ((bytesRead = input.read(buffer)) != -1) {
result.write(buffer, 0, bytesRead);
}
return result.toByteArray();
}
public static byte[] readEntry(InputStream input, String entryName) throws IOException {
ZipInputStream zis = new ZipInputStream(input);
ZipEntry entry;
try {
while ((entry = zis.getNextEntry()) != null) {
if (entry.getName().equals(entryName)) {
byte[] result = readStream(zis);
zis.closeEntry();
return result;
}
zis.closeEntry();
}
} finally {
zis.close();
}
/* entry not found */
return null;
}
/** ECMA CRC64 polynomial. */
private static final long CRC_64_POLY =
new BigInteger("C96C5795D7870F42", 16).longValue();
/**
* Rolls CRC64 calculation.
*
* <p> {@code CRC64(data) = -1 ^ updateCrc64((... updateCrc64(-1, firstBlock), ...), lastBlock);}
* <p> This simple and reliable checksum is chosen to make is easy to calculate the same value
* across the variety of languages (C++, Java, Go, ...).
*/
public static long updateCrc64(long crc, byte[] data, int offset, int length) {
for (int i = offset; i < offset + length; ++i) {
long c = (crc ^ (long) (data[i] & 0xFF)) & 0xFF;
for (int k = 0; k < 8; k++) {
c = ((c & 1) == 1) ? CRC_64_POLY ^ (c >>> 1) : c >>> 1;
}
crc = c ^ (crc >>> 8);
}
return crc;
}
/**
* Calculates CRC64 of stream contents.
*/
public static long fingerprintStream(InputStream input) throws IOException {
byte[] buffer = new byte[65536];
long crc = -1;
while (true) {
int len = input.read(buffer);
if (len <= 0) {
break;
}
crc = updateCrc64(crc, buffer, 0, len);
}
return ~crc;
}
public static long getExpectedFingerprint(String entryName) {
int dotIndex = entryName.indexOf('.');
String entryCrcString = (dotIndex == -1) ? entryName : entryName.substring(0, dotIndex);
return new BigInteger(entryCrcString, 16).longValue();
}
}
|