Merge pull request #1005 from sullis:enum-values
PiperOrigin-RevId: 506138469
diff --git a/bootstrap b/bootstrap
old mode 100644
new mode 100755
index 1da6d60..d4325b2
--- a/bootstrap
+++ b/bootstrap
@@ -9,7 +9,8 @@
# -E is POSIX. -r is for GNU sed older than 4.2.
echo hello | sed -E s/hello/world/ >/dev/null 2>&1 && SED_ERE=-E || SED_ERE=-r
-# If libtool is not installed -> "error: Libtool library used but 'LIBTOOL' is undefined"
+# If libtool is not installed ->
+# "error: Libtool library used but 'LIBTOOL' is undefined"
if [ ! -e "./m4" ]; then
mkdir m4 2>/dev/null
diff --git a/c/dec/bit_reader.h b/c/dec/bit_reader.h
index c737bda..64701ec 100644
--- a/c/dec/bit_reader.h
+++ b/c/dec/bit_reader.h
@@ -341,6 +341,11 @@
return TO_BROTLI_BOOL(pad_bits == 0);
}
+static BROTLI_INLINE void BrotliDropBytes(BrotliBitReader* br, size_t num) {
+ br->avail_in -= num;
+ br->next_in += num;
+}
+
/* Copies remaining input bytes stored in the bit reader to the output. Value
|num| may not be larger than BrotliGetRemainingBytes. The bit reader must be
warmed up again after this. */
@@ -352,9 +357,10 @@
++dest;
--num;
}
- memcpy(dest, br->next_in, num);
- br->avail_in -= num;
- br->next_in += num;
+ if (num > 0) {
+ memcpy(dest, br->next_in, num);
+ BrotliDropBytes(br, num);
+ }
}
#if defined(__cplusplus) || defined(c_plusplus)
diff --git a/c/dec/decode.c b/c/dec/decode.c
index 845f556..3ee1963 100644
--- a/c/dec/decode.c
+++ b/c/dec/decode.c
@@ -1354,6 +1354,57 @@
return BROTLI_TRUE;
}
+static BrotliDecoderErrorCode BROTLI_NOINLINE
+SkipMetadataBlock(BrotliDecoderState* s) {
+ BrotliBitReader* br = &s->br;
+
+ if (s->meta_block_remaining_len == 0) {
+ return BROTLI_DECODER_SUCCESS;
+ }
+
+ BROTLI_DCHECK((BrotliGetAvailableBits(br) & 7) == 0);
+
+ /* Drain accumulator. */
+ if (BrotliGetAvailableBits(br) >= 8) {
+ uint8_t buffer[8];
+ int nbytes = (int)(BrotliGetAvailableBits(br)) >> 3;
+ BROTLI_DCHECK(nbytes <= 8);
+ if (nbytes > s->meta_block_remaining_len) {
+ nbytes = s->meta_block_remaining_len;
+ }
+ BrotliCopyBytes(buffer, br, (size_t)nbytes);
+ if (s->metadata_chunk_func) {
+ s->metadata_chunk_func(s->metadata_callback_opaque, buffer,
+ (size_t)nbytes);
+ }
+ s->meta_block_remaining_len -= nbytes;
+ if (s->meta_block_remaining_len == 0) {
+ return BROTLI_DECODER_SUCCESS;
+ }
+ }
+
+ /* Direct access to metadata is possible. */
+ int nbytes = (int)BrotliGetRemainingBytes(br);
+ if (nbytes > s->meta_block_remaining_len) {
+ nbytes = s->meta_block_remaining_len;
+ }
+ if (nbytes > 0) {
+ if (s->metadata_chunk_func) {
+ s->metadata_chunk_func(s->metadata_callback_opaque, br->next_in,
+ (size_t)nbytes);
+ }
+ BrotliDropBytes(br, (size_t)nbytes);
+ s->meta_block_remaining_len -= nbytes;
+ if (s->meta_block_remaining_len == 0) {
+ return BROTLI_DECODER_SUCCESS;
+ }
+ }
+
+ BROTLI_DCHECK(BrotliGetRemainingBytes(br) == 0);
+
+ return BROTLI_DECODER_NEEDS_MORE_INPUT;
+}
+
static BrotliDecoderErrorCode BROTLI_NOINLINE CopyUncompressedBlockToOutput(
size_t* available_out, uint8_t** next_out, size_t* total_out,
BrotliDecoderState* s) {
@@ -2414,6 +2465,10 @@
}
if (s->is_metadata) {
s->state = BROTLI_STATE_METADATA;
+ if (s->metadata_start_func) {
+ s->metadata_start_func(s->metadata_callback_opaque,
+ (size_t)s->meta_block_remaining_len);
+ }
break;
}
if (s->meta_block_remaining_len == 0) {
@@ -2506,17 +2561,11 @@
}
case BROTLI_STATE_METADATA:
- for (; s->meta_block_remaining_len > 0; --s->meta_block_remaining_len) {
- uint32_t bits;
- /* Read one byte and ignore it. */
- if (!BrotliSafeReadBits(br, 8, &bits)) {
- result = BROTLI_DECODER_NEEDS_MORE_INPUT;
- break;
- }
+ result = SkipMetadataBlock(s);
+ if (result != BROTLI_DECODER_SUCCESS) {
+ break;
}
- if (result == BROTLI_DECODER_SUCCESS) {
- s->state = BROTLI_STATE_METABLOCK_DONE;
- }
+ s->state = BROTLI_STATE_METABLOCK_DONE;
break;
case BROTLI_STATE_METABLOCK_HEADER_2: {
@@ -2785,6 +2834,15 @@
return BROTLI_VERSION;
}
+void BrotliDecoderSetMetadataCallbacks(
+ BrotliDecoderState* state,
+ brotli_decoder_metadata_start_func start_func,
+ brotli_decoder_metadata_chunk_func chunk_func, void* opaque) {
+ state->metadata_start_func = start_func;
+ state->metadata_chunk_func = chunk_func;
+ state->metadata_callback_opaque = opaque;
+}
+
/* Escalate internal functions visibility; for testing purposes only. */
#if defined(BROTLI_TEST)
BROTLI_BOOL SafeReadSymbolForTest(
diff --git a/c/dec/state.c b/c/dec/state.c
index 08d4c8b..a3baf37 100644
--- a/c/dec/state.c
+++ b/c/dec/state.c
@@ -89,6 +89,10 @@
BrotliSharedDictionaryCreateInstance(alloc_func, free_func, opaque);
if (!s->dictionary) return BROTLI_FALSE;
+ s->metadata_start_func = NULL;
+ s->metadata_chunk_func = NULL;
+ s->metadata_callback_opaque = 0;
+
return BROTLI_TRUE;
}
diff --git a/c/dec/state.h b/c/dec/state.h
index 6ec5c8f..84fddc8 100644
--- a/c/dec/state.h
+++ b/c/dec/state.h
@@ -9,6 +9,7 @@
#ifndef BROTLI_DEC_STATE_H_
#define BROTLI_DEC_STATE_H_
+#include <brotli/decode.h>
#include <brotli/shared_dictionary.h>
#include <brotli/types.h>
@@ -322,6 +323,10 @@
/* Less used attributes are at the end of this struct. */
+ brotli_decoder_metadata_start_func metadata_start_func;
+ brotli_decoder_metadata_chunk_func metadata_chunk_func;
+ void* metadata_callback_opaque;
+
/* For reporting. */
uint64_t used_input; /* how many bytes of input are consumed */
diff --git a/c/enc/encode.c b/c/enc/encode.c
index 1d22525..4627ea0 100644
--- a/c/enc/encode.c
+++ b/c/enc/encode.c
@@ -1188,7 +1188,7 @@
if (block_size == 0) {
BrotliWriteBits(2, 0, &storage_ix, header);
} else {
- uint32_t nbits = (block_size == 1) ? 0 :
+ uint32_t nbits = (block_size == 1) ? 1 :
(Log2FloorNonZero((uint32_t)block_size - 1) + 1);
uint32_t nbytes = (nbits + 7) / 8;
BrotliWriteBits(2, nbytes, &storage_ix, header);
diff --git a/c/enc/find_match_length.h b/c/enc/find_match_length.h
index dee0414..f3de0bd 100644
--- a/c/enc/find_match_length.h
+++ b/c/enc/find_match_length.h
@@ -22,31 +22,23 @@
static BROTLI_INLINE size_t FindMatchLengthWithLimit(const uint8_t* s1,
const uint8_t* s2,
size_t limit) {
- size_t matched = 0;
- size_t limit2 = (limit >> 3) + 1; /* + 1 is for pre-decrement in while */
- while (BROTLI_PREDICT_TRUE(--limit2)) {
- if (BROTLI_PREDICT_FALSE(BROTLI_UNALIGNED_LOAD64LE(s2) ==
- BROTLI_UNALIGNED_LOAD64LE(s1 + matched))) {
- s2 += 8;
- matched += 8;
- } else {
- uint64_t x = BROTLI_UNALIGNED_LOAD64LE(s2) ^
- BROTLI_UNALIGNED_LOAD64LE(s1 + matched);
+ const uint8_t *s1_orig = s1;
+ for (; limit >= 8; limit -= 8) {
+ uint64_t x = BROTLI_UNALIGNED_LOAD64LE(s2) ^
+ BROTLI_UNALIGNED_LOAD64LE(s1);
+ s2 += 8;
+ if (x != 0) {
size_t matching_bits = (size_t)BROTLI_TZCNT64(x);
- matched += matching_bits >> 3;
- return matched;
+ return (size_t)(s1 - s1_orig) + (matching_bits >> 3);
}
+ s1 += 8;
}
- limit = (limit & 7) + 1; /* + 1 is for pre-decrement in while */
- while (--limit) {
- if (BROTLI_PREDICT_TRUE(s1[matched] == *s2)) {
- ++s2;
- ++matched;
- } else {
- return matched;
- }
+ while (limit && *s1 == *s2) {
+ limit--;
+ ++s2;
+ ++s1;
}
- return matched;
+ return (size_t)(s1 - s1_orig);
}
#else
static BROTLI_INLINE size_t FindMatchLengthWithLimit(const uint8_t* s1,
diff --git a/c/include/brotli/decode.h b/c/include/brotli/decode.h
index 9b580d2..3c473d6 100644
--- a/c/include/brotli/decode.h
+++ b/c/include/brotli/decode.h
@@ -361,6 +361,47 @@
*/
BROTLI_DEC_API uint32_t BrotliDecoderVersion(void);
+/**
+ * Callback to fire on metadata block start.
+ *
+ * After this callback is fired, if @p size is not @c 0, it is followed by
+ * ::brotli_decoder_metadata_chunk_func as more metadata block contents become
+ * accessible.
+ *
+ * @param opaque callback handle
+ * @param size size of metadata block
+ */
+typedef void (*brotli_decoder_metadata_start_func)(void* opaque, size_t size);
+
+/**
+ * Callback to fire on metadata block chunk becomes available.
+ *
+ * This function can be invoked multiple times per metadata block; block should
+ * be considered finished when sum of @p size matches the announced metadata
+ * block size. Chunks contents pointed by @p data are transient and shouln not
+ * be accessed after leaving the callback.
+ *
+ * @param opaque callback handle
+ * @param data pointer to metadata contents
+ * @param size size of metadata block chunk, at least @c 1
+ */
+typedef void (*brotli_decoder_metadata_chunk_func)(void* opaque,
+ const uint8_t* data,
+ size_t size);
+
+/**
+ * Sets callback for receiving metadata blocks.
+ *
+ * @param state decoder instance
+ * @param start_func callback on metadata block start
+ * @param chunk_func callback on metadata block chunk
+ * @param opaque callback handle
+ */
+BROTLI_DEC_API void BrotliDecoderSetMetadataCallbacks(
+ BrotliDecoderState* state,
+ brotli_decoder_metadata_start_func start_func,
+ brotli_decoder_metadata_chunk_func chunk_func, void* opaque);
+
#if defined(__cplusplus) || defined(c_plusplus)
} /* extern "C" */
#endif
diff --git a/configure-cmake b/configure-cmake
old mode 100644
new mode 100755
index 6dfb92c..929300b
--- a/configure-cmake
+++ b/configure-cmake
@@ -315,4 +315,8 @@
done
fi
-eval "${CMAKE_CMD}" "${TOP_SRCDIR}" -DCMAKE_BUILD_TYPE="${BUILD_TYPE}" -DCMAKE_INSTALL_PREFIX="${PREFIX}" -DCMAKE_INSTALL_LIBDIR="${LIBDIR}" ${CMAKE_ARGS}
+eval "${CMAKE_CMD}" "${TOP_SRCDIR}" \
+ -DCMAKE_BUILD_TYPE="${BUILD_TYPE}" \
+ -DCMAKE_INSTALL_PREFIX="${PREFIX}" \
+ -DCMAKE_INSTALL_LIBDIR="${LIBDIR}" \
+ ${CMAKE_ARGS}
diff --git a/docs/decode.h.3 b/docs/decode.h.3
index 3d4e538..320663c 100644
--- a/docs/decode.h.3
+++ b/docs/decode.h.3
@@ -23,6 +23,14 @@
.in +1c
.ti -1c
+.RI "typedef void(* \fBbrotli_decoder_metadata_chunk_func\fP) (void *opaque, const uint8_t *data, size_t size)"
+.br
+.RI "\fICallback to fire on metadata block chunk becomes available\&. \fP"
+.ti -1c
+.RI "typedef void(* \fBbrotli_decoder_metadata_start_func\fP) (void *opaque, size_t size)"
+.br
+.RI "\fICallback to fire on metadata block start\&. \fP"
+.ti -1c
.RI "typedef enum \fBBrotliDecoderParameter\fP \fBBrotliDecoderParameter\fP"
.br
.RI "\fIOptions to be used with \fBBrotliDecoderSetParameter\fP\&. \fP"
@@ -76,6 +84,10 @@
.br
.RI "\fIChecks if instance has already consumed input\&. \fP"
.ti -1c
+.RI "void \fBBrotliDecoderSetMetadataCallbacks\fP (\fBBrotliDecoderState\fP *state, \fBbrotli_decoder_metadata_start_func\fP start_func, \fBbrotli_decoder_metadata_chunk_func\fP chunk_func, void *opaque)"
+.br
+.RI "\fISets callback for receiving metadata blocks\&. \fP"
+.ti -1c
.RI "\fBBROTLI_BOOL\fP \fBBrotliDecoderSetParameter\fP (\fBBrotliDecoderState\fP *state, \fBBrotliDecoderParameter\fP param, uint32_t value)"
.br
.RI "\fISets the specified parameter to the given decoder instance\&. \fP"
@@ -123,6 +135,34 @@
The value of the last error code, negative integer\&. All other error code values are in the range from \fBBROTLI_LAST_ERROR_CODE\fP to \fC-1\fP\&. There are also 4 other possible non-error codes \fC0\fP \&.\&. \fC3\fP in \fBBrotliDecoderErrorCode\fP enumeration\&.
.SH "Typedef Documentation"
.PP
+.SS "typedef void(* brotli_decoder_metadata_chunk_func) (void *opaque, const uint8_t *data, size_t size)"
+
+.PP
+Callback to fire on metadata block chunk becomes available\&. This function can be invoked multiple times per metadata block; block should be considered finished when sum of \fCsize\fP matches the announced metadata block size\&. Chunks contents pointed by \fCdata\fP are transient and shouln not be accessed after leaving the callback\&.
+.PP
+\fBParameters:\fP
+.RS 4
+\fIopaque\fP callback handle
+.br
+\fIdata\fP pointer to metadata contents
+.br
+\fIsize\fP size of metadata block chunk, at least \fC1\fP
+.RE
+.PP
+
+.SS "typedef void(* brotli_decoder_metadata_start_func) (void *opaque, size_t size)"
+
+.PP
+Callback to fire on metadata block start\&. After this callback is fired, if \fCsize\fP is not \fC0\fP, it is followed by \fBbrotli_decoder_metadata_chunk_func\fP as more metadata block contents become accessible\&.
+.PP
+\fBParameters:\fP
+.RS 4
+\fIopaque\fP callback handle
+.br
+\fIsize\fP size of metadata block
+.RE
+.PP
+
.SS "typedef enum \fBBrotliDecoderParameter\fP \fBBrotliDecoderParameter\fP"
.PP
@@ -378,6 +418,23 @@
.RE
.PP
+.SS "void BrotliDecoderSetMetadataCallbacks (\fBBrotliDecoderState\fP * state, \fBbrotli_decoder_metadata_start_func\fP start_func, \fBbrotli_decoder_metadata_chunk_func\fP chunk_func, void * opaque)"
+
+.PP
+Sets callback for receiving metadata blocks\&.
+.PP
+\fBParameters:\fP
+.RS 4
+\fIstate\fP decoder instance
+.br
+\fIstart_func\fP callback on metadata block start
+.br
+\fIchunk_func\fP callback on metadata block chunk
+.br
+\fIopaque\fP callback handle
+.RE
+.PP
+
.SS "\fBBROTLI_BOOL\fP BrotliDecoderSetParameter (\fBBrotliDecoderState\fP * state, \fBBrotliDecoderParameter\fP param, uint32_t value)"
.PP
diff --git a/python/bro.py b/python/bro.py
index 6d71549..b742fd7 100755
--- a/python/bro.py
+++ b/python/bro.py
@@ -3,9 +3,9 @@
from __future__ import print_function
import argparse
-import sys
import os
import platform
+import sys
import brotli