diff options
Diffstat (limited to 'java/org/brotli/integration/BundleHelper.java')
-rwxr-xr-x | java/org/brotli/integration/BundleHelper.java | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/java/org/brotli/integration/BundleHelper.java b/java/org/brotli/integration/BundleHelper.java new file mode 100755 index 0000000..0eab7bc --- /dev/null +++ b/java/org/brotli/integration/BundleHelper.java @@ -0,0 +1,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(); + } +} |