blob: 0eab7bcb18cd0b553a2b5e128443aabe08786334 [file] [log] [blame]
/* 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();
}
}