From 36e05c72a73f96768d9af78cb1c209a37b64be14098a3395b68b2314e27ed850 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Wed, 26 Aug 2020 16:39:18 +0000 Subject: [PATCH] - Update to 1.0.8 OBS-URL: https://build.opensuse.org/package/show/Archiving/brotli?expand=0&rev=25 --- brotli-1.0.7.tar.gz | 3 - brotli.changes | 11 + brotli.spec | 13 +- ...ure-decompression-consumes-all-input.patch | 74 - brotli_Verbose-CLI+Shared-Brotli.patch | 1375 ----------------- v1.0.8.tar.gz | 3 + 6 files changed, 17 insertions(+), 1462 deletions(-) delete mode 100644 brotli-1.0.7.tar.gz delete mode 100644 brotli_Ensure-decompression-consumes-all-input.patch delete mode 100644 brotli_Verbose-CLI+Shared-Brotli.patch create mode 100644 v1.0.8.tar.gz diff --git a/brotli-1.0.7.tar.gz b/brotli-1.0.7.tar.gz deleted file mode 100644 index 98f9eb9..0000000 --- a/brotli-1.0.7.tar.gz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4c61bfb0faca87219ea587326c467b95acb25555b53d1a421ffa3c8a9296ee2c -size 23827908 diff --git a/brotli.changes b/brotli.changes index 6c79ca1..bb03ba9 100644 --- a/brotli.changes +++ b/brotli.changes @@ -1,3 +1,14 @@ +------------------------------------------------------------------- +Wed Aug 26 16:30:45 UTC 2020 - Jan Engelhardt + +- Update to 1.0.8 + * Fix integer overflow when input chunk is longer than 2GiB + * `brotli -v` now reports raw / compressed size + * decoder: minor speed / memory usage improvements + * encoder: fix rare access to uninitialized data in ring-buffer +- Drop brotli_Ensure-decompression-consumes-all-input.patch, + brotli_Verbose-CLI+Shared-Brotli.patch (merged) + ------------------------------------------------------------------- Wed Aug 12 14:52:42 UTC 2020 - andy great diff --git a/brotli.spec b/brotli.spec index b38ae12..d377b55 100644 --- a/brotli.spec +++ b/brotli.spec @@ -19,17 +19,15 @@ %define sover 1 Name: brotli -Version: 1.0.7 +Version: 1.0.8 Release: 0 Summary: Lossless Compression Algorithm License: MIT Group: Productivity/Archiving/Compression URL: https://github.com/google/brotli -Source: %url/archive/v%version.tar.gz#/%name-%version.tar.gz +Source: https://github.com/google/brotli/archive/v%version.tar.gz Source99: baselibs.conf -Patch: brotli_Verbose-CLI+Shared-Brotli.patch -Patch1: brotli_Ensure-decompression-consumes-all-input.patch -BuildRequires: cmake >= 2.8.6 +BuildRequires: cmake BuildRequires: gcc-c++ BuildRequires: gzip BuildRequires: pkg-config @@ -123,25 +121,20 @@ install -pm0644 docs/*.3 "%buildroot/%_mandir/man3/" %postun -n libbrotlienc%sover -p /sbin/ldconfig %files -%defattr(-,root,root) %license LICENSE %_bindir/brotli %_mandir/man1/brotli.1* %files -n libbrotlicommon%sover -%defattr(-,root,root) %_libdir/libbrotlicommon.so.* %files -n libbrotlidec%sover -%defattr(-,root,root) %_libdir/libbrotlidec.so.* %files -n libbrotlienc%sover -%defattr(-,root,root) %_libdir/libbrotlienc.so.* %files -n libbrotli-devel -%defattr(-,root,root) %_includedir/brotli/ %_libdir/libbrotlicommon.so %_libdir/libbrotlidec.so diff --git a/brotli_Ensure-decompression-consumes-all-input.patch b/brotli_Ensure-decompression-consumes-all-input.patch deleted file mode 100644 index cc60b6d..0000000 --- a/brotli_Ensure-decompression-consumes-all-input.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 5805f99a533a8f8118699c0100d8c102f3605f65 Mon Sep 17 00:00:00 2001 -From: Justin Ridgewell -Date: Mon, 12 Nov 2018 04:36:00 -0500 -Subject: [PATCH] Ensure decompression consumes all input (#730) - -* Ensure decompression consumes all input - -If not, it's a corrupt stream. - -* Use byte strings ---- - python/_brotli.cc | 4 ++-- - python/tests/decompress_test.py | 4 ++++ - python/tests/decompressor_test.py | 9 +++++++++ - 3 files changed, 15 insertions(+), 2 deletions(-) - -diff --git a/python/_brotli.cc b/python/_brotli.cc -index a6f925ef..5e1828e9 100644 ---- a/python/_brotli.cc -+++ b/python/_brotli.cc -@@ -414,7 +414,7 @@ static BROTLI_BOOL decompress_stream(BrotliDecoderState* dec, - (*output).insert((*output).end(), buffer, buffer + buffer_length); - } - } -- ok = result != BROTLI_DECODER_RESULT_ERROR; -+ ok = result != BROTLI_DECODER_RESULT_ERROR && !available_in; - - Py_END_ALLOW_THREADS - return ok; -@@ -672,7 +672,7 @@ static PyObject* brotli_decompress(PyObject *self, PyObject *args, PyObject *key - if (available_out != 0) - output.insert(output.end(), next_out, next_out + available_out); - } -- ok = result == BROTLI_DECODER_RESULT_SUCCESS; -+ ok = result == BROTLI_DECODER_RESULT_SUCCESS && !available_in; - BrotliDecoderDestroyInstance(state); - - Py_END_ALLOW_THREADS -diff --git a/python/tests/decompress_test.py b/python/tests/decompress_test.py -index 7a9e9e30..814e5633 100644 ---- a/python/tests/decompress_test.py -+++ b/python/tests/decompress_test.py -@@ -31,6 +31,10 @@ def _test_decompress(self, test_data): - self._decompress(test_data) - self._check_decompression(test_data) - -+ def test_garbage_appended(self): -+ with self.assertRaises(brotli.error): -+ brotli.decompress(brotli.compress(b'a') + b'a') -+ - - _test_utils.generate_test_methods(TestDecompress, for_decompression=True) - -diff --git a/python/tests/decompressor_test.py b/python/tests/decompressor_test.py -index 99667bcd..05918ada 100644 ---- a/python/tests/decompressor_test.py -+++ b/python/tests/decompressor_test.py -@@ -43,6 +43,15 @@ def _test_decompress(self, test_data): - self._decompress(test_data) - self._check_decompression(test_data) - -+ def test_garbage_appended(self): -+ with self.assertRaises(brotli.error): -+ self.decompressor.process(brotli.compress(b'a') + b'a') -+ -+ def test_already_finished(self): -+ self.decompressor.process(brotli.compress(b'a')) -+ with self.assertRaises(brotli.error): -+ self.decompressor.process(b'a') -+ - - _test_utils.generate_test_methods(TestDecompressor, for_decompression=True) - - diff --git a/brotli_Verbose-CLI+Shared-Brotli.patch b/brotli_Verbose-CLI+Shared-Brotli.patch deleted file mode 100644 index a555bf4..0000000 --- a/brotli_Verbose-CLI+Shared-Brotli.patch +++ /dev/null @@ -1,1375 +0,0 @@ -From d0ffe60b87aa5ec302fcb031c8ebf726c1a1692a Mon Sep 17 00:00:00 2001 -From: Eugene Kliuchnikov -Date: Wed, 24 Oct 2018 16:06:09 +0200 -Subject: [PATCH] Verbose CLI + start pulling "Shared-Brotli" (#722) - -* Verbose CLI + start pulling "Shared-Brotli" - - * vesbose CLI output; fix #666 - * pull `SHIFT` transforms; currently this is semantically dead code; - later it will be used by "Shared-Brotli" ---- - c/common/transform.c | 56 +++ - c/common/transform.h | 5 + - c/enc/backward_references.h | 6 +- - c/enc/backward_references_hq.c | 11 +- - c/enc/backward_references_hq.h | 10 +- - c/enc/backward_references_inc.h | 6 +- - c/enc/encode.c | 2 - - c/enc/encoder_dict.c | 1 - - c/tools/brotli.c | 54 ++- - java/org/brotli/dec/BrotliInputStream.java | 12 +- - java/org/brotli/dec/Decode.java | 63 ++- - java/org/brotli/dec/SynthTest.java | 513 ++++++++++++++++++++- - java/org/brotli/dec/Transform.java | 183 ++++++-- - java/org/brotli/dec/TransformTest.java | 14 +- - 14 files changed, 848 insertions(+), 88 deletions(-) - -diff --git a/c/common/transform.c b/c/common/transform.c -index 426e635f..c182053d 100755 ---- a/c/common/transform.c -+++ b/c/common/transform.c -@@ -166,6 +166,7 @@ static BrotliTransforms kBrotliTransforms = { - kPrefixSuffixMap, - sizeof(kTransformsData) / (3 * sizeof(kTransformsData[0])), - kTransformsData, -+ NULL, /* no extra parameters */ - {0, 12, 27, 23, 42, 63, 56, 48, 59, 64} - }; - -@@ -190,6 +191,48 @@ static int ToUpperCase(uint8_t* p) { - return 3; - } - -+static int Shift(uint8_t* word, int word_len, uint16_t parameter) { -+ /* Limited sign extension: scalar < (1 << 24). */ -+ uint32_t scalar = -+ (parameter & 0x7FFFu) + (0x1000000u - (parameter & 0x8000u)); -+ if (word[0] < 0x80) { -+ /* 1-byte rune / 0sssssss / 7 bit scalar (ASCII). */ -+ scalar += (uint32_t)word[0]; -+ word[0] = (uint8_t)(scalar & 0x7Fu); -+ return 1; -+ } else if (word[0] < 0xC0) { -+ /* Continuation / 10AAAAAA. */ -+ return 1; -+ } else if (word[0] < 0xE0) { -+ /* 2-byte rune / 110sssss AAssssss / 11 bit scalar. */ -+ if (word_len < 2) return 1; -+ scalar += (uint32_t)((word[1] & 0x3Fu) | ((word[0] & 0x1Fu) << 6u)); -+ word[0] = (uint8_t)(0xC0 | ((scalar >> 6u) & 0x1F)); -+ word[1] = (uint8_t)((word[1] & 0xC0) | (scalar & 0x3F)); -+ return 2; -+ } else if (word[0] < 0xF0) { -+ /* 3-byte rune / 1110ssss AAssssss BBssssss / 16 bit scalar. */ -+ if (word_len < 3) return word_len; -+ scalar += (uint32_t)((word[2] & 0x3Fu) | ((word[1] & 0x3Fu) << 6u) | -+ ((word[0] & 0x0Fu) << 12u)); -+ word[0] = (uint8_t)(0xE0 | ((scalar >> 12u) & 0x0F)); -+ word[1] = (uint8_t)((word[1] & 0xC0) | ((scalar >> 6u) & 0x3F)); -+ word[2] = (uint8_t)((word[2] & 0xC0) | (scalar & 0x3F)); -+ return 3; -+ } else if (word[0] < 0xF8) { -+ /* 4-byte rune / 11110sss AAssssss BBssssss CCssssss / 21 bit scalar. */ -+ if (word_len < 4) return word_len; -+ scalar += (uint32_t)((word[3] & 0x3Fu) | ((word[2] & 0x3Fu) << 6u) | -+ ((word[1] & 0x3Fu) << 12u) | ((word[0] & 0x07u) << 18u)); -+ word[0] = (uint8_t)(0xF0 | ((scalar >> 18u) & 0x07)); -+ word[1] = (uint8_t)((word[1] & 0xC0) | ((scalar >> 12u) & 0x3F)); -+ word[2] = (uint8_t)((word[2] & 0xC0) | ((scalar >> 6u) & 0x3F)); -+ word[3] = (uint8_t)((word[3] & 0xC0) | (scalar & 0x3F)); -+ return 4; -+ } -+ return 1; -+} -+ - int BrotliTransformDictionaryWord(uint8_t* dst, const uint8_t* word, int len, - const BrotliTransforms* transforms, int transform_idx) { - int idx = 0; -@@ -221,6 +264,19 @@ int BrotliTransformDictionaryWord(uint8_t* dst, const uint8_t* word, int len, - uppercase += step; - len -= step; - } -+ } else if (t == BROTLI_TRANSFORM_SHIFT_FIRST) { -+ uint16_t param = (uint16_t)(transforms->params[transform_idx * 2] -+ + (transforms->params[transform_idx * 2 + 1] << 8u)); -+ Shift(&dst[idx - len], len, param); -+ } else if (t == BROTLI_TRANSFORM_SHIFT_ALL) { -+ uint16_t param = (uint16_t)(transforms->params[transform_idx * 2] -+ + (transforms->params[transform_idx * 2 + 1] << 8u)); -+ uint8_t* shift = &dst[idx - len]; -+ while (len > 0) { -+ int step = Shift(shift, len, param); -+ shift += step; -+ len -= step; -+ } - } - } - { -diff --git a/c/common/transform.h b/c/common/transform.h -index 456c12db..b6f86cc7 100755 ---- a/c/common/transform.h -+++ b/c/common/transform.h -@@ -37,6 +37,8 @@ enum BrotliWordTransformType { - BROTLI_TRANSFORM_OMIT_FIRST_7 = 18, - BROTLI_TRANSFORM_OMIT_FIRST_8 = 19, - BROTLI_TRANSFORM_OMIT_FIRST_9 = 20, -+ BROTLI_TRANSFORM_SHIFT_FIRST = 21, -+ BROTLI_TRANSFORM_SHIFT_ALL = 22, - BROTLI_NUM_TRANSFORM_TYPES /* Counts transforms, not a transform itself. */ - }; - -@@ -50,6 +52,9 @@ typedef struct BrotliTransforms { - uint32_t num_transforms; - /* Each entry is a [prefix_id, transform, suffix_id] triplet. */ - const uint8_t* transforms; -+ /* Shift for BROTLI_TRANSFORM_SHIFT_FIRST and BROTLI_TRANSFORM_SHIFT_ALL, -+ must be NULL if and only if no such transforms are present. */ -+ const uint8_t* params; - /* Indices of transforms like ["", BROTLI_TRANSFORM_OMIT_LAST_#, ""]. - 0-th element corresponds to ["", BROTLI_TRANSFORM_IDENTITY, ""]. - -1, if cut-off transform does not exist. */ -diff --git a/c/enc/backward_references.h b/c/enc/backward_references.h -index 3a414664..f82a80da 100644 ---- a/c/enc/backward_references.h -+++ b/c/enc/backward_references.h -@@ -25,9 +25,9 @@ extern "C" { - initially the total amount of commands output by previous - CreateBackwardReferences calls, and must be incremented by the amount written - by this call. */ --BROTLI_INTERNAL void BrotliCreateBackwardReferences( -- size_t num_bytes, size_t position, const uint8_t* ringbuffer, -- size_t ringbuffer_mask, const BrotliEncoderParams* params, -+BROTLI_INTERNAL void BrotliCreateBackwardReferences(size_t num_bytes, -+ size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask, -+ const BrotliEncoderParams* params, - HasherHandle hasher, int* dist_cache, size_t* last_insert_len, - Command* commands, size_t* num_commands, size_t* num_literals); - -diff --git a/c/enc/backward_references_hq.c b/c/enc/backward_references_hq.c -index 96b0e708..5737f752 100644 ---- a/c/enc/backward_references_hq.c -+++ b/c/enc/backward_references_hq.c -@@ -419,8 +419,8 @@ static size_t UpdateNodes( - size_t k; - size_t gap = 0; - -- EvaluateNode(block_start, pos, max_backward_limit, gap, starting_dist_cache, -- model, queue, nodes); -+ EvaluateNode(block_start, pos, max_backward_limit, gap, -+ starting_dist_cache, model, queue, nodes); - - { - const PosData* posdata = StartPosQueueAt(queue, 0); -@@ -587,9 +587,10 @@ void BrotliZopfliCreateCommands(const size_t num_bytes, - { - size_t distance = ZopfliNodeCopyDistance(next); - size_t len_code = ZopfliNodeLengthCode(next); -- size_t max_distance = -- BROTLI_MIN(size_t, block_start + pos, max_backward_limit); -- BROTLI_BOOL is_dictionary = TO_BROTLI_BOOL(distance > max_distance + gap); -+ size_t max_distance = BROTLI_MIN(size_t, -+ block_start + pos, max_backward_limit); -+ BROTLI_BOOL is_dictionary = -+ TO_BROTLI_BOOL(distance > max_distance + gap); - size_t dist_code = ZopfliNodeDistanceCode(next); - InitCommand(&commands[i], ¶ms->dist, insert_length, - copy_length, (int)len_code - (int)copy_length, dist_code); -diff --git a/c/enc/backward_references_hq.h b/c/enc/backward_references_hq.h -index 1e4275d4..fb1ff3fa 100644 ---- a/c/enc/backward_references_hq.h -+++ b/c/enc/backward_references_hq.h -@@ -23,14 +23,16 @@ extern "C" { - #endif - - BROTLI_INTERNAL void BrotliCreateZopfliBackwardReferences(MemoryManager* m, -- size_t num_bytes, size_t position, const uint8_t* ringbuffer, -- size_t ringbuffer_mask, const BrotliEncoderParams* params, -+ size_t num_bytes, -+ size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask, -+ const BrotliEncoderParams* params, - HasherHandle hasher, int* dist_cache, size_t* last_insert_len, - Command* commands, size_t* num_commands, size_t* num_literals); - - BROTLI_INTERNAL void BrotliCreateHqZopfliBackwardReferences(MemoryManager* m, -- size_t num_bytes, size_t position, const uint8_t* ringbuffer, -- size_t ringbuffer_mask, const BrotliEncoderParams* params, -+ size_t num_bytes, -+ size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask, -+ const BrotliEncoderParams* params, - HasherHandle hasher, int* dist_cache, size_t* last_insert_len, - Command* commands, size_t* num_commands, size_t* num_literals); - -diff --git a/c/enc/backward_references_inc.h b/c/enc/backward_references_inc.h -index c18cdb00..e29daf33 100644 ---- a/c/enc/backward_references_inc.h -+++ b/c/enc/backward_references_inc.h -@@ -60,7 +60,8 @@ static BROTLI_NOINLINE void EXPORT_FN(CreateBackwardReferences)( - FN(FindLongestMatch)(hasher, - ¶ms->dictionary, - ringbuffer, ringbuffer_mask, dist_cache, position + 1, max_length, -- max_distance, gap, params->dist.max_distance, &sr2); -+ max_distance, gap, params->dist.max_distance, -+ &sr2); - if (sr2.score >= sr.score + cost_diff_lazy) { - /* Ok, let's just write one byte for now and start a match from the - next byte. */ -@@ -76,7 +77,8 @@ static BROTLI_NOINLINE void EXPORT_FN(CreateBackwardReferences)( - } - apply_random_heuristics = - position + 2 * sr.len + random_heuristics_window_size; -- max_distance = BROTLI_MIN(size_t, position, max_backward_limit); -+ max_distance = BROTLI_MIN(size_t, -+ position, max_backward_limit); - { - /* The first 16 codes are special short-codes, - and the minimum offset is 1. */ -diff --git a/c/enc/encode.c b/c/enc/encode.c -index 141e70aa..c82f2d3f 100644 ---- a/c/enc/encode.c -+++ b/c/enc/encode.c -@@ -114,8 +114,6 @@ typedef struct BrotliEncoderStateStruct { - BROTLI_BOOL is_initialized_; - } BrotliEncoderStateStruct; - --static BROTLI_BOOL EnsureInitialized(BrotliEncoderState* s); -- - static size_t InputBlockSize(BrotliEncoderState* s) { - return (size_t)1 << s->params.lgblock; - } -diff --git a/c/enc/encoder_dict.c b/c/enc/encoder_dict.c -index 8b2f6ad4..e58ca670 100755 ---- a/c/enc/encoder_dict.c -+++ b/c/enc/encoder_dict.c -@@ -24,7 +24,6 @@ void BrotliInitEncoderDictionary(BrotliEncoderDictionary* dict) { - - dict->cutoffTransformsCount = kCutoffTransformsCount; - dict->cutoffTransforms = kCutoffTransforms; -- - } - - #if defined(__cplusplus) || defined(c_plusplus) -diff --git a/c/tools/brotli.c b/c/tools/brotli.c -index ce05b641..838539ad 100644 ---- a/c/tools/brotli.c -+++ b/c/tools/brotli.c -@@ -86,10 +86,10 @@ typedef struct { - /* Parameters */ - int quality; - int lgwin; -+ int verbosity; - BROTLI_BOOL force_overwrite; - BROTLI_BOOL junk_source; - BROTLI_BOOL copy_stat; -- BROTLI_BOOL verbose; - BROTLI_BOOL write_to_stdout; - BROTLI_BOOL test_integrity; - BROTLI_BOOL decompress; -@@ -121,6 +121,12 @@ typedef struct { - const uint8_t* next_in; - size_t available_out; - uint8_t* next_out; -+ -+ /* Reporting */ -+ /* size_t would be large enough, -+ until 4GiB+ files are compressed / decompressed on 32-bit CPUs. */ -+ size_t total_in; -+ size_t total_out; - } Context; - - /* Parse up to 5 decimal digits. */ -@@ -279,11 +285,11 @@ static Command ParseParams(Context* params) { - command = COMMAND_TEST_INTEGRITY; - continue; - } else if (c == 'v') { -- if (params->verbose) { -+ if (params->verbosity > 0) { - fprintf(stderr, "argument --verbose / -v already set\n"); - return COMMAND_INVALID; - } -- params->verbose = BROTLI_TRUE; -+ params->verbosity = 1; - continue; - } else if (c == 'V') { - /* Don't parse further. */ -@@ -415,11 +421,11 @@ static Command ParseParams(Context* params) { - command_set = BROTLI_TRUE; - command = COMMAND_TEST_INTEGRITY; - } else if (strcmp("verbose", arg) == 0) { -- if (params->verbose) { -+ if (params->verbosity > 0) { - fprintf(stderr, "argument --verbose / -v already set\n"); - return COMMAND_INVALID; - } -- params->verbose = BROTLI_TRUE; -+ params->verbosity = 1; - } else if (strcmp("version", arg) == 0) { - /* Don't parse further. */ - return COMMAND_VERSION; -@@ -787,6 +793,8 @@ static void InitializeBuffers(Context* context) { - context->next_in = NULL; - context->available_out = kFileBufferSize; - context->next_out = context->output; -+ context->total_in = 0; -+ context->total_out = 0; - } - - static BROTLI_BOOL HasMoreInput(Context* context) { -@@ -796,6 +804,7 @@ static BROTLI_BOOL HasMoreInput(Context* context) { - static BROTLI_BOOL ProvideInput(Context* context) { - context->available_in = - fread(context->input, 1, kFileBufferSize, context->fin); -+ context->total_in += context->available_in; - context->next_in = context->input; - if (ferror(context->fin)) { - fprintf(stderr, "failed to read input [%s]: %s\n", -@@ -808,6 +817,7 @@ static BROTLI_BOOL ProvideInput(Context* context) { - /* Internal: should be used only in Provide-/Flush-Output. */ - static BROTLI_BOOL WriteOutput(Context* context) { - size_t out_size = (size_t)(context->next_out - context->output); -+ context->total_out += out_size; - if (out_size == 0) return BROTLI_TRUE; - if (context->test_integrity) return BROTLI_TRUE; - -@@ -833,6 +843,25 @@ static BROTLI_BOOL FlushOutput(Context* context) { - return BROTLI_TRUE; - } - -+static void PrintBytes(size_t value) { -+ if (value < 1024) { -+ fprintf(stderr, "%d B", (int)value); -+ } else if (value < 1048576) { -+ fprintf(stderr, "%0.3f KiB", (double)value / 1024.0); -+ } else if (value < 1073741824) { -+ fprintf(stderr, "%0.3f MiB", (double)value / 1048576.0); -+ } else { -+ fprintf(stderr, "%0.3f GiB", (double)value / 1073741824.0); -+ } -+} -+ -+static void PrintFileProcessingProgress(Context* context) { -+ fprintf(stderr, "[%s]: ", PrintablePath(context->current_input_path)); -+ PrintBytes(context->total_in); -+ fprintf(stderr, " -> "); -+ PrintBytes(context->total_out); -+} -+ - static BROTLI_BOOL DecompressFile(Context* context, BrotliDecoderState* s) { - BrotliDecoderResult result = BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT; - InitializeBuffers(context); -@@ -853,6 +882,11 @@ static BROTLI_BOOL DecompressFile(Context* context, BrotliDecoderState* s) { - PrintablePath(context->current_input_path)); - return BROTLI_FALSE; - } -+ if (context->verbosity > 0) { -+ fprintf(stderr, "Decompressed "); -+ PrintFileProcessingProgress(context); -+ fprintf(stderr, "\n"); -+ } - return BROTLI_TRUE; - } else { - fprintf(stderr, "corrupt input [%s]\n", -@@ -915,7 +949,13 @@ static BROTLI_BOOL CompressFile(Context* context, BrotliEncoderState* s) { - } - - if (BrotliEncoderIsFinished(s)) { -- return FlushOutput(context); -+ if (!FlushOutput(context)) return BROTLI_FALSE; -+ if (context->verbosity > 0) { -+ fprintf(stderr, "Compressed "); -+ PrintFileProcessingProgress(context); -+ fprintf(stderr, "\n"); -+ } -+ return BROTLI_TRUE; - } - } - } -@@ -979,11 +1019,11 @@ int main(int argc, char** argv) { - - context.quality = 11; - context.lgwin = -1; -+ context.verbosity = 0; - context.force_overwrite = BROTLI_FALSE; - context.junk_source = BROTLI_FALSE; - context.copy_stat = BROTLI_TRUE; - context.test_integrity = BROTLI_FALSE; -- context.verbose = BROTLI_FALSE; - context.write_to_stdout = BROTLI_FALSE; - context.decompress = BROTLI_FALSE; - context.large_window = BROTLI_FALSE; -diff --git a/java/org/brotli/dec/BrotliInputStream.java b/java/org/brotli/dec/BrotliInputStream.java -index a27e9284..5cc2e284 100644 ---- a/java/org/brotli/dec/BrotliInputStream.java -+++ b/java/org/brotli/dec/BrotliInputStream.java -@@ -85,7 +85,17 @@ public BrotliInputStream(InputStream source, int byteReadBufferSize) throws IOEx - } - - public void setEager(boolean eager) { -- state.isEager = eager ? 1 : 0; -+ boolean isEager = (state.isEager != 0); -+ if (eager == isEager) { -+ /* Shortcut for no-op change. */ -+ return; -+ } -+ if (eager) { -+ Decode.setEager(state); -+ } else { -+ /* Once decoder is "eager", there is no way back. */ -+ throw new IllegalStateException("Brotli decoder has been already switched to eager mode"); -+ } - } - - /** -diff --git a/java/org/brotli/dec/Decode.java b/java/org/brotli/dec/Decode.java -index 9e3d43b0..60bf9c61 100644 ---- a/java/org/brotli/dec/Decode.java -+++ b/java/org/brotli/dec/Decode.java -@@ -18,18 +18,19 @@ - // RunningState - //---------------------------------------------------------------------------- - private static final int UNINITIALIZED = 0; -- private static final int BLOCK_START = 1; -- private static final int COMPRESSED_BLOCK_START = 2; -- private static final int MAIN_LOOP = 3; -- private static final int READ_METADATA = 4; -- private static final int COPY_UNCOMPRESSED = 5; -- private static final int INSERT_LOOP = 6; -- private static final int COPY_LOOP = 7; -- private static final int TRANSFORM = 8; -- private static final int FINISHED = 9; -- private static final int CLOSED = 10; -- private static final int INIT_WRITE = 11; -- private static final int WRITE = 12; -+ private static final int INITIALIZED = 1; -+ private static final int BLOCK_START = 2; -+ private static final int COMPRESSED_BLOCK_START = 3; -+ private static final int MAIN_LOOP = 4; -+ private static final int READ_METADATA = 5; -+ private static final int COPY_UNCOMPRESSED = 6; -+ private static final int INSERT_LOOP = 7; -+ private static final int COPY_LOOP = 8; -+ private static final int TRANSFORM = 9; -+ private static final int FINISHED = 10; -+ private static final int CLOSED = 11; -+ private static final int INIT_WRITE = 12; -+ private static final int WRITE = 13; - - private static final int DEFAULT_CODE_LENGTH = 8; - private static final int CODE_LENGTH_REPEAT_CODE = 16; -@@ -139,6 +140,20 @@ private static int decodeWindowBits(State s) { - return 17; - } - -+ /** -+ * Switch decoder to "eager" mode. -+ * -+ * In "eager" mode decoder returns as soon as there is enough data to fill output buffer. -+ * -+ * @param s initialized state, before any read is performed. -+ */ -+ static void setEager(State s) { -+ if (s.runningState != INITIALIZED) { -+ throw new IllegalStateException("State MUST be freshly initialized"); -+ } -+ s.isEager = 1; -+ } -+ - /** - * Associate input with decoder state. - * -@@ -152,13 +167,7 @@ static void initState(State s, InputStream input) { - s.blockTrees = new int[6 * HUFFMAN_TABLE_SIZE]; - s.input = input; - BitReader.initBitReader(s); -- int windowBits = decodeWindowBits(s); -- if (windowBits == 9) { /* Reserved case for future expansion. */ -- throw new BrotliRuntimeException("Invalid 'windowBits' code"); -- } -- s.maxRingBufferSize = 1 << windowBits; -- s.maxBackwardDistance = s.maxRingBufferSize - 16; -- s.runningState = BLOCK_START; -+ s.runningState = INITIALIZED; - } - - static void close(State s) throws IOException { -@@ -727,6 +736,16 @@ static void decompress(State s) { - if (s.runningState == CLOSED) { - throw new IllegalStateException("Can't decompress after close"); - } -+ if (s.runningState == INITIALIZED) { -+ int windowBits = decodeWindowBits(s); -+ if (windowBits == 9) { /* Reserved case for future expansion. */ -+ throw new BrotliRuntimeException("Invalid 'windowBits' code"); -+ } -+ s.maxRingBufferSize = 1 << windowBits; -+ s.maxBackwardDistance = s.maxRingBufferSize - 16; -+ s.runningState = BLOCK_START; -+ } -+ - int fence = calculateFence(s); - int ringBufferMask = s.ringBufferSize - 1; - byte[] ringBuffer = s.ringBuffer; -@@ -935,9 +954,9 @@ static void decompress(State s) { - int wordIdx = wordId & mask; - int transformIdx = wordId >>> shift; - offset += wordIdx * s.copyLength; -- if (transformIdx < Transform.NUM_TRANSFORMS) { -- int len = Transform.transformDictionaryWord(ringBuffer, s.pos, -- Dictionary.getData(), offset, s.copyLength, transformIdx); -+ if (transformIdx < Transform.NUM_RFC_TRANSFORMS) { -+ int len = Transform.transformDictionaryWord(ringBuffer, s.pos, Dictionary.getData(), -+ offset, s.copyLength, Transform.RFC_TRANSFORMS, transformIdx); - s.pos += len; - s.metaBlockLength -= len; - if (s.pos >= fence) { -diff --git a/java/org/brotli/dec/SynthTest.java b/java/org/brotli/dec/SynthTest.java -index c95a3c90..de91c377 100644 ---- a/java/org/brotli/dec/SynthTest.java -+++ b/java/org/brotli/dec/SynthTest.java -@@ -64,6 +64,474 @@ private void checkSynth(byte[] compressed, boolean expectSuccess, - - /* GENERATED CODE START */ - -+ @Test -+ public void testAllTransforms10() { -+ byte[] compressed = { -+ (byte) 0x1b, (byte) 0xfc, (byte) 0x05, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x80, -+ (byte) 0xe3, (byte) 0xb4, (byte) 0x0d, (byte) 0x00, (byte) 0x00, (byte) 0x07, (byte) 0x5b, -+ (byte) 0x26, (byte) 0x31, (byte) 0x40, (byte) 0x02, (byte) 0x00, (byte) 0xe0, (byte) 0x4e, -+ (byte) 0x1b, (byte) 0x13, (byte) 0x7c, (byte) 0x84, (byte) 0x26, (byte) 0xf8, (byte) 0x04, -+ (byte) 0x10, (byte) 0x4c, (byte) 0xf0, (byte) 0x89, (byte) 0x38, (byte) 0x30, (byte) 0xc1, -+ (byte) 0x27, (byte) 0x4e, (byte) 0xc1, (byte) 0x04, (byte) 0x9f, (byte) 0x64, (byte) 0x06, -+ (byte) 0x26, (byte) 0xf8, (byte) 0x24, (byte) 0x3f, (byte) 0x34, (byte) 0xc1, (byte) 0x27, -+ (byte) 0x7d, (byte) 0x82, (byte) 0x09, (byte) 0x3e, (byte) 0xe9, (byte) 0x16, (byte) 0x4d, -+ (byte) 0xf0, (byte) 0xc9, (byte) 0xd2, (byte) 0xc0, (byte) 0x04, (byte) 0x9f, (byte) 0x0c, -+ (byte) 0x8f, (byte) 0x4c, (byte) 0xf0, (byte) 0xc9, (byte) 0x06, (byte) 0xd1, (byte) 0x04, -+ (byte) 0x9f, (byte) 0x6c, (byte) 0x92, (byte) 0x4d, (byte) 0xf0, (byte) 0xc9, (byte) 0x39, -+ (byte) 0xc1, (byte) 0x04, (byte) 0x9f, (byte) 0xdc, (byte) 0x94, (byte) 0x4c, (byte) 0xf0, -+ (byte) 0xc9, (byte) 0x69, (byte) 0xd1, (byte) 0x04, (byte) 0x9f, (byte) 0x3c, (byte) 0x98, -+ (byte) 0x4d, (byte) 0xf0, (byte) 0x29, (byte) 0x9c, (byte) 0x81, (byte) 0x09, (byte) 0x3e, -+ (byte) 0x45, (byte) 0x37, (byte) 0x31, (byte) 0xc1, (byte) 0xa7, (byte) 0x60, (byte) 0x47, -+ (byte) 0x26, (byte) 0xf8, (byte) 0x14, (byte) 0xfa, (byte) 0xcc, (byte) 0x04, (byte) 0x9f, -+ (byte) 0xc2, (byte) 0x20, (byte) 0x9a, (byte) 0xe0, (byte) 0x53, (byte) 0x48, (byte) 0x54, -+ (byte) 0x13, (byte) 0x7c, (byte) 0x8a, (byte) 0x8f, (byte) 0x6c, (byte) 0x82, (byte) 0x4f, -+ (byte) 0xb1, (byte) 0xd2, (byte) 0x4d, (byte) 0xf0, (byte) 0x29, (byte) 0x67, (byte) 0x82, -+ (byte) 0x09, (byte) 0x3e, (byte) 0xe5, (byte) 0x4f, (byte) 0x31, (byte) 0xc1, (byte) 0xa7, -+ (byte) 0x7c, (byte) 0x4a, (byte) 0x26, (byte) 0xf8, (byte) 0x94, (byte) 0x57, (byte) 0xcd, -+ (byte) 0x04, (byte) 0x9f, (byte) 0x12, (byte) 0x2c, (byte) 0x9a, (byte) 0xe0, (byte) 0x53, -+ (byte) 0xba, (byte) 0x55, (byte) 0x13, (byte) 0x7c, (byte) 0xca, (byte) 0xbf, (byte) 0x6c, -+ (byte) 0x82, (byte) 0x4f, (byte) 0xb9, (byte) 0xd8, (byte) 0x4d, (byte) 0xf0, (byte) 0xa9, -+ (byte) 0x30, (byte) 0x03, (byte) 0x13, (byte) 0x7c, (byte) 0x2a, (byte) 0xd2, (byte) 0xc2, -+ (byte) 0x04, (byte) 0x9f, (byte) 0x4a, (byte) 0x36, (byte) 0x31, (byte) 0xc1, (byte) 0xa7, -+ (byte) 0xca, (byte) 0x6d, (byte) 0x4c, (byte) 0xf0, (byte) 0xa9, (byte) 0x94, (byte) 0x23, -+ (byte) 0x13, (byte) 0x7c, (byte) 0x2a, (byte) 0xeb, (byte) 0xca, (byte) 0x04, (byte) 0x9f, -+ (byte) 0xea, (byte) 0x3c, (byte) 0x33, (byte) 0xc1, (byte) 0xa7, (byte) 0xb2, (byte) 0xef, -+ (byte) 0x4c, (byte) 0xf0, (byte) 0xa9, (byte) 0xf8, (byte) 0x43, (byte) 0x13, (byte) 0x7c, -+ (byte) 0xaa, (byte) 0x00, (byte) 0xd3, (byte) 0x04, (byte) 0x9f, (byte) 0x2a, (byte) 0x42, -+ (byte) 0x35, (byte) 0xc1, (byte) 0xa7, (byte) 0xc2, (byte) 0x70, (byte) 0x4d, (byte) 0xf0, -+ (byte) 0xa9, (byte) 0x52, (byte) 0x64, (byte) 0x13, (byte) 0x7c, (byte) 0x2a, (byte) 0x1a, -+ (byte) 0xdb, (byte) 0x04, (byte) 0x9f, (byte) 0x6a, (byte) 0x48, (byte) 0x37, (byte) 0xc1, -+ (byte) 0xa7, (byte) 0x92, (byte) 0xf2, (byte) 0x4d, (byte) 0xf0, (byte) 0xa9, (byte) 0xc3, -+ (byte) 0x04, (byte) 0x13, (byte) 0x7c, (byte) 0xea, (byte) 0x32, (byte) 0xc3, (byte) 0x04, -+ (byte) 0x9f, (byte) 0x7a, (byte) 0x4e, (byte) 0x31, (byte) 0xc1, (byte) 0xa7, (byte) 0x06, -+ (byte) 0x74, (byte) 0x4c, (byte) 0xf0, (byte) 0xa9, (byte) 0x19, (byte) 0x25, (byte) 0x13, -+ (byte) 0x7c, (byte) 0x6a, (byte) 0x4d, (byte) 0xcb, (byte) 0x04, (byte) 0x9f, (byte) 0x1a, -+ (byte) 0x55, (byte) 0x33, (byte) 0xc1, (byte) 0xa7, (byte) 0x56, (byte) 0xf5, (byte) 0x4c, -+ (byte) 0xf0, (byte) 0xa9, (byte) 0x5d, (byte) 0x45, (byte) 0x13, (byte) 0x7c, (byte) 0xea, -+ (byte) 0x59, (byte) 0xd3, (byte) 0x04, (byte) 0x9f, (byte) 0xfa, (byte) 0x57, (byte) 0x35, -+ (byte) 0xc1, (byte) 0xa7, (byte) 0x66, (byte) 0x76, (byte) 0x4d, (byte) 0xf0, (byte) 0xa9, -+ (byte) 0x9f, (byte) 0x65, (byte) 0x13, (byte) 0x7c, (byte) 0x6a, (byte) 0x6f, (byte) 0xdb, -+ (byte) 0x04, (byte) 0x9f, (byte) 0x9a, (byte) 0x5d, (byte) 0x37, (byte) 0xc1, (byte) 0xa7, -+ (byte) 0x06, (byte) 0xf8, (byte) 0x4d, (byte) 0xf0, (byte) 0x69, (byte) 0x0c, (byte) 0x06, -+ (byte) 0x26, (byte) 0xf8, (byte) 0x34, (byte) 0x08, (byte) 0x07, (byte) 0x13, (byte) 0x7c, -+ (byte) 0x1a, (byte) 0x8b, (byte) 0x85, (byte) 0x09, (byte) 0x3e, (byte) 0x8d, (byte) 0xc8, -+ (byte) 0xc3, (byte) 0x04, (byte) 0x9f, (byte) 0xe6, (byte) 0x65, (byte) 0x62, (byte) 0x82, -+ (byte) 0x4f, (byte) 0xb3, (byte) 0x73, (byte) 0x31, (byte) 0xc1, (byte) 0xa7, (byte) 0x41, -+ (byte) 0xda, (byte) 0x98, (byte) 0xe0, (byte) 0xd3, (byte) 0x54, (byte) 0x7d, (byte) 0x4c, -+ (byte) 0xf0, (byte) 0x69, (byte) 0xc4, (byte) 0x46, (byte) 0x26, (byte) 0xf8, (byte) 0x34, -+ (byte) 0x72, (byte) 0x27, (byte) 0x13, (byte) 0x7c, (byte) 0x1a, (byte) 0xc5, (byte) 0x95, -+ (byte) 0x09, (byte) 0x3e, (byte) 0x8d, (byte) 0xe5, (byte) 0xcb, (byte) 0x04, (byte) 0x9f, -+ (byte) 0x06, (byte) 0x75, (byte) 0x66, (byte) 0x82, (byte) 0x4f, (byte) 0x43, (byte) 0x7b, -+ (byte) 0x33, (byte) 0xc1, (byte) 0xa7, (byte) 0x09, (byte) 0xde, (byte) 0x99, (byte) 0xe0, -+ (byte) 0xd3, (byte) 0x34, (byte) 0xff, (byte) 0x4c, (byte) 0xf0, (byte) 0x69, (byte) 0xb2, -+ (byte) 0x87, (byte) 0x26, (byte) 0xf8, (byte) 0x34, (byte) 0xe9, (byte) 0x47, (byte) 0x13, -+ (byte) 0x7c, (byte) 0x9a, (byte) 0xfb, (byte) 0xa5, (byte) 0x09, (byte) 0x3e, (byte) 0x4d, -+ (byte) 0x01, (byte) 0xd4, (byte) 0x04, (byte) 0x9f, (byte) 0x46, (byte) 0x82, (byte) 0x6a, -+ (byte) 0x82, (byte) 0x4f, (byte) 0x03, (byte) 0x82, (byte) 0x35, (byte) 0xc1, (byte) 0xa7, -+ (byte) 0x61, (byte) 0xe1, (byte) 0x9a, (byte) 0xe0, (byte) 0xd3, (byte) 0xe4, (byte) 0x80, -+ (byte) 0x4d, (byte) 0xf0, (byte) 0x69, (byte) 0x8a, (byte) 0xc8, (byte) 0x26, (byte) 0xf8, -+ (byte) 0x34, (byte) 0x52, (byte) 0x68, (byte) 0x13, (byte) 0x7c, (byte) 0x9a, (byte) 0x2f, -+ (byte) 0xb6, (byte) 0x09, (byte) 0x3e, (byte) 0x8d, (byte) 0x1b, (byte) 0xdc, (byte) 0x04, -+ (byte) 0x9f, (byte) 0x86, (byte) 0x8f, (byte) 0x6e, (byte) 0x82, (byte) 0x4f, (byte) 0xb3, -+ (byte) 0x88, (byte) 0x37, (byte) 0xc1, (byte) 0xa7, (byte) 0xd9, (byte) 0xe4, (byte) 0x9b, -+ (byte) 0xe0, (byte) 0xd3, (byte) 0x9e, (byte) 0x02, (byte) 0x4c, (byte) 0xf0, (byte) 0x69, -+ (byte) 0x6d, (byte) 0x09, (byte) 0x26, (byte) 0xf8, (byte) 0xb4, (byte) 0xc3, (byte) 0x08, -+ (byte) 0x13, (byte) 0x7c, (byte) 0x5a, (byte) 0x68, (byte) 0x86, (byte) 0x09, (byte) 0x3e, -+ (byte) 0xad, (byte) 0x37, (byte) 0xc4, (byte) 0x04, (byte) 0x9f, (byte) 0x56, (byte) 0x9d, -+ (byte) 0x62, (byte) 0x82, (byte) 0x4f, (byte) 0x9b, (byte) 0x8f, (byte) 0x31, (byte) 0xc1, -+ (byte) 0xa7, (byte) 0x2d, (byte) 0xe8, (byte) 0x98, (byte) 0xe0, (byte) 0xd3, (byte) 0x4a, -+ (byte) 0x84, (byte) 0x4c, (byte) 0xf0, (byte) 0x69, (byte) 0x3f, (byte) 0x4a, (byte) 0x26, -+ (byte) 0xf8, (byte) 0xb4, (byte) 0x2c, (byte) 0x29, (byte) 0x13, (byte) 0x7c, (byte) 0xda, -+ (byte) 0x9c, (byte) 0x96, (byte) 0x09, (byte) 0x3e, (byte) 0x2d, (byte) 0x52, (byte) 0xcc, -+ (byte) 0x04, (byte) 0x9f, (byte) 0xb6, (byte) 0xaa, (byte) 0x66, (byte) 0x82, (byte) 0x4f, -+ (byte) 0x2b, (byte) 0x96, (byte) 0x33, (byte) 0xc1, (byte) 0xa7, (byte) 0x7d, (byte) 0xeb, -+ (byte) 0x99, (byte) 0xe0, (byte) 0xd3, (byte) 0xf6, (byte) 0x05, (byte) 0x4d, (byte) 0xf0, -+ (byte) 0x69, (byte) 0x17, (byte) 0x8b, (byte) 0x26, (byte) 0xf8, (byte) 0xb4, (byte) 0x97, -+ (byte) 0x49, (byte) 0x13, (byte) 0x7c, (byte) 0xda, (byte) 0xd1, (byte) 0xa6, (byte) 0x09, -+ (byte) 0x3e, (byte) 0x2d, (byte) 0x6c, (byte) 0xd4, (byte) 0x04, (byte) 0x9f, (byte) 0xb6, -+ (byte) 0xb7, (byte) 0x6a, (byte) 0x82, (byte) 0x4f, (byte) 0xab, (byte) 0x9c, (byte) 0x35, -+ (byte) 0xc1, (byte) 0xa7, (byte) 0xc5, (byte) 0xee, (byte) 0x9a, (byte) 0xe0, (byte) 0xd3, -+ (byte) 0x9a, (byte) 0x87, (byte) 0x4d, (byte) 0xf0, (byte) 0x69, (byte) 0xe9, (byte) 0xcb -+ }; -+ checkSynth( -+ /* -+ * // The stream consists of word "time" with all possible transforms. -+ * main_header -+ * metablock_header_easy: 1533, 1 -+ * command_easy: 10, "|", 2 // = 0 << 10 + 1 + 1 -+ * command_easy: 10, "|", 1037 // = 1 << 10 + 1 + 12 -+ * command_easy: 10, "|", 2073 // = 2 << 10 + 1 + 24 -+ * command_easy: 10, "|", 3110 // = 3 << 10 + 1 + 37 -+ * command_easy: 10, "|", 4144 // = 4 << 10 + 1 + 47 -+ * command_easy: 10, "|", 5180 // = 5 << 10 + 1 + 59 -+ * command_easy: 10, "|", 6220 // = 6 << 10 + 1 + 75 -+ * command_easy: 10, "|", 7256 // = 7 << 10 + 1 + 87 -+ * command_easy: 10, "|", 8294 // = 8 << 10 + 1 + 101 -+ * command_easy: 10, "|", 9333 // = 9 << 10 + 1 + 116 -+ * command_easy: 10, "|", 10368 // = 10 << 10 + 1 + 127 -+ * command_easy: 10, "|", 11408 // = 11 << 10 + 1 + 143 -+ * command_easy: 10, "|", 12441 // = 12 << 10 + 1 + 152 -+ * command_easy: 10, "|", 13475 // = 13 << 10 + 1 + 162 -+ * command_easy: 10, "|", 14513 // = 14 << 10 + 1 + 176 -+ * command_easy: 10, "|", 15550 // = 15 << 10 + 1 + 189 -+ * command_easy: 10, "|", 16587 // = 16 << 10 + 1 + 202 -+ * command_easy: 10, "|", 17626 // = 17 << 10 + 1 + 217 -+ * command_easy: 10, "|", 18665 // = 18 << 10 + 1 + 232 -+ * command_easy: 10, "|", 19703 // = 19 << 10 + 1 + 246 -+ * command_easy: 10, "|", 20739 // = 20 << 10 + 1 + 258 -+ * command_easy: 10, "|", 21775 // = 21 << 10 + 1 + 270 -+ * command_easy: 10, "|", 22812 // = 22 << 10 + 1 + 283 -+ * command_easy: 10, "|", 23848 // = 23 << 10 + 1 + 295 -+ * command_easy: 10, "|", 24880 // = 24 << 10 + 1 + 303 -+ * command_easy: 10, "|", 25916 // = 25 << 10 + 1 + 315 -+ * command_easy: 10, "|", 26956 // = 26 << 10 + 1 + 331 -+ * command_easy: 10, "|", 27988 // = 27 << 10 + 1 + 339 -+ * command_easy: 10, "|", 29021 // = 28 << 10 + 1 + 348 -+ * command_easy: 10, "|", 30059 // = 29 << 10 + 1 + 362 -+ * command_easy: 10, "|", 31100 // = 30 << 10 + 1 + 379 -+ * command_easy: 10, "|", 32136 // = 31 << 10 + 1 + 391 -+ * command_easy: 10, "|", 33173 // = 32 << 10 + 1 + 404 -+ * command_easy: 10, "|", 34209 // = 33 << 10 + 1 + 416 -+ * command_easy: 10, "|", 35247 // = 34 << 10 + 1 + 430 -+ * command_easy: 10, "|", 36278 // = 35 << 10 + 1 + 437 -+ * command_easy: 10, "|", 37319 // = 36 << 10 + 1 + 454 -+ * command_easy: 10, "|", 38355 // = 37 << 10 + 1 + 466 -+ * command_easy: 10, "|", 39396 // = 38 << 10 + 1 + 483 -+ * command_easy: 10, "|", 40435 // = 39 << 10 + 1 + 498 -+ * command_easy: 10, "|", 41465 // = 40 << 10 + 1 + 504 -+ * command_easy: 10, "|", 42494 // = 41 << 10 + 1 + 509 -+ * command_easy: 10, "|", 43534 // = 42 << 10 + 1 + 525 -+ * command_easy: 10, "|", 44565 // = 43 << 10 + 1 + 532 -+ * command_easy: 10, "|", 45606 // = 44 << 10 + 1 + 549 -+ * command_easy: 10, "|", 46641 // = 45 << 10 + 1 + 560 -+ * command_easy: 10, "|", 47680 // = 46 << 10 + 1 + 575 -+ * command_easy: 10, "|", 48719 // = 47 << 10 + 1 + 590 -+ * command_easy: 10, "|", 49758 // = 48 << 10 + 1 + 605 -+ * command_easy: 10, "|", 50786 // = 49 << 10 + 1 + 609 -+ * command_easy: 10, "|", 51824 // = 50 << 10 + 1 + 623 -+ * command_easy: 10, "|", 52861 // = 51 << 10 + 1 + 636 -+ * command_easy: 10, "|", 53897 // = 52 << 10 + 1 + 648 -+ * command_easy: 10, "|", 54935 // = 53 << 10 + 1 + 662 -+ * command_easy: 10, "|", 55973 // = 54 << 10 + 1 + 676 -+ * command_easy: 10, "|", 56999 // = 55 << 10 + 1 + 678 -+ * command_easy: 10, "|", 58027 // = 56 << 10 + 1 + 682 -+ * command_easy: 10, "|", 59056 // = 57 << 10 + 1 + 687 -+ * command_easy: 10, "|", 60092 // = 58 << 10 + 1 + 699 -+ * command_easy: 10, "|", 61129 // = 59 << 10 + 1 + 712 -+ * command_easy: 10, "|", 62156 // = 60 << 10 + 1 + 715 -+ * command_easy: 10, "|", 63195 // = 61 << 10 + 1 + 730 -+ * command_easy: 10, "|", 64233 // = 62 << 10 + 1 + 744 -+ * command_easy: 10, "|", 65277 // = 63 << 10 + 1 + 764 -+ * command_easy: 10, "|", 66307 // = 64 << 10 + 1 + 770 -+ * command_easy: 10, "|", 67333 // = 65 << 10 + 1 + 772 -+ * command_easy: 10, "|", 68371 // = 66 << 10 + 1 + 786 -+ * command_easy: 10, "|", 69407 // = 67 << 10 + 1 + 798 -+ * command_easy: 10, "|", 70444 // = 68 << 10 + 1 + 811 -+ * command_easy: 10, "|", 71480 // = 69 << 10 + 1 + 823 -+ * command_easy: 10, "|", 72517 // = 70 << 10 + 1 + 836 -+ * command_easy: 10, "|", 73554 // = 71 << 10 + 1 + 849 -+ * command_easy: 10, "|", 74591 // = 72 << 10 + 1 + 862 -+ * command_easy: 10, "|", 75631 // = 73 << 10 + 1 + 878 -+ * command_easy: 10, "|", 76679 // = 74 << 10 + 1 + 902 -+ * command_easy: 10, "|", 77715 // = 75 << 10 + 1 + 914 -+ * command_easy: 10, "|", 78757 // = 76 << 10 + 1 + 932 -+ * command_easy: 10, "|", 79793 // = 77 << 10 + 1 + 944 -+ * command_easy: 10, "|", 80830 // = 78 << 10 + 1 + 957 -+ * command_easy: 10, "|", 81866 // = 79 << 10 + 1 + 969 -+ * command_easy: 10, "|", 82902 // = 80 << 10 + 1 + 981 -+ * command_easy: 10, "|", 83942 // = 81 << 10 + 1 + 997 -+ * command_easy: 10, "|", 84980 // = 82 << 10 + 1 + 1011 -+ * command_easy: 10, "|", 86018 // = 83 << 10 + 1 + 1025 -+ * command_easy: 10, "|", 87055 // = 84 << 10 + 1 + 1038 -+ * command_easy: 10, "|", 88093 // = 85 << 10 + 1 + 1052 -+ * command_easy: 10, "|", 89129 // = 86 << 10 + 1 + 1064 -+ * command_easy: 10, "|", 90166 // = 87 << 10 + 1 + 1077 -+ * command_easy: 10, "|", 91202 // = 88 << 10 + 1 + 1089 -+ * command_easy: 10, "|", 92239 // = 89 << 10 + 1 + 1102 -+ * command_easy: 10, "|", 93276 // = 90 << 10 + 1 + 1115 -+ * command_easy: 10, "|", 94315 // = 91 << 10 + 1 + 1130 -+ * command_easy: 10, "|", 95353 // = 92 << 10 + 1 + 1144 -+ * command_easy: 10, "|", 96392 // = 93 << 10 + 1 + 1159 -+ * command_easy: 10, "|", 97432 // = 94 << 10 + 1 + 1175 -+ * command_easy: 10, "|", 98468 // = 95 << 10 + 1 + 1187 -+ * command_easy: 10, "|", 99507 // = 96 << 10 + 1 + 1202 -+ * command_easy: 10, "|", 100544 // = 97 << 10 + 1 + 1215 -+ * command_easy: 10, "|", 101581 // = 98 << 10 + 1 + 1228 -+ * command_easy: 10, "|", 102619 // = 99 << 10 + 1 + 1242 -+ * command_easy: 10, "|", 103655 // = 100 << 10 + 1 + 1254 -+ * command_easy: 10, "|", 104694 // = 101 << 10 + 1 + 1269 -+ * command_easy: 10, "|", 105730 // = 102 << 10 + 1 + 1281 -+ * command_easy: 10, "|", 106767 // = 103 << 10 + 1 + 1294 -+ * command_easy: 10, "|", 107804 // = 104 << 10 + 1 + 1307 -+ * command_easy: 10, "|", 108841 // = 105 << 10 + 1 + 1320 -+ * command_easy: 10, "|", 109878 // = 106 << 10 + 1 + 1333 -+ * command_easy: 10, "|", 110917 // = 107 << 10 + 1 + 1348 -+ * command_easy: 10, "|", 111954 // = 108 << 10 + 1 + 1361 -+ * command_easy: 10, "|", 112991 // = 109 << 10 + 1 + 1374 -+ * command_easy: 10, "|", 114028 // = 110 << 10 + 1 + 1387 -+ * command_easy: 10, "|", 115066 // = 111 << 10 + 1 + 1401 -+ * command_easy: 10, "|", 116104 // = 112 << 10 + 1 + 1415 -+ * command_easy: 10, "|", 117140 // = 113 << 10 + 1 + 1427 -+ * command_easy: 10, "|", 118176 // = 114 << 10 + 1 + 1439 -+ * command_easy: 10, "|", 119213 // = 115 << 10 + 1 + 1452 -+ * command_easy: 10, "|", 120250 // = 116 << 10 + 1 + 1465 -+ * command_easy: 10, "|", 121287 // = 117 << 10 + 1 + 1478 -+ * command_easy: 10, "|", 122325 // = 118 << 10 + 1 + 1492 -+ * command_easy: 10, "|", 123363 // = 119 << 10 + 1 + 1506 -+ * command_easy: 10, "|", 124401 // = 120 << 10 + 1 + 1520 -+ */ -+ compressed, -+ true, -+ "|categories|categories | categories |ategories|Categories |categories the | categories|s cat" -+ + "egories |categories of |Categories|categories and |tegories|categorie|, categories |catego" -+ + "ries, | Categories |categories in |categories to |e categories |categories\"|categories.|c" -+ + "ategories\">|categories\n|categor|categories]|categories for |egories|categori|categories " -+ + "a |categories that | Categories|categories. |.categories| categories, |gories|categories w" -+ + "ith |categories'|categories from |categories by |ories|ries| the categories|catego|categor" -+ + "ies. The |CATEGORIES|categories on |categories as |categories is |cat|categorieing |catego" -+ + "ries\n\t|categories:| categories. |categoriesed |s|ies|cate|categories(|Categories, |ca|ca" -+ + "tegories at |categoriesly | the categories of |categ|c| Categories, |Categories\"|.categor" -+ + "ies(|CATEGORIES |Categories\">|categories=\"| categories.|.com/categories| the categories " -+ + "of the |Categories'|categories. This |categories,|.categories |Categories(|Categories.|cat" -+ + "egories not | categories=\"|categorieser | CATEGORIES |categoriesal | CATEGORIES|categorie" -+ + "s='|CATEGORIES\"|Categories. | categories(|categoriesful | Categories. |categoriesive |cat" -+ + "egoriesless |CATEGORIES'|categoriesest | Categories.|CATEGORIES\">| categories='|Categorie" -+ + "s,|categoriesize |CATEGORIES.|\302\240categories| categories,|Categories=\"|CATEGORIES=" -+ + "\"|categoriesous |CATEGORIES, |Categories='| Categories,| CATEGORIES=\"| CATEGORIES, |CATE" -+ + "GORIES,|CATEGORIES(|CATEGORIES. | CATEGORIES.|CATEGORIES='| CATEGORIES. | Categories=\"| C" -+ + "ATEGORIES='| Categories='" -+ ); -+ } -+ -+ @Test -+ public void testAllTransforms4() { -+ byte[] compressed = { -+ (byte) 0x1b, (byte) 0x40, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x80, -+ (byte) 0xe3, (byte) 0xb4, (byte) 0x0d, (byte) 0x00, (byte) 0x00, (byte) 0x07, (byte) 0x5b, -+ (byte) 0x26, (byte) 0x31, (byte) 0x40, (byte) 0x02, (byte) 0x00, (byte) 0xe0, (byte) 0x4e, -+ (byte) 0x1b, (byte) 0x51, (byte) 0x3e, (byte) 0x42, (byte) 0x51, (byte) 0x3e, (byte) 0x81, -+ (byte) 0x02, (byte) 0x51, (byte) 0x3e, (byte) 0x11, (byte) 0x04, (byte) 0xa2, (byte) 0x7c, -+ (byte) 0xe2, (byte) 0x0b, (byte) 0x44, (byte) 0xf9, (byte) 0x24, (byte) 0x1b, (byte) 0x10, -+ (byte) 0xe5, (byte) 0x93, (byte) 0x84, (byte) 0x50, (byte) 0x94, (byte) 0x4f, (byte) 0xba, -+ (byte) 0x02, (byte) 0x51, (byte) 0x3e, (byte) 0x69, (byte) 0x0c, (byte) 0x45, (byte) 0xf9, -+ (byte) 0x64, (byte) 0x39, (byte) 0x20, (byte) 0xca, (byte) 0x27, (byte) 0x13, (byte) 0x22, -+ (byte) 0x51, (byte) 0x3e, (byte) 0xd9, (byte) 0x11, (byte) 0x8a, (byte) 0xf2, (byte) 0xc9, -+ (byte) 0xa2, (byte) 0x58, (byte) 0x94, (byte) 0x4f, (byte) 0x4e, (byte) 0x05, (byte) 0xa2, -+ (byte) 0x7c, (byte) 0x72, (byte) 0x2c, (byte) 0x12, (byte) 0xe5, (byte) 0x93, (byte) 0x83, -+ (byte) 0xa1, (byte) 0x28, (byte) 0x9f, (byte) 0xfc, (byte) 0x8c, (byte) 0x45, (byte) 0xf9, -+ (byte) 0x14, (byte) 0x6e, (byte) 0x40, (byte) 0x94, (byte) 0x4f, (byte) 0x71, (byte) 0x47, -+ (byte) 0x44, (byte) 0xf9, (byte) 0x14, (byte) 0x80, (byte) 0x48, (byte) 0x94, (byte) 0x4f, -+ (byte) 0x81, (byte) 0xc8, (byte) 0x44, (byte) 0xf9, (byte) 0x14, (byte) 0x8e, (byte) 0x50, -+ (byte) 0x94, (byte) 0x4f, (byte) 0x41, (byte) 0x49, (byte) 0x45, (byte) 0xf9, (byte) 0x14, -+ (byte) 0x9b, (byte) 0x58, (byte) 0x94, (byte) 0x4f, (byte) 0x11, (byte) 0xca, (byte) 0x45, -+ (byte) 0xf9, (byte) 0x94, (byte) 0xa3, (byte) 0x40, (byte) 0x94, (byte) 0x4f, (byte) 0x99, -+ (byte) 0x4a, (byte) 0x44, (byte) 0xf9, (byte) 0x94, (byte) 0xb3, (byte) 0x48, (byte) 0x94, -+ (byte) 0x4f, (byte) 0x59, (byte) 0xcb, (byte) 0x44, (byte) 0xf9, (byte) 0x94, (byte) 0xb8, -+ (byte) 0x50, (byte) 0x94, (byte) 0x4f, (byte) 0x09, (byte) 0x4c, (byte) 0x45, (byte) 0xf9, -+ (byte) 0x94, (byte) 0xcb, (byte) 0x58, (byte) 0x94, (byte) 0x4f, (byte) 0x19, (byte) 0xcd, -+ (byte) 0x45, (byte) 0xf9, (byte) 0x54, (byte) 0xd8, (byte) 0x80, (byte) 0x28, (byte) 0x9f, -+ (byte) 0xca, (byte) 0x9b, (byte) 0x10, (byte) 0xe5, (byte) 0x53, (byte) 0x99, (byte) 0x23, -+ (byte) 0xa2, (byte) 0x7c, (byte) 0xaa, (byte) 0x73, (byte) 0x46, (byte) 0x94, (byte) 0x4f, -+ (byte) 0x25, (byte) 0x0f, (byte) 0x89, (byte) 0xf2, (byte) 0xa9, (byte) 0xf0, (byte) 0x29, -+ (byte) 0x51, (byte) 0x3e, (byte) 0xd5, (byte) 0x40, (byte) 0x26, (byte) 0xca, (byte) 0xa7, -+ (byte) 0x62, (byte) 0xe8, (byte) 0x44, (byte) 0xf9, (byte) 0x54, (byte) 0x0d, (byte) 0xa1, -+ (byte) 0x28, (byte) 0x9f, (byte) 0xca, (byte) 0xa1, (byte) 0x14, (byte) 0xe5, (byte) 0x53, -+ (byte) 0x61, (byte) 0xa4, (byte) 0xa2, (byte) 0x7c, (byte) 0xaa, (byte) 0x8c, (byte) 0x56, -+ (byte) 0x94, (byte) 0x4f, (byte) 0x45, (byte) 0x12, (byte) 0x8b, (byte) 0xf2, (byte) 0xa9, -+ (byte) 0x52, (byte) 0x6a, (byte) 0x51, (byte) 0x3e, (byte) 0x95, (byte) 0x4c, (byte) 0x2e, -+ (byte) 0xca, (byte) 0xa7, (byte) 0xda, (byte) 0xe9, (byte) 0x45, (byte) 0xf9, (byte) 0xd4, -+ (byte) 0x44, (byte) 0x81, (byte) 0x28, (byte) 0x9f, (byte) 0xba, (byte) 0xa8, (byte) 0x10, -+ (byte) 0xe5, (byte) 0x53, (byte) 0x37, (byte) 0x25, (byte) 0xa2, (byte) 0x7c, (byte) 0x6a, -+ (byte) 0xaa, (byte) 0x46, (byte) 0x94, (byte) 0x4f, (byte) 0xad, (byte) 0x15, (byte) 0x89, -+ (byte) 0xf2, (byte) 0xa9, (byte) 0xc5, (byte) 0x2a, (byte) 0x51, (byte) 0x3e, (byte) 0xb5, -+ (byte) 0x5a, (byte) 0x26, (byte) 0xca, (byte) 0xa7, (byte) 0x5e, (byte) 0xeb, (byte) 0x44, -+ (byte) 0xf9, (byte) 0xd4, (byte) 0x6c, (byte) 0xa1, (byte) 0x28, (byte) 0x9f, (byte) 0xba, -+ (byte) 0xad, (byte) 0x14, (byte) 0xe5, (byte) 0x53, (byte) 0xcf, (byte) 0xa5, (byte) 0xa2, -+ (byte) 0x7c, (byte) 0x6a, (byte) 0xbd, (byte) 0x56, (byte) 0x94, (byte) 0x4f, (byte) 0xbd, -+ (byte) 0x17, (byte) 0x8b, (byte) 0xf2, (byte) 0xa9, (byte) 0x09, (byte) 0x6b, (byte) 0x51, -+ (byte) 0x3e, (byte) 0x35, (byte) 0x63, (byte) 0x2e, (byte) 0xca, (byte) 0xa7, (byte) 0xd6, -+ (byte) 0xec, (byte) 0x45, (byte) 0xf9, (byte) 0x34, (byte) 0x9b, (byte) 0x01, (byte) 0x51, -+ (byte) 0x3e, (byte) 0x0d, (byte) 0x67, (byte) 0x41, (byte) 0x94, (byte) 0x4f, (byte) 0x43, -+ (byte) 0x9a, (byte) 0x10, (byte) 0xe5, (byte) 0xd3, (byte) 0xa8, (byte) 0x36, (byte) 0x44, -+ (byte) 0xf9, (byte) 0x34, (byte) 0xb1, (byte) 0x11, (byte) 0x51, (byte) 0x3e, (byte) 0xcd, -+ (byte) 0x6d, (byte) 0x45, (byte) 0x94, (byte) 0x4f, (byte) 0xe3, (byte) 0x9b, (byte) 0x11, -+ (byte) 0xe5, (byte) 0xd3, (byte) 0x14, (byte) 0x77, (byte) 0x44, (byte) 0xf9, (byte) 0x34, -+ (byte) 0xcc, (byte) 0x21, (byte) 0x51, (byte) 0x3e, (byte) 0x8d, (byte) 0x75, (byte) 0x49, -+ (byte) 0x94, (byte) 0x4f, (byte) 0x83, (byte) 0x9e, (byte) 0x12, (byte) 0xe5, (byte) 0xd3, -+ (byte) 0xb8, (byte) 0xb7, (byte) 0x44, (byte) 0xf9, (byte) 0x34, (byte) 0xfa, (byte) 0x31, -+ (byte) 0x51, (byte) 0x3e, (byte) 0x0d, (byte) 0x80, (byte) 0x4d, (byte) 0x94, (byte) 0x4f, -+ (byte) 0x73, (byte) 0xa0, (byte) 0x13, (byte) 0xe5, (byte) 0xd3, (byte) 0x34, (byte) 0xf8, -+ (byte) 0x44, (byte) 0xf9, (byte) 0x34, (byte) 0x13, (byte) 0x42, (byte) 0x51, (byte) 0x3e, -+ (byte) 0x4d, (byte) 0x87, (byte) 0x51, (byte) 0x94, (byte) 0x4f, (byte) 0x53, (byte) 0xa2, -+ (byte) 0x14, (byte) 0xe5, (byte) 0xd3, (byte) 0xb4, (byte) 0x38, (byte) 0x45, (byte) 0xf9, -+ (byte) 0x34, (byte) 0x34, (byte) 0x52, (byte) 0x51, (byte) 0x3e, (byte) 0x0d, (byte) 0x8f, -+ (byte) 0x55, (byte) 0x94, (byte) 0x4f, (byte) 0x23, (byte) 0xa4, (byte) 0x15, (byte) 0xe5, -+ (byte) 0xd3, (byte) 0x24, (byte) 0x79, (byte) 0x45, (byte) 0xf9, (byte) 0x34, (byte) 0x4f, -+ (byte) 0x62, (byte) 0x51, (byte) 0x3e, (byte) 0x8d, (byte) 0x95, (byte) 0x59, (byte) 0x94, -+ (byte) 0x4f, (byte) 0xd3, (byte) 0xa5, (byte) 0x16, (byte) 0xe5, (byte) 0xd3, (byte) 0x98, -+ (byte) 0xb9, (byte) 0x45, (byte) 0xf9, (byte) 0x34, (byte) 0x6e, (byte) 0x72, (byte) 0x51, -+ (byte) 0x3e, (byte) 0xcd, (byte) 0x9d, (byte) 0x5d, (byte) 0x94, (byte) 0x4f, (byte) 0x13, -+ (byte) 0xa8, (byte) 0x17, (byte) 0xe5, (byte) 0xd3, (byte) 0x1c, (byte) 0xfa, (byte) 0x45, -+ (byte) 0xf9, (byte) 0xb4, (byte) 0x90, (byte) 0x02, (byte) 0x51, (byte) 0x3e, (byte) 0xed, -+ (byte) 0xa5, (byte) 0x41, (byte) 0x94, (byte) 0x4f, (byte) 0xeb, (byte) 0xa9, (byte) 0x10, -+ (byte) 0xe5, (byte) 0xd3, (byte) 0x9a, (byte) 0x3a, (byte) 0x44, (byte) 0xf9, (byte) 0xb4, -+ (byte) 0xac, (byte) 0x12, (byte) 0x51, (byte) 0x3e, (byte) 0x6d, (byte) 0xad, (byte) 0x45, -+ (byte) 0x94, (byte) 0x4f, (byte) 0xbb, (byte) 0xab, (byte) 0x11, (byte) 0xe5, (byte) 0xd3, -+ (byte) 0x0a, (byte) 0x7b, (byte) 0x44, (byte) 0xf9, (byte) 0xb4, (byte) 0xc9, (byte) 0x22, -+ (byte) 0x51, (byte) 0x3e, (byte) 0x2d, (byte) 0xb4, (byte) 0x49, (byte) 0x94, (byte) 0x4f, -+ (byte) 0x7b, (byte) 0xad, (byte) 0x12, (byte) 0xe5, (byte) 0xd3, (byte) 0x82, (byte) 0xbb, -+ (byte) 0x44, (byte) 0xf9, (byte) 0xb4, (byte) 0xe7, (byte) 0x32, (byte) 0x51, (byte) 0x3e, -+ (byte) 0xad, (byte) 0xbb, (byte) 0x4d, (byte) 0x94, (byte) 0x4f, (byte) 0x5b, (byte) 0xaf, -+ (byte) 0x13, (byte) 0xe5, (byte) 0xd3, (byte) 0xf6, (byte) 0xfb, (byte) 0x44, (byte) 0xf9, -+ (byte) 0xb4, (byte) 0x05, (byte) 0x43, (byte) 0x51, (byte) 0x3e, (byte) 0xed, (byte) 0xc2, -+ (byte) 0x51, (byte) 0x94, (byte) 0x4f, (byte) 0x1b, (byte) 0xb1, (byte) 0x14, (byte) 0xe5, -+ (byte) 0xd3, (byte) 0x62, (byte) 0x3c, (byte) 0x45, (byte) 0xf9, (byte) 0xb4, (byte) 0x1f, -+ (byte) 0x53, (byte) 0x51, (byte) 0x3e, (byte) 0xad, (byte) 0xc9, (byte) 0x55, (byte) 0x94, -+ (byte) 0x4f, (byte) 0xeb, (byte) 0xb2, (byte) 0x15, (byte) 0xe5, (byte) 0xd3, (byte) 0xda, -+ (byte) 0x7c, (byte) 0x45, (byte) 0xf9, (byte) 0xb4, (byte) 0x3e, (byte) 0x63 -+ }; -+ checkSynth( -+ /* -+ * // The stream consists of word "time" with all possible transforms. -+ * main_header -+ * metablock_header_easy: 833, 1 -+ * command_easy: 4, "|", 2 // = 0 << 10 + 1 + 1 -+ * command_easy: 4, "|", 1031 // = 1 << 10 + 1 + 6 -+ * command_easy: 4, "|", 2061 // = 2 << 10 + 1 + 12 -+ * command_easy: 4, "|", 3092 // = 3 << 10 + 1 + 19 -+ * command_easy: 4, "|", 4120 // = 4 << 10 + 1 + 23 -+ * command_easy: 4, "|", 5150 // = 5 << 10 + 1 + 29 -+ * command_easy: 4, "|", 6184 // = 6 << 10 + 1 + 39 -+ * command_easy: 4, "|", 7214 // = 7 << 10 + 1 + 45 -+ * command_easy: 4, "|", 8246 // = 8 << 10 + 1 + 53 -+ * command_easy: 4, "|", 9279 // = 9 << 10 + 1 + 62 -+ * command_easy: 4, "|", 10308 // = 10 << 10 + 1 + 67 -+ * command_easy: 4, "|", 11342 // = 11 << 10 + 1 + 77 -+ * command_easy: 4, "|", 12369 // = 12 << 10 + 1 + 80 -+ * command_easy: 4, "|", 13397 // = 13 << 10 + 1 + 84 -+ * command_easy: 4, "|", 14429 // = 14 << 10 + 1 + 92 -+ * command_easy: 4, "|", 15460 // = 15 << 10 + 1 + 99 -+ * command_easy: 4, "|", 16491 // = 16 << 10 + 1 + 106 -+ * command_easy: 4, "|", 17524 // = 17 << 10 + 1 + 115 -+ * command_easy: 4, "|", 18557 // = 18 << 10 + 1 + 124 -+ * command_easy: 4, "|", 19589 // = 19 << 10 + 1 + 132 -+ * command_easy: 4, "|", 20619 // = 20 << 10 + 1 + 138 -+ * command_easy: 4, "|", 21649 // = 21 << 10 + 1 + 144 -+ * command_easy: 4, "|", 22680 // = 22 << 10 + 1 + 151 -+ * command_easy: 4, "|", 23710 // = 23 << 10 + 1 + 157 -+ * command_easy: 4, "|", 24736 // = 24 << 10 + 1 + 159 -+ * command_easy: 4, "|", 25766 // = 25 << 10 + 1 + 165 -+ * command_easy: 4, "|", 26800 // = 26 << 10 + 1 + 175 -+ * command_easy: 4, "|", 27826 // = 27 << 10 + 1 + 177 -+ * command_easy: 4, "|", 28853 // = 28 << 10 + 1 + 180 -+ * command_easy: 4, "|", 29885 // = 29 << 10 + 1 + 188 -+ * command_easy: 4, "|", 30920 // = 30 << 10 + 1 + 199 -+ * command_easy: 4, "|", 31950 // = 31 << 10 + 1 + 205 -+ * command_easy: 4, "|", 32981 // = 32 << 10 + 1 + 212 -+ * command_easy: 4, "|", 34011 // = 33 << 10 + 1 + 218 -+ * command_easy: 4, "|", 35043 // = 34 << 10 + 1 + 226 -+ * command_easy: 4, "|", 36068 // = 35 << 10 + 1 + 227 -+ * command_easy: 4, "|", 37103 // = 36 << 10 + 1 + 238 -+ * command_easy: 4, "|", 38133 // = 37 << 10 + 1 + 244 -+ * command_easy: 4, "|", 39168 // = 38 << 10 + 1 + 255 -+ * command_easy: 4, "|", 40201 // = 39 << 10 + 1 + 264 -+ * command_easy: 4, "|", 41226 // = 40 << 10 + 1 + 265 -+ * command_easy: 4, "|", 42251 // = 41 << 10 + 1 + 266 -+ * command_easy: 4, "|", 43285 // = 42 << 10 + 1 + 276 -+ * command_easy: 4, "|", 44310 // = 43 << 10 + 1 + 277 -+ * command_easy: 4, "|", 45345 // = 44 << 10 + 1 + 288 -+ * command_easy: 4, "|", 46374 // = 45 << 10 + 1 + 293 -+ * command_easy: 4, "|", 47407 // = 46 << 10 + 1 + 302 -+ * command_easy: 4, "|", 48440 // = 47 << 10 + 1 + 311 -+ * command_easy: 4, "|", 49473 // = 48 << 10 + 1 + 320 -+ * command_easy: 4, "|", 50498 // = 49 << 10 + 1 + 321 -+ * command_easy: 4, "|", 51530 // = 50 << 10 + 1 + 329 -+ * command_easy: 4, "|", 52561 // = 51 << 10 + 1 + 336 -+ * command_easy: 4, "|", 53591 // = 52 << 10 + 1 + 342 -+ * command_easy: 4, "|", 54623 // = 53 << 10 + 1 + 350 -+ * command_easy: 4, "|", 55655 // = 54 << 10 + 1 + 358 -+ * command_easy: 4, "|", 56680 // = 55 << 10 + 1 + 359 -+ * command_easy: 4, "|", 57705 // = 56 << 10 + 1 + 360 -+ * command_easy: 4, "|", 58730 // = 57 << 10 + 1 + 361 -+ * command_easy: 4, "|", 59760 // = 58 << 10 + 1 + 367 -+ * command_easy: 4, "|", 60791 // = 59 << 10 + 1 + 374 -+ * command_easy: 4, "|", 61816 // = 60 << 10 + 1 + 375 -+ * command_easy: 4, "|", 62849 // = 61 << 10 + 1 + 384 -+ * command_easy: 4, "|", 63881 // = 62 << 10 + 1 + 392 -+ * command_easy: 4, "|", 64919 // = 63 << 10 + 1 + 406 -+ * command_easy: 4, "|", 65944 // = 64 << 10 + 1 + 407 -+ * command_easy: 4, "|", 66969 // = 65 << 10 + 1 + 408 -+ * command_easy: 4, "|", 68001 // = 66 << 10 + 1 + 416 -+ * command_easy: 4, "|", 69031 // = 67 << 10 + 1 + 422 -+ * command_easy: 4, "|", 70062 // = 68 << 10 + 1 + 429 -+ * command_easy: 4, "|", 71092 // = 69 << 10 + 1 + 435 -+ * command_easy: 4, "|", 72123 // = 70 << 10 + 1 + 442 -+ * command_easy: 4, "|", 73154 // = 71 << 10 + 1 + 449 -+ * command_easy: 4, "|", 74185 // = 72 << 10 + 1 + 456 -+ * command_easy: 4, "|", 75219 // = 73 << 10 + 1 + 466 -+ * command_easy: 4, "|", 76261 // = 74 << 10 + 1 + 484 -+ * command_easy: 4, "|", 77291 // = 75 << 10 + 1 + 490 -+ * command_easy: 4, "|", 78327 // = 76 << 10 + 1 + 502 -+ * command_easy: 4, "|", 79357 // = 77 << 10 + 1 + 508 -+ * command_easy: 4, "|", 80388 // = 78 << 10 + 1 + 515 -+ * command_easy: 4, "|", 81418 // = 79 << 10 + 1 + 521 -+ * command_easy: 4, "|", 82448 // = 80 << 10 + 1 + 527 -+ * command_easy: 4, "|", 83482 // = 81 << 10 + 1 + 537 -+ * command_easy: 4, "|", 84514 // = 82 << 10 + 1 + 545 -+ * command_easy: 4, "|", 85546 // = 83 << 10 + 1 + 553 -+ * command_easy: 4, "|", 86577 // = 84 << 10 + 1 + 560 -+ * command_easy: 4, "|", 87609 // = 85 << 10 + 1 + 568 -+ * command_easy: 4, "|", 88639 // = 86 << 10 + 1 + 574 -+ * command_easy: 4, "|", 89670 // = 87 << 10 + 1 + 581 -+ * command_easy: 4, "|", 90700 // = 88 << 10 + 1 + 587 -+ * command_easy: 4, "|", 91731 // = 89 << 10 + 1 + 594 -+ * command_easy: 4, "|", 92762 // = 90 << 10 + 1 + 601 -+ * command_easy: 4, "|", 93795 // = 91 << 10 + 1 + 610 -+ * command_easy: 4, "|", 94827 // = 92 << 10 + 1 + 618 -+ * command_easy: 4, "|", 95860 // = 93 << 10 + 1 + 627 -+ * command_easy: 4, "|", 96894 // = 94 << 10 + 1 + 637 -+ * command_easy: 4, "|", 97924 // = 95 << 10 + 1 + 643 -+ * command_easy: 4, "|", 98957 // = 96 << 10 + 1 + 652 -+ * command_easy: 4, "|", 99988 // = 97 << 10 + 1 + 659 -+ * command_easy: 4, "|", 101019 // = 98 << 10 + 1 + 666 -+ * command_easy: 4, "|", 102051 // = 99 << 10 + 1 + 674 -+ * command_easy: 4, "|", 103081 // = 100 << 10 + 1 + 680 -+ * command_easy: 4, "|", 104114 // = 101 << 10 + 1 + 689 -+ * command_easy: 4, "|", 105144 // = 102 << 10 + 1 + 695 -+ * command_easy: 4, "|", 106175 // = 103 << 10 + 1 + 702 -+ * command_easy: 4, "|", 107206 // = 104 << 10 + 1 + 709 -+ * command_easy: 4, "|", 108237 // = 105 << 10 + 1 + 716 -+ * command_easy: 4, "|", 109268 // = 106 << 10 + 1 + 723 -+ * command_easy: 4, "|", 110301 // = 107 << 10 + 1 + 732 -+ * command_easy: 4, "|", 111332 // = 108 << 10 + 1 + 739 -+ * command_easy: 4, "|", 112363 // = 109 << 10 + 1 + 746 -+ * command_easy: 4, "|", 113394 // = 110 << 10 + 1 + 753 -+ * command_easy: 4, "|", 114426 // = 111 << 10 + 1 + 761 -+ * command_easy: 4, "|", 115458 // = 112 << 10 + 1 + 769 -+ * command_easy: 4, "|", 116488 // = 113 << 10 + 1 + 775 -+ * command_easy: 4, "|", 117518 // = 114 << 10 + 1 + 781 -+ * command_easy: 4, "|", 118549 // = 115 << 10 + 1 + 788 -+ * command_easy: 4, "|", 119580 // = 116 << 10 + 1 + 795 -+ * command_easy: 4, "|", 120611 // = 117 << 10 + 1 + 802 -+ * command_easy: 4, "|", 121643 // = 118 << 10 + 1 + 810 -+ * command_easy: 4, "|", 122675 // = 119 << 10 + 1 + 818 -+ * command_easy: 4, "|", 123707 // = 120 << 10 + 1 + 826 -+ */ -+ compressed, -+ true, -+ "|time|time | time |ime|Time |time the | time|s time |time of |Time|time and |me|tim|, time |" -+ + "time, | Time |time in |time to |e time |time\"|time.|time\">|time\n|t|time]|time for |e|ti" -+ + "|time a |time that | Time|time. |.time| time, ||time with |time'|time from |time by ||| th" -+ + "e time||time. The |TIME|time on |time as |time is ||timing |time\n\t|time:| time. |timeed " -+ + "||||time(|Time, ||time at |timely | the time of ||| Time, |Time\"|.time(|TIME |Time\">|tim" -+ + "e=\"| time.|.com/time| the time of the |Time'|time. This |time,|.time |Time(|Time.|time no" -+ + "t | time=\"|timeer | TIME |timeal | TIME|time='|TIME\"|Time. | time(|timeful | Time. |time" -+ + "ive |timeless |TIME'|timeest | Time.|TIME\">| time='|Time,|timeize |TIME.|\302\240time| ti" -+ + "me,|Time=\"|TIME=\"|timeous |TIME, |Time='| Time,| TIME=\"| TIME, |TIME,|TIME(|TIME. | TIM" -+ + "E.|TIME='| TIME. | Time=\"| TIME='| Time='" -+ ); -+ } -+ - @Test - public void testBaseDictWord() { - byte[] compressed = { -@@ -446,6 +914,28 @@ public void testCopyLengthTooLong() { - ); - } - -+ @Test -+ public void testCopyTooLong() { -+ byte[] compressed = { -+ (byte) 0xa1, (byte) 0x08, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, -+ (byte) 0x1c, (byte) 0xa7, (byte) 0x6d, (byte) 0x00, (byte) 0x00, (byte) 0x38, (byte) 0xd8, -+ (byte) 0x32, (byte) 0x89, (byte) 0x01, (byte) 0x12, (byte) 0x00, (byte) 0x00, (byte) 0x77, -+ (byte) 0xda, (byte) 0x34, (byte) 0xab, (byte) 0xdb, (byte) 0x50, (byte) 0x00 -+ }; -+ checkSynth( -+ /* -+ * // Has a copy length that goes over the end of the meta-block, -+ * // with a ringbuffer wrap. -+ * main_header: 10 -+ * metablock_header_easy: 2, 1 -+ * command_easy: 1024, "a", 1 -+ */ -+ compressed, -+ false, -+ "" -+ ); -+ } -+ - @Test - public void testCustomHuffmanCode() { - byte[] compressed = { -@@ -2199,6 +2689,23 @@ public void testSimplePrefixOutOfRangeSymbols() { - ); - } - -+/* DISABLED: Java decoder does not tolerate extra input after the brotli stream. -+ @Test -+ public void testSimplePrefixPlusExtraData() { -+ byte[] compressed = { -+ (byte) 0x1b, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0xa0, (byte) 0xc3, (byte) 0xc4, -+ (byte) 0xc6, (byte) 0xc8, (byte) 0x02, (byte) 0x00, (byte) 0x70, (byte) 0xb0, (byte) 0x65, -+ (byte) 0x12, (byte) 0x03, (byte) 0x24, (byte) 0x00, (byte) 0x00, (byte) 0xee, (byte) 0xb4, -+ (byte) 0x51, (byte) 0xa0, (byte) 0x1d, (byte) 0x55, (byte) 0xaa -+ }; -+ checkSynth( -+ compressed, -+ true, -+ "abcd" -+ ); -+ } -+*/ -+ - @Test - public void testTooManySymbolsRepeated() { - byte[] compressed = { -@@ -2246,7 +2753,7 @@ public void testTransformedDictWord() { - * main_header - * metablock_header_easy: 9, 1 - * command_inscopy_easy: 0, 4 -- * command_dist_easy: 5121 -+ * command_dist_easy: 5121 // 5 << 10 + 1 - */ - compressed, - true, -@@ -2270,7 +2777,7 @@ public void testTransformedDictWordTooLong() { - * main_header - * metablock_header_easy: 4, 1 - * command_inscopy_easy: 0, 4 -- * command_dist_easy: 5121 -+ * command_dist_easy: 5121 // 5 << 10 + 1 - */ - compressed, - false, -@@ -2280,4 +2787,4 @@ public void testTransformedDictWordTooLong() { - - /* GENERATED CODE END */ - --} -\ No newline at end of file -+} -diff --git a/java/org/brotli/dec/Transform.java b/java/org/brotli/dec/Transform.java -index b90f2e96..3279ee73 100644 ---- a/java/org/brotli/dec/Transform.java -+++ b/java/org/brotli/dec/Transform.java -@@ -10,13 +10,58 @@ - - /** - * Transformations on dictionary words. -+ * -+ * Transform descriptor is a triplet: {prefix, operator, suffix}. -+ * "prefix" and "suffix" are short strings inserted before and after transformed dictionary word. -+ * "operator" is applied to dictionary word itself. -+ * -+ * Some operators has "built-in" parameters, i.e. parameter is defined by operator ordinal. Other -+ * operators have "external" parameters, supplied via additional table encoded in shared dictionary. -+ * -+ * Operators: -+ * - IDENTITY (0): dictionary word is inserted "as is" -+ * - OMIT_LAST_N (1 - 9): last N octets of dictionary word are not inserted; N == ordinal -+ * - OMIT_FIRST_M (12-20): first M octets of dictionary word are not inserted; M == ordinal - 11 -+ * - UPPERCASE_FIRST (10): first "scalar" is XOR'ed with number 32 -+ * - UPPERCASE_ALL (11): all "scalars" are XOR'ed with number 32 -+ * - SHIFT_FIRST (21): first "scalar" is shifted by number form parameter table -+ * - SHIFT_ALL (22): all "scalar" is shifted by number form parameter table -+ * -+ * Here "scalar" is a variable length character coding similar to UTF-8 encoding. -+ * UPPERCASE_XXX / SHIFT_XXX operators were designed to change the case of UTF-8 encoded characters. -+ * While UPPERCASE_XXX works well only on ASCII charset, SHIFT is much more generic and could be -+ * used for most (all?) alphabets. - */ - final class Transform { - -- static final int NUM_TRANSFORMS = 121; -- private static final int[] TRANSFORMS = new int[NUM_TRANSFORMS * 3]; -- private static final byte[] PREFIX_SUFFIX = new byte[217]; -- private static final int[] PREFIX_SUFFIX_HEADS = new int[51]; -+ static final class Transforms { -+ final int numTransforms; -+ final int[] triplets; -+ final byte[] prefixSuffixStorage; -+ final int[] prefixSuffixHeads; -+ final short[] params; -+ -+ Transforms(int numTransforms, int prefixSuffixLen, int prefixSuffixCount) { -+ this.numTransforms = numTransforms; -+ this.triplets = new int[numTransforms * 3]; -+ this.params = new short[numTransforms]; -+ this.prefixSuffixStorage = new byte[prefixSuffixLen]; -+ this.prefixSuffixHeads = new int[prefixSuffixCount + 1]; -+ } -+ } -+ -+ static final int NUM_RFC_TRANSFORMS = 121; -+ static final Transforms RFC_TRANSFORMS = new Transforms(NUM_RFC_TRANSFORMS, 167, 50); -+ -+ private static final int OMIT_FIRST_LAST_LIMIT = 9; -+ -+ private static final int IDENTITY = 0; -+ private static final int OMIT_LAST_BASE = IDENTITY + 1 - 1; // there is no OMIT_LAST_0. -+ private static final int UPPERCASE_FIRST = OMIT_LAST_BASE + OMIT_FIRST_LAST_LIMIT + 1; -+ private static final int UPPERCASE_ALL = UPPERCASE_FIRST + 1; -+ private static final int OMIT_FIRST_BASE = UPPERCASE_ALL + 1 - 1; // there is no OMIT_FIRST_0. -+ private static final int SHIFT_FIRST = OMIT_FIRST_BASE + OMIT_FIRST_LAST_LIMIT + 1; -+ private static final int SHIFT_ALL = SHIFT_FIRST + 1; - - // Bundle of 0-terminated strings. - private static final String PREFIX_SUFFIX_SRC = "# #s #, #e #.# the #.com/#\u00C2\u00A0# of # and" -@@ -29,71 +74,87 @@ - + " G% ! *A *% H! D I!+! J!+ K +- *4! A L!*4 M N +6 O!*% +.! K *G P +%( ! G *D +D " - + " Q +# *K!*G!+D!+# +G +A +4!+% +K!+4!*D!+K!*K"; - -- private static void unpackTransforms(byte[] prefixSuffix, int[] prefixSuffixHeads, -- int[] transforms, String prefixSuffixSrc, String transformsSrc) { -+ private static void unpackTransforms(byte[] prefixSuffix, -+ int[] prefixSuffixHeads, int[] transforms, String prefixSuffixSrc, String transformsSrc) { - int n = prefixSuffixSrc.length(); - int index = 1; -+ int j = 0; - for (int i = 0; i < n; ++i) { - char c = prefixSuffixSrc.charAt(i); -- prefixSuffix[i] = (byte) c; - if (c == 35) { // == # -- prefixSuffixHeads[index++] = i + 1; -- prefixSuffix[i] = 0; -+ prefixSuffixHeads[index++] = j; -+ } else { -+ prefixSuffix[j++] = (byte) c; - } - } - -- for (int i = 0; i < NUM_TRANSFORMS * 3; ++i) { -+ for (int i = 0; i < NUM_RFC_TRANSFORMS * 3; ++i) { - transforms[i] = transformsSrc.charAt(i) - 32; - } - } - - static { -- unpackTransforms(PREFIX_SUFFIX, PREFIX_SUFFIX_HEADS, TRANSFORMS, PREFIX_SUFFIX_SRC, -- TRANSFORMS_SRC); -+ unpackTransforms(RFC_TRANSFORMS.prefixSuffixStorage, RFC_TRANSFORMS.prefixSuffixHeads, -+ RFC_TRANSFORMS.triplets, PREFIX_SUFFIX_SRC, TRANSFORMS_SRC); - } - -- static int transformDictionaryWord(byte[] dst, int dstOffset, ByteBuffer data, int wordOffset, -- int len, int transformIndex) { -+ static int transformDictionaryWord(byte[] dst, int dstOffset, ByteBuffer src, int srcOffset, -+ int len, Transforms transforms, int transformIndex) { - int offset = dstOffset; -+ int[] triplets = transforms.triplets; -+ byte[] prefixSuffixStorage = transforms.prefixSuffixStorage; -+ int[] prefixSuffixHeads = transforms.prefixSuffixHeads; - int transformOffset = 3 * transformIndex; -- int transformPrefix = PREFIX_SUFFIX_HEADS[TRANSFORMS[transformOffset]]; -- int transformType = TRANSFORMS[transformOffset + 1]; -- int transformSuffix = PREFIX_SUFFIX_HEADS[TRANSFORMS[transformOffset + 2]]; -+ int prefixIdx = triplets[transformOffset]; -+ int transformType = triplets[transformOffset + 1]; -+ int suffixIdx = triplets[transformOffset + 2]; -+ int prefix = prefixSuffixHeads[prefixIdx]; -+ int prefixEnd = prefixSuffixHeads[prefixIdx + 1]; -+ int suffix = prefixSuffixHeads[suffixIdx]; -+ int suffixEnd = prefixSuffixHeads[suffixIdx + 1]; -+ -+ int omitFirst = transformType - OMIT_FIRST_BASE; -+ int omitLast = transformType - OMIT_LAST_BASE; -+ if (omitFirst < 1 || omitFirst > OMIT_FIRST_LAST_LIMIT) { -+ omitFirst = 0; -+ } -+ if (omitLast < 1 || omitLast > OMIT_FIRST_LAST_LIMIT) { -+ omitLast = 0; -+ } - - // Copy prefix. -- while (PREFIX_SUFFIX[transformPrefix] != 0) { -- dst[offset++] = PREFIX_SUFFIX[transformPrefix++]; -+ while (prefix != prefixEnd) { -+ dst[offset++] = prefixSuffixStorage[prefix++]; - } - - // Copy trimmed word. -- int omitFirst = transformType >= 12 ? (transformType - 11) : 0; - if (omitFirst > len) { - omitFirst = len; - } -- wordOffset += omitFirst; -+ srcOffset += omitFirst; - len -= omitFirst; -- len -= transformType <= 9 ? transformType : 0; // Omit last. -+ len -= omitLast; - int i = len; - while (i > 0) { -- dst[offset++] = data.get(wordOffset++); -+ dst[offset++] = src.get(srcOffset++); - i--; - } - - // Ferment. -- if (transformType == 11 || transformType == 10) { -+ if (transformType == UPPERCASE_FIRST || transformType == UPPERCASE_ALL) { - int uppercaseOffset = offset - len; -- if (transformType == 10) { -+ if (transformType == UPPERCASE_FIRST) { - len = 1; - } - while (len > 0) { -- int tmp = dst[uppercaseOffset] & 0xFF; -- if (tmp < 0xc0) { -- if (tmp >= 97 && tmp <= 122) { // in [a..z] range -+ int c0 = dst[uppercaseOffset] & 0xFF; -+ if (c0 < 0xC0) { -+ if (c0 >= 97 && c0 <= 122) { // in [a..z] range - dst[uppercaseOffset] ^= (byte) 32; - } - uppercaseOffset += 1; - len -= 1; -- } else if (tmp < 0xe0) { -+ } else if (c0 < 0xE0) { - dst[uppercaseOffset + 1] ^= (byte) 32; - uppercaseOffset += 2; - len -= 2; -@@ -103,11 +164,71 @@ static int transformDictionaryWord(byte[] dst, int dstOffset, ByteBuffer data, i - len -= 3; - } - } -+ } else if (transformType == SHIFT_FIRST || transformType == SHIFT_ALL) { -+ int shiftOffset = offset - len; -+ short param = transforms.params[transformIndex]; -+ /* Limited sign extension: scalar < (1 << 24). */ -+ int scalar = (param & 0x7FFF) + (0x1000000 - (param & 0x8000)); -+ while (len > 0) { -+ int step = 1; -+ int c0 = dst[shiftOffset] & 0xFF; -+ if (c0 < 0x80) { -+ /* 1-byte rune / 0sssssss / 7 bit scalar (ASCII). */ -+ scalar += c0; -+ dst[shiftOffset] = (byte) (scalar & 0x7F); -+ } else if (c0 < 0xC0) { -+ /* Continuation / 10AAAAAA. */ -+ } else if (c0 < 0xE0) { -+ /* 2-byte rune / 110sssss AAssssss / 11 bit scalar. */ -+ if (len >= 2) { -+ byte c1 = dst[shiftOffset + 1]; -+ scalar += (c1 & 0x3F) | ((c0 & 0x1F) << 6); -+ dst[shiftOffset] = (byte) (0xC0 | ((scalar >> 6) & 0x1F)); -+ dst[shiftOffset + 1] = (byte) ((c1 & 0xC0) | (scalar & 0x3F)); -+ step = 2; -+ } else { -+ step = len; -+ } -+ } else if (c0 < 0xF0) { -+ /* 3-byte rune / 1110ssss AAssssss BBssssss / 16 bit scalar. */ -+ if (len >= 3) { -+ byte c1 = dst[shiftOffset + 1]; -+ byte c2 = dst[shiftOffset + 2]; -+ scalar += (c2 & 0x3F) | ((c1 & 0x3F) << 6) | ((c0 & 0x0F) << 12); -+ dst[shiftOffset] = (byte) (0xE0 | ((scalar >> 12) & 0x0F)); -+ dst[shiftOffset + 1] = (byte) ((c1 & 0xC0) | ((scalar >> 6) & 0x3F)); -+ dst[shiftOffset + 2] = (byte) ((c2 & 0xC0) | (scalar & 0x3F)); -+ step = 3; -+ } else { -+ step = len; -+ } -+ } else if (c0 < 0xF8) { -+ /* 4-byte rune / 11110sss AAssssss BBssssss CCssssss / 21 bit scalar. */ -+ if (len >= 4) { -+ byte c1 = dst[shiftOffset + 1]; -+ byte c2 = dst[shiftOffset + 2]; -+ byte c3 = dst[shiftOffset + 3]; -+ scalar += (c3 & 0x3F) | ((c2 & 0x3F) << 6) | ((c1 & 0x3F) << 12) | ((c0 & 0x07) << 18); -+ dst[shiftOffset] = (byte) (0xF0 | ((scalar >> 18) & 0x07)); -+ dst[shiftOffset + 1] = (byte) ((c1 & 0xC0) | ((scalar >> 12) & 0x3F)); -+ dst[shiftOffset + 2] = (byte) ((c2 & 0xC0) | ((scalar >> 6) & 0x3F)); -+ dst[shiftOffset + 3] = (byte) ((c3 & 0xC0) | (scalar & 0x3F)); -+ step = 4; -+ } else { -+ step = len; -+ } -+ } -+ shiftOffset += step; -+ len -= step; -+ if (transformType == SHIFT_FIRST) { -+ len = 0; -+ } -+ } - } - - // Copy suffix. -- while (PREFIX_SUFFIX[transformSuffix] != 0) { -- dst[offset++] = PREFIX_SUFFIX[transformSuffix++]; -+ while (suffix != suffixEnd) { -+ dst[offset++] = prefixSuffixStorage[suffix++]; - } - - return offset - dstOffset; -diff --git a/java/org/brotli/dec/TransformTest.java b/java/org/brotli/dec/TransformTest.java -index 616ba351..6e04f0dc 100644 ---- a/java/org/brotli/dec/TransformTest.java -+++ b/java/org/brotli/dec/TransformTest.java -@@ -36,8 +36,8 @@ private static long crc64(byte[] data) { - public void testTrimAll() { - byte[] output = new byte[0]; - byte[] input = {119, 111, 114, 100}; // "word" -- Transform.transformDictionaryWord( -- output, 0, ByteBuffer.wrap(input), 0, input.length, 39); -+ Transform.transformDictionaryWord(output, 0, -+ ByteBuffer.wrap(input), 0, input.length, Transform.RFC_TRANSFORMS, 39); - byte[] expectedOutput = new byte[0]; - assertArrayEquals(expectedOutput, output); - } -@@ -46,8 +46,8 @@ public void testTrimAll() { - public void testCapitalize() { - byte[] output = new byte[6]; - byte[] input = {113, -61, -90, -32, -92, -86}; // "qæप" -- Transform.transformDictionaryWord( -- output, 0, ByteBuffer.wrap(input), 0, input.length, 44); -+ Transform.transformDictionaryWord(output, 0, -+ ByteBuffer.wrap(input), 0, input.length, Transform.RFC_TRANSFORMS, 44); - byte[] expectedOutput = {81, -61, -122, -32, -92, -81}; // "QÆय" - assertArrayEquals(expectedOutput, output); - } -@@ -60,9 +60,9 @@ public void testAllTransforms() { - byte[] testWord = {111, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102}; - byte[] output = new byte[2259]; - int offset = 0; -- for (int i = 0; i < Transform.NUM_TRANSFORMS; ++i) { -- offset += Transform.transformDictionaryWord( -- output, offset, ByteBuffer.wrap(testWord), 0, testWord.length, i); -+ for (int i = 0; i < Transform.NUM_RFC_TRANSFORMS; ++i) { -+ offset += Transform.transformDictionaryWord(output, offset, -+ ByteBuffer.wrap(testWord), 0, testWord.length, Transform.RFC_TRANSFORMS, i); - output[offset++] = -1; - } - assertEquals(output.length, offset); - diff --git a/v1.0.8.tar.gz b/v1.0.8.tar.gz new file mode 100644 index 0000000..6a7f442 --- /dev/null +++ b/v1.0.8.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6dcc73364b1a1ee7e49024d25e00b8ca4968396a81af99c8c6eb8757b52f74ea +size 474171