SolarFM/plugins/translate/brotli/build.py

225 lines
10 KiB
Python

# -*- coding: utf-8 -*-
import sys
from cffi import FFI
ffi = FFI()
libraries = ['libbrotli']
if 'win32' not in str(sys.platform).lower():
libraries.append('stdc++')
ffi.set_source(
"_brotli",
"""#include <brotli/decode.h>
#include <brotli/encode.h>
""",
libraries=libraries,
include_dirs=["libbrotli", "libbrotli/include"]
)
ffi.cdef("""
/* common/types.h */
typedef bool BROTLI_BOOL;
#define BROTLI_TRUE ...
#define BROTLI_FALSE ...
/* dec/state.h */
/* Allocating function pointer. Function MUST return 0 in the case of
failure. Otherwise it MUST return a valid pointer to a memory region of
at least size length. Neither items nor size are allowed to be 0.
opaque argument is a pointer provided by client and could be used to
bind function to specific object (memory pool). */
typedef void* (*brotli_alloc_func)(void* opaque, size_t size);
/* Deallocating function pointer. Function SHOULD be no-op in the case the
address is 0. */
typedef void (*brotli_free_func)(void* opaque, void* address);
/* dec/decode.h */
typedef enum {
/* Decoding error, e.g. corrupt input or memory allocation problem */
BROTLI_DECODER_RESULT_ERROR = 0,
/* Decoding successfully completed */
BROTLI_DECODER_RESULT_SUCCESS = 1,
/* Partially done; should be called again with more input */
BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT = 2,
/* Partially done; should be called again with more output */
BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT = 3
} BrotliDecoderResult;
typedef enum {...} BrotliDecoderErrorCode;
typedef ... BrotliDecoderState;
/* Creates the instance of BrotliDecoderState and initializes it.
|alloc_func| and |free_func| MUST be both zero or both non-zero. In the
case they are both zero, default memory allocators are used. |opaque| is
passed to |alloc_func| and |free_func| when they are called. */
BrotliDecoderState* BrotliDecoderCreateInstance(brotli_alloc_func,
brotli_free_func,
void *);
/* Deinitializes and frees BrotliDecoderState instance. */
void BrotliDecoderDestroyInstance(BrotliDecoderState* state);
/* Decompresses the data. Supports partial input and output.
Must be called with an allocated input buffer in |*next_in| and an
allocated output buffer in |*next_out|. The values |*available_in| and
|*available_out| must specify the allocated size in |*next_in| and
|*next_out| respectively.
After each call, |*available_in| will be decremented by the amount of
input bytes consumed, and the |*next_in| pointer will be incremented by
that amount. Similarly, |*available_out| will be decremented by the
amount of output bytes written, and the |*next_out| pointer will be
incremented by that amount. |total_out|, if it is not a null-pointer,
will be set to the number of bytes decompressed since the last state
initialization.
Input is never overconsumed, so |next_in| and |available_in| could be
passed to the next consumer after decoding is complete. */
BrotliDecoderResult BrotliDecoderDecompressStream(BrotliDecoderState* s,
size_t* available_in,
const uint8_t** next_in,
size_t* available_out,
uint8_t** next_out,
size_t* total_out);
/* Fills the new state with a dictionary for LZ77, warming up the
ringbuffer, e.g. for custom static dictionaries for data formats.
Not to be confused with the built-in transformable dictionary of Brotli.
|size| should be less or equal to 2^24 (16MiB), otherwise the dictionary
will be ignored. The dictionary must exist in memory until decoding is
done and is owned by the caller. To use:
1) Allocate and initialize state with BrotliCreateInstance
2) Use BrotliSetCustomDictionary
3) Use BrotliDecompressStream
4) Clean up and free state with BrotliDestroyState
*/
void BrotliDecoderSetCustomDictionary(
BrotliDecoderState* s, size_t size, const uint8_t* dict);
/* Returns true, if decoder has some unconsumed output.
Otherwise returns false. */
BROTLI_BOOL BrotliDecoderHasMoreOutput(const BrotliDecoderState* s);
/* Returns true, if decoder has already received some input bytes.
Otherwise returns false. */
BROTLI_BOOL BrotliDecoderIsUsed(const BrotliDecoderState* s);
/* Returns true, if decoder is in a state where we reached the end of the
input and produced all of the output; returns false otherwise. */
BROTLI_BOOL BrotliDecoderIsFinished(const BrotliDecoderState* s);
/* Returns detailed error code after BrotliDecompressStream returns
BROTLI_DECODER_RESULT_ERROR. */
BrotliDecoderErrorCode BrotliDecoderGetErrorCode(
const BrotliDecoderState* s);
const char* BrotliDecoderErrorString(BrotliDecoderErrorCode c);
/* enc/encode.h */
typedef ... BrotliEncoderState;
typedef enum BrotliEncoderParameter {
BROTLI_PARAM_MODE = 0,
/* Controls the compression-speed vs compression-density tradeoffs. The
higher the quality, the slower the compression. Range is 0 to 11. */
BROTLI_PARAM_QUALITY = 1,
/* Base 2 logarithm of the sliding window size. Range is 10 to 24. */
BROTLI_PARAM_LGWIN = 2,
/* Base 2 logarithm of the maximum input block size. Range is 16 to 24.
If set to 0, the value will be set based on the quality. */
BROTLI_PARAM_LGBLOCK = 3
} BrotliEncoderParameter;
typedef enum BrotliEncoderMode {
/* Default compression mode. The compressor does not know anything in
advance about the properties of the input. */
BROTLI_MODE_GENERIC = 0,
/* Compression mode for UTF-8 format text input. */
BROTLI_MODE_TEXT = 1,
/* Compression mode used in WOFF 2.0. */
BROTLI_MODE_FONT = 2
} BrotliEncoderMode;
int BROTLI_DEFAULT_QUALITY = 11;
int BROTLI_DEFAULT_WINDOW = 22;
#define BROTLI_DEFAULT_MODE ...
typedef enum BrotliEncoderOperation {
BROTLI_OPERATION_PROCESS = 0,
/* Request output stream to flush. Performed when input stream is
depleted and there is enough space in output stream. */
BROTLI_OPERATION_FLUSH = 1,
/* Request output stream to finish. Performed when input stream is
depleted and there is enough space in output stream. */
BROTLI_OPERATION_FINISH = 2
} BrotliEncoderOperation;
/* Creates the instance of BrotliEncoderState and initializes it.
|alloc_func| and |free_func| MUST be both zero or both non-zero. In the
case they are both zero, default memory allocators are used. |opaque| is
passed to |alloc_func| and |free_func| when they are called. */
BrotliEncoderState* BrotliEncoderCreateInstance(brotli_alloc_func,
brotli_free_func,
void *);
/* Deinitializes and frees BrotliEncoderState instance. */
void BrotliEncoderDestroyInstance(BrotliEncoderState* state);
/* Compresses the data in |input_buffer| into |encoded_buffer|, and sets
|*encoded_size| to the compressed length.
BROTLI_DEFAULT_QUALITY, BROTLI_DEFAULT_WINDOW and BROTLI_DEFAULT_MODE
should be used as |quality|, |lgwin| and |mode| if there are no specific
requirements to encoder speed and compression ratio.
If compression fails, |*encoded_size| is set to 0.
If BrotliEncoderMaxCompressedSize(|input_size|) is not zero, then
|*encoded_size| is never set to the bigger value.
Returns false if there was an error and true otherwise. */
BROTLI_BOOL BrotliEncoderCompress(int quality,
int lgwin,
BrotliEncoderMode mode,
size_t input_size,
const uint8_t* input_buffer,
size_t* encoded_size,
uint8_t* encoded_buffer);
BROTLI_BOOL BrotliEncoderCompressStream(BrotliEncoderState* s,
BrotliEncoderOperation op,
size_t* available_in,
const uint8_t** next_in,
size_t* available_out,
uint8_t** next_out,
size_t* total_out);
BROTLI_BOOL BrotliEncoderSetParameter(BrotliEncoderState* state,
BrotliEncoderParameter p,
uint32_t value);
/* Fills the new state with a dictionary for LZ77, warming up the
ringbuffer, e.g. for custom static dictionaries for data formats.
Not to be confused with the built-in transformable dictionary of Brotli.
To decode, use BrotliSetCustomDictionary() of the decoder with the same
dictionary. */
void BrotliEncoderSetCustomDictionary(BrotliEncoderState* state,
size_t size,
const uint8_t* dict);
/* Check if encoder is in "finished" state, i.e. no more input is
acceptable and no more output will be produced.
Works only with BrotliEncoderCompressStream workflow.
Returns 1 if stream is finished and 0 otherwise. */
BROTLI_BOOL BrotliEncoderIsFinished(BrotliEncoderState* s);
/* Check if encoder has more output bytes in internal buffer.
Works only with BrotliEncoderCompressStream workflow.
Returns 1 if has more output (in internal buffer) and 0 otherwise. */
BROTLI_BOOL BrotliEncoderHasMoreOutput(BrotliEncoderState* s);
""")
if __name__ == '__main__':
ffi.compile()