mirror of
https://github.com/google/brotli.git
synced 2024-11-09 13:40:06 +00:00
add pure-kotlin decoder
PiperOrigin-RevId: 608917286
This commit is contained in:
parent
c1362a7903
commit
ccec9628e4
5
.github/workflows/build_test.yml
vendored
5
.github/workflows/build_test.yml
vendored
@ -320,8 +320,9 @@ jobs:
|
|||||||
export MAVEN_OPTS=-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn
|
export MAVEN_OPTS=-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn
|
||||||
cd java/org/brotli
|
cd java/org/brotli
|
||||||
mvn -B install
|
mvn -B install
|
||||||
cd integration
|
# TODO(eustas): nuke maven build?
|
||||||
mvn -B verify
|
# cd integration
|
||||||
|
# mvn -B verify
|
||||||
|
|
||||||
- uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c # v5.0.0
|
- uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c # v5.0.0
|
||||||
if: ${{ matrix.build_system == 'python' }}
|
if: ${{ matrix.build_system == 'python' }}
|
||||||
|
@ -9,6 +9,8 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive", "http_file"
|
|||||||
|
|
||||||
RULES_JVM_EXTERNAL_TAG = "4.0"
|
RULES_JVM_EXTERNAL_TAG = "4.0"
|
||||||
RULES_JVM_EXTERNAL_SHA = "31701ad93dbfe544d597dbe62c9a1fdd76d81d8a9150c2bf1ecf928ecdf97169"
|
RULES_JVM_EXTERNAL_SHA = "31701ad93dbfe544d597dbe62c9a1fdd76d81d8a9150c2bf1ecf928ecdf97169"
|
||||||
|
RULES_KOTLIN_VERSION = "1.9.0"
|
||||||
|
RULES_KOTLIN_SHA = "5766f1e599acf551aa56f49dab9ab9108269b03c557496c54acaf41f98e2b8d6"
|
||||||
|
|
||||||
http_archive(
|
http_archive(
|
||||||
name = "rules_jvm_external",
|
name = "rules_jvm_external",
|
||||||
@ -19,6 +21,18 @@ http_archive(
|
|||||||
|
|
||||||
load("@rules_jvm_external//:defs.bzl", "maven_install")
|
load("@rules_jvm_external//:defs.bzl", "maven_install")
|
||||||
|
|
||||||
|
http_archive(
|
||||||
|
name = "rules_kotlin",
|
||||||
|
urls = ["https://github.com/bazelbuild/rules_kotlin/releases/download/v%s/rules_kotlin-v%s.tar.gz" % (RULES_KOTLIN_VERSION, RULES_KOTLIN_VERSION)],
|
||||||
|
sha256 = RULES_KOTLIN_SHA,
|
||||||
|
)
|
||||||
|
|
||||||
|
load("@rules_kotlin//kotlin:repositories.bzl", "kotlin_repositories")
|
||||||
|
kotlin_repositories() # if you want the default. Otherwise see custom kotlinc distribution below
|
||||||
|
|
||||||
|
load("@rules_kotlin//kotlin:core.bzl", "kt_register_toolchains")
|
||||||
|
kt_register_toolchains() # to use the default toolchain, otherwise see toolchains below
|
||||||
|
|
||||||
maven_install(
|
maven_install(
|
||||||
artifacts = ["junit:junit:4.12"],
|
artifacts = ["junit:junit:4.12"],
|
||||||
repositories = [
|
repositories = [
|
||||||
|
@ -9,6 +9,7 @@ licenses(["notice"]) # MIT
|
|||||||
|
|
||||||
TEST_DEPS = [
|
TEST_DEPS = [
|
||||||
":dec",
|
":dec",
|
||||||
|
":test_utils",
|
||||||
"@maven//:junit_junit",
|
"@maven//:junit_junit",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -25,6 +26,12 @@ java_library(
|
|||||||
resources = ["//:license"],
|
resources = ["//:license"],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
java_library(
|
||||||
|
name = "test_utils",
|
||||||
|
srcs = ["TestUtils.java"],
|
||||||
|
deps = [":dec"],
|
||||||
|
)
|
||||||
|
|
||||||
brotli_java_test(
|
brotli_java_test(
|
||||||
name = "BitReaderTest",
|
name = "BitReaderTest",
|
||||||
srcs = ["BitReaderTest.java"],
|
srcs = ["BitReaderTest.java"],
|
||||||
@ -34,6 +41,7 @@ brotli_java_test(
|
|||||||
brotli_java_test(
|
brotli_java_test(
|
||||||
name = "DecodeTest",
|
name = "DecodeTest",
|
||||||
srcs = ["DecodeTest.java"],
|
srcs = ["DecodeTest.java"],
|
||||||
|
test_kotlin = True,
|
||||||
deps = TEST_DEPS,
|
deps = TEST_DEPS,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -52,6 +60,7 @@ brotli_java_test(
|
|||||||
brotli_java_test(
|
brotli_java_test(
|
||||||
name = "SynthTest",
|
name = "SynthTest",
|
||||||
srcs = ["SynthTest.java"],
|
srcs = ["SynthTest.java"],
|
||||||
|
test_kotlin = True,
|
||||||
deps = TEST_DEPS,
|
deps = TEST_DEPS,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -6,34 +6,27 @@
|
|||||||
|
|
||||||
package org.brotli.dec;
|
package org.brotli.dec;
|
||||||
|
|
||||||
|
import static org.brotli.dec.TestUtils.newBrotliInputStream;
|
||||||
|
import static org.brotli.dec.TestUtils.readUniBytes;
|
||||||
import static org.junit.Assert.assertArrayEquals;
|
import static org.junit.Assert.assertArrayEquals;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.junit.runners.JUnit4;
|
import org.junit.runners.JUnit4;
|
||||||
|
|
||||||
/**
|
/** Tests for {@link BrotliInputStream}. */
|
||||||
* Tests for {@link Decode}.
|
|
||||||
*/
|
|
||||||
@RunWith(JUnit4.class)
|
@RunWith(JUnit4.class)
|
||||||
public class DecodeTest {
|
public class DecodeTest {
|
||||||
|
|
||||||
static byte[] readUniBytes(String uniBytes) {
|
|
||||||
byte[] result = new byte[uniBytes.length()];
|
|
||||||
for (int i = 0; i < result.length; ++i) {
|
|
||||||
result[i] = (byte) uniBytes.charAt(i);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private byte[] decompress(byte[] data, boolean byByte) throws IOException {
|
private byte[] decompress(byte[] data, boolean byByte) throws IOException {
|
||||||
byte[] buffer = new byte[65536];
|
byte[] buffer = new byte[65536];
|
||||||
ByteArrayInputStream input = new ByteArrayInputStream(data);
|
ByteArrayInputStream input = new ByteArrayInputStream(data);
|
||||||
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
||||||
BrotliInputStream brotliInput = new BrotliInputStream(input);
|
InputStream brotliInput = newBrotliInputStream(input);
|
||||||
if (byByte) {
|
if (byByte) {
|
||||||
byte[] oneByte = new byte[1];
|
byte[] oneByte = new byte[1];
|
||||||
while (true) {
|
while (true) {
|
||||||
@ -68,16 +61,12 @@ public class DecodeTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEmpty() throws IOException {
|
public void testEmpty() throws IOException {
|
||||||
checkDecodeResource(
|
checkDecodeResource("", "\u0006");
|
||||||
"",
|
|
||||||
"\u0006");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testX() throws IOException {
|
public void testX() throws IOException {
|
||||||
checkDecodeResource(
|
checkDecodeResource("X", "\u000B\u0000\u0080X\u0003");
|
||||||
"X",
|
|
||||||
"\u000B\u0000\u0080X\u0003");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -91,54 +80,53 @@ public class DecodeTest {
|
|||||||
public void testX64() throws IOException {
|
public void testX64() throws IOException {
|
||||||
checkDecodeResource(
|
checkDecodeResource(
|
||||||
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
|
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
|
||||||
"\u001B\u003F\u0000\u0000$\u00B0\u00E2\u0099\u0080\u0012");
|
"\u001B?\u0000\u0000$\u00B0\u00E2\u0099\u0080\u0012");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUkkonooa() throws IOException {
|
public void testUkkonooa() throws IOException {
|
||||||
checkDecodeResource(
|
checkDecodeResource(
|
||||||
"ukko nooa, ukko nooa oli kunnon mies, kun han meni saunaan, "
|
"ukko nooa, ukko nooa oli kunnon mies, kun han meni saunaan, "
|
||||||
+ "pisti laukun naulaan, ukko nooa, ukko nooa oli kunnon mies.",
|
+ "pisti laukun naulaan, ukko nooa, ukko nooa oli kunnon mies.",
|
||||||
"\u001Bv\u0000\u0000\u0014J\u00AC\u009Bz\u00BD\u00E1\u0097\u009D\u007F\u008E\u00C2\u0082"
|
"\u001Bv\u0000\u0000\u0014J\u00AC\u009Bz\u00BD\u00E1\u0097\u009D\u007F\u008E\u00C2\u0082"
|
||||||
+ "6\u000E\u009C\u00E0\u0090\u0003\u00F7\u008B\u009E8\u00E6\u00B6\u0000\u00AB\u00C3\u00CA"
|
+ "6\u000E\u009C\u00E0\u0090\u0003\u00F7\u008B\u009E8\u00E6\u00B6\u0000\u00AB\u00C3\u00CA"
|
||||||
+ "\u00A0\u00C2\u00DAf6\u00DC\u00CD\u0080\u008D.!\u00D7n\u00E3\u00EAL\u00B8\u00F0\u00D2"
|
+ "\u00A0\u00C2\u00DAf6\u00DC\u00CD\u0080\u008D.!\u00D7n\u00E3\u00EAL\u00B8\u00F0\u00D2"
|
||||||
+ "\u00B8\u00C7\u00C2pM:\u00F0i~\u00A1\u00B8Es\u00AB\u00C4W\u001E");
|
+ "\u00B8\u00C7\u00C2pM:\u00F0i~\u00A1\u00B8Es\u00AB\u00C4W\u001E");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMonkey() throws IOException {
|
public void testMonkey() throws IOException {
|
||||||
checkDecodeResource(
|
checkDecodeResource(
|
||||||
"znxcvnmz,xvnm.,zxcnv.,xcn.z,vn.zvn.zxcvn.,zxcn.vn.v,znm.,vnzx.,vnzxc.vn.z,vnz.,nv.z,nvmz"
|
"znxcvnmz,xvnm.,zxcnv.,xcn.z,vn.zvn.zxcvn.,zxcn.vn.v,znm.,vnzx.,vnzxc.vn.z,vnz.,nv.z,nvmz"
|
||||||
+ "xc,nvzxcvcnm.,vczxvnzxcnvmxc.zmcnvzm.,nvmc,nzxmc,vn.mnnmzxc,vnxcnmv,znvzxcnmv,.xcnvm,zxc"
|
+ "xc,nvzxcvcnm.,vczxvnzxcnvmxc.zmcnvzm.,nvmc,nzxmc,vn.mnnmzxc,vnxcnmv,znvzxcnmv,.xcnvm,zxc"
|
||||||
+ "nzxv.zx,qweryweurqioweupropqwutioweupqrioweutiopweuriopweuriopqwurioputiopqwuriowuqeriou"
|
+ "nzxv.zx,qweryweurqioweupropqwutioweupqrioweutiopweuriopweuriopqwurioputiopqwuriowuqeriou"
|
||||||
+ "pqweropuweropqwurweuqriopuropqwuriopuqwriopuqweopruioqweurqweuriouqweopruioupqiytioqtyio"
|
+ "pqweropuweropqwurweuqriopuropqwuriopuqwriopuqweopruioqweurqweuriouqweopruioupqiytioqtyio"
|
||||||
+ "wtyqptypryoqweutioioqtweqruowqeytiowquiourowetyoqwupiotweuqiorweuqroipituqwiorqwtioweuri"
|
+ "wtyqptypryoqweutioioqtweqruowqeytiowquiourowetyoqwupiotweuqiorweuqroipituqwiorqwtioweuri"
|
||||||
+ "ouytuioerytuioweryuitoweytuiweyuityeruirtyuqriqweuropqweiruioqweurioqwuerioqwyuituierwot"
|
+ "ouytuioerytuioweryuitoweytuiweyuityeruirtyuqriqweuropqweiruioqweurioqwuerioqwyuituierwot"
|
||||||
+ "ueryuiotweyrtuiwertyioweryrueioqptyioruyiopqwtjkasdfhlafhlasdhfjklashjkfhasjklfhklasjdfh"
|
+ "ueryuiotweyrtuiwertyioweryrueioqptyioruyiopqwtjkasdfhlafhlasdhfjklashjkfhasjklfhklasjdfh"
|
||||||
+ "klasdhfjkalsdhfklasdhjkflahsjdkfhklasfhjkasdfhasfjkasdhfklsdhalghhaf;hdklasfhjklashjklfa"
|
+ "klasdhfjkalsdhfklasdhjkflahsjdkfhklasfhjkasdfhasfjkasdhfklsdhalghhaf;hdklasfhjklashjklfa"
|
||||||
+ "sdhfasdjklfhsdjklafsd;hkldadfjjklasdhfjasddfjklfhakjklasdjfkl;asdjfasfljasdfhjklasdfhjka"
|
+ "sdhfasdjklfhsdjklafsd;hkldadfjjklasdhfjasddfjklfhakjklasdjfkl;asdjfasfljasdfhjklasdfhjka"
|
||||||
+ "ghjkashf;djfklasdjfkljasdklfjklasdjfkljasdfkljaklfj",
|
+ "ghjkashf;djfklasdjfkljasdklfjklasdjfkljasdfkljaklfj",
|
||||||
"\u001BJ\u0003\u0000\u008C\u0094n\u00DE\u00B4\u00D7\u0096\u00B1x\u0086\u00F2-\u00E1\u001A"
|
"\u001BJ\u0003\u0000\u008C\u0094n\u00DE\u00B4\u00D7\u0096\u00B1x\u0086\u00F2-\u00E1\u001A"
|
||||||
+ "\u00BC\u000B\u001C\u00BA\u00A9\u00C7\u00F7\u00CCn\u00B2B4QD\u008BN\u0013\b\u00A0\u00CDn"
|
+ "\u00BC\u000B\u001C\u00BA\u00A9\u00C7\u00F7\u00CCn\u00B2B4QD\u008BN\u0013\b\u00A0\u00CDn"
|
||||||
+ "\u00E8,\u00A5S\u00A1\u009C],\u001D#\u001A\u00D2V\u00BE\u00DB\u00EB&\u00BA\u0003e|\u0096j"
|
+ "\u00E8,\u00A5S\u00A1\u009C],\u001D#\u001A\u00D2V\u00BE\u00DB\u00EB&\u00BA\u0003e|\u0096j"
|
||||||
+ "\u00A2v\u00EC\u00EF\u0087G3\u00D6\'\u000Ec\u0095\u00E2\u001D\u008D,\u00C5\u00D1(\u009F`"
|
+ "\u00A2v\u00EC\u00EF\u0087G3\u00D6\'\u000Ec\u0095\u00E2\u001D\u008D,\u00C5\u00D1(\u009F`"
|
||||||
+ "\u0094o\u0002\u008B\u00DD\u00AAd\u0094,\u001E;e|\u0007EZ\u00B2\u00E2\u00FCI\u0081,\u009F"
|
+ "\u0094o\u0002\u008B\u00DD\u00AAd\u0094,\u001E;e|\u0007EZ\u00B2\u00E2\u00FCI\u0081,\u009F"
|
||||||
+ "@\u00AE\u00EFh\u0081\u00AC\u0016z\u000F\u00F5;m\u001C\u00B9\u001E-_\u00D5\u00C8\u00AF^"
|
+ "@\u00AE\u00EFh\u0081\u00AC\u0016z\u000F\u00F5;m\u001C\u00B9\u001E-_\u00D5\u00C8\u00AF^"
|
||||||
+ "\u0085\u00AA\u0005\u00BESu\u00C2\u00B0\"\u008A\u0015\u00C6\u00A3\u00B1\u00E6B\u0014"
|
+ "\u0085\u00AA\u0005\u00BESu\u00C2\u00B0\"\u008A\u0015\u00C6\u00A3\u00B1\u00E6B\u0014"
|
||||||
+ "\u00F4\u0084TS\u0019_\u00BE\u00C3\u00F2\u001D\u00D1\u00B7\u00E5\u00DD\u00B6\u00D9#\u00C6"
|
+ "\u00F4\u0084TS\u0019_\u00BE\u00C3\u00F2\u001D\u00D1\u00B7\u00E5\u00DD\u00B6\u00D9#\u00C6"
|
||||||
+ "\u00F6\u009F\u009E\u00F6Me0\u00FB\u00C0qE\u0004\u00AD\u0003\u00B5\u00BE\u00C9\u00CB"
|
+ "\u00F6\u009F\u009E\u00F6Me0\u00FB\u00C0qE\u0004\u00AD\u0003\u00B5\u00BE\u00C9\u00CB\u00FD\u00E2PZFt\u0004\r"
|
||||||
+ "\u00FD\u00E2PZFt\u0004\r\u00FF \u0004w\u00B2m\'\u00BFG\u00A9\u009D\u001B\u0096,b\u0090#"
|
+ "\u00FF \u0004w\u00B2m\'\u00BFG\u00A9\u009D\u001B\u0096,b\u0090#"
|
||||||
+ "\u008B\u00E0\u00F8\u001D\u00CF\u00AF\u001D=\u00EE\u008A\u00C8u#f\u00DD\u00DE\u00D6m"
|
+ "\u008B\u00E0\u00F8\u001D\u00CF\u00AF\u001D=\u00EE\u008A\u00C8u#f\u00DD\u00DE\u00D6m\u00E3*\u0082\u008Ax\u008A\u00DB\u00E6"
|
||||||
+ "\u00E3*\u0082\u008Ax\u008A\u00DB\u00E6 L\u00B7\\c\u00BA0\u00E3?\u00B6\u00EE\u008C\""
|
+ " L\u00B7\\c\u00BA0\u00E3?\u00B6\u00EE\u008C\"\u00A2*\u00B0\"\n"
|
||||||
+ "\u00A2*\u00B0\"\n\u0099\u00FF=bQ\u00EE\b\u00F6=J\u00E4\u00CC\u00EF\"\u0087\u0011\u00E2"
|
+ "\u0099\u00FF=bQ\u00EE\b\u00F6=J\u00E4\u00CC\u00EF\"\u0087\u0011\u00E2"
|
||||||
+ "\u0083(\u00E4\u00F5\u008F5\u0019c[\u00E1Z\u0092s\u00DD\u00A1P\u009D8\\\u00EB\u00B5\u0003"
|
+ "\u0083(\u00E4\u00F5\u008F5\u0019c[\u00E1Z\u0092s\u00DD\u00A1P\u009D8\\\u00EB\u00B5\u0003jd\u0090\u0094\u00C8\u008D\u00FB/\u008A\u0086\"\u00CC\u001D\u0087\u00E0H\n"
|
||||||
+ "jd\u0090\u0094\u00C8\u008D\u00FB/\u008A\u0086\"\u00CC\u001D\u0087\u00E0H\n\u0096w\u00909"
|
+ "\u0096w\u00909\u00C6##H\u00FB\u0011GV\u00CA"
|
||||||
+ "\u00C6##H\u00FB\u0011GV\u00CA \u00E3B\u0081\u00F7w2\u00C1\u00A5\\@!e\u0017@)\u0017\u0017"
|
+ " \u00E3B\u0081\u00F7w2\u00C1\u00A5\\@!e\u0017@)\u0017\u0017lV2\u00988\u0006\u00DC\u0099M3)\u00BB\u0002\u00DFL&\u0093l\u0017\u0082\u0086"
|
||||||
+ "lV2\u00988\u0006\u00DC\u0099M3)\u00BB\u0002\u00DFL&\u0093l\u0017\u0082\u0086 \u00D7"
|
+ " \u00D7"
|
||||||
+ "\u0003y}\u009A\u0000\u00D7\u0087\u0000\u00E7\u000Bf\u00E3Lfqg\b2\u00F9\b>\u00813\u00CD"
|
+ "\u0003y}\u009A\u0000\u00D7\u0087\u0000\u00E7\u000Bf\u00E3Lfqg\b2\u00F9\b>\u00813\u00CD\u0017r1\u00F0\u00B8\u0094RK\u00901\u008Eh\u00C1\u00EF\u0090\u00C9\u00E5\u00F2a"
|
||||||
+ "\u0017r1\u00F0\u00B8\u0094RK\u00901\u008Eh\u00C1\u00EF\u0090\u00C9\u00E5\u00F2a\tr%"
|
+ "\tr%\u00AD\u00EC\u00C5b\u00C0\u000B\u0012\u0005\u00F7\u0091u\r"
|
||||||
+ "\u00AD\u00EC\u00C5b\u00C0\u000B\u0012\u0005\u00F7\u0091u\r\u00EEa..\u0019\t\u00C2\u0003"
|
+ "\u00EEa..\u0019\t\u00C2\u0003");
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -146,8 +134,8 @@ public class DecodeTest {
|
|||||||
checkDecodeResource(
|
checkDecodeResource(
|
||||||
"The quick brown fox jumps over the lazy dog",
|
"The quick brown fox jumps over the lazy dog",
|
||||||
"\u001B*\u0000\u0000\u0004\u0004\u00BAF:\u0085\u0003\u00E9\u00FA\f\u0091\u0002H\u0011,"
|
"\u001B*\u0000\u0000\u0004\u0004\u00BAF:\u0085\u0003\u00E9\u00FA\f\u0091\u0002H\u0011,"
|
||||||
+ "\u00F3\u008A:\u00A3V\u007F\u001A\u00AE\u00BF\u00A4\u00AB\u008EM\u00BF\u00ED\u00E2\u0004K"
|
+ "\u00F3\u008A:\u00A3V\u007F\u001A\u00AE\u00BF\u00A4\u00AB\u008EM\u00BF\u00ED\u00E2\u0004K"
|
||||||
+ "\u0091\u00FF\u0087\u00E9\u001E");
|
+ "\u0091\u00FF\u0087\u00E9\u001E");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
package org.brotli.dec;
|
package org.brotli.dec;
|
||||||
|
|
||||||
|
import static org.brotli.dec.TestUtils.newBrotliInputStream;
|
||||||
|
import static org.brotli.dec.TestUtils.readUniBytes;
|
||||||
import static org.junit.Assert.assertArrayEquals;
|
import static org.junit.Assert.assertArrayEquals;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
import static org.junit.Assume.assumeTrue;
|
import static org.junit.Assume.assumeTrue;
|
||||||
@ -13,29 +15,20 @@ import static org.junit.Assume.assumeTrue;
|
|||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.junit.runners.JUnit4;
|
import org.junit.runners.JUnit4;
|
||||||
|
|
||||||
/**
|
/** Tests for {@link BrotliInputStream}. */
|
||||||
* Tests for {@link Decode}.
|
|
||||||
*/
|
|
||||||
@RunWith(JUnit4.class)
|
@RunWith(JUnit4.class)
|
||||||
public class SynthTest {
|
public class SynthTest {
|
||||||
|
|
||||||
static byte[] readUniBytes(String uniBytes) {
|
|
||||||
byte[] result = new byte[uniBytes.length()];
|
|
||||||
for (int i = 0; i < result.length; ++i) {
|
|
||||||
result[i] = (byte) uniBytes.charAt(i);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private byte[] decompress(byte[] data) throws IOException {
|
private byte[] decompress(byte[] data) throws IOException {
|
||||||
byte[] buffer = new byte[65536];
|
byte[] buffer = new byte[65536];
|
||||||
ByteArrayInputStream input = new ByteArrayInputStream(data);
|
ByteArrayInputStream input = new ByteArrayInputStream(data);
|
||||||
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
||||||
BrotliInputStream brotliInput = new BrotliInputStream(input);
|
InputStream brotliInput = newBrotliInputStream(input);
|
||||||
while (true) {
|
while (true) {
|
||||||
int len = brotliInput.read(buffer, 0, buffer.length);
|
int len = brotliInput.read(buffer, 0, buffer.length);
|
||||||
if (len <= 0) {
|
if (len <= 0) {
|
||||||
@ -47,8 +40,7 @@ public class SynthTest {
|
|||||||
return output.toByteArray();
|
return output.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkSynth(byte[] compressed, boolean expectSuccess,
|
private void checkSynth(byte[] compressed, boolean expectSuccess, String expectedOutput) {
|
||||||
String expectedOutput) {
|
|
||||||
byte[] expected = readUniBytes(expectedOutput);
|
byte[] expected = readUniBytes(expectedOutput);
|
||||||
try {
|
try {
|
||||||
byte[] actual = decompress(compressed);
|
byte[] actual = decompress(compressed);
|
||||||
|
35
java/org/brotli/dec/TestUtils.java
Normal file
35
java/org/brotli/dec/TestUtils.java
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
package org.brotli.dec;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Common utility methods.
|
||||||
|
*/
|
||||||
|
public final class TestUtils {
|
||||||
|
|
||||||
|
public static InputStream newBrotliInputStream(InputStream input) throws IOException {
|
||||||
|
String brotliClass = System.getProperty("BROTLI_INPUT_STREAM");
|
||||||
|
if (brotliClass == null) {
|
||||||
|
return new BrotliInputStream(input);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Class<?> clazz = Class.forName(brotliClass);
|
||||||
|
Constructor<?> ctor = clazz.getConstructor(InputStream.class);
|
||||||
|
return (InputStream) ctor.newInstance(new Object[] { input });
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static byte[] readUniBytes(String uniBytes) {
|
||||||
|
byte[] result = new byte[uniBytes.length()];
|
||||||
|
for (int i = 0; i < result.length; ++i) {
|
||||||
|
result[i] = (byte) uniBytes.charAt(i);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private TestUtils() {}
|
||||||
|
}
|
@ -4,13 +4,19 @@ _TEST_JVM_FLAGS = [
|
|||||||
"-DBROTLI_ENABLE_ASSERTS=true",
|
"-DBROTLI_ENABLE_ASSERTS=true",
|
||||||
]
|
]
|
||||||
|
|
||||||
def brotli_java_test(name, main_class = None, jvm_flags = None, **kwargs):
|
_KOTLIN_DECODER_DEPS = [
|
||||||
|
"//org/brotli/dec/kt:dec",
|
||||||
|
]
|
||||||
|
|
||||||
|
def brotli_java_test(name, main_class = None, jvm_flags = None, test_kotlin = False, runtime_deps = [], **kwargs):
|
||||||
"""test duplication rule that creates 32/64-bit test pair.
|
"""test duplication rule that creates 32/64-bit test pair.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
name: target name prefix
|
name: target name prefix
|
||||||
main_class: override for test_class
|
main_class: override for test_class
|
||||||
jvm_flags: base Java VM options
|
jvm_flags: base Java VM options
|
||||||
|
test_kotlin: add target for Kotlin BrotliInputStream
|
||||||
|
runtime_deps: runtime target dependencies
|
||||||
**kwargs: pass-through
|
**kwargs: pass-through
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -31,6 +37,7 @@ def brotli_java_test(name, main_class = None, jvm_flags = None, **kwargs):
|
|||||||
test_class = test_class,
|
test_class = test_class,
|
||||||
jvm_flags = jvm_flags + ["-DBROTLI_32_BIT_CPU=true"],
|
jvm_flags = jvm_flags + ["-DBROTLI_32_BIT_CPU=true"],
|
||||||
visibility = ["//visibility:private"],
|
visibility = ["//visibility:private"],
|
||||||
|
runtime_deps = runtime_deps,
|
||||||
**kwargs
|
**kwargs
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -40,5 +47,17 @@ def brotli_java_test(name, main_class = None, jvm_flags = None, **kwargs):
|
|||||||
test_class = test_class,
|
test_class = test_class,
|
||||||
jvm_flags = jvm_flags + ["-DBROTLI_32_BIT_CPU=false"],
|
jvm_flags = jvm_flags + ["-DBROTLI_32_BIT_CPU=false"],
|
||||||
visibility = ["//visibility:private"],
|
visibility = ["//visibility:private"],
|
||||||
|
runtime_deps = runtime_deps,
|
||||||
**kwargs
|
**kwargs
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if test_kotlin:
|
||||||
|
native.java_test(
|
||||||
|
name = name + "_kt",
|
||||||
|
main_class = main_class,
|
||||||
|
test_class = test_class,
|
||||||
|
jvm_flags = jvm_flags + ["-DBROTLI_INPUT_STREAM=org.brotli.dec.kt.BrotliInputStream"],
|
||||||
|
visibility = ["//visibility:private"],
|
||||||
|
runtime_deps = runtime_deps + _KOTLIN_DECODER_DEPS,
|
||||||
|
**kwargs
|
||||||
|
)
|
||||||
|
17
java/org/brotli/dec/kt/BUILD.bazel
Normal file
17
java/org/brotli/dec/kt/BUILD.bazel
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
# Description:
|
||||||
|
# Korlin port of Brotli decoder.
|
||||||
|
|
||||||
|
load("@rules_kotlin//kotlin:jvm.bzl", "kt_jvm_library")
|
||||||
|
|
||||||
|
package(default_visibility = ["//visibility:public"])
|
||||||
|
|
||||||
|
licenses(["notice"]) # MIT
|
||||||
|
|
||||||
|
kt_jvm_library(
|
||||||
|
name = "dec",
|
||||||
|
srcs = [
|
||||||
|
"BrotliInputStream.kt",
|
||||||
|
"Decode.kt",
|
||||||
|
],
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
138
java/org/brotli/dec/kt/BrotliInputStream.kt
Normal file
138
java/org/brotli/dec/kt/BrotliInputStream.kt
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
/* Copyright 2015 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.dec.kt
|
||||||
|
|
||||||
|
import java.io.IOException
|
||||||
|
import java.io.InputStream
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [InputStream] decorator that decompresses brotli data.
|
||||||
|
*
|
||||||
|
* Not thread-safe.
|
||||||
|
*/
|
||||||
|
class BrotliInputStream
|
||||||
|
@JvmOverloads
|
||||||
|
constructor(source: InputStream, byteReadBufferSize: Int = DEFAULT_INTERNAL_BUFFER_SIZE) :
|
||||||
|
InputStream() {
|
||||||
|
|
||||||
|
/** Internal buffer used for efficient byte-by-byte reading. */
|
||||||
|
private val buffer: ByteArray
|
||||||
|
|
||||||
|
/** Number of decoded but still unused bytes in internal buffer. */
|
||||||
|
private var remainingBufferBytes: Int
|
||||||
|
|
||||||
|
/** Next unused byte offset. */
|
||||||
|
private var bufferOffset: Int
|
||||||
|
|
||||||
|
/** Decoder state. */
|
||||||
|
private val state: State = State()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a [InputStream] wrapper that decompresses brotli data.
|
||||||
|
*
|
||||||
|
* For byte-by-byte reading ([.read]) internal buffer with [.DEFAULT_INTERNAL_BUFFER_SIZE] size is
|
||||||
|
* allocated and used.
|
||||||
|
*
|
||||||
|
* Will block the thread until first [BitReader.CAPACITY] bytes of data of source are available.
|
||||||
|
*
|
||||||
|
* @param source underlying data source
|
||||||
|
* @throws IOException in case of corrupted data or source stream problems
|
||||||
|
*/
|
||||||
|
init {
|
||||||
|
require(byteReadBufferSize > 0) { "Bad buffer size:$byteReadBufferSize" }
|
||||||
|
buffer = ByteArray(byteReadBufferSize)
|
||||||
|
remainingBufferBytes = 0
|
||||||
|
bufferOffset = 0
|
||||||
|
try {
|
||||||
|
state.input = source
|
||||||
|
initState(state)
|
||||||
|
} catch (ex: BrotliRuntimeException) {
|
||||||
|
throw IOException("Brotli decoder initialization failed", ex)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun attachDictionaryChunk(data: ByteArray) {
|
||||||
|
attachDictionaryChunk(state, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun enableEagerOutput() {
|
||||||
|
enableEagerOutput(state)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun enableLargeWindow() {
|
||||||
|
enableLargeWindow(state)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
@Throws(IOException::class)
|
||||||
|
override fun close() {
|
||||||
|
close(state)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
@Throws(IOException::class)
|
||||||
|
override fun read(): Int {
|
||||||
|
if (bufferOffset >= remainingBufferBytes) {
|
||||||
|
remainingBufferBytes = read(buffer, 0, buffer.size)
|
||||||
|
bufferOffset = 0
|
||||||
|
if (remainingBufferBytes == END_OF_STREAM_MARKER) {
|
||||||
|
// Both Java and C# return the same value for EOF on single-byte read.
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buffer[bufferOffset++].toInt() and 0xFF
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
@Throws(IOException::class)
|
||||||
|
override fun read(destBuffer: ByteArray, destOffset: Int, destLen: Int): Int {
|
||||||
|
require(destOffset >= 0) { "Bad offset: $destOffset" }
|
||||||
|
require(destLen >= 0) { "Bad length: $destLen" }
|
||||||
|
require(destOffset + destLen <= destBuffer.size) {
|
||||||
|
"Buffer overflow: " + (destOffset + destLen) + " > " + destBuffer.size
|
||||||
|
}
|
||||||
|
if (destLen == 0) {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
var copyLen = Math.max(remainingBufferBytes - bufferOffset, 0)
|
||||||
|
var offset = destOffset
|
||||||
|
var len = destLen
|
||||||
|
if (copyLen != 0) {
|
||||||
|
copyLen = Math.min(copyLen, len)
|
||||||
|
System.arraycopy(buffer, bufferOffset, destBuffer, offset, copyLen)
|
||||||
|
bufferOffset += copyLen
|
||||||
|
offset += copyLen
|
||||||
|
len -= copyLen
|
||||||
|
if (len == 0) {
|
||||||
|
return copyLen
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return try {
|
||||||
|
state.output = destBuffer
|
||||||
|
state.outputOffset = offset
|
||||||
|
state.outputLength = len
|
||||||
|
state.outputUsed = 0
|
||||||
|
decompress(state)
|
||||||
|
copyLen += state.outputUsed
|
||||||
|
copyLen = if (copyLen > 0) copyLen else END_OF_STREAM_MARKER
|
||||||
|
copyLen
|
||||||
|
} catch (ex: BrotliRuntimeException) {
|
||||||
|
throw IOException("Brotli stream decoding failed", ex)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val DEFAULT_INTERNAL_BUFFER_SIZE = 256
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Value expected by InputStream contract when stream is over.
|
||||||
|
*
|
||||||
|
* In Java it is -1. In C# it is 0 (should be patched during transpilation).
|
||||||
|
*/
|
||||||
|
private const val END_OF_STREAM_MARKER = -1
|
||||||
|
}
|
||||||
|
}
|
1845
java/org/brotli/dec/kt/Decode.kt
Normal file
1845
java/org/brotli/dec/kt/Decode.kt
Normal file
File diff suppressed because one or more lines are too long
@ -23,9 +23,10 @@ java_library(
|
|||||||
java_library(
|
java_library(
|
||||||
name = "bundle_checker",
|
name = "bundle_checker",
|
||||||
srcs = ["BundleChecker.java"],
|
srcs = ["BundleChecker.java"],
|
||||||
|
runtime_deps = ["//org/brotli/dec"],
|
||||||
deps = [
|
deps = [
|
||||||
":bundle_helper",
|
":bundle_helper",
|
||||||
"//org/brotli/dec",
|
"//org/brotli/dec:test_utils",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -6,7 +6,8 @@
|
|||||||
|
|
||||||
package org.brotli.integration;
|
package org.brotli.integration;
|
||||||
|
|
||||||
import org.brotli.dec.BrotliInputStream;
|
import static org.brotli.dec.TestUtils.newBrotliInputStream;
|
||||||
|
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.FilterInputStream;
|
import java.io.FilterInputStream;
|
||||||
@ -45,7 +46,7 @@ public class BundleChecker implements Runnable {
|
|||||||
public void close() {}
|
public void close() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
BrotliInputStream decompressedStream = new BrotliInputStream(entryStream);
|
InputStream decompressedStream = newBrotliInputStream(entryStream);
|
||||||
long crc;
|
long crc;
|
||||||
try {
|
try {
|
||||||
crc = BundleHelper.fingerprintStream(decompressedStream);
|
crc = BundleHelper.fingerprintStream(decompressedStream);
|
||||||
|
Loading…
Reference in New Issue
Block a user