ruby-brs 1.1.1 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +87 -85
- data/ext/brs_ext/buffer.c +21 -7
- data/ext/brs_ext/buffer.h +7 -7
- data/ext/brs_ext/common.h +3 -0
- data/ext/brs_ext/error.c +0 -1
- data/ext/brs_ext/error.h +2 -1
- data/ext/brs_ext/gvl.h +24 -0
- data/ext/brs_ext/io.c +273 -157
- data/ext/brs_ext/main.c +0 -1
- data/ext/brs_ext/option.c +37 -30
- data/ext/brs_ext/option.h +39 -32
- data/ext/brs_ext/stream/compressor.c +124 -61
- data/ext/brs_ext/stream/compressor.h +7 -4
- data/ext/brs_ext/stream/decompressor.c +60 -31
- data/ext/brs_ext/stream/decompressor.h +7 -4
- data/ext/brs_ext/string.c +118 -66
- data/ext/extconf.rb +9 -0
- data/lib/brs/file.rb +4 -0
- data/lib/brs/option.rb +6 -0
- data/lib/brs/stream/abstract.rb +9 -12
- data/lib/brs/stream/raw/abstract.rb +6 -2
- data/lib/brs/stream/raw/compressor.rb +3 -7
- data/lib/brs/stream/raw/decompressor.rb +1 -5
- data/lib/brs/stream/reader.rb +71 -52
- data/lib/brs/stream/writer.rb +10 -5
- data/lib/brs/stream/writer_helpers.rb +6 -5
- data/lib/brs/validation.rb +15 -2
- data/lib/brs/version.rb +1 -1
- metadata +20 -19
data/ext/brs_ext/main.c
CHANGED
data/ext/brs_ext/option.c
CHANGED
@@ -5,21 +5,18 @@
|
|
5
5
|
|
6
6
|
#include <brotli/decode.h>
|
7
7
|
#include <brotli/encode.h>
|
8
|
-
#include <stdbool.h>
|
9
|
-
#include <stdlib.h>
|
10
8
|
|
11
|
-
#include "brs_ext/common.h"
|
12
9
|
#include "brs_ext/error.h"
|
13
10
|
#include "ruby.h"
|
14
11
|
|
15
12
|
// -- values --
|
16
13
|
|
17
|
-
static inline VALUE
|
14
|
+
static inline VALUE get_raw_value(VALUE options, const char* name)
|
18
15
|
{
|
19
16
|
return rb_funcall(options, rb_intern("[]"), 1, ID2SYM(rb_intern(name)));
|
20
17
|
}
|
21
18
|
|
22
|
-
static inline bool
|
19
|
+
static inline bool get_bool_value(VALUE raw_value)
|
23
20
|
{
|
24
21
|
int raw_type = TYPE(raw_value);
|
25
22
|
if (raw_type != T_TRUE && raw_type != T_FALSE) {
|
@@ -29,35 +26,39 @@ static inline bool get_bool_option_value(VALUE raw_value)
|
|
29
26
|
return raw_type == T_TRUE;
|
30
27
|
}
|
31
28
|
|
32
|
-
static inline unsigned int
|
29
|
+
static inline unsigned int get_uint_value(VALUE raw_value)
|
33
30
|
{
|
34
31
|
Check_Type(raw_value, T_FIXNUM);
|
35
32
|
|
36
33
|
return NUM2UINT(raw_value);
|
37
34
|
}
|
38
35
|
|
39
|
-
static inline
|
36
|
+
static inline size_t get_size_value(VALUE raw_value)
|
37
|
+
{
|
38
|
+
Check_Type(raw_value, T_FIXNUM);
|
39
|
+
|
40
|
+
return NUM2SIZET(raw_value);
|
41
|
+
}
|
42
|
+
|
43
|
+
static inline BrotliEncoderMode get_mode_value(VALUE raw_value)
|
40
44
|
{
|
41
45
|
Check_Type(raw_value, T_SYMBOL);
|
42
46
|
|
43
47
|
ID raw_id = SYM2ID(raw_value);
|
44
48
|
if (raw_id == rb_intern("text")) {
|
45
49
|
return BROTLI_MODE_TEXT;
|
46
|
-
}
|
47
|
-
else if (raw_id == rb_intern("font")) {
|
50
|
+
} else if (raw_id == rb_intern("font")) {
|
48
51
|
return BROTLI_MODE_FONT;
|
49
|
-
}
|
50
|
-
else if (raw_id == rb_intern("generic")) {
|
52
|
+
} else if (raw_id == rb_intern("generic")) {
|
51
53
|
return BROTLI_MODE_GENERIC;
|
52
|
-
}
|
53
|
-
else {
|
54
|
+
} else {
|
54
55
|
brs_ext_raise_error(BRS_EXT_ERROR_VALIDATE_FAILED);
|
55
56
|
}
|
56
57
|
}
|
57
58
|
|
58
|
-
void
|
59
|
+
void brs_ext_resolve_option(VALUE options, brs_ext_option_t* option, brs_ext_option_type_t type, const char* name)
|
59
60
|
{
|
60
|
-
VALUE raw_value =
|
61
|
+
VALUE raw_value = get_raw_value(options, name);
|
61
62
|
|
62
63
|
option->has_value = raw_value != Qnil;
|
63
64
|
if (!option->has_value) {
|
@@ -68,13 +69,13 @@ void brs_ext_get_option(VALUE options, brs_ext_option_t* option, brs_ext_option_
|
|
68
69
|
|
69
70
|
switch (type) {
|
70
71
|
case BRS_EXT_OPTION_TYPE_BOOL:
|
71
|
-
value =
|
72
|
+
value = get_bool_value(raw_value) ? 1 : 0;
|
72
73
|
break;
|
73
74
|
case BRS_EXT_OPTION_TYPE_UINT:
|
74
|
-
value = (brs_ext_option_value_t)
|
75
|
+
value = (brs_ext_option_value_t) get_uint_value(raw_value);
|
75
76
|
break;
|
76
77
|
case BRS_EXT_OPTION_TYPE_MODE:
|
77
|
-
value = (brs_ext_option_value_t)
|
78
|
+
value = (brs_ext_option_value_t) get_mode_value(raw_value);
|
78
79
|
break;
|
79
80
|
default:
|
80
81
|
brs_ext_raise_error(BRS_EXT_ERROR_UNEXPECTED);
|
@@ -83,13 +84,18 @@ void brs_ext_get_option(VALUE options, brs_ext_option_t* option, brs_ext_option_
|
|
83
84
|
option->value = value;
|
84
85
|
}
|
85
86
|
|
86
|
-
|
87
|
+
bool brs_ext_get_bool_option_value(VALUE options, const char* name)
|
87
88
|
{
|
88
|
-
VALUE raw_value =
|
89
|
+
VALUE raw_value = get_raw_value(options, name);
|
89
90
|
|
90
|
-
|
91
|
+
return get_bool_value(raw_value);
|
92
|
+
}
|
91
93
|
|
92
|
-
|
94
|
+
size_t brs_ext_get_size_option_value(VALUE options, const char* name)
|
95
|
+
{
|
96
|
+
VALUE raw_value = get_raw_value(options, name);
|
97
|
+
|
98
|
+
return get_size_value(raw_value);
|
93
99
|
}
|
94
100
|
|
95
101
|
// -- set params --
|
@@ -108,7 +114,8 @@ brs_ext_result_t brs_ext_set_compressor_options(BrotliEncoderState* state_ptr, b
|
|
108
114
|
SET_ENCODER_PARAM(state_ptr, BROTLI_PARAM_QUALITY, options->quality);
|
109
115
|
SET_ENCODER_PARAM(state_ptr, BROTLI_PARAM_LGWIN, options->lgwin);
|
110
116
|
SET_ENCODER_PARAM(state_ptr, BROTLI_PARAM_LGBLOCK, options->lgblock);
|
111
|
-
SET_ENCODER_PARAM(
|
117
|
+
SET_ENCODER_PARAM(
|
118
|
+
state_ptr, BROTLI_PARAM_DISABLE_LITERAL_CONTEXT_MODELING, options->disable_literal_context_modeling);
|
112
119
|
SET_ENCODER_PARAM(state_ptr, BROTLI_PARAM_SIZE_HINT, options->size_hint);
|
113
120
|
SET_ENCODER_PARAM(state_ptr, BROTLI_PARAM_LARGE_WINDOW, options->large_window);
|
114
121
|
|
@@ -118,9 +125,12 @@ brs_ext_result_t brs_ext_set_compressor_options(BrotliEncoderState* state_ptr, b
|
|
118
125
|
#define SET_DECODER_PARAM(state_ptr, param, option) \
|
119
126
|
SET_OPTION_VALUE(BrotliDecoderSetParameter, state_ptr, param, option);
|
120
127
|
|
121
|
-
brs_ext_result_t brs_ext_set_decompressor_options(
|
128
|
+
brs_ext_result_t brs_ext_set_decompressor_options(
|
129
|
+
BrotliDecoderState* state_ptr,
|
130
|
+
brs_ext_decompressor_options_t* options)
|
122
131
|
{
|
123
|
-
SET_DECODER_PARAM(
|
132
|
+
SET_DECODER_PARAM(
|
133
|
+
state_ptr, BROTLI_DECODER_PARAM_DISABLE_RING_BUFFER_REALLOCATION, options->disable_ring_buffer_reallocation);
|
124
134
|
SET_DECODER_PARAM(state_ptr, BROTLI_DECODER_PARAM_LARGE_WINDOW, options->large_window);
|
125
135
|
|
126
136
|
return 0;
|
@@ -136,11 +146,8 @@ void brs_ext_option_exports(VALUE root_module)
|
|
136
146
|
{
|
137
147
|
VALUE module = rb_define_module_under(root_module, "Option");
|
138
148
|
|
139
|
-
VALUE modes =
|
140
|
-
3,
|
141
|
-
ID2SYM(rb_intern("text")),
|
142
|
-
ID2SYM(rb_intern("font")),
|
143
|
-
ID2SYM(rb_intern("generic")));
|
149
|
+
VALUE modes =
|
150
|
+
rb_ary_new_from_args(3, ID2SYM(rb_intern("text")), ID2SYM(rb_intern("font")), ID2SYM(rb_intern("generic")));
|
144
151
|
rb_define_const(module, "MODES", modes);
|
145
152
|
RB_GC_GUARD(modes);
|
146
153
|
|
data/ext/brs_ext/option.h
CHANGED
@@ -7,7 +7,6 @@
|
|
7
7
|
#include <brotli/decode.h>
|
8
8
|
#include <brotli/encode.h>
|
9
9
|
#include <stdbool.h>
|
10
|
-
#include <stdint.h>
|
11
10
|
#include <stdlib.h>
|
12
11
|
|
13
12
|
#include "brs_ext/common.h"
|
@@ -16,21 +15,24 @@
|
|
16
15
|
// Default option values depends on brotli library.
|
17
16
|
// We will set only user defined values.
|
18
17
|
|
19
|
-
enum
|
18
|
+
enum
|
19
|
+
{
|
20
20
|
BRS_EXT_OPTION_TYPE_BOOL = 1,
|
21
21
|
BRS_EXT_OPTION_TYPE_UINT,
|
22
22
|
BRS_EXT_OPTION_TYPE_MODE
|
23
23
|
};
|
24
24
|
|
25
|
-
typedef
|
26
|
-
typedef uint32_t
|
25
|
+
typedef brs_ext_byte_fast_t brs_ext_option_type_t;
|
26
|
+
typedef uint32_t brs_ext_option_value_t;
|
27
27
|
|
28
|
-
typedef struct
|
28
|
+
typedef struct
|
29
|
+
{
|
29
30
|
bool has_value;
|
30
31
|
brs_ext_option_value_t value;
|
31
32
|
} brs_ext_option_t;
|
32
33
|
|
33
|
-
typedef struct
|
34
|
+
typedef struct
|
35
|
+
{
|
34
36
|
brs_ext_option_t mode;
|
35
37
|
brs_ext_option_t quality;
|
36
38
|
brs_ext_option_t lgwin;
|
@@ -40,40 +42,45 @@ typedef struct {
|
|
40
42
|
brs_ext_option_t large_window;
|
41
43
|
} brs_ext_compressor_options_t;
|
42
44
|
|
43
|
-
typedef struct
|
45
|
+
typedef struct
|
46
|
+
{
|
44
47
|
brs_ext_option_t disable_ring_buffer_reallocation;
|
45
48
|
brs_ext_option_t large_window;
|
46
49
|
} brs_ext_decompressor_options_t;
|
47
50
|
|
48
|
-
void
|
49
|
-
|
50
|
-
#define
|
51
|
-
|
52
|
-
|
53
|
-
#define BRS_EXT_GET_COMPRESSOR_OPTIONS(options)
|
54
|
-
brs_ext_compressor_options_t compressor_options;
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
#define BRS_EXT_GET_DECOMPRESSOR_OPTIONS(options)
|
65
|
-
brs_ext_decompressor_options_t decompressor_options;
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
51
|
+
void brs_ext_resolve_option(VALUE options, brs_ext_option_t* option, brs_ext_option_type_t type, const char* name);
|
52
|
+
|
53
|
+
#define BRS_EXT_RESOLVE_OPTION(options, target_options, type, name) \
|
54
|
+
brs_ext_resolve_option(options, &target_options.name, type, #name);
|
55
|
+
|
56
|
+
#define BRS_EXT_GET_COMPRESSOR_OPTIONS(options) \
|
57
|
+
brs_ext_compressor_options_t compressor_options; \
|
58
|
+
\
|
59
|
+
BRS_EXT_RESOLVE_OPTION(options, compressor_options, BRS_EXT_OPTION_TYPE_MODE, mode); \
|
60
|
+
BRS_EXT_RESOLVE_OPTION(options, compressor_options, BRS_EXT_OPTION_TYPE_UINT, quality); \
|
61
|
+
BRS_EXT_RESOLVE_OPTION(options, compressor_options, BRS_EXT_OPTION_TYPE_UINT, lgwin); \
|
62
|
+
BRS_EXT_RESOLVE_OPTION(options, compressor_options, BRS_EXT_OPTION_TYPE_UINT, lgblock); \
|
63
|
+
BRS_EXT_RESOLVE_OPTION(options, compressor_options, BRS_EXT_OPTION_TYPE_BOOL, disable_literal_context_modeling); \
|
64
|
+
BRS_EXT_RESOLVE_OPTION(options, compressor_options, BRS_EXT_OPTION_TYPE_UINT, size_hint); \
|
65
|
+
BRS_EXT_RESOLVE_OPTION(options, compressor_options, BRS_EXT_OPTION_TYPE_BOOL, large_window);
|
66
|
+
|
67
|
+
#define BRS_EXT_GET_DECOMPRESSOR_OPTIONS(options) \
|
68
|
+
brs_ext_decompressor_options_t decompressor_options; \
|
69
|
+
\
|
70
|
+
BRS_EXT_RESOLVE_OPTION(options, decompressor_options, BRS_EXT_OPTION_TYPE_BOOL, disable_ring_buffer_reallocation); \
|
71
|
+
BRS_EXT_RESOLVE_OPTION(options, decompressor_options, BRS_EXT_OPTION_TYPE_BOOL, large_window);
|
72
|
+
|
73
|
+
bool brs_ext_get_bool_option_value(VALUE options, const char* name);
|
70
74
|
size_t brs_ext_get_size_option_value(VALUE options, const char* name);
|
71
75
|
|
72
|
-
#define
|
73
|
-
|
76
|
+
#define BRS_EXT_GET_BOOL_OPTION(options, name) size_t name = brs_ext_get_bool_option_value(options, #name);
|
77
|
+
#define BRS_EXT_GET_SIZE_OPTION(options, name) size_t name = brs_ext_get_size_option_value(options, #name);
|
74
78
|
|
75
79
|
brs_ext_result_t brs_ext_set_compressor_options(BrotliEncoderState* state_ptr, brs_ext_compressor_options_t* options);
|
76
|
-
|
80
|
+
|
81
|
+
brs_ext_result_t brs_ext_set_decompressor_options(
|
82
|
+
BrotliDecoderState* state_ptr,
|
83
|
+
brs_ext_decompressor_options_t* options);
|
77
84
|
|
78
85
|
void brs_ext_option_exports(VALUE root_module);
|
79
86
|
|
@@ -5,15 +5,15 @@
|
|
5
5
|
|
6
6
|
#include <brotli/encode.h>
|
7
7
|
#include <brotli/types.h>
|
8
|
-
#include <stdint.h>
|
9
|
-
#include <stdlib.h>
|
10
8
|
|
11
9
|
#include "brs_ext/buffer.h"
|
12
|
-
#include "brs_ext/common.h"
|
13
10
|
#include "brs_ext/error.h"
|
11
|
+
#include "brs_ext/gvl.h"
|
14
12
|
#include "brs_ext/option.h"
|
15
13
|
#include "ruby.h"
|
16
14
|
|
15
|
+
// -- initialization --
|
16
|
+
|
17
17
|
static void free_compressor(brs_ext_compressor_t* compressor_ptr)
|
18
18
|
{
|
19
19
|
BrotliEncoderState* state_ptr = compressor_ptr->state_ptr;
|
@@ -21,7 +21,7 @@ static void free_compressor(brs_ext_compressor_t* compressor_ptr)
|
|
21
21
|
BrotliEncoderDestroyInstance(state_ptr);
|
22
22
|
}
|
23
23
|
|
24
|
-
|
24
|
+
brs_ext_byte_t* destination_buffer = compressor_ptr->destination_buffer;
|
25
25
|
if (destination_buffer != NULL) {
|
26
26
|
free(destination_buffer);
|
27
27
|
}
|
@@ -32,14 +32,14 @@ static void free_compressor(brs_ext_compressor_t* compressor_ptr)
|
|
32
32
|
VALUE brs_ext_allocate_compressor(VALUE klass)
|
33
33
|
{
|
34
34
|
brs_ext_compressor_t* compressor_ptr;
|
35
|
-
|
36
|
-
VALUE self = Data_Make_Struct(klass, brs_ext_compressor_t, NULL, free_compressor, compressor_ptr);
|
35
|
+
VALUE self = Data_Make_Struct(klass, brs_ext_compressor_t, NULL, free_compressor, compressor_ptr);
|
37
36
|
|
38
37
|
compressor_ptr->state_ptr = NULL;
|
39
38
|
compressor_ptr->destination_buffer = NULL;
|
40
39
|
compressor_ptr->destination_buffer_length = 0;
|
41
40
|
compressor_ptr->remaining_destination_buffer = NULL;
|
42
41
|
compressor_ptr->remaining_destination_buffer_length = 0;
|
42
|
+
compressor_ptr->gvl = false;
|
43
43
|
|
44
44
|
return self;
|
45
45
|
}
|
@@ -52,8 +52,9 @@ VALUE brs_ext_initialize_compressor(VALUE self, VALUE options)
|
|
52
52
|
{
|
53
53
|
GET_COMPRESSOR(self);
|
54
54
|
Check_Type(options, T_HASH);
|
55
|
+
BRS_EXT_GET_SIZE_OPTION(options, destination_buffer_length);
|
56
|
+
BRS_EXT_GET_BOOL_OPTION(options, gvl);
|
55
57
|
BRS_EXT_GET_COMPRESSOR_OPTIONS(options);
|
56
|
-
BRS_EXT_GET_BUFFER_LENGTH_OPTION(options, destination_buffer_length);
|
57
58
|
|
58
59
|
BrotliEncoderState* state_ptr = BrotliEncoderCreateInstance(NULL, NULL, NULL);
|
59
60
|
if (state_ptr == NULL) {
|
@@ -70,7 +71,7 @@ VALUE brs_ext_initialize_compressor(VALUE self, VALUE options)
|
|
70
71
|
destination_buffer_length = BRS_DEFAULT_DESTINATION_BUFFER_LENGTH_FOR_COMPRESSOR;
|
71
72
|
}
|
72
73
|
|
73
|
-
|
74
|
+
brs_ext_byte_t* destination_buffer = malloc(destination_buffer_length);
|
74
75
|
if (destination_buffer == NULL) {
|
75
76
|
BrotliEncoderDestroyInstance(state_ptr);
|
76
77
|
brs_ext_raise_error(BRS_EXT_ERROR_ALLOCATE_FAILED);
|
@@ -81,72 +82,137 @@ VALUE brs_ext_initialize_compressor(VALUE self, VALUE options)
|
|
81
82
|
compressor_ptr->destination_buffer_length = destination_buffer_length;
|
82
83
|
compressor_ptr->remaining_destination_buffer = destination_buffer;
|
83
84
|
compressor_ptr->remaining_destination_buffer_length = destination_buffer_length;
|
85
|
+
compressor_ptr->gvl = gvl;
|
84
86
|
|
85
87
|
return Qnil;
|
86
88
|
}
|
87
89
|
|
90
|
+
// -- compress --
|
91
|
+
|
88
92
|
#define DO_NOT_USE_AFTER_CLOSE(compressor_ptr) \
|
89
93
|
if (compressor_ptr->state_ptr == NULL || compressor_ptr->destination_buffer == NULL) { \
|
90
94
|
brs_ext_raise_error(BRS_EXT_ERROR_USED_AFTER_CLOSE); \
|
91
95
|
}
|
92
96
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
const
|
97
|
-
size_t
|
98
|
-
|
99
|
-
|
97
|
+
typedef struct
|
98
|
+
{
|
99
|
+
brs_ext_compressor_t* compressor_ptr;
|
100
|
+
const brs_ext_byte_t* remaining_source;
|
101
|
+
size_t* remaining_source_length_ptr;
|
102
|
+
BROTLI_BOOL result;
|
103
|
+
} compress_args_t;
|
104
|
+
|
105
|
+
static inline void* compress_wrapper(void* data)
|
106
|
+
{
|
107
|
+
compress_args_t* args = data;
|
108
|
+
brs_ext_compressor_t* compressor_ptr = args->compressor_ptr;
|
109
|
+
|
110
|
+
args->result = BrotliEncoderCompressStream(
|
111
|
+
compressor_ptr->state_ptr,
|
112
|
+
BROTLI_OPERATION_PROCESS,
|
113
|
+
args->remaining_source_length_ptr,
|
114
|
+
&args->remaining_source,
|
115
|
+
&compressor_ptr->remaining_destination_buffer_length,
|
116
|
+
&compressor_ptr->remaining_destination_buffer,
|
117
|
+
NULL);
|
118
|
+
|
119
|
+
return NULL;
|
120
|
+
}
|
100
121
|
|
101
122
|
VALUE brs_ext_compress(VALUE self, VALUE source_value)
|
102
123
|
{
|
103
124
|
GET_COMPRESSOR(self);
|
104
125
|
DO_NOT_USE_AFTER_CLOSE(compressor_ptr);
|
105
|
-
|
126
|
+
Check_Type(source_value, T_STRING);
|
106
127
|
|
107
|
-
|
128
|
+
const char* source = RSTRING_PTR(source_value);
|
129
|
+
size_t source_length = RSTRING_LEN(source_value);
|
130
|
+
const brs_ext_byte_t* remaining_source = (const brs_ext_byte_t*) source;
|
131
|
+
size_t remaining_source_length = source_length;
|
108
132
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
&remaining_source_length
|
113
|
-
&compressor_ptr->remaining_destination_buffer_length, &compressor_ptr->remaining_destination_buffer,
|
114
|
-
NULL);
|
133
|
+
compress_args_t args = {
|
134
|
+
.compressor_ptr = compressor_ptr,
|
135
|
+
.remaining_source = remaining_source,
|
136
|
+
.remaining_source_length_ptr = &remaining_source_length};
|
115
137
|
|
116
|
-
|
138
|
+
BRS_EXT_GVL_WRAP(compressor_ptr->gvl, compress_wrapper, &args);
|
139
|
+
if (!args.result) {
|
117
140
|
brs_ext_raise_error(BRS_EXT_ERROR_UNEXPECTED);
|
118
141
|
}
|
119
142
|
|
120
143
|
VALUE bytes_written = SIZET2NUM(source_length - remaining_source_length);
|
121
|
-
VALUE needs_more_destination = BrotliEncoderHasMoreOutput(state_ptr) ? Qtrue : Qfalse;
|
144
|
+
VALUE needs_more_destination = BrotliEncoderHasMoreOutput(compressor_ptr->state_ptr) ? Qtrue : Qfalse;
|
122
145
|
|
123
146
|
return rb_ary_new_from_args(2, bytes_written, needs_more_destination);
|
124
147
|
}
|
125
148
|
|
126
|
-
|
127
|
-
{
|
128
|
-
GET_COMPRESSOR(self);
|
129
|
-
DO_NOT_USE_AFTER_CLOSE(compressor_ptr);
|
149
|
+
// -- compressor flush --
|
130
150
|
|
131
|
-
|
151
|
+
typedef struct
|
152
|
+
{
|
153
|
+
brs_ext_compressor_t* compressor_ptr;
|
154
|
+
BROTLI_BOOL result;
|
155
|
+
} compressor_flush_args_t;
|
132
156
|
|
133
|
-
|
134
|
-
|
157
|
+
static inline void* compressor_flush_wrapper(void* data)
|
158
|
+
{
|
159
|
+
compressor_flush_args_t* args = data;
|
160
|
+
brs_ext_compressor_t* compressor_ptr = args->compressor_ptr;
|
161
|
+
const brs_ext_byte_t* remaining_source = NULL;
|
162
|
+
size_t remaining_source_length = 0;
|
135
163
|
|
136
|
-
|
137
|
-
state_ptr,
|
164
|
+
args->result = BrotliEncoderCompressStream(
|
165
|
+
compressor_ptr->state_ptr,
|
138
166
|
BROTLI_OPERATION_FLUSH,
|
139
|
-
&remaining_source_length,
|
140
|
-
&
|
167
|
+
&remaining_source_length,
|
168
|
+
&remaining_source,
|
169
|
+
&compressor_ptr->remaining_destination_buffer_length,
|
170
|
+
&compressor_ptr->remaining_destination_buffer,
|
141
171
|
NULL);
|
142
172
|
|
143
|
-
|
173
|
+
return NULL;
|
174
|
+
}
|
175
|
+
|
176
|
+
VALUE brs_ext_flush_compressor(VALUE self)
|
177
|
+
{
|
178
|
+
GET_COMPRESSOR(self);
|
179
|
+
DO_NOT_USE_AFTER_CLOSE(compressor_ptr);
|
180
|
+
|
181
|
+
compressor_flush_args_t args = {.compressor_ptr = compressor_ptr};
|
182
|
+
|
183
|
+
BRS_EXT_GVL_WRAP(compressor_ptr->gvl, compressor_flush_wrapper, &args);
|
184
|
+
if (!args.result) {
|
144
185
|
brs_ext_raise_error(BRS_EXT_ERROR_UNEXPECTED);
|
145
186
|
}
|
146
187
|
|
147
|
-
|
188
|
+
return BrotliEncoderHasMoreOutput(compressor_ptr->state_ptr) ? Qtrue : Qfalse;
|
189
|
+
}
|
190
|
+
|
191
|
+
// -- compressor finish --
|
148
192
|
|
149
|
-
|
193
|
+
typedef struct
|
194
|
+
{
|
195
|
+
brs_ext_compressor_t* compressor_ptr;
|
196
|
+
BROTLI_BOOL result;
|
197
|
+
} compressor_finish_args_t;
|
198
|
+
|
199
|
+
static inline void* compressor_finish_wrapper(void* data)
|
200
|
+
{
|
201
|
+
compressor_finish_args_t* args = data;
|
202
|
+
brs_ext_compressor_t* compressor_ptr = args->compressor_ptr;
|
203
|
+
const brs_ext_byte_t* remaining_source = NULL;
|
204
|
+
size_t remaining_source_length = 0;
|
205
|
+
|
206
|
+
args->result = BrotliEncoderCompressStream(
|
207
|
+
compressor_ptr->state_ptr,
|
208
|
+
BROTLI_OPERATION_FINISH,
|
209
|
+
&remaining_source_length,
|
210
|
+
&remaining_source,
|
211
|
+
&compressor_ptr->remaining_destination_buffer_length,
|
212
|
+
&compressor_ptr->remaining_destination_buffer,
|
213
|
+
NULL);
|
214
|
+
|
215
|
+
return NULL;
|
150
216
|
}
|
151
217
|
|
152
218
|
VALUE brs_ext_finish_compressor(VALUE self)
|
@@ -154,40 +220,33 @@ VALUE brs_ext_finish_compressor(VALUE self)
|
|
154
220
|
GET_COMPRESSOR(self);
|
155
221
|
DO_NOT_USE_AFTER_CLOSE(compressor_ptr);
|
156
222
|
|
157
|
-
|
158
|
-
|
159
|
-
const uint8_t* remaining_source = NULL;
|
160
|
-
size_t remaining_source_length = 0;
|
161
|
-
|
162
|
-
BROTLI_BOOL result = BrotliEncoderCompressStream(
|
163
|
-
state_ptr,
|
164
|
-
BROTLI_OPERATION_FINISH,
|
165
|
-
&remaining_source_length, &remaining_source,
|
166
|
-
&compressor_ptr->remaining_destination_buffer_length, &compressor_ptr->remaining_destination_buffer,
|
167
|
-
NULL);
|
223
|
+
compressor_finish_args_t args = {.compressor_ptr = compressor_ptr};
|
168
224
|
|
169
|
-
|
225
|
+
BRS_EXT_GVL_WRAP(compressor_ptr->gvl, compressor_finish_wrapper, &args);
|
226
|
+
if (!args.result) {
|
170
227
|
brs_ext_raise_error(BRS_EXT_ERROR_UNEXPECTED);
|
171
228
|
}
|
172
229
|
|
173
|
-
|
174
|
-
|
175
|
-
|
230
|
+
return (BrotliEncoderHasMoreOutput(compressor_ptr->state_ptr) ||
|
231
|
+
!BrotliEncoderIsFinished(compressor_ptr->state_ptr)) ?
|
232
|
+
Qtrue :
|
233
|
+
Qfalse;
|
176
234
|
}
|
177
235
|
|
236
|
+
// -- other --
|
237
|
+
|
178
238
|
VALUE brs_ext_compressor_read_result(VALUE self)
|
179
239
|
{
|
180
240
|
GET_COMPRESSOR(self);
|
181
241
|
DO_NOT_USE_AFTER_CLOSE(compressor_ptr);
|
182
242
|
|
183
|
-
|
184
|
-
size_t
|
185
|
-
size_t
|
243
|
+
brs_ext_byte_t* destination_buffer = compressor_ptr->destination_buffer;
|
244
|
+
size_t destination_buffer_length = compressor_ptr->destination_buffer_length;
|
245
|
+
size_t remaining_destination_buffer_length = compressor_ptr->remaining_destination_buffer_length;
|
186
246
|
|
187
|
-
const char* result = (const char*)destination_buffer;
|
247
|
+
const char* result = (const char*) destination_buffer;
|
188
248
|
size_t result_length = destination_buffer_length - remaining_destination_buffer_length;
|
189
|
-
|
190
|
-
VALUE result_value = rb_str_new(result, result_length);
|
249
|
+
VALUE result_value = rb_str_new(result, result_length);
|
191
250
|
|
192
251
|
compressor_ptr->remaining_destination_buffer = destination_buffer;
|
193
252
|
compressor_ptr->remaining_destination_buffer_length = destination_buffer_length;
|
@@ -195,6 +254,8 @@ VALUE brs_ext_compressor_read_result(VALUE self)
|
|
195
254
|
return result_value;
|
196
255
|
}
|
197
256
|
|
257
|
+
// -- cleanup --
|
258
|
+
|
198
259
|
VALUE brs_ext_compressor_close(VALUE self)
|
199
260
|
{
|
200
261
|
GET_COMPRESSOR(self);
|
@@ -207,7 +268,7 @@ VALUE brs_ext_compressor_close(VALUE self)
|
|
207
268
|
compressor_ptr->state_ptr = NULL;
|
208
269
|
}
|
209
270
|
|
210
|
-
|
271
|
+
brs_ext_byte_t* destination_buffer = compressor_ptr->destination_buffer;
|
211
272
|
if (destination_buffer != NULL) {
|
212
273
|
free(destination_buffer);
|
213
274
|
|
@@ -220,6 +281,8 @@ VALUE brs_ext_compressor_close(VALUE self)
|
|
220
281
|
return Qnil;
|
221
282
|
}
|
222
283
|
|
284
|
+
// -- exports --
|
285
|
+
|
223
286
|
void brs_ext_compressor_exports(VALUE root_module)
|
224
287
|
{
|
225
288
|
VALUE module = rb_define_module_under(root_module, "Stream");
|